<?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>mikejcorey.com</title>
	<atom:link href="http://www.mikejcorey.com/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mikejcorey.com/wordpress</link>
	<description>Online mapping, data visualization, and the future of journalism.</description>
	<lastBuildDate>Fri, 25 Feb 2011 21:53:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Tutorial part 2: Create beautiful hillshade maps from digital elevation models with GDAL and Mapnik</title>
		<link>http://www.mikejcorey.com/wordpress/2011/02/25/tutorial-part-2-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/</link>
		<comments>http://www.mikejcorey.com/wordpress/2011/02/25/tutorial-part-2-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 21:31:44 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[digital elevation model]]></category>
		<category><![CDATA[gdal]]></category>
		<category><![CDATA[GeoTIFF]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[Mapnik]]></category>
		<category><![CDATA[open-source]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=389</guid>
		<description><![CDATA[In part 1 of our GDAL and Mapnik hillshade map tutorial, we used GDAL to convert tiled USGS digital elevation models to a merged GeoTIFF. When also reprojected the map to Mercator and used a California border shapefile to cut...]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.mikejcorey.com/wordpress/2011/02/05/tutorial-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/">In part 1 of our GDAL and Mapnik hillshade map tutorial</a>, we used GDAL to convert tiled USGS digital elevation models to a merged GeoTIFF. When also reprojected the map to Mercator and used a California border shapefile to cut out just the state of California.</p>
<p>In this installment, we&#8217;ll use the result as a Mapnik layer, and check out some different options for using raster data in your Mapnik maps.</p>
<p>Before we dive in, a note about versions. In this tutorial I&#8217;m using Mapnik2, which is now in beta release. I&#8217;m doing this both because Mapnik2 adds some exciting new capabilities, and so this tutorial is worth anything for more than a few weeks. Even though Mapnik2 is still beta, I&#8217;ve been running it for several weeks now and so far haven&#8217;t run into any serious difficulties, so especially if you&#8217;re on Mac OS X, I&#8217;d recommend giving version 2 a shot.</p>
<p>Even if you do run into problems, <a href="http://www.mail-archive.com/mapnik-users@lists.berlios.de/info.html">the Mapnik listserv is very active</a>, and the developers themselves are very quick to respond with help and to fix bugs. If only every open-source project was so well-maintained!</p>
<p>If you&#8217;re not running version 2, a lot of this will still work, though you might need to tweak syntax a little bit. I&#8217;ll note anything you just can&#8217;t do in Mapnik before version 2.</p>
<p><strong>Data mis en place</strong></p>
<p>Here&#8217;s the data we&#8217;ll use for this part of the tutorial:</p>
<ul>
<li><a href="http://www.mikejcorey.com/download/ca-mercator.tar.gz">A California border shapefile in Mercator projection (SRID 3395)</a></li>
<li><a href="http://www.mikejcorey.com/download/california_county_shortline.tar.gz">A California county/shorelines shapefile (SRID 4326)</a></li>
<li><a href="http://www.mikejcorey.com/download/california_water.tar.gz">A California water shapefile (SRID 4269)</a></li>
<li><a href="http://www.mikejcorey.com/download/ca-dem-combined-merc-cutout.tif.gz">The final GeoTIFF cutout from part 1</a> (This is an 88 MB file, so don&#8217;t download if you don&#8217;t have to!)</li>
</ul>
<p>Now on to the fun!</p>
<p>First, let&#8217;s do a basic Mapnik map with our GeoTIFF layer. For many Mapnik maps, <a href="https://github.com/mapnik/Cascadenik/wiki/Cascadenik">Cascadenik makes styling much simpler for anyone familiar with CSS syntax</a>, but currently (February 2011) Cascadenik doesn&#8217;t support raster layers. So we&#8217;ll start with this XML:</p>
<p><code>&lt;Map srs="+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="hillshade style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;RasterSymbolizer opacity="1" scaling="bilinear" mode="normal" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="hillshade"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;hillshade style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;gdal&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/yourname/Documents/gdaltutorial/ca-dem-combined-merc-cutout.tif&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&lt;/Map&gt;</code></p>
<p>Let&#8217;s break this down in stages. First, the overall <strong>&lt;Map&gt;</strong> wrapper:</p>
<p><code>&lt;Map srs="+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"&gt;<br />
&lt;/Map&gt;</code></p>
<p>This is where we set the projection of the overall map. Don&#8217;t worry, you don&#8217;t need to understand what all of it means (although it&#8217;s fun to find out!). As you no doubt noticed, this is the same srs data we used to reproject our GeoTIFF in part 1.</p>
<p>One of the great features of Mapnik is that even if the data for separate layers are in different projections, in most cases Mapnik can simply reproject that data on the fly. You can&#8217;t reproject raster data within Mapnik, however, so you&#8217;ll always want to be sure that you get your GeoTIFF into the projection you want your final map to use before you get to Mapnik (as we did in part 1).</p>
<p>Now let&#8217;s drop down a bit to the layer data:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="hillshade"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;hillshade style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;gdal&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/yourname/Documents/gdaltutorial/ca-dem-combined-merc-cutout.tif&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;</code></p>
<p>This is where we tell Mapnik what type of data we&#8217;re using for this layer. Inside the <strong>&lt;Datasource&gt;&lt;/Datasource&gt;</strong> tags, we specify the data type (<strong>gdal</strong>), and point to the location of our GeoTIFF file. It&#8217;s good practice to use the absolute path to your files so if you move your Mapnik files you won&#8217;t break the script.</p>
<p>The remaining line inside our <strong>&lt;Layer&gt;&lt;/Layer&gt;</strong> tags is the <strong>&lt;StyleName&gt;&lt;/StyleName&gt;</strong>. This tells Mapnik which style definition to use for this layer. So let&#8217;s take a look at that style definition.</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="hillshade style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;RasterSymbolizer opacity="1" scaling="bilinear" mode="normal" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;</code><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
There&#8217;s a lot you can do with raster data, especially in Mapnik2. This style definiton is pretty basic, though. We&#8217;re saying that we want the GeoTIFF to be rendered at 100% opacity. Scaling controls how Mapnik renders the image when scaling it down from its original size, and the mode controls how the raster layer is blended with layers below it. Since there&#8217;s nothing currently behind the layer, mode is somewhat moot at the moment. <a href="http://trac.mapnik.org/wiki/RasterSymbolizer#Usage"</a>Feel free to play with different values for both scaling and mode.</a></p>
<p>That&#8217;s about it. Just make sure your style name matches the <strong>&lt;StyleName&gt;&lt;/StyleName&gt;</strong> tag in your layer.</p>
<p>That&#8217;s it for our first, pretty basic GeoTIFF Mapnik map. Save this file as <strong>ca-map.xml</strong>.</p>
<p>Now we&#8217;ll use Python to compile this XML into an image. I highly recommend that once you get the basics down, you simplify your life and download <a href="https://github.com/mapnik/Cascadenik/wiki/Cascadenik">Cascadenik</a> and <a href="http://code.google.com/p/mapnik-utils/wiki/Nik2Img">nik2img</a> to do a little of this coding for you, but at this point you&#8217;ve installed enough for one tutorial. So we&#8217;ll stick to a basic Python script. Even if you&#8217;ve never used Python before, now&#8217;s the time to start. Trust me, if you have any programming experience this will make sense.</p>
<p>Open a new text file, and save the following code as <strong>ca-stuff-compile.py</strong> into the same directory as your XML document:</p>
<p><code>#!/usr/bin/env python<br />
import mapnik2<br />
mapfile = 'ca-stuff.xml'<br />
map_output = 'ca-map.png'<br />
m = mapnik2.Map(1200, 800)<br />
mapnik2.load_map(m, mapfile)<br />
bbox = mapnik2.Box2d(mapnik2.Coord(-14000000, 3700000), mapnik2.Coord(-12500000, 5200000))<br />
m.zoom_to_box(bbox)<br />
mapnik2.render_to_file(m, map_output)</code></p>
<p>Right off the bat, if you&#8217;re not using Mapnik2 for this, you&#8217;ll need to change everthing that says <strong>mapnik2</strong> to simply <strong>mapnik</strong>.</p>
<p>Next we assign some variables. We specify our XML file for Mapnik to chew on, and tell Mapnik what filename to use for the final image.</p>
<p><code>mapfile = 'ca-stuff.xml'<br />
map_output = 'ca-map.png'</code></p>
<p>Next we instantiate a new mapnik map, and pass our XML to Mapnik&#8217;s load_map() function. We also specify the pixel dimensions we want to give our final map, 800 pixels wide by 600 pixels deep.</p>
<p><code>m = mapnik2.Map(800, 600)<br />
mapnik2.load_map(m, mapfile)</code></p>
<p>Now we tell Mapnik what bounding box we want the map to use. We&#8217;ll use this to control how much space will show up around our map content, but you could also specify only a section of the map or any other arbitrary bounding box. But how do we know what to use?</p>
<p>Remember back in part 1 when we used <strong>ogrinfo</strong> to get the bounding box of our California shapefile that we used to cut out the GeoTIFF? Here&#8217;s what that returned:</p>
<p><code>Extent: (-13849389.898804, 3810165.061203) - (-12704836.275367, 5133847.169980)</code></p>
<p>So if you want to clip your map at California&#8217;s exact boundaries, you can use that extent exactly. But generally we want our maps to have a little padding, so we&#8217;ll round up and down a bit:</p>
<p><code>bbox = mapnik2.Box2d(mapnik2.Coord(-14000000, 3700000), mapnik2.Coord(-12500000, 5200000))<br />
m.zoom_to_box(bbox)</code></p>
<p>Note that, mercifully, Mapnik uses the same format for its bounding box as <strong>ogrinfo</strong>. The points represent the lower left and upper right corners of our image.</p>
<p>Finally, the script renders the map to our file:</p>
<p><code>mapnik2.render_to_file(m, map_output)</code></p>
<p>If you haven&#8217;t already save this file into the same directory as your XML document as <strong>ca-stuff-compile.py</strong>.</p>
<p>Now, in a terminal window, change into this directory, and let&#8217;s build that map:</p>
<p><code>$ python ca-stuff-compile.py</code></p>
<p>If you don&#8217;t get any error messages, check your directory. You should see a new file called ca-map.png, and hopefully your hillshade map is in the middle.</p>
<p><img src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-mapnik-1.jpg" alt="" title="ca-mapnik-1" width="610" height="406" class="aligncenter size-full wp-image-400" /></p>
<p>Neato! Well, sort of &#8211; it&#8217;s pretty boring, right? Not much different from our original GeoTIFF. Let&#8217;s change that now by adding more styles and more map layers to our XML. We&#8217;ll add a lot at once here, but not so much conceptually:</p>
<p><code>&lt;Map background-color="rgb(51,122,207)" srs="+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="hillshade style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;RasterSymbolizer opacity="0.8" scaling="bilinear" mode="multiply" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="polygon style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;PolygonSymbolizer fill="rgb(255,204,102)" fill-opacity="1" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="county style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LineSymbolizer stroke="#CCCCCC" stroke-width="0.4" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="water style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;PolygonSymbolizer fill="rgb(51,122,207)" fill-opacity="1" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="stateborder"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;polygon style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/ca-mercator/ca-mercator.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="hillshade"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;hillshade style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;gdal&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/ca-dem-combined-merc-cutout.tif&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="water" srs="+proj=longlat +ellps=WGS84 +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;water style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/california_water/california_water.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="counties" srs="+proj=longlat +ellps=GRS80 +datum=NAD83 +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;county style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/california_county_shoreline/california_county_shoreline.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&lt;/Map&gt;</code></p>
<p>We&#8217;ve added 3 shapefile layers: one in Mercator projection that you may recognize as the state border shapefile we used to cutout the GeoTIFF in part 1:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="stateborder"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;polygon style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/ca-mercator/ca-mercator.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;</code></p>
<p>You&#8217;ll also notice that we&#8217;ve put this layer before the GeoTIFF in our XML. This is because we want the state border to be behind the GeoTIFF in the rendered image.</p>
<p>We&#8217;ve specified that this layer uses <strong>&lt;StyleName&gt;polygon style&lt;/StyleName&gt;</strong>, so let&#8217;s take a look at the <strong>polygon style</strong> style, defined above the layers:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="polygon style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;PolygonSymbolizer fill="rgb(255,204,102)" fill-opacity="1" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;</code><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
This one&#8217;s pretty simple. We set a fill color for features in this layer using standard Web RGB syntax and Mapnik&#8217;s <a href="http://trac.mapnik.org/wiki/PolygonSymbolizer"><strong>PolygonSymbolizer</strong></a>, and specify that we want 100% opacity for this layer.</p>
<p>Next let&#8217;s turn to the style for the GeoTIFF, which we&#8217;ve now changed so it will blend with our state border background layer:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="hillshade style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;RasterSymbolizer opacity="0.8" scaling="bilinear" mode="multiply" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;</code></p>
<p>We&#8217;ve changed the opacity of the GeoTIFF layer to 80%, to keep the level of gray down, and we&#8217;ve changed the blend mode to <strong>multiply</strong>. This tells Mapnik how to blend the GeoTIFF with the underlying layers. There are <a href="http://trac.mapnik.org/wiki/RasterSymbolizer#Usage">several other modes you can experiment with</a>, but in most cases you&#8217;ll probably want multiply.</p>
<p>Now we&#8217;ll add a water layer so we can see some of California&#8217;s major lakes, and then county borders. Here&#8217;s another great thing about Mapnik: You can use many types of data as layers: shapefiles, PostGIS tables and many other ogr types.</p>
<p>Here&#8217;s the top 2 layers:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="water" srs="+proj=longlat +ellps=WGS84 +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;water style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/california_water/california_water.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Layer name="counties" srs="+proj=longlat +ellps=GRS80 +datum=NAD83 +no_defs"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StyleName&gt;county style&lt;/StyleName&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="file"&gt;/Users/youruser/Documents/gdaltutorial/california_county_shoreline/california_county_shoreline.shp&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Parameter name="type"&gt;shape&lt;/Parameter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Datasource&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Layer&gt;</code><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
The main thing to notice about these layers is that we&#8217;ve specified an additional parameter in the <strong>&lt;Layer&gt;&lt;/Layer&gt;</strong> tag: <strong>srs</strong>. We&#8217;re doing this because each of these layers is in a different spatial reference system than our main map. The water layer is in SRID 4326, or standard latitude/longitude pairs. The county layer is in SRID 4269, otherwise known as NAD83. As long as you specify the correct srs, Mapnik will do any reprojection needed on the fly (though not on raster layers, remember), so there&#8217;s no need to reproject everything into the same projection on your own.</p>
<p>All that&#8217;s left is the style definitions for those two layers:</p>
<p><code>&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="county style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;LineSymbolizer stroke="#CCCCCC" stroke-width="0.4" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Style name="water style"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Rule name="rule 1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;PolygonSymbolizer fill="rgb(51,122,207)" fill-opacity="1" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Style&gt;</code></p>
<p>Nothing too fancy here. The county style is using a <a href="http://trac.mapnik.org/wiki/LineSymbolizer"><strong>LineSymbolizer</strong></a> instead of the PolygonSymbolizer we saw earlier. Look &#8211; we can use hexadecimal color codes too! And we set the stroke width to 0.4 pixels. The water style colors the water blue &#8212; not much more to say than that.</p>
<p>OK, time to render this map. In your Terminal:</p>
<p><code>$ python ca-stuff-compile.py</code></p>
<p>If you did everything right, you should have a simple but pretty nice multi-layer Mapnik map.</p>
<p><a href="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-mapnik-2.jpg"><img src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-mapnik-2.jpg" alt="" title="ca-mapnik-2" width="610" height="407" class="aligncenter size-full wp-image-402" /></a></p>
<p>Since we used a fairly high-resolution GeoTIFF, you should be able to change the image dimensions in ca-stuff-compile.py to make the image quite large for print, HD video, or a poster for your bedroom. But even I don&#8217;t do that with my maps!</p>
<p>Unless you want to <a href="http://www.axismaps.com/typographic.php">send me this one</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2011/02/25/tutorial-part-2-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial: Create beautiful hillshade maps from digital elevation models with GDAL and Mapnik</title>
		<link>http://www.mikejcorey.com/wordpress/2011/02/05/tutorial-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/</link>
		<comments>http://www.mikejcorey.com/wordpress/2011/02/05/tutorial-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 06:59:37 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[digital elevation model]]></category>
		<category><![CDATA[gdal]]></category>
		<category><![CDATA[GeoTIFF]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[Mapnik]]></category>
		<category><![CDATA[open-source]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=368</guid>
		<description><![CDATA[Mapnik is your best friend if you want to create map tiles for a slippy map or just want an open-source way to output high-quality printed maps for a wide variety of uses. Though for your first project I might...]]></description>
			<content:encoded><![CDATA[<p>Mapnik is your best friend if you want to create map tiles for a slippy map or just want an open-source way to output high-quality printed maps for a wide variety of uses.</p>
<p>Though for your first project I might recommend a somewhat lower-priority project, <a href="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/SaveTheDate3-5x5.jpg">I like to think I&#8217;m the only person to ever use Mapnik to make wedding invitations</a>.</p>
<p>(If I&#8217;m wrong, I&#8217;d love to see more examples!)</p>
<p>One of Mapnik&#8217;s greatest strengths is its ability to combine multiple types of data into a single map: shapefiles, PostGIS data and raster data are all easy to combine.</p>
<p>When I began working with GIS data I started with exclusively vector data, because vector data are so easily scaled to any size and don&#8217;t take up much storage space. Vector layers are also easy to color and style, and are great at keeping your thematic maps clean and easy to read.</p>
<p>But sooner or later you&#8217;ll want to add some texture to your maps, and it&#8217;s time to add elevation models with raster data.</p>
<p>Luckily, there&#8217;s lots of raster data available to get started. The <a href="http://edc2.usgs.gov/geodata/index.php">USGS publishes digital elevation models (.DEM) of most of the United States</a> (everywhere except Alaska, I believe). This is definitely high-enough resolution for adding texture to a state-level visualization.</p>
<p>Less luckily, the digital elevation models are sliced up into small pieces. This can be nice because it cuts down on file sizes, but if you want a statewide elevation map, you&#8217;ll have to put many pieces together.</p>
<p>A statewide elevation model of California, for example, requires <a href="http://www.brenorbrophy.com/California-DEM.htm">merging 70 .dem files at the 2 arc-second resolution</a>.</p>
<p><a href="http://www.brenorbrophy.com/California-DEM.htm"><img class="aligncenter size-full wp-image-374" title="ca-components" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-components.jpg" alt="" width="610" height="610" /></a></p>
<p>However, never fear! GDAL is here to help.</p>
<p><a href="http://www.gdal.org/">GDAL is a powerful, open-source library of translation scripts</a> for raster geographic data.</p>
<p>So with GDAL, a shapefile of California&#8217;s border and a set of digital elevation models and Mapnik, it&#8217;s straightforward to make a seamless high-resolution .PNG map of California with nice elevation hillshades.</p>
<p>This tutorial isn&#8217;t for people without any GIS or programming experience, but if you have a little of both you&#8217;ll be fine. This tutorial is for Mac OS X Snow Leopard users, but will probably work for Linux users with a few OS-related tweaks.</p>
<p>Using GDAL requires knowledge of basic GIS concepts and basic command-line programming. I&#8217;ve had good luck installing the <a href="http://www.kyngchaos.com/software/frameworks">GDAL Complete package from kyngchaos.com</a>. Scroll down to the &#8220;GDAL 1.8 Complete&#8221; .dmg installer.</p>
<p>To get started with raster data, you mostly just need to know what a TIF image is.</p>
<p>To do any Mapnik work, you should feel comfortable with:</p>
<ul>
<li> GIS concepts like map projections</li>
<li> Shapefiles and/or PostGIS</li>
<li> XML</li>
<li> Basic command-line programming</li>
</ul>
<p>The Mapnik website has detailed <a href="http://trac.mapnik.org/wiki/MacInstallation">installation guides</a> and  <a href="http://trac.mapnik.org/wiki/MapnikTutorials">tutorials on how to use it</a>. There&#8217;s an excellent <a href="http://mojodna.net/2009/12/05/the-os-x-spatial-stack.html">OS X-specific guide to installing Mapnik and dependencies (including GDAL and many other useful spacial libraries) here</a>. There&#8217;s many ways to do it and I won&#8217;t get into that here. Just make sure you have Mapnik running with GDAL support.</p>
<p>The tutorial is divided into two parts. Part 1, this post, will focus on merging, converting, projecting and clipping the digital elevation models so they can be used with Mapnik. We&#8217;ll handle the Mapnik process in part 2.</p>
<h2>Data mis en place</h2>
<p>Here&#8217;s the data we&#8217;ll use for this tutorial:<a href="http://www.mikejcorey.com/download/ca-mercator.tar.gz"></a></p>
<ul>
<li><a href="http://www.mikejcorey.com/download/ca-mercator.tar.gz">A California border shapefile in Mercator projection (SRID 3395)</a></li>
<li> <a href="http://www.mikejcorey.com/download/raw-ca-dems.tar.gz">A g-zipped archive of all the digital elevation models you&#8217;ll need for California</a></li>
</ul>
<h2>Fun with GDAL</h2>
<p>Download and upzip the shapefile and the .dem folder. Then open a terminal window and navigate to wherever you downloaded the shapefile and dem folders.</p>
<p>Then, in the terminal:</p>
<p><code>$ cd raw-ca-dems</code></p>
<p>First we&#8217;ll merge the digital elevation model tiles into a single .dem file using <strong>gdal_merge</strong>. We need to specify that we want any areas without data to be white by specifying <strong>-init &#8220;255&#8243;</strong>. Then we specify our desired output filename with <strong>-o (filename)</strong> and then list the files we want to merge together. Like so:</p>
<p><code>$ gdal_merge.py -init "255" -o ca-dem-combined.dem alturas-e.dem alturas-w.dem bakersfield-e.dem bakersfield-w.dem chico-e.dem chico-w.dem crescent_city-e.dem death_valley-e.dem death_valley-w.dem el_centro-e.dem el_centro-w.dem eureka-e.dem fresno-e.dem fresno-w.dem goldfield-w.dem kingman-e.dem kingman-w.dem klamath_falls-w.dem las_vegas-w.dem long_beach-e.dem long_beach-w.dem los_angeles-e.dem los_angeles-w.dem lovelock-w.dem mariposa-e.dem mariposa-w.dem medford-e.dem medford-w.dem monterey-e.dem monterey-w.dem needles-e.dem needles-w.dem noyo_canyon-e.dem redding-e.dem redding-w.dem reno-e.dem reno-w.dem sacramento-e.dem sacramento-w.dem salton_sea-e.dem salton_sea-w.dem san_bernardino-e.dem san_bernardino-w.dem san_clemente_island-e.dem san_diego-e.dem san_diego-w.dem san_francisco-e.dem san_francisco-w.dem san_jose-e.dem san_jose-w.dem san_luis_obispo-e.dem san_luis_obispo-w.dem santa_ana-e.dem santa_ana-w.dem santa_cruz-e.dem santa_maria-e.dem santa_rosa_island-e.dem santa_rosa-e.dem santa_rosa-w.dem susanville-e.dem susanville-w.dem trona-e.dem trona-w.dem ukiah-e.dem ukiah-w.dem vya-w.dem walker_lake-e.dem walker_lake-w.dem weed-e.dem weed-w.dem</code></p>
<p>As long as you don&#8217;t get any errors, you should now have a new file in your folder called ca-dem-combined.dem. If you have GIS software like Quantum GIS you should be able to add this as a raster layer. If you do open it up, you shouldn&#8217;t see any seams between the former tiles &#8212; that&#8217;s what we want for a good-looking Mapnik layer.</p>
<p>But for this to work in Mapnik, we need a GeoTIFF. To convert the merged .dem to a GeoTIFF, we&#8217;ll use <a href="http://www.gdal.org/gdaldem.html"><strong>gdaldem</strong></a>. The gdaldem command has several modes; we&#8217;ll use hillshade to create a shaded relief map, the most common way to visualize texture. We also need to specify the ratio of vertical units to horizontal. Since right now the .dem is in WGS84 projection (standard latitude/longitude), we&#8217;ll use degrees, so <strong>-s 111120</strong>. Then we specify the input file and the output file. Here&#8217;s the full command:</p>
<p><code>$ gdaldem hillshade -s 111120 ca-dem-combined.dem ca-dem-combined.tif</code></p>
<p>Even if you don&#8217;t have a GIS viewer, you should be able to open the .tif file in any image browser like Preview or Photoshop. (Be careful you don&#8217;t resave the file, though &#8212; most image editors will remove necessary geometric data from the file if you re-save it.) You&#8217;ll see a few thin black lines around the outside edge of the old tile data, but don&#8217;t worry &#8212; we&#8217;ll cut this out later.</p>
<p><img class="aligncenter size-full wp-image-378" title="ca-combined" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-combined.jpg" alt="" width="620" height="620" /></p>
<p>So now we have a combined .tif, but most of the time we want to display our finished project in Mercator projection &#8212; most non-GIS types will think non-Mercator maps look a bit strange. We need to reproject our .tif to Mercator with <a href="http://www.gdal.org/gdalwarp.html"><strong>gdalwarp</strong></a>. We&#8217;ll use the <strong>-t_srs</strong> option to set the target projection, and use the projection specification for the version of Mercator that&#8217;s also used by Google Maps and OpenLayers.</p>
<p><code>$ gdalwarp -t_srs '+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs' ca-dem-combined.tif ca-dem-combined-merc.tif</code></p>
<p>If you open up the resulting file, you should see that the projection has changed.</p>
<p><img class="aligncenter size-full wp-image-379" title="ca-merc" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-merc.jpg" alt="" width="620" height="781" /></p>
<p>Now we have our final hillshade data, but we want to only show California &#8212; not all the extra stuff outside the border. We&#8217;ll use our California border shapefile as a mask to cut out just the hillshade data inside the boundary. This is a three-step process.</p>
<p>First, we determine the bounding box, or extent, of our clipping mask &#8212; the California border shapefile in this case. We use <strong>ogrinfo</strong> for this, which comes along with GDAL Complete.</p>
<p><code>$ ogrinfo -al ../ca-mercator/ca-mercator.shp</code></p>
<p>This will return a lot of details about the shapefile. But if you scroll back to the top of the output you&#8217;ll see:</p>
<p><code>Extent: (-13849389.898804, 3810165.061203) - (-12704836.275367, 5133847.169980)</code></p>
<p>These represent the longitude and latitude points (in Mercator projection) of the southwest and northeast corners of our shapefile data.</p>
<p>Next, we trim our merged Mercator .tif to those exact boundaries with <a href="http://www.gdal.org/gdal_translate.html"><strong>gdal_translate</strong></a>.</p>
<p><code>$ gdal_translate -projwin -13849389.898804 5133847.169980 -12704836.275367 3810165.061203 ca-dem-combined-merc.tif ca-dem-combined-merc-box.tif</code></p>
<p><strong>Warning:</strong> Notice that in the above command we reversed the order of the two y-axis values (5133847.169980 and 3810165.061203) from how they appeared in our ogrinfo query. This is because gdal_translate&#8217;s <strong>-projwin</strong> option is looking for the upper left and lower right coordinates &#8212; exactly the opposite of the extent we got from ogrinfo. Annoying, but that&#8217;s just the way it is.</p>
<p>Finally, we&#8217;ll use the shapefile&#8217;s polygon boundaries as a clipping mask on the merged, projected and trimmed .tif, which is now trimmed to show the same area as the shapefile. We&#8217;ll use <a><strong>gdalwarp</strong></a> for this, using some different options than before. The <strong>-co COMPRESS=DEFLATE</strong> option is a generic &#8220;creation option&#8221; that can have many values. We specify <strong>-dstalpha</strong> to create a &#8220;nodata&#8221; band in our resulting .tif, so we are left with a transparent background. And finally we use <strong>-cutline</strong> to specify a file to use as the clipping mask. As before we then specify our input file and desired output filename.</p>
<p><code>$ gdalwarp -co COMPRESS=DEFLATE -dstalpha -cutline ../ca-mercator/ca-mercator.shp ca-dem-combined-merc-box.tif ca-dem-combined-merc-cutout.tif</code></p>
<p>And there&#8217;s our textured California border. If you open <strong>ca-dem-combined-merc-cutout.tif</strong> in an image viewer, you should see a beautifully clipped grayscale image.</p>
<p><img class="aligncenter size-full wp-image-380" title="ca-cutout" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2011/02/ca-cutout.jpg" alt="" width="620" height="717" /></p>
<p><a href="http://www.mikejcorey.com/wordpress/2011/02/25/tutorial-part-2-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/">In the second half of our tutorial, we&#8217;ll use this cutout .tif as a layer in Mapnik</a>. We&#8217;re more than halfway there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2011/02/05/tutorial-create-beautiful-hillshade-maps-from-digital-elevation-models-with-gdal-and-mapnik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Maps API hands-on training, part 2</title>
		<link>http://www.mikejcorey.com/wordpress/2010/03/09/google-maps-api-hands-on-training-part-2/</link>
		<comments>http://www.mikejcorey.com/wordpress/2010/03/09/google-maps-api-hands-on-training-part-2/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 04:39:58 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=235</guid>
		<description><![CDATA[The notes from a hands-on class I'm helping teach at NICAR 2010 in Phoenix this week.]]></description>
			<content:encoded><![CDATA[<style type="text/css">
.level1 {
	list-style-type : decimal ;
	margin-left : 10px ;
}
.level2 {
	list-style-type : upper-alpha ;
	margin-left : 10px ;
}
</style>
<p><a href="http://www.mikejcorey.com/wordpress/2010/03/07/google-maps-api-hands-on-training-part-1/">Go back to part one of the training</a>.<br />
<b>Assumed knowledge:</b><br />
	HTML<br />
	Moderate to advanced Javascript understanding<br />
	CSS<br />
	XML<br />
	Google Maps API basic skills:
<ul>
<li>Initialization of map</li>
<li>Adding map controls</li>
<li>Basic adding of points, click event listeners</li>
<li>Display of map points from flat XML</li>
</ul>
<p><b>Supporting files:</b></p>
<ul>
<li class="level1">Starter file, with a basic map, for you to follow along: <a href="http://mikejcorey.com/nicar2010/googlemapstartfile2.html" target="_new">googlemapstartfile2.html</a></li>
<li class="level1">XML file, which you will want to have locally so you can modify it: <a href="http://mikejcorey.com/nicar2010/basicmapxml.xml" target="_new">basicmapxml.xml</a></li>
<li class="level1">Completed file, if you&#8217;re stuck or just want to skip ahead: <a href="http://mikejcorey.com/nicar2010/googlemapspart2-complete.html" target="_new">googlemapspart2-complete.html</a></li>
</ul>
<p>		</p>
<ol>
<li class="level1"><B>Dynamic geocoding</b><br/><br />
Users often will want to figure out how your data relates to their own geographic location. They want to search against an address or by clicking on a point on the map. To do this kind of functionality you&#8217;ll need to use Google&#8217;s gecoder function.</p>
<ol>
<li class="level2">Create an instance of the geocoder to use for your searches. This should be placed in the code outside of the function that you use to create your map so you can use it anywhere on the page.<br/>
<pre class="brush: jscript; light: true;">var objGeocoder = new GClientGeocoder();</pre>
</li>
<p><br/></p>
<li class="level2">Now let&#8217;s put the geocoder to use. Whereas most of our actions are called against the map instance (objMap), in this case we use the geocoder. Lets do a really basic manual address query that in any real situation you&#8217;d probably collect from an HTML form. You&#8217;ll see that Google takes the address and returns a point &#8212; formatted as a lat,long pair &#8212; if it finds something, and returns as undefined if it can&#8217;t geocode the address. In this case, if it does find an address, we&#8217;ll center the map on that point at zoom level 10. This code goes INSIDE the loadMap function, after the map has been instantiated.<br/>
<pre class="brush: jscript; light: true;">var strTestAddress = &quot;Your address here&quot;;
objGeocoder.getLatLng(strTestAddress, function(objPoint) {
	if (!objPoint) {
		alert(strTestAddress + &quot; not found&quot;);
	} else {
		objMap.panTo(objPoint,10);
	}
});
</pre>
</li>
<p><br/></p>
<li class="level2">Another way to react to user activity is to ask Google for a lat-long pair based on a user&#8217;s click. This allows a user who doesn&#8217;t know the address for their desired location to still use a proximity feature. This involves applying an event listener to the entire map. When a user clicks on the map, we first make sure they&#8217;re not clicking on a marker. If they are, we let that marker&#8217;s earlier set click handler do its work and do nothing in our function. If it&#8217;s not a marker, we re-center the map and do whatever else we might want to. Often we&#8217;ll want to pass the geocoded point to another function.<br/>
<pre class="brush: jscript; light: true;">GEvent.addListener(objMap, 'click', function(objMarker,objPoint) {
	if (objMarker) {
	}
	else {
		objMap.panTo(objPoint,10);
		var objNewMarker = new GMarker(objPoint);
		objMap.addOverlay(objNewMarker);
		objNewMarker.openInfoWindowHtml(&quot;Pssst, pass it on: &quot; + objPoint);
	}
});</pre>
</li>
<p><br/>
	</ol>
</li>
<p><br/></p>
<li class="level1"><B>Polylines and polygons</b><br/><br />
Markers are the most commonly used overlays in the Google Maps API, but polylines and polygons are next. Polylines are familar to most Google Maps users from the driving directions feature, but you can use them for other applications. Polygons are useful for showing regions and other non-point data.<br/><br />
I know what you&#8217;re thinking: STOP! Please don&#8217;t think you can throw up a Google map showing all the counties in your state. It will be slow, slow slow &#8212; this is a major failing of the Javascript API to me, and is one of the main reasons we use Google Maps for Flash for complex polygon data.<br/><br />
That said, polygons used one at a time or a few at a time work well. Let&#8217;s start by drawing a basic line:<br/></p>
<ol>
<li class="level2">We&#8217;ll start by putting some points into an array:<br/>
<pre class="brush: jscript; light: true;">var arrLinePoints = new Array();
arrLinePoints.push(new GLatLng(33.5081, -112.2047));
arrLinePoints.push(new GLatLng(33.5642, -112.1154));
arrLinePoints.push(new GLatLng(33.5608, -112.0042));
arrLinePoints.push(new GLatLng(33.5116, -111.9211));</pre>
</li>
<p><br/></p>
<li class="level2">Then we&#8217;ll spit those points back out as a line. We specify an array that&#8217;s the source of the points, the color of the line, the line width, and the opacity of the line (0.1 to 1):<br/>
<pre class="brush: jscript; light: true;">var objMyLine = new GPolyline(arrLinePoints, &quot;#446891&quot;, 3, 1);
objMap.addOverlay(objMyLine);</pre>
</li>
<p><br/></p>
<li class="level2">Polygons work much the same, except that the last point in the array should be the same as the first one to close the polygon, and you specify a color and opacity for the fill color in addition to the stroke color and opacity:<br/>
<pre class="brush: jscript; light: true;">var arrShapePoints = new Array();
arrShapePoints.push(new GLatLng(33.4623, -112.1086));
arrShapePoints.push(new GLatLng(33.4632, -112.0382));
arrShapePoints.push(new GLatLng(33.4280, -112.0375));
arrShapePoints.push(new GLatLng(33.4285, -112.1075));
arrShapePoints.push(new GLatLng(33.4623, -112.1086));
var objMyPolygon = new GPolygon(arrShapePoints, &quot;#446891&quot;, 3, 1, &quot;#99C1D8&quot;, 0.2);
objMap.addOverlay(objMyPolygon);</pre>
</li>
<p>
	</ol>
</li>
<li class="level1"><B>Clustering markers</b><br/><br />
Many times you&#8217;ll have a lot of points that at wide zoom levels are too close together to distinguish. Using marker clustering is generally the best way to get around this. Google has built-in clustering functions, but we like one called ClusterMarker better because it has more flexibility. The approach works so well that we use ClusterMarker even when we&#8217;re not clustering icons because it makes it easy to trigger clicks to a particular point.<br/><br />
You can download the plugin here:<br/><br />
<a href="http://googlemapsapi.martinpearman.co.uk/downloads.php?cat_id=1" target="_new">http://googlemapsapi.martinpearman.co.uk/downloads.php?cat_id=1</a><br/><br />
And read more about using it here:<br/><br/></p>
<p>	<a href="http://googlemapsapi.martinpearman.co.uk/articles.php?cat_id=1" target="_new">http://googlemapsapi.martinpearman.co.uk/articles.php?cat_id=1</a><br/><br/></p>
<ol>
<li class="level2">For today&#8217;s example, in your HTML document&#8217;s &lt;HEAD&gt;, import the Javascript file that contains the clustering functions.<br/>
<pre class="brush: jscript; html-script: true; light: true;">&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.mikejcorey.com/nicar2010/ClusterMarker.js&quot;&gt;&lt;/script&gt;
</pre>
</li>
<li class="level2">Create a custom icon to be used as your clustering icon. Since this icon has a different size and shape from the other icons from part one, we won&#8217;t base this on the baseIcon we created earlier. This should be defined with your other markers, outside the loadMap function<br/>
<pre class="brush: jscript; light: true;">var objGroupIcon = new GIcon();
objGroupIcon.image = &quot;http://www.mikejcorey.com/nicar2010/images/severalicons-brown.png&quot;;
objGroupIcon.shadow = &quot;http://www.mikejcorey.com/nicar2010/images/severalicons-brown-shadow.png&quot;;
objGroupIcon.iconSize = new GSize(41.0, 36.0);
objGroupIcon.shadowSize = new GSize(57.0, 34.0);
objGroupIcon.iconAnchor = new GPoint(20.5, 18.0);
objGroupIcon.infoWindowAnchor = new GPoint(20.5, 18.0);
</pre>
</li>
<p><br/></p>
<li class="level2">Create a new ClusterMarker instance for your map. We&#8217;ll also tell ClusterMarker what icon to use to mark a cluster. We can also easily turn the clustering on and off by setting the second line to true or false. <b>Note: For some reason my code display tags are freaking out after this point, so delete any backslashes in the code</b><br/>
<pre class="brush: jscript; light: true;">var objMyCluster;
var arrMarkerStorage = new Array();

objMyCluster = new ClusterMarker(objMap, { clusterMarkerIcon: objGroupIcon });
objMyCluster.clusteringEnabled = true;</pre>
</li>
<p><br/></p>
<li class="level2">Instead of manually adding a marker using map.addOverlay, when our marker function runs each time we&#8217;ll push each marker into the array we just created.<br/>
<pre class="brush: jscript; light: true;">function createMarker(objPoint,strHTML,strIconName) {
	var objMarker = new GMarker(objPoint,{ icon:strIconName });
	GEvent.addListener(objMarker, 'click', function() {
		objMarker.openInfoWindowHtml(strHTML);
	});
	arrMarkerStorage.push(objMarker);
	return objMarker;
</pre>
</li>
<p></p>
<li class="level2">Since the ClusterMarker is now going to handle the placement of markers, we can delete or comment out the line inside loadMyLocations that actually places the marker.<br/>
<pre class="brush: jscript; light: true;">
//objMap.addOverlay(objMarker);
</pre>
</li>
<p><br/></p>
<li class="level2">Once our XML loop has finished running, we&#8217;ll tell cluster marker to go to work on the array of points we&#8217;ve stored up. Make sure this is outside and after your loop but still inside the loadLocations function.<br/>
<pre class="brush: jscript; light: true;">
objMyCluster.addMarkers(arrMarkerStorage);
objMyCluster.refresh();
</pre>
</li>
</ol>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2010/03/09/google-maps-api-hands-on-training-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Location-aware potholes map lives!</title>
		<link>http://www.mikejcorey.com/wordpress/2010/03/09/location-aware-potholes-map-lives/</link>
		<comments>http://www.mikejcorey.com/wordpress/2010/03/09/location-aware-potholes-map-lives/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 02:07:51 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[News and posts]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[des moines]]></category>
		<category><![CDATA[Droid]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[Google Maps Static API]]></category>
		<category><![CDATA[government]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[iowa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[journalism]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[potholes]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=225</guid>
		<description><![CDATA[We launched a beta today of our mobile potholes map, which features extensive use of geolocation using the user&#8217;s Web browser. This has been on my and James Wilkerson&#8217;s plate for a long time, and it feels really good to...]]></description>
			<content:encoded><![CDATA[<p>We launched a beta today of our mobile potholes map, which features extensive use of geolocation using the user&#8217;s Web browser. This has been on my and James Wilkerson&#8217;s plate for a long time, and it feels really good to get at least this version out in the public.</p>
<p>The mobile site is at <a href="http://dmreg.com/potholes" target="_blank">http://dmreg.com/potholes</a>.</p>
<p>You can see the desktop browser version at <a href="http://DesMoinesRegister.com/potholes" target="_blank">DesMoinesRegister.com/potholes</a>, and <a href="http://www.mikejcorey.com/wordpress/2010/02/26/new-project-killing-potholes-with-user-input-local-government-support/">there&#8217;s more info on that project in a previous post</a>.</p>
<p>This is our first extensively location-aware site, and it&#8217;s our first really extensive specialty mobile site, so there&#8217;s a lot of figuring out still left on this one. But we&#8217;re pretty happy with the result.</p>
<p>We used quite a few methods that were different or modified from our other mapping projects.</p>
<p>1. For geolocation, we&#8217;re using the <a href="http://dev.w3.org/geo/api/spec-source.html" target="_blank">W3C geolocation API</a> built in to many phones&#8217; browsers. Safari for iPhone and most Google phones have it, but BlackBerries don&#8217;t. Theoretically we&#8217;re also supporting <a href="http://code.google.com/apis/gears/api_geolocation.html" target="_blank">Google Gears geolocation</a>, but we haven&#8217;t really tested it on mobile devices.</p>
<p>2. We used the <a href="http://code.google.com/apis/maps/documentation/staticmaps/" target="_blank">Google Static Maps API</a> instead of the more-familiar <a href="http://code.google.com/apis/maps/" target="_blank">Javascript API</a>. The Javascript API actually works fairly well, technically speaking, on iPhones and Google phones, but the user experience can quickly become confusing. Dragging things on the map is hard on a mobile device, and zooming in and out on the map often messes with the browser zoom. The static maps API is a lot lighter load for a mobile connection to bear. Almost as a bonus, <a href="http://www.mikejcorey.com/wordpress/2010/03/02/frustrated-with-all-things-blackberry/">because I was about ready to write off the BlackBerry browser</a>, using the static API also enables BlackBerry users to use the site (the lack of browser GPS still limits BlackBerry users, but they can at least submit a pothole using an address).</p>
<p>3. We&#8217;re using Prototype&#8217;s Ajax and JSON to load points and send new pothole data. We&#8217;ve done this a few times now, and it&#8217;s becoming our standard. JSON is lighter than XML on the server, and you can send data back and forth as Javascript objects, which makes sending complex data much easier (and much easier to modify later).</p>
<p>4. We did this as a website instead of an app in order to work with more platforms at once, and because we&#8217;re much better at Web design than objective C (which is to say I know not a bit, and learning will take a while). I&#8217;m curious to hear others&#8217; thoughts on this, because I think most journalism shops are going to have a hard time making the economics of iPhone, BlackBerry and Google apps a pretty tough thing to make work. As long as mobile browsers keep developing quickly, I think this is probably the way to go for now, unless you can afford to build your own apps, have a lot more time to devote to one project than we do, or can afford to pay someone else to build them for you.</p>
<p>Check it out, let me know what works and what doesn&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2010/03/09/location-aware-potholes-map-lives/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Maps API hands-on training, part 1</title>
		<link>http://www.mikejcorey.com/wordpress/2010/03/07/google-maps-api-hands-on-training-part-1/</link>
		<comments>http://www.mikejcorey.com/wordpress/2010/03/07/google-maps-api-hands-on-training-part-1/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 03:01:23 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=197</guid>
		<description><![CDATA[The notes from a hands-on class I'm helping teach at NICAR 2010 in Phoenix this week.]]></description>
			<content:encoded><![CDATA[<style type="text/css">.level1 {
	list-style-type : decimal ;
	margin-left : 10px ;
}
.level2 {
	list-style-type : upper-alpha ;
	margin-left : 10px ;
}</style>
<p><a href="http://www.mikejcorey.com/wordpress/2010/03/09/google-maps-api-hands-on-training-part-2/">Go to part two of the training</a><br />
<b>Presumed knowledge:</b><br />
	HTML<br />
	Moderate Javascript understanding<br />
	CSS<br />
	Basic XML<br />
<b>What you&#8217;ll need:</b></p>
<ul>
<li class="level1">A Google Maps API key (one per server, make an include)</li>
<li class="level1">A text editor</li>
<li class="level1">Some addresses or Lat-Long coordinates<br />
		<b>Where to geocode points:</b></p>
<ul>
<li class="level2">geocoder.us</li>
<li class="level2">batchgeocode.com (feed it a tab-delimited file of addresses, get one back)</li>
</ul>
</li>
<li class="level1">A browser</li>
<li class="level1">Firebug is very helpful</li>
</ul>
<p>
<b>Supporting files:</b></p>
<ul>
<li class="level1">Starter file, with a basic map, for you to follow along: <a href="http://mikejcorey.com/nicar2010/googlemapstartfile.html" target="_new">googlemapstartfile.html</a></li>
<li class="level1">Completed file, if you&#8217;re stuck or just want to skip ahead: <a href="http://mikejcorey.com/nicar2010/googlemapspart1-complete.html" target="_new">googlemapspart1-complete.html</a></li>
</ul>
<p>
<b>Getting started:</b></p>
<ol>
<li class="level1">Make sure you&#8217;re using the API appropriately. The good news is that Google has very open terms, but be sure you understand the advertising caveat</li>
<p></p>
<li class="level1">Create a basic HTML page</li>
<p></p>
<li class="level1">Sign up for an API key at <a href="http://code.google.com/apis/maps/signup.html" target="_new">http://code.google.com/apis/maps/signup.html</a></li>
<p></p>
<li class="level1">Keep a tab open for the API reference at <a href="http://code.google.com/apis/maps/documentation/reference.html" target="_new">http://code.google.com/apis/maps/documentation/reference.html</a></li>
<p></p>
<li class="level1">Load your API key inside the &lt;HEAD&gt; of the HTML document
<pre class="brush: jscript; light: true;">&lt;!--mikejcorey.com key (will work offline, but not if you upload it to another site)--&gt;
&lt;script src=&quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAnXJbcYra5cIfy6uPpLTD6hQ5QqU9rgaQFdjDVk398i-rXfaBgBTE1-zdxRWaL7MjmfClkvNiI-i4KA&amp;sensor=false&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</pre>
</li>
<p></p>
<li class="level1">Inside your HTML body, create a target &lt;DIV&gt; for your map
<pre class="brush: jscript; light: true;">&lt;div id=&quot;map&quot; style=&quot;width:500px;height:400px;border:1px solid #000;&quot;&gt;&lt;/div&gt;</pre>
</li>
<p></p>
<li class="level1">Inside your document&#8217;s &lt;/HEAD&gt; tag, write Javascript to initialize your map after the entire body of the document has loaded
<pre class="brush: jscript; light: true;">var objMap; //A variable we declare early so our map is accessible outside the function that creates it.
//A function that loads when the HTML page is finished loading, which creates the map
function loadMap() {
	if (GBrowserIsCompatible()) {
		objMap = new GMap2(document.getElementById(&quot;map&quot;));
	} else {
		document.getElementById(&quot;map&quot;).innerHTML = &quot;There's supposed to be a Google Map here, but your browser isn't capable of showing it.&quot;;
	}
}</pre>
</li>
<p></p>
<li class="level1">Set a center point (lat-long pair) and zoom level for the map
<pre class="brush: jscript; light: true;">objMap.setCenter(new GLatLng(33.453814, -112.073239), 12);</pre>
</li>
<p></p>
<li class="level1">Add this code to the &lt;BODY&gt; tag of your HTML document to initialize the map once the body has finished loading, and to prevent memory leaks
<pre class="brush: jscript; light: true;">&lt;body onload=&quot;loadMap()&quot; onunload=&quot;GUnload()&quot;&gt;</pre>
</li>
<p></p>
<li class="level1">Add a different map type, set the map to use that type
<pre class="brush: jscript; light: true;">objMap.addMapType(G_PHYSICAL_MAP);
objMap.setMapType(G_PHYSICAL_MAP);</pre>
</li>
<p></p>
<li class="level1">Add some controls to the map for zooming and changing the map type
<pre class="brush: jscript; light: true;">objMap.addControl(new GLargeMapControl());
objMap.addControl(new GMapTypeControl());</pre>
</li>
<p></p>
<li class="level1">A marker is one type of overlay. Other overlays include lines, polygons, and ground overlays. There&#8217;s several ways to add markers to the map. Let&#8217;s start with the simplest method, and add a marker to the map using the default icon.
<pre class="brush: jscript; light: true;">//The simplest way to add a marker
var objBasicPoint = new GLatLng(33.453814, -112.073239);
var objBasicMarker = new GMarker(objBasicPoint);
objMap.addOverlay(objBasicMarker);</pre>
</li>
<p></p>
<li class="level1">That&#8217;s fine if we don&#8217;t want too many markers and we don&#8217;t want them to do much, but as soon as you get over about 5 markers, this approach becomes impractical. <b>Writing a function</b> that can be called over and over is a good way to handle multiple markers. Inside the function we&#8217;ll also add an <b>event listener</b> to pop up a label (called an InfoWindow) when the user clicks on the icon.
<pre class="brush: jscript; light: true;">//Our function for creating markers with event listeners
function createMarker(objPoint,strHTML,strIconName) {
	var objMarker = new GMarker(objPoint,{ icon:strIconName });
	GEvent.addListener(objMarker, 'click', function() {
		objMarker.openInfoWindowHtml(strHTML);
	});
	return objMarker;
}

//Adding a marker the more useful way, using a function
var objPoint = new GLatLng(33.479035, -112.047882);
var strWindowContent = &quot;&lt;div style='color:#CC0000;width:200px;'&gt;&lt;b&gt;Barrio Cafe\&lt;/b&gt;&lt;br/&gt;Azcentral.com raves: Superb Mexican food in a funky setting.\&lt;/div&gt;&quot;;
var objTestMarker = createMarker(objPoint,strWindowContent);
objMap.addOverlay(objTestMarker);</pre>
</li>
<p></p>
<li class="level1">If you have more than one type of data you want to show on the map, you&#8217;ll want to use a different color or shape of icon. You can make custom markers with any .PNG image file with a transparent background. Photoshop will work fine, but Adobe Fireworks is even better for this. We won&#8217;t cover creating the icon image here, so we&#8217;re starting with an image that we know the pixel dimensions of. For this map we&#8217;re going to use two icons that are the same shape, but are different sizes. First we&#8217;ll tell Google some key information about both icons. We&#8217;ll declare these variables before our other functions and outside of those functions, so we can access the markers from anywhere in the script.
<pre class="brush: jscript; light: true;">//marker definitions
var objBaseIcon = new GIcon();
objBaseIcon.shadow = &quot;http://www.mikejcorey.com/nicar2010/images/shadow-stop.png&quot;;
objBaseIcon.iconSize = new GSize(19, 25);
objBaseIcon.shadowSize = new GSize(32, 25);
objBaseIcon.iconAnchor = new GPoint(9, 25);
objBaseIcon.infoWindowAnchor = new GPoint(9, 1);</pre>
</li>
<p></p>
<li class="level1">Now we&#8217;ll define the different icons, which will be based on our baseicon, and put the icons into an array for easy reference later.
<pre class="brush: jscript; light: true;">var objRedIcon = new GIcon(objBaseIcon);
objRedIcon.image = &quot;http://www.mikejcorey.com/nicar2010/images/stop.png&quot;;

var objGreenIcon = new GIcon(objBaseIcon);
objGreenIcon.image = &quot;http://www.mikejcorey.com/nicar2010/images/start.png&quot;;

var arrMapIcons = [objRedIcon,objGreenIcon];</pre>
</li>
<p></p>
<li class="level1">If you want to load marker data from a database, or if you&#8217;d like to be able to easily change the markers, you&#8217;ll want to load markers dynamically from XML or JSON. In this example we&#8217;ll load multiple points from a flat XML file. This process uses a custom <b>asynchronous request</b> from Google called <b>GDownloadUrl</b>.
<pre class="brush: jscript; light: true;">//function for retrieving list of points from XML
function loadMyLocations(strWhichXML) {
	GDownloadUrl(strWhichXML, function(data) {
		var objXML = GXml.parse(data);
		var objLocations = objXML.documentElement.getElementsByTagName(&quot;location&quot;);

	});
}</pre>
</li>
<p></p>
<li class="level1">Set up a basic Javascript loop to get each XML row
<pre class="brush: jscript; light: true;">for (var numI = 0; numI &lt; objLocations.length; numI++) {
}</pre>
</li>
<p></p>
<li class="level1">For each row, get the attributes you need and run our marker function as before
<pre class="brush: jscript; light: true;">var objLocationItem = objLocations[numI];
var numMarkerLabel = objLocationItem.getAttribute(&quot;label&quot;);
var numMarkerIcon = objLocationItem.getAttribute(&quot;markertype&quot;);
var numMarkerLat = parseFloat(objLocationItem.getAttribute(&quot;lat&quot;));
var numMarkerLng = parseFloat(objLocationItem.getAttribute(&quot;lng&quot;));
var objPoint = new GLatLng(numMarkerLat, numMarkerLng);
var strWindowContent = &quot;&lt;div style='color:#CC0000;'&gt;&quot; + numMarkerLabel + &quot;\&lt;/div&gt;&quot;;
var objMarker = createMarker(objPoint,strWindowContent,arrMapIcons[numMarkerIcon]);
objMap.addOverlay(objMarker);</pre>
</li>
<p></p>
<li class="level1">That&#8217;s all for part one. Here&#8217;s the code for the entire page:</li>
<pre class="brush: jscript; light: true;">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
	&lt;title&gt;My awesome first Google map&lt;/title&gt;
	&lt;!--mikejcorey.com key (will work offline, but not if you upload it to another site)--&gt;
	&lt;script src=&quot;http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAnXJbcYra5cIfy6uPpLTD6hQ5QqU9rgaQFdjDVk398i-rXfaBgBTE1-zdxRWaL7MjmfClkvNiI-i4KA&amp;sensor=false&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
	&lt;script language=&quot;Javascript&quot;&gt;
	//&lt;![CDATA[
		var objMap; //A variable we declare early so our map is accessible outside the function that creates it.

		//marker definitions
		var objBaseIcon = new GIcon();
		objBaseIcon.shadow = &quot;http://www.mikejcorey.com/nicar2010/images/shadow-stop.png&quot;;
		objBaseIcon.iconSize = new GSize(19, 25);
		objBaseIcon.shadowSize = new GSize(32, 25);
		objBaseIcon.iconAnchor = new GPoint(9, 25);
		objBaseIcon.infoWindowAnchor = new GPoint(9, 1);
		var objRedIcon = new GIcon(objBaseIcon);
		objRedIcon.image = &quot;http://www.mikejcorey.com/nicar2010/images/stop.png&quot;;

		var objGreenIcon = new GIcon(objBaseIcon);
		objGreenIcon.image = &quot;http://www.mikejcorey.com/nicar2010/images/start.png&quot;;

		var arrMapIcons = [objRedIcon,objGreenIcon];
		//A function that loads when the HTML page is finished loading, which creates the map
		function loadMap() {
			if (GBrowserIsCompatible()) {

				objMap = new GMap2(document.getElementById(&quot;map&quot;));
				objMap.setCenter(new GLatLng(33.453814, -112.073239), 12);

				objMap.addMapType(G_PHYSICAL_MAP);
				objMap.setMapType(G_PHYSICAL_MAP);

				objMap.addControl(new GLargeMapControl());
				objMap.addControl(new GMapTypeControl());

				//The simplest way to add a marker
				var objBasicPoint = new GLatLng(33.453814, -112.073239);
				var objBasicMarker = new GMarker(objBasicPoint);
				objMap.addOverlay(objBasicMarker);

				//Adding a marker the more useful way, using a function
    			var objPoint = new GLatLng(33.479035, -112.047882);
    			var strWindowContent = &quot;&lt;div style='color:#CC0000;width:200px;'&gt;&lt;b&gt;Barrio Cafe\&lt;/b&gt;&lt;br/&gt;Azcentral.com raves: Superb Mexican food in a funky setting.\&lt;/div&gt;&quot;;
				var objTestMarker = createMarker(objPoint,strWindowContent);
				objMap.addOverlay(objTestMarker);

				//Or we can just load a bunch of points from an XML file
				loadMyLocations(&quot;basicmapxml.xml&quot;);
			} else {
				document.getElementById(&quot;map&quot;).innerHTML = &quot;There's supposed to be a Google Map here, but your browser isn't capable of showing it.&quot;;
			}
		}

		//Our function for creating markers with event listeners
		function createMarker(objPoint,strHTML,strIconName) {
			var objMarker = new GMarker(objPoint,{ icon:strIconName });
			GEvent.addListener(objMarker, 'click', function() {
				objMarker.openInfoWindowHtml(strHTML);
			});
			return objMarker;
		}

		//function for retrieving list of points from XML
		function loadMyLocations(strWhichXML) {
			GDownloadUrl(strWhichXML, function(data) {

				var objXML = GXml.parse(data);
				var objLocations = objXML.documentElement.getElementsByTagName(&quot;location&quot;);

				for (var numI = 0; numI &lt; objLocations.length; numI++) {
					var objLocationItem = objLocations[numI];

					var numMarkerLabel = objLocationItem.getAttribute(&quot;label&quot;);
					var numMarkerIcon = objLocationItem.getAttribute(&quot;markertype&quot;);
					var numMarkerLat = parseFloat(objLocationItem.getAttribute(&quot;lat&quot;));
					var numMarkerLng = parseFloat(objLocationItem.getAttribute(&quot;lng&quot;));

					var objPoint = new GLatLng(numMarkerLat, numMarkerLng);
					var strWindowContent = &quot;&lt;div style='color:#CC0000;'&gt;&quot; + numMarkerLabel + &quot;\&lt;/div&gt;&quot;;
					var objMarker = createMarker(objPoint,strWindowContent,arrMapIcons[numMarkerIcon]);
					objMap.addOverlay(objMarker);
				}
			});
		}
	//]]&gt;
	&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=&quot;loadMap()&quot; onunload=&quot;GUnload()&quot;&gt;
	&lt;div id=&quot;map&quot; style=&quot;width:500px;height:400px;border:1px solid #000;&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</li>
</ol>
<p><a href="http://www.mikejcorey.com/wordpress/2010/03/09/google-maps-api-hands-on-training-part-2/">Go to part two of the training</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2010/03/07/google-maps-api-hands-on-training-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Frustrated with all things BlackBerry</title>
		<link>http://www.mikejcorey.com/wordpress/2010/03/02/frustrated-with-all-things-blackberry/</link>
		<comments>http://www.mikejcorey.com/wordpress/2010/03/02/frustrated-with-all-things-blackberry/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 04:01:46 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[News and posts]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[Google Maps Static API]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[potholes]]></category>
		<category><![CDATA[smartphone]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=192</guid>
		<description><![CDATA[This week I&#8217;m getting to sink my teeth into one of my big priorities for the year: building mobile websites. Yes, websites and not apps. I&#8217;d love to be building phone apps as well, but for now in the interest...]]></description>
			<content:encoded><![CDATA[<p>This week I&#8217;m getting to sink my teeth into one of my big priorities for the year: building mobile websites.</p>
<p>Yes, websites and not apps. I&#8217;d love to be building phone apps as well, but for now in the interest of speed we&#8217;re going with Web pages before apps. (Not that we&#8217;re not working on apps either, that&#8217;s just a separate topic.)</p>
<p>The good news for most Web designers is that building basic mobile websites is easy: Just write really simple HTML. You can use all the PHP you want since it&#8217;s server-side (insert also ASP, Django, your server-side secret weapon of choice). Ems are your friend in mobile Web design: Yes, you finally have to actually use them.</p>
<p>So far this year we&#8217;ve knocked out really simple mobile pages for <a href="http://data.desmoinesregister.com/dmr/iowa-high-school-wrestling-results/mobile-results.php" target="_blank">state high school wrestling tournament results</a> and for <a href="http://data.desmoinesregister.com/dmr/iowa-high-school-girls-basketball-results/index.php" target="_blank">state high school basketball tournament scores</a>.</p>
<p><a href="http://www.mikejcorey.com/wordpress/wp-content/uploads/2010/03/wrestlingandbballmobile.jpg"><img class="alignnone size-full wp-image-193" title="wrestlingandbballmobile" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2010/03/wrestlingandbballmobile.jpg" alt="wrestlingandbballmobile" width="630" height="395" /></a></p>
<p>As you can see, nothing fancy, but they look pretty, and they work on pretty much every mobile browser we tried them on, smartphone or no.</p>
<p>These were also a bit of R and D for the one I really want to build, which is in progress now: a mobile, location-aware version of our <a href="http://www.mikejcorey.com/wordpress/2010/02/26/new-project-killing-potholes-with-user-input-local-government-support/">potholes map</a>.</p>
<p>This one is a lot more technically complex, as you might imagine. And as soon as I started researching and testing, I hit a big snag: BlackBerries.</p>
<p>We want to use basic Google Maps API features, so we have to use Javascript and Ajax. Right there is a big problem: Even the newest BlackBerry browsers don&#8217;t work with the Google Maps Javascript API.</p>
<p>We also want to include Facebook Connect integration, but the Javascript method won&#8217;t work for that on BlackBerries either (to be fair, it&#8217;s pretty buggy on iPhones and Android as well, but the FBML all renders, and you can log in with Javascript).</p>
<p>Location awareness in the browser? No problem on iPhones and Android, as long as the phone has GPS. Not so on most BlackBerries.</p>
<p>So that makes three dead-ends today. I figured I could at least <a href="http://na.blackberry.com/eng/developers/" target="_blank">download the BlackBerry simulator</a> and figure out what type of site I COULD make work on a BlackBerry with the <a href="http://code.google.com/apis/maps/documentation/staticmaps/" target="_blank">Google Static Maps API</a>. (This would certainly work, but no moving the point once it&#8217;s geocoded, which would be an issue for our purposes)</p>
<p>Oops, the simulator is for Windows only. Does RIM really think there&#8217;s only a few Web developers using Macs? Is it even a majority using Windows?</p>
<p>So I&#8217;ll just download the simulator on my Virtual Box and run it from there, right? Only if I want to spend 5 minutes waiting for the simulator to actually run, only to give me a connection error and not show any sites when I DO get the browser running.</p>
<p>I. Give. Up.</p>
<p>So can Web developers afford to ignore BlackBerry? Well, not probably not completely, but luckily <a href="http://arstechnica.com/gadgets/news/2010/02/google-makes-biggest-gain-in-smartphone-market-share.ars" target="_blank">the number of BlackBerry browser users is heading the in the right direction</a>.</p>
<p>Comscore reported in December that from September 2009 to Dec. 2009 RIM browser market share fell by one percentage point, while mobile Safari was up 1.2 percentage points. Google mobile browser share was up 2.7 percentage points. Yes, RIM still had 41.6% of the smartphone marketshare, but that&#8217;s not so much more than iPhones and Google phones combined: 30.5% in December, and certainly still going up.</p>
<p>And my (admittedly unscientific) research with BlackBerry users in our newsroom seemed to indicate that people with BlackBerries aren&#8217;t as interested in Web usage as their Google- and iPhone-toting colleagues. They don&#8217;t seem to expect the same degree of neato interface/experience.</p>
<p>In any case, our options for mobile potholes:</p>
<p>1) Build two mobile sites, one for iPhones and Google, and another for BlackBerries. Do you want to build 2 sites for everything? Me neither.</p>
<p>2) Build for the browsers that work (OK, not fair, but it&#8217;s not like the Google Maps Javascrip API is new), on the theory that you&#8217;re offering the people who DO care the best experience you can, and that the number of people with access to the best features is rising all the time. And maybe BlackBerry will get its act together.</p>
<p>Neither are great, but for now I think I have to opt for 2. Sorry, BlackBerry friends! But I&#8217;d love to hear your thoughts. Am I way off base on the &#8220;BlackBerry users aren&#8217;t after great Web experiences&#8221; theory?</p>
<p>Am I missing the magical secret to BlackBerry Javascript development?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2010/03/02/frustrated-with-all-things-blackberry/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New project: Killing potholes with user input, local government support</title>
		<link>http://www.mikejcorey.com/wordpress/2010/02/26/new-project-killing-potholes-with-user-input-local-government-support/</link>
		<comments>http://www.mikejcorey.com/wordpress/2010/02/26/new-project-killing-potholes-with-user-input-local-government-support/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 04:22:18 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Featured projects]]></category>
		<category><![CDATA[News and posts]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[des moines]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Facebook Connect]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[government partnership]]></category>
		<category><![CDATA[iowa]]></category>
		<category><![CDATA[MySQL->PHP->JSON->Ajax]]></category>
		<category><![CDATA[potholes]]></category>
		<category><![CDATA[user-generated]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=176</guid>
		<description><![CDATA[Location awareness, Facebook Connect and the first time we've ever sent data TO a local government.]]></description>
			<content:encoded><![CDATA[<p><strong>Project link:</strong> <a href="http://data.desmoinesregister.com/dmr/des-moines-potholes-map/" target="_blank">DesMoinesRegister.com/potholes</a></p>
<p><strong>HTML/Javascript/Facebook Connect Development:</strong> Michael Corey<br />
<strong>Database backend/Local government admin:</strong> James E. Wilkerson</p>
<p><a href="http://www.mikejcorey.com/wordpress/2010/03/09/location-aware-potholes-map-lives/"><strong>UPDATE:</strong> Mobile, location-aware potholes beta map now launched!</a></p>
<p>In case you haven&#8217;t noticed, potholes are everywhere. We hate &#8216;em, and we&#8217;re out to kill them.</p>
<p>We did a similar map two years ago, but there&#8217;s a few big twists that make us pretty proud of this one.</p>
<p><strong>Working with local governments:</strong> We consulted extensively with Des Moines Public Works to see how we could build a system for reporting potholes that worked for our users AND for the city. We sent them data last time as well, but it didn&#8217;t work well for them. We didn&#8217;t have reverse-geocoding figured out two years ago, and someone had to re-enter our data into the city&#8217;s system to make anything happen.</p>
<p>Neither side wanted a repeat of that, but we really wanted to build a system Des Moines would actually use. The result: We send them daily e-mails with Excel attachments showing new potholes with exact locations. They&#8217;ve told use they&#8217;re going to hand those spreadsheets directly to their road crews and use that as a manifest for the day alongside their existing system. We&#8217;ve gotten word from several suburbs that they&#8217;ll participate as well.</p>
<p>As far as I know this is the first time we&#8217;ve ever pushed data TO a government agency. Usually we&#8217;re trying our best to pry it loose from them. And we think this is a pretty big win-win. We have a larger megaphone than the city Web site, and they have the power to make the evil potholes go away.</p>
<p><strong>Facebook Connect support:</strong> This is our first Facebook Connect app. We&#8217;re giving users the option of logging in with their Facebook ID or their DesMoinesRegister.com account. We wanted to add registration of some kind this time around to cut down on spam and to see how willing people will be to use their real ID on our site.</p>
<p>We&#8217;re only scratching the surface of what we can do with Facebook Connect, but hey, we launched this thing today. Give us a bit. Lots more to come.</p>
<p><strong>Geo-awareness:</strong> We&#8217;ve enabled browser-geolocation if the user chooses, so she can mark a pothole near her current location. This isn&#8217;t incredibly useful for desktop users, but we&#8217;re adding a mobile version soon, and we all know that&#8217;s where the real geolocation action is.</p>
<p>The early buzz on Twitter in response to the launch has really been good. And this is the first time I&#8217;ve been happy about the worst winter in my recent memory: there won&#8217;t be a shortage of potholes to fill this spring.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2010/02/26/new-project-killing-potholes-with-user-input-local-government-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Denmark photos!</title>
		<link>http://www.mikejcorey.com/wordpress/2009/11/27/denmark-photos/</link>
		<comments>http://www.mikejcorey.com/wordpress/2009/11/27/denmark-photos/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 02:55:25 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[News and posts]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=169</guid>
		<description><![CDATA[Lots of photos from my trip to Denmark are now posted! Highlights include Koldinghus: Tivoli at Jul, with København city hall in the background: Smørrebrød in Amagerbro:]]></description>
			<content:encoded><![CDATA[<p><a href="http://picasaweb.google.com/mikejcorey/BestOfDenmark2009?authkey=Gv1sRgCM7ztaGzm8bqew&amp;feat=directlink">Lots of photos from my trip to Denmark are now posted!</a></p>
<p>Highlights include Koldinghus:</p>
<p><a href="http://picasaweb.google.com/mikejcorey/BestOfDenmark2009?authkey=Gv1sRgCM7ztaGzm8bqew&amp;feat=directlink"><img class="alignnone size-full wp-image-170" title="Koldinghus620" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2009/11/Koldinghus620.jpg" alt="Koldinghus620" width="620" height="465" /></a></p>
<p>Tivoli at Jul, with København city hall in the background:</p>
<p><a href="http://picasaweb.google.com/mikejcorey/BestOfDenmark2009?authkey=Gv1sRgCM7ztaGzm8bqew&amp;feat=directlink"><img class="alignnone size-full wp-image-171" title="TivoliTower500" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2009/11/TivoliTower500.jpg" alt="TivoliTower500" width="500" height="609" /></a></p>
<p>Smørrebrød in Amagerbro:</p>
<p><a href="http://picasaweb.google.com/mikejcorey/BestOfDenmark2009?authkey=Gv1sRgCM7ztaGzm8bqew&amp;feat=directlink"><img class="alignnone size-full wp-image-172" title="Smorrebrod620" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2009/11/Smorrebrod620.jpg" alt="Smorrebrod620" width="620" height="420" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2009/11/27/denmark-photos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Danmark, farvel</title>
		<link>http://www.mikejcorey.com/wordpress/2009/11/25/danmark-farvel/</link>
		<comments>http://www.mikejcorey.com/wordpress/2009/11/25/danmark-farvel/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 08:32:12 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[News and posts]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=164</guid>
		<description><![CDATA[I&#8217;m waiting groggily (not the Tivoli kind of grog) and a bit grumpily for my flight out of København. I&#8217;ve had a great time in Denmark and will have a lot more to say in the next few days, but...]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m waiting groggily (not the Tivoli kind of grog) and a bit grumpily for my flight out of København. I&#8217;ve had a great time in Denmark and will have a lot more to say in the next few days, but for now anything I post is going to be more unintelligible than me trying to say <a href="http://www.youtube.com/watch?v=z8VziyktyS0" target="_blank">&#8220;<span id="result_box"><span style="background-color: #ffffff;" title="red gruel with cream">rød grød med fløde.&#8221;</span></span></a></p>
<p>So an early thank you to everyone who made me feel so welcome here. I miss home, but it&#8217;s very hard to leave. Hopefully we&#8217;ll all meet again soon.</p>
<p><a href="http://www.mikejcorey.com/wordpress/wp-content/uploads/2009/11/TivoliStars.jpg"><img class="size-full wp-image-165 alignnone" title="TivoliStars" src="http://www.mikejcorey.com/wordpress/wp-content/uploads/2009/11/TivoliStars.jpg" alt="Tivoli at night" width="620" height="465" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2009/11/25/danmark-farvel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Danmark, her kommer jeg!</title>
		<link>http://www.mikejcorey.com/wordpress/2009/11/10/danmark-her-kommer-jeg/</link>
		<comments>http://www.mikejcorey.com/wordpress/2009/11/10/danmark-her-kommer-jeg/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 01:56:52 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[News and posts]]></category>
		<category><![CDATA[brondby]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[danmark]]></category>
		<category><![CDATA[Denmark]]></category>
		<category><![CDATA[geoforum]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[kolding]]></category>
		<category><![CDATA[kortdage]]></category>
		<category><![CDATA[mapping]]></category>
		<category><![CDATA[ob]]></category>

		<guid isPermaLink="false">http://www.mikejcorey.com/wordpress/?p=158</guid>
		<description><![CDATA[Hello, Denmark visitors! I can see some traffic coming in from the GeoForum site, and rest assured, I&#8217;m plugging away and putting the finishing touches on my presentation for Kortdage 2009 in Kolding next week. I&#8217;ll be talking about the...]]></description>
			<content:encoded><![CDATA[<p>Hello, Denmark visitors! I can see some traffic coming in from the <a href="http://www.geoforum.dk/" target="_blank">GeoForum site</a>, and rest assured, I&#8217;m plugging away and putting the finishing touches on my presentation for <a href="http://www.geoforum.dk/Velkommen.aspx" target="_blank">Kortdage 2009 in Kolding next week</a>.</p>
<p><a href="http://www.geoforum.dk/Default.aspx?ID=8845" target="_blank">I&#8217;ll be talking about the use of Google Maps in journalism</a>, and it should be a fun talk. In any case it has been fun for me to go back over the last few years of work and see how far we&#8217;ve come.</p>
<p>And of course I&#8217;m extremely excited to be visiting Denmark. Many thanks in advance to GeoForum Danmark and especially to Jesper Ishøj, Hans Ravnkjær Larsen, Lars Brodersen and more for helping to bring me across the Atlantic. I&#8217;m excited to learn more about Danish history and culture, and I&#8217;m especially looking forward to meeting some of the innovators in Danish neocartography and journalism.</p>
<p>Those who know me well also know how excited I am to have the opportunity to see a European football match while I&#8217;m there between <a href="http://www.brondby.com" target="_blank">Bronby</a> and <a href="http://www.ob.dk" target="_blank">OB</a>, two of Denmark&#8217;s top teams. Someone be sure to tell me what colors not to wear before we go!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikejcorey.com/wordpress/2009/11/10/danmark-her-kommer-jeg/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

