<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>indiemaps.com/blog</title>
	<atom:link href="http://indiemaps.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://indiemaps.com/blog</link>
	<description>the notebook of cartographer zachary forest johnson</description>
	<pubDate>Fri, 20 Apr 2012 05:10:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>introducing OpenLayers Symbology</title>
		<link>http://indiemaps.com/blog/2012/04/introducing-openlayers-symbology/</link>
		<comments>http://indiemaps.com/blog/2012/04/introducing-openlayers-symbology/#comments</comments>
		<pubDate>Wed, 18 Apr 2012 12:30:25 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[cartogram]]></category>

		<category><![CDATA[choropleth]]></category>

		<category><![CDATA[classification]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[dot density]]></category>

		<category><![CDATA[geojson]]></category>

		<category><![CDATA[isolines]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[library]]></category>

		<category><![CDATA[NACIS]]></category>

		<category><![CDATA[noncontiguous cartogram]]></category>

		<category><![CDATA[openlayers]]></category>

		<category><![CDATA[projections]]></category>

		<category><![CDATA[proportional symbol]]></category>

		<category><![CDATA[symbology]]></category>

		<category><![CDATA[thematic mapping]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=138</guid>
		<description><![CDATA[a JavaScript library for thematic mapping in OpenLayers

At last October&#8217;s NACIS Practical Cartography Day I gave a very sweaty presentation that was later described as bewildering and incoherent.  I had always meant to partially redeem myself by packaging and cleaning up the code that formed the basis of that talk.  And here it is!
OL-Symbology is [...]]]></description>
			<content:encoded><![CDATA[<p><em>a JavaScript library for thematic mapping in OpenLayers</em></p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/olSymbology/ol-isolines.png" alt="" width="596" height="596" /></div>
<p>At last October&#8217;s <a href="http://www.nacis.org/">NACIS</a> Practical Cartography Day I gave a very sweaty presentation that was later described as bewildering and incoherent.  I had always meant to partially redeem myself by packaging and cleaning up the code that formed the basis of that talk.  <a href="https://github.com/indiemaps/OpenLayers-Symbology">And here it is!</a></p>
<p>OL-Symbology is just a small JavaScript library for easily creating 5 basic thematic map types dynamically in <a href="http://openlayers.org/">OpenLayers</a>: choropleth, proportional symbol, cartogram, dot density, and isoline.  Each basic symbology includes many options for customization, and symbology classes can be combined to create multivariate thematic layers.  Below I&#8217;ll go through the background and specific features of the library; if you just want to check out the code, head over to the <a href="https://github.com/indiemaps/OpenLayers-Symbology">Github page for the project</a>.</p>
<h3>Impetus</h3>
<p>OpenLayers has been around for six years now, and really is the most fully-featured web mapping platform going.  I&#8217;d argue that it&#8217;s been used mostly for reference mapping, as opposed to thematic data mapping.  I first saw OL used for thematic mapping in <a href="http://crschmidt.net/blog/archives/307/choropleth-maps-with-openlayers-26/">choropleth</a> and <a href="http://blog.thematicmapping.org/2008/04/proportional-symbol-mapping-with.html">proportional symbol applications</a> in 2008.  I <a href="http://indiemaps.com/blog/2011/02/noncontiguous-cartograms-in-openlayers-and-polymaps/">added noncontiguous cartograms</a> to the mix last year.  </p>
<p>These previous implementations, though, were all written and presented more or less as &#8220;one offs&#8221;.  That is, they weren&#8217;t packaged up as classes to be re-used by other developers; rather they were all more proofs of concept.  I wanted to expand and develop a library of classes that would allow end developers or cartographers to easily create basic thematic mapping types with very little code.  Before getting into the library, I need to mention the one previous attempt I know of to do pretty much the same thing: the MapFish widgets for <a href="http://www.mapfish.org/apidoc/trunk/files/mapfish/widgets/geostat/Choropleth-js.html">choropleth</a> and <a href="http://www.mapfish.org/apidoc/trunk/files/mapfish/widgets/geostat/ProportionalSymbol-js.html">proportional symbol</a> mapping.</p>
<p><a href="http://mapfish.org/">MapFish</a> is a RIA framework for web mapping that uses OpenLayers as its map engine. I saw the two MapFish thematic mapping widgets mentioned in the 2008 post by Bjørn Sandvik on <a href="http://blog.thematicmapping.org/2008/04/thematic-mapping-with-geojson.html">choropleth mapping with GeoJSON</a>, and I&#8217;m really not sure that any work has been done on them since then.  Though the MapFish widgets are quite limited &#8212; only one color scheme for choropleth, no classed choropleth or unclassed proportional symbols, only one shape type available for proportional symbols &#8212; I did borrow some ideas from the format and organization of the two widgets.  Before talking about the five individual thematic mapping types in my library, I&#8217;ll just go through a bit of what they hold in common.</p>
<h3>Common features</h3>
<p>To create a new thematic layer, the user/developer only needs to set three options:</p>
<ol>
<li><span class="incode">url</span> or <span class="incode">layer</span>: a data source, in the form of a URL string or a pre-loaded <a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/Vector-js.html">Vector Layer</a></li>
<li><span class="incode">indicator</span> or <span class="incode">valuator</span>: the name of the variable (attribute/indicator) that you are representing with this symbology.  If you need to standardize your variable (ex. disease cases divided by population) just define the optional valuator function</li>
<li><span class="incode">map</span>: the <a href="http://dev.openlayers.org/docs/files/OpenLayers/Map-js.html">Map</a> instance that the thematic layer should be added to</li>
</ol>
<p>All other symbology settings are optional and have at least semi-intelligent defaults.  So, most basically:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> isoLayer = <span class="kw2">new</span> ol.<span class="me1">thematic</span>.<span class="me1">Isoline</span><span class="br0">&#40;</span> map, <span class="br0">&#123;</span><br />
&nbsp; &nbsp;url &nbsp;&nbsp;: <span class="st0">'geothermal.geo.json'</span>,<br />
&nbsp; &nbsp;indicator &nbsp; &nbsp;: <span class="st0">'temp_depth_75km'</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div></div>
<p>That would create a completely serviceable isarithmic representation and add it to your map, though you&#8217;d likely want to customize it by at least setting the isoline <span class="incode">interval</span> option (the default is 5; see below).  </p>
<p>Each thematic map type has unique options (<span class="incode">colorScheme</span> for choropleth, <span class="incode">maxSize</span> for proportional symbols, etc.); but they share a few <em>classification</em> options: <span class="incode">classed</span>, <span class="incode">numClasses</span>, classification <span class="incode">method</span>, and <span class="incode">classBreaks</span>.  The classification <span class="incode">method</span> is currently limited to <a href="http://support.esri.com/en/knowledgebase/GISDictionary/term/quantile%20classification">quantiles</a> or <a href="http://support.esri.com/en/knowledgebase/GISDictionary/term/equal-interval%20classification">equal interval</a>, though any breaks can be applied by setting the <span class="incode">classBreaks</span> option.  Below I&#8217;ll just touch on the 5 thematic map types and the symbology options that can be applied to each.</p>
<h3>Symbologies</h3>
<h4>Choropleth</h4>
<p><img class="inimg" style="border: 1px solid grey" src="http://indiemaps.com/images/olSymbology/ol-choropleth.jpeg" alt="OL-Symbology choropleth" /></p>
<p><a href="http://en.wikipedia.org/wiki/Choropleth_map">Choropleth</a> is one of the most basic thematic mapping types, and was the first I programmed for this library.  To add a choropleth layer to your map, the only required options are the <span class="incode">indicator</span> and <span class="incode">url</span>:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> choroLayer = <span class="kw2">new</span> ol.<span class="me1">thematic</span>.<span class="me1">Choropleth</span><span class="br0">&#40;</span> map, <span class="br0">&#123;</span><br />
&nbsp; &nbsp;url &nbsp;&nbsp;: <span class="st0">'counties.json'</span>,<br />
&nbsp; &nbsp;indicator &nbsp; &nbsp;: <span class="st0">'unemployment'</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div></div>
<p>To create a more custom representation, the class includes many different symbology options:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">choroLayer = <span class="kw2">new</span> ol.<span class="me1">thematic</span>.<span class="me1">Choropleth</span><span class="br0">&#40;</span> map, <span class="br0">&#123;</span><br />
&nbsp; &nbsp; url &nbsp; &nbsp; &nbsp; &nbsp; : <span class="st0">'counties.json'</span>,<br />
&nbsp; &nbsp; indicator &nbsp; : <span class="st0">'unemployment'</span>,<br />
&nbsp; &nbsp; classed&nbsp;&nbsp;: <span class="kw2">true</span>,<br />
&nbsp; &nbsp; numClasses&nbsp; : <span class="nu0">6</span>,<br />
&nbsp; &nbsp; method &nbsp;&nbsp;: ol.<span class="me1">thematic</span>.<span class="me1">Distribution</span>.<span class="me1">CLASSIFY_BY_QUANTILE</span>,<br />
&nbsp; &nbsp; colorScheme : <span class="st0">'GnBu'</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div></div>
<p>The color scheme &#8220;GnBu&#8221; is the name of a <a href="http://colorbrewer2.org/">ColorBrewer</a> color scheme.  All of the ColorBrewer schemes are available just by referencing their reference name.  Alternatively users can set the <span class="incode">colors</span> property to any custom colors they&#8217;d like.</p>
<p>One property not shown above is the <span class="incode">colorStrokes</span> boolean.  If set to true, feature strokes will also be colored.  While this can be applied to polygonal features in a traditional choropleth map, it is perhaps most useful in applying a choropleth symbology to isolines or other linear features (see &#8220;multivariate symbologies&#8221; below).</p>
<p>Here&#8217;s an <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/choropleth.html">advanced example</a> that shows most of the options available in the <a href="https://github.com/indiemaps/OpenLayers-Symbology/blob/master/src/js/ol/thematic/ol.choropleth.js">Choropleth class</a>.</p>
<h4>Proportional Symbol</h4>
<p><img class="inimg" style="border: 1px solid grey" src="http://indiemaps.com/images/olSymbology/ol-propsymbol.jpeg" alt="OL-Symbology proportional symbols" /></p>
<p>Proportional symbols are another basic representation of a quantitative dataset, and can be created just as simply as choropleth layers (above).  As with all other symbologies, proportional symbols may be classed (graduated) or unclassed.  Symbols themselves can be circles, squares, or triangles; the correct area will be applied no matter what shape is chosen. Similar to the <span class="incode">colorStrokes</span> property of the Choropleth class, the ProportionalSymbol class includes a <span class="incode">sizeStrokes</span> option that allows feature strokes to be sized instead of feature areas.  This property is most useful in multivariate applications (for example, sizing the strokes of isolines to represent the value of each isarithm).</p>
<p>A unique feature of this library is that it allows for <a href="http://makingmaps.net/2007/08/28/perceptual-scaling-of-map-symbols/">perceptual scaling</a> of proportional symbol features.  Back in they heyday of psychophysical research in academic cartography, a lot of studies showed that map readers routinely underestimated the size of areal symbols.  To correct for this, symbols can be scaled up by an exponent derived from a power function designed to estimate the relationship between actual and perceived size of symbols.  For academics and other researchers interested in tweaking the power function exponent, this can be set with the <span class="incode">powerFunctionExponent</span> option (the default is the .8747 average derived from <a href="http://utpjournals.metapress.com/content/j6471776745h3667/">James Flannery&#8217;s touchstone 1971 study</a>).  Most users should just ignore perceptual scaling and use the mathematical default.</p>
<p>Perceptual scaling and other options are shown off in this <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/propSymbol.html">advanced example</a> of the <a href="https://github.com/indiemaps/OpenLayers-Symbology/blob/master/src/js/ol/thematic/ol.propsymbol.js">ProportionalSymbol class</a>.  </p>
<h4>Noncontiguous Cartogram</h4>
<p><img class="inimg" style="border: 1px solid grey" src="http://indiemaps.com/images/olSymbology/ol-cartogram.jpeg" alt="OL-Symbology noncontiguous cartogram" /></p>
<p>I&#8217;m kind of a fan of noncontiguous cartograms &#8212; I&#8217;ve written about them <a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/">here</a>, <a href="http://indiemaps.com/blog/2009/10/classed-cartograms/">here</a>, and <a href="http://indiemaps.com/blog/2011/02/noncontiguous-cartograms-in-openlayers-and-polymaps/">here</a>.  My noncontiguous cartogram class just extends the <span class="incode">ProportionalSymbol</span> class, so all options (besides shape; see above) for prop symbols are also available for cartograms (classification, perceptual scaling, etc.).</p>
<p>To see the <a href="https://github.com/indiemaps/OpenLayers-Symbology/blob/master/src/js/ol/thematic/ol.cartogram.js">Cartogram class</a> in action, check out <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/cartogram.html">this example</a>.  And as <a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/">before</a>, I created a <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/olson.html">reproduction of the iconic noncontiguous cartogram</a> from <a href="http://onlinelibrary.wiley.com/doi/10.1111/j.0033-0124.1976.00371.x/abstract">Judy Olson&#8217;s touchstone study of the form</a>.</p>
<h4>Dot Density</h4>
<p><img class="inimg" style="border: 1px solid grey" src="http://indiemaps.com/images/olSymbology/ol-dotdensity.jpeg" alt="OL-Symbology dot density" /></p>
<p>Another basic textbook thematic symbology is <a href="http://en.wikipedia.org/wiki/Dot_distribution_map">dot density</a>, in which dots are randomly scattered across polygons in numbers according to their indicator value.  The <span class="incode">dotValue</span> option controls the ratio of dots to indicator units, and thus the number of dots on the map.  The dot size (as well as dot shape) can be set on the <span class="incode">defaultSymbolizer</span> object &#8212; a style object that each symbology class has that controls non-data related styling properties of the representation.  View the source of <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/dotDensity.html">this example</a> for more.</p>
<p>You may notice that the dot density representation takes a while to process.  The basic strategy for creating a dot density layer is to figure out how many dots need to be placed for each polygonal feature, and then to place those dots randomly within the bounds of the features.  To accomplish this goal, dots are randomly placed within the <a href="http://en.wikipedia.org/wiki/Minimum_bounding_box">bounding box</a> of each feature and then tested to see if they actually lie within the feature.  Though this requires some processing, it doesn&#8217;t need to be as slow as the current implementation in this library.  It is slow only because I decided to use the built-in <a href="http://dev.openlayers.org/docs/files/OpenLayers/Geometry/Polygon-js.html#OpenLayers.Geometry.Polygon.containsPoint"><span class="incode">containsPoint</span></a> method of the <a href="http://dev.openlayers.org/docs/files/OpenLayers/Geometry/Polygon-js.html">OpenLayers Polygon geometry class</a>.  This point-in-polygon method requires that random points be tested one-at-a-time; a much faster strategy (the one Andy and I used when developing this symbology for <a href="http://indiemapper.com/">Indiemapper</a>) is to use a points-in-polygon test that can test many points at a time.  Eventually I&#8217;ll implement that method here but for now this class should work plenty fast with a small number of features and relatively high <span class="incode">dotValue</span>.</p>
<h4>Isolines</h4>
<p><img class="inimg" style="border: 1px solid grey" src="http://indiemaps.com/images/olSymbology/ol-isoline-weighted.jpeg" alt="OL-Symbology weighted isolines" /></p>
<p>Making your browser interpolate isolines is fun!  I first did these <a href="http://indiemaps.com/blog/2008/06/isolining-package-for-actionscript-3/">in ActionScript 3 back in 2008</a>.  This JavaScript version works essentially the same way: generating a <a href="http://en.wikipedia.org/wiki/Triangulated_irregular_network">triangulated irregular network</a> (TIN), interpolating isoline interval values along each triangle edge, and then connecting these interpolated points to form lines of constant value (isolines).  See my older post for more description of the basic method.  Check out <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/isoline.html">this simple example</a> of the OL-Symbology <a href="https://github.com/indiemaps/OpenLayers-Symbology/blob/master/src/js/ol/thematic/ol.isoline.js">Isoline class</a>.</p>
<p>The only options available to customize your isoline representation are <span class="incode">interval</span> (the distance in attribute space between lines) and <span class="incode">showTIN</span> (whether to show the triangulated irregular network used to interpolate the isolines).  As described in the next section, you can also apply choropleth and proportional symbologies to your isolines after creation.</p>
<h4>Multivariate symbologies</h4>
<p>These thematic mapping classes were written in such a way that they can be easily combined to form bivariate and trivariate representations.  Of course, this only makes sense with certain symbology combinations; and map readers are bad enough at interpreting univariate symbologies that increased complexity should rarely be attempted.  But for those rare cases, OL-Symbology can be used like so:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> choropleth;<br />
<span class="kw2">var</span> cartogram = <span class="kw2">new</span> ol.<span class="me1">thematic</span>.<span class="me1">Cartogram</span><span class="br0">&#40;</span> map, <span class="br0">&#123;</span><br />
&nbsp; &nbsp; url &nbsp; &nbsp; &nbsp; &nbsp; : url,<br />
&nbsp; &nbsp; indicator &nbsp; : indicator,<br />
&nbsp; &nbsp; requestSuccess &nbsp;&nbsp;: <span class="kw2">function</span><span class="br0">&#40;</span> request <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; choropleth = <span class="kw2">new</span> ol.<span class="me1">thematic</span>.<span class="me1">Choropleth</span><span class="br0">&#40;</span> map, <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; indicator : otherIndicator,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; layer : <span class="kw1">this</span>.<span class="me1">layer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div></div>
<p>That would create a noncontiguous cartogram and then color the features with a choropleth color scheme, accepting all defaults; <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/cartogram.choro.html">see the example</a>.  There are a few things to note in the above.  The <span class="incode">requestSuccess</span> method can be defined on any symbology object &#8212; it is called only once, when remote features have been loaded and processed.  The choropleth class is instantiated in the above without a <span class="incode">url</span> option &#8212; that is because the features have already been loaded from the remote URL.  Instead of defining the URL the <span class="incode">layer</span> option is set to the <span class="incode">layer</span> property of the cartogram representation.  Interestingly, the exact same representation would be created by reversing the order and first creating a choropleth representation, and then sizing the features using a cartogram representation.</p>
<p>The same strategy was used to create the <a href="http://indiemaps.com/images/olSymbology/ol-isolines.png">image</a> at the top of this post of colored isolines.  You can see a basic <a href="http://indiemaps.github.com/OpenLayers-Symbology/tests/coloredIsolines.html">colored isolines example here</a>.  Other possible symbology combinations include proportional symbol + choropleth, dot density + choropleth, isolines + proportional symbols, and proportional symbol + proportional symbol (where the 2nd instance of the ProportionalSymbol class would apply to the proportional symbols&#8217; strokes).</p>
<h3>Limitations and next steps</h3>
<p>When I presented this work last October, I also showed off a very similar library I&#8217;d written that works with <a href="http://polymaps.org/">Polymaps</a> instead of OpenLayers.  Those classes still need some work, and I&#8217;ll blog about them separately.  The OpenLayers version I&#8217;m presenting here is really pretty full-featured, including basic and advanced options for all symbologies.  This version is limited to OpenLayers, but the dependencies aren&#8217;t that deep so most of the code could be modified to work with another JavaScript mapping API.  </p>
<p>Most classes are decently fast, with dot density being the only one I&#8217;d hesitate to use in production; but I&#8217;ll add my own point-in-polygon method to the dot density class soon.  I hope the library is useful to at least a few others, either in pedagogical or production contexts.  And it&#8217;s <a href="https://github.com/indiemaps/OpenLayers-Symbology/blob/master/LICENSE.md">BSD licensed</a> so do whatever you want with it!</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2012/04/introducing-openlayers-symbology/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hexbins!</title>
		<link>http://indiemaps.com/blog/2011/10/hexbins/</link>
		<comments>http://indiemaps.com/blog/2011/10/hexbins/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 05:43:50 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[2d histogram]]></category>

		<category><![CDATA[aggregation]]></category>

		<category><![CDATA[binning]]></category>

		<category><![CDATA[bivariate]]></category>

		<category><![CDATA[charting]]></category>

		<category><![CDATA[d3.js]]></category>

		<category><![CDATA[data binning]]></category>

		<category><![CDATA[geometry]]></category>

		<category><![CDATA[hexagon]]></category>

		<category><![CDATA[hexbin]]></category>

		<category><![CDATA[histogram]]></category>

		<category><![CDATA[html5]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[maths]]></category>

		<category><![CDATA[multivariate]]></category>

		<category><![CDATA[plotting]]></category>

		<category><![CDATA[polymaps]]></category>

		<category><![CDATA[R]]></category>

		<category><![CDATA[scatterplot]]></category>

		<category><![CDATA[shape]]></category>

		<category><![CDATA[statistics]]></category>

		<category><![CDATA[svg]]></category>

		<category><![CDATA[symbology]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=135</guid>
		<description><![CDATA[
Binning is a general term for grouping a dataset of N values into less than N discrete groups.  These groups/bins may be spatial, temporal, or otherwise attribute-based.  In this post I&#8217;m only talking about spatial (long-lat) and 2-dimensional attribute-based (scatterplot) bins.  Such binnings may be thought of as 2D histograms.  This [...]]]></description>
			<content:encoded><![CDATA[<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/random_hex.png" alt="" width="525" height="526" /></div>
<p><a href="http://en.wikipedia.org/wiki/Data_binning">Binning</a> is a general term for grouping a dataset of <em>N</em> values into less than <em>N</em> discrete groups.  These groups/bins may be spatial, temporal, or <em>otherwise</em> attribute-based.  In this post I&#8217;m only talking about spatial (long-lat) and 2-dimensional attribute-based (scatterplot) bins.  Such binnings may be thought of as 2D histograms.  This may make more or less sense after what lies beneath.  </p>
<p>If you&#8217;re just after that sweet honey that is my code, bear down on my Github repository for this project &#8212; <a href="https://github.com/indiemaps/hexbin-js">hexbin-js</a>.</p>
<h3>Rectangular binning</h3>
<p>The simplest 2D <em>bin</em> is rectangular. Indeed, for most purposes rectangular bins suffice, and their computational simplicity is a significant advantage.</p>
<div class="centerIMG"><a href="http://jsfiddle.net/indiemaps/gzPDU/"><img class="alignnone" src="http://indiemaps.com/images/binning/rect_binning.png" alt="" width="637" height="321" /></a></div>
<p>The above is a shot from <a href="http://jsfiddle.net/indiemaps/gzPDU/">a little example</a> I produced on <a href="http://doc.jsfiddle.net/">jsFiddle</a>, while learning <a href="http://bost.ocks.org/mike/">Mike Bostock&#8217;s</a> fantastic <a href="http://mbostock.github.com/d3/">D3 JavaScript library</a> for HTML and SVG data-binding and visualization. The example demonstrates the need for and the technique of 2D rectangular binning and aggregation.  </p>
<p>Binning can be good for both the users and the creators/developers of static or interactive thematic maps or other visualizations. For the user, showing every single point can lead to cognitive overload, and may even be inaccurate, as overlapping points lead to a misreading of density.</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/overload.jpg" alt="" width="700" height="447" /></div>
<p>In the above image (from <a href="http://www.antaeus-data.com/concepts/sunflowerplot.html">Antaeus Concepts</a>) the data points are represented in black, and due to overlap the true concentration/density distribution is indiscernible from the graphic.</p>
<p>A binned representation may reveal patterns not readily seen in the raw point representation of the data (see <a href="http://www.antaeus-data.com/concepts/sunflowerplot.html">Antaeus&#8217; sunflower plot</a> for the same data below).  For the developer or cartographer, too, binning can present an advantage, chiefly in efficiency. Back in the day, manual cartographers probably weren&#8217;t too keen on drawing 10&#8217;s of 1000&#8217;s of data points &#8212; I&#8217;m guessing they&#8217;d rather do the cheap bin math so that they could then only draw 10&#8217;s or 100&#8217;s of uniformly-shaped bins to represent the same data.</p>
<p>Though we modern cartographers have fancy-fangled computers to draw our data points for us, even these beasts hiccup when asked to draw 10,000+ points at once.  Hiccups are acceptable in static rendering, but not in real-time apps that employ animation (as even at just 5 frames per second, rendering 1000s of points each frame would prove intensive for even newer home desktops).</p>
<p>So anyway, binned representations can be beneficial for both users and creators.  Below I&#8217;ll just describe one binning method (hexagon binning, or hexbinning), its implementation, and some examples.</p>
<h3>Hexagonal binning</h3>
<p>I first encountered hexagonal binning in the sweet 2006 O&#8217;Reilly book by Joseph Adler, <a href="http://books.google.com/books?id=51PS5G2Y2a4C&amp;lpg=PA191&amp;ots=3_5tXRi5Bq&amp;dq=baseball%20hacks%20hexagonal&amp;pg=PP1#v=onepage&amp;q&amp;f=false"><em>Baseball Hacks</em></a>.  Adler demonstrates the need for binning by showing a &#8220;spraychart&#8221; of David Ortiz&#8217;s 2003 balls-in-play.</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/baseball_hacks_spraychart.png" alt="" width="366" height="317" /></div>
<p>Adler writes,</p>
<blockquote><p>Clearly, you can see that David Ortiz tends to hit balls more often to right field.  Wouldn&#8217;t it be nice to have a cleaner way to see this density? We&#8217;ll use another visualization technique, called hexagonal binning, to get a clearer picture of where Ortiz&#8217;s hits land.</p>
<p>The idea of hexagonal binning is to break a two-dimensional plane into different bins.  First, the bins make interlocking hexagons.  It is possible to use squares (or interlocking triangles or another shape), but hexagons look &#8220;rounder&#8221; than squares.</p></blockquote>
<p>To turn his spraychart into hexbins, Adler used the <a href="http://cran.r-project.org/web/packages/hexbin/index.html">hexbin package</a> for R developed by Nicholas Lewin-Koh and Martin Maechler (inspired by Dan Carr&#8217;s work; more on this below).</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/baseball_hacks_hexbinning.png" alt="" width="362" height="238" /></div>
<p>Though unfortunately printed smaller in the book than the spraychart, I think the hexbin representation does effectively simplify the data while revealing patterns not easily retrieved from the full spraychart representation.</p>
<h4>Hex history and theory</h4>
<p>The technique of using interlocking hexagons to aggregate 2-dimensional data was first described in a 1987 paper by four Pacific Northwest Laboratory statisticians (D.B. Carr <em>et al</em>, <a href="http://www.jstor.org/pss/2289444">&#8220;Scatterplot Matrix Techniques for Large N&#8221;</a>).  The authors note, though, that they were inspired by another binning technique &#8212; sunflower plots &#8212; described a few years earlier by William Cleveland and Robert McGill.</p>
<p>Cleveland and McGill (1984, <a href="http://www.jstor.org/pss/2288711">&#8220;The Many Faces of a Scatterplot&#8221;</a>) didn&#8217;t mention hexagons; indeed they specified that squares be used to bin the data, with each bin then being tranformed into a &#8220;sunflower&#8221;, with each &#8220;petal&#8221; representing a datum within the bin:</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/cleveland_sunflowerPlot.png" alt="" width="499" height="495" /></div>
<p>In their later 1987 paper, D.B. Carr <em>et al</em> suggested that hexagon-bin-based sunflowers represented the data more faithfully than the rectangular-bin version.  They cite various reasons for this advantage, but I think it basically comes down to Joseph Adler&#8217;s later observation that &#8220;hexagons look rounder than squares&#8221;.  Indeed, a regular tessellation of a 2D surface is not possible with polygons of greater than six sides, making the hexagonal tessellation the most efficient and compact division of 2D data space.</p>
<p>Besides hexbin sunflower plots, D.B. Carr <em>et al</em> note two other possible symbologies to employ once the data have been successfully hex-binned.  To use thematic mapping parlance, the methods are proportional symbols and choropleth.  These symbologies and other possibilities are discussed below.</p>
<h4>Hexbin symbologies</h4>
<p>Hexbinning consists of 1) laying a hexagonal grid or lattice atop a 2-dimensional field of data and 2) determining data point counts for each hexagon.  This says nothing of the symbolization or representation method that can then be employed to communicate these counts to the graphic&#8217;s reader.</p>
<h5>Sunflower plots</h5>
<p>Sunflowers are likely the most complex symbology for representing hexbins, but I&#8217;m covering them first in this section because they actually inspired the hexbinning method itself.</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/sunflower_antaeus.jpg" alt="" width="661" height="490" /></div>
<p>The above screenshot is <a href="http://www.antaeus-data.com/concepts/sunflowerplot.html">from the Antaeus statistics project</a>, and hexagonal sunflower plots have also been <a href="http://www.stata.com/support/faqs/graphics/gph/graphdocs/dist11.html">implemented</a> within the popular <a href="http://www.stata.com/">Stata</a> statistics package:</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/stata_sunflowerPlot.png" alt="" width="442" height="344" /></div>
<p>Whether square-bin or hexbin-based, these sunflower plots are notable for allowing the user to simultaneously view generalities and retrieve specifics.  A higher number of &#8220;petals&#8221; leads to a darker hexagon, and clusters of such hexagons will reveal the overall trend of the data.  At the same time, individual petals can be counted to determine the exact number of data lying within each hexagonal bin.</p>
<h5>Proportional symbol</h5>
<p>The choropleth and proportional symbologies don&#8217;t really need any explanation here, so images should suffice.</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/carr_propHex.png" alt="" width="421" height="428" /></div>
<h5>Choropleth</h5>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/binning/chorohex.png" alt="" width="551" height="596" /></div>
<h5>Multivariate</h5>
<p>In a multivariate hexbin representation, the <em>secondary</em> variable  can be anything, though the sum or average of some attribute of the binned points within each hex would be typical.</p>
<p>In the below, a bivariate <em>symbology</em> is shown, though in this case the variable distribution represented by color value/saturation is the same as that represented by size (making this a redundant symbolization).</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.github.com/hexbin-js/images/redundant_hex.png" alt="" width="597" height="598" /></div>
<p>In addition to size and saturation/value, alpha (opacity) could also be used to represent a hex attribute (see the bottom of <a href="file:///Applications/MAMP/htdocs/hexbin-js/tests/hexComponent_test.html">this example page</a> for a value-by-alpha representation of density above a Google map).  </p>
<h4>Implementation</h4>
<p>As noted above, hexbins have been implemented in a few statistical packages, including <a href="http://cran.r-project.org/web/packages/hexbin/index.html">R</a>.  But I haven&#8217;t seen any other implementations, and certainly not a client-side one.  At first I tried to just port the R code, but it made no sense to me, and included many dependencies within R.  So I decided I&#8217;d have to roll my own.  Rolling my own seemed <em>really</em> hard, so luckily I ran into Alex Tingle&#8217;s <a href="http://libhex.firetree.net/">libhex</a> library.  Though certainly not designed for hex-binning (I believe it was made with game developers in mind), this great library has all the methods necessary to create a hexagonal lattice data structure.  And though written in C++, the author had completed an experimental JavaScript version.</p>
<p>It took some back-and-forth with libhex&#8217;s author <a href="http://www.firetree.net/calvino/alex/">Alex</a> to figure it out, but the library&#8217;s methods make it easy to create a hexagonal lattice or grid of a given size with specified hexagon size.  Once created, the <a href="http://libhex.firetree.net/classhex_1_1Grid.html#824bec0f4ee7a860e17661f7353a6757"><span class="incode">Grid.Hex</span> method</a> can be used to determine corresponding hexes for each 2D point in the dataset to be binned.  After this is achieved, we have a hexagonal lattice data structure, with each hex in the grid storing the points contained within its data space.</p>
<p>This creates the data structure, and performs the necessary binning routine for each point, but the library wasn&#8217;t meant to <em>render</em> anything.  I therefore paired it with my favorite data-driven visualization (or document-manipulation) library, <a href="http://mbostock.github.com/d3/">D3.js</a>.  The result is <a href="https://github.com/indiemaps/hexbin-js/blob/master/src/d3.hexbin.js">d3.hexbin.js</a>, which can be used like so:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> hexset = d3.<span class="me1">layout</span>.<span class="me1">hexbin</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">xValue</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span>d<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> d.<span class="me1">x</span>; <span class="br0">&#125;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">yValue</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span>d<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> d.<span class="me1">y</span>; <span class="br0">&#125;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">hexI</span><span class="br0">&#40;</span> hexI <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span> data <span class="br0">&#41;</span>;</div></div>
<p>The result <a href="https://github.com/indiemaps/hexbin-js/blob/master/src/d3.hexbin.js#L70">returned by <span class="incode">d3.layout.hexbin()</span></a> &#8212; <span class="incode">hexset</span> in the above &#8212; is simply an array of hex objects with important properties &#8212; notably <span class="incode">data</span> (the binned points for the particular hex) and <span class="incode">pointString</span> (a string representing the outline points of the hex). As far as symbolization, once the hexbinning routine is completed, representing the data with multiple symbologies is quite easy with D3.  The example <a href="http://indiemaps.github.com/hexbin-js/tests/hexComponent_test.html">posted here</a> shows off the exact same random data represented with dots, choropleth, proportional symbol, bivariate, and value-by-alpha symbologies.  The code below is used to render the frequency hexgrid as a choropleth.</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">d3.<span class="me1">select</span><span class="br0">&#40;</span> <span class="st0">&quot;div#choroplethHexgrid&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">append</span><span class="br0">&#40;</span> <span class="st0">&quot;svg:svg&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">append</span><span class="br0">&#40;</span> <span class="st0">&quot;svg:g&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">attr</span><span class="br0">&#40;</span> <span class="st0">&quot;class&quot;</span>, cbScheme + <span class="st0">&quot; stroke-true&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">selectAll</span><span class="br0">&#40;</span> <span class="st0">&quot;polygon&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">data</span><span class="br0">&#40;</span> hexset <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">enter</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">append</span><span class="br0">&#40;</span> <span class="st0">&quot;svg:polygon&quot;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">attr</span><span class="br0">&#40;</span> <span class="st0">&quot;class&quot;</span>, <span class="kw2">function</span><span class="br0">&#40;</span>d<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="st0">'q'</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + <span class="br0">&#40;</span> <span class="br0">&#40;</span>numClasses<span class="nu0">-1</span><span class="br0">&#41;</span> - scale<span class="br0">&#40;</span>d.<span class="me1">data</span>.<span class="me1">length</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + <span class="st0">&quot;-&quot;</span> + numClasses;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">attr</span><span class="br0">&#40;</span> <span class="st0">&quot;points&quot;</span>, <span class="kw2">function</span><span class="br0">&#40;</span>d<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> d.<span class="me1">pointString</span>; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div></div>
<p>All the code is stored in the <a href="https://github.com/indiemaps/hexbin-js/">hexbin-js</a> Github repository.  Please browse the <a href="https://github.com/indiemaps/hexbin-js/tree/master/src">src</a> and <a href="https://github.com/indiemaps/hexbin-js/tree/master/tests">tests</a> folders to see more of what&#8217;s going on here.</p>
<p>Because I&#8217;m a cartographer (or something), I wanted to create a geographic proof-of-concept for this method.  I came up with <a href="http://indiemaps.github.com/hexbin-js/tests/walmart.html">this</a>, combining my custom hexbin layout class with D3.js and <a href="http://polymaps.org/">Polymaps</a>.  The resultant interactive visualization shows an overview + focus view of all Walmarts in the USA.  Hexes can be moused over for a focus view.</p>
<div class="centerIMG"><a href="http://indiemaps.github.com/hexbin-js/tests/walmart.html"><img class="alignnone" src="http://indiemaps.github.com/hexbin-js/images/walMart_hex.png" alt="" width="900" height="447" /></a></div>
<p><span class="incode">d3.layout.hexbin</span> requires D3.js, though the dependencies don&#8217;t go that deep, so a few quick mods would allow you to use the hexbinning methods with any JavaScript mapping or graphics library.  Use as you will.  Many thanks to both Alex Tingle and Mike Bostock for answering my questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2011/10/hexbins/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dymaxion projection in OpenLayers</title>
		<link>http://indiemaps.com/blog/2011/04/dymaxion-projection-in-openlayers/</link>
		<comments>http://indiemaps.com/blog/2011/04/dymaxion-projection-in-openlayers/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 04:10:19 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[buckminster fuller]]></category>

		<category><![CDATA[dymaxion]]></category>

		<category><![CDATA[geometry]]></category>

		<category><![CDATA[icosahedron]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[kml]]></category>

		<category><![CDATA[openlayers]]></category>

		<category><![CDATA[projections]]></category>

		<category><![CDATA[protovis]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=129</guid>
		<description><![CDATA[
The great Buckminster Fuller created a series of Dymaxion maps utilizing various forms of his patented Fuller projection in the 1940s and 50s.  The most well-known, icosahedral form of the projection (above) was devised in Raleigh, North Carolina, in 1954.  Fuller intended the projection to better balance shape and areal distortion, while also [...]]]></description>
			<content:encoded><![CDATA[<div class="centerIMG"><img class="alignnone" src="http://www.bfi.org/sites/default/files/raleigh_0.jpg?1270682098" width="800" height="280" alt="" /></div>
<p>The great <a href="http://en.wikipedia.org/wiki/Buckminster_Fuller">Buckminster Fuller</a> created a series of <a href="http://www.bfi.org/about-bucky/buckys-big-ideas/dymaxion-world/dymaxion-map">Dymaxion maps</a> utilizing various forms of his <a href="http://www.genekeyes.com/FULLER/BF-4-1946.html">patented</a> Fuller projection in the 1940s and 50s.  The most well-known, <em>icosahedral</em> form of the projection (above) was <a href="http://www.bfi.org/slideshow-images/raleigh-edition-dymaxion-map">devised in Raleigh, North Carolina</a>, in 1954.  Fuller intended the projection to better balance shape and areal distortion, while also eschewing the north-south cultural bias he saw in common projections.</p>
<p>I&#8217;ve seen a few code implementations of Bucky&#8217;s design over the years, including the <a href="http://search.cpan.org/~sderle/Geo-Dymaxion-0.12/Dymaxion.pm">Perl scripts</a> Schuyler Erle wrote for his touchstone <a href="http://books.google.com/books?id=CiO5JtP171oC&#038;pg=PA148&#038;lpg=PA148&#038;dq=dymaxion+projection+code&#038;source=bl&#038;ots=V2WSSurTpz&#038;sig=H6VlmITkblc90eyzWf_NDHMkhB8&#038;hl=en&#038;ei=R0-jTZjsNNK1twen2cGAAw&#038;sa=X&#038;oi=book_result&#038;ct=result&#038;resnum=4&#038;ved=0CDMQ6AEwAw#v=onepage&#038;q=dymaxion%20projection%20code&#038;f=false"><em>Mapping Hacks</em></a>.  Erle&#8217;s modules were based on <a href="http://www.rwgrayprojects.com/rbfnotes/maps/graymap1.html">Robert Gray&#8217;s foundational work</a> in determining the appropriate transformation equations which were then incorporated into C source code.  But I hadn&#8217;t seen a client-side implementation until I saw <a href="http://vis.stanford.edu/protovis/ex/dymax.html">this map</a> in the <a href="http://vis.stanford.edu/protovis/ex/">examples section</a> of <a href="http://hci.stanford.edu/jheer/">Jeff Heer</a> and <a href="http://bost.ocks.org/">Mike Bostock</a>&#8217;s excellent JavaScript visualization framework <a href="http://vis.stanford.edu/protovis/">Protovis</a>.  In this post I just show how their <a href="http://vis.stanford.edu/protovis/ex/dymax.js">JavaScript Dymaxion code</a> can be brought into OpenLayers as a custom projection.</p>
<p>Since Buckminster Fuller, Robert Gray, and Mike Bostock have already done all the hard work, adding the projection to OpenLayers is a cinch.  But I think it&#8217;s worth showing here because there isn&#8217;t much info out there on using custom (that is, outside of <a href="http://trac.osgeo.org/proj/">PROJ.4</a>) projections in OpenLayers.  And I&#8217;d love to see more online slippy maps using such experimental projections.</p>
<h3>OpenLayers implementation</h3>
<p>Most web mapping frameworks only display data in the <a href="http://spatialreference.org/ref/sr-org/6864/">Web Mercator projection</a>.  This is basically because of a <a href="http://www.google.com/support/forum/p/maps/thread?tid=075eb10962e00cc5&#038;hl=en">decision Google made</a> six or seven years ago and because web mapping platforms have been used more for reference than thematic mapping.  OpenLayers is unique in allowing coordinate system transforms from any arbitrary projection to any other.  Of course, if you&#8217;re loading in Google or Bing tiles, you&#8217;ll have to stick to Web Mercator for any overlays; in this case OpenLayers will just be transforming your overlay data from lat/long to Mercator for display.  But if you&#8217;re using all vector data &#8212; from KML, GeoJSON, or many other <a href="http://docs.openlayers.org/library/formats.html">formats</a> &#8212; you can take advantage of OpenLayers&#8217; projection abilities.  And this is almost always going to involve the <a href="http://trac.osgeo.org/proj4js/">Proj4js library</a>, a port of PROJ.4.</p>
<p>Bjørn Sandvik <a href="http://blog.thematicmapping.org/2009/10/projecting-kml-with-openlayers-and.html">provides a great introduction</a> to projecting KML data with OpenLayers and Proj4js.  Proj4js contains most of your old favorites, like Lambert and Albers and Transverse Mercator.  But for custom projections like Dymaxion, OpenLayers includes the <span class="incode"><a href="http://dev.openlayers.org/releases/OpenLayers-2.6/doc/apidocs/files/OpenLayers/Projection-js.html#OpenLayers.Projection.addTransform">OpenLayers.Projection.addTransform</a></span> method, which I&#8217;m using like so:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">OpenLayers.<span class="me1">Projection</span>.<span class="me1">addTransform</span><span class="br0">&#40;</span> <span class="st0">&quot;EPSG:4326&quot;</span>, <span class="st0">&quot;DYMAX&quot;</span>, <br />
&nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span> point <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> converted = convert_s_t_p<span class="br0">&#40;</span> point.<span class="me1">x</span>, point.<span class="me1">y</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; point.<span class="me1">x</span> = converted.<span class="me1">x</span> * <span class="nu0">150</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; point.<span class="me1">y</span> = converted.<span class="me1">y</span> * <span class="nu0">150</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> point;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span> <br />
<span class="br0">&#41;</span>;</div></div>
<p><a href="http://spatialreference.org/ref/epsg/4326/">EPSG:4326</a> in the above method represents the standard WGS 84 lat/long coordinate system.  &#8220;DYMAX&#8221; is an arbitrary string that we&#8217;ll use whenever we want to apply the Dymaxion transformation.  The <span class="incode">convert_s_t_p</span> method is from the <a href="http://vis.stanford.edu/protovis/ex/dymax.js">dymax.js code</a> included with Protovis and does all the heavy lifting of converting lat/long points to Fuller x-y coordinates.  Notice I&#8217;m only defining the forward transformation &#8212; from lat/long to Fuller.  The inverse would be quite difficult but is luckily not necessary for projecting geodata onto a Dymaxion map.</p>
<p>To utilize the defined projection, then, we just have to instantiate an <span class="incode"><a href="http://dev.openlayers.org/releases/OpenLayers-2.6/doc/apidocs/files/OpenLayers/Projection-js.html">OpenLayers.Projection</a></span> object with our &#8220;DYMAX&#8221; projection identifier, and include this as an option when we create our OpenLayers map.</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> map = <span class="kw2">new</span> OpenLayers.<span class="me1">Map</span><span class="br0">&#40;</span><span class="st0">&quot;olmap&quot;</span>, <span class="br0">&#123;</span><br />
&nbsp; &nbsp; projection : <span class="kw2">new</span> OpenLayers.<span class="me1">Projection</span><span class="br0">&#40;</span> <span class="st0">&quot;DYMAX&quot;</span> <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; maxExtent : <span class="kw2">new</span> OpenLayers.<span class="me1">Bounds</span><span class="br0">&#40;</span> <span class="nu0">0</span>, <span class="nu0">0</span>, <span class="nu0">860</span>, <span class="nu0">400</span> <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; allOverlays : <span class="kw2">true</span><br />
<span class="br0">&#125;</span> <span class="br0">&#41;</span>;</div></div>
<p>Below&#8217;s an image linking to an example of the Protovis Dymaxion code being used within OpenLayers.  <em>View source</em> on that page to see the very little code that&#8217;s driving the example.  The triangles and world countries should load right away in the Fuller projection, but the 3000+ world cities may take a bit.</p>
<div class="centerIMG"><a href="http://indiemaps.com/projects/openlayers-dymaxion/examples/world_dymaxion.html"><img class="alignnone" width="900" height="543"  src="http://indiemaps.com/images/dymaxion/ol_dymaxion.png" alt="" /></a></div>
<h3>Next</h3>
<p>I&#8217;d be remiss if I didn&#8217;t mention Mike Migurski&#8217;s remarkable work on the <a href="http://mike.teczno.com/notes/slippy-faumaxion-II.html">&#8220;Faumaxion&#8221; projection</a>, which resulted in an experimental and <a href="http://teczno.com/faumaxion-II/">path-breaking interactive browser</a> that re-orients and re-configures its equilateral triangular coordinate system based on the map center and scale.  Ideally something similar would be possible using OpenLayers and the icosahedral geometry of the Dymaxion projection.  But that&#8217;s way ahead of me and this post.  Please see Mr. Migurski&#8217;s posts (<a href="http://mike.teczno.com/notes/dymaxion-oops.html">I</a>, <a href="http://mike.teczno.com/notes/faumaxion.html">II</a>, <a href="http://mike.teczno.com/notes/slippy-faumaxion.html">III</a>, and <a href="http://mike.teczno.com/notes/slippy-faumaxion-II.html">IV</a>) for more information on the Dymaxion transformation and Migurski&#8217;s reasons for switching to a <a href="http://mathworld.wolfram.com/GnomonicProjection.html">gnomonic projection</a> thanks in part to its extant and efficient inverse equation.</p>
<p>I just want to see more and more geographic projections available in web mapping frameworks.  An argument can certainly be made that no more than a handful of projections are necessary for the vast majority of reference and thematic mapping purposes.  But this leaves out certain artistic and political mapping pursuits that may benefit from more experimental projections like the Dymaxion.</p>
<p><a href="http://www.genekeyes.com/">Gene Keyes</a>, a Fuller devotee, has <a href="http://www.genekeyes.com/FULLER/BF-1-intro.html">declared</a> a similar but earlier <a href="http://en.wikipedia.org/wiki/Octahedron">octahedral</a> projection (below) by <a href="http://en.wikipedia.org/wiki/Bernard_J.S._Cahill">B.J.S. Cahill</a> superior to Fuller&#8217;s (h.t. <a href="http://www.maproomblog.com/2009/06/cahills_butterfly_map_vs_fullers_dymaxion_projection.php">the Map Room</a>).  So next I&#8217;d like to see about implementing Cahill&#8217;s <a href="http://www.genekeyes.com/Cahill-map-patent/Cahill-map-patent.html">also-patented</a> &#8220;butterfly&#8221; projection <em>for vector data</em> in JavaScript.  Both Fuller and Cahill are in a class of <a href="http://www.progonos.com/furuti/MapProj/Dither/ProjInt/projInt.html">interrupted projections</a> that are 1) especially difficult to implement for vector data because of section crossings and 2) potentially quite useful for mapping global datasets due to minimized shape/area distortion and the horizontalization of the classic world map projection&#8217;s north-south orientation.</p>
<div class="centerIMG"><img class="alignnone" src="http://indiemaps.com/images/dymaxion/cahill_butterfly.jpg" width="512" height="331" alt="" /></div>
<p>Much love to the <a href="http://www.bfi.org/">Buckminster Fuller Institute</a>, the current patent-holders of Fuller&#8217;s geographic transformations.  And again full credit must go to the Protovis people for their <a href="http://vis.stanford.edu/protovis/ex/dymax.js">client-side implementation of the Dymaxion/Fuller projection algorithm</a>.</p>
<div class="centerIMG"><img class="alignnone" width="900" height="479"  src="http://indiemaps.com/images/dymaxion/ol_dymaxion_zoomed.png" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2011/04/dymaxion-projection-in-openlayers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Noncontiguous cartograms in OpenLayers and Polymaps</title>
		<link>http://indiemaps.com/blog/2011/02/noncontiguous-cartograms-in-openlayers-and-polymaps/</link>
		<comments>http://indiemaps.com/blog/2011/02/noncontiguous-cartograms-in-openlayers-and-polymaps/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 23:24:30 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[area]]></category>

		<category><![CDATA[cartograms]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[geocommons]]></category>

		<category><![CDATA[geojson]]></category>

		<category><![CDATA[geometry]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[kml]]></category>

		<category><![CDATA[maths]]></category>

		<category><![CDATA[noncontiguous cartograms]]></category>

		<category><![CDATA[openlayers]]></category>

		<category><![CDATA[polymaps]]></category>

		<category><![CDATA[stamen]]></category>

		<category><![CDATA[svg]]></category>

		<category><![CDATA[symbology]]></category>

		<category><![CDATA[thematic mapping]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=130</guid>
		<description><![CDATA[I&#8217;m happy to be doing less Flash and more JavaScript development these days.  In particular, I&#8217;ve been investigating two open-source JavaScript web mapping platforms: one old, OpenLayers, and one new, Polymaps.
OpenLayers has been around a while, but still performs remarkably well as a slippy map framework while allowing easy thematic map customization. Polymaps is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to be doing less Flash and more JavaScript development these days.  In particular, I&#8217;ve been investigating two open-source JavaScript web mapping platforms: one old, <a href="http://openlayers.org/">OpenLayers</a>, and one new, <a href="http://polymaps.org/">Polymaps</a>.</p>
<p>OpenLayers has been around a while, but still performs remarkably well as a slippy map framework while allowing easy thematic map customization. Polymaps is brand new (from <a href="http://stamen.com/">Stamen</a> so you know it&#8217;s going to blow your mind), but is remarkable for enabling web standards-based thematic customization of geographic layers loaded via <a href="http://geojson.org/">GeoJSON</a> or KML onto &#8220;vector tiles that are rendered with SVG&#8221;.</p>
<p>In this post I show how either OpenLayers or Polymaps can be used to create dynamic and customizable noncontiguous cartograms with very little code.</p>
<h3>Idea</h3>
<div class="centerIMG"><img class="alignnone" width="750" height="468"  src="/images/noncontiguous2/cartogram_nyTimes.jpg" alt="NY Times noncontiguous cartogram example from 2007" /></div>
<p class="caption">The above is a cartogram of state electoral influence from 2007 <a href="http://www.nytimes.com/interactive/2008/11/02/opinion/20081102_OPCHART.html">by the <em>NY Times</em></a></p>
<p>I&#8217;ve <a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/">written about these gals before</a>.  The form involves resizing features (like states or countries) relative to the units&#8217; attribute values in a given field (often population).  Unlike the more common, contiguous form of the cartogram, noncontiguous cartograms don&#8217;t attempt to maintain <em>topology</em>, but are therefore free to maintain <em>shape</em> perfectly and experiment with <em>position</em>, as in the above example.</p>
<p>Here&#8217;s an example from <a href="http://onlinelibrary.wiley.com/doi/10.1111/j.0033-0124.1976.00371.x/abstract">Judy Olson&#8217;s original 1976 article</a> on this cartogram form.</p>
<div class="centerIMG"><img class="alignnone" src="/images/noncontiguous/olsonExample-reduced.png" alt="noncontiguous cartogram from Olson\" /></div>
<p>See <a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/">my older post</a> or Olson&#8217;s article for more info on the technique and the theory behind it.  Olson produced the above image semi-manually using a projector &#8212; each state was projected at a precise scaling factor and then traced.  Below I show how to do more or less the same thing, but with JavaScript and either OpenLayers or Polymaps.</p>
<h3>Implementation</h3>
<p>I wanted to be able to load in any polygonal geodata file (supported by the chosen web mapping framework) and resize the features based on any numerical attribute in order to form a noncontiguous cartogram.  The advantage of implementing this within a web mapping framework is obviously that additional data layers from various sources can easily be over or underlain.  </p>
<p>As a test and proof of concept for both frameworks, I wanted to reproduce Olson&#8217;s graphic (above) as best as I fairly easily could.  Olson used 1970 Census data to show the number of people aged 65+ by state; here I&#8217;m updating it with estimated 2009 data.  Specifically, I&#8217;ll be loading <a href="http://geocommons.com/overlays/55629">this Geocommons data layer</a> uploaded last year.</p>
<p>I&#8217;ve been working with OpenLayers for about half a year so I implemented cartograms there first.</p>
<h4>OpenLayers</h4>
<p>Implementing noncontiguous cartograms in OpenLayers is fairly straightforward, thanks to the helpful methods provided by this comprehensive framework.  The first step is loading the geodata.</p>
<h5>Load geodata</h5>
<p>OpenLayers makes loading geodata quite easy; the library can parse WKT, GML, KML, GeoJSON, GeoRSS, etc.  For all we&#8217;re gonna use the <a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/Vector-js.html"><span class="incode">Layer.Vector</span> class</a>.  In this case I&#8217;ll load in the KML version from Geocommons, and therefore OpenLayer&#8217;s <a href="http://dev.openlayers.org/docs/files/OpenLayers/Format/KML-js.html"><span class="incode">Format.KML</span> parser</a>.</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> kmlLayer = <span class="kw2">new</span> OpenLayers.<span class="me1">Layer</span>.<span class="me1">Vector</span><span class="br0">&#40;</span> <span class="st0">&quot;KML&quot;</span>, <span class="br0">&#123;</span><br />
&nbsp; &nbsp; projection : <span class="kw2">new</span> OpenLayers.<span class="me1">Projection</span><span class="br0">&#40;</span><span class="st0">&quot;EPSG:4326&quot;</span><span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; strategies: <span class="br0">&#91;</span> <span class="kw2">new</span> OpenLayers.<span class="me1">Strategy</span>.<span class="me1">Fixed</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#93;</span>,<br />
&nbsp; &nbsp; protocol: <span class="kw2">new</span> OpenLayers.<span class="me1">Protocol</span>.<span class="me1">HTTP</span><span class="br0">&#40;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; url: <span class="st0">&quot;http://geocommons.com/overlays/55629.kml&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; format: <span class="kw2">new</span> OpenLayers.<span class="me1">Format</span>.<span class="me1">KML</span><span class="br0">&#40;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; extractStyles: <span class="kw2">false</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; extractAttributes: <span class="kw2">true</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; maxDepth: <span class="nu0">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#41;</span>,<br />
&nbsp; &nbsp; style : <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'fillColor'</span> : <span class="st0">'#dddddd'</span>, <span class="st0">'fillOpacity'</span> : <span class="nu0">1</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">'strokeColor'</span> : <span class="st0">'#666666'</span>, <span class="st0">'strokeWidth'</span> : <span class="nu0">1</span> <br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span> <span class="br0">&#41;</span>;</div></div>
<p>Noncontiguous cartograms don&#8217;t require a geographic projection &#8212; regardless of the projection of the original linework the features can still be scaled up or down accurately to form the cartogram.  So the only reasons for projection are aesthetics and to enhance recognizability of features.  I&#8217;m unsure of what projection Olson used, but I just went for that old classic, <a href="http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html">Albers Equal Area</a>.  Specifically, I used <a href="http://proj4js.org/">Proj4js</a> and the following definition:</p>
<p><span class="incode">Proj4js.defs["MY_ALBERS"] = &#8220;+proj=aea +lat_1=32 +lat_2=58 +lat_0=45 +lon_0=-97 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs&#8221;;</span></p>
<p>To apply it, I just create a new <a href="http://dev.openlayers.org/releases/OpenLayers-2.6/doc/apidocs/files/OpenLayers/Projection-js.html"><span class="incode">OpenLayers.Projection</span></a> which gets <a href="http://dev.openlayers.org/docs/files/OpenLayers/Map-js.html#OpenLayers.Map.projection">applied to the map</a> when it&#8217;s instantiated.  <a href="http://blog.thematicmapping.org/2009/10/projecting-kml-with-openlayers-and.html">Thematicmapping.org has more info</a> on projections and OpenLayers.</p>
<p>Unless you already know the maximum value of whatever attribute you&#8217;re mapping, you&#8217;ll have to loop through them all once before you can loop through them again to scale.  Attributes are accessible via the <span class="incode"><a href="http://dev.openlayers.org/docs/files/OpenLayers/Feature/Vector-js.html#OpenLayers.Feature.Vector.attributes">attributes</a></span> property of each <span class="incode"><a href="http://dev.openlayers.org/docs/files/OpenLayers/Feature/Vector-js.html">OpenLayers.Feature.Vector</a></span> (accessible via the <span class="incode"><a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/Vector-js.html#OpenLayers.Layer.Vector.features">features</a></span> property of the <span class="incode"><a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/Vector-js.html">OpenLayers.Layer.Vector</a></span>).</p>
<h5>Scale features</h5>
<p>In order to scale a polygonal feature for a noncontiguous cartogram, we must know:</p>
<ol>
<li>the feature&#8217;s value for the chosen thematic attribute (see above)</li>
<li>the feature&#8217;s area and centroid as rendered
<p>
OpenLayers makes these easily accessible.  Each feature&#8217;s <span class="incode">geometry</span> object has <a href="http://dev.openlayers.org/docs/files/OpenLayers/Geometry-js.html#OpenLayers.Geometry.getArea"><span class="incode">getArea</span></a> and <a href="http://dev.openlayers.org/docs/files/OpenLayers/Geometry-js.html#OpenLayers.Geometry.getCentroid"><span class="incode">getCentroid</span></a> methods.  As far as I can tell, the <span class="incode">getCentroid</span> function returns the true polygonal center of mass, and not just the center of the feature&#8217;s bounding box.
</p>
</li>
<li>the feature&#8217;s desired area (in pixels) given the maximum area provided and the feature&#8217;s value as a percentage of the layer&#8217;s maximum value
<p><span class="incode">desiredArea = ( value / maxValue ) * maxArea;</span></p>
</li>
<li>finally, the feature&#8217;s scale which is just a function of its original and desired area
<p>
<span class="incode">desiredScale = Math.sqrt( desiredArea / originalArea );</span></p>
<p>This scale is then applied via the <a href="http://dev.openlayers.org/apidocs/files/OpenLayers/Geometry/Collection-js.html#OpenLayers.Geometry.Collection.resize"><span class="incode">resize</span></a> method of each feature&#8217;s geometry.</p>
<p><span class="incode">feature.geometry.resize( desiredScale, centroid );</span>
</p>
</li>
</ol>
<h5>Result</h5>
<p>Here&#8217;s an image from the example you can find on <a href="http://indiemaps.com/projects/noncontiguous/openlayers/examples/olson_OpenLayers.html">this page</a>.  All source can just be accessed from there.  </p>
<div class="centerIMG"><img class="alignnone" src="/images/noncontiguous2/olson_OpenLayers.png" alt="noncontiguous cartogram from Olson redrawn in OpenLayers" /></div>
<p>Hey, that looks pretty great.  Michigan&#8217;s kinda off-center, but I believe that&#8217;s because the polygon is only defined by one ring of coordinates, though it should be a multipolygon.  Perhaps more noticeable is the overlap in the Northeast.  In Judy Olson&#8217;s original example, states were blown up by a visual projector and then traced.  But the projector could be aimed before tracing, thus avoiding overlap.  In this case I simply scale the states and keep them at their original centroids.  </p>
<p>I could avoid overlap by determining appropriate positioning and setting this within OpenLayers (but overlap would be very difficult to determine and then address dynamically) or by significantly reducing the configurable maximum area allowable on the resultant cartogram (but in order to be sure you&#8217;re preventing overlap features would have to be scaled quite small, which would detract from the readability of the cartogram).</p>
<h4>Polymaps</h4>
<p>Polymaps is a fairly new JavaScript mapping library by Stamen and <a href="http://simplegeo.com/">SimpleGeo</a>.  <a href="http://blog.fortiusone.com/2010/11/17/introducing-polymaps-to-geocommons/">Geocommons recently introduced</a> Polymaps to their online mapping service, creating a quite powerful Flash-free online thematic mapping tool.  Creating noncontiguous cartograms in Polymaps was a bit tougher than the process detailed above, just because the library is so light-weight.</p>
<h5>Load geodata</h5>
<p>The first step is quite easy.  As far as vector geodata formats, Polymaps only has built-in support for <a href="http://polymaps.org/docs/geoJson.html">GeoJSON</a>, though they do provide a <a href="https://github.com/simplegeo/polymaps/tree/master/examples/kml">KML example</a> that takes advantage of an optional <span class="incode">fetch</span> method <a href="http://polymaps.org/docs/geoJson.html#url">specified in the GeoJSON layer constructor</a>.  </p>
<p>But I&#8217;ll just go with GeoJSON for this one.  I found out in <a href="http://developer.geoiq.com/blog/2010/12/08/integrating-geocommons-datasets-with-polymaps/">this post from GeoIQ</a> that I can access a GeoJSON version of features in any Geocommons dataset by going to the &#8220;features.json&#8221; endpoint.  So for my 2009 estimated census dataset I&#8217;ll be loading in <span class="incode">http://geocommons.com/overlays/55629/features.json?geojson=1</span> using the following simple method:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">var</span> url = <span class="st0">&quot;http://geocommons.com/overlays/55629/features.json?geojson=1&quot;</span>;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
map.<span class="me1">add</span><span class="br0">&#40;</span>po.<span class="me1">geoJson</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">url</span><span class="br0">&#40;</span>url<span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">on</span><span class="br0">&#40;</span><span class="st0">&quot;load&quot;</span>, load<span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">tile</span><span class="br0">&#40;</span> <span class="kw2">false</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; .<span class="me1">id</span><span class="br0">&#40;</span><span class="st0">&quot;states&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div></div>
<p>Note that loading directly from Geocommons only works while developing locally because of cross-domain policy.  So in my <a href="http://indiemaps.com/projects/noncontiguous/polymaps/examples/olson_Polymaps.html">finished example</a> I end up loading a <a href="http://indiemaps.com/projects/noncontiguous/data/55629.kml">local version of the JSON</a>.</p>
<p>Polymaps is limited to the <a href="http://spatialreference.org/ref/sr-org/45/">Web Mercator projection</a> for display, but we can still produce a passable reproduction of Olson&#8217;s original.</p>
<p>As in the OpenLayers example above, unless you already know the maximum value of your attribute, you&#8217;ll need to first loop through the features to determine it.  In the above code, you can see I&#8217;m using the layer&#8217;s <a href="http://polymaps.org/docs/dispatch.html#on"><span class="incode">on</span></a> method to listen for the &#8220;load&#8221; event.  And in there I can get my features off the event object&#8217;s <span class="incode">features</span> property.  Attributes are stored on each feature&#8217;s <span class="incode">data.properties</span> property.</p>
<h5>Scale features</h5>
<p>To scale each feature we must first know it&#8217;s value in the chosen attribute (see above).  Then we need to determine it&#8217;s current area (in pixels) in order to figure the feature&#8217;s desired area on the eventual cartogram.  OpenLayers provides a <a href="http://dev.openlayers.org/docs/files/OpenLayers/Geometry-js.html#OpenLayers.Geometry.getArea">convenient method</a> for this but in Polymaps we have to roll our own; for this <a href="http://bost.ocks.org/mike/">Mike Bostock</a> (one of the primary authors of Polymaps) was of much help.  To calculate the area of each feature I just needed access to the list of projected coordinates (then I could employ the basic technique <a href="http://paulbourke.net/geometry/polyarea/">detailed here</a>).  Mr. Bostock pointed me to the <a href="http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegList"><span class="incode">pathSegList</span></a> property of the <a href="http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathElement"><span class="incode">SVGPathElement</span></a> interface.  The <span class="incode">pathSegList</span> exposes a list of path segments with the <a href="http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSeg"><span class="incode">SVGPathSeg</span></a> interface.  Mike said I could count on these segments being one of types &#8220;M&#8221; (move to), &#8220;L&#8221; (line to), or &#8220;Z&#8221; (end line).  With this information I quickly put together a method that should return the projected area of any <a href="http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegList"><span class="incode">SVGPathElement</span></a> that Polymaps may produce.</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">function</span> getPathArea<span class="br0">&#40;</span> segList <span class="br0">&#41;</span> <br />
<span class="br0">&#123;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw2">var</span> area = <span class="nu0">0</span>;<br />
&nbsp; &nbsp; <span class="kw2">var</span> seg1, seg2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw2">var</span> nPts = segList.<span class="me1">numberOfItems</span>;<br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="co1">// let's see if the last item is a 'Z' (it should be)</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> lastLetter = <br />
&nbsp; &nbsp; &nbsp; &nbsp; segList.<span class="me1">getItem</span><span class="br0">&#40;</span> nPts - <span class="nu0">1</span> <span class="br0">&#41;</span>.<span class="me1">pathSegTypeAsLetter</span>;<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> lastLetter.<span class="me1">toLowerCase</span><span class="br0">&#40;</span><span class="br0">&#41;</span> == <span class="st0">'z'</span> <span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; nPts --;<br />
&nbsp; &nbsp; <span class="kw2">var</span> j = nPts - <span class="nu0">1</span>;<br />
&nbsp; &nbsp; segItem_list:<br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> i = <span class="nu0">0</span>; i &lt; nPts; j=i++ <span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; seg1 = segList.<span class="me1">getItem</span><span class="br0">&#40;</span> i <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; seg2 = segList.<span class="me1">getItem</span><span class="br0">&#40;</span> j <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; area += seg1.<span class="me1">x</span> * seg2.<span class="me1">y</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; area -= seg1.<span class="me1">y</span> * seg2.<span class="me1">x</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; area /= <span class="nu0">2</span>;<br />
&nbsp; &nbsp; <span class="kw1">return</span> Math.<span class="me1">abs</span><span class="br0">&#40;</span> area <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div></div>
<p>I could easily create a similar centroid method, but I got lazy and decided to just use the center of each feature&#8217;s bounding box (accessible via each feature SVG element&#8217;s <span class="incode">getBBox</span> method).</p>
<p>The desired area and scale are calculated just as we did above in OpenLayers:</p>
<p><span class="incode">desiredArea = ( value / maxValue ) * maxArea;</span><br />
<span class="incode">desiredScale = Math.sqrt( desiredArea / originalArea );</span></p>
<p>The scale is then applied via the <a href="http://www.w3.org/TR/SVG/coords.html#TransformAttribute">&#8216;transform&#8217; attribute</a> of each SVG element; both scale and x-y translation must be defined in the &#8216;transform&#8217; attribute:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">feature.<span class="me1">element</span>.<span class="me1">setAttribute</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;transform&quot;</span>, <br />
&nbsp; &nbsp; <span class="st0">&quot;scale(&quot;</span> + scale + <span class="st0">&quot; &quot;</span> + scale + <span class="st0">&quot;)&quot;</span> + <span class="st0">&quot; &quot;</span> + &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="st0">&quot;translate(&quot;</span> + <br />
&nbsp; &nbsp; &nbsp; &nbsp; -<span class="br0">&#40;</span> <span class="br0">&#40;</span> centerX * scale - centerX <span class="br0">&#41;</span> / scale <span class="br0">&#41;</span> + <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot; &quot;</span> + <br />
&nbsp; &nbsp; &nbsp; &nbsp; -<span class="br0">&#40;</span> <span class="br0">&#40;</span> centerY * scale - centerY <span class="br0">&#41;</span> / scale <span class="br0">&#41;</span> + <br />
&nbsp; &nbsp; <span class="st0">&quot;)&quot;</span><br />
<span class="br0">&#41;</span>;</div></div>
<h5>Result</h5>
<p>As before, here&#8217;s an image captured from the example you can find on <a href="http://indiemaps.com/projects/noncontiguous/polymaps/examples/olson_Polymaps.html">this page</a>.  You&#8217;ll see a bit of the code there, but please &#8216;view source&#8217; to see all the code and markup.</p>
<div class="centerIMG"><img class="alignnone" src="/images/noncontiguous2/olson_Polymaps.png" alt="noncontiguous cartogram from Olson redrawn in OpenLayers" /></div>
<p>Aside from the necessary difference of projection, the main thing that stands out is the overlap in the Northeast.  I discussed possible ways to avoid this in the OpenLayers example above.</p>
<h3>Conclusion</h3>
<p>Nothing here is new.  I&#8217;ve been doing this in Flash for a while &#8212; see <a href="http://indiemaps.com/blog/2008/12/noncontiguous-area-cartograms/">here</a> and <a href="http://indiemaps.com/blog/2009/01/political-cartography-voting-with-our-pocketbooks/">here</a>; and of course Judy Olson was doing it some 35 years ago.  But it&#8217;s nice to see it working dynamically in a couple of open source, web standards-compliant libraries.  Thanks to OpenLayers, Polymaps, and Geocommmons for making it possible!</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2011/02/noncontiguous-cartograms-in-openlayers-and-polymaps/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Interactive mapping with HTML5, JavaScript, and Canvas</title>
		<link>http://indiemaps.com/blog/2010/06/interactive-mapping-with-html5-javascript-and-canvas/</link>
		<comments>http://indiemaps.com/blog/2010/06/interactive-mapping-with-html5-javascript-and-canvas/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 06:13:01 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[canvas]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[flash]]></category>

		<category><![CDATA[howto]]></category>

		<category><![CDATA[html5]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[jquery]]></category>

		<category><![CDATA[kml]]></category>

		<category><![CDATA[mapping]]></category>

		<category><![CDATA[proj4]]></category>

		<category><![CDATA[projections]]></category>

		<category><![CDATA[w3c]]></category>

		<category><![CDATA[web standards]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=116</guid>
		<description><![CDATA[Part 1: Loading, projecting, and drawing geodata
I&#8217;m getting into more canvas and JavaScript for interactive mapping.  Much of the Flash/ActionScript work I&#8217;ve written or come to rely upon is directly portable to JS/canvas.  What&#8217;s missing is a sweet RIA framework and IDE for the kind of development Flash and Flex have made possible [...]]]></description>
			<content:encoded><![CDATA[<p><strong><em>Part 1: Loading, projecting, and drawing geodata</em></strong></p>
<p>I&#8217;m getting into more <a href="http://dev.w3.org/html5/spec/Overview.html"><span class="incode">canvas</span></a> and JavaScript for interactive mapping.  Much of the Flash/ActionScript work I&#8217;ve written or come to rely upon is directly portable to JS/<span class="incode">canvas</span>.  What&#8217;s missing is a sweet RIA framework and IDE for the kind of development Flash and Flex have made possible for years.  </p>
<p>Luckily it&#8217;s not hard to roll our own interactive web map using web standard technologies.  In this post I&#8217;m just showing off the basics: dynamically loading geodata, projecting it client-side, and rendering to the <span class="incode">canvas</span> element.</p>
<div id="html5" title="africanCountries"></div>
<p>Hopefully the above map shows up for you.  It&#8217;s <a href="http://www.codediesel.com/wordpress/adding-html5-canvas-element-to-wordpress/">loaded into this blog post</a> with dynamic KML data, projected using the <a href="http://proj4js.org/">Proj4js library</a>, and drawn onto HTML&#8217;s <span class="incode">canvas</span> element using JavaScript.  You can check out <a href="http://indiemaps.com/projects/CanvasMap/index.html">the P.O.C. on a separate page</a>.</p>
<h3>Loading geographic data</h3>
<p>It all starts with data.  Points, polylines, or polygons &#8212; typically defined by latitude/longitude coordinates.  Your data may be in a CSV file or in a database.  For a simple interactive web map it&#8217;s best if it&#8217;s in a common GIS file format, like the <a href="http://en.wikipedia.org/wiki/Shapefile">Shapefile</a> or <a href="http://code.google.com/apis/kml/documentation/">KML</a>.</p>
<p>These days, it&#8217;s not too hard to load a geographic layer on top of a web map &#8212; using <a href="http://code.google.com/apis/kml/documentation/mapsSupport.html">Google Maps</a> or <a href="http://openlayers.org/">OpenLayers</a>, say.  But since we&#8217;re looking down the road to interactivity, custom projections, and thematic mapping, it&#8217;s best to roll our own.  Luckily, getting the data in is pretty easy.</p>
<p>In ActionScript I would use <a href="http://code.google.com/p/vanrijkom-flashlibs/wiki/SHP">Edwin van Rijkom&#8217;s ESRI SHP parser</a>, my own <a href="http://indiemaps.com/blog/2009/02/e00parser-an-actionscript-3-parser-for-the-arcinfo-export-topological-gis-format/">E00 parser</a>, or some simple custom methods I&#8217;ve written to load in KML documents.  <a href="http://stamen.com/studio/tom">Tom Carden of Stamen</a> has done some great work <a href="http://github.com/RandomEtc/shapefile-js">porting the AS3 SHP library to JavaScript</a>, with additional classes and methods to allow basic layering, panning, and zooming.</p>
<p>Carden&#8217;s classes are great; for demo purposes, and to keep this as lightweight as possible, I&#8217;ve just written a quick JavaScript method to grab what I need from a KML document:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">$.<span class="me1">get</span><span class="br0">&#40;</span> <span class="st0">&quot;data/kml/generalized_african_countries.kml&quot;</span>, <span class="kw2">function</span><span class="br0">&#40;</span> xml <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> features = <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; $<span class="br0">&#40;</span> xml <span class="br0">&#41;</span>.<span class="me1">find</span><span class="br0">&#40;</span> <span class="st0">'Placemark'</span> <span class="br0">&#41;</span>.<span class="me1">each</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> rings = <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span class="br0">&#40;</span> <span class="kw1">this</span> <span class="br0">&#41;</span>.<span class="me1">find</span><span class="br0">&#40;</span> <span class="st0">'outerBoundaryIs'</span> <span class="br0">&#41;</span>.<span class="me1">each</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> ring = <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> coordsText = $<span class="br0">&#40;</span> <span class="kw1">this</span> <span class="br0">&#41;</span>.<span class="me1">find</span><span class="br0">&#40;</span> <span class="st0">'coordinates'</span> <span class="br0">&#41;</span>.<span class="me1">text</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> coordStrings = coordsText.<span class="me1">split</span><span class="br0">&#40;</span> <span class="st0">' '</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> coordText <span class="kw1">in</span> coordStrings <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> coordinate = <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> coordSplit = coordStrings<span class="br0">&#91;</span> coordText <span class="br0">&#93;</span>.<span class="me1">split</span><span class="br0">&#40;</span> <span class="st0">','</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> coordInd <span class="kw1">in</span> coordSplit <span class="br0">&#41;</span> coordinate.<span class="me1">push</span><span class="br0">&#40;</span> Number<span class="br0">&#40;</span> coordSplit<span class="br0">&#91;</span> coordInd <span class="br0">&#93;</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ring.<span class="me1">push</span><span class="br0">&#40;</span> coordinate <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rings.<span class="me1">push</span><span class="br0">&#40;</span> ring <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; features.<span class="me1">push</span><span class="br0">&#40;</span> rings <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="coMULTI">/* feature coordinates all loaded -- now do something with them */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
<span class="br0">&#125;</span> <span class="br0">&#41;</span>;</div></div>
<p>You&#8217;ll notice a bit of <a href="http://jquery.com/">jQuery</a> in there.  And you&#8217;ll also notice that it grabs only coordinate data and works only for polygons.  But it produces an array of feature coordinates, which is an array of ring coordinates, which is an array of lat/long coordinates, which is all we need for the current application.</p>
<h3>Projecting geographic data</h3>
<p>One of my biggest beefs with the typical online map providers is that they&#8217;re all rendered in a <a href="http://en.wikipedia.org/wiki/Mercator_projection">Mercator projection</a>.  No problem for most purposes (and great for producing those 90 degree road intersections), but not so great for country-level mapping and bad for many thematic mapping pursuits. That&#8217;s one reason we&#8217;re rolling our own here.  </p>
<p><a href="http://trac.osgeo.org/proj/">PROJ.4</a> is a generally sweet projections library, originally written in C by Gerald Evenden then of the USGS. It&#8217;s been ported to JavaScript as <a href="http://trac.osgeo.org/proj4js/">Proj4js</a>.  To use it you just have to define <span class="incode">source</span> and a <span class="incode">dest</span> objects:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;">Proj4js.<span class="me1">defs</span><span class="br0">&#91;</span> <span class="st0">'albersEqualArea_Africa'</span> <span class="br0">&#93;</span> = <span class="st0">'+title= albers_AFR<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +proj=aea<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +lat_1=20<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +lat_2=-23<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +lat_0=0<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +lon_0=25<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +x_0=0<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +y_0=0<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +ellps=WGS84<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +datum=WGS84<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +units=m<span class="es0">\</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +no_defs'</span>;<br />
<span class="kw2">var</span> source = <span class="kw2">new</span> Proj4js.<span class="me1">Proj</span><span class="br0">&#40;</span> <span class="st0">'WGS:84'</span> <span class="br0">&#41;</span>;<br />
<span class="kw2">var</span> dest = <span class="kw2">new</span> Proj4js.<span class="me1">Proj</span><span class="br0">&#40;</span> <span class="st0">'albersEqualArea_Africa'</span> <span class="br0">&#41;</span>;</div></div>
<p>And thereafter you can call</p>
<div class="codecolorer-container javascript" style="height:20px;"><div class="codecolorer" style="font-family: monospace;">Proj4js.<span class="me1">transform</span><span class="br0">&#40;</span> source, dest, pt <span class="br0">&#41;</span>;</div></div>
<p>where <span class="incode">pt</span> is any object with <span class="incode">x</span> and <span class="incode">y</span> properties.  So all coordinates gathered from the KML above can be run through the <span class="incode">Proj4js.transform()</span> method, in this case applying a custom <a href="http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html">Albers Equal Area projection</a> (<span class="incode">proj=aea</span>) for the African continent.</p>
<h3>Drawing geographic data on the <span class="incode">canvas</span> element</h3>
<p>The results of the above can be easily rendered to HTML&#8217;s <span class="incode">canvas</span> element using JavaScript.  I&#8217;m used to <a href="http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/Graphics.html">ActionScript&#8217;s Graphics class</a>, and its assorted vector drawing methods.  Of course, given the common <a href="http://en.wikipedia.org/wiki/ECMAScript">ECMAScript</a> heritage, the JS methods are nearly identical.  So the projected linework is rendered thusly:</p>
<div class="codecolorer-container javascript"><div class="codecolorer" style="font-family: monospace;"><span class="kw2">function</span> drawPolygonFeatures<span class="br0">&#40;</span> features, minX, maxX, minY, maxY <span class="br0">&#41;</span> <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> c_canvas = document.<span class="me1">getElementById</span><span class="br0">&#40;</span> <span class="st0">&quot;map&quot;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw2">var</span> context = c_canvas.<span class="me1">getContext</span><span class="br0">&#40;</span><span class="st0">&quot;2d&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw2">var</span> multiFactor = Math.<span class="me1">min</span><span class="br0">&#40;</span> c_canvas.<span class="me1">width</span> <span class="re0">/ <span class="br0">&#40;</span> maxX - minX <span class="br0">&#41;</span>, c_canvas.<span class="me1">height</span> /</span> <span class="br0">&#40;</span> maxY - minY <span class="br0">&#41;</span> <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw2">var</span> x = <span class="nu0">0</span>; <span class="kw2">var</span> y = <span class="nu0">0</span>;<br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> featureNum <span class="kw1">in</span> features <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> ringNum <span class="kw1">in</span> features<span class="br0">&#91;</span> featureNum <span class="br0">&#93;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> ring = features<span class="br0">&#91;</span> featureNum <span class="br0">&#93;</span><span class="br0">&#91;</span> ringNum <span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">moveTo</span><span class="br0">&#40;</span> <span class="br0">&#40;</span> ring<span class="br0">&#91;</span> <span class="nu0">0</span> <span class="br0">&#93;</span><span class="br0">&#91;</span> <span class="nu0">0</span> <span class="br0">&#93;</span> - minX <span class="br0">&#41;</span> * multiFactor, c_canvas.<span class="me1">height</span> - <span class="br0">&#40;</span> ring<span class="br0">&#91;</span> <span class="nu0">0</span> <span class="br0">&#93;</span><span class="br0">&#91;</span> <span class="nu0">1</span> <span class="br0">&#93;</span> - minY <span class="br0">&#41;</span> * multiFactor <span class="br0">&#41;</span>;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span> <span class="kw2">var</span> coordNum = <span class="nu0">1</span>; coordNum &lt; ring.<span class="me1">length</span>; coordNum++ <span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = <span class="br0">&#40;</span> ring<span class="br0">&#91;</span> coordNum <span class="br0">&#93;</span><span class="br0">&#91;</span> <span class="nu0">0</span> <span class="br0">&#93;</span> - minX <span class="br0">&#41;</span> * multiFactor;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = c_canvas.<span class="me1">height</span> - <span class="br0">&#40;</span> ring<span class="br0">&#91;</span> coordNum <span class="br0">&#93;</span><span class="br0">&#91;</span> <span class="nu0">1</span> <span class="br0">&#93;</span> - minY <span class="br0">&#41;</span> * multiFactor;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.<span class="me1">lineTo</span><span class="br0">&#40;</span> x, y <span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; context.<span class="me1">shadowOffsetX</span> = context.<span class="me1">shadowOffsetY</span> = <span class="nu0">3</span>;<br />
&nbsp; &nbsp; context.<span class="me1">shadowBlur</span>&nbsp; &nbsp; = <span class="nu0">4</span>;<br />
&nbsp; &nbsp; context.<span class="me1">shadowColor</span>&nbsp; &nbsp;= <span class="st0">'rgba(0, 0, 0, 0.5)'</span>;<br />
&nbsp; &nbsp; context.<span class="me1">fillStyle</span> = <span class="st0">&quot;#0099cc&quot;</span>;<br />
&nbsp; &nbsp; context.<span class="me1">fill</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; context.<span class="me1">shadowOffsetX</span> = context.<span class="me1">shadowOffsetY</span> = context.<span class="me1">shadowBlur</span> = <span class="nu0">0</span>;<br />
&nbsp; &nbsp; context.<span class="me1">strokeStyle</span> = <span class="st0">&quot;#fff&quot;</span>;<br />
&nbsp; &nbsp; context.<span class="me1">stroke</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div></div>
<p>That method&#8217;s made a bit longer by that bitchin&#8217; drop shadow (sorry Firefox, but you <a href="http://www.konqueror.org/">Konqueror</a> folks should be cool).  See above, or the <a href="http://indiemaps.com/projects/CanvasMap/index.html">P.O.C. on a separate page</a>.</p>
<h3>Up next</h3>
<p>So far this has been pretty sweet: we&#8217;ve loaded coordinate data dynamically, projected it, and drawn it to the <span class="incode">canvas</span> element.  But it hasn&#8217;t exactly lived up to the &#8220;interactive&#8221; part of the title.  Next time I hope to get going on panning and zooming, feature mouse-over, and perhaps even attribute loading and thematic mapping.</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2010/06/interactive-mapping-with-html5-javascript-and-canvas/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RIP Jacques Bertin</title>
		<link>http://indiemaps.com/blog/2010/05/rip-jacques-bertin/</link>
		<comments>http://indiemaps.com/blog/2010/05/rip-jacques-bertin/#comments</comments>
		<pubDate>Wed, 19 May 2010 02:10:04 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[academia]]></category>

		<category><![CDATA[cartographer]]></category>

		<category><![CDATA[french]]></category>

		<category><![CDATA[graphic design]]></category>

		<category><![CDATA[graphics]]></category>

		<category><![CDATA[information design]]></category>

		<category><![CDATA[jacques bertin]]></category>

		<category><![CDATA[person]]></category>

		<category><![CDATA[rip]]></category>

		<category><![CDATA[semiology of graphics]]></category>

		<category><![CDATA[visual variables]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=115</guid>
		<description><![CDATA[
French cartographer Jacques Bertin died in Paris on May 3rd.  This news has been out on a few English-language lists, but I otherwise hadn&#8217;t seen it mentioned, so thought I&#8217;d note it here.  Bertin&#8217;s Semiologie and seven visual variables greatly influenced cartographic and graphic design theory and education over the last 40 years. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/kbean/491051226/" title="jacques bertin by pavilion tone, on Flickr"><img src="http://farm1.static.flickr.com/208/491051226_46a122ee3d.jpg" width="286" height="400" alt="jacques bertin" /></a></p>
<p>French cartographer <a href="http://en.wikipedia.org/wiki/Jacques_Bertin">Jacques Bertin</a> died in Paris on May 3rd.  This <a href="http://www.cartotalk.com/index.php?showtopic=5722">news</a> has been out on a few English-language lists, but I otherwise hadn&#8217;t seen it mentioned, so thought I&#8217;d note it here.  Bertin&#8217;s <a href="http://www.infovis.net/printMag.php?num=84&#038;lang=2"><em>Semiologie</em></a> and <a href="http://www.infovis-wiki.net/index.php?title=Visual_Variables">seven visual variables</a> greatly influenced cartographic and graphic design theory and education over the last 40 years.  Sadly out of print for years, his <em>Semiology of Graphics</em> will be <a href="http://www.scribd.com/doc/26115819/ESRI-Press-Catalog-2010-Semiology-Graphics">reissued</a> in extended form by ESRI Press this November.</p>
<p class="left-caption">photo © <a href="http://www.flickr.com/photos/kbean/491051226/">pavilion tone</a></p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2010/05/rip-jacques-bertin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>indiemapper</title>
		<link>http://indiemaps.com/blog/2010/04/indiemapper/</link>
		<comments>http://indiemaps.com/blog/2010/04/indiemapper/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 05:16:46 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Axis Maps]]></category>

		<category><![CDATA[cartograms]]></category>

		<category><![CDATA[cartography]]></category>

		<category><![CDATA[choropleth]]></category>

		<category><![CDATA[flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[GIS]]></category>

		<category><![CDATA[indiemapper]]></category>

		<category><![CDATA[mapping]]></category>

		<category><![CDATA[Mate]]></category>

		<category><![CDATA[noncontiguous cartogram]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[thematic mapping]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=111</guid>
		<description><![CDATA[Axis Maps (Andy, Ben, Dave, Mark, and I) just released indiemapper, a sweet browser-based thematic and reference mapping application.




For some more indie maps, check out our gallery.  To try it out, just head over to indiemapper.com: you can sign up for a free 30 day trial without entering a credit card; after your trial, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.axismaps.com/">Axis Maps</a> (<a href="http://www.cartogrammar.com/blog/">Andy</a>, <a href="http://www.axismaps.com/about.php?id=ben">Ben</a>, <a href="http://www.axismaps.com/about.php?id=dave">Dave</a>, <a href="http://www.geography.wisc.edu/~harrower/">Mark</a>, and I) just released <a href="http://indiemapper.com/">indiemapper</a>, a sweet browser-based thematic and reference mapping application.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/slice2.png" alt="" /></div>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/slice1.png" alt="" /></div>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/slice3.png" alt="" /></div>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/slice4.png" alt="" /></div>
<p>For some more indie maps, check out our <a href="http://indiemapper.com/gallery.php">gallery</a>.  To try it out, just head over to <a href="http://indiemapper.com">indiemapper.com</a>: you can sign up for a free 30 day trial without entering a credit card; after your trial, indie is just $30/month ($20 academic).  Oh, and I guess there&#8217;ll be a free version, but it&#8217;d be pretty embarrassing if you were caught using that.</p>
<h3>A little history</h3>
<p>Indiemapper took a long time coming.  The seeds were planted in December 2007.  I had just discovered  Edwin van Rijkom&#8217;s <a href="http://shp.riaforge.org/">AS3 SHP library</a>, which lets you load and draw <a href="http://en.wikipedia.org/wiki/Shapefile">ESRI shapefiles</a> at run-time in Flash.  Using widely available formulae for simple projections like Mercator and <a href="http://en.wikipedia.org/wiki/Lambert_conformal_conic_projection">Lambert conformal conic</a> I began <a href="http://indiemaps.com/blog/2008/01/shapefiles-projections-in-flash-as3/">loading and projecting shapefiles</a> in Flash at run-time pretty quickly.  These were heady times, and this seemed pretty cool.</p>
<p><a href="http://www.cartogrammar.com/blog/">Andrew &#8220;Woody&#8221; Woodruff</a> joined in and we set off to create a full-fledged thematic mapping tool in Flash.  We designed the product for ourselves, honestly, and the cartographers we knew.  We hoped it&#8217;d be useful to other map-makers, whether casual or professional, who may not need nor want to learn the extensive analytical capabilities of a modern GIS, but do want a multitude of symbology and design options for their geographical data.</p>
<p>We presented a super-early version of indiemapper to <a href="http://www.geography.wisc.edu/students/student-groups.htm#macdad">MACDAD</a> on May 9, 2008.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/indiemapper_spring2008_600x450.png" alt="" /></div>
<p>As you can see, the basic workflow and trademark indie (<font color="#0099cc">#0099cc</font>) blue were already in place.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/oldIndie_symbology.png" alt="" /></div>
<p>We had some pretty gnarly styling panels, though; at this point we were just working in Flash and creating all the panels from scratch.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/oldIndie_lines.png" alt="" /></div>
<p>Of course things like getting Master&#8217;s degrees, real paying projects, moving, and having actual jobs (however briefly) got in the way, and development on indiemapper didn&#8217;t restart for another year or so.  Axis Maps (where Andy became a partner in Summer 2008) took up development of indie while I went and did something else for a while.  Axis Maps released <a href="http://indiemapper.com/blog/2009/05/announcing-indieprojector/">indieprojector</a> as a preview in May 2009, not realizing it&#8217;d be another 11 months before the full thing was ready.  I joined the team later in 2009, and have been co-developer (with Andy) since.  </p>
<h3>Development</h3>
<p>Mark and Ben are our static and interaction designers here, with Mark also providing the &#8220;learn more&#8221; content, drawing from his years of academic cartography experience.  Dave is our project manager, marketing guru, and AJAX guy; he created the backend to our user management and sharing systems.  </p>
<p>Andy and I both wrote AS3 code and <a href="http://en.wikipedia.org/wiki/MXML">MXML</a> markup, but he was mostly focused on the former with me working more on the latter.  This meant I programmed more of the framework and UI, while Andy was rocking the math-heavy projections work and all the exporting/imp/svg stuff.</p>
<p>When I joined the company, I immediately set to work refactoring the indiemapper code base to incorporate the <a href="http://mate.asfusion.com/">MVC framework Mate</a>.  Mate, as they say, is &#8220;a tag-based, event-driven Flex framework&#8221;.  I had to use <a href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm">Cairngorm</a> for work a while back, and by comparison Mate is quite lightweight and unobtrusive.  There&#8217;s much more to say here, but I&#8217;ll save that for later.</p>
<p>Though it&#8217;s old school what with <a href="http://opensource.adobe.com/wiki/display/flexsdk/FXG+1.0+Specification">FXG</a>, I still really like <a href="http://www.degrafa.org/">Degrafa</a>, and used it a fair amount for skinning.  Aside from Mate, Degrafa, and a few open source Flex components, we pretty much wrote our own little AS3 GIS SDK.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/indiemapper/fullMug.png" alt="" /></div>
<h3>This is just the beginning</h3>
<p>Given our platform and development philosophy, we can quickly respond to our users&#8217; needs in a thematic and reference mapping tool.  Please <a href="mailto:sales@indiemapper.com">let us know</a> what you want.</p>
<p>I think our first goals are:</p>
<ul>
<li>performance improvements so you can load larger geodata files faster</li>
<li>attribute editing and joining</li>
<li>more charting options for your data as an aid to classification and symbology selection</li>
<li>more symbologies, like <a href="http://www.geovista.psu.edu/publications/MacEachren/MacEachren_AnimatedMaps_91.pdf">chorodot</a> and additional cartogram styles</li>
<li>custom choropleth color schemes and graduated symbol size schemes</li>
<li>line generalization</li>
</ul>
<p>But let us know what else you&#8217;d like to see.  We&#8217;ve already been able to respond to a few new feature requests and, oh, maybe one or two bugs in our first week.</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2010/04/indiemapper/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Wild Bill Bunge</title>
		<link>http://indiemaps.com/blog/2010/03/wild-bill-bunge/</link>
		<comments>http://indiemaps.com/blog/2010/03/wild-bill-bunge/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 03:43:42 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[academia]]></category>

		<category><![CDATA[activism]]></category>

		<category><![CDATA[biography]]></category>

		<category><![CDATA[Canada]]></category>

		<category><![CDATA[cartography]]></category>

		<category><![CDATA[critical cartography]]></category>

		<category><![CDATA[Detroit]]></category>

		<category><![CDATA[Detroit Geographical Expedition and Institute]]></category>

		<category><![CDATA[geography]]></category>

		<category><![CDATA[history]]></category>

		<category><![CDATA[mapping]]></category>

		<category><![CDATA[maps]]></category>

		<category><![CDATA[mathematics]]></category>

		<category><![CDATA[Michigan]]></category>

		<category><![CDATA[person]]></category>

		<category><![CDATA[poverty]]></category>

		<category><![CDATA[PPGIS]]></category>

		<category><![CDATA[social science]]></category>

		<category><![CDATA[William Bunge]]></category>

		<category><![CDATA[Wisconsin]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=107</guid>
		<description><![CDATA[
Many aspiring social cartographers of the last few decades (including myself) drew inspiration from the legend of William Wheeler Bunge, Jr. Unfortunately, little information about this geographic and cartographic pioneer exists online. Below&#8217;s a biography of the radical cartographer and anti-academic, &#8220;Wild Bill&#8221; Bunge.

Mini bio
There are unfortunately few sources of biographical information on William Bunge. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="inimg" src="http://indiemaps.com/images/williamBunge/toTheChildren.png" alt="Dedication to William Bunge's (1988) Nuclear War Atlas" /></p>
<p>Many aspiring social cartographers of the last few decades (including myself) drew inspiration from the legend of <a href="http://en.wikipedia.org/wiki/William_Bunge">William Wheeler Bunge, Jr</a>. Unfortunately, little information about this geographic and cartographic pioneer exists online. Below&#8217;s a biography of the radical cartographer and anti-academic, &#8220;Wild Bill&#8221; Bunge.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/bunge_bw.png" alt="A portion of Ronald Horvath's map 'Automobile Territory' as printed in the Nuclear War Atlas" /></div>
<h3>Mini bio</h3>
<p>There are unfortunately few sources of biographical information on William Bunge.  Here, I rely on the autobiographical first chapter (&#8221;Preface and Acknowledgements: Rethinking&#8221;) to Bunge&#8217;s last published book, the <em>Nuclear War Atlas</em> (1988); UCSB professor Michael Goodchild&#8217;s (2008) <a href="http://www.geog.ucsb.edu/~good/papers/450.pdf">review [pdf]</a> of Bunge&#8217;s (1962) <a href="http://openlibrary.org/b/OL5581907M/Theoretical_geography"><em>Theoretical Geography</em></a>; many of Bunge&#8217;s articles (see &#8220;Further reading&#8221; below); and a handful of secondary sources.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/billAndBettyBunge.png" alt="William Bunge with his first wife Betty" /></div>
<h4>Early career</h4>
<p>At the start of the Korean War in 1950, a 22-year old conscripted Bunge was teaching atomic warfare at Camp McCoy, Wisconsin.  He completed his Masters degree in Geography in 1955 at the University of Wisconsin (natch), where he was influenced by <a href="http://en.wikipedia.org/wiki/Richard_Hartshorne">Richard Hartshorne</a> and <a href="http://en.wikipedia.org/wiki/Arthur_H._Robinson">Arthur Robinson</a>.  Establishing a pattern to be repeated throughout his turbulent academic career, Bunge was rejected by Wisconsin and continued his PhD studies at the University of Washington. There, Bunge and fellow grad students <a href="http://faculty.washington.edu/morrill/">Richard Morrill</a> and <a href="http://en.wikipedia.org/wiki/Waldo_Tobler">Waldo Tobler</a> were influenced by the quantitative geographer <a href="http://faculty.washington.edu/morrill/">William Garrison</a>.</p>
<p>Interestingly, this was also the height of the University of Washington&#8217;s cartography program.  The program led by <a href="http://faculty.washington.edu/krumme/faculty/shermanbib.html">John Sherman</a> and Donald Hudson was then rivaled only by the University of Wisconsin.  Chapter 2 of <a href="http://www.amazon.com/Thematic-Cartography-Visualization-Terry-Slocum/dp/0132097761">Slocum <em>et al</em>&#8217;s cartography text</a> describes the era well.</p>
<p>Bunge completed his PhD in 1960; his dissertation would become the touchstone in quantitative geography, <em>Theoretical Geography</em>.</p>
<h4><em>Theoretical Geography</em> and the spatial-quantitative revolution</h4>
<p>In a <a href="http://phg.sagepub.com/cgi/pdf_extract/25/1/71">2001 retrospective on the classics of human geography</a>, <a href="http://www.geography.osu.edu/faculty/kcox/">Kevin Cox</a> wrote that <em>Theoretical Geography</em> is &#8220;perhaps the seminal text of the spatial-quantitative revolution&#8221; and that (speaking of the broader field of human geography) &#8220;if we want to see where we have come from, what our intellectual debts are, there are few better places to start than <em>Theoretical Geography</em>.&#8221;  Bunge&#8217;s work promotes geography as a science and mathematics as the most fruitful language and tool for its study.  As the title makes clear, the author was concerned with theory, and believed that simple laws were discoverable about the patterns of social phenomena found on the earth&#8217;s surface. </p>
<p>In part, this was a reaction against the <a href="http://en.wikipedia.org/wiki/Nomothetic_and_idiographic">idiographic perspective</a> then present in the discipline.  Idiographic methods are concerned with describing the infinite variation in these social phenomena rather than discovering generalizable laws common to the entire surface.  Bunge thought such an idiographic view would continue to marginalize geography as a science, but received much opposition from geographers who valued the traditional role of description in geographic practice. Later opposition formed against Bunge&#8217;s conflation of geometric pattern with <em>explanation</em>; mathematical functions and simple geometric patters couldn&#8217;t, in and of themselves, be said to <em>explain</em> anything.</p>
<p>The ideas contained within are too complex and far outside my areas of expertise to cover here; for a better summary of the issues and debates involved, see <a href="http://openlibrary.org/b/OL5581907M/Theoretical_geography">Michael Goodchild&#8217;s 2008 review (pdf)</a>.  Though his book would become a classic, Bunge had a hard time getting it published stateside, and apparently <a href="http://en.wikipedia.org/wiki/Torsten_Hägerstrand">Torsten Hägerstrand</a> had a hand in its eventual publication by Swedish (&#8221;that freer place&#8221;) company Gleerup in 1962.  Before this, but with his University of Washington PhD in hand, Bunge received his first academic appointment at the  University of Iowa in 1960.  By 1961, he&#8217;d been fired.  The next year, with his book published, the activist/academic Bunge moved to the <a href="http://maps.google.com/maps/place?sourceid=chrome&#038;um=1&#038;ie=UTF-8&#038;q=fitzgerald+detroit&#038;fb=1&#038;gl=us&#038;ftid=0x8824cc13dc5ab0ef:0x5c88393126dde67f&#038;ei=9i6TS9yxHYzUM9bzkMEN&#038;sa=X&#038;oi=geocode_result&#038;ct=title&#038;resnum=1&#038;ved=0CAcQ8gEwAA">Detroit neighborhood of Fitzgerald</a> to join the Geography Department at <a href="http://wayne.edu/">Wayne State University</a>.</p>
<h4>Detroit: <em>Fitzgerald</em> and the Detroit Geographical Expedition and Institute</h4>
<p><em>Fitzgerald: Geography of a Revolution</em> was published in 1971, a year after Bunge&#8217;s infamous Detroit Geographical Expedition and Institute (DGEI) lost the support of Michigan State University. But it was written in 1967, the year before Bunge formed the DGEI, so will be covered first.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/income_small.jpeg" alt="The Fitzgerald neighborhood highlighted on a map of Detroit income" /></div>
<p><em>Fitzgerald</em> is an experimental work of urban geography, and one of the most impressive scholarly works I&#8217;ve seen.  The delay in publication was due to the book&#8217;s odd size (23 x 29 cm), format (text, photos, and maps of divergent scale and symbology) and content (very critical of the pervasive racism Bunge <a href="http://books.google.com/books?id=8VcEAAAAMBAJ&#038;pg=PA494&#038;lpg=PA494&#038;dq=">seemed to find everywhere</a>).  Bunge describes <em>Fitzgerald</em> thusly:</p>
<blockquote><p><em>Fitzgerald: The Geography of a Revolution</em> is a humanist geography, describing Fitzgerald, a community in Detroit. The book is science: its data are maps, graphics, photographs, and the words of people. But the book also makes a value judgment &#8212; the desirability of human survival &#8212; and thus transforms itself into a steel-hard hammer of humanism.</p></blockquote>
<p>Fitzgerald&#8217;s history is traced from the first white settlers arriving in 1816 to the racial tension and revolution Bunge saw taking place around him in the 1960s.</p>
<p><img class="inimg" src="http://indiemaps.com/images/williamBunge/farmMap.png" alt="A portion of the 'Fitzgerald District Farm Era 1900-1925' created by cartographer George Shenkar for William Bunge's 'Fitzgerald: Geography of a Revolution'" /></p>
<p>Much of Bunge&#8217;s cartographic theory is contained in the foreword to the book.  Speaking of a historical farm map created for the book (portion above):</p>
<blockquote><p>Maps attempt to integrate over time, that is, maps assume an average span of time. This means that nothing that moves is mapped, and therefore property is inherently preferred over humans&#8230;In order to restore truth to the map it is necessary to achieve a fiction of accuracy through an assumption, namely that the map is drawn at an exact instant of time. In this case, the time is June 20, 1915 at 2 p.m. on a sunny day. This fiction freezes the men and horses on the roads, the strawberry pickers in the fields, as well as the crops in rotation and the animals in pasture. This restores life to the dead map of property.</p></blockquote>
<p>Bunge wasn&#8217;t a passive observer of the revolution taking place in Fitzgerald.  He was an active member of the Fitzgerald Community Council and developed deep connections in the neighborhood; this laid the groundwork for the Detroit Geographical Expedition he would later found (more below).  Here, Bunge at a block club meeting in his Fitzgerald home:</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/bunge_blockClub.png" alt="William Bunge holding a block club meeting in his home" /></div>
<p>And Bunge in <em>Fitzgerald</em> doesn&#8217;t merely describe; he advocates. Here, Bunge on cannabis:</p>
<blockquote><p>The confusion between marijuana and heroin and other hard drugs seems self-serving on the white adult society. Marijuana grows so easily and abundantly that the apparatus of provision is uncomplicated. It is almost like air, a free resource. Further, unlike alcohol, marijuana seems to produce no aggressive outburst, judging from the teenage dances where the odor in the men&#8217;s room indicates its use. It has been argued that marijuana leads to heroin and other hard drugs, but cause and effect in this case is murky since baby&#8217;s milk also leads to heroin in the sense that it always precedes it.</p></blockquote>
<p>The above must smack of the <a href="http://en.wikipedia.org/wiki/Nomothetic_and_idiographic">idiography</a> Bunge opposed with <em>Theoretical Geography</em>. Bunge tried to preempt such criticism by insisting on the &#8220;disciplined objectivity&#8221; of <em>Fitzgerald</em> and the generalizability of the story:</p>
<blockquote><p>Another major technical difficulty is the generalizability of the story. What can we learn about America from studying a core region of only one square mile? At first it was thought that especially the historic geography would be very spotty and unrepresentative of America, but discovery after discovery gradually reversed this apprehension. Who could possibly believe that this region was typical of all America? Would one square mile in the middle of Cincinnati or Miami turn up Indians, land speculators, gypsies black pioneers and so forth? Yes, if it were studied deeply enough.</p></blockquote>
<p><em>Fitzgerald</em>&#8217;s reception at the time wasn&#8217;t great. Bunge <a href="http://www.informaworld.com/smpp/content~db=all~content=a788928498">attributed</a> all negative responses to racism and entrenched conservative attitudes within academic geography at the time. Legitimate criticism actually centered on the experimental method employed, Bunge&#8217;s generalizations of white racism, and the conclusions drawn from a square mile study area. Further, Bunge&#8217;s loving but at times simplistic descriptions of &#8220;black culture&#8221; would now appear politically incorrect or as unfounded/inaccurate as any racialist descriptions.</p>
<h5>Detroit Geographical Expedition and Institute</h5>
<p>Besides <em>Theoretical Geography</em>, Bunge should be most well known for the radical mapping + educational mission undertaken in downtown Detroit between 1968-1970 under the name <em>Detroit Geographical Expedition and Institute</em>.  Bunge formed the DGEI with a poor 18-year old resident of Fitzgerald, Gwendolyn Warren (below at 16, from <em>Fitzgerald</em>).</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/gwendolynWarren.png" alt="Gwendolyn Warren at age 16 (from Fitzgerald: Geography of a Revolution)" /></div>
<p>Variously affiliated with the University of Michigan, Michigan State University, and Wayne State University, the Expedition attempted and at times succeeded in providing free college courses to young inner-city Detroit residents. Bunge wanted to do research in the black community while also teaching the skills necessary for them to conduct research for themselves. All volunteer faculty were used, and the Expedition was generally successful in attracting experts from across the U.S. to teach courses at facilities freely provided on Wayne State University&#8217;s Detroit campus.</p>
<p>Classes focused on geography and geographic skills.  Two courses &#8212; Cartography and Geographical Aspects of Urban Planning &#8212; provided the context for perhaps the Expedition&#8217;s greatest achievement: <a href="http://www.geo.hunter.cuny.edu/courses/geog701/articles/report_school_decentralization.pdf">A Report to the Parents of Detroit on School Decentralization [pdf]</a> (1970).  Expedition participant and Geography professor Ronald Horvath <a href="http://www3.interscience.wiley.com/cgi-bin/fulltext/119692922/PDFSTART">describes</a> the relevance of cartography to the students:</p>
<blockquote><p>The material covered just did not seem terribly important to the students. Before the request came in to do the decentralization study, a lot of effort had to be spent shoring up the morale of the students, who had real difficulties just showing up to even free classes &#8212; some came hungry, others couldn&#8217;t afford bus fare, one student had been living in a car for five weeks. Learning how to make a clean line, lay a rip-a-tone pattern, or design a map with the right Combination of point, area, and line symbols did not seem to be critical knowledge to members of a survival culture. But the school decentralization study made sense. The next three weeks both saved and came to define the potential of the Expedition.</p></blockquote>
<p>The decentralization report &#8212; rich in graphs and maps created by Bunge and the Expedition&#8217;s students &#8212; was adopted by a community group and forced the Board of Education to respond to charges that its school districting plans were illegal.  The Expedition released a few other documents using cartographic experimentation as a weapon of social justice, including the &#8220;Geography of the Children of Detroit&#8221;. At its height in the Spring of 1970 the Expedition enrolled nearly 500 inner-city students in 11 different courses.  By that fall, zero courses were being taught and the Expedition was effectively over, having lost the support of Michigan State University.</p>
<h4>Leaving the U.S.</h4>
<p>Below you&#8217;ll see Bunge&#8217;s name on part of an <a href="http://news.google.com/newspapers?nid=1928&#038;dat=19701024&#038;id=_5sgAAAAIBAJ&#038;sjid=GWgFAAAAIBAJ&#038;pg=1018,5984834">infamous listing of 65 &#8220;radical&#8221; speakers</a> compiled in 1970 by <a href="http://en.wikipedia.org/wiki/Richard_Howard_Ichord_Jr.">U.S. Representative Richard H. Ichord</a>, then chairman of the <a href="http://en.wikipedia.org/wiki/Huac">House Un-American Activities Committee</a>.  This blacklist was the subject of much controversy and a federal court order actually prohibited official government publication of the names of these anti-war protesters and/or open communists.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/radicalSpeakers.png" alt="William Bunge's name on Representative Ichord's blacklist of 'radical speakers' (scanned from NY Times)" /></div>
<p>After his brief (1960-61) stint at the University of Iowa, Bunge was employed for the <em>Fitzgerald</em> and early DGEI days by Wayne State University (1962-69).  He was<a href="http://news.google.com/newspapers?id=DQsyAAAAIBAJ&#038;sjid=w6EFAAAAIBAJ&#038;pg=5346%2C2370017"> fired from Wayne State University</a> when his attempts to draw black geographers to the department rankled administrators.  Unemployment allowed Bunge to travel to campuses in the U.S., Canada, and Britain on his &#8220;have map, will travel&#8221; campaign.  He used an overhead projector to show &#8220;peace maps&#8221; as a protest against U.S. militarism (these would evolve into the <em>Nuclear War Atlas</em>; see below). Bunge&#8217;s speeches during this period drew the attention of Representative Ichord, and the resulting blacklist made Bunge basically unemployable in U.S. academia.</p>
<p>Bunge moved to Canada and had two more brief stints in academia: at the University of Western Ontario (1970-71) and York University (1972-73).  This period was Bunge&#8217;s most prolific with regard to non-book publication: I count 12 single-author pubs between 1970 and 1974.  In this period, Bunge formed a few short-lived expeditions on the Detroit model: the Society for Human Exploration (1971-72), Toronto Geographical Expedition (1972-73), and the Canadian-American Geographical Expedition. Bunge touted such expeditions as the highest calling for the geographer. </p>
<p>I&#8217;ve barely done justice to the history, theory, and impact of these urban expeditions.  I recommend seeking out the primary and secondary material on the period (see &#8220;Further reading&#8221; below), particularly Ronald Horvath&#8217;s <a href="http://www3.interscience.wiley.com/journal/119692922/abstract">&#8220;The &#8216;Detroit Geographical Expedition and Institute&#8217; Experience&#8221;</a>, Bunge&#8217;s <a href="http://openlibrary.org/b/OL5327153M/first_years_of_the_Detroit_Geographical_Expedition">&#8220;The First Years of the Detroit Geographical Expedition: A Personal Report&#8221;</a>, and the decentralization study linked above.</p>
<p>Later in the decade, now outside both Canadian and American academia, Bunge would become a cab driver in Quebec. Though an odd turn for such an influential geographer, Bunge had previously compared cab drivers glowingly to the native guides who led explorers across the Americas and Africa. Bunge had <a href="http://www3.interscience.wiley.com/journal/119675428/abstract">elsewhere</a> praised cabbies: the &#8220;regions within cities are better known by cab drivers than by &#8216;urban geographers&#8217;&#8221;.  Bunge lived in <a href="http://maps.google.com/maps?f=q&#038;source=s_q&#038;hl=en&#038;geocode=&#038;q=3+rue+Sacre-Coeur,+Arthabaska,+Quebec&#038;sll=43.086341,-89.359557&#038;sspn=0.013242,0.029054&#038;ie=UTF8&#038;hq=&#038;hnear=3+Rue+Du+Sacré-Coeur,+Victoriaville,+Arthabaska,+Québec,+Canada&#038;ll=46.060989,-71.945525&#038;spn=0.00316,0.007263&#038;t=h&#038;z=18&#038;iwloc=A">Arthabaska, Quebec</a> from some time in the late 70s to some time in the <a href="http://cyberbadger.blogspot.com/2006/10/william-bunges-nuclear-war-atlas-i-got.html#8581178665013316553">early oughts</a>.</p>
<h4>The 80s and the <em>Nuclear War Atlas</em></h4>
<p>William Bunge was published thrice in the 1980s: one <a href="http://www.jstor.org/pss/20001933">article</a> (<strong>correction</strong>: found <a href="http://www.sciencedirect.com/science?_ob=ArticleURL&#038;_udi=B6X2W-4698R9B-19&#038;_user=10&#038;_coverDate=01/31/1983&#038;_rdoc=1&#038;_fmt=high&#038;_orig=search&#038;_sort=d&#038;_docanchor=&#038;view=c&#038;_searchStrId=1265948126&#038;_rerunOrigin=google&#038;_acct=C000050221&#038;_version=1&#038;_urlVersion=0&#038;_userid=10&#038;md5=4bb6b6fb63de9531a10a5e50771ee966">another article</a>, though it was originally submitted in the late 70s), one <a href="http://www.wiley.com/WileyCDA/WileyTitle/productCd-0631162712.html">epilogue</a>, and one <a href="http://openlibrary.org/b/OL2399341M/Nuclear_war_atlas">book</a>. The book, Bunge&#8217;s latest, was also his most experimental and map-heavy work. The intro contains a limited biography of the man himself. Further chapters include remixes of his previous works, copious maps (see &#8220;Maps&#8221; section below), and Bunge&#8217;s ruminations on the potential destructiveness of U.S. and Soviet nuclear power.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclearWarAtlas_small.png" alt="Cover of William Bunge's Nuclear War Atlas" /></div>
<p>The atlas started as a poster (<a href="http://cyberbadger.blogspot.com/2006/10/william-bunges-nuclear-war-atlas-i-got.html">from Martin Dodge&#8217;s blog</a>):</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/nuclear.jpg" alt="An early poster version of William Bunge's Nuclear War Atlas" /></div>
<p>In the appendix, Bunge called Geography the &#8220;Queen of the Peace Sciences&#8221;: </p>
<blockquote><p>Interestingly, geography, a subject currently in low academic status, dying out in one university after another, can actually make a serious claim to be the &#8216;queen of the peace sciences&#8217; &#8212; not out of our innocence, but rather out of our guilt. It is the quintessential war science. This might account for its decline. Today, who needs more expertise on how to kill people?</p></blockquote>
<p>The <em>Nuclear War Atlas</em> is a significant geographic and cartographic work. Again, I do it little justice. The atlas may have had more traction had the wall not fallen a year after its publication, but the maps and text within are still necessary reading for any radical geographer or social cartographer.</p>
<h4>Back to the USSR</h4>
<p>Since the <em>Nuclear War Atlas</em> little has been heard from William Bunge.  Nothing was published in the decade until 1998. By this time Bunge&#8217;s social liberalism seemed to be verging on Stalinism. His latest published article (that I know of) &#8212; 1998&#8217;s &#8220;Where are the Germans?&#8221; &#8212; was printed in <a href="http://www.northstarcompass.org/"><em>Northstar Compass</em></a>, the journal unabashedly dedicated to the re-establishment of the Soviet Union as a socialist state.  I can&#8217;t find the text of the article (it&#8217;s not included in Northstar&#8217;s <a href="http://www.northstarcompass.org/archive.html?active=4">archives for the issue</a>) but its publication was noted in a <a href="http://www.geography.wisc.edu/archiveNews/newsletters/madgeognews/MadGeogNews54.pdf">Spring 1999 edition of MADGEOGNEWS [pdf]</a>.</p>
<p>The same article notes that Bunge &#8220;was awarded the &#8216;Representative of the <a href="http://www.pcq.qc.ca/Dossiers/Modeles/index.html?id=Autres/Archives/Nouveautes&#038;lang=fr"><em>Parti communiste du Québec</em></a> to the Federal government&#8217; in 1998&#8243;.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/cov1001.jpg" alt="" /></div>
<p>A 2001 letter also contained a bit of revisionist Stalinism. The below was included in <a href="http://www.northstarcompass.org/nsc0108/discussion.htm">some discussion on a World Congress for Solidarity and Friendship with the Soviet People page</a>.</p>
<blockquote><p>
We have a lot of basics in common. We remember and respect the fact that under the brilliant leadership of Joseph Stalin the Soviet Union practically single handedly defeated Hitler. Almost ninety per cent of all the military fatalities sustained by Hitler&#8217;s Nazi hordes in World War II were rendered by the Soviets, leaving but ten per cent for all the other &#8220;allies.&#8221; Many Western war veterans were saved by the defeat of the fascists by the Soviet Red Army.<br />
We are also enthusiastic about the restoration of the USSR since its collapse had practically collapsed most of the left movement worldwide. Philosophically there would be no understanding of even pre-Leninist works, Marx and Engels, without the Soviet press and its publishing of all their works in many languages of the world.<br />
At the World Congress which I shall attend I will try to bring the following question to discussion: &#8220;How does religion differ in Fidel Castro&#8217;s Socialist Cuba compared to Stalin&#8217;s Socialist Soviet Union?&#8221;
</p></blockquote>
<p>Certainly Bunge always leaned towards Marx &#8212; his later Stalinist leanings should by no means detract from his 30+ years of service to the downtrodden of America, those who&#8217;d been failed by the state supposedly dedicated to serving them. Bunge is alive and (I hope quite) well, and I regret missing <a href="http://foucaultblog.files.wordpress.com/2008/04/bunge.pdf">this document</a> distributed at the 2008 <a href="http://www.aag.org/">AAG</a> conference in Boston, at which Bunge and I were both rumored to be in attendance.</p>
<h3>Maps</h3>
<p>But what the hell do I really care about?&#8211; maps.  Here&#8217;s a gallery of works of his I&#8217;ve scanned from books and articles or found online.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/islandsAndContinentsOfMankind.png" alt="William Bunge's map, 'Islands and Continents of Mankind'" /></div>
<p class="caption"><a href="http://makingmaps.net/2008/02/05/more-principles-of-map-design/">From Professor Krygier&#8217;s Making Maps blog</a>: &#8220;Redrawn from William Bunge, The Continents and Islands of Mankind. Areas in black have more than 30 people per square mile. Reproduced from Making Maps, p. 160-161&#8243;</p>
<h4>Fitzgerald and the Detroit Geographical Expedition</h4>
<p>Bunge&#8217;s <em>Fitzgerald: Geography of a Revolution</em> and the output of the Detroit Geographic Expedition (see bio above) included some of Bunge&#8217;s most experimental and powerful maps of Detroit.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/recreationalFacilities.png" alt="A simple map from William Bunge's Fitzgerald: Geography of a Revolution" /></div>
<p class="caption">A simple map I scanned from <em>Fitzgerald</em></p>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/money.png" alt="A flow map by William Bunge: 'Direction of Money Transfers in Metropolitan Detroit'" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/purchasedToys.png" alt="'Purchased Toys' by William Bunge" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/rat-bitten.png" alt="'Region of Rat-bitten Babies' by William Bunge" /></div>
<p>The above three maps were published last December in <del>what I can only assume is</del> [<a href="http://translate.google.com/translate?hl=en&#038;sl=fr&#038;u=http://blog.mondediplo.net/2009-12-29-William-Bunge-le-geographe-revolutionnaire-de&#038;ei=uF2hS_T9F4TaNaePnUM&#038;sa=X&#038;oi=translate&#038;ct=result&#038;resnum=1&#038;ved=0CAkQ7gEwAA&#038;prev=/search%3Fq%3DWilliam%2BBunge,%2Ble%2Bg%25C3%25A9ographe%2Br%25C3%25A9volutionnaire%2Bde%2BDetroit%26hl%3Den">translated here</a>] an excellent post on Bunge&#8217;s work in Detroit: <a href="http://blog.mondediplo.net/2009-12-29-William-Bunge-le-geographe-revolutionnaire-de"><em>William Bunge, le géographe révolutionnaire de Detroit</em></a>. </p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/detroit_cartogram.png" alt="A rectangular cartogram of population in southeastern Michigan by William Bunge" /></div>
<p class="caption">Another example of Bunge&#8217;s cartographic experimentation: a rectangular cartogram when the form was quite rare. An image I clipped from the DGEI&#8217;s <a href="http://www.geo.hunter.cuny.edu/courses/geog701/articles/report_school_decentralization.pdf">&#8220;A report to the parents of Detroit on school decentralization&#8221; [pdf]</a>&#8220;</p>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/runOverMap.png" alt="'Where Commuters Run Over Black Children on the Pointes-Downtown Track' by William Bunge" /></div>
<p class="caption">This map is from <em>Fitzgerald</em>, but I snagged it from a <a href="http://makingmaps.net/2009/06/06/making-advocacy-humanitarian-maps/">post on Krygier&#8217;s blog</a></p>
<p></p>
<div class="centerIMG"><img src="http://proceedings.esri.com/library/userconf/proc95/to150/p1071.gif" alt="Detroit Geographical Expedition Maps of the Bloomfield Hills and Mack Avenue areas of Detroit" /></div>
<p class="caption">Another map from the DGEI, this time scanned from an <a href="http://proceedings.esri.com/library/userconf/proc95/to150/p107.html">ESRI proceedings paper</a>.  I can&#8217;t make out all the map symbols, but some are dogs, cats, rubbish, gym equipment, bicycles, telephone poles, and broken bottles.</p>
<h4><em>Nuclear War Atlas</em></h4>
<p>Bunge&#8217;s <em>Nuclear War Atlas</em> is perhaps his most important cartographic work.  Indeed, it is his only <em>atlas</em> (his <em>Atlas of Love and Hate</em> was never realized, <a href="http://www.partizanpublik.nl/article/67/atlas-of-love-and-hate/">not by Bunge anyway</a>).  The mostly duotone (red and black) maps contained therein display more cartographic experimentation than any of his previous works. There&#8217;s also some <em>pretty weird shit</em>. Bunge notes in the preface:</p>
<blockquote><p>The color red is used throughout the atlas on the maps to depict death, and green life. This atlas is awash in red as our planet might soon be in death. Hopefully, at last my fellow revolutionaries will show some keen interest in conducting revolution without annihilation.</p></blockquote>
<p>I had to search quite a bit to find any maps containing green (life). </p>
<p>Here&#8217;s a sampling of nine maps I scanned from the atlas, complete with original captions. Bunge&#8217;s work contains many redesigns of maps previously included in <em>Fitzgerald</em> or DGEI publications (for example, the &#8220;Region of rat-bitten babies&#8221; map below).</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_fig1.1.png" alt="Figure 1.1 ('Firepower') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map1.4.png" alt="Map 1.4 ('New Chicago') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_2.5.png" alt="Map 2.5 ('To conquer the world, conquer Inner Asia') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map2.7.png" alt="Map 2.7 ('American Domino Theory') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map2.15.png" alt="Map 2.15 ('Automobile Territory - Downtown Detroit') from William Bunge's Nuclear War Atlas" /></div>
<p class="caption">Someone helpfully pointed out to me that (as the source indicates) the above is actually reprinted by Bunge from Ronald Horvath&#8217;s (1974) article &#8220;Machine Space&#8221;</p>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map2.16.png" alt="Map 2.16 (Children's Automobile 'Accidents' in Detroit) from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map3.15.png" alt="Map 3.15 (Detroit's Infant Mortality Compared with Foreign Countries) from William Bunge's Nuclear War Atlas" /></div>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map3.16.png" alt="Map 3.16 ('Region of Rat-bitten Babies') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/nuclear_map3.17.png" alt="Map 3.17 ('World Speciescide') from William Bunge's Nuclear War Atlas" /></div>
<p></p>
<h3>Influence</h3>
<p>Bunge&#8217;s concept of the Expedition was very influential in geography in the 1970s.  Unfortunately, the influence didn&#8217;t last long and there have only been minor resurgences since.  Still, a small group of radical geographers &#8212; particularly those associated with the <a href="http://www.antipode-online.net/">Antipode journal</a> &#8212; have carried on the revolutionary spirit of Bunge&#8217;s geography.</p>
<p>Bunge is certainly an influence on academic <a href="http://krygier.owu.edu/index.html">John Krygier</a> and anti-academic <a href="http://en.wikipedia.org/wiki/Denis_Wood">Denis Wood</a>.  The former has mentioned Bunge <a href="http://makingmaps.net/?s=bunge">a few times</a> on his blog and his definitional work on <em>maps as propositions</em> (see the sweet Krygier/Wood comic, <a href="http://makingmaps.owu.edu/this_is_not_krygier_wood.pdf"><em>Ce n&#8217;est pas le monde</em> [pdf]</a>) is inspired by Bunge&#8217;s advocacy maps of the 1960s.  Wood too was influenced by the Detroit Geographical Expedition; his as yet uncompleted <a href="http://makingmaps.net/2008/01/10/denis-wood-a-narrative-atlas-of-boylan-heights/"><em>Narrative Atlas of Boylan Heights</em></a> is directly influenced by Bunge in terms of scale, subject matter, and cartographic technique.</p>
<p>I am personally not as convinced as Bunge as to the state&#8217;s ability to solve the very real problems about which he writes and maps; and I just can&#8217;t get down with his more recent Stalinist leanings. I admire William Bunge primarily as a social cartographer willing to experiment with symbology and as a geographer willing to stand up for his political principles. Ultimately the latter led to him having no place in American <em>academe</em>. This is unfortunate, for his experimental cartography and radical geography writings could have had a much greater impact on critical cartography, public participation GIS (PPGIS), and human geography.</p>
<h3>
<img class="inimg" src="http://indiemaps.com/images/williamBunge/nuclear_appendix.png" alt="Appendix: For Geographer's Only" /><br />
</h3>
<h3>
Further reading<br />
</h3>
<h4>By Bunge</h4>
<h5>Books</h5>
<ul>
<li>
<a href="http://openlibrary.org/b/OL5581907M/Theoretical_geography"><em>Theoretical Geography</em></a>. Lund, Sweden: Gleerup. (1962)
</li>
<li>
<a href="http://openlibrary.org/b/OL4576180M/Fitzgerald_geography_of_a_revolution"><em>Fitzgerald: Geography of a Revolution</em></a>. Cambridge, Mass.: Schenkman Pub. Co. (1971)
</li>
<li>
<a href="http://openlibrary.org/b/OL2399341M/Nuclear_war_atlas"><em>Nuclear War Atlas</em></a>. New York, NY: Basil Blackwell Inc. (1988)
</li>
</ul>
<h5>Journal articles and chapters</h5>
<p>Bunge certainly shouldn&#8217;t be judged by his peer-reviewed scholarly output; in many ways he was an anti-academic who preferred action to being published. Nonetheless, here are all the published Bunge articles or chapters I could find.  Links provided are occasionally to full-text content, but most are to references on <a href="http://www.jstor.org/">JStor</a>, <a href="http://openlibrary.org/">OpenLibrary</a>, and similar sources.  I throw in a quote or an abstract here and there.</p>
<ul>
<li>(with Reid A. Bryson) <a href="http://madcat.library.wisc.edu/cgi-bin/Pwebrecon.cgi?v1=8&#038;ti=1,8&#038;CNT=50&#038;Search_Arg=bunge,%20william&#038;Search_Code=NAME@&#038;PID=0-g8xAd2yMjQfT8gmtFU54N9b9REl&#038;SEQ=20100313203624&#038;SID=1">&#8220;Ice on Wisconsin Lakes&#8221;</a> (1956) Published by University of Wisconsin Dept. of Meteorology</li>
<li><a href="http://www-personal.umich.edu/~copyrght/image/micmg/bunge/bunge.pdf">&#8220;Patterns of Location&#8221; [pdf]</a> (1964) Discussion paper of the Michigan Inter-University Community of Mathematical Geographers, no. 3</li>
<li><a href="http://www.informaworld.com/smpp/content~content=a788947980&#038;db=all">&#8220;Geographical Dialectics&#8221;</a> (1964) <em>Professional Geographer</em> 16, pp. 28-29</li>
<li><a href="http://books.google.com/books?id=8VcEAAAAMBAJ&#038;pg=PA494&#038;lpg=PA494&#038;dq="racism+in+geography"+bunge&#038;source=bl&#038;ots=elSnrGLRwY&#038;sig=YM9e21ASeNqEeYx638UjKCMyuA8&#038;hl=en&#038;ei=QiShS8y2C47ONMOmoKwM&#038;sa=X&#038;oi=book_result&#038;ct=result&#038;resnum=1&#038;ved=0CAYQ6AEwAA#v=onepage&#038;q=%22racism%20in%20geography%22%20bunge&#038;f=false">&#8220;Racism in Geography&#8221;</a> (1965) <em>The Crisis</em> (NAACP magazine) October, pp. 494-497</li>
<li><a href="http://www.jstor.org/pss/2569379">&#8220;Locations Are Not Unique&#8221;</a> (1966) <em>Annals of the Association of American Geographers</em> 56, pp. 375-376</li>
<li><a href="http://www.jstor.org/pss/212882">&#8220;Gerrymandering, Geography, and Grouping&#8221;</a> (1966) <em>Geographical Review</em> 56, pp. 256-263</li>
<li><a href="http://www.jstor.org/pss/2569559">&#8220;Fred K. Schaefer and the Science of Geography&#8221;</a> (1968) <em>Harvard Papers in Theoretical Geography</em>, Special Papers Series, Paper A</li>
<li><a href="http://openlibrary.org/b/OL5327153M/first_years_of_the_Detroit_Geographical_Expedition">&#8220;The First Years of the Detroit Geographical Expedition: A Personal Report&#8221;</a> (1969) <em>field notes</em>, discussion paper no. 1, pp. 1-59</li>
<li><a href="http://www.geo.hunter.cuny.edu/courses/geog701/articles/report_school_decentralization.pdf">&#8220;A report to the parents of Detroit on school decentralization&#8221; [pdf]</a> (1970) Detroit Geographical Expedition and Institute</li>
<li><a href="http://books.google.com/books?id=WL7WOgAACAAJ&#038;source=gbs_ViewAPI">&#8220;Geography of the Children of Detroit&#8221;</a> (1971) <em>field notes</em>, discussion paper no. 3</li>
<li><a href="http://www.informaworld.com/smpp/content~db=all~content=a788964423">&#8220;The Geography&#8221;</a> (1973) <em>Professional Geographer</em> 25, pp. 331-337</li>
<li><a href="http://www.jstor.org/pss/2561993">&#8220;The Geography of Human Survival&#8221;</a> (1973) <em>Annals of the Association of American Geographers</em> 63, pp. 275-295</li>
<li>&#8220;Ethics and logic in geography&#8221; (1973) In R. J. Chorley (ed.), <em>Directions in Geography</em>, London: Methuen, pp. 317-31</li>
<li> (with Robert Sack) <a href="http://www.informaworld.com/smpp/content~db=all~content=a788929045">&#8220;Spatial Prediction&#8221;</a> (1973) <em>Annals of the Association of American Geographers</em> 63, pp. 566-569</li>
<li>&#8220;Urban Nationalism: An Example from Canada&#8221; (1973) <em>La Revue de Geographie deMontreal</em> 27</li>
<li><a href="http://www3.interscience.wiley.com/journal/119675428/abstract">&#8220;Exploration in Guadeloupe: Region of the Future&#8221;</a> (1973) <em>Antipode</em> 5, no. 2, pp. 67-73</li>
<li><a href="http://www.jstor.org/stable/20000840">&#8220;Regions Are Sort of Unique&#8221;</a> (1974) <em>Area</em> 6, no. 2, pp. 92-99</li>
<li>(with Donald W. Fryer) <a href="http://www.jstor.org/pss/2562383">&#8220;A Geographer’s Inhumanity to Man&#8221;</a> (1974) <em>Annals of the Association of American Geographers</em> 64, no. 3, pp. 479-484</li>
<li>&#8220;Practical Applications of Theoretical Geography&#8221; (1974) Published by the University of Iowa Dept. of Geography</li>
<li><a href="http://www.jstor.org/pss/2562384">&#8220;Fitzgerald from a Distance&#8221;</a> (1974) <em>Annals of the Association of American Geographers</em> 64, no. 3: pp. 485-489</li>
<li>( with R. Bordessa) <a href="http://openlibrary.org/b/OL14551434M/Canadian_alternative">&#8220;The Canadian alternative : survival, expeditions and urban change&#8221;</a> (1975) Published by the Dept. of Geography, Atkinson College, Toronto</li>
<li><a href="http://www3.interscience.wiley.com/journal/119629448/abstract">&#8220;The Point of Reproduction: A Second Front&#8221;</a> (1977) <em>Antipode</em> 9, no. 2, pp. 60-76</li>
<li>(with John D. Nystuen) <a href="http://www-personal.umich.edu/~copyrght/image/micmg/toulmin/toulmin.pdf">&#8220;The Philosophy of Maps&#8221; [pdf]</a> (1978) Michigan Inter-University Community of Mathematical Geographers, Discussion Paper no. 12</li>
<li><a href="http://www.jstor.org/pss/2569566">&#8220;Perspective on <em>Theoretical Geography</em>&#8220;</a> (1979) <em>Annals of the Association of American Geographers</em> 69, no. 1: pp. 196-174</li>
<li>
<a href="http://www.sciencedirect.com/science?_ob=ArticleURL&#038;_udi=B6X2W-4698R9B-19&#038;_user=10&#038;_coverDate=01/31/1983&#038;_rdoc=1&#038;_fmt=high&#038;_orig=search&#038;_sort=d&#038;_docanchor=&#038;view=c&#038;_searchStrId=1265948126&#038;_rerunOrigin=google&#038;_acct=C000050221&#038;_version=1&#038;_urlVersion=0&#038;_userid=10&#038;md5=4bb6b6fb63de9531a10a5e50771ee966">&#8220;The Cave of Coulibistrie&#8221;</a> (1983; originally submitted 1978) <em>Political Geography Quarterly</em> 2, no. 1: pp. 57-70</p>
<blockquote><p>Geography and politics are intertwined in a study of a single small Caribbean settlement, Coulibistrie, on the windward island of Dominica. The sense of the place is provided through a sympathetic description of its rhythms, its people, their reactions to their poverty and their survival strategies. Political movements from Dreadism to Socialism are discussed in this specific context, and the position of women and children analysed. Political strategies are evaluated and the conclusion proposes a pro-children dialectical experiment of allying Marxism with the Catholic Church.</p></blockquote>
</li>
<li><a href="http://www.jstor.org/pss/20001933">&#8220;Geography is a field subject&#8221;</a> (1983) <em>Area</em> 15, no. 3: pp. 209</li>
<li>&#8220;Epilogue: Our Planet is Big Enough for Peace but Too Small for War&#8221; (1986) in R. J. Johnson and P.J. Taylor (ed.) <a href="http://www.wiley.com/WileyCDA/WileyTitle/productCd-0631162712.html"><em>A World in Crisis?: Geographical Perspectives</em></a>, Oxford: Basil Blackwell</li>
<li>&#8220;Where are the Germans?&#8221; (1998) <a href="http://www.northstarcompass.org/"><em>Northstar Compass</em></a> 7, no. 6
</li>
<li><a href="http://phg.sagepub.com/cgi/pdf_extract/25/1/71">&#8220;Author’s response: geography the innocent science – a completed geography<br />
awaiting its birth in print&#8221;</a> (2001) <em>Progress in Human Geography</em> 25, no. 1, pp. 75-77</p>
<blockquote><p>So what is the state of geography today? It is in a mess – hyphenated, obfuscated, as confused as it is confusing. Why? Society is itself degenerating. The culture is coarse, vulgar, prostituted, chaotic, ‘dummied down’. We are in desperate need of intellectual reinforcements, and geography can help some.
</p></blockquote>
</li>
</ul>
<h5>Letters to the editor</h5>
<ul>
<li>&#8220;A Geological Decision&#8221; (1962) <em>Iowa Defender</em> (Iowa City underground newspaper, 1959-1970), 5 January, 1, 3, 4</li>
<li><a href="http://select.nytimes.com/gst/abstract.html?res=F10E14FA3C5F147A93C5AB178DD85F418685F9&#038;scp=1&#038;sq="william%20bunge"&#038;st=cse">&#8220;When to Organize&#8221;</a> (1965) <em>New York Times</em>, 27 June, E11</li>
<li><a href="http://select.nytimes.com/gst/abstract.html?res=F00917FC3B5812738DDDA10994D0405B858AF1D3&#038;scp=3&#038;sq="william%20bunge"&#038;st=cse">&#8220;Soviet Consumption&#8221;</a> (1965) <em>New York Times</em>, 18 August, pp. 34</li>
</ul>
<h4>By others</h4>
<p>Bunge has been covered in many divergent sources &#8212; below are just a few.</p>
<h5>Articles</h5>
<ul>
<li>
Ronald J. Horvath (1971) <a href="http://www3.interscience.wiley.com/journal/119692922/abstract">&#8220;The &#8216;Detroit Geographical Expedition and Institute&#8217; Experience&#8221;</a>. <em>Antipode</em> 3, 1, 1
</li>
<li>Richard Peet (1977) &#8220;The development of the radical geography in the United States&#8221; in R. Peet (dir.) <em>Radical Geography, alternatives viewpoints on contemporary social issues</em>. Chicago: Maaroufa Press</li>
<li>A. Merrifield (1995) <a href="http://www3.interscience.wiley.com/journal/119241006/abstract">&#8220;Situated Knowledge through Exploration: Reflections on Bunge&#8217;s &#8216;Geographical Expeditions&#8217;&#8221;</a>. <em>Antipode</em> 27, no. 1, pp. 49-70</li>
<li>K.R. Cox (2001) <a href="http://phg.sagepub.com/cgi/pdf_extract/25/1/71">&#8220;Classics in human geography revisited: Bunge, W., <em>Theoretical Geography</em>. Commentary 1.&#8221;</a> <em>Progress in Human Geography</em> 25, no. 1, pp. 71-73</li>
<li>
M.F. Goodchild (2008) <a href="http://www.geog.ucsb.edu/~good/papers/450.pdf">&#8220;William Bunge&#8217;s <em>Theoretical Geography</em>&#8221; [pdf]</a>. In P. Hubbard, R. Kitchin, and G. Valentine, editors, <em>Key Texts in Human Geography</em>. Los Angeles: SAGE, pp. 9–16. [450]
</li>
</ul>
<h5>Blog posts</h5>
<ul>
<li><a href="http://cyberbadger.blogspot.com/">Cyber Badger Research Blog</a> (by <a href="http://www.sed.manchester.ac.uk/geography/staff/dodge_martin.htm">Martin Dodge</a>): <a href="http://cyberbadger.blogspot.com/2006/10/william-bunges-nuclear-war-atlas-i-got.html">&#8220;William Bunge&#8217;s <em>Nuclear War Atlas</em>&#8220;</a> (October 2006)
</li>
<li><a href="http://newmapsofulster.blogspot.com/">New Maps of Ulster</a>: <a href="http://newmapsofulster.blogspot.com/2008/06/often-i-get-interlibrary-loan-via.html">&#8220;William Bunge&#8221;</a> (June 2008)</li>
<li>John Krygier&#8217;s <em>Making Maps</em> blog: <a href="http://makingmaps.net/2009/06/06/making-advocacy-humanitarian-maps/">&#8220;Making Advocacy &#038; Humanitarian Maps&#8221;</a> (June 2009)</li>
<li>Le Monde diplomatique: <a href="http://blog.mondediplo.net/2009-12-29-William-Bunge-le-geographe-revolutionnaire-de">&#8220;William Bunge, <em>le géographe révolutionnaire de Detroit</em>&#8220;</a> (December 2009)</li>
</ul>
<div class="centerIMG"><img src="http://indiemaps.com/images/williamBunge/bunge.png" alt="William Bunge in the mid-1960s" /></div>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2010/03/wild-bill-bunge/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building topology in Flash</title>
		<link>http://indiemaps.com/blog/2010/01/building-topology-in-flash/</link>
		<comments>http://indiemaps.com/blog/2010/01/building-topology-in-flash/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 05:27:32 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[bitmap]]></category>

		<category><![CDATA[BitmapData.threshold()]]></category>

		<category><![CDATA[borders]]></category>

		<category><![CDATA[cartograms]]></category>

		<category><![CDATA[circular cartograms]]></category>

		<category><![CDATA[collision detection]]></category>

		<category><![CDATA[color]]></category>

		<category><![CDATA[dorling]]></category>

		<category><![CDATA[flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[game development]]></category>

		<category><![CDATA[generalization]]></category>

		<category><![CDATA[GIS]]></category>

		<category><![CDATA[mapping]]></category>

		<category><![CDATA[mathematics]]></category>

		<category><![CDATA[raster]]></category>

		<category><![CDATA[topology]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=106</guid>
		<description><![CDATA[
For a while now, I&#8217;ve wanted to build geographic topology in Flash.  Topology, as described in an ESRI white paper, is
a set of rules and behaviors that model how points, lines, and polygons share geometry.  For example, adjacent features, such as two counties, will share a common edge. 
For the applications I&#8217;ve had [...]]]></description>
			<content:encoded><![CDATA[<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/rgb.png" alt="" /></div>
<p>For a while now, I&#8217;ve wanted to build geographic topology in Flash.  Topology, as described in an <a href="http://www.esri.com/library/whitepapers/pdfs/gis_topology.pdf">ESRI white paper</a>, is</p>
<blockquote><p>a set of rules and behaviors that model how points, lines, and polygons share geometry.  For example, adjacent features, such as two counties, will share a common edge. </p></blockquote>
<p>For the applications I&#8217;ve had in mind, polygonal or areal topology is all that&#8217;s required: I need to know which features share a common border with which features. As a bonus, it&#8217;d be nice to know how long a border they share (how contiguous are they?). </p>
<p>Described further down is a raster method to determine vector feature adjacency. First, though, I&#8217;ll cover why such information must be built in the first place and how it is useful for certain cartographic applications.</p>
<h3>Application to cartography and visualization</h3>
<p>Topology needs to be built because it is not encoded in the most popular vector GIS formats (KML and the shapefile).  In these formats, features (states or counties perhaps) are all stored separately; redundant points (like the shared corner of the &#8220;four corners&#8221; states) are repeated. There <em>are</em> topological GIS formats, like <a href="http://indiemaps.com/blog/2009/02/e00parser-an-actionscript-3-parser-for-the-arcinfo-export-topological-gis-format/">Arc/Info Export (e00)</a>, but geospatial data are rarely distributed in such formats.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/mapAndGraph.png" alt="" /></div>
<p>One potential use for topological information is graph decomposition.  Dasgupta <em>et al</em> write in <a href="http://www.cs.berkeley.edu/~vazirani/algorithms.html"><em>Algorithms</em></a>:</p>
<blockquote><p>A wide range of problems can be expressed with clarity and precision in the concise pictorial language of graphs. For instance, consider the task of coloring a political map. What is the minimum number of colors needed, with the obvious restriction that neighboring countries should have different colors? One of the difficulties in attacking this problem is that the map itself, even a stripped-down version like Figure 3.1(a), is usually cluttered with irrelevant information: intricate boundaries, border posts where three or more countries meet, open seas, and meandering rivers. Such distractions are absent from the mathematical object of Figure 3.1(b), a graph with one <em>vertex</em> for each country (1 is Brazil, 11 is Argentina) and <em>edges</em> between neighbors. It contains exactly the information needed for coloring, and nothing more.</p></blockquote>
<p>The simple graph above is two steps away from a circular cartogram of the form popularized by Daniel Dorling. On such maps, 1) feature circles are sized according to some numeric attribute, and neighbors &#8212; instead of being connected by lines &#8212; are 2) iteratively moved together or apart so that adjacencies are maintained where possible while avoiding circle overlap. The circular cartogram below is a snapshot of a <a href="http://www.nytimes.com/interactive/2008/08/04/sports/olympics/20080804_MEDALCOUNT_MAP.html">NY Times interactive app</a> developed in part <a href="http://leebyron.com/how/2008/08/09/olympic-medals-cartogram/">by Lee Byron</a>.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/nyTimesDorling.png" alt="" /></div>
<p>In addition to knowing the neighbors of all features, <a href="http://indiemaps.com/blog/2008/01/dorlingpy/">Daniel Dorling&#8217;s original algorithm</a> requires as input the shared border lengths of all contiguous features. These are used in the force-repulsion algorithm &#8212; while attempting to maintain all feature adjacencies, Dorling&#8217;s algorithm applies extra attraction forces to features that share relatively longer borders.</p>
<p>In cartography, topology has much value beyond that described above.  Generalization immediately comes to mind; to generalize/simplify/smooth the outline of a polygonal feature, one must also consider the feature&#8217;s neighbors.  If the cartographer fails to do so, gaps may be created where features previously neatly adjoined. That noted, I should say that the method described here &#8212; while quite accurate in evaluating adjacencies &#8212; can only determine adjacency and relative (pixel-based) feature overlap, whereas polygonal shapefile generalization necessitates a true (and computationally intensive) topological indexing of each and every coordinate in the dataset. More on this later.</p>
<h3>Method</h3>
<p>Features stored in KML and shapefiles are defined by a series of latitude-longitude coordinates.  The brute force method of determining if two features are topological neighbors would be to loop through their coordinates searching for an exact match.  Not only would this be quite computationally intensive, but it wouldn&#8217;t detect true neighbors that were digitized independently; a shared border does not necessarily mean that the two features are defined using the exact same control points.</p>
<p>Of course it can be done.  Most GIS software today will accurately build topology from a non-topological data source.  The NY Times&#8217; <a href="http://maps.grammata.com/">Matt Bloch</a> detailed a server-side method in his Wisconsin (natch) Cartography MS thesis (as well as a <a href="http://www.geography.wisc.edu/~harrower/pdf/AUTOCARTO_06_Bloch_Harrower.pdf">2006 AUTOCARTO proceedings paper</a>), used in his <a href="http://mapshaper.org/">MapShaper</a> app, for essentially converting a polygonal shapefile to a non-redundant polyline shapefile.  Though more efficient than simple brute force, these applications still rely on algorithms that require a large number of computations, and this scales up quickly as features get more complex.  This is why topology is always built server-side.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/arkansasTopologyTest.png" alt="" /></div>
<p>The method I settled on is similar to <a href="http://www.gamedev.net/reference/articles/article735.asp">pixel-based collision detection</a> (also called &#8220;pro pixel collision&#8221; or &#8220;pixel-perfect collision&#8221;) familiar to game developers.  In Flash, hitTests are only possible with specific points.  To test for overlap of complex polygonal features, game developers have often relied on a pixel-level bitmap test for overlap.  As described in an <a href="http://troygilbert.com/2007/06/pixel-perfect-collision-detection-in-actionscript3/">article by Troy Gilbert</a>,</p>
<blockquote><p>It&#8217;s pretty straightforward: you render two display objects to separate color channels, combine the color channels, then search the resulting image for any overlapping color.</p></blockquote>
<p>I first encountered the technique in a <a href="http://www.gskinner.com/blog/archives/2005/08/flash_8_shape_b.html">post by Grant Skinner</a> describing a method for shape-based collision detection in Flash published in 2005. GSkinner&#8217;s method doesn&#8217;t work <em>as is</em> in detecting adjacency in geographic features drawn from shapefiles. But with a few additions, the method is quite accurate and efficient in detecting feature neighbors in real-time. Try it out:</p>

<object	type="application/x-shockwave-flash"
			data="http://indiemaps.com/flash/bitmapTopology/FlashTopologyTest.swf"
			base="http://indiemaps.com/flash/bitmapTopology/"
			width="850"
			height="400">
	<param name="movie" value="http://indiemaps.com/flash/bitmapTopology/FlashTopologyTest.swf" />
	<param name=base" value="http://indiemaps.com/flash/bitmapTopology/" />
</object>
<h4>Some code</h4>
<p>This isn&#8217;t really fully developed.  It&#8217;s just something I&#8217;ve been thinking about for a while and wanted to get out there.  <a href="http://indiemaps.com/flash/bitmapTopology/AdjacencyTest.as">Here though</a> is a class I wrote to perform this pixel-based adjacency testing, as used in the above demo. It contains two chief public static methods:</p>
<ul>
<li><span class="incode">getNeighborsForFeature()</span>: Returns a Vector of DisplayObject features determined to be neighbors of the passed-in feature (from a passed-in Vector of all features)</li>
<li><span class="incode">checkFeatureAdjacency()</span>: Checks the two passed-in DisplayObject features for adjacency.  Returns the number of overlapping pixels.</li>
</ul>
<h4>How it works</h4>
<p>To test for adjacency, features are drawn to a bitmap.  The second feature is overlain using the <a href="http://en.wikipedia.org/wiki/Blend_modes#Difference"><em>difference</em> blend mode</a>. Any pixels shared by both features will now be lighter than before; I can check for such pixels using the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#threshold()"><span class="incode">BitmapData.threshold()</span></a> method.</p>
<p>Adjacent features, though, will only overlap if they&#8217;ve been drawn with an external stroke. The two methods above accept a <span class="incode">strokeWidth</span> parameter.  If this is less than 2 (features with external strokes of 1 sometimes fail to detect overlap accurately), I apply a precise GlowFilter to each raster.  This increases accuracy but affects performance; though it&#8217;s not necessary, the methods perform best when features are initially drawn with a 2px stroke (as in the demo above).</p>
<h3>Limitations</h3>
<h4>Accuracy</h4>
<p>This method is quite accurate for most realistic geographies.  But of course it&#8217;s all dependent on 1) the scale and complexity of your data and 2) the size of the BitmapData instance used for testing.  One particular area of concern is features that share a corner but no actual border line segments. In some applications, these should be considered neighbors; in others, not.  With a large enough BitmapData, such adjacencies will be detected.  </p>
<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/sharedCorner.png" alt="" /></div>
<p>If such features should not be considered neighbors in your application, a threshold may be set.  <span class="incode">checkFeatureAdjacency()</span> returns the number of overlapping pixels; if this number is sufficiently low, features can be considered non-adjacent.</p>
<h4>Performance</h4>
<p>I haven&#8217;t done any real performance tests, but the method works fine, in a test with the 3000+ U.S. counties drawn from a large-scale shapefile in Firefox on my MacBook; neighbor detection was detected in real-time and nothing was cached.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/bitmapTopology/countyTopology.png" alt="" /></div>
<p>As noted above, the methods perform fastest when features are initially drawn with a 2px stroke.  If the methods are to be called repeatedly, it&#8217;s best to pass in shared BitmapData instances to be used for testing; the larger the BitmapData instance, the greater the accuracy, though this is offset by increased processing time for the BitmapData instance methods. No matter what you pass in, though, this raster-based method is far faster than any true coordinate-based adjacency testing algorithm (important b/c it is being performed client-side).</p>
<h4>Generalization</h4>
<p>This method simply doesn&#8217;t work for generalization (simplification or smoothing of feature border linework). Such processes require knowledge of all shared line segments, necessitating true coordinate-based topology building; my method only returns the number of overlapping pixels, which only correlates with actual shared border length (this, though, is sufficient information for the Dorling circular cartogram algorithm).</p>
<p>But I hope it&#8217;s useful for at least a few visualization applications.  True topological indexing is best; but this computationally intensive process cannot yet be performed client-side in Flash. I&#8217;ll be working with these methods in the future, most likely in an implementation of Dorling&#8217;s circular cartograms in <a href="http://indiemapper.com/">indiemapper</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2010/01/building-topology-in-flash/feed/</wfw:commentRss>
		</item>
		<item>
		<title>the first thematic maps</title>
		<link>http://indiemaps.com/blog/2009/11/the-first-thematic-maps/</link>
		<comments>http://indiemaps.com/blog/2009/11/the-first-thematic-maps/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 04:22:03 +0000</pubDate>
		<dc:creator>zach'ry</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Arthur Robinson]]></category>

		<category><![CDATA[cartogram]]></category>

		<category><![CDATA[cartography]]></category>

		<category><![CDATA[Charles Dupin]]></category>

		<category><![CDATA[choropleth]]></category>

		<category><![CDATA[dot density]]></category>

		<category><![CDATA[Edwin Halley]]></category>

		<category><![CDATA[Émile Levasseur]]></category>

		<category><![CDATA[flow maps]]></category>

		<category><![CDATA[Frère de Montizon]]></category>

		<category><![CDATA[Henry Drury Harness]]></category>

		<category><![CDATA[history]]></category>

		<category><![CDATA[isoline]]></category>

		<category><![CDATA[Joseph Minard]]></category>

		<category><![CDATA[Pieter Bruinsz]]></category>

		<category><![CDATA[proportional symbols]]></category>

		<category><![CDATA[symbology]]></category>

		<category><![CDATA[thematic mapping]]></category>

		<category><![CDATA[visualization]]></category>

		<category><![CDATA[William Playfair]]></category>

		<guid isPermaLink="false">http://indiemaps.com/blog/?p=100</guid>
		<description><![CDATA[Below&#8217;s a quick outline of the first maps created with six common cartographic symbologies. All of the below is out there, in books, articles, and blog posts.  Particularly helpful are Alan MacEachren&#8217;s 1979 article The Evolution of Thematic Cartography, Arthur Robinson&#8217;s Early Thematic Mapping in the History of Cartography (1982), Borden Dent&#8217;s thematic cartography [...]]]></description>
			<content:encoded><![CDATA[<p>Below&#8217;s a quick outline of the first maps created with six common cartographic symbologies. All of the below is out there, in books, articles, and blog posts.  Particularly helpful are Alan MacEachren&#8217;s 1979 article <a href="http://www.geovista.psu.edu/publications/MacEachren/MacEachren_Evolution_1979.pdf"><em>The Evolution of Thematic Cartography</em></a>, Arthur Robinson&#8217;s <a href="http://www.press.uchicago.edu/presssite/metadata.epl?mode=synopsis&#038;bookkey=3642990"><em>Early Thematic Mapping in the History of Cartography</em></a> (1982), <a href="http://en.wikipedia.org/wiki/Borden_Dent">Borden Dent&#8217;s</a> thematic cartography textbook, and Michael Friendly and Daniel J. Denis&#8217; <a href="http://datavis.ca/milestones/"><em>Milestones</em></a> chronology.  I couldn&#8217;t find a good modern summary, though, of these &#8220;firsts&#8221; of thematic cartography.  So I put a quick one together.</p>
<p>The six symbologies are <em>the</em> classic thematic cartography representation methods: choropleth, proportional symbol, dot density, flow, isarithmic, and cartogram.  Borden Dent&#8217;s great cartography textbook, in the section titled &#8220;Techniques of Quantitative Thematic Mapping&#8221;, dedicates a chapter to each of these symbologies, and to no others.  The classic Robinson textbook, as well as the modern Slocum <em>et al</em> one, also dedicate more space to these six representation methods than to any others.</p>
<h3>isoline</h3>
<p>The first isarithmic (representation of continuous phenomena using lines of equal value) map is <a href="http://datavis.ca/milestones/index.php?group=1700s&#038;mid=ms53">often ascribed to</a> Edwin Halley, with his <strong>1701</strong> isogonic contour maps of magnetic declination.  </p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/halley_isoline_1701.jpg" alt="Edwin Halley's (1701) isogonic contour map" /></div>
<p>Not so, as the symbology has been traced back to as early as <strong>1584</strong>. Robinson notes in <em>Early Thematic Mapping</em>:</p>
<blockquote><p>
The contour had tentative beginnings as early as the end of the sixteenth centruly in the form of lines of equal depth on a map of the River Spaarne made in 1584 by the Dutch surveyor Pieter Bruinsz.  The next use of the symbol came more than a hundred years later in 1697 by Pierre Ancellin&#8230;
</p></blockquote>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/bruinsz_isoline_1584.png" alt="the earliest known isoline or contour map, produced by Pieter Bruinsz in 1584" /></div>
<p>You can&#8217;t see too much in the above &#8212; a terrible scan I made from Robinson&#8217;s<em> Early Thematic Mapping</em>.  This map isn&#8217;t listed on <a href="http://datavis.ca/milestones/"><em>Milestones</em></a>, nor could I find any reproductions of Bruinsz&#8217;s map on the internet. What I did find was a <a href="http://liber-maps.kb.nl/articles/15egmond15.jpg">detail image</a> of unknown provenance on the interesting site, <a href="http://liber-maps.kb.nl/articles/15egmond.html"><em>Dutch thematic maps on the web</em></a>.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/bruinsz_isoline_1584_detail.png" alt="detail of the earliest known isoline or contour map, produced by Pieter Bruinsz in 1584" /></div>
<p>On the above you can clearly see the dashed bathymetric line of equal depth.</p>
<h3>choropleth</h3>
<p>Frenchman <a href="http://en.wikipedia.org/wiki/Charles_Dupin">Charles Dupin&#8217;s</a> (<strong>1826</strong>) <a href="http://datavis.ca/milestones/index.php?group=1800%2B&#038;mid=ms99"><em>Carte figurative de l&#8217;instruction populaire de la France</em></a> is the first known choropleth map.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/classedCartograms/dupin1826.jpg" alt="the earliest choropleth map, produced by Charles Dupin in 1826" /></div>
<p>Dupin&#8217;s map was and is well known, and had a great impact on cartographers and statisticians at the time.  Interestingly, the particular form of Dupin&#8217;s choropleth map &#8212; the unclassed variety, in which each unique value gets a unique shade &#8212; didn&#8217;t stick.  The classed variety quickly took hold, with the first such map appearing in an <strong>1828</strong> Prussian atlas, <em>Administrativ-Statistischer Atlas vom Preussischen Staatae</em>.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/prussianChoropleth_classed_1828.png" alt="the earliest classed choropleth, included in an 1828 Prussian atlas" /></div>
<p>Notice not the subtle lean in my scan (from Robinson since I couldn&#8217;t find it elsewhere), but the class breaks shown along the bottom.  The author of the thematic portion of the atlas is unknown.</p>
<h3>dot density</h3>
<p>Dupin&#8217;s fellow countryman Frère de Montizon is responsible for the first dot density map, <a href="http://datavis.ca/milestones/index.php?group=1800%2B&#038;mid=ms105"><em>Carte philosophique figurant la population de la France</em></a> (<strong>1830</strong>). </p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/montizon_dotMap_1830.png" alt="the earliest dot density map, produced by Frère de Montizon in 1830" /></div>
<p>Unlike Dupin, who is fairly well known, Robinson describes Montizon as a &#8220;mystery man&#8221;.  He continues,</p>
<blockquote><p>It is one of the accidents of history that Frère de Montizon&#8217;s invention of the thematic dot map should have gone completely unnoticed.  In terms of cartographic innovation it ranks with the isothermal map, yet as far as can be ascertained no reference to him or to his dot map was made by anyone well into the twentieth century&#8230;this basically simple, logical idea had to wait some thirty years to be reinvented and much longer than that to become generally known.
</p></blockquote>
<p>The symbology was &#8220;reinvented&#8221; by Thure Alexander von Mentzer in his <strong>1859</strong> map of population distribution in the Scandinavian peninsula.  I can&#8217;t find any reproductions of this map anywhere.</p>
<h3>proportional symbols</h3>
<p>The first known example of a proportional symbol map appeared in the <em>Atlas to Accompany Second Report of the Railway Commissioners, Ireland</em> (<strong>1837</strong>).  Though the atlas was apparently quite innovative with regard to thematic cartography, it went largely unnoticed due to limited distribution.</p>
<p>Here, Henry Drury Harness&#8217;s map of Irish population density from the atlas.</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/harness_propSymbols.png" alt="the earliest proportional symbol map, of Irish population, published by Henry Drury Harness in 1837" /></div>
<p>They&#8217;re a bit hard to make out in this horrible scan (again from Robinson &#8212; listed as part of his personal collection), but there they are: circles scaled according to population centered at various Irish cities. This wasn&#8217;t the first time that proportional circles had been used to convey data, but it was the first time it had been done on a map.  Notice the shading?&#8211; this is also one of the first <a href="http://astro.temple.edu/~jmennis/research/dasymetric/index.htm">dasymetric maps</a>.</p>
<h3>flow maps</h3>
<p>The following map is <a href="http://datavis.ca/milestones/index.php?group=1800%2B&#038;mid=ms113">more well known</a>, and could share the title of first proportional symbol map, as it appeared in the same <strong>1837</strong> atlas as the above map.  Here, the innovation is the use of line thickness to convey a quantitative value, in this case the traffic between Irish cities (again by Henry Drury Harness).</p>
<div class="centerIMG"><img src="http://indiemaps.com/images/firsts/harness_flowMap.png" alt="the earliest known flow map, produced by Henry Drury Harness in 1837" /></div>
<h3>cartogram</h3>
<p>I&#8217;ve <a href="http://indiemaps.com/blog/2008/12/early-cartograms/">written about this before</a>, so below&#8217;s a quick summary.</p>
<p>Many sources, including Dent&#8217;s text, point to <a href="http://en.wikipedia.org/wiki/Pierre_Émile_Levasseur">Émile Levasseur</a> as the originator of the value-by-area cartogram.  Levasseur included diagrammatic maps like the following <strong>1868</strong> map of Europe in his economic geography textbooks.</p>
<div class="centerIMG"><img src='/images/levasseur.png' alt='early diagrammatic map (supposedly first cartogram) by Levasseur' class='alignnone' /></div</p>
<p>The above map was reprinted <a href="http://www.jstor.org/pss/301591">by Funkhouser</a> in 1937 and by Waldo Tobler in his <a href="http://www.geog.ucsb.edu/~tobler/publications/pdf_docs/inprog/Thirtyfiveyears.pdf"><em>Thirty Five Years of Computer Cartograms</em></a>. In the latter, Tobler notes:</p>
<blockquote><p>This is a map of the countries of Europe in which each country is represented by a square whose size is proportional to the area of the country, and with countries in their approximately correct position and adjacency. Could this be called an equal area map? Or is it an equal area cartogram?</p></blockquote>
<p>I believe the former: that this should be considered a diagrammatic equal area map, but not a value-by-area cartogram.  Sara Fabrikant <a href="http://www.geog.ucsb.edu/~sara/html/research/pubs/fabrikant_cagis03.pdf">makes the case</a> for the German provenance of the first cartogram:</p>
<blockquote><p>Another notable and early European contribution to the thematic mapper&#8217;s toolbox is the value-by-area cartogram. Hermann Haack and H. Wiechel published a cartogram depicting election results from the German Reichstag in <strong>1903</strong> (cited in Eckert 1925).</p></blockquote>
<p>Haack and Wiechel&#8217;s map is indeed cited in Eckert&#8217;s famous <em>Die Kartenwissenschaft</em> volumes, but it isn&#8217;t reprinted there.  Nor is it clear that unit areas on their election maps represented something other than land area. The earliest true value-by-area cartogram that I&#8217;ve seen reproduced came by way of Professor John Krygier, who <a href="http://makingmaps.net/2008/02/19/1911-cartogram-apportionment-map/">reprinted</a> William Bailey&#8217;s <strong>1911</strong> population cartogram.</p>
<div class="centerIMG"><img src='/images/bailey-1911.png' alt='perhaps the first American cartogram' class='alignnone' /></div>
<p>I doubt the above is truly the first cartogram, and welcome any scans or references to true value-by-area cartograms that precede the 1911 map.</p>
<h3>conclusion</h3>
<p>Four of the six classic thematic cartography symbologies &#8212; choropleth, dot density, proportional symbol, and flow &#8212; originated between 1826 and 1837. Two of them &#8212; proportional symbol and flow &#8212; were initially produced by one man (Harness), and appeared in the same obscure railway atlas. All were refined in the 19th century, and only one (isolines) predate the century.</p>
<p>Conspicuously absent above are the names <a href="http://en.wikipedia.org/wiki/William_Playfair">William Playfair</a> and <a href="http://en.wikipedia.org/wiki/Charles_Joseph_Minard">Joseph Minard</a>.  Indeed, some sources still cite these well-known engineer-statisticians as the originators of the proportional symbol and flow symbologies.  Playfair may have been the first to use proportional (value-by-area) symbols (specifically circles) to represent quantitative data, but it wasn&#8217;t on a map.</p>
<p>Funkhouser <a href="http://www.jstor.org/pss/301591">credited</a> Minard with the invention of the flow symbology, ignoring Harness&#8217;s innovation eight years earlier:</p>
<blockquote><p>The second, called cartograms with bands (<em>cartogramme a bandes</em>), was originated simultaneously and independently by the French engineer, Minard, and the Belgian engineer, Belpaire, in 1845. This consists of colored bands or ribbons which follow the watercourses and railways on a map, the width of the band being proportional to the amount of traffic or number of passengers carried.</p></blockquote>
<p>It&#8217;s certainly the case, though, that Playfair paved the way for much thematic mapping experimentation in the early 19th C. and that Minard helped popularize the flow, proportional symbol, and choropleth symbologies.</p>
]]></content:encoded>
			<wfw:commentRss>http://indiemaps.com/blog/2009/11/the-first-thematic-maps/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
