{"action":"created","comment":{"url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/comments/68597568","id":68597568,"diff_hunk":"@@ -3,70 +3,127 @@ package treecanopy\n import geotrellis.proj4._\n import geotrellis.raster._\n import geotrellis.raster.render._\n-import geotrellis.raster.render.png._\n import geotrellis.raster.resample._\n import geotrellis.spark._\n-import geotrellis.spark.etl.Etl\n-import geotrellis.spark.io._\n import geotrellis.spark.io.s3._\n import geotrellis.spark.pyramid.Pyramid\n import geotrellis.spark.render._\n import geotrellis.spark.tiling._\n import geotrellis.spark.util.SparkUtils\n import geotrellis.vector._\n-import geotrellis.vector.io._\n \n import com.amazonaws.services.s3.model._\n-import org.apache.hadoop.conf.Configuration\n import org.apache.hadoop.mapreduce.Job\n import org.apache.spark._\n import org.apache.spark.rdd.RDD\n \n+\n object Ingest {\n-  val targetLayoutScheme =\n-    ZoomedLayoutScheme(WebMercator, 512)\n-\n-  val colorMap =\n-    ColorMap(\n-      Map(\n-        0 -> 0x00000000,\n-        1 -> 0x139A68FF\n-      )\n-    )\n \n   def main(args: Array[String]): Unit = {\n     implicit val sc = SparkUtils.createSparkContext(\"Tree Canopy ETL\", new SparkConf(true))\n \n-    try {\n+    val sourceBucket = \"azavea-datahub\"\n+    val statewideLayerName = \"raw/treecanopy-2006-2008-pennsylvania-albers\"\n+    val localLayerName = \"raw/treecanopy-pennsylvania-local/harrisburg\"\n+    val localLayerNames = List(\n+      \"raw/treecanopy-pennsylvania-local/abingtons\",\n+      \"raw/treecanopy-pennsylvania-local/alleghenyCounty\",\n+      \"raw/treecanopy-pennsylvania-local/harrisburg\",\n+      \"raw/treecanopy-pennsylvania-local/lancasterCity\",\n+      \"raw/treecanopy-pennsylvania-local/montgomeryCounty\",\n+      \"raw/treecanopy-pennsylvania-local/stateCollege\"\n+    )\n+    val outputPath = \"s3://com.azavea.datahub.tms/{name}/{z}/{x}/{y}.png\"\n+    val outputName = \"treecanopy-2006-2008-pa-merged\"\n+\n+    val tileSize = 256\n+    val targetLayoutScheme =\n+      ZoomedLayoutScheme(WebMercator, tileSize)\n+\n+    // Map 1 to the canopy color and everything else to 0\n+    val colorMap =\n+      ColorMap(\n+        Map(\n+          0 -> 0x00000000,\n+          1 -> 0x139A68FF,\n+          Int.MaxValue -> 0x00000000\n+        )\n+      )\n+\n+    val clipTo = Polygon(\n+      Point(1257023, 2337147),\n+      Point(1257023, 1954954),\n+      Point(1793996, 1954954),\n+      Point(1793996, 2337147),\n+      Point(1257023, 2337147)\n+    )\n \n-      println(args.toSeq)\n-      val etl = Etl(args)\n+    val maxLocalZoom = 19  // highest zoom level of local datasets\n+    val partitioner = new HashPartitioner(5000)\n \n-      val sourceTiles =\n-        etl.load[ProjectedExtent, Tile]\n+    try {\n+      val raw = loadFromS3(sourceBucket, statewideLayerName, partitioner.numPartitions)\n+        .filter { case (key, value) => key.extent.intersects(clipTo) }\n+      val (myMaxZoom, tiled) = tile(raw, tileSize, NearestNeighbor, partitioner)\n+      val resampled = if (myMaxZoom >= maxLocalZoom) {\n+        tiled\n+      } else {\n+        tiled.resampleToZoom(myMaxZoom, maxLocalZoom, NearestNeighbor)\n+      }\n+      val statewideLevelStream = Pyramid.levelStream(resampled, targetLayoutScheme, maxLocalZoom, NearestNeighbor)\n \n-      // Reproject and tile the layer.\n-      val (zoom, canopy) =\n-        etl.tile(sourceTiles)\n+      val raw2 = loadFromS3(sourceBucket, localLayerName, partitioner.numPartitions)\n+      val (myMaxZoom2, tiled2) = tile(raw2, tileSize, NearestNeighbor, partitioner)\n+      val resampled2 = if (myMaxZoom2 >= maxLocalZoom) {\n+        tiled2\n+      } else {\n+        tiled2.resampleToZoom(myMaxZoom2, maxLocalZoom, NearestNeighbor)\n+      }\n+      val localLevelStream = Pyramid.levelStream(resampled2, targetLayoutScheme, maxLocalZoom, NearestNeighbor)\n \n-      val conf = etl.conf\n-      val path = \"s3://com.azavea.datahub.tms/{name}/{z}/{x}/{y}.png\"\n+      statewideLevelStream\n+        .zip(localLevelStream)\n+        .foreach { case ((z, statewideLayer), (_, localLayer)) =>\n+          // merge() will add statewide values only where the local value is absent or NODATA\n+          val merged = localLayer.merge(statewideLayer)","path":"src/main/scala/treecanopy/Main.scala","position":112,"original_position":112,"commit_id":"13173cc5de8b65c04f82fddebcebd610975aab1c","original_commit_id":"13173cc5de8b65c04f82fddebcebd610975aab1c","user":{"login":"RickMohr","id":2162993,"avatar_url":"https://avatars.githubusercontent.com/u/2162993?v=3","gravatar_id":"","url":"https://api.github.com/users/RickMohr","html_url":"https://github.com/RickMohr","followers_url":"https://api.github.com/users/RickMohr/followers","following_url":"https://api.github.com/users/RickMohr/following{/other_user}","gists_url":"https://api.github.com/users/RickMohr/gists{/gist_id}","starred_url":"https://api.github.com/users/RickMohr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RickMohr/subscriptions","organizations_url":"https://api.github.com/users/RickMohr/orgs","repos_url":"https://api.github.com/users/RickMohr/repos","events_url":"https://api.github.com/users/RickMohr/events{/privacy}","received_events_url":"https://api.github.com/users/RickMohr/received_events","type":"User","site_admin":false},"body":"In this simplified version I still haven't been able to get around a \"Task not serializable\" exception on the above `merge` line. The \"Serialization stack\" says the offending object is `geotrellis.spark.package$`, which contains the `merge` method.\r\n\r\nAny ideas?\r\n\r\nThe code is based on\r\nhttps://github.com/lossyrob/geotrellis-ned-example/blob/master/src/main/scala/elevation/Main.scala#L215, which presumably doesn't have the same problem though it doesn't do a merge.\r\n\r\n```\r\n6/06/27 14:13:31 ERROR ApplicationMaster: User class threw exception: org.apache.spark.SparkException: Task not serializable\r\norg.apache.spark.SparkException: Task not serializable\r\n\tat org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:304)\r\n\tat org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:294)\r\n\tat org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:122)\r\n\tat org.apache.spark.SparkContext.clean(SparkContext.scala:2055)\r\n\tat org.apache.spark.rdd.RDD$$anonfun$flatMap$1.apply(RDD.scala:333)\r\n\tat org.apache.spark.rdd.RDD$$anonfun$flatMap$1.apply(RDD.scala:332)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:150)\r\n\tat org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:111)\r\n\tat org.apache.spark.rdd.RDD.withScope(RDD.scala:316)\r\n\tat org.apache.spark.rdd.RDD.flatMap(RDD.scala:332)\r\n\tat geotrellis.spark.merge.RDDLayoutMergeMethods.merge(RddLayoutMergeMethods.scala:26)\r\n\tat treecanopy.Ingest$$anonfun$main$1.apply(Main.scala:88)\r\n\tat treecanopy.Ingest$$anonfun$main$1.apply(Main.scala:86)\r\n\tat scala.collection.immutable.Stream.foreach(Stream.scala:547)\r\n\tat treecanopy.Ingest$.main(Main.scala:86)\r\n\tat treecanopy.Ingest.main(Main.scala)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\r\n\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.lang.reflect.Method.invoke(Method.java:606)\r\n\tat org.apache.spark.deploy.yarn.ApplicationMaster$$anon$2.run(ApplicationMaster.scala:542)\r\nCaused by: java.io.NotSerializableException: geotrellis.spark.package$\r\nSerialization stack:\r\n\t- object not serializable (class: geotrellis.spark.package$, value: geotrellis.spark.package$@297b65ff)\r\n\t- field (class: geotrellis.spark.merge.Implicits$withRDDLayoutMergeMethods, name: $outer, type: interface geotrellis.spark.merge.Implicits)\r\n\t- object (class geotrellis.spark.merge.Implicits$withRDDLayoutMergeMethods, geotrellis.spark.merge.Implicits$withRDDLayoutMergeMethods@4930cfab)\r\n\t- field (class: geotrellis.spark.merge.RDDLayoutMergeMethods$$anonfun$1, name: $outer, type: class geotrellis.spark.merge.RDDLayoutMergeMethods)\r\n\t- object (class geotrellis.spark.merge.RDDLayoutMergeMethods$$anonfun$1, <function1>)\r\n\tat org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)\r\n\tat org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)\r\n\tat org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:101)\r\n\tat org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:301)\r\n\t... 20 more\r\n```","created_at":"2016-06-27T15:29:53Z","updated_at":"2016-06-27T15:29:53Z","html_url":"https://github.com/lossyrob/treecanopy-ingest/pull/3#discussion_r68597568","pull_request_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3","_links":{"self":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/comments/68597568"},"html":{"href":"https://github.com/lossyrob/treecanopy-ingest/pull/3#discussion_r68597568"},"pull_request":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3"}}},"pull_request":{"url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3","id":75331216,"html_url":"https://github.com/lossyrob/treecanopy-ingest/pull/3","diff_url":"https://github.com/lossyrob/treecanopy-ingest/pull/3.diff","patch_url":"https://github.com/lossyrob/treecanopy-ingest/pull/3.patch","issue_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/3","number":3,"state":"open","locked":false,"title":"Create statewide canopy tiles augmented with local canopy data","user":{"login":"RickMohr","id":2162993,"avatar_url":"https://avatars.githubusercontent.com/u/2162993?v=3","gravatar_id":"","url":"https://api.github.com/users/RickMohr","html_url":"https://github.com/RickMohr","followers_url":"https://api.github.com/users/RickMohr/followers","following_url":"https://api.github.com/users/RickMohr/following{/other_user}","gists_url":"https://api.github.com/users/RickMohr/gists{/gist_id}","starred_url":"https://api.github.com/users/RickMohr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RickMohr/subscriptions","organizations_url":"https://api.github.com/users/RickMohr/orgs","repos_url":"https://api.github.com/users/RickMohr/repos","events_url":"https://api.github.com/users/RickMohr/events{/privacy}","received_events_url":"https://api.github.com/users/RickMohr/received_events","type":"User","site_admin":false},"body":"* Load statewide canopy raster and the Harrisburg local canopy raster\r\n* Load directly rather than using built-in ETL (ETL control is cumbersome with multiple datasets in the same job)\r\n* Resample both raster to zoom 19 (the max zoom of the local raster)\r\n* Use tile size 256 (because of https://github.com/geotrellis/geotrellis/issues/1550)\r\n* Merge statewide and local data, with local taking precedence","created_at":"2016-06-27T15:28:15Z","updated_at":"2016-06-27T15:29:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"357e3c702f78ffd0868d02b56bcda91279255ece","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3/commits","review_comments_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3/comments","review_comment_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/comments{/number}","comments_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/3/comments","statuses_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/statuses/13173cc5de8b65c04f82fddebcebd610975aab1c","head":{"label":"RickMohr:simpler-merge","ref":"simpler-merge","sha":"13173cc5de8b65c04f82fddebcebd610975aab1c","user":{"login":"RickMohr","id":2162993,"avatar_url":"https://avatars.githubusercontent.com/u/2162993?v=3","gravatar_id":"","url":"https://api.github.com/users/RickMohr","html_url":"https://github.com/RickMohr","followers_url":"https://api.github.com/users/RickMohr/followers","following_url":"https://api.github.com/users/RickMohr/following{/other_user}","gists_url":"https://api.github.com/users/RickMohr/gists{/gist_id}","starred_url":"https://api.github.com/users/RickMohr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RickMohr/subscriptions","organizations_url":"https://api.github.com/users/RickMohr/orgs","repos_url":"https://api.github.com/users/RickMohr/repos","events_url":"https://api.github.com/users/RickMohr/events{/privacy}","received_events_url":"https://api.github.com/users/RickMohr/received_events","type":"User","site_admin":false},"repo":{"id":60856252,"name":"treecanopy-ingest","full_name":"RickMohr/treecanopy-ingest","owner":{"login":"RickMohr","id":2162993,"avatar_url":"https://avatars.githubusercontent.com/u/2162993?v=3","gravatar_id":"","url":"https://api.github.com/users/RickMohr","html_url":"https://github.com/RickMohr","followers_url":"https://api.github.com/users/RickMohr/followers","following_url":"https://api.github.com/users/RickMohr/following{/other_user}","gists_url":"https://api.github.com/users/RickMohr/gists{/gist_id}","starred_url":"https://api.github.com/users/RickMohr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RickMohr/subscriptions","organizations_url":"https://api.github.com/users/RickMohr/orgs","repos_url":"https://api.github.com/users/RickMohr/repos","events_url":"https://api.github.com/users/RickMohr/events{/privacy}","received_events_url":"https://api.github.com/users/RickMohr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/RickMohr/treecanopy-ingest","description":"","fork":true,"url":"https://api.github.com/repos/RickMohr/treecanopy-ingest","forks_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/forks","keys_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/teams","hooks_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/hooks","issue_events_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/issues/events{/number}","events_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/events","assignees_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/assignees{/user}","branches_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/branches{/branch}","tags_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/tags","blobs_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/git/refs{/sha}","trees_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/statuses/{sha}","languages_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/languages","stargazers_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/stargazers","contributors_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/contributors","subscribers_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/subscribers","subscription_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/subscription","commits_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/commits{/sha}","git_commits_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/git/commits{/sha}","comments_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/comments{/number}","issue_comment_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/issues/comments{/number}","contents_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/contents/{+path}","compare_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/merges","archive_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/downloads","issues_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/issues{/number}","pulls_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/pulls{/number}","milestones_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/milestones{/number}","notifications_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/labels{/name}","releases_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/releases{/id}","deployments_url":"https://api.github.com/repos/RickMohr/treecanopy-ingest/deployments","created_at":"2016-06-10T15:03:58Z","updated_at":"2016-06-10T15:04:00Z","pushed_at":"2016-06-27T15:14:36Z","git_url":"git://github.com/RickMohr/treecanopy-ingest.git","ssh_url":"git@github.com:RickMohr/treecanopy-ingest.git","clone_url":"https://github.com/RickMohr/treecanopy-ingest.git","svn_url":"https://github.com/RickMohr/treecanopy-ingest","homepage":null,"size":27,"stargazers_count":0,"watchers_count":0,"language":"Shell","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"lossyrob:master","ref":"master","sha":"96ddab2469c7a0e04674177e792274ce5f6b8b25","user":{"login":"lossyrob","id":2320142,"avatar_url":"https://avatars.githubusercontent.com/u/2320142?v=3","gravatar_id":"","url":"https://api.github.com/users/lossyrob","html_url":"https://github.com/lossyrob","followers_url":"https://api.github.com/users/lossyrob/followers","following_url":"https://api.github.com/users/lossyrob/following{/other_user}","gists_url":"https://api.github.com/users/lossyrob/gists{/gist_id}","starred_url":"https://api.github.com/users/lossyrob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lossyrob/subscriptions","organizations_url":"https://api.github.com/users/lossyrob/orgs","repos_url":"https://api.github.com/users/lossyrob/repos","events_url":"https://api.github.com/users/lossyrob/events{/privacy}","received_events_url":"https://api.github.com/users/lossyrob/received_events","type":"User","site_admin":false},"repo":{"id":57062788,"name":"treecanopy-ingest","full_name":"lossyrob/treecanopy-ingest","owner":{"login":"lossyrob","id":2320142,"avatar_url":"https://avatars.githubusercontent.com/u/2320142?v=3","gravatar_id":"","url":"https://api.github.com/users/lossyrob","html_url":"https://github.com/lossyrob","followers_url":"https://api.github.com/users/lossyrob/followers","following_url":"https://api.github.com/users/lossyrob/following{/other_user}","gists_url":"https://api.github.com/users/lossyrob/gists{/gist_id}","starred_url":"https://api.github.com/users/lossyrob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lossyrob/subscriptions","organizations_url":"https://api.github.com/users/lossyrob/orgs","repos_url":"https://api.github.com/users/lossyrob/repos","events_url":"https://api.github.com/users/lossyrob/events{/privacy}","received_events_url":"https://api.github.com/users/lossyrob/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/lossyrob/treecanopy-ingest","description":"","fork":false,"url":"https://api.github.com/repos/lossyrob/treecanopy-ingest","forks_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/forks","keys_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/teams","hooks_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/hooks","issue_events_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/events{/number}","events_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/events","assignees_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/assignees{/user}","branches_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/branches{/branch}","tags_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/tags","blobs_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/git/refs{/sha}","trees_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/statuses/{sha}","languages_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/languages","stargazers_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/stargazers","contributors_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/contributors","subscribers_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/subscribers","subscription_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/subscription","commits_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/commits{/sha}","git_commits_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/git/commits{/sha}","comments_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/comments{/number}","issue_comment_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/comments{/number}","contents_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/contents/{+path}","compare_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/merges","archive_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/downloads","issues_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues{/number}","pulls_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls{/number}","milestones_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/milestones{/number}","notifications_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/labels{/name}","releases_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/releases{/id}","deployments_url":"https://api.github.com/repos/lossyrob/treecanopy-ingest/deployments","created_at":"2016-04-25T17:43:59Z","updated_at":"2016-04-25T17:44:10Z","pushed_at":"2016-06-27T15:28:16Z","git_url":"git://github.com/lossyrob/treecanopy-ingest.git","ssh_url":"git@github.com:lossyrob/treecanopy-ingest.git","clone_url":"https://github.com/lossyrob/treecanopy-ingest.git","svn_url":"https://github.com/lossyrob/treecanopy-ingest","homepage":null,"size":22,"stargazers_count":0,"watchers_count":0,"language":"Shell","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3"},"html":{"href":"https://github.com/lossyrob/treecanopy-ingest/pull/3"},"issue":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/3"},"comments":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/lossyrob/treecanopy-ingest/statuses/13173cc5de8b65c04f82fddebcebd610975aab1c"}}}}
{"actor":{"display_login":"RickMohr"}}