{"componentChunkName":"component---src-templates-blog-post-js","path":"/generating_topojson/","result":{"data":{"site":{"siteMetadata":{"title":"tigue.com"}},"markdownRemark":{"id":"2e83b25b-79a4-59e7-b88a-312b8ef5e0ef","excerpt":"(Update: since originally posting this, I have learned a trick or two which avoids some of the problems discussed here. \nNonetheless, this post still stands as…","html":"<p>(<strong>Update:</strong> since originally posting this, I have learned a trick or two which avoids some of the problems discussed here.\nNonetheless, this post still stands as potentially helpful to anyone walking the same path I did.\nSee below for details.)</p>\n<p>This is one of those posts that a confounded developer hopes to find in a time of need.\nThe situation: generating <a href=\"https://github.com/mbostock/topojson\">TopoJSON</a> files.\nPresented here are two attempts to generate a TopoJSON file; the first one failed, the second worked for me, <a href=\"https://en.wiktionary.org/wiki/YMMV\">YMMV</a>.\nThe fail path is due to a naive attempt to do the conversion in one step. The successful path is one I eventually figured out that involves two steps.\nThe two step process consists of using <code class=\"language-text\">topojson</code> and then <a href=\"http://www.gdal.org/\">GDAL</a> (on OSX, it can be installed via <code class=\"language-text\">brew install gdal</code>).</p>\n<p>As part of the <a href=\"http://tigue.com/by-time/2015/12/09/seattle-boundaries/\">seattle-boundaries</a> project, I needed to translate a\nshapefile for the Seattle City Council Districts to TopoJSON.\nI got the shapefile, <a href=\"https://data.seattle.gov/City-Business/City-Council-Districts/th8u-8xnq\">Seattle<em>City</em>Council_Districts.zip</a>, from\n<a href=\"https://data.seattle.gov/\">the City of Seattle’s open data site</a>.</p>\n<p>TopoJSON is from the mind of Mike Bostock. As part of that effort he created a <a href=\"https://en.wikipedia.org/wiki/Unix_philosophy#Origin\">“small, sharp tool”</a> for generating TopoJSON files.\nThe command line tool is appropriately called <a href=\"https://github.com/mbostock/topojson/wiki/Command-Line-Reference\"><code class=\"language-text\">topojson</code></a>.</p>\n<p>My naive and doomed first attempt was to generate the TopoJSON directly from the shapefile, which is advertised as possible.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">topojson --out seattle-city-council-districts-as-topojson.bad.json City_Council_Districts.shp</code></pre></div>\n<p>(<strong>Update:</strong> turns out the mistake I made was not using the <code class=\"language-text\">--spherical</code> option. Inspecting the <code class=\"language-text\">*.prj</code> file that came with the <code class=\"language-text\">*.shp</code> file revealed that the data was on a spherical projection. Re-running original command as <code class=\"language-text\">topojson --spherical ...</code> worked like a charm.)</p>\n<p>Below is the generated file, uploaded to GitHub. Notice the orange line at the north pole. That is the TopoJSON rendered (read: FAIL).</p>\n<p><a title='TopoJSON fail' href='https://github.com/JohnTigue/nodeio/blob/master/data/generating-topojson/seattle-city-council-districts-as-topojson.bad.json'><span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 750px;\">\n      <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 61.73333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAABaklEQVQoz7WQ2XaCMBCG8/7P1da6VOtWtW6gKIr7QiAJ9O9MkAtse2dzzs9M5pvMgjDG4JES/EmSBPf2t1j+6K98lviXCR9bMElp1BSGxy/YzLfMFGMFVshPIRIloWOJlOyXJqszy0pUCBMXY7lvYmLqJxMD74TF9oKOe0TLOaLp3Oz0iLF/xjy42HvO2jfrrM9W90x0lzHcnUHVkej5CvO9QXMeoenF6K8UpluN8kRiFGjK02jMIrSI8X0YKFSm0uaMNxp1YmJzMSiNr5jtFPhEOkXdDeFsFby9QpnY+qQtO4QGNSfE8qAxCWJUp6GN8fGP2r4TH8sILA58rmK8zyReqQg36fkR+n7GepTTIFYaXWniEAPKZTHreMRciRdigrvwhQs8D6+2a430RP4bTcPiIvm9MskYN2Y/f1d3s0EEd2l70q68PhvsrsZ2bM6lnaC7iGh1jQ2xgMSFOotsct6M19/Sb8tWlvgGEDCUWCkD88gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;\"></span>\n  <img class=\"gatsby-resp-image-image\" alt=\"Generated TopoJSON which does not work\" title=\"Generated TopoJSON which does not work\" src=\"/static/609951dfea5705e4eeb75de462eb13cd/b8ccf/topojson-fail.png\" srcset=\"/static/609951dfea5705e4eeb75de462eb13cd/1abb1/topojson-fail.png 250w,\n/static/609951dfea5705e4eeb75de462eb13cd/7217d/topojson-fail.png 500w,\n/static/609951dfea5705e4eeb75de462eb13cd/b8ccf/topojson-fail.png 750w\" sizes=\"(max-width: 750px) 100vw, 750px\" loading=\"lazy\">\n    </span></a></p>\n<p>The tool, <code class=\"language-text\">topojson</code>, can read from multiple file formats, including shapefiles (*.shp), but there were problems with it converting the Seattle City Council District file.\nThe root of the problem is in the JSON with the nutty <code class=\"language-text\">bbox</code> and <code class=\"language-text\">transform</code> which clearly are not latitude and longitude numbers:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">bbox<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token number\">1244215.911418721</span><span class=\"token punctuation\">,</span>\n  <span class=\"token number\">183749.53649789095</span><span class=\"token punctuation\">,</span>\n  <span class=\"token number\">1297226.8887299001</span><span class=\"token punctuation\">,</span>\n  <span class=\"token number\">271529.74938854575</span>\n<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"token operator\">...</span>\ntranslate<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token number\">1244215.911418721</span><span class=\"token punctuation\">,</span>\n  <span class=\"token number\">183749.53649789095</span>\n<span class=\"token punctuation\">]</span></code></pre></div>\n<p>On the other hand, if this file is uploaded to <a href=\"http://www.mapshaper.org/\">mapshaper.org</a> then it renders well. Note though that there is no geographic “context” for the rendering, i.e., no global map and the Seattle City Districts are scaled to take up the full window’s allocated pixels. Perhaps mapshaper is not using the <code class=\"language-text\">bbox</code> and such, which enables it to render.</p>\n<p>I explored the <code class=\"language-text\">topojson</code> command line switches but was not getting anywhere, so I went to Plan B which eventually got me better results. This involved two stages: first use GDAL’s ogr2ogr to translate the shapefile to GeoJSON, and then feed the GeoJSON to <code class=\"language-text\">topojson</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">ogr2ogr -f GeoJSON -t_srs crs:84 seattle-city-council-districts-as-geojson.json City_Council_Districts.shp\ntopojson --out seattle-city-council-districts-as-topojson.good.json seattle-city-council-districts-as-geojson.json</code></pre></div>\n<p>The resulting TopoJSON renders on GitHub as follows.</p>\n<p><a title='TopoJSON win' href='https://github.com/JohnTigue/nodeio/blob/master/data/generating-topojson/seattle-city-council-districts-as-topojson.good.json'><span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 750px;\">\n      <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 61.86666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACdklEQVQozzVT527bMBj0+79P/xco2jhN07pJ2gzLjiwP2dYiJQ6RlHQ9KqgAQgu87xYXadGj6jzu3zsUnYEPA8IQkFUWX986ZKWFDQ7K9bDeI0wT/DjCjYH3CYFr4HvcNwwjFlnZc5PDoXFw3Gh9gPYaZedwk3RILwqllBD241/TtvMyoZ+BDL8HAsXnaSJgLjySUwvZRYaWoB5vZ4XHvcbt1uBhc0Z1fMHhuIe0FrVo0AgBTxXKGFR1AyJhjEwjw7MkwFFCSoGL7LGjxFw6rDKNm3WL/fYvdLbEJblFdjrBDrRkGgjoqIR2eLJ0frbDhYDFaqdQqQDHiYaSnnYC602C+3WBX68ZZHqDcvONgEv8eU3ot0JKtnUrEa8wTLRHzYBR9qL3caJDSmaN6ZELjUtV4mEncZcIbJMXXF8/I33+jk0u0DkDoTWyq0CrOrKzDMwSeMBE2YuBD+9ZivunNQ7XElmtcRIGLzk9ZCi/nzdI7j7hbfWF3xSHKtTKYH2oUTdcqpmlRnbRx0Vg3F2nUTUN1mRwqC22V4071uhHUuOariBSeri9x/5cotI9raESaVinKJN+EtB6pk2sReyPJ0ulLZJ9ztRKFK3Dz1RimSjkKUPJH1Gmv7DdZVB+QuNK1LakVDOzs86hKCvsjgcyJJhlWoYrBqP4s+t7pIVldQyeNjmklugo7Xg6oBQtCz3MCXeuw8iqOIY5sjqHyxGLkdo1J/2fFvt1kQxIORxZ9uVa4FwUaHuHRht0RqMPsRX0bAIGltnSghiI9SYyHD+aPowf0RMwb3qydEy8n2UXPJrSGrLycwdbGwj6cdzy4gxhBGK4hb7gH4V4kfMYxJe2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;\"></span>\n  <img class=\"gatsby-resp-image-image\" alt=\"Generated TopoJSON which does work\" title=\"Generated TopoJSON which does work\" src=\"/static/a2b3b3f0c3590ce3cfef09930b5b2f3d/b8ccf/topojson-win.png\" srcset=\"/static/a2b3b3f0c3590ce3cfef09930b5b2f3d/1abb1/topojson-win.png 250w,\n/static/a2b3b3f0c3590ce3cfef09930b5b2f3d/7217d/topojson-win.png 500w,\n/static/a2b3b3f0c3590ce3cfef09930b5b2f3d/b8ccf/topojson-win.png 750w\" sizes=\"(max-width: 750px) 100vw, 750px\" loading=\"lazy\">\n    </span></a></p>\n<p>Notice how the districts are colored orange, similar to the TopoJSON “North Pole line” in the bad file.</p>\n<p>I guess <code class=\"language-text\">ogr2ogr</code> is better at handling shapefiles. TopoJSON was invented in order to make a more efficient geo-info JSON format that the rather “naive” GeoJSON, so it stands to reason that Bostock’s tool is better at <code class=\"language-text\">GeoJSON to TopoJSON</code> than it is at <code class=\"language-text\">Shapefile to TopoJSON</code>. Or at least that is my guess. I have no ability to judge the quality of the input Shapefile; maybe the thing was funky to start with.</p>\n<p>For more information and all the files related to this task, check out <a href=\"https://github.com/JohnTigue/nodeio/tree/master/data/generating-topojson\">my GitHub repo on this topic</a>.</p>\n<p><strong>Update:</strong>\nTake 2 of the work in the post used <code class=\"language-text\">topojson@1.6.20</code> and I am not sure which version was used for Take 1 but that version of <code class=\"language-text\">topojson</code> was installed over six months earlier.</p>\n<p>Also, the City now has UI for exporting (read: downloading) their datasets as GeoJSON, which leads to another option: use <code class=\"language-text\">topojson</code> to convert the City’s GeoJSON to TopoJSON, no shapefile involved at all.</p>","frontmatter":{"title":"Generating TopoJSON debug","date":"December 14, 2015","description":null}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/generating_topojson/","previous":{"fields":{"slug":"/seattle_boundaries/"},"frontmatter":{"title":"Seattle map boundaries repository"}},"next":{"fields":{"slug":"/seattle_speed_testing/"},"frontmatter":{"title":"Seattle ISP quality monitor"}}}}}