<?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/"
	>

<channel>
	<title>Cartogrammar &#187; Code</title>
	<atom:link href="http://www.cartogrammar.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cartogrammar.com/blog</link>
	<description>Adventures in maps, cartography, visualization, and Flash</description>
	<lastBuildDate>Tue, 20 Jul 2010 15:36:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Shaded relief in AS3</title>
		<link>http://www.cartogrammar.com/blog/shaded-relief-in-as3/</link>
		<comments>http://www.cartogrammar.com/blog/shaded-relief-in-as3/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 05:59:25 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[hawaii]]></category>
		<category><![CDATA[shaded relief]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=784</guid>
		<description><![CDATA[
Did you know that basic relief shading is fairly simple to accomplish? I didn&#8217;t until a few days ago when I was flipping through the Slocum et al. cartography textbook, Thematic Cartography and Geographic Visualization, wherein a four-step process is presented. It sounded easy, so it was time for further adventures in raster-based cartography in [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.cartogrammar.com/images/shadedrelief/molokai_shaded_tinted.jpg" alt="Shaded relief map of Molokai generated in AS3" /></p>
<p>Did you know that basic <a href="http://en.wikipedia.org/wiki/Cartographic_relief_depiction#Shaded_relief">relief shading</a> is fairly simple to accomplish? I didn&#8217;t until a few days ago when I was flipping through the Slocum et al. cartography textbook, <em>Thematic Cartography and Geographic Visualization</em>, wherein a four-step process is presented. It sounded easy, so it was time for further adventures in raster-based cartography in Flash! I swore off code projects outside my day job because they tend to be more headache- and hair-loss-inducing than enjoyable, but an easy one that produces pretty pictures is worth an exception.</p>
<p>I previously tried <a href="http://www.cartogrammar.com/blog/raster-map-projection-with-actionscript-3/">raster map projection</a> in AS3, and the same caveats apply. Flash shouldn&#8217;t be your first choice for hill-shading, but it&#8217;s good to demonstrate that it can be done on the fly in AS3, which could occasionally come in handy. Here follows a tutorial-like explanation of how simple shaded relief can be achieved in AS3. Code is only shown in bits and pieces, so to see it all in one place (or if you want to skip the details), you can download the <a href="http://www.cartogrammar.com/source/ShadedRelief.as">source AS3 file</a> and the <a href="http://www.cartogrammar.com/flash/source/molokai.png">source image file</a>.</p>
<p><span style="font-size: 120%;"><strong><br/>1) THE DATA SOURCE</strong></span><br />
Any shaded relief map is born of elevation data, typically from a <a href="http://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation model</a> (DEM), a.k.a. digital terrain model. Ideally the relief map would be generated from the actual elevation values in the DEM, but a DEM is often visually displayed as a grayscale image, which is what my example uses as a source. (See the bottom of this post for a bit more info on DEM data.) Darker means lower elevation; lighter means higher. The price of using the image as a starting point is precision, as there are only 256 different gray values (elevations) in the image.</p>
<p>My source, an elevation map of the Hawaiian island of Moloka&#8217;i, is below.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/molokai_dem.jpg" alt="Molokai DEM" /></p>
<p><span style="font-size: 120%;"><strong><br/>2) LOADING AND PREPARING DATA</strong></span><br />
To generate the shaded relief it&#8217;s necessary to go through the DEM image pixel-by-pixel, calculate a result pixel for the relief, and draw that pixel to an an output image. So the setup for this whole thing is to load the image using a Loader, draw it to a BitmapData, and create another BitmapData for the relief map.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> ShadedRelief extends <span style="color: #004993;">Sprite</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">loader</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Loader</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Loader</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
	<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> sourceBitmap <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">BitmapData</span>;
	<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> reliefBitmap <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">BitmapData</span>;
	<span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> ShadedRelief<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #004993;">loader</span>.<span style="color: #004993;">load</span><span style="color: #000000;">&#40;</span> <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">URLRequest</span><span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;molokai.png&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span>;
		<span style="color: #004993;">loader</span>.<span style="color: #004993;">contentLoaderInfo</span>.<span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">Event</span>.<span style="color: #004993;">COMPLETE</span>,onLoaded<span style="color: #000000;">&#41;</span>;
	<span style="color: #000000;">&#125;</span>
	<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> onLoaded<span style="color: #000000;">&#40;</span> event <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Event</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #0033ff; font-weight: bold;">void</span>
	<span style="color: #000000;">&#123;</span>
		sourceBitmap = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">BitmapData</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">loader</span>.<span style="color: #004993;">width</span>, <span style="color: #004993;">loader</span>.<span style="color: #004993;">height</span> <span style="color: #000000;">&#41;</span>;
		sourceBitmap.<span style="color: #004993;">draw</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">loader</span> <span style="color: #000000;">&#41;</span>;
		reliefBitmap = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">BitmapData</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">loader</span>.<span style="color: #004993;">width</span>, <span style="color: #004993;">loader</span>.<span style="color: #004993;">height</span>,<span style="color: #0033ff; font-weight: bold;">true</span>, <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span>;
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p><span style="font-size: 120%;"><strong><br/>3) GET YOUR MATH ON</strong></span><br />
Now I start following the mathematical steps laid out in the Slocum et al. text, which are three. For each pixel in the grid:</p>
<ol>
<li>Calculate the <strong>slope</strong> of the land.</li>
<li>Calculate the <strong>aspect</strong> of the land (the direction it faces).</li>
<li>Calculate a <strong>reflectance</strong> value.</li>
</ol>
<p>These calculations are made by observing the data in a 3&#215;3 pixel window, at the center of which is the pixel of interest. So to start, loop through the rows and columns of the source image. There are, I think, more efficient ways to do pixel-level manipulation than what I spell out below, but I&#8217;m keeping it simple here.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> drawMap<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span> <span style="color: #6699cc; font-weight: bold;">var</span> i <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span>; i <span style="color: #000000; font-weight: bold;">&lt;</span> sourceBitmap.<span style="color: #004993;">width</span>; i <span style="color: #000000; font-weight: bold;">++</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span> <span style="color: #6699cc; font-weight: bold;">var</span> j <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span>; j <span style="color: #000000; font-weight: bold;">&lt;</span> sourceBitmap.<span style="color: #004993;">height</span>; j <span style="color: #000000; font-weight: bold;">++</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
			<span style="color: #009900;">// magic will occur here</span>
		<span style="color: #000000;">&#125;</span>	
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>For reference, here&#8217;s a diagram of the 3&#215;3 window for any given pixel <em>(i,j)</em>:</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/table.png" alt="3x3 window of elevation values" /></p>
<p>The Z values represent elevation values for each pixel. To find the <strong>slope</strong> of the cell, do a simple rise over run division in both the x and y directions.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/slx.png" alt="x slope equation" /><br />
<img src="http://www.cartogrammar.com/images/shadedrelief/sly.png" alt="y slope equation" /></p>
<p>From the x and y slopes follows an overall slope:</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/sl0.png" alt="overall slope equation" /></p>
<p>The grayscale image no longer has any real elevation values, so the 0-255 gray value will stand in. That can be obtained with the <code>BitmapData.getPixel</code> method and from that grabbing just one of the RGB channels, e.g. <code>source.getPixel(i+1,j) &#038; 0xFF</code>. The D value (the distance between pixels) isn&#8217;t known in meaningful units anymore either, so D could just be 1. However, for some reason I found that using a slightly larger number produced a nicer result. My slope code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> topValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = sourceBitmap.<span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span> i, <span style="color: #004993;">Math</span>.<span style="color: #004993;">max</span><span style="color: #000000;">&#40;</span>j<span style="color: #000000; font-weight: bold;">-</span><span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;</span> 0xff;
<span style="color: #6699cc; font-weight: bold;">var</span> leftValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = sourceBitmap.<span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">max</span><span style="color: #000000;">&#40;</span>i<span style="color: #000000; font-weight: bold;">-</span><span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#41;</span>, j <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;</span> 0xff;
<span style="color: #6699cc; font-weight: bold;">var</span> rightValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = sourceBitmap.<span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">min</span><span style="color: #000000;">&#40;</span>i<span style="color: #000000; font-weight: bold;">+</span><span style="color: #000000; font-weight:bold;">1</span>,sourceBitmap.width<span style="color: #000000; font-weight: bold;">-</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span>, j <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;</span> 0xff;
<span style="color: #6699cc; font-weight: bold;">var</span> bottomValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = sourceBitmap.<span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span> i, <span style="color: #004993;">Math</span>.<span style="color: #004993;">min</span><span style="color: #000000;">&#40;</span>j<span style="color: #000000; font-weight: bold;">+</span><span style="color: #000000; font-weight:bold;">1</span>,sourceBitmap.height<span style="color: #000000; font-weight: bold;">-</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;</span> 0xff;
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> slx <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #000000;">&#40;</span>rightValue <span style="color: #000000; font-weight: bold;">-</span> leftValue<span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">3</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> sly <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #000000;">&#40;</span> bottomValue <span style="color: #000000; font-weight: bold;">-</span> topValue <span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">3</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> sl0 <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #004993;">Math</span>.<span style="color: #004993;">sqrt</span><span style="color: #000000;">&#40;</span> slx<span style="color: #000000; font-weight: bold;">*</span>slx <span style="color: #000000; font-weight: bold;">+</span> sly<span style="color: #000000; font-weight: bold;">*</span>sly <span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>Next, the <strong>aspect</strong>. First, get a local angle between the x slope and the overall slope.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/phi.png" alt="facet angle" /></p>
<p>To get an azimuth (0º to 360º, where north is 0º, east 90º, etc.), this table is provided:</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/azimuth.png" alt="Converting angle to azimuth" /></p>
<p>Code, then. Remember that AS3 works in radians, not degrees.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> phi <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #004993;">Math</span>.<span style="color: #004993;">acos</span><span style="color: #000000;">&#40;</span> slx<span style="color: #000000; font-weight: bold;">/</span>sl0 <span style="color: #000000;">&#41;</span>;
<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sl0 == <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #009900;">// account for division by zero trouble</span>
	phi = <span style="color: #000000; font-weight:bold;">0</span>;
<span style="color: #000000;">&#125;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> azimuth <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span>;
<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> slx <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = phi <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #000000; font-weight:bold;">1.5</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
	<span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = <span style="color: #000000; font-weight:bold;">1.5</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span> <span style="color: #000000; font-weight: bold;">-</span> phi;
	<span style="color: #0033ff; font-weight: bold;">else</span> phi = <span style="color: #000000; font-weight:bold;">1.5</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
<span style="color: #000000;">&#125;</span> <span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> slx <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span><span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = phi <span style="color: #000000; font-weight: bold;">+</span> .5<span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
	<span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = .5<span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span> <span style="color: #000000; font-weight: bold;">-</span> phi;
	<span style="color: #0033ff; font-weight: bold;">else</span> azimuth = .5<span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
<span style="color: #000000;">&#125;</span> <span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = <span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
	<span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> sly <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> azimuth = <span style="color: #000000; font-weight:bold;">0</span>;
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>And now, a <strong>reflectance</strong> value, which will be the brightness of the final output pixel. A Lambertian reflectance is suggested, and the formula provided ends up looking like this in code:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> sunElev <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span><span style="color: #000000; font-weight: bold;">*</span>.25;
<span style="color: #6699cc; font-weight: bold;">var</span> sunAzimuth <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">1.75</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span>;
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> L <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #004993;">Math</span>.<span style="color: #004993;">cos</span><span style="color: #000000;">&#40;</span> azimuth <span style="color: #000000; font-weight: bold;">-</span> sunAzimuth <span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">cos</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span><span style="color: #000000; font-weight: bold;">*</span>.5 <span style="color: #000000; font-weight: bold;">-</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">atan</span><span style="color: #000000;">&#40;</span>sl0<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">cos</span><span style="color: #000000;">&#40;</span> sunElev <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">+</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">sin</span><span style="color: #000000;">&#40;</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">PI</span><span style="color: #000000; font-weight: bold;">*</span>.5 <span style="color: #000000; font-weight: bold;">-</span> <span style="color: #004993;">Math</span>.<span style="color: #004993;">atan</span><span style="color: #000000;">&#40;</span>sl0<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #004993;">Math</span>.<span style="color: #004993;">sin</span><span style="color: #000000;">&#40;</span> sunElev <span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>The <code>sunAzimuth</code> and <code>sunElevation</code> values can be freely chosen and will affect the final appearance of shadows. 315º (northwest) and 45º respectively are pretty typical values. For some reason that I haven&#8217;t figured out, I ended up with some negative reflectance values, which I guess indicate black holes on the surface of the earth. I don&#8217;t understand the math going on here, but setting those to zero seemed to make the result look okay. (If anyone can explain or help me here, it&#8217;d be greatly appreciated!)</p>
<p><span style="font-size: 120%;"><strong><br/>4) DRAW THE RELIEF</strong></span><br />
The reflectance value just needs to be translated into a shade of gray. The reflectance is basically a proportion of white, so to get RGB values it needs to be multiplied by 255 and assigned to each of the three channels. Finally, the pixel can be drawn on the output image.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> grayValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = <span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">255</span> <span style="color: #000000; font-weight: bold;">*</span> L<span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> grayValue <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">0</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	grayValue = <span style="color: #000000; font-weight:bold;">0</span>;
<span style="color: #000000;">&#125;</span>
<span style="color: #009900;">// doing ARGB instead of RGB because transparency comes in handy elsewhere</span>
reliefBitmap.<span style="color: #004993;">setPixel32</span><span style="color: #000000;">&#40;</span>i,j,0xff <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">24</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">16</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">8</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue<span style="color: #000000;">&#41;</span>;</pre></div></div>

<p>Running through all that gets me the following Moloka&#8217;i map.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/molokai_relief_gray.jpg" alt="Molokai shaded relief grayscale" /></p>
<p><span style="font-size: 120%;"><strong><br/>5) HYPSOMETRIC TINTING</strong></span><br />
The gray relief map wowed me enough the first time because I was amazed at how simple it was to produce (despite my lengthy explanation above). But it&#8217;s not a nice map without colors! <strong>Hypsometric tinting</strong>, in which colors are mapped to elevation ranges, is a common and aesthetically pleasing technique on relief maps. To get hypsometric tints on my relief map, another BitmapData is drawn based on the grayscale source image, but this time the math is much simpler. All that needs to be done is to match the gray value of each source pixel to a color class or a point in a continuous gradient of colors. I settled on the following gradient for elevation colors. It stays mostly in the greens to reflect the tropical setting, and moves a bit toward warmer colors at just the highest elevations.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/tint_gradient.jpg" alt="Colors for hypsometric tints" /></p>
<p>I won&#8217;t explain all the code in detail, but basically I drew a vector gradient 256 pixels wide, then sampled the color at each x location and saved it in an array. Thus each 0-255 gray value can be matched to an index in that array. Then, in the loop where all that reflectance math is taking place, I added a couple of lines to draw that color to another BitmapData.</p>
<p>Note there is some additional funny business involving the first couple of values in the array. This is to deal with the ocean in my map. I had trouble getting the blues to look good in the gradient, so after creating the array I set those blues using brute force. I also didn&#8217;t want the ocean to show up as gray in the relief image, so if a pixel has a value at that low end that indicates it as water, it isn&#8217;t drawn to the relief map.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> gradientColors <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span>0x0000ff,0x004000,0x679167, 0x81b279, 0xbfdfa8, 0xd0b8aa<span style="color: #000000;">&#93;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> gradientRatios <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">3</span>,<span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000; font-weight:bold;">255</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">4</span>,<span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000; font-weight:bold;">255</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">4</span>,<span style="color: #000000; font-weight:bold;">3</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000; font-weight:bold;">255</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">4</span>,<span style="color: #000000; font-weight:bold;">4</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #000000; font-weight:bold;">255</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000; font-weight:bold;">4</span><span style="color: #000000;">&#93;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> gradientAlphas <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">1</span>,<span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#93;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">matrix</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Matrix</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Matrix</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
<span style="color: #004993;">matrix</span>.<span style="color: #004993;">createGradientBox</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">255</span>,<span style="color: #000000; font-weight:bold;">5</span><span style="color: #000000;">&#41;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> gradientShape <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Shape</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Shape</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
gradientShape.<span style="color: #004993;">graphics</span>.<span style="color: #004993;">beginGradientFill</span><span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;linear&quot;</span>,gradientColors,gradientAlphas,gradientRatios,<span style="color: #004993;">matrix</span><span style="color: #000000;">&#41;</span>;
gradientShape.<span style="color: #004993;">graphics</span>.<span style="color: #004993;">drawRect</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">255</span>,<span style="color: #000000; font-weight:bold;">5</span><span style="color: #000000;">&#41;</span>;
gradientShape.<span style="color: #004993;">graphics</span>.<span style="color: #004993;">endFill</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
gradBmp = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">BitmapData</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">255</span>,<span style="color: #000000; font-weight:bold;">5</span><span style="color: #000000;">&#41;</span>;
gradBmp.<span style="color: #004993;">draw</span><span style="color: #000000;">&#40;</span>gradientShape<span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">colors</span> <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Array</span> = <span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span>;
&nbsp;
<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span> <span style="color: #6699cc; font-weight: bold;">var</span> n <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span>; n <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight:bold;">256</span>; n <span style="color: #000000; font-weight: bold;">++</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #004993;">colors</span>.<span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span> gradBmp.<span style="color: #004993;">getPixel32</span><span style="color: #000000;">&#40;</span>n,<span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span>;
<span style="color: #000000;">&#125;</span>
<span style="color: #009900;">// ARGB again</span>
<span style="color: #004993;">colors</span><span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#93;</span> = 0xffccccff;
<span style="color: #004993;">colors</span><span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#93;</span> = 0xffccccff;
&nbsp;
<span style="color: #000000;">&#91;</span>...<span style="color: #000000;">&#93;</span>
&nbsp;
<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span> <span style="color: #6699cc; font-weight: bold;">var</span> i <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span>; i <span style="color: #000000; font-weight: bold;">&lt;</span> sourceBitmap.<span style="color: #004993;">width</span>; i <span style="color: #000000; font-weight: bold;">++</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">for</span> <span style="color: #000000;">&#40;</span> <span style="color: #6699cc; font-weight: bold;">var</span> j <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span>; j <span style="color: #000000; font-weight: bold;">&lt;</span> sourceBitmap.<span style="color: #004993;">height</span>; j <span style="color: #000000; font-weight: bold;">++</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
		<span style="color: #000000;">&#91;</span>...<span style="color: #000000;">&#93;</span>
		<span style="color: #6699cc; font-weight: bold;">var</span> centerValue <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Number</span> = sourceBitmap.<span style="color: #004993;">getPixel</span><span style="color: #000000;">&#40;</span> i,j <span style="color: #000000;">&#41;</span> <span style="color: #000000; font-weight: bold;">&amp;</span> 0xff;
		tintBitmap.<span style="color: #004993;">setPixel32</span><span style="color: #000000;">&#40;</span> i,j,<span style="color: #004993;">colors</span><span style="color: #000000;">&#91;</span><span style="color: #004993;">int</span><span style="color: #000000;">&#40;</span>centerValue<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span> <span style="color: #000000;">&#41;</span>;
		<span style="color: #000000;">&#91;</span>...<span style="color: #000000;">&#93;</span>
		<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span> centerValue <span style="color: #000000; font-weight: bold;">&gt;</span>= <span style="color: #000000; font-weight:bold;">3</span> <span style="color: #000000;">&#41;</span> reliefBitmap.<span style="color: #004993;">setPixel32</span><span style="color: #000000;">&#40;</span>i,j,0xff <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">24</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">16</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue <span style="color: #000000; font-weight: bold;">&lt;&lt;</span> <span style="color: #000000; font-weight:bold;">8</span> <span style="color: #000000; font-weight: bold;">|</span> grayValue<span style="color: #000000;">&#41;</span>;
	<span style="color: #000000;">&#125;</span>	
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The hypsometric tinting by itself looks like this:</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/molokai_tints.jpg" alt="Molokai hypsometric tints" /></p>
<p><span style="font-size: 120%;"><strong><br/>6) PUTTING IT ALL TOGETHER</strong></span><br />
The final map is a matter of combining the relief and tint images. I found that overlaying the relief map at 30% opacity looked pretty good. A blur filter on both the tint and relief maps helps to smooth out the pixelated coastline and some noise, respectively. And a glow filter on the relief map provides a nice coastal effect, even if I haven&#8217;t quite perfected it here.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">tintBitmap.<span style="color: #004993;">applyFilter</span><span style="color: #000000;">&#40;</span> tintBitmap, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Rectangle</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">0</span>,tintBitmap.<span style="color: #004993;">width</span>,tintBitmap.<span style="color: #004993;">height</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Point</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">BlurFilter</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">1.2</span>,<span style="color: #000000; font-weight:bold;">1.2</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> tintMap <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Bitmap</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Bitmap</span><span style="color: #000000;">&#40;</span>tintBitmap<span style="color: #000000;">&#41;</span>;
<span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>tintMap<span style="color: #000000;">&#41;</span>;
&nbsp;
reliefBitmap.<span style="color: #004993;">applyFilter</span><span style="color: #000000;">&#40;</span> reliefBitmap, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Rectangle</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">0</span>,reliefBitmap.<span style="color: #004993;">width</span>,reliefBitmap.<span style="color: #004993;">height</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Point</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">BlurFilter</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">2</span>,<span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span>;
reliefBitmap.<span style="color: #004993;">applyFilter</span><span style="color: #000000;">&#40;</span> reliefBitmap, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Rectangle</span><span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">0</span>,<span style="color: #000000; font-weight:bold;">0</span>,reliefBitmap.<span style="color: #004993;">width</span>,reliefBitmap.<span style="color: #004993;">height</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Point</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">GlowFilter</span><span style="color: #000000;">&#40;</span>0xffffff,.75,<span style="color: #000000; font-weight:bold;">45</span>,<span style="color: #000000; font-weight:bold;">45</span>,<span style="color: #000000; font-weight:bold;">3</span>,<span style="color: #000000; font-weight:bold;">2</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#41;</span>;
<span style="color: #6699cc; font-weight: bold;">var</span> reliefMap <span style="color: #000000; font-weight: bold;">:</span> <span style="color: #004993;">Bitmap</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">Bitmap</span><span style="color: #000000;">&#40;</span> reliefBitmap <span style="color: #000000;">&#41;</span>;
<span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span> reliefMap <span style="color: #000000;">&#41;</span>;
reliefMap.<span style="color: #004993;">alpha</span> = .3;</pre></div></div>

<p>Pow. And pau.</p>
<p><img src="http://www.cartogrammar.com/images/shadedrelief/molokai_shaded_tinted.jpg" alt="Shaded relief map of Molokai generated in AS3" /></p>
<p><span style="font-size: 120%;"><strong><br/>7) ADDITIONAL RESOURCES</strong></span><br />
The formulas in the Slocum et al. textbook are derived from:<br/>Eyton, J.R. (1991) &#8220;Rate-of-change-maps.&#8221; <em>Cartography and Geographic Information Systems</em> 18, no. 2:87–103.<br />
As for the textbook itself, I&#8217;m looking at the second edition, pages 300-301.</p>
<p>It&#8217;s been a while since I actually sought out DEM data, but at least for the United States the best source remains the USGS. You can download data for anywhere in the country at <a href="http://seamless.usgs.gov/">http://seamless.usgs.gov/</a>. The USGS also has some worldwide data with <a href="http://eros.usgs.gov/#/Find_Data/Products_and_Data_Available/gtopo30_info">GTOPO30</a>. A bit of Googling will likely lead you to additional sources of DEMs.</p>
<p>DEM data may not always come in a format suitable for this particular tutorial. (But remember that this is not the way to go most of the time anyway.) It may come in the actual DEM file format, or perhaps a GeoTIFF that you may have trouble opening in ordinary image editing software. Unfortunately I&#8217;m not up on the best ways to convert DEMs to grayscale images. I grew to like <a href="http://www.usna.edu/Users/oceano/pguth/website/microdem/microdem.htm">MicroDEM</a>, a Windows program from several years ago, for all kinds of DEM manipulation. I&#8217;m a Mac user but have fired up Windows on my machine more than once to use this program. Anyway, again the best I can suggest is to use your Google-fu.</p>
<p>Finally, there is no avoiding mentioning the man who is barely short of a deity of relief shading: Tom Patterson. Mr. Patterson, who is known to and revered by all cartographers, does mind-blowing work for the National Park Service, and he has been kind enough to impart some of his wisdom through <a href="http://www.shadedrelief.com/">shadedrelief.com</a>. Do check out that site for a lot of good information and tutorials. He also has created the wonderful Natural Earth <a href="http://www.shadedrelief.com/natural/">I</a>, <a href="http://www.shadedrelief.com/natural2/index.html">II</a>, and <a href="http://www.shadedrelief.com/natural3/index.html">III</a> maps and has co-spearheaded the <a href="http://www.naturalearthdata.com/">Natural Earth vector</a> effort.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/shaded-relief-in-as3/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Shapefile code now loads DBF too</title>
		<link>http://www.cartogrammar.com/blog/shapefile-code-now-loads-dbf-too/</link>
		<comments>http://www.cartogrammar.com/blog/shapefile-code-now-loads-dbf-too/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 16:34:08 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[shapefiles]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=252</guid>
		<description><![CDATA[For the benefit of anyone following along via RSS, just a quick note to say that I have updated the AS3 shapefile loading and drawing helper classes from last week to include basic loading of attributes from a DBF file, again using Edwin van Rijkom&#8217;s libraries.  I hope it helps a bit more for [...]]]></description>
			<content:encoded><![CDATA[<p>For the benefit of anyone following along via RSS, just a quick note to say that I have updated the <a href="http://www.cartogrammar.com/blog/simple-shapefile-drawing-in-actionscript-3/">AS3 shapefile loading and drawing helper classes</a> from last week to include basic loading of attributes from a DBF file, again using Edwin van Rijkom&#8217;s libraries.  I hope it helps a bit more for anyone trying to get started with shapefiles in Flash and ActionScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/shapefile-code-now-loads-dbf-too/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple shapefile drawing in ActionScript 3</title>
		<link>http://www.cartogrammar.com/blog/simple-shapefile-drawing-in-actionscript-3/</link>
		<comments>http://www.cartogrammar.com/blog/simple-shapefile-drawing-in-actionscript-3/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 03:19:48 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[shapefiles]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=235</guid>
		<description><![CDATA[
Recently I&#8217;ve heard two friends independently inquire about some sort of basic guide for loading and drawing a shapefile in Flash. The only real tutorial/example I can recall is here, dealing with Google Maps.  But these guys are looking for something more bare-bones.  Being a regular user of Edwin van Rijkom&#8217;s invaluable code [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.cartogrammar.com/images/shpToMap.jpg" alt="Shapefile + magic = map in Flash!" /></p>
<p>Recently I&#8217;ve heard two friends independently inquire about some sort of basic guide for loading and drawing a shapefile in Flash. The only real tutorial/example I can recall is <a href="http://www.boxshapedworld.com/blog/post/Shapefiles-Actionscript-30-and-Google-Maps.aspx">here</a>, dealing with Google Maps.  But these guys are looking for something more bare-bones.  Being a regular user of <a href="http://vanrijkom.org/wordpress/">Edwin van Rijkom</a>&#8217;s invaluable <a href="http://code.google.com/p/vanrijkom-flashlibs">code libraries</a> for reading shapefiles, and usually forgetting the process myself, I thought it would be a good idea to put together a very simple set of AS3 classes that load a shapefile and throw a map on screen. </p>
<p>So to get those jerks off my back, I wrote a little thing called ShpMap, which supplements van Rijkom&#8217;s classes by loading and drawing a shapefile. It&#8217;s nothing fancier than that. Sometimes all you need is to get your base map on screen.  (<em><strong>Update</strong>: just to round it out a little more, I&#8217;ve added basic loading and parsing of a shapefile&#8217;s accompanying DBF file, which contains attribute data. This also uses classes by van Rijkom.</em>)</p>
<p>I hope that this class (and the several associated classes) can both be directly usable for some projects and serve as a basic guide to using van Rijkom&#8217;s classes to load shapefiles.</p>
<p>Dig it:</p>
<ul>
<li>An <a href="http://www.cartogrammar.com/flash/shp/ShapefileExample.html">example</a> that loads and displays a US states shapefile (and then puts a square on my house and colors the state of Wisconsin green). View the source code <a href="http://www.cartogrammar.com/flash/shp/srcview/index.html">here</a>.</li>
<li>Download the <a href="http://www.cartogrammar.com/flash/shp/srcview/ShapefileExample.zip">source code</a>. (My classes plus van Rijkom&#8217;s, as well as a demo US States shapefile.) </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/simple-shapefile-drawing-in-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>ActionScript curves update</title>
		<link>http://www.cartogrammar.com/blog/actionscript-curves-update/</link>
		<comments>http://www.cartogrammar.com/blog/actionscript-curves-update/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 20:44:00 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[curves]]></category>
		<category><![CDATA[drawing]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=22</guid>
		<description><![CDATA[I finally opened my CubicBezier AS3 class, the only reason anyone ever finds this site at all, for the first time in many months to attempt to address some of the various comments and reported problems from the original.  It&#8217;s not perfected, but I&#8217;ve done three things:

Added a &#8220;moveTo&#8221; argument to the curveThroughPoints method, [...]]]></description>
			<content:encoded><![CDATA[<p>I finally opened my <a href="http://www.cartogrammar.com/blog/continuous-curves-with-actionscript-3/">CubicBezier</a> AS3 class, the only reason anyone ever finds this site at all, for the first time in many months to attempt to address some of the various comments and reported problems from the original.  It&#8217;s not perfected, but I&#8217;ve done three things:</p>
<ol>
<li>Added a &#8220;moveTo&#8221; argument to the curveThroughPoints method, following the idea in one comment on my blog post.  Ignore it if you wish, but if you set it to false, the curves will connect to wherever graphics drawing left off rather than moving to the beginning of the curve and starting anew.</li>
<li>Hooray trigonometry!  Messed with some of the angle calculations to fix problems with zero angles and division by zero.  I hope it worked.</li>
<li>Provided a line of code that can be altered to use lineTo for straight segments of 3 or more points rather than curving.</li>
</ol>
<p>Straight lines were raised as an issue in several comments.  While I think I have fixed the crazy behavior of straight horizontal and vertical lines, I suspect the result for three points in a line may be surprising at first glance.  For instance, the three middle points in the image below are all aligned horizontally.</p>
<p><img src="http://www.cartogrammar.com/images/straightline_scurve.png" alt="Straight line with S-curve" /></p>
<p>The S-curve through those points may look odd at first, but it&#8217;s actually to be expected with these cubic Bézier curves.  Of those three points, only the middle one has curve control points that are also aligned horizontally.  The outer two have control points that are also based on the points outside the line.  Here&#8217;s an approximate example from Illustrator of what they look like</p>
<p><img src="http://www.cartogrammar.com/images/straightline_illy.jpg" alt="S-curve in Illustrator" /></p>
<p>I&#8217;ve left that as the default behavior, but I did insert some code that can be modified so that the curve essentially stops curving when it reaches several points in a line, draws a straight line through them, and then continues curving as normal after that.  Here&#8217;s what the same example looks like with that option enabled.</p>
<p><img src="http://www.cartogrammar.com/images/straightline_straight.png" alt="Straight line with lineTo" /></p>
<p>It&#8217;s probably often fine, but I caution that it can result in sharp corners.  Here&#8217;s the same with those dots removed:</p>
<p><img src="http://www.cartogrammar.com/images/straightline_nodots.png" alt="Straight line with lineTo and sharp corners" /></p>
<p>I&#8217;m uncertain what&#8217;s best, so I&#8217;ve made that a line of code that has to be changed rather than a more accessible option.  I&#8217;d be glad to hear ideas on how best to handle it.  Feel free to change it however you like, of course.  That and other modifications are identified in the comments.</p>
<p>Download the class here: <a href="http://cartogrammar.com/source/CubicBezier.as">CubicBezier.as</a><br />
The previous version is <a href="http://cartogrammar.com/source/CubicBezier_May08.as">here</a>, in case I screwed something up.  Forgive my lack of version control.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/actionscript-curves-update/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Simple map panning and zooming with ActionScript</title>
		<link>http://www.cartogrammar.com/blog/simple-map-panning-and-zooming-with-actionscript/</link>
		<comments>http://www.cartogrammar.com/blog/simple-map-panning-and-zooming-with-actionscript/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 00:43:16 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[interactive maps]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=20</guid>
		<description><![CDATA[A while ago I wrote a summary of basic map panning and zooming methods along with demonstrations of most of them.  There were a few requests for code examples for those demos, so (finally) I thought I&#8217;d outline some of the simple methods for doing it in Flash/ActionScript.
I&#8217;ve put together two AS files:

A PanZoomMap [...]]]></description>
			<content:encoded><![CDATA[<p>A while ago I wrote a summary of <a href="http://www.cartogrammar.com/blog/map-panning-and-zooming-methods/">basic map panning and zooming methods</a> along with demonstrations of most of them.  There were a few requests for code examples for those demos, so (finally) I thought I&#8217;d outline some of the simple methods for doing it in Flash/ActionScript.</p>
<p>I&#8217;ve put together two AS files:</p>
<ul>
<li>A <a href="http://www.cartogrammar.com/source/PanZoomMap.as">PanZoomMap class</a>, with some simple panning and zooming methods.</li>
<li>An <a href="http://www.cartogrammar.com/source/PanZoomTest.as">example class</a> that creates an instance of the PanZoomMap and demonstrates zooming, basic click and drag panning, and a zoom box.</li>
</ul>
<p>The code has some simple comments that I hope give an idea of how it works.  I&#8217;ll let them do the talking, as anything I write here is likely to be long-winded and confusing.</p>
<p>The example is really very basic.  A real interactive map is likely to require some more complicated capabilities than what I have provided here, but this is a starting point that may be helpful to anyone who needs an introduction.</p>
<p>Here&#8217;s what the test file does.  A simple click-and-drag pan/zoom example:</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_panZoomTest_632939686"
			class="flashmovie"
			width="210"
			height="250">
	<param name="movie" value="http://www.cartogrammar.com/flash/panZoomTest.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.cartogrammar.com/flash/panZoomTest.swf"
			name="fm_panZoomTest_632939686"
			width="210"
			height="250">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>And a zoom box example:</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_zoomBoxTest_1771009610"
			class="flashmovie"
			width="210"
			height="250">
	<param name="movie" value="http://www.cartogrammar.com/flash/zoomBoxTest.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.cartogrammar.com/flash/zoomBoxTest.swf"
			name="fm_zoomBoxTest_1771009610"
			width="210"
			height="250">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/simple-map-panning-and-zooming-with-actionscript/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Faking a progressive image download in Flash</title>
		<link>http://www.cartogrammar.com/blog/faking-a-progressive-image-download-in-flash/</link>
		<comments>http://www.cartogrammar.com/blog/faking-a-progressive-image-download-in-flash/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 22:04:21 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[flash]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=13</guid>
		<description><![CDATA[
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_progressive_486074867"
			class="flashmovie"
			width="600"
			height="400">
	<param name="movie" value="http://www.cartogrammar.com/flash/progressive.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.cartogrammar.com/flash/progressive.swf"
			name="fm_progressive_486074867"
			width="600"
			height="400">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
So I have a single map that I need to show at several different scales in an interactive fashion.  It&#8217;s got to be a pretty big image to look decent when I zoom in, so that means a large file and a long download.  But I only need to [...]]]></description>
			<content:encoded><![CDATA[
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_progressive_1042366652"
			class="flashmovie"
			width="600"
			height="400">
	<param name="movie" value="http://www.cartogrammar.com/flash/progressive.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.cartogrammar.com/flash/progressive.swf"
			name="fm_progressive_1042366652"
			width="600"
			height="400">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>So I have a single map that I need to show at several different scales in an interactive fashion.  It&#8217;s got to be a pretty big image to look decent when I zoom in, so that means a large file and a long download.  But I only need to see the scaled-down map when it first loads.  I don&#8217;t want to wait for a big image to download when I just need a little one to start!  The hip (or some might say &#8220;smart&#8221;) way to deal with such a problem is to break the image into tiles and load said tiles on the fly as needed.  But this is a simple, one-off creation, and I&#8217;m too lazy, too stupid, or too pressed for time to figure out tiling.</p>
<p>That was my situation recently.  And I thought to myself <em>hey, the world needs more backward-looking individuals</em>, and patted myself on the back for avoiding learning and taking the easy way out: <strong>use Flash&#8217;s timeline to fake a progressive download!</strong></p>
<p>The solution takes advantage of the way a Flash movie loads: rather than waiting for the whole file to load, individual timeline frames appear as soon as their content has loaded.  It&#8217;s something I first exploited for my <a href="http://www.cincinnatiroads.com">CincinnatiRoads</a> map, embedding videos right in the timeline to allow easier playback manipulation but also have a progressive download.  Flash, from what I can tell, supports progressive JPEGs but does not display them progressively.</p>
<p>So, for my map:</p>
<ol>
<li>Save a scaled-down image that is a manageable file size.</li>
<li>Divide the full-res image into tiles, also of manageable file sizes (mine is 16 tiles).</li>
<li>In Flash, plop the small image from (1) on the stage.</li>
<li>Then place the full-res tiles on top of the small image, scaling them down (in Flash!) to match the size of the small image.  (When they&#8217;re blown back up by zooming in, they&#8217;ll look fine.)  Place each tile in its own layer, and move each to its own frame.  My timeline looks like this:</li>
</ol>
<p><img src="http://www.cartogrammar.com/images/timeline.jpg" alt=" Flash timeline for fake map tiles" /></p>
<p>That&#8217;s all.  No code (except a <code>stop()</code> at the end), very little thinking, and maybe a half hour spent.  I then drop it into my map interface.  When the movie loads, it should show up as soon as the small image has finished loading, and then the high-res tiles will come in one by one.  Hopefully you noticed that the simple demo map at the top of this post appeared without too much delay even though the full image is a few thousand pixels across and the file is a couple of megabytes (and if files of that size load quickly anyway because you have an amazing internet connection, <em>shut up and I hate you</em>).</p>
<p>Caveats:</p>
<ul>
<li>Yes, I know this is not much different from having only two images: one small and one large.  But I figured it&#8217;s better to see pieces of the high-res image appear as they load rather than <em>nothing&#8230; nothing&#8230; nothing&#8230; EVERYTHING</em>.  And it almost looks like there is some kind of actual tiling going on!</li>
<li>This was helpful for displaying an image that takes too long to download but is not too large to handle.  It is not a solution for loading an absolutely huge image.  That&#8217;s going to bog down the system in the end.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/faking-a-progressive-image-download-in-flash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Raster map projection with ActionScript 3</title>
		<link>http://www.cartogrammar.com/blog/raster-map-projection-with-actionscript-3/</link>
		<comments>http://www.cartogrammar.com/blog/raster-map-projection-with-actionscript-3/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 01:02:22 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[projections]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=9</guid>
		<description><![CDATA[This is probably a stupid idea, but that&#8217;s never stopped me before.
Lately some of my Flash mapping colleagues and I have come to rely on transforming geographic data&#8212;say, shapefiles&#8212;into various map projections on the client side via the ActionScript vector drawing methods.  (See, for example, a post by my friend Zachary Johnson with an [...]]]></description>
			<content:encoded><![CDATA[<p>This is probably a stupid idea, but that&#8217;s never stopped me before.</p>
<p>Lately some of my Flash mapping colleagues and I have come to rely on transforming geographic data&mdash;say, <a href="http://en.wikipedia.org/wiki/Shapefile">shapefiles</a>&mdash;into various map projections on the client side via the ActionScript vector drawing methods.  (See, for example, a <a href="http://indiemaps.com/blog/2008/01/shapefiles-projections-in-flash-as3/">post by my friend Zachary Johnson</a> with an old-as-the-hills demo.  And don&#8217;t you worry: we&#8217;ll be releasing something way, way cooler eventually.)  But as cartographers know, <a href="http://en.wikipedia.org/wiki/Vector_graphics">vector</a> data is just one side of things.  What about <a href="http://en.wikipedia.org/wiki/Raster_graphics">raster</a> data?</p>
<p>These days Flash allows good pixel-level manipulation of raster images with the BitmapData class.  As a cartographer, I thought I&#8217;d try a little experiment in map projections.</p>
<p><strong>The goal: Convert an &#8220;unprojected&#8221; (plate carrée) world map map to a Winkel Tripel projection.</strong> I used an image from <a href="http://en.wikipedia.org/wiki/Image:Equirectangular-projection.jpg">Wikipedia</a> as a starting point.</p>
<p><img src="http://www.cartogrammar.com/images/unprojected.jpg" alt="Unprojected map" /></p>
<p>This is what we want to end up with:</p>
<p><img src="http://www.cartogrammar.com/images/projected_proper.jpg" alt="Wikel Tripel projection" /></p>
<p>Not terribly long ago for a mapping project I wasted a ridiculous amount of time on someone else&#8217;s dime attempting to reproject a raster map using the ActionScript DisplacementMapFilter class.  If you don&#8217;t know, what the DisplacementMapFilter does is use the colors on a <em>displacement map image</em> (a BitmapData object) to determine displacement of pixels on another object.  One color channel determines the x displacement and another the y displacement, both relative to the midpoint in the range of values for that color (i.e., 127 out of 255).  For example, if we use the red channel for x and the blue channel for y, and a pixel in the displacement map has a red value of 255 and a blue value of 0, the corresponding pixel in the target object will be displaced positively 100% in the x direction and negatively 100% in the y direction.  The actual number of pixels that 100% represents depends on a specified scale factor.</p>
<p>For a map projection, then, what we have to do is go through the unprojected source image pixel by pixel and determine how far each pixel has to be displaced on both axes by plugging the latitude and longitude values for the pixel into a projection formula.  Using red for the x displacement and blue for the y displacement, below is the displacement map I generated for turning the unprojected map into Winkel Tripel.</p>
<p><img src="http://www.cartogrammar.com/images/displacement_map.jpg" alt="Winkel Tripel displacement map" /></p>
<p>I then applied that to the source image.  The result?  Yuck.</p>
<p><img src="http://www.cartogrammar.com/images/projected_displacement.jpg" alt="Projected map from DisplacementMapFilter" /></p>
<p>It&#8217;s probably possible to mess with this method and produce better results.  As previously suggested, though, I&#8217;ve already spent too much time doing that without coming up with anything decent.  In my experience there are three drawbacks to using the DisplacementMapFilter for map projections: (1) because of the way the filter works, if what you know ahead of time is the exact distance that pixels need to be displaced, it seems to be necessary to iterate over every single pixel twice, once to determine the maximum displacement in each direction for the entire image and once to then actually draw the displacement map; (2) precision in displacement is very limited, as it can only be from 0 to 127, in whole numbers, in either direction (multiplied by the scale factor); and (3) some projections will result in larger images than the original unprojected map, and it is a nuisance to try to deal with those using this method.</p>
<p>Screw it, then.  Why not just move the pixels manually?  To do this, we basically look at each pixel in the source image, run its latitude and longitude through the projection formula to determine its new location on the projected map, and then draw that pixel on the projected map with the color of the source pixel.  Here&#8217;s what happened when I did that:</p>
<p><img src="http://www.cartogrammar.com/images/projected_resampled.jpg" alt="Winkel Tripel map projected pixel-by-pixel" /></p>
<p>Hey, it&#8217;s the correct shape!  But there are two issues with distorting a map to project it, namely, that the map is going to be compressed in some places and stretched in others.  I&#8217;ve already attempted to deal with the compression in the above image.  Instead of directly transferring the color of a source pixel to the projected map, I kept track of all the source colors that corresponded to a pixel on the projected map, then drew the average color on that projected pixel.  Otherwise, when more than one source pixel corresponds to a projected pixel, the color would just be replaced every time one of those source pixels is encountered.  In this case it was actually difficult to see much difference, but the attempt at resampling seemed like a good idea.</p>
<p>The second issue, the stretched parts, is evident in the above map, showing up as those white (empty) curves emanating from the edges.  That occurred where pixels on the projected map had no corresponding source pixel because of distance distortions in the projection.  To correct for this I did a simple interpolation in which I identified pixels with no data and assigned each a color that was the average of any neighboring colors.  With that, then, we have our final map:</p>
<p><img src="http://www.cartogrammar.com/images/projected_interpolated.jpg" alt="Interpolated Winkel Tripel map" /></p>
<p>It&#8217;s not the most beautiful map, but not too bad, I&#8217;d say.  That&#8217;s just one type of projection, though.  As you might expect, the more interpolation that&#8217;s needed, the worse it&#8217;s going to look with these methods.  Below, for example, is part of a Mercator projection.  (Remember how I said larger map projections are a nuisance with the DisplacementMapFilter?  Well, they&#8217;re kind of a nuisance in general, hence &#8220;part of&#8221; a map here.)  The Mercator projection stretches the map pretty significantly in high latitudes, and as you can see the map doesn&#8217;t look very good near the top and bottom.</p>
<p><img src="http://www.cartogrammar.com/images/projected_mercator.jpg" alt="Mercator map" /></p>
<p>It&#8217;s also worth noting that these raster methods are probably best with continuous images like the example used here.  The flaws are more noticeable with a rasterized line map, as below (projected using a source image from the wonderful <a href="http://www.csiss.org/map-projections/index.html">Gallery of Map Projections</a>).</p>
<p><img src="http://www.cartogrammar.com/images/projected_interpolated_line.jpg" alt="Winkel Tripel line map" /></p>
<p>And Mercator&#8217;s not so hot:</p>
<p><img src="http://www.cartogrammar.com/images/projected_mercator_line.jpg" alt="Mercator line map" /></p>
<p>For the record, here&#8217;s what a nice, scalable, vector map projection from a shapefile looks like in Flash:</p>
<p><img src="http://www.cartogrammar.com/images/projected_vector.jpg" alt="Projected vector map" /></p>
<p>This little experiment has demonstrated that reprojecting raster maps in ActionScript is possible, perhaps with acceptable results in a pinch, but it&#8217;s far from perfect.  I don&#8217;t doubt that it would be possible to use more advanced resampling and interpolation methods, but this is already a lot to deal with.  The projections here took several seconds to compute and draw on my machine.  That&#8217;s probably already an eternity in computer time, especially for a relatively small image, and it&#8217;s only going to grow as the algorithm becomes more complex.  (Okay, minus the time that would be saved if my surely inefficient code were improved.)  This kind of thing isn&#8217;t Flash&#8217;s strong suit anyway, right?  Real geographic raster processing is being done with things like <a href="http://www.gdal.org">GDAL</a>.</p>
<p>But again: in a pinch, it works!</p>
<p>Some references:</p>
<ul>
<li>The aforementioned <a href="http://www.csiss.org/map-projections/index.html">Gallery of Map Projections</a> is a good resource for seeing what different projections look like.</li>
<li>This <a href="http://www.btinternet.com/~se16/js/mapproj.htm">Java applet demonstrating map projections</a> appears to use a raster map, though I&#8217;m not entirely sure how it operates. The source code is available.</li>
<li>For map projection formulas, I recommend <a href="http://mathworld.wolfram.com/topics/MapProjections.html">Wolfram Mathworld</a> or <a href="http://en.wikipedia.org/wiki/Map_projection">Wikipedia</a>.</li>
<li>If you have access to the journal <em>Cartographic Perspectives</em>, check out Number 59 (Winter 2008) to see a gallery artistic renderings of map projection distortions by daan Strebe. The displacement map image used in this post reminded me of those images, which were presented at the 2007 <a href="http://www.nacis.org/">NACIS</a> conference.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/raster-map-projection-with-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Continuous curves with ActionScript 3</title>
		<link>http://www.cartogrammar.com/blog/continuous-curves-with-actionscript-3/</link>
		<comments>http://www.cartogrammar.com/blog/continuous-curves-with-actionscript-3/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 16:12:39 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[curves]]></category>
		<category><![CDATA[drawing]]></category>
		<category><![CDATA[isolines]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=3</guid>
		<description><![CDATA[Seeing my comrade Zach Johnson&#8217;s impressive work on generating isoline maps in Flash, I offered to try to lend a hand with smoothing the lines (point-to-point connections) he was deriving from interpolations via Delauney triangulation.  I first turned to the fantastic book Foundation Actionscript 3.0 Animation: Making Things Move!, in which Keith Peters presents [...]]]></description>
			<content:encoded><![CDATA[<p>Seeing my comrade <a href="http://indiemaps.com/blog">Zach Johnson&#8217;s</a> impressive work on generating <a href="http://indiemaps.com/blog/2008/06/isolining-package-for-actionscript-3/">isoline maps in Flash</a>, I offered to try to lend a hand with smoothing the lines (point-to-point connections) he was deriving from interpolations via Delauney triangulation.  I first turned to the fantastic book <em>Foundation Actionscript 3.0 Animation: Making Things Move!</em>, in which <a href="http://www.bit-101.com/blog/">Keith Peters</a> presents a method for drawing a continuous curve based on multiple points.  (<a href="http://www.gskinner.com/blog/">Grant Skinner</a> has a post with a nice <a href="http://www.gskinner.com/blog/archives/2008/05/drawing_curved.html">demo of the same method</a> and an even cooler demo of a double-line version for fills.)  While the method produces a nice, smooth, continuously curved line, it&#8217;s not very appropriate for the isoline problem because the curve doesn&#8217;t actually pass <em>through</em> any of the specified points, save the first and last.  The points in this case are interpolations, so a smoothed line that is  essentially an interpolation of an interpolation would be sacrificing too much accuracy.</p>
<p><img style="border: 0pt none;" src="http://www.cartogrammar.com/images/bezier.jpg" alt="Bezier curves" width="388" height="149" /></p>
<p>The bottom line is that I had no luck finding a satisfactory way to use Flash&#8217;s built-in <code>curveTo</code> method&mdash;which draws quadratic <a href="http://en.wikipedia.org/wiki/Bezier_curve">Bézier curves</a>&mdash;and instead opted for creating cubic Bézier curves (compare the two in the above image from the Flash documentation).  Thanks to Flash&#8217;s BezierSegment class, it&#8217;s pretty easy to construct these curves.  With my limited understanding of the math involved, however, finding good control points for a continuous curve was a bit more challenging.</p>
<p>I put together an AS3 <a href="http://cartogrammar.com/source/CubicBezier.as">CubicBezier class</a>, which for now just contains two methods: one to draw a continuous series of curves through many points (as was my goal), and one to draw a single curve between two points (seemed worthwhile to throw that in), both demonstrated below.  I&#8217;m sure there are a few kinks (ha!) to work out, but generally the results seem pretty satisfying. This was written with cartographic generalization in mind, but hopefully it can be more broadly useful.</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_curveTest_2071315139"
			class="flashmovie"
			width="400"
			height="480">
	<param name="movie" value="http://cartogrammar.com/flash/curveTest.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://cartogrammar.com/flash/curveTest.swf"
			name="fm_curveTest_2071315139"
			width="400"
			height="480">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>Files:<br />
<em>These are old versions! See my <a href="http://www.cartogrammar.com/blog/actionscript-curves-update/">update post</a> for the latest.</em><br />
<a href="http://cartogrammar.com/source/CubicBezier_May08.as">CubicBezier.as</a><br />
<a href="http://cartogrammar.com/source/curveTest.zip">curveTest.zip</a> (AS plus the above demo)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/continuous-curves-with-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Drawing dashed lines with ActionScript 3</title>
		<link>http://www.cartogrammar.com/blog/drawing-dashed-lines-with-actionscript-3/</link>
		<comments>http://www.cartogrammar.com/blog/drawing-dashed-lines-with-actionscript-3/#comments</comments>
		<pubDate>Fri, 30 May 2008 22:16:22 +0000</pubDate>
		<dc:creator>Andy Woodruff</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[drawing]]></category>

		<guid isPermaLink="false">http://www.cartogrammar.com/blog/?p=5</guid>
		<description><![CDATA[Drawing in Flash dynamically with ActionScript is a jolly fun time, but when doing so one of course lacks some of the finer controls of drawing the graphics manually in the Flash authoring environment.  One such deficiency is dashed lines, so a while back I made a simple DashedLine class in AS3 to use [...]]]></description>
			<content:encoded><![CDATA[<p>Drawing in Flash dynamically with ActionScript is a jolly fun time, but when doing so one of course lacks some of the finer controls of drawing the graphics manually in the Flash authoring environment.  One such deficiency is dashed lines, so a while back I made a simple DashedLine class in AS3 to use here and there in my projects.</p>
<p>It&#8217;s basically a Sprite that has simple drawing methods with dashed lines. Just make a new instance, providing the line width, color, and an array of alternating dash and gap lengths (in pixels).  Then call <code>moveTo()</code> and <code>lineTo()</code> methods directly on the Sprite, not its <code>graphics</code> property.  (You can also do <code>beginFill()</code> if you want.) For example:</p>
<div class="codeblock">
<p><img src="http://www.cartogrammar.com/images/dashedLine.jpg" alt="Dashed line triangle" /></p>
<p><code>var dashy:DashedLine = new DashedLine(1,0x339933,new Array(8,4,2,4));<br />
dashy.moveTo(0,50);<br />
dashy.lineTo(100,0);<br />
dashy.lineTo(200,50);<br />
dashy.lineTo(300,0);<br />
addChild(dashy);<br />
</code></p>
</div>
<p style="text-align:center;">Try it out below!</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_dashTest_640421637"
			class="flashmovie"
			width="400"
			height="200">
	<param name="movie" value="http://www.cartogrammar.com/flash/dashTest.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.cartogrammar.com/flash/dashTest.swf"
			name="fm_dashTest_640421637"
			width="400"
			height="200">
	<!--<![endif]-->
		
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>This is by no means complete, as I&#8217;d like to add the rest of the usual drawing methods (curves are going to be tricky) and resolve the bugs that surely exist.  For now, though, download the <a href="http://www.cartogrammar.com/source/DashedLine.as">DashedLine class</a> as is; hopefully it&#8217;ll make sense through the basic comments I&#8217;ve included.</p>
<p><a href="http://www.cartogrammar.com/source/DashedLine.as">DashedLine.as</a><br />
<a href="http://www.cartogrammar.com/source/dashTest.zip">dashTest.zip</a> (AS file plus the above demo FLA)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cartogrammar.com/blog/drawing-dashed-lines-with-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>38</slash:comments>
		</item>
	</channel>
</rss>
