<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html" />
  <link rel="self" type="application/atom+xml" href="http://www.insideria.com/atom.xml" />
  <id>tag:www.insideria.com,2009://34/tag:www.insideria.com,2008://34.24067-</id>
  <updated>2009-11-18T18:27:55Z</updated>
  <title>Comments for Visualizing Geographic Data Sets (http://www.insideria.com/2008/06/working-with-geogrpahic-data.html)</title>
  <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.21-en</generator>
  <entry>
    <id>tag:www.insideria.com,2008://34.24067</id>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://blogs.oreilly.com/cgi-bin/mt/mt-atom.cgi/weblog/blog_id=34/entry_id=24067" title="Visualizing Geographic Data Sets" />
    <published>2008-06-20T02:18:48Z</published>
    <updated>2008-06-20T13:10:29Z</updated>
    <title>Visualizing Geographic Data Sets</title>
    <summary>Continuing on with my recent trend of posts related to data visualization and web based mapping, this time I&apos;ve decided to have some fun and combine the two with the visualization of geographic data.   </summary>
    <author>
      <name>Andrew Trice</name>
      
    </author>
    
    <category term="Blogs" />
    
    <content type="html" xml:lang="en" xml:base="http://www.insideria.com/">
      <![CDATA[Continuing on with my recent trend of posts related to <a href="http://www.cynergysystems.com/blogs/page/andrewtrice?entry=visualizing_data_in_multiple_dimensions" target="_blank">data visualization</a> and <a href="http://www.insideria.com/2008/05/google-releases-as3-maps-api.html" target="_blank">web based mapping</a>, this time I've decided to have some fun and combine the two with the visualization of geographic data.   
<br /><br />
Before I get started, it is important to note that GIS on the web has become a commodity.  There are numerous APIs that can be used to enhance your RIAs with mapping and/or GIS related information.  Here are a few web based mapping APIs, just to get started:
<br /><br />
<a href="http://code.google.com/apis/maps/" target="_blank">Google MAPs API</a>   (flex/flash/javascript)<br/>
<a href="http://developer.yahoo.com/maps/" target="_blank">Yahoo Maps API</a>   (flex/flash/javascript)<br/>
<a href="http://www1.arcwebservices.com/v2006/index.jsp" target="_blank">ESRI Arcwebservices</a>  (flex/javascript)<br/>
<a href="http://developer.mapquest.com/" target="_blank">MapQuest</a>   (flex/flash/javascript)<br/>
<a href="http://modestmaps.com/" target="_blank">Modest Maps</a>  (flex/flash)<br/>
<a href="http://www.pushpin.com/" target="_blank">Pushpin</a>  (javascript)<br/>

<br />
In this example, I decided to use the recently released <a href="http://code.google.com/apis/maps/documentation/flash/intro.html" target="_blank">Google Maps API for Flash/Flex</a>.  I actually didn't set out on this topic;  I started out by google-ing the term "data set", just to see what comes up.   I knew there had to be some public data sets that I could tackle for Flex-based data visualization.   I came across a <a href="http://lib.stat.cmu.edu/DASL/DataArchive.html" target="_blank">library of statistical data sets (from 1996) </a> hosted by <a href="http://www.cmu.edu/index.shtml" target="_blank">Carnegie Melon University</a>.   
<br/><br/>
The <a href="http://lib.stat.cmu.edu/DASL/Datafiles/USTemperatures.html" target="_blank">"US Temperatures" data set</a> grabbed my attention because it seemed like a perfect data set that can be used to show how to visualize geographically related data.   From the dataset:
<br/><br/>
<blockquote>The data gives the normal average January minimum temperature in degrees Fahrenheit with the latitude and longitude of 56 U.S. cities. (For each year from 1931 to 1960, the daily minimum temperatures in January were added together and divided by 31. Then, the averages for each year were averaged over the 30 years.)</blockquote>
<br/>
My first thought was that this would be great to show a point on the map for each city, with the color varying to show the average value for that geographic location.
Here is what I came up with...  This example shows the average temperature per geographic location, and shows the data trend hot to cold (red to blue):  <em>I apologize to those that are color blind, since they won't be able to see the nuances of this example.</em>
<br /><br />

<iframe 
src="http://www.tricedesigns.com/portfolio/googletemps/geographicDistribution.html"
width="425" height="550" frameborder="0">
</iframe>
<br /><br />
The map is still completely interactive.  You can zoom in/out with the mouse wheel, click and drag, or you can click on a row in the datagrid to center on that lat/lon.   <em>One note though,  I've noticed that not all of the lat/lon coordinates in the data set exactly match the actual geographic center of the locations.</em>

<br /><br />
Now, here's how it all works...   The first thing that I had to do was transform the tabular data into a format that can be easily consumed by a flex application.   I used simple string replacement to replace tabs (\t) with a colon, and newline (\n) with a semicolon, and then used basic string parsing to transform that into xml that I could easily use in the example.

<br /><br />
<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;"> 
<code language="perl">
<pre><span class="category1">private</span> <span class="category1">function</span> onCreationComplete() : <span class="category1">void</span>
{
 	<span class="category1">var</span> output : <span class="category2">XML</span> = <span class="category1">new</span> <span class="category2">XML</span>( "<span class="quote">&lt;dataset /&gt;</span>" );
 	<span class="category1">var</span> sourceData : <span class="category2">String</span> = "<span class="quote">Mobile, AL:44:31.2:88.5;Montgomery, AL:38:32.9:86.8;Phoenix, AZ:35:33.6:112.5;Little Rock, AR:31:35.4:92.8;Los Angeles, CA:47:34.3:118.7;San Francisco, CA:42:38.4:123.0;Denver, CO:15:40.7:105.3;New Haven, CT:22:41.7:73.4;Wilmington, DE:26:40.5:76.3;Washington, DC:30:39.7:77.5;Jacksonville, FL:45:31.0:82.3;Key West, FL:65:25.0:82.0;Miami, FL:58:26.3:80.7;Atlanta, GA:37:33.9:85.0;Boise, ID:22:43.7:117.1;Chicago, IL:19:42.3:88.0;Indianapolis, IN:21:39.8:86.9;Des Moines, IA:11:41.8:93.6;Wichita, KS:22:38.1:97.6;Louisville, KY:27:39.0:86.5;New Orleans, LA:45:30.8:90.2;Portland, ME:12:44.2:70.5;Baltimore, MD:25:39.7:77.3;Boston, MA:23:42.7:71.4;Detroit, MI:21:43.1:83.9;Minneapolis, MN:2:45.9:93.9;St. Louis, MO:24:39.3:90.5;Helena, MT:8:47.1:112.4;Omaha, NE:13:41.9:96.1;Concord, NH:11:43.5:71.9;Atlantic City, NJ:27:39.8:75.3;Albuquerque, NM:24:35.1:106.7;Albany, NY:14:42.6:73.7;New York, NY:27:40.8:74.6;Charlotte, NC:34:35.9:81.5;Raleigh, NC:31:36.4:78.9;Bismarck, ND:0:47.1:101.0;Cincinnati, OH:26:39.2:85.0;Cleveland, OH:21:42.3:82.5;Oklahoma City, OK:28:35.9:97.5;Portland, OR:33:45.6:123.2;Harrisburg, PA:24:40.9:77.8;Philadelphia, PA:24:40.9:75.5;Charleston, SC:38:33.3:80.8;Nashville, TN:31:36.7:87.6;Amarillo, TX:24:35.6:101.9;Galveston, TX:49:29.4:95.5;Houston, TX:44:30.1:95.9;Salt Lake City, UT:18:41.1:112.3;Burlington, VT:7:45.0:73.9;Norfolk, VA:32:37.0:76.6;Seattle, WA:33:48.1:122.5;Spokane, WA:19:48.1:117.9;Madison, WI:9:43.4:90.2;Milwaukee, WI:13:43.3:88.1;Cheyenne, WY:14:41.2:104.9</span>";
 	<span class="category1">var</span> rows : <span class="category2">Array</span> = sourceData.<span class="category2">split</span>( "<span class="quote">;</span>" );
 	<span class="category1">for</span> each ( <span class="category1">var</span> row : <span class="category2">String</span> <span class="category1">in</span> rows )
 	{
  		<span class="category1">var</span> <span class="category2">data</span> : <span class="category2">XML</span> = <span class="category1">new</span> <span class="category2">XML</span>( "<span class="quote">&lt;data /&gt;</span>" ); 
  		<span class="category1">var</span> i : <span class="category1">int</span> = 0;
  		<span class="category1">var</span> columns : <span class="category2">Array</span> = row.<span class="category2">split</span>( "<span class="quote">:</span>" );
  		<span class="category1">for</span> each ( <span class="category1">var</span> column : <span class="category2">String</span> <span class="category1">in</span> columns )
  		{
   			<span class="category1">switch</span> ( i )
   			{
    				<span class="category1">case</span> 0: 
    					<span class="category2">data</span>.@location = column;
    					<span class="category1">break</span>;
    				<span class="category1">case</span> 1: 
    					<span class="category2">data</span>.@janTemp = column;
    					<span class="category1">break</span>;
    				<span class="category1">case</span> 2: 
    					<span class="category2">data</span>.@lat = column;
    					<span class="category1">break</span>;
    				<span class="category1">case</span> 3: 
    					<span class="category2">data</span>.@lon = column;
    					<span class="category1">break</span>;
    			}
   			i ++;
   		}
  		output.<span class="category2">appendChild</span>( <span class="category2">data</span> );
  	}
 	outputText.<span class="category2">text</span> = output.toXMLString();
}</pre>
</code>
 
</div></div> 
<br/>

And here is how it turned out...

<iframe 
src="http://www.tricedesigns.com/portfolio/googletemps/dataTransform.html"
width="425" height="350" frameborder="0">
</iframe>
<br /><br />

Next, I setup a flex project to display this in a datagrid, and to display the data on a map.  I used the same technique as my <a href="http://www.insideria.com/2008/05/google-releases-as3-maps-api.html" target="_blank">previous post on the Google Maps API</a> to display the map within a Flex application.
<br /><br />
The next step was to calculate the appropriate colors for the markers on the map, and go ahead and add the markers to the map.   I used the color blue (0000FF) to denote the coldest data point, and the color red (FF0000) to denote the warmest data point.   I adapted a color-tween technique from <a href="//http://www.darronschall.com/weblog/archives/000251.cfm" target="_blank">Darron Schall</a> to calculate the incremental color values from the low to high value.

<br/><br/>
<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;"> 
<code language="perl">
<pre><span class="category1">public</span> <span class="category1">function</span> getTempColor( temp : <span class="category2">Number</span> ) : <span class="category1">int</span>
{
 	<span class="category1">var</span> percentage : <span class="category2">Number</span> = (temp / maxTemp);
 	<span class="category1">return</span> ( ( maxColorObj.r - percentage * delta.r ) &lt;&lt; 16 )
            + ((maxColorObj.g - percentage * delta.g ) &lt;&lt; 8 )
            + ( maxColorObj.b - percentage * delta.b );
}</pre>
</code>
 
</div></div> 

<br/>
Then, the map markers were added based on the calculated color and the lat/lon coordinates:

<div class="acode" style="overflow: auto; padding: 10px;" ><div style="overflow-x: visible;"> 
<code language="perl">
<pre><span class="category1">public</span> <span class="category1">function</span> getTempColor( temp : <span class="category2">Number</span> )<span class="category1">for</span> each ( <span class="category1">var</span> <span class="category2">data</span> : <span class="category2">XML</span> <span class="category1">in</span> dataSet.<span class="category2">data</span> )
{
 	<span class="category1">var</span> latlng:LatLng = <span class="category1">new</span> LatLng( <span class="category1">parseFloat</span>( <span class="category2">data</span>.@lat ), -<span class="category1">parseFloat</span>( <span class="category2">data</span>.@lon ) );
 	<span class="category1">var</span> markerOptions : MarkerOptions = <span class="category1">new</span> MarkerOptions({
          strokeStyle: <span class="category1">new</span> StrokeStyle({<span class="category2">color</span>: 0x000000}),
          fillStyle: <span class="category1">new</span> FillStyle({<span class="category2">color</span>: getTempColor( <span class="category1">parseFloat</span>( <span class="category2">data</span>.@janTemp.<span class="category2">toString</span>() ) ), alpha: 0.8}),
          radius: 12,
          hasShadow: <span class="category1">true</span>
        })
 	markerOptions.tooltip = <span class="category2">data</span>.@location.<span class="category2">toString</span>() + "<span class="quote">:    </span>" + <span class="category2">data</span>.@janTemp.<span class="category2">toString</span>() + "<span class="quote"> F</span>";
 	<span class="category1">var</span> marker : Marker = <span class="category1">new</span> Marker( latlng, markerOptions );
 	map.addOverlay( marker );
}</pre>
</code>
 
</div></div> 

<br /><br />

Full source code is available at:<br/>
<a href="http://www.tricedesigns.com/portfolio/googletemps/srcview/" target="_blank">http://www.tricedesigns.com/portfolio/googletemps/srcview/</a>

<br /><br />
___________________________________<br />
<strong>Andrew Trice</strong><br />
Principal Architect<br />
<a href="http://www.cynergysystems.com" target="_blank">Cynergy Systems<br />
http://www.cynergysystems.com</a>]]>
      
    </content>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2018215</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2018215" />
    <title>Comment from Fernanda Gomez on 2008-06-23</title>
    <author>
        <name>Fernanda Gomez</name>
        <uri>http://www.adsmap.net</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.adsmap.net">
        <![CDATA[<p>Great example, hopefully I can incorporate some to my site. Thanks!</p>]]>
    </content>
    <published>2008-06-23T17:03:03Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2018797</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2018797" />
    <title>Comment from Gary T on 2008-07-15</title>
    <author>
        <name>Gary T</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>This is really cool! One question for you, say you wanted the markers to show up one after another rather than all at once, how would you add a timer to the source code?</p>]]>
    </content>
    <published>2008-07-15T20:09:53Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2046978</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2046978" />
    <title>Comment from Scott Stern on 2008-11-25</title>
    <author>
        <name>Scott Stern</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Is there any way to do something similar in the regular API?  I need to accomplish this for hundreds of data points, but it seems that I would then have to make 100s of separate little icons.  I have no flash experience to be able to mimic what you've done so far.  Any help would be greatly appreciated!</p>]]>
    </content>
    <published>2008-11-25T15:27:47Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2046982</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2046982" />
    <title>Comment from Andrew Trice on 2008-11-25</title>
    <author>
        <name>Andrew Trice</name>
        <uri>http://www.tricedesigns.com</uri>
    </author>
    <content type="html" xml:lang="en" xml:base="http://www.tricedesigns.com">
        <![CDATA[<p>You could probably use HTML and CSS styles to dynamically set colors on points.  If you are using purely images as data points, then you need a different image for each color/data point.   The benefit with Flash is that you can dynamically change all the colors at runtime.</p>]]>
    </content>
    <published>2008-11-25T15:37:30Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2047053</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2047053" />
    <title>Comment from Scott Stern on 2008-11-25</title>
    <author>
        <name>Scott Stern</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>Thanks for the response.  I definitely did not want to create a different image for each GIcon.</p>

<p>After thinking about it some more, I realized I could use the GPolyline to do what I want.  I have the line going from point X to 0.0000001 latitude/longitude away, so it looks like a point (but is actually a line).  The line color is specified by HTML hexadecimal, and you can add a click event to pull up data.  Works perfectly!  For even more heating effects, I have the weighting of the "line" change as well.</p>

<p>Thanks again anyways.</p>]]>
    </content>
    <published>2008-11-26T00:02:39Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2057280</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2057280" />
    <title>Comment from santosh kumar sadasivuni on 2009-04-09</title>
    <author>
        <name>santosh kumar sadasivuni</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>sir,<br />
i found your example interesting when i was searching some data for my term project. i would appreciate your concern if you could tell how and where to run the source code, so as to run the application and what softwares have to be installed , as i am technically nil. i would be thankful for the patience. </p>]]>
    </content>
    <published>2009-04-09T22:44:28Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2192359</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2192359" />
    <title>Comment from John on 2009-11-18</title>
    <author>
        <name>John</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>I really like your example.  Great work!  I am trying to do a similar project, but would like to display a marker info window when I click on either the marker or the data grid.  Do you have any suggestions on how to do this?  I seem to be stuck.  Thanks!</p>]]>
    </content>
    <published>2009-11-18T18:26:19Z</published>
  </entry>

  <entry>
    <id>tag:www.insideria.com,2008://34.24067-comment:2192361</id>
    <thr:in-reply-to ref="tag:www.insideria.com,2008://34.24067" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html"/>
    <link rel="alternate" type="text/html" href="http://www.insideria.com/2008/06/working-with-geogrpahic-data.html#comment-2192361" />
    <title>Comment from John on 2009-11-18</title>
    <author>
        <name>John</name>
        <uri></uri>
    </author>
    <content type="html" xml:lang="en" xml:base="">
        <![CDATA[<p>I really like your example.  Great work!  I am trying to do a similar project, but would like to display a marker info window when I click on either the marker or the data grid.  Do you have any suggestions on how to do this?  I seem to be stuck.  Thanks!</p>]]>
    </content>
    <published>2009-11-18T18:27:48Z</published>
  </entry>

</feed
