<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>vis4.net &#187; coding</title>
	<atom:link href="http://vis4.net/blog/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://vis4.net</link>
	<description>The geeky side of information visualization</description>
	<lastBuildDate>Thu, 12 Jan 2012 22:59:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How To Avoid Equidistant HSV Colors</title>
		<link>http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/?piwik_campaign=rss&#038;piwik_kwd=3199</link>
		<comments>http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/?piwik_campaign=rss&#038;piwik_kwd=3199#comments</comments>
		<pubDate>Tue, 13 Dec 2011 13:35:25 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[featured]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=3199</guid>
		<description><![CDATA[As some of you pointed out in the comments of my last post, taking equidistant colors in the HSV color space is no solution for finding a set of colors that are perceived as equidistant. This post describes what's wrong with HSV and what we can do about this. Note that since this post contains [...]]]></description>
			<content:encoded><![CDATA[<p>As some of you pointed out in the comments of my last post, taking equidistant colors in the HSV color space is no solution for finding a set of colors that are <em>perceived</em> as equidistant. This post describes what's wrong with HSV and what we can do about this. Note that since this post contains interactive elements built on the latest web technologies, you might need a <a href="https://www.google.com/chrome">modern</a> <a href="http://www.mozilla.org/firefox/">browser</a> to get the most out of it.<br />
<span id="more-3199"></span></p>
<h2>What's so wrong with HSV?</h2>
<p>Well, the main problem is that the <strong>value</strong> component of HSV is just a measure for the <em>physical lightness</em> of color, but not for the <em>perceived brightness</em>. Thus, fully saturated yellow has the same "value" as blue. The same is true for the HSL color space. Here is a set of six colors of the same <em>value</em> to demonstrate this effect. The second row shows how the colors look after converting to grayscale via Photoshop.</p>
<p><img class="aligncenter size-full wp-image-3218" title="equivalue-hsv" src="http://vis4.net/blog/wp-content/uploads/2011/12/equivalue-hsv.png" alt="" width="306" height="51" /></p>
<p><img class="aligncenter size-full wp-image-3219" title="equivalue-hsv-grayscale" src="http://vis4.net/blog/wp-content/uploads/2011/12/equivalue-hsv-grayscale.png" alt="" width="306" height="51" /></p>
<p>Beside of this strong <em>hue-dependency</em> of brightness, there is also no linear brightness gradient within a single hue. For instance, in the following HSL color scale the brightness step between the second and the third red appears much bigger than the step between the 3th and 4th color. Even worse, this effect seems to differ across different hues, as the comparison to the blue scale shows.</p>
<p><img class="aligncenter size-full wp-image-3220" title="hsv-reds" src="http://vis4.net/blog/wp-content/uploads/2011/12/hsv-reds.png" alt="" width="309" height="53" /></p>
<p><img class="aligncenter size-full wp-image-3221" title="Bildschirmfoto 2011-12-12 um 22.35.07" src="http://vis4.net/blog/wp-content/uploads/2011/12/Bildschirmfoto-2011-12-12-um-22.35.07.png" alt="" width="309" height="54" /></p>
<p>After all, this should be enough reason to avoid equidistant HSV/HSL scales. But what options do we have instead?</p>
<h2>For the lazy ones: Use ColorBrewer</h2>
<p>So the question is, what shall we do about it? In the comments someone mentioned <a href="http://colorbrewer2.com/">ColorBrewer</a>, which is in fact a great solution for those who just want to get some colors without caring too much about the details. Here's a selection of sequential ColorBrewer scales.</p>
<p><img class="aligncenter size-full wp-image-3223" title="colorbrewer-scales" src="http://vis4.net/blog/wp-content/uploads/2011/12/Bildschirmfoto-2011-12-12-um-22.57.54.png" alt="" width="312" height="278" /></p>
<p>One drawback of this solution is that you're limited to a fixed number of colors. For each color scale, the collection gives you variants from 3 to 9 colors. Another drawback is that sticking to a predefined set of colors means giving away some artistic freedom. Also, and most importantly, it's not half as fun to pick existing solutions, isn't it?</p>
<h2>For the color geeks: Make friends with CIE L*a*b*</h2>
<p>At this point, you better prepare yourself for some ultimate color geekyness. Thanks to the <a href="http://davidad.net/colorviz/">gentle introduction of David Dalrymple</a>, I finally dared to enter the magic world of the <strong>CIE L*a*b*</strong> color space. To get a better understanding of this color model, I ported David's code to JavaScript and built a tiny Lab color selector. The vertical slider allows you to navigate through the space. Also you can change the x and y axis using the links next to the slider.</p>
<p><iframe style="border: 0pt none;" src="http://vis4.net/labs/colorvis/embed.html?m=lab" width="522" height="475"></iframe></p>
<p>In general, the<a href="http://en.wikipedia.org/wiki/Lab_color_space"> Lab color space</a> has one component for <strong>L</strong>ightness and two bipolar color components <strong>a</strong> (yellow-blue) and <strong>b</strong> (green-magenta). While the lightness ranges from 0% to 100%, determining the valid ranges for <em>a</em> and <em>b</em> is somewhat tricky.</p>
<p>The problem is that CIE L*a*b* contains more colors than are available in RGB. For instance, the "valid" range for <em>a</em> depends on the lightness and the second color channel. Another problem is that it's hard to select colors by mixing four colors. To get around those issues, David Dalrymple suggests a fancy transformation of the Lab space.</p>
<h2>CSL: Making CIE Lab more accessible</h2>
<p>The trick is easy. You use the <strong>a</strong> and <strong>b</strong> components to compute a color angle (hue) and a radius (saturation). Because it's not exactly the same as hue in HSV, it's named <strong>c</strong> (for chroma). Basically this gives this us the CSL color space (although I'm not sure how this is named in vis science).</p>
<p><iframe style="border: 0pt none;" src="http://vis4.net/labs/colorvis/embed.html?m=csl" width="522" height="475"></iframe></p>
<p>While the problem of non-existent colors still remains (especially if you increase saturation) this looks like something we can start to work with. For instance, if we take a look at equidistant CSL colors of the same lightness we get a much better result. Actually, if you'd convert this into grayscale again you get the exact gray value for all colors. Well, this is no big surprise, I bet Photoshop itself uses CIE L*a*b* for grayscale conversions.</p>
<p><img class="aligncenter" title="csl-equidistant" src="http://vis4.net/blog/wp-content/uploads/2011/12/csl-equidistant.png" alt="CSL" width="309" height="54" /></p>
<h2>Now, let's grab some colors..</h2>
<p>This is where the fun begins, so I'm glad you made it up to here. To learn more about the difference of equidistant colors across color spaces, I visualized the linear gradient in the color selector. Feel free to experiment with them and check how the <a href="http://vis4.net/labs/colorvis/embed.html?m=csl&amp;gradients=6" target="colpick">CSL</a> color space compares to other spaces like <a href="http://vis4.net/labs/colorvis/embed.html?m=lab&amp;gradients=6" target="colpick">LAB</a>, <a href="http://vis4.net/labs/colorvis/embed.html?m=hsv&amp;gradients=6" target="colpick">HSV</a>, <a href="http://vis4.net/labs/colorvis/embed.html?m=hsl&amp;gradients=6" target="colpick">HSL</a><!--, <a href="http://vis4.net/labs/colorvis/embed.html?m=hsi&amp;gradients=6" target="colpick">HSI--> or <a href="http://vis4.net/labs/colorvis/embed.html?m=rgb&amp;gradients=6" target="colpick">RGB</a>.</p>
<p><iframe style="border: 0pt none;" name="colpick" src="http://vis4.net/labs/colorvis/embed.html?m=csl&amp;gradients=6" width="522" height="532"></iframe></p>
<p><script type="text/javascript">// < ![CDATA[
// < ![CDATA[
 var c0, c1; function pUpdateGradient(fcol, tcol) { c0 = fcol; c1 = tcol; updateGradientFrame();         } function updateGradientFrame() {    if (frames['interpol'].setGradient != undefined)           frames['interpol'].setGradient(c0, c1);    else setTimeout(updateGradientFrame, 400); }
// ]]&gt;</script></p>
<p>Also, it's interesting to directly compare the interpolated colors across different color spaces:</p>
<p><iframe id="interpol" style="border: 0pt none;" name="interpol" src="http://vis4.net/labs/colorvis/interpolate.html" width="500" height="342"></iframe></p>
<h2>Nice! How do I get those colors?</h2>
<p>To make things easy, I packed everything up in a small JavaScript library named <a href="https://github.com/gka/chroma.js">chroma.js</a>. It has a simple yet powerful API,check out the <a href="https://github.com/gka/chroma.js">Github repository</a> to learn more. Since this is still in early beta phase, l'd appreciate if you <a href="https://github.com/gka/chroma.js/issues/new">document bugs</a> you may encounter.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1"><span class="co1">// most simple interpolation in CSL space</span>
chroma.<span class="me1">interpolate</span><span class="br0">&#40;</span><span class="st0">&quot;#383D41&quot;</span><span class="sy0">,</span> <span class="st0">&quot;#EFEE69&quot;</span><span class="sy0">,</span> <span class="nu0">0.5</span><span class="sy0">,</span> <span class="st0">'csl'</span><span class="br0">&#41;</span>.<span class="me1">hex</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> 
<span class="co1">// returns &quot;#5C9A7C&quot;</span>
&nbsp;
<span class="co1">// also, you can instantiate CSL colors directly </span>
chroma.<span class="me1">csl</span><span class="br0">&#40;</span><span class="nu0">60</span><span class="sy0">,</span> .7<span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span>.<span class="me1">hex</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// returns &quot;#C6A860&quot;</span></pre></div></div></div></div></div></div></div>


]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/avoid-equidistant-hsv-colors/?piwik_campaign=rss&#038;piwik_kwd=3199/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Matching Regions of GeoIP and Natural Earth</title>
		<link>http://vis4.net/blog/posts/piwik-matching-regions/?piwik_campaign=rss&#038;piwik_kwd=2939</link>
		<comments>http://vis4.net/blog/posts/piwik-matching-regions/?piwik_campaign=rss&#038;piwik_kwd=2939#comments</comments>
		<pubDate>Tue, 01 Nov 2011 14:45:57 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[geocitylite]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[naturalearth]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/posts/piwik-matching-regions/</guid>
		<description><![CDATA[In this post I'll describe the process of bringing together the region shapes from the Natural Earth dataset with the regions provided in the GeoCityLite database. In the GeoCityLite db, the regions are referenced by a two-letter ID (FIPS10-4 for some countries, ISO3366-2 for others). Initially I thought that those IDs would be same as [...]]]></description>
			<content:encoded><![CDATA[<p><!--:en-->In this post I'll describe the process of bringing together the region shapes from the Natural Earth dataset with the regions provided in the GeoCityLite database. In the GeoCityLite db, the regions are referenced by a <a href="http://www.maxmind.com/app/fips10_4">two-letter ID</a> (FIPS10-4 for some countries, ISO3366-2 for others). Initially I thought that those IDs would be same as used in the Geonames <a href="http://download.geonames.org/export/dump/admin1CodesASCII.txt">admin-level 1 region db</a>, which brought me to the first idea of mapping the regions via name similarity.</p>
<p><!--:--><span id="more-2939"></span><!--:en--></p>
<h2>Trying to match via region names..</h2>
<p>So, the basic idea was to use the region meta-data in the Geonames db to map the Natural Earth regions with the GeoCityLite db. Both Geonames and Natural Earth store different versions of the region names that could be thrown into a word similarity measurement like Levenshtein to compute similarities. Before I actually started to matches the regions I grabbed some statistics on the distribution of countries and region in both datasets. Here's a summary of the results:</p>
<p><img class="aligncenter" style="margin-top: 10px; margin-bottom: 10px;" title="overview" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-26-um-23.09.52.png" alt="" width="444" height="180" />In all datasets combined, a total of <strong>237</strong> countries is included. Of those countries, only <strong>90</strong> have the same number of region polygons and region meta-data (shown in green). The red slices represent countries that still have polygons and meta-data available, but there is either a surplus in region meta-data (<strong>46</strong>) or in region polygons (<strong>35</strong>). Finally, the blue slices represent countries that have no region polygons at all (<strong>60</strong>) or that have polygons but no meta-data (<strong>6</strong>).</p>
<p>To learn a little more about those countries, I displayed the results on a world map:</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2011/10/region-merging-map-01.png"><img class="aligncenter size-medium wp-image-3050" title="region-merging-map-01" src="http://vis4.net/blog/wp-content/uploads/2011/10/region-merging-map-01-522x291.png" alt="" width="522" height="291" /></a></p>
<p>However, I started the matching and created this more detailed map of coherence between Geonames and Natural Earth regions. Green means perfect matching (no regions left on both sides) while dark red means that almost no region could be mapped properly. The map reveals the differences between France and UK. In one case, only some island regions are missing while in the other case there's a complete mismatch between regions.</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2011/10/ne-admin1.png"><img class="aligncenter size-medium wp-image-3055" title="ne-admin1" src="http://vis4.net/blog/wp-content/uploads/2011/10/ne-admin1-522x269.png" alt="" width="522" height="269" /></a></p>
<h2>..and what I learned from this</h2>
<p>The good side of trying out the region name matching was that this made me aware of the UK case, which fundamentally changed my initial assumptions. To begin with, here's the region map of the UK regions in the Natural Earth shapefile:</p>
<p><img class="aligncenter size-full wp-image-3058" title="UK regions" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-31-um-13.53.58.png" alt="" width="520" height="356" /></p>
<p>The first thing I learned is that the Natural Earth regions are very detailed in some cases. In fact, they're too detailed to be useful for our purpose. The regions simply get too small to be clicked. The second thing I learned is that Geonames and Natural Earth have different definitions of administrative level 1 regions. While Geonames sees England, Scotland, Wales and Northern Ireland as first level regions, Natural Earth goes down to a very detailed level shown above. Then I checked if the GeoCityLite database also stores just the four UK "regions", which would be very sad because they're too general. And surprise, GeoCityLite uses different regions for UK.</p>
<p>The implications are that we need a completely different way of matching and that we need to merge regions in some countries to a reasonable degree.</p>
<h2>Merging too detailed regions</h2>
<p>To find out which countries regions need to be merged I looked at the countries that have the highest number of regions. This involves United Kingdom, Slovenia, Philippines, Macedonia and Uganda.</p>
<p>To merge the regions I used meta-data I (fortunately) found in the Natural Earth shapefile. For instance, the UK provinces (e.g. Derby) stored the name of the region they belong to (e.g. East Midlands). The actual merging was done by my good friend the Python Polygon package.</p>
<p>However, for Macedonia, the region names turned out to be incomplete, so I had to match the regions by hand using an overlay image I took from Wikipedia. Here's a screencast that shows me doing this:</p>
<p><object style="height: 300px; width: 520px;" width="520" height="300" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://www.youtube.com/v/QB2iLqT7NBw?version=3&amp;feature=player_detailpage" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><embed style="height: 300px; width: 520px;" width="520" height="300" type="application/x-shockwave-flash" src="http://www.youtube.com/v/QB2iLqT7NBw?version=3&amp;feature=player_detailpage" allowFullScreen="true" allowScriptAccess="always" allowfullscreen="true" allowscriptaccess="always" /></object></p>
<p>At the end, I got a CSV files that stores all regions that need to be joined along with the new region id. The data is used both for rendering the maps and in the next step of matching the GeoIP regions. For instance, here's how the merged regions look like for the United Kingdom:</p>
<p><img class="aligncenter size-full wp-image-3076" title="UK" src="http://vis4.net/blog/wp-content/uploads/2011/11/UK.png" alt="" width="332" height="317" /></p>
<h2>And, finally, matching the regions</h2>
<p>Since the definitions of what's an admin-level 1 region seem to vary across Natural Earth and GeoCityLite, I needed to use a more low-level approach to match the regions. Fortunately, the GeoCityLite db stores plenty of locations for each regions, which I used to match.</p>
<p>For every <em>source region</em> (GeoCityLite) I randomly selected five locations. Then I did point-in-polygon tests for each location with each of the <em>target regions</em> (Natural Earth), and the region that contains most of the locations probably is the one that matches the region.</p>
<p>I checked the accuracy by counting the number of matched regions:</p>
<ul>
<li>regions that matches to <strong>no</strong> target region: 73</li>
<li>regions that match to exactly <strong>one</strong> region: 2434</li>
<li>regions that match to <strong>two</strong> regions: 437</li>
<li>regions that match to <strong>three or more</strong> regions: ~140</li>
</ul>
<p>The cause of the <strong>missing matches</strong> could be that some regions are simply missing in the map (e.g. small island polygons). I think those cases can be ignored. Another reason could be that a country has been split up recently (like Sudan) and thus some regions couldn't be found.</p>
<p>The cause of the <strong>multiple matches</strong> is that some GeoCityLite regions are more general (or larger) than the regions in the Natural Earth map and one solution would be to merge the affected regions.</p>
<h2>Investigating the multiple matches</h2>
<p>So, again, let's look at the details of what we've done. Here's a close-up view on a case in Northern Germany where multiple map regions where matched to the same GeoLiteCity region. Obviously, in this case the cause is imprecision of the Natural Earth shapefile.</p>
<p><img class="aligncenter size-full wp-image-3071" title="region-matching-bremen" src="http://vis4.net/blog/wp-content/uploads/2011/10/region-matching-bremen.png" alt="" width="522" height="246" /></p>
<p>Here's another example, showing the Northern Switzerland where a region matched to four map regions. We can see that there are errors in the GeoLiteCity locations, too.</p>
<p><img class="aligncenter size-full wp-image-3072" title="region-match-che" src="http://vis4.net/blog/wp-content/uploads/2011/10/region-match-che.png" alt="" width="521" height="194" /></p>
<p>Looking at those examples, I think the best idea is to simply take the region that matches the most locations. We'll hopefully get some more feedback from local Piwik users.</p>
<p>As suspected, the locations for South Sudan still are assigned to Sudan in the GeoLiteCity database, which is going to be fixed.</p>
<p><img class="aligncenter size-full wp-image-3073" title="sudan" src="http://vis4.net/blog/wp-content/uploads/2011/10/sudan.png" alt="" width="247" height="293" /></p>
<p>At the end, I'm quite happy with this solution. Next time, I will start to write the JS code that "renders" the SVG maps using RaphaelJS and that also allows to display some data – either region-based or location-based – in the map.</p>
<h2 id="update">Update 1</h2>
<p>I further investigated the "missing" regions that can't be matched to any of the map polygons. For instance, here's a close-up view on Southern England, where some regions couldn't be matched. The reason is that the locations are a little bit outside the polygon.</p>
<p><img class="aligncenter size-full wp-image-3081" title="gbr-missing2" src="http://vis4.net/blog/wp-content/uploads/2011/11/gbr-missing2.png" alt="" width="367" height="129" /></p>
<p>The core of the problem is that the data is not accurate enough: either the region outline or the location coordinates are wrong. An easy fix is to build this inaccuracy into the matching algorithm. Since we don't know the <em>exact</em> coordinates of a given GeoIP location, the same location could as well be moved (slightly) in any direction. The algorithm now also checks the neighborhood for each point, which reduced the number of missing regions to 14.</p>
<p><img class="aligncenter size-full wp-image-3082" title="jittering" src="http://vis4.net/blog/wp-content/uploads/2011/11/Bildschirmfoto-2011-11-03-um-10.41.16.png" alt="" width="328" height="150" /></p>
<p>The remaining missing regions are due to missing polygons for small island parts of countries like the United States or Finland:</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2011/11/Bildschirmfoto-2011-11-03-um-13.11.37.png"><img class="aligncenter size-full wp-image-3087" title="Missing regions in Southern Finland" src="http://vis4.net/blog/wp-content/uploads/2011/11/Bildschirmfoto-2011-11-03-um-13.11.37.png" alt="" width="422" height="118" /></a><!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/piwik-matching-regions/?piwik_campaign=rss&#038;piwik_kwd=2939/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[Recreating the Piwik Maps in SVG]]></series:name>
	</item>
		<item>
		<title>Rendering SVG Country Maps in Python</title>
		<link>http://vis4.net/blog/posts/rendering_country_maps/?piwik_campaign=rss&#038;piwik_kwd=3020</link>
		<comments>http://vis4.net/blog/posts/rendering_country_maps/?piwik_campaign=rss&#038;piwik_kwd=3020#comments</comments>
		<pubDate>Wed, 26 Oct 2011 09:30:09 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[cartography]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/posts/rendering_country_maps/</guid>
		<description><![CDATA[In this post I will explain the rendering process of the Piwik country maps. The results will basically look like this: Getting the viewport The first step of drawing a map is to define the viewport, which is a rectangle containing the geometry that will be visible in each map. To simplify things a lot, [...]]]></description>
			<content:encoded><![CDATA[<p><!--:en-->In this post I will explain the rendering process of the Piwik country maps. The results will basically look like this:</p>
<p><img title="FR" src="http://vis4.net/blog/wp-content/uploads/2011/10/FR1.png" alt="" width="520" height="311" /><br />
<span id="more-3020"></span></p>
<h2>Getting the viewport</h2>
<p>The first step of drawing a map is to define the viewport, which is a rectangle containing the geometry that will be visible in each map. To simplify things a lot, we decided to use a fixed aspect ratio for the maps. What we need next is a way to get the outer bounding box of the countries.</p>
<p>The simple approach is to use the lat/lon bounding box, but this actually doesn't work for the orthographic projection, as the minimum latitude of a country doesn't necessarily correspond with the minimum y of the projected country. For instance, the following image shows the lat/lon bounding box of China:</p>
<p><img title="lat/lon bbox china" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-13.19.37.png" alt="" width="522" height="342" /></p>
<p>Instead, you need to project the polygons first, and then compute the bounding box in x/y space. As explained in the last post, I will use the orthographic projection. To avoid distortions and ensure that the country is fully visible, the <strong>projection must be centered on the target country</strong>. For the computation of the center latitude and longitude I used the Polygon package (a Python wrapper around the GPC library) which provides a function for computation of center of gravity (also called <em>centroids</em>). <a href="https://gist.github.com/1315736">Code</a>.</p>
<p>Now we can project the country polygons and compute the exact bounding box, which then can be used to scale and position the map inside the viewport. Here's the bounding box of China, again:</p>
<p><img title="correct bounding box of China" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-13.22.05.png" alt="" width="522" height="331" /></p>
<p>However, while this approach works for most countries, other countries are a bit trickier to handle. As you can see in the next image, Spain has one big polygon commonly known as Spain along with several little polygons (islands) which located far away of the main country. This leads to a much bigger bounding box that we want, since in our scenario, we want the maps to be focused on the major part of each country. We have to find a better way to compute the bounding box.</p>
<p><img title="full bounding box of Spain" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-13.25.49.png" alt="" width="522" height="274" /></p>
<p>My first thought was to only consider the largest polygon when computing the bounding box. The shape area computation is done by a nice algorithm I found <a href="http://forum.worldwindcentral.com/showthread.php?t=20724">here</a> and was ported to Python <a href="https://gist.github.com/1267470">there</a>. Again, this works in many cases (like Spain, USA), but it won't work in other cases, like New Zealand:</p>
<p><img title="Wrong bounding box of New Zealand" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-13.38.23.png" alt="" width="522" height="264" /></p>
<p>My final solution was to compare each country polygon area with the maximum polygon area of that country. Every polygon below a fixed threshold (for instance 10% of the maximum polygon area) is discarded, which seem to work out very well. For five countries (including Japan), I had to manually change the threshold to get a nicer bounding box, which was faster and easier than spending more time in algorithm improvements.</p>
<p>&nbsp;</p>
<h2>Projection</h2>
<p>Now we can proceed with the actual projection of all visible countries. For the orthographic projection, I initially wanted to use the <a href="http://code.google.com/p/pyproj/">pyproj package</a>, a wrapper around the de facto 'gold standard' PROJ.4. Unfortunately, the design of the map requires that the client-side also needs to be able to perform projections. Therefore, I would have to port parts of the PROJ.4 code to JavaScript, which is something <a href="http://vis4.net/blog/posts/as3-proj/">I've done before in ActionScript</a> and actually don't want to do again. Instead, I found a nice and simple <a href="http://www.mccarroll.net/snippets/svgworld/#orthographic">Python implementation of the orthographic projection</a> by <a href="http://www.mccarroll.net">Niall McCarroll</a>, which was very easy to port to JavaScript.</p>
<p>Using this class it was very easy to render such a beautiful globe in SVG:</p>
<p><a href="http://vis4.net/tmp/globe.svg"><img title="globe" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-14.08.48.png" alt="" width="412" height="410" /></a></p>
<p>The bounding boxes computed in the last step are now used to detect all countries that (probably) intersect our viewport. This is important to know because we need to reduce the data to keep the rendering time low. To give the country a little more context, the bounding boxes are inflated by 30% and then centered inside the viewport. Now every countrys bounding box is checked for  intersections with the viewport.</p>
<p><img title="viewport" src="http://vis4.net/blog/wp-content/uploads/2011/10/viewport1.png" alt="" width="401" height="241" /></p>
<p>The basic idea now is to render the inner-country administrative boundaries for the focus country and the national boundaries for the neighbor countries. At the end of this step, we end up with a map like this.</p>
<p><img title="France, unclipped" src="http://vis4.net/blog/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-24-um-14.31.04.png" alt="" width="522" height="445" /></p>
<h2>Polygon simplification and clipping</h2>
<p>What you can't see in the above screenshot is that the resulting SVG file has a size of 578kB, which is way to much given the fact that we need to store more than 200 maps. I actually agreed with the Piwik core developers that the zipped final size of the SVG maps should not 1 megabyte. So, what we need to do is to simplify or <em>generalize</em> the polygons.</p>
<p>There are several algorithms for polygon simplification, like the ones by <a href="http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm">Douglas &amp; Peuker</a> and <a href="http://www2.dcs.hull.ac.uk/CISRG/projects/Royal-Inst/demos/mahes.html">Visvalingam</a>, but I used a very fast and simple one. Actually, it's the same algorithm that <a href="http://vis4.net/blog/posts/simplification-of-country-outlines/">I used a few years ago</a>, when I <a href="http://vis4.net/blog/posts/rendering-world-maps-in-as3/">rendered my first world maps in Flash</a>.</p>
<p><img title="simplification" src="http://vis4.net/blog/wp-content/uploads/2011/10/simplification.png" alt="" width="522" height="400" /></p>
<p>Since we don't need the surrounding countries in the same quality as the focus country, I used different qualities for the simplification, which is great for reducing the map size. After simplification, the file size has reduced to 21kB or 3%.</p>
<p>The next task was to throw away everything that lays outside of the viewport. It's important to do this after simplification since otherwise the simplification could destroy the viewport borders.</p>
<p>To clip the polygons to the viewport I used the <a href="http://polygon.origo.ethz.ch/">Python Polygon package</a> again, which allows for syntactic sugar like this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="python"><pre class="de1">clippedPoly <span class="sy0">=</span> polygon &amp;amp<span class="sy0">;</span> viewport</pre></div></div></div></div></div></div></div>


<h2>Conclusion</h2>
<p>After clipping, I rendered the polygons as <a href="http://vis4.net/tmp/FRA.svg">SVG file</a> to get the final map. The final <a href="http://vis4.net/tmp/all_maps.zip">zip-file with  all 238 country maps</a> is 840kB.</p>
<p><img title="FR" src="http://vis4.net/blog/wp-content/uploads/2011/10/FR1.png" alt="" width="520" height="311" /></p>
<p>In the next post I will write about how to connect the region ids of the Natural Earth shapefile with the region ids of the GeoIP database.</p>
<h2>Update (Nov. 3)</h2>
<p>Instead of the Orthographic projection, the maps now are projected using the <a href="http://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection_4nAJ9A&amp;sig2=UXwl4kHA1ZFdFtU-eVaT3w&amp;cad=rja">Lambert Azimuthal Equal Area</a> projection, which is widely used in cartography. For most countries, the differences are invisible, but the surrounding of larger countries like Russia look much less distorted.<!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/rendering_country_maps/?piwik_campaign=rss&#038;piwik_kwd=3020/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[Recreating the Piwik Maps in SVG]]></series:name>
	</item>
		<item>
		<title>Moving on with the Piwik Maps</title>
		<link>http://vis4.net/blog/posts/moving-on-with-the-piwik-maps/?piwik_campaign=rss&#038;piwik_kwd=2874</link>
		<comments>http://vis4.net/blog/posts/moving-on-with-the-piwik-maps/?piwik_campaign=rss&#038;piwik_kwd=2874#comments</comments>
		<pubDate>Thu, 06 Oct 2011 22:56:50 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[cartography]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[sketch]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/posts/moving-on-with-the-piwik-maps/</guid>
		<description><![CDATA[Here's a short documentation of my current progress in re-creating the Piwik maps in SVG/JS. Since we're going to create at least one pre-generated map source file per country, file size is going to be an important issue. That's why we thought about removing all polygons whose area is below a certain threshold, say 10 [...]]]></description>
			<content:encoded><![CDATA[<p><!--:en-->Here's a short documentation of my current progress in <a href="http://vis4.net/blog/posts/recreating-the-piwik-map/">re-creating the Piwik maps in SVG/JS</a>. Since we're going to create at least one pre-generated map source file per country, file size is going to be an important issue. That's why we <a href="http://dev.piwik.org/trac/ticket/1652#comment:26">thought about</a> removing all polygons whose area is below a certain threshold, say 10 square km.<br />
<!--:--><span id="more-2874"></span><!--:en--></p>
<h2>What to do with those tiny island states?</h2>
<p>To get started I opened a world shapefile and computed the areas of all 3761 polygons (multiple polygons per countries). Filtering every polygon smaller than 10 square km would remove 434 polygons, or 11% of the polygons. I checked the names of the countries which the removed polygons belong to and found many island states among them (as expected).</p>
<p>However, I think a hard cut at 10 sq km has some problems: One the one hand it removes some countries entirely (like the Maldives Islands) while still keeping many very many small islands (starting from 11sqkm). Click image to zoom.</p>
<p><a href="http://vis4.net/tmp/world-hardcut.png"><img class="  alignnone" title="World minus every polygon smaller than 50 square km" src="http://vis4.net/tmp/world-hardcut.png" alt="" width="511" /></a></p>
<p>Then I tried a different rule: remove all polygons smaller than 5% of the maximum polygon area of that country. Since the maximum area of the Maldives is 9sqkm, all islands are kept, while all small islands of the USA are removed. Also this halved the resulting SVG file size keeping the map correct in terms of includedness of countries.</p>
<p><a href="http://vis4.net/tmp/world-softcut.png"><img class="  alignnone" title="World minus every polygon smaller 1% of the maximum country area" src="http://vis4.net/tmp/world-softcut.png" alt="" width="511" /></a></p>
<p>However, removing every polygon smaller than 5% of the maximum per country is not satisfactory as well. Big and also well-known islands like Hawaii or <a href="http://en.wikipedia.org/wiki/Novaya_Zemlya"> Novaya Zemlya</a> shouldn't be removed in my opinion. Finally I came up with a combination of both rules: remove every polygon smaller than the minimum of x square km and 5% of the maximum area per country. This removes the small and unimportant islands but keeps the tiny island states.</p>
<p><a href="http://vis4.net/tmp/maldives.png"><img class="alignleft" src="http://vis4.net/tmp/maldives.png" alt="" width="80" height="264" /></a></p>
<p>Being very happy with this solution I looked at the Maldives islands for the first time (those black little dots on the left). Obviously, the islands seem to be way too small to be rendered in a meaningful way. This leads to this important question:</p>
<p><em>Does the map need to include all countries or is it acceptable to ignore some countries, like the Maldives Islands? </em></p>
<p>In the old map widget this wasn't important because there was no country level view.</p>
<h2 style="clear: both;">One projection for all countries?</h2>
<p>A few thoughts regarding the projection that's going to be used for the country-level views. I would like to simplify the whole thing by using the same projection for every country, but with different parameters (namely the projection center).</p>
<p>One of the simpler projections is the <a href="http://en.wikipedia.org/wiki/Orthographic_projection_%28cartography%29">orthographic projection</a>, which looks the same as if looking onto a 3D globe. This gives quite good and less-distorted views for almost every country. The only country that looks quite distorted is Russia.</p>
<p><a href="http://vis4.net/tmp/russia.png"><img class="alignnone" title="Russia is getting a bit distorted in the orthographic projection" src="http://vis4.net/tmp/russia.png" alt="" height="264" /></a></p>
<p>My opinion is that this distortion is acceptable given the simplicity of rendering maps in a single projection. In an ideal mapping world, however, one would use specialized projection for every country, like the New Zealand Map Grid for New Zealand etc.</p>
<h2>Fixed vs. dynamic aspect ratio</h2>
<p>The next design decision has to do with the aspect ratio of the maps. At some point in the map generation process I need to crop the country-level maps to a bounding box. The idea is to fit the countries as big as possible into the views while also showing a bit of their neighbour countries for navigation.</p>
<p>Now the question arises to which aspect ratio the maps should be cropped. As far as I see do we have to options:</p>
<ol>
<li>A <strong>fixed aspect ratio</strong> (presumably some wide-screenish format) would be the simplest solution. The complete cropping could be done in the preprocessing stage, which would reduce complexity of map rendering. However, the obvious drawback of this solution is that the maps won't look as good as they could when displaying countries in the "opposite" aspect ratio. For some portrait countries (like <a href="http://vis4.net/tmp/germany.png">Germany</a>), this should be acceptable. For other, more extreme aspect ratios (my favourite example is <a href="http://vis4.net/tmp/chile.png">Chile</a>) don't.</li>
<li>In the latter cases, a <strong>dynamic aspect ratio</strong> would make much more sense. It would be perfect if we could present the Chilean Piwik users (I assume there are some) with a portrait view of their country. Dynamic aspect ratios could be done either by choosing a fixed ratio per country or by cropping the maps at rendering time. Choosing a fixed ratio per country has the drawback that those countries could not fit a landscape ratio in fullscreen mode. In contrast, cropping at runtime may take more CPU. Also, I don't know if the current dashboard supports dynamic resizing of widgets, but this may be easy to implement.</li>
</ol>
<p><a href="http://vis4.net/tmp/chilean-dashboard.png"><img src="http://vis4.net/tmp/chilean-dashboard.png" width="522" title="Chilean users would love dynamic aspect ratios" /></a><!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/moving-on-with-the-piwik-maps/?piwik_campaign=rss&#038;piwik_kwd=2874/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<series:name><![CDATA[Recreating the Piwik Maps in SVG]]></series:name>
	</item>
		<item>
		<title>Transforming a Processing Sketch to HTML5</title>
		<link>http://vis4.net/blog/posts/transforming-a-processing-sketch-to-html5/?piwik_campaign=rss&#038;piwik_kwd=2844</link>
		<comments>http://vis4.net/blog/posts/transforming-a-processing-sketch-to-html5/?piwik_campaign=rss&#038;piwik_kwd=2844#comments</comments>
		<pubDate>Thu, 29 Sep 2011 14:32:45 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[visualized]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=2844</guid>
		<description><![CDATA[More for exercising than for competition reasons, I recently recreated a great Processing visualization by Ben Fry using HTML5. I had the strong feeling that the kind of animation is totally doable without plugins like Java and Flash. This post sums up what I learned. Initially I wanted to use the relatively new PaperJS library [...]]]></description>
			<content:encoded><![CDATA[<p><!--:en--><img src="http://vis4.net/blog/wp-content/uploads/2011/09/fortune5002.jpg" alt="" title="fortune500" width="522" height="185" class="aligncenter size-full wp-image-2850" /></p>
<p>More for exercising than for competition reasons, I recently recreated a great <a href="http://fathom.info/fortune500/">Processing visualization by Ben Fry</a> using HTML5. I had the strong feeling that the kind of animation is totally doable without plugins like Java and Flash. This post sums up what I learned.</p>
<p><!--:--><span id="more-2844"></span><!--:en--></p>
<p>Initially I wanted to use the relatively new <a href="http://paperjs.org">PaperJS</a> library for the animation part. I managed to use JQuery along with PaperJS, loaded the CSV file and started to draw all those company lines (500 per year for 55 years = 27500 lines). Since using the <a href="http://paperjs.org/reference/path">Path</a> for just drawing simple 1px lines would be way to much overhead, I grabbed the canvas context directly and used the "native" <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#simple-shapes-%28rectangles%29">fillRect()</a>. The drawing took around 900ms. Removing the PaperJS library reduced drawing time to 350ms. Then I replaced the fillRect() with direct pixel manipulation using <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation">getImageData()</a> and finally got to 50ms which is like 20 fps. </p>
<p>After showing this to the world, Moritz Stefaner reminded me to use <a href="https://developer.mozilla.org/en/DOM/window.mozRequestAnimationFrame">requestAnimationFrame</a> instead of setInterval(), which gave the visualization the final performance boost. </p>
<p>For drawing of the spline I could've used the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-beziercurveto">bezierCurveTo()</a> function, but this way I would have to hazzle around with the curve control points, which I didn't want to. Instead, I added another canvas "layer" on top, that is now used by PaperJS to draw the smoothed paths. Both apps communicate through a simple and global accessible API which allows the jQuery-app to draw, update and remove splines. This was fast enough to animate the curves.</p>
<p>The data is served as pure CSV and all parsing and data wrangling is done in JavaScript. Since the size of the data is 1.1MB, I told the web server to serve the CSV file gzipped using the .htaccess code below. This reduced the data size to 360kB.</p>
<pre>AddOutputFilterByType DEFLATE text/html text/plain text/csv</pre>
<p>After all, remaking an existing visualization was quite a fun thing to do. I learned some new things about working with HTML5 and finally had the chance to use the promising PaperJS library for the first time. Also, in Ben's initial version the profits view doesn't show companies with negative profits, which I didn't realize until I started working with the raw data myself. </p>
<p>If you're interested, here's the <a href="http://vis4.net/labs/fortune500">link to my version</a>. Also you're invited to inspect the <a href="http://vis4.net/labs/fortune500/fortune500.zip">source code and data</a>.<!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/transforming-a-processing-sketch-to-html5/?piwik_campaign=rss&#038;piwik_kwd=2844/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Generating Color Blindness Test Images with Processing</title>
		<link>http://vis4.net/blog/posts/color-blindness/?piwik_campaign=rss&#038;piwik_kwd=2611</link>
		<comments>http://vis4.net/blog/posts/color-blindness/?piwik_campaign=rss&#038;piwik_kwd=2611#comments</comments>
		<pubDate>Sun, 03 Jul 2011 20:46:42 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[sketch]]></category>
		<category><![CDATA[circle]]></category>
		<category><![CDATA[color]]></category>
		<category><![CDATA[color blindness]]></category>
		<category><![CDATA[icons]]></category>
		<category><![CDATA[nounproject]]></category>
		<category><![CDATA[packing]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=2611</guid>
		<description><![CDATA[My wife recently observed my two-year-old son eating green strawberries and is now curious if he has some kind of red-green color blindness. Unfortunately, he is not yet able to give us the name of numbers, so the commonly used Ishihara test images won't do. Well, I thought it´s a nice idea for this rainy [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://vis4.net/blog/wp-content/plugins/simple-post-thumbnails/timthumb.php?src=net/blog/wp-content/thumbnails/2611.png&amp;w=250&amp;h=0&amp;zc=1&amp;ft=png' alt='post thumbnail' /></p>
<p><!--:en-->My wife recently observed my two-year-old son eating green strawberries and is now curious if he has some kind of red-green color blindness. Unfortunately, he is not yet able to give us the name of numbers, so the commonly used <a href="http://www.colour-blindness.com/colour-blindness-tests/ishihara-colour-test-plates/">Ishihara test images</a> won't do. Well, I thought it´s a nice idea for this rainy Sunday afternoon to generate some of those images myself. Instead of numbers I used simple images of things I knew my son is able to name. If you like, find the source files <a href="http://vis4.net/blog/wp-content/uploads/2011/07/colorblindness.zip">here</a>. The icons are taken from <a href="http://thenounproject.com/">thenounproject</a>.</p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/bear.png"><img class="aligncenter size-full wp-image-2613" title="bear" src="http://vis4.net/blog/wp-content/uploads/2011/07/bear.png" alt="" width="600" height="600" /></a></p>
<p><!--:--><!--:de-->My wife recently watched my 2 years old son eating green strawberries and was now curious if he has some kind of red-green color blindness. Unfortunately, he is not yet able to tell us the name of numbers, so the commonly used <a href="http://www.colour-blindness.com/colour-blindness-tests/ishihara-colour-test-plates/">Ishihara test images</a> won't work in this case. Well, I thought it would be a nice idea for this rainy Sunday to generate some of those images myself. Instead of numbers I used simple images of things I knew my son is able to name. If you like, find the source files <a href="http://vis4.net/blog/wp-content/uploads/2011/07/colorblindness.zip">here</a>. Icons taken from <a href="http://thenounproject.com/">thenounproject</a>.</p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/bear.png"><img class="aligncenter size-full wp-image-2613" title="bear" src="http://vis4.net/blog/wp-content/uploads/2011/07/bear.png" alt="" width="600" height="600" /></a></p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/duck.png"><img class="wp-image-2615  size-full" title="duck" src="http://vis4.net/blog/wp-content/uploads/2011/07/duck.png" alt="" width="600" height="600" /></a></p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/butterfly.png"><img class="alignnone size-thumbnail wp-image-2619" title="butterfly" src="http://vis4.net/blog/wp-content/uploads/2011/07/butterfly-200x200.png" alt="" width="200" height="200" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/tree.png"><img class=" size-thumbnail wp-image-2617" title="tree" src="http://vis4.net/blog/wp-content/uploads/2011/07/tree-200x200.png" alt="" width="200" height="200" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/dog.png"><img class="alignnone size-thumbnail wp-image-2621" title="dog" src="http://vis4.net/blog/wp-content/uploads/2011/07/dog-200x200.png" alt="" width="200" height="200" /></a></p>
<p>&nbsp;<!--:--><span id="more-2611"></span><!--:en--></p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/duck.png"><img class="wp-image-2615  size-full" title="duck" src="http://vis4.net/blog/wp-content/uploads/2011/07/duck.png" alt="" width="600" height="600" /></a></p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2011/07/butterfly.png"><img class="alignnone size-thumbnail wp-image-2619" title="butterfly" src="http://vis4.net/blog/wp-content/uploads/2011/07/butterfly.png" alt="" width="250" height="250" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/tree.png"><img class=" size-thumbnail wp-image-2617" title="tree" src="http://vis4.net/blog/wp-content/uploads/2011/07/tree.png" alt="" width="250" height="250" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/car.png"><img src="http://vis4.net/blog/wp-content/uploads/2011/07/car-250x250.png" alt="" title="car" width="250" height="250" class="alignnone size-thumbnail wp-image-2633" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/dog.png"><img class="alignnone size-thumbnail wp-image-2621" title="dog" src="http://vis4.net/blog/wp-content/uploads/2011/07/dog.png" alt="" width="250" height="250" /></a><a href="http://vis4.net/blog/wp-content/uploads/2011/07/apple.png"><img src="http://vis4.net/blog/wp-content/uploads/2011/07/apple-522x522.png" alt="" title="apple" width="522" height="522" class="alignnone size-medium wp-image-2635" /></a></p>
<p>&nbsp;<!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/color-blindness/?piwik_campaign=rss&#038;piwik_kwd=2611/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Vector Animation Performance: Flash vs. SVG</title>
		<link>http://vis4.net/blog/posts/performance-flash-vs-svg/?piwik_campaign=rss&#038;piwik_kwd=2452</link>
		<comments>http://vis4.net/blog/posts/performance-flash-vs-svg/?piwik_campaign=rss&#038;piwik_kwd=2452#comments</comments>
		<pubDate>Wed, 16 Feb 2011 11:20:58 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=2452</guid>
		<description><![CDATA[To make it clear: I love SVG. It's an open standard for description of vector graphics, it renders well in most common browsers, and it provides a huge amount of features. So, what's wrong with SVG? There's one little thing: SVG is slow, very slow! Here's a little example. I took one icon of the [...]]]></description>
			<content:encoded><![CDATA[<p><!--:en-->To make it clear: I love SVG. It's an open standard for description of vector graphics, it renders well in most common browsers, and it provides a huge amount of features. So, what's wrong with SVG? There's one little thing: SVG is slow, very slow! Here's a little example. I took one icon of the wonderful <a href="http://thenounproject.com">noun project</a> collection, extracted the SVG path and displayed it using the RaphaelJS framework. Now I added a bit of animation that periodically scales the icon, like this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1"><span class="kw2">var</span> paper <span class="sy0">=</span> Raphael<span class="br0">&#40;</span><span class="st0">&quot;canvas&quot;</span><span class="sy0">,</span> <span class="st0">&quot;800&quot;</span><span class="sy0">,</span> <span class="st0">&quot;600&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw2">var</span> icon <span class="sy0">=</span> paper.<span class="me1">path</span><span class="br0">&#40;</span>svgPath<span class="br0">&#41;</span><span class="sy0">;</span>
icon.<span class="me1">attr</span><span class="br0">&#40;</span><span class="br0">&#123;</span> fill<span class="sy0">:</span> <span class="st0">'#000'</span><span class="sy0">,</span> stroke<span class="sy0">:</span> <span class="st0">'none'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
timer <span class="sy0">=</span> window.<span class="me1">setInterval</span><span class="br0">&#40;</span>animate<span class="sy0">,</span> <span class="nu0">1000</span><span class="sy0">/</span><span class="nu0">30</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw2">function</span> animate<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	t <span class="sy0">+=</span> .1<span class="sy0">;</span>
	icon.<span class="me1">scale</span><span class="br0">&#40;</span><span class="br0">&#40;</span>Math.<span class="me1">sin</span><span class="br0">&#40;</span>t<span class="br0">&#41;</span><span class="sy0">+</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">*</span>.5 <span class="sy0">+</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Here are the links to the demos. </p>
<table border cellpadding="5">
<tr>
<th>Icons</th>
<th>Demo</th>
<th>Performance</th>
<th>Demo</th>
<th>Performance</th>
</tr>
<tr>
<th>1</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_1.html">SVG</a></td>
<td>good</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_1.html">Flash</a></td>
<td>good</td>
</tr>
<tr>
<th>2x2</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_4.html">SVG</a></td>
<td>good</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_4.html">Flash</a></td>
<td>good</td>
</tr>
<tr>
<th>5x5</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_25.html">SVG</a></td>
<td>good</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_25.html">Flash</a></td>
<td>good</td>
</tr>
<tr>
<th>10x10</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_100.html">SVG</a></td>
<td>getting slower</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_100.html">Flash</a></td>
<td>good</td>
</tr>
<tr>
<th>20x20</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_400.html">SVG</a></td>
<td>nearly slow motion</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_400.html">Flash</a></td>
<td>high CPU load, but still fine</td>
</tr>
</table>
<p>The result: <del datetime="2011-02-16T16:55:15+00:00">we should forget about SVG animation by now</del>. SVG animations are a little slower than flash.</p>
<p><strong>Update</strong>: <a href="http://twitter.com/erikdahlstrom">Erik Dahlstrom</a> told me about the fact that RaphaelJS re-draws the SVG paths on every scale() call. I now implemented the scaling using <a href="http://www.w3.org/TR/SVG/coords.html#TransformAttribute">svg transformations</a>.<!--:--><!--:de-->Um eins gleich vorweg zu nehmen: Ich liebe SVG. Ein offener Standard zur Beschreibung von Vektorgrafiken, darstellbar in so gut wie allen g&auml;ngigen Browsern, mit einer beinahe endlosen Vielfalt an M&ouml;glichkeiten. Was will man noch mehr? Naja, eine Sache f&auml;llt mir da ein. Es w&auml;re toll, wenn SVG auch noch einigerma&szlig;en fix gerendert w&uuml;rde. Hier mal ein kleines Beispiel. Ich habe ein Icon vom wundervollen <a href="http://thenounproject.com">Nounproject</a> genommen, den SVG-Pfad daraus kopiert und mit Hilfe des RaphaelJS Frameworks eingebunden. Dazu kommt jetzt noch eine einfache Animation, die das Icon gr&ouml;&szlig;er und kleiner werden l&auml;sst:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="javascript"><pre class="de1"><span class="kw2">var</span> paper <span class="sy0">=</span> Raphael<span class="br0">&#40;</span><span class="st0">&quot;canvas&quot;</span><span class="sy0">,</span> <span class="st0">&quot;800&quot;</span><span class="sy0">,</span> <span class="st0">&quot;600&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw2">var</span> icon <span class="sy0">=</span> paper.<span class="me1">path</span><span class="br0">&#40;</span>svgPath<span class="br0">&#41;</span><span class="sy0">;</span>
icon.<span class="me1">attr</span><span class="br0">&#40;</span><span class="br0">&#123;</span> fill<span class="sy0">:</span> <span class="st0">'#000'</span><span class="sy0">,</span> stroke<span class="sy0">:</span> <span class="st0">'none'</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
timer <span class="sy0">=</span> window.<span class="me1">setInterval</span><span class="br0">&#40;</span>animate<span class="sy0">,</span> <span class="nu0">1000</span><span class="sy0">/</span><span class="nu0">30</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw2">function</span> animate<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
	t <span class="sy0">+=</span> .1<span class="sy0">;</span>
	<span class="kw2">var</span> s <span class="sy0">=</span> <span class="br0">&#40;</span>Math.<span class="me1">sin</span><span class="br0">&#40;</span>t<span class="br0">&#41;</span><span class="sy0">+</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">*</span>.5 <span class="sy0">+</span> <span class="nu0">1</span><span class="sy0">;</span>
	icon.<span class="me1">node</span>.<span class="me1">setAttribute</span><span class="br0">&#40;</span><span class="st0">&quot;transform&quot;</span><span class="sy0">,</span> <span class="st0">&quot;translate(55,34) scale(&quot;</span><span class="sy0">+</span>s<span class="sy0">+</span><span class="st0">&quot;) translate(-55,-34)&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Hier sind die Links zu den Demos.</p>
<table border cellpadding="5">
<tr>
<th>Icons</th>
<th>Demo</th>
<th>Performance</th>
<th>Demo</th>
<th>Performance</th>
</tr>
<tr>
<th>1</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_1.html">SVG</a></td>
<td>fl&uuml;ssig</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_1.html">Flash</a></td>
<td>fl&uuml;ssig</td>
</tr>
<tr>
<th>2x2</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_4.html">SVG</a></td>
<td>fl&uuml;ssig</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_4.html">Flash</a></td>
<td>fl&uuml;ssig</td>
</tr>
<tr>
<th>5x5</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_25.html">SVG</a></td>
<td>fl&uuml;ssig</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_25.html">Flash</a></td>
<td>fl&uuml;ssig</td>
</tr>
<tr>
<th>10x10</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_100.html">SVG</a></td>
<td>ruckelt etwas</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_100.html">Flash</a></td>
<td>fl&uuml;ssig</td>
</tr>
<tr>
<th>20x20</th>
<td><a href="http://vis4.net/experiments/svgicons/svg_400.html">SVG</a></td>
<td>Zeitlupe</td>
<td><a href="http://vis4.net/experiments/svgicons/flash_400.html">Flash</a></td>
<td>CPU unter Volllast, aber l&auml;uft noch</td>
</tr>
</table>
<p>Das simple Ergebnis: Animation von Vektorgrafiken kann man mit SVG derzeit <del datetime="2011-02-16T16:55:15+00:00">einfach vergessen</del> schon begrenzt f&uuml;r Visualisierungen verwenden. Trotzdem noch etwas langsamer als Flash.</p>
<p><strong>Update</strong>: <a href="http://twitter.com/erikdahlstrom">Erik Dahlstrom</a> hat mich freundlicherweise darauf hingewiesen, dass RaphaelJS die SVG-Pfade bei jedem scale() Aufruf neu zeichnet. Habe die Skalierung jetzt &uuml;ber <a href="http://www.w3.org/TR/SVG/coords.html#TransformAttribute">SVG-Transformationen</a> gel&ouml;st. <!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/performance-flash-vs-svg/?piwik_campaign=rss&#038;piwik_kwd=2452/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kurzes Fazit zu SVG-Infografiken und RaphaelJS</title>
		<link>http://vis4.net/blog/posts/kurzes-fazit-zu-svg-infografiken-und-raphaeljs/?piwik_campaign=rss&#038;piwik_kwd=2251</link>
		<comments>http://vis4.net/blog/posts/kurzes-fazit-zu-svg-infografiken-und-raphaeljs/?piwik_campaign=rss&#038;piwik_kwd=2251#comments</comments>
		<pubDate>Tue, 30 Nov 2010 23:17:48 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[coding]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=2251</guid>
		<description><![CDATA[Hab heute mal zur &#220;bung meine Parteispendenvisualisierung in JavaScript/SVG nachgebaut. Das Ergebnis befindet sich hier. Fazit: RaphaelJS ist ein geiles Framework. Hat richtig Spa&#223; gemacht damit zu arbeiten. Einarbeitung hat keine 10 Minuten gedauert. Die Entwicklung ging wesentlich schneller als ich dachte. Ohne irgendwelchen Code zu portieren hat mich der komplette rewrite from scratch nur [...]]]></description>
			<content:encoded><![CDATA[<p>Hab heute mal zur &Uuml;bung meine <a href="http://labs.vis4.net/parteispenden">Parteispendenvisualisierung</a> in JavaScript/SVG nachgebaut. Das Ergebnis <a href="http://labs.vis4.net/parteispenden/noflash.html">befindet sich hier</a>.</p>
<p><strong>Fazit:</strong></p>
<ul>
<li><a href="http://raphaeljs.com/">RaphaelJS</a> ist ein geiles Framework. Hat richtig Spa&szlig; gemacht damit zu arbeiten. Einarbeitung hat keine 10 Minuten gedauert.</li>
<li>Die Entwicklung ging wesentlich schneller als ich dachte. Ohne  irgendwelchen Code zu portieren hat mich der komplette rewrite from  scratch nur vier Stunden gekostet.</li>
<li>Leider ist das SVG-Rendering zwischen den Browsern nicht 100% einheitlich.</li>
<li>Das Text-Rendering sieht in allen Browsern merkw&uuml;rdig aus, besonders  wenn der Text gedreht wird. In Chrome wirkt der Text verwaschen, in  Firefox scheinen sich die Buchstaben mitten im Wort nach oben und unten  zu verschieben. Das kann Flash deutlich besser (siehe Bild).</li>
<li>Einige Effekte lassen sich nur &uuml;ber CSS realisieren und sind nur  eingeschr&auml;nkt benutzbar. Firefox kann z.B. kein text-shadow f&uuml;r  SVG-Text, und transparente Schatten kennt die CSS3 &uuml;berhaupt nicht.</li>
<li>F&uuml;r komplizierte Vektorgrafiken wie B&ouml;gen oder Bezierkurven bietet  SVG bessere Unterst&uuml;tzung an als Flash. Auch das Darstellen von  Liniendicken &lt; 1 sieht bei SVG besser aus als in Flash.</li>
</ul>
<p><img src="http://media.tumblr.com/tumblr_lcrq1ii17s1qdzr0z.png" alt="" /></p>
<p>Hat also alles seine Vor- und Nachteile. Am sinnvollsten erscheint  mir daher, Info-Visualisierungen sowohl in Flash als auch in SVG  anzubieten, Flash als Standard und SVG als Fallback f&uuml;r  IPhone/IPad-Benutzer.</p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/kurzes-fazit-zu-svg-infografiken-und-raphaeljs/?piwik_campaign=rss&#038;piwik_kwd=2251/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Map Visualization Using OpenFlashMaps</title>
		<link>http://vis4.net/blog/posts/map-visualization-using-openflashmaps/?piwik_campaign=rss&#038;piwik_kwd=2049</link>
		<comments>http://vis4.net/blog/posts/map-visualization-using-openflashmaps/?piwik_campaign=rss&#038;piwik_kwd=2049#comments</comments>
		<pubDate>Fri, 24 Sep 2010 23:30:30 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[cartography]]></category>
		<category><![CDATA[coding]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=2049</guid>
		<description><![CDATA[If you know Edward Tufte's wonderful book "The Visual Display of Quantitative Information" you might already know the following visualization. The cool new thing is that it's rendered in Flash using OpenFlashMaps..]]></description>
			<content:encoded><![CDATA[<p><img src='http://vis4.net/blog/wp-content/plugins/simple-post-thumbnails/timthumb.php?src=net/blog/wp-content/thumbnails/2049.png&amp;w=250&amp;h=0&amp;zc=1&amp;ft=png' alt='post thumbnail' /></p>
<p>If you know Edward Tufte's wonderful book <em>The Visual Display of Quantitative Information</em> you might already know the following visualization. The cool new thing is that it's rendered in Flash using <a href="http://www.openflashmaps.org">OpenFlashMaps</a> - a new open source map visualization framework that I'm currently working on. </p>
<p>The data is taken from <a href="http://www.census.gov/support/DataDownload.htm#IPE">U.S. Census Bureau</a> and shows the percentage of people living in poverty in 2006.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="730" height="400" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="flashvars" value="map=http://openflashmaps.org/latest/us-full-orthographic-1km.ofm&#038;drawSea=false&#038;drawSeaBorder=false&#038;drawLevel1Border=true&#038;level1BorderColor=#000000&#038;level1BorderAlpha=.2&#038;coastlineColor=#000000&#038;enableZoom=true&#038;dataSrc=http://openflashmaps.org/latest/us-poverty.csv&#038;dataFormat=tsv&#038;dataMode=colorScale&#038;colorScaleFrom=#FFFCE8&#038;colorScaleTo=#AD2121&#038;dataColorColumn=1" /><param name="menu" value="false" /><param name="src" value="http://openflashmaps.org/latest/OFM.swf" /><embed type="application/x-shockwave-flash" width="730" height="400" src="http://openflashmaps.org/latest/OFM.swf" menu="false" flashvars="map=http://openflashmaps.org/latest/us-full-orthographic-1km.ofm&#038;drawSea=false&#038;drawSeaBorder=false&#038;drawLevel1Border=true&#038;level1BorderColor=#000000&#038;drawLevel2Border=true&#038;level2BorderColor=#000000&#038;level2BorderAlpha=.5&#038;level1BorderAlpha=.2&#038;coastlineColor=#000000&#038;enableZoom=true&#038;dataSrc=http://openflashmaps.org/latest/us-poverty.csv&#038;dataFormat=tsv&#038;dataMode=colorScale&#038;colorScaleFrom=#FFFCE8&#038;colorScaleTo=#AD2121&#038;dataColorColumn=1&#038;dataMinValue=0&#038;dataMaxValue=55"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/map-visualization-using-openflashmaps/?piwik_campaign=rss&#038;piwik_kwd=2049/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplification of Country Outlines</title>
		<link>http://vis4.net/blog/posts/simplification-of-country-outlines/?piwik_campaign=rss&#038;piwik_kwd=1705</link>
		<comments>http://vis4.net/blog/posts/simplification-of-country-outlines/?piwik_campaign=rss&#038;piwik_kwd=1705#comments</comments>
		<pubDate>Sat, 10 Jul 2010 10:19:17 +0000</pubDate>
		<dc:creator>Gregor Aisch</dc:creator>
				<category><![CDATA[cartography]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://vis4.net/blog/?p=1705</guid>
		<description><![CDATA[<!--:en-->This post shows how I implemented simple polygon outline simplification in AS3.<!--:--><!--:de-->This post shows how I implemented simple polygon outline simplification in AS3.<!--:-->]]></description>
			<content:encoded><![CDATA[<p><img src='http://vis4.net/blog/wp-content/plugins/simple-post-thumbnails/timthumb.php?src=net/blog/wp-content/thumbnails/1705.png&amp;w=250&amp;h=0&amp;zc=1&amp;ft=png' alt='post thumbnail' /></p>
<p>Simplification is a common task in vector-based map visualization. In some situations you don't want to display a map in its full resolution for reasons like the overall filesize and the rendering time. One major class of simplification algorithms works by removing some vertices without moving the remaining ones. While there are already some good tutorials for implementation of line simplification algorithms online<sup class='footnote'><a href='#fn-1705-1' id='fnref-1705-1'>1</a></sup>, none of them takes into account the special requirements of map data simplifications. This gap will be closed by this post.<span id="more-1705"></span></p>
<p>At first I want to introduce the used data set. It's a very basic map of all european countries. The first image shows the output of the map rendering without simplification.</p>
<p style="text-align: center;"><a href="http://vis4.net/blog/wp-content/uploads/2010/07/full_res.png"><img class="size-full wp-image-1718 aligncenter" title="full_res__" src="http://vis4.net/blog/wp-content/uploads/2010/07/full_res__1.png" alt="" width="630" height="300" /></a></p>
<p>While there are many simplification algorithms out there, this tutorial uses a very simple one. It's strategy is to remove certain points that are too close to the last kept point. This is not the smartest algorithm ever, but still one of the fastest, because it don't needs recursion and runs in O(n).</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="actionscript"><pre class="de1">const minDistSq:<span class="kw3">Number</span> = <span class="nu0">100000</span> <span class="sy0">*</span> <span class="nu0">100000</span>; <span class="co1">// radius 100km</span>
<span class="kw2">var</span> countries:<span class="kw3">Array</span>, shapes:<span class="kw3">Array</span>, shape:<span class="kw3">Array</span>, pt:<span class="kw3">Object</span>, lastPt:<span class="kw3">Object</span>, distSq:<span class="kw3">Number</span>;
&nbsp;
<span class="kw1">for</span> <span class="kw1">each</span> <span class="br0">&#40;</span>shapes <span class="kw1">in</span> countries<span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="kw1">for</span> <span class="kw1">each</span> <span class="br0">&#40;</span>shape <span class="kw1">in</span> shapes<span class="br0">&#41;</span> <span class="br0">&#123;</span>
		lastPt = shape<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>;
		<span class="kw1">for</span> <span class="kw1">each</span> <span class="br0">&#40;</span>pt <span class="kw1">in</span> shape<span class="br0">&#41;</span> <span class="br0">&#123;</span>
			<span class="kw1">if</span> <span class="br0">&#40;</span>pt == shape<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="kw1">continue</span>; <span class="co1">// skip first point</span>
			distSq = <span class="br0">&#40;</span>lastPt.<span class="me1">x</span> <span class="sy0">*</span> lastPt.<span class="me1">x</span> - pt.<span class="me1">x</span> <span class="sy0">*</span> pt.<span class="me1">x</span><span class="br0">&#41;</span> + <span class="br0">&#40;</span>lastPt.<span class="me1">y</span> <span class="sy0">*</span> lastPt.<span class="me1">y</span> - pt.<span class="me1">y</span> <span class="sy0">*</span> pt.<span class="me1">y</span><span class="br0">&#41;</span>;
			<span class="kw1">if</span> <span class="br0">&#40;</span>distSq <span class="sy0">&amp;</span>lt; minDistSq<span class="br0">&#41;</span> pt.<span class="me1">deleted</span> = <span class="kw2">true</span>;
			<span class="kw1">else</span> lastPt = pt;
		<span class="br0">&#125;</span>
	<span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>This algorithm works perfect on single polygons, but there are some drawbacks when using it for simplication of country outlines. As you can see in the next image, the simplification introduced overlappings and gaps between the countries.</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2010/07/step1.png"><img class="aligncenter size-full wp-image-1720" title="step1__" src="http://vis4.net/blog/wp-content/uploads/2010/07/step1__.png" alt="" width="630" height="300" /></a></p>
<p>The problem here is that different polygons that share the same boundary were treated seperately. To fix this we need to refine the current map topology (CONTINENT &gt; COUNTRY &gt; SHAPES) in a way, that the "shared vertices" were stored only once.  The algorithm simply iterates over all points and stores them into a global point register. Every new point will then be checked for equality (same x and y coordinates) with any of the previously saved points. If the algorithm finds an equal point, the reference to the duplicate point will be replaced and the custom property <tt>inner</tt> will be set to true (which means that this point lays on more than one country border). Incidentally this will also decrease the map file size and gives us a classification of  "inner" and "outer" points for free.</p>
<p>When we run the algorithm again, we need to remeber wether the simplification already visited point, to avoid double removal. The results look much better than before, but still need some improvements:</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2010/07/step2.png"><img class="aligncenter size-full wp-image-1722" title="step2__" src="http://vis4.net/blog/wp-content/uploads/2010/07/step2__.png" alt="" width="630" height="300" /></a></p>
<p>Obviously, there is one case we forgot, which I call <em>three-country-crossings</em>, which means all points that lay on more than <em>two</em> country borders. Removing one of these points leads to triangle shaped holes inside the continent area. To avoid those holes, we got to mark all three-country-crossings as undeletable. We can find three-country-crossings by counting how often we visit a single point during the topology initialization.</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2010/07/step3.png"><img class="aligncenter size-full wp-image-1724" title="step3__" src="http://vis4.net/blog/wp-content/uploads/2010/07/step3__.png" alt="" width="630" height="300" /></a></p>
<p>Now we are nearly finished. It took me a few days to notice that there is another case, we have to consider. If you compare at the crossover between Spain and France at the Mediterranean  Sea side, then you note the tiny cut into the landscape, that is introduced by the simplification.</p>
<p><img class="aligncenter size-full wp-image-1730" title="cut" src="http://vis4.net/blog/wp-content/uploads/2010/07/cut.png" alt="" width="621" height="239" /></p>
<p>To avoid those cuts we must identify all vertices that connects two countries and lay on the outside of a continent area. We can do so by comparing the current visited point with the last visited point, and if one lays on two countries and the other only on one, we mark the one on two countries as undeletable. The last picture shows the final output of the simplification:</p>
<p><a href="http://vis4.net/blog/wp-content/uploads/2010/07/map-4.png"><img class="aligncenter size-full wp-image-1733" title="map-4p" src="http://vis4.net/blog/wp-content/uploads/2010/07/map-4p.png" alt="" width="630" height="300" /></a></p>
<p>I hope this tutorial was useful to you, if anyone needs more code examples on this topic, let me know via comment.</p>
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-1705-1'>for instance the <a href="http://www.lostinactionscript.com/blog/index.php/2007/07/11/douglas-peuker-line-generalization/">Douglas Peuker Line Generalization</a> or <a href="http://motiondraw.com/md/as_samples/t/LineGeneralization/demo.html">Lang Simplification and McMaster's Slide Averaging Algorithm</a> <span class='footnotereverse'><a href='#fnref-1705-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://vis4.net/blog/posts/simplification-of-country-outlines/?piwik_campaign=rss&#038;piwik_kwd=1705/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using memcached (User agent is rejected)
Database Caching 1/71 queries in 0.034 seconds using memcached
Object Caching 1056/1186 objects using memcached
Content Delivery Network via N/A

Served from: www.vis4.net @ 2012-02-05 22:23:04 -->
