<?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>Spatial Horizons &#187; Map Tiles</title>
	<atom:link href="http://spatialhorizons.com/category/map-tiles/feed/" rel="self" type="application/rss+xml" />
	<link>http://spatialhorizons.com</link>
	<description>Exploring Geographic Technologies with GIS, GPS, C#, XNA, and Open Source Tools</description>
	<lastBuildDate>Thu, 18 Sep 2008 19:00:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using MapServer (2) &#8211; Generating Map Tiles</title>
		<link>http://spatialhorizons.com/2007/11/14/using-mapserver-2-generating-map-tiles/</link>
		<comments>http://spatialhorizons.com/2007/11/14/using-mapserver-2-generating-map-tiles/#comments</comments>
		<pubDate>Wed, 14 Nov 2007 23:44:06 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Map Tiles]]></category>
		<category><![CDATA[Mapserver]]></category>

		<guid isPermaLink="false">http://spatialhorizons.com/2007/11/14/using-mapserver-2-generating-map-tiles/</guid>
		<description><![CDATA[This post is the second in a series on using MapServer. First-time visitors are encouraged to read part 1 which details how to download, setup, and create a web mapping site using MapServer. Additionally, the topic of map tiles has already been introduced in a previous series.
Once the MapServer for Windows (MS4W) package with ka-Map [...]]]></description>
			<content:encoded><![CDATA[<p class="moreinfo">This post is the second in a series on using <a href="http://mapserver.gis.umn.edu/">MapServer</a>. First-time visitors are encouraged to read <a href="http://spatialhorizons.com/2007/05/19/mapserver-1-10-minute-tutorial/">part 1</a> which details how to download, setup, and create a web mapping site using MapServer. Additionally, the topic of map tiles has already been introduced in a <a href="http://spatialhorizons.com/category/map-tiles/">previous series</a>.</p>
<p>Once the <a href="http://www.maptools.org/ms4w/">MapServer for Windows (MS4W)</a> package with <a href="http://ka-map.maptools.org/">ka-Map</a> is installed on your local machine, some new mapping functionality becomes available. One area that interests us is the ability to automatically generate a set of map tiles.</p>
<p><strong>ka-Map Configuration</strong></p>
<p>The first step in creating a set of map tiles is to configure ka-Map to point to a valid MapServer mapfile (see <a href="http://spatialhorizons.com/2007/10/06/using-qgis-5-export-to-mapserver/">here</a> for more on a mapfile). Navigate to this directory: <strong>C:\ms4w\apps\ka-map-1.0\include</strong> and open the file named <strong>config.php</strong> in any text editor.</p>
<p>This configuration file contains several parameters which you should be familiar with before creating our map tiles. We won&#8217;t change any of their values yet but it is important to understand what they do. First, on lines 73 and 74, the pixel size of each tile to be generated is defined:</p>
<p>
<pre lang="csharp">$tileWidth = 256;
$tileHeight = 256;</pre>
</p>
<p>Lines 106 through 110 define the most important parameters:</p>
<p>
<pre lang="csharp">$aszGMap = array (
         'title' => 'GMap 75',
         'path' => '../../gmap/htdocs/gmap75.map',
         'scales' => array( 40000000, 25000000, 12000000,
                                 7500000, 3000000, 1000000 ),
         'format' =>'PNG'
 );</pre>
</p>
<p><span id="more-134"></span><br />
By default, ka-Map is setup to use the GMap application that we downloaded and setup in the <a href="http://spatialhorizons.com/2007/05/19/mapserver-1-10-minute-tutorial/">first post</a>. So the values for the title, path, and scales reflect that.</p>
<p>The path variable is relative based on the location of config.php (config.php is in C:\ms4w\apps\ka-map-1.0\include and the gmap75.map file is in C:\ms4w\apps\gmap\htdocs).</p>
<p>The scales array contains all the map scales at which the tiles will be generated. Determining which scales and how many scale levels is completely configurable based on the user&#8217;s preference. For now we will leave them as-is.</p>
<p>Lastly, the output image format is defined as PNG.</p>
<p><strong>Precache.php</strong></p>
<p>ka-Map is a web-based interface for viewing MapServer-based maps using map tiles. Normally, ka-Map generates only the necessary map tiles needed to show in the browser&#8217;s window. But there is a separate file, named precache.php, that also comes with the ka-Map that does generate all the map tiles for every scale of the map.</p>
<p>Navigate to the following directory: <strong>C:\ms4w\apps\ka-map-1.0\htdocs</strong>. Scroll through the list of files to find the file <strong>precache.php</strong>. The good news is this file does not need to be modified in any way. It relies solely on the config.php settings described above to determine what mapfile and map scales to use when creating the map tiles.</p>
<p><strong>Running Precache.php</strong></p>
<p>Readers are encouraged to first read over <a href="http://ka-map.ominiverdi.org/wiki/index.php/Pre-caching_system" target="_blank">this article</a> in the ka-Map wiki about precache.php. You don&#8217;t have to understand everything it discusses &#8211; just glance over the parameters needed to run precache.php.</p>
<p>Running precache.php requires returning to the world of DOS prompts and command line. It is important to follow these steps exactly as listed otherwise it may not work correctly.</p>
<ol>
<li>Open a command prompt. On Windows, go to Start&#8230;Run and type <strong>cmd</strong>.</li>
<li>Type <strong>cd C:\ms4w\apps\ka-map-1.0\htdocs</strong> to go to the directory with precache.php.</li>
<li>Since precache.php is a PHP file, we need to run it using the PHP executable (php.exe). Fortunately this is already included with the MS4W package. Type <strong>C:\ms4w\Apache\cgi-bin\php.exe precache.php</strong> in the command prompt. We left out the required parameters on purpose here so you can see the usage instructions:
</ol>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/11/precache_usage.jpg" alt="Precache.php Usage" /></p>
<p>We won&#8217;t need to use -f, -m, or -s options but we do need to add the tile_url parameter. This is the web address (hence &#8220;_url&#8221;) to ka-Map&#8217;s <strong>tile.php</strong> file. Even though the file is stored locally at <strong>C:\ms4w\apps\ka-map-1.0\htdocs\tile.php</strong>, we need to enter a valid URL. The usage instructions suggest using http://localhost/ka-map/htdocs/tile.php but that didn&#8217;t work for us. Instead we will use <strong>http://localhost/kamap/tile.php</strong>.</p>
<ol start="4">
<li>Type <strong>C:\ms4w\Apache\cgi-bin\php.exe precache.php http://localhost/kamap/tile.php</strong>. Press enter the map tiles will be generated.</li>
</ol>
<p>This process will take several minutes as all the tiles at each of the scale levels are generated. The command prompt will display information on each scale level. This information on meta tiles and tile counts is informative but not necessary to understand right now. In short, precache.php requests larger tiles (&#8221;meta tiles&#8221;) and then cuts them up to arrive at the final set of tiles.</p>
<p><strong>Viewing the Map Tile Cache</strong></p>
<p>Navigate to <strong>C:\ms4w\tmp\ms_tmp\kacache\gmap</strong>. Inside this folder should be a folder named for each scale level in the map. Inside each scale level folder our folders named __base__ and then a sub-folder named def. This is where the tile images can be found.</p>
<p>Because ka-Map tiles are generally only used internally and not designed for end-user interaction, there is a potentially confusing way to name tiles and tile folders. Anytime a folder or file contains the letters &#8220;t&#8221; or &#8220;l&#8221;, it means top or left. So instead of naming tiles with X/Ys or Row/Columns, ka-Map uses the &#8220;Left/Top&#8221; naming convention.  </p>
<p>It also names each tile based on it&#8217;s pixel location and tile size. Since the config.php was set to output 256&#215;256 tiles, each tile image will include top and left numbers based on multiples of 256. So if one tile is named t0l0.png, the adjacent tiles on each side would be named t0l256.png and t0l-256.png. Glance through the folders and view some of the individual tiles to get a sense of the tiling structure.</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/11/kamap_tile_t-256l0.png" alt="kaMap Tile Example" /></p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/11/kamap_tile_t-256l-256.png" alt="kaMap Tile Example" /></p>
<p><strong>What&#8217;s the Benefit?</strong></p>
<p>Traditional usage of precache.php is for improving the load times on a web mapping site by caching all the tiles ahead of time.  For our objectives, having a complete set of pre-compiled map tiles means we can create a desktop application without including a GIS code library or GIS data. It also eliminates the extra processing time and would make deploying our applications easier. Instead of including extra DLLs and shapefiles, we simply need to include a folder of map tiles to run the application.</p>
<p><strong>Conclusion</strong></p>
<p>This post is probably the most technical topic we&#8217;ve covered to date. For now, simply understanding how to generate map tiles using precache.php is a what&#8217;s important. In the next post we will discuss the map tiles in some more depth, including how we can use them in other applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://spatialhorizons.com/2007/11/14/using-mapserver-2-generating-map-tiles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Map Tiles (4) &#8211; XNA Program</title>
		<link>http://spatialhorizons.com/2007/08/13/map-tiles-4-xna-program/</link>
		<comments>http://spatialhorizons.com/2007/08/13/map-tiles-4-xna-program/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 22:47:07 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Map Tiles]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://spatialhorizons.com/2007/08/13/map-tiles-4-xna-program/</guid>
		<description><![CDATA[The last three posts discussed map tiles in some detail but without getting into programming. First, we described terminology surrounding map tiles. Then we setup a sample TileMap from an image of the world.  And finally, we covered some &#8220;tile math&#8221; examples. Now we will wrap everything up by developing a mapping program that [...]]]></description>
			<content:encoded><![CDATA[<p>The last three posts discussed map tiles in some detail but without getting into programming. First, we described <a href="http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/">terminology</a> surrounding map tiles. Then we setup a <a href="http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/">sample TileMap</a> from an image of the world.  And finally, we covered some &#8220;<a href="http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/">tile math</a>&#8221; examples. Now we will wrap everything up by developing a mapping program that uses map tiles.</p>
<p>The program we created was built off one of our previous projects (see World Mapper parts <a href="http://spatialhorizons.com/2007/02/15/world-mapper-1/">1</a>,<a href="http://spatialhorizons.com/2007/04/02/world-mapper-2/">2</a>,<a href="http://spatialhorizons.com/2007/04/16/world-mapper-3/">3</a>) and, as always, the <a href="http://msdn2.microsoft.com/en-us/xna/default.aspx">XNA framework</a>. This project turned out to be much more complex than any of our previous programs so it would be impossible to cover all the source code in detail. Instead, this post will provide an overview of the program&#8217;s structure and then provide the source code for you to download and explore on your own.<br />
<span id="more-89"></span><br />
<strong>Program Structure</strong></p>
<p>Below is a graphic of all the classes used in the program with our main class named WorldMapper.cs.</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/08/worldmapper_classes.jpg" alt="World Mapper Classes" /></p>
<p>We designed three classes to handle the maps tiles &#8211; a <strong>TileMap</strong>, <strong>TileSet</strong>, and <strong>Tile</strong> class. The main program only interacts with the TileMap class and the creation of TileSets and Tiles is done automatically.</p>
<p>We also needed a separate class to keep track of where the user is looking on the map. This concept of a &#8220;viewport&#8221; or &#8220;camera&#8221; is commonly used in game programming so the program knows which tiles need to be drawn on-screen. It also tracks which TileSet the user is viewing. The class was named <strong>GeoCamera2D</strong> and contains methods to pan, zoom, and recenter the map. Remembering the <a href="http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/">discussion</a> in the last post on tile coordinates versus geographic coordinates, our camera stores all it&#8217;s location information in tile coordinates like 0,0 or 2.4, 1.3 and relies on the current TileSet class to convert the location to longitude/latitude coordinates when needed.</p>
<p>Both the <strong>Keyboard</strong> and <strong>Mouse</strong> classes have been covered in previous posts so we will skip those now.  Some of the code was updated but the main functionality remained the same.</p>
<p><strong>C# Programming</strong></p>
<p>Our map tilling program follows the standard XNA structure but with the addition of our tile mapping classes. Some of the source code is covered below.</p>
<p>We first create several variables to store our new classes and constants to define some pixel parameters:</p>
<p>
<pre lang="csharp">shTileMap _tileMap;
shGeoCamera2D _camera2D;

const int _mapWidth = 800;
const int _mapHeight = 400;

const int _tileWidth = 800;
const int _tileHeight = 400;
</pre>
</p>
<p>In the constructor, we initiate our TileMap class with some general information, including the extent of the entire map (in this case, the entire world). The camera class is also initiated:</p>
<p>
<pre lang="csharp">_tileMap = new shTileMap("WorldMap", _tileWidth, _tileHeight, -180, -90, 180, 90);
_camera2D = new shGeoCamera2D(_mapWidth, _mapHeight, _tileWidth, _tileHeight);</pre>
</p>
<p>Next we have to define each of our three TileSets (see <a href="http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/">part 2</a> for more information). We first use the AddTileSet method to create a new TileSet with information on it&#8217;s zoom level (0), and tile coordinate extent (0,0 to 1,1).</p>
<p>
<pre lang="csharp">//--> setup TileSet 0
shTileSet newTileSet = _tileMap.AddTileSet(0, 0, 0, 1, 1, _graphics.GraphicsDevice);</pre>
</p>
<p>We then have to define some conversion parameters (see <a href="http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/">part 3</a>) to enable the TileSet to convert between tile coordinates and geographic coordinates.</p>
<p>
<pre lang="csharp">newTileSet.DefineConversionParameters(new Vector2(-180, -90), 360, 180);</pre>
</p>
<p>We repeat the TileSet creation twice more for the other TileSets.</p>
<p>In the Update method, we check for mouse and keyboard clicks.  A mouse click simply shows the user the geographic coordinates of where they clicked on the map.</p>
<p>
<pre lang="csharp">// check if a mouse click has occured
_mouse.Update();
if (_mouse.LeftButton == ButtonState.Pressed)
{
    //--> convert click position to grid position
    Vector2 gridPos = _camera2D.ConvertScreenPos2GridPos(_mouse.X, _mouse.Y);

    //--> convert grid position to real world position
    Vector2 realPos = _tileMap.ActiveTileSet.ConvertGridPos2RealPos(gridPos.X, gridPos.Y);

    //--> update last click position for display on-screen
    _lastClickPos = realPos;
}</pre>
</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/08/worldmapper_screenshot.jpg" alt="World Mapper Screenshot" /></p>
<p>Arrow keys will pan around the map, the Z key zooms in, and the X key zooms out. One of the keyboard checks looks like this:</p>
<p>
<pre lang="csharp">// check if a key has been pressed
_keyboard.Update(gameTime);
if (_keyboard.IsNewKeyDown(Keys.Left))
{
    _camera2D.PanLeft(_tileMap.ActiveTileSet.MinCol);
}</pre>
</p>
<p>Every time a pan occurs, we send as a parameter the boundary being approached by the pan to ensure the user can&#8217;t go outside the bounding box of the map.</p>
<p>Finally, in the Draw method, displaying the map takes only one line:</p>
<p>
<pre lang="csharp">_tileMap.Draw(_spriteBatch, _camera2D);</pre>
</p>
<p><strong>Conclusion</strong></p>
<p>The code involved in this project is rather complex and represents only one approach to making a tile-based mapping program.  The objective was to create a framework that could easily be applied to other TileMaps of different sizes, extents, and tile counts. There are aspects of the program that would need to be addressed though before it succeeded in that respect. For example, our program pre-loads all 22 map tiles for convenience but this wouldn&#8217;t be practical for a TileMap that has hundreds of tiles. Some form of a &#8220;tile cache&#8221; would need to be implemented that only loaded and stored tiles within the user&#8217;s view. </p>
<p>The source code and compiled program are available to download below.  The source code requires the <a href="http://msdn2.microsoft.com/en-us/xna/aa937795.aspx">XNA Game Studio Express</a> and the program download requires at minimum the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=A7DA4763-6807-4BD5-8D18-18C60C437F93&#038;displaylang=en">XNA runtime redistributable</a> to run.</p>
<p><a href="http://spatialhorizons.com/downloads/WorldMapperMapTiles.zip"><img border="0" alt="Download Source Code" src="http://spatialhorizons.com/downloads/code_download.jpg" /></a><br />
<a href="http://spatialhorizons.com/downloads/WorldMapperMapTiles_EXE.zip"><img border="0" alt="Download Program" src="http://spatialhorizons.com/downloads/program_download.jpg" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://spatialhorizons.com/2007/08/13/map-tiles-4-xna-program/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Map Tiles (3) &#8211; Tile Math</title>
		<link>http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/</link>
		<comments>http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 00:31:59 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Map Tiles]]></category>

		<guid isPermaLink="false">http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/</guid>
		<description><![CDATA[Before using our Tile Map we created in the last post, a quick discussion on &#8220;tile math&#8221; might be helpful. More specifically, we need be able to easily switch between tile coordinates and real-world coordinates to create a complete tile mapping program.
We will use this map tile as an example:


Also included in the image is [...]]]></description>
			<content:encoded><![CDATA[<p>Before using our Tile Map we created in the last <a href="http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/">post</a>, a quick discussion on &#8220;tile math&#8221; might be helpful. More specifically, we need be able to easily switch between tile coordinates and real-world coordinates to create a complete tile mapping program.</p>
<p>We will use this map tile as an example:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/08/worldmap_sampletilegrid.jpg" alt="Map Tile Sample" /><br />
<span id="more-91"></span><br />
Also included in the image is the tile coordinates of it&#8217;s four corners (remember that we are naming map tiles based on the lower-left corner so this tile is the 0,0 tile).</p>
<p>The tile also has real-world (geographic) coordinates. We are keeping this simple by using longitude (X) and latitude (Y) so the corner locations look like this:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/08/worldmap_sampletilereal.jpg" alt="Tile Map Sample" /></p>
<p>Our tile mapping program will use tile coordinates throughout the code but numerous functions will require geographic coordinates. So to convert tile coordinates to geographic coordinates, we need two more related pieces of information &#8211; the geographic width and height of each tile. In the above example, the geographic width (&#8221;tile distance X&#8221;) is 180 degrees and the height (&#8221;tile distance Y&#8221;) is 90 degrees.</p>
<p><strong>Tile Math Example</strong></p>
<p>Let&#8217;s envision a scenario where our tile mapping program is centered on the tile coordinate 0.5,0.5 &#8211; basically the center of our sample tile. We want to show the user the location of the map center but telling them 0.5, 0.5 is useless. So to display longitude/latitude, we need to perform separate calculations. First, longitude:</p>
<p>
<pre lang="csharp">Longitude = [Tile Coordinate X] x [Tile Distance X]
Longitude = 0.5 * 180 = 90</pre>
</p>
<p>And latitude:</p>
<p>
<pre lang="csharp">Latitude = [Tile Coordinate Y] x [Tile Distance Y]
Latitude = 0.5 * 90 = 45</pre>
</p>
<p>So converting tile coordinate 0.5,0.5 to geographic coordinates is 90,45. </p>
<p><strong>Special Case &#8211; Tile Origin doesn&#8217;t match Geographic Origin</strong></p>
<p>The above equations work for TileSets that have their origin at the geographic origin. In some TileSets, this may not be the case. For example, remember this tile from the last post:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/worldmap_level0.jpg" alt="TileSet 0" /></p>
<p>This single tile of the entire earth has it&#8217;s origin at the lower left corner which is really -180, -90 in terms of longitude and latitude. </p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/02/latlon_map.jpg" alt="LatLongMap" /></p>
<p>When we convert tile coordinates here to geographic coordinates, we must include the tile origin in the equation.</p>
<p>Again, assuming our map is centered on tile coordinate 0.5, 0.5, the geographic center is calculated below. Note that with this tile, the tile distance X is 360 degrees and the tile distance Y is 180 degrees.</p>
<p>
<pre lang="csharp">Longitude = (0.5 * 360) + -180 = 0</pre>
</p>
<p>
<pre lang="csharp">Latitude = (0.5 * 180) + -90 = 0</pre>
</p>
<p>So converting tile coordinate 0.5, 0.5 to geographic coordinates is 0,0.</p>
<p>The next post will begin constructing our XNA-based tile mapping program so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://spatialhorizons.com/2007/08/06/map-tiles-3-tile-math/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Map Tiles (2) &#8211; Sample TileMap</title>
		<link>http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/</link>
		<comments>http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 22:57:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Map Tiles]]></category>

		<guid isPermaLink="false">http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/</guid>
		<description><![CDATA[Our last post introduced the concept of map tiles and the benefits for using them in a desktop application. Before using map tiles in XNA, we need to create a sample &#8220;TileMap&#8221;.  Normally, tile maps would be created automatically using some GIS or Mapping program.  To gain a better understanding though, we will [...]]]></description>
			<content:encoded><![CDATA[<p>Our last <a href="http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/">post</a> introduced the concept of map tiles and the benefits for using them in a desktop application. Before using map tiles in XNA, we need to create a sample &#8220;TileMap&#8221;.  Normally, tile maps would be created automatically using some GIS or Mapping program.  To gain a better understanding though, we will manually create a set of map tiles using this world map that we have used before:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/06/imageswap_image1.jpg" alt="World Map" /></p>
<p>The original <a href="http://upload.wikimedia.org/wikipedia/commons/c/cf/WorldMap-A_non-Frame.png" target="_blank">image</a> from the <a href="http://commons.wikimedia.org/wiki/Main_Page">Wikimedia Commons</a> is over 8 MB in size so we can cut it up in a graphics program and create each tile individually. All tiles will be the same size &#8211; 800 pixels wide by 400 pixels tall. Our sample TileMap will have 3 TileSets each a different scale (also referred to as &#8220;zoom levels&#8221;). They will be numbered from 0 to 2 with 0 being the farthest from ground level.<br />
<span id="more-85"></span><br />
<strong>Tile Coordinates</strong></p>
<p>The <a href="http://wiki.osgeo.org/index.php/Tile_Map_Service_Specification">OSGeo tile map standards document</a> includes an image showing how the tiles are named (see <a href="http://wiki.osgeo.org/index.php/Image:Tms.png">here</a>). Each tile has a set of tile coordinates that describe the tiles column (X) and row (Y) position within the TileSet.  It is important to note the a tile&#8217;s coordinates are based on the <strong>lower left corner of the tile</strong>.</p>
<p>Understanding the concept of tile coordinates is crucial to everything we will do with map tiles. They make working with tiles much easier than if we were to use geographic coordinates.  In fact, as long as we know some geographic information about each TileSet, we can convert any tile coordinate to it&#8217;s corresponding &#8220;real-world&#8221; location (all of our examples will continue to use only longitude/latitude locations to keep things simple).</p>
<p><strong>TileSet 0</strong></p>
<p>The first zoom level will be the entire world and contain only 1 tile.  It&#8217;s tile coordinate is then obviously 0,0.  Remember a tile coordinate of 0,0 means the lower left corner is 0,0 so if we were convert the origin to longitude/latitude, the origin would be -180, -90.</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/worldmap_level0.jpg" alt="TileSet 0" /></p>
<p><strong>TileSet 1</strong></p>
<p>The second TileSet zooms in closer (2x), resulting in 4 tiles. The center of the TileSet (0,0) is placed in the middle so in this case it corresponds with the longitude/latitude origin.</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/worldmap_level1.jpg" alt="TileMap 1" /></p>
<p><strong>TileSet 2</strong></p>
<p>The third and final set zooms in 2x again, resulting in 16 tiles.</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/worldmap_level2.jpg" alt="TileMap 2" /></p>
<p><strong>Tile Naming Convention</strong></p>
<p>We will name each tile image using the convention: &#8220;Map Name&#8221; + &#8220;Zoom Level&#8221; + &#8220;Column(x)&#8221; + &#8220;Row(y)&#8221;. So TileSet 1 has these file names:</p>
<ul>
<li>WorldMap_1_0_0.jpg</li>
<li>WorldMap_1_0_-1.jpg</li>
<li>WorldMap_1_-1_-1.jpg</li>
<li>WorldMap_1_-1_0.jpg</li>
</ul>
<p>Click <a href="http://spatialhorizons.com/downloads/WorldMap_Tiles.zip">here</a> to download all the map tiles that will we use next time to start making an XNA &#8220;tile mapping&#8221; program.</p>
]]></content:encoded>
			<wfw:commentRss>http://spatialhorizons.com/2007/07/24/map-tiles-2-sample-tilemap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Map Tiles (1) &#8211; Introduction</title>
		<link>http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/</link>
		<comments>http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/#comments</comments>
		<pubDate>Sun, 15 Jul 2007 17:51:08 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Map Tiles]]></category>

		<guid isPermaLink="false">http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/</guid>
		<description><![CDATA[Google Maps ushered in a new era in web mapping: pre-rendered map tiles. Traditionally, web mapping followed a 4-tiered approach for generating map images:

The benefits in this scenario are obvious. Maps at any scale can be produced and layers of information (e.g. roads, lakes, etc.) can be turned on or off with each map request. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://maps.google.com/">Google Maps</a> ushered in a new era in web mapping: pre-rendered map tiles. Traditionally, web mapping followed a 4-tiered approach for generating map images:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/webmapping_4_steps.jpg" alt="Web Mapping 4 Steps" /></p>
<p>The benefits in this scenario are obvious. Maps at any scale can be produced and layers of information (e.g. roads, lakes, etc.) can be turned on or off with each map request.  Map colors, shapes, and symbols can even be changed between requests. The unlimited possibilities come a cost though of slower rendering because each request requires the raw data to be accessed, combined with other layers, and the returned as a single image.<br />
<span id="more-82"></span><br />
An alternative approach made popular by Google Maps involves pre-rendering map tiles at a variety of scales. This 3-tiered approach removed GIS data from the workflow:</p>
<p><img src="http://spatialhorizons.com/wp-content/uploads/2007/07/webmapping_3_steps.jpg" alt="Web Mapping 3 Steps" /></p>
<p>The primary benefit here is speed. Having the map images already rendered means the only limitation is how fast the images can be transferred across the web.  A secondary result of having the maps &#8220;ready-to-go&#8221; means that tiles adjacent to the user&#8217;s current view can be loaded concurrently to allow for seamless panning. Tiles can also be cached so if the user returns to an area, the images don&#8217;t even need to be re-accessed from the web server.</p>
<p>The disadvantage to the tiling approach is that there is only a limited number of map scales and layer combinations available. A pre-tiled map may only have 5-10 map scales (although Google Maps has over 15) which the user can view data from.  In most cases, individual layers cannot be turned on or off. The map&#8217;s cartography is presented &#8220;as-is&#8221; so colors, symbols, and sizes cannot be altered.</p>
<p>For a in-depth discussion how Google Maps works, here is a <a href="http://cfis.savagexi.com/articles/2006/05/03/google-maps-deconstructed">link</a> to a great article.</p>
<p><strong>Map Tiles for Desktop Applications</strong></p>
<p>Pre-rendering map tiles can also be beneficial for desktop mapping applications. In terms of our exploration with <a href="http://msdn2.microsoft.com/en-us/xna/default.aspx">XNA</a>, having pre-rendered map tiles allows us to treat them just like a standard texture. We can load them and easily draw, shift, rescale, etc. without even having to rely an outside GIS/mapping engine or API. Basically, we are then using the same technique video game makers have been using to create games for the last decade.</p>
<p><strong>Map Tile Basics</strong></p>
<p>Let&#8217;s briefly define some terminology relating to map tiling that will be used in some upcoming projects. Many of the terms come from a <a href="http://wiki.osgeo.org/index.php/Tile_Map_Service_Specification">document</a> at the <a href="http://www.osgeo.org/">Open Source Geospatial Foundation (OSGEO)</a> discussing proposed standards for tile mapping on the web.</p>
<ul>
<li><strong>Tile</strong> &#8211; a single map image</li>
<li><strong>Tile Format Width</strong> &#8211; the width of a tile in pixels</li>
<li><strong>Tile Format Height</strong> &#8211; the height of a tile in pixels</li>
<li><strong>TileSet</strong> &#8211;  a set of tiles for a single scale of a map</li>
<li><strong>Tile Coordinate</strong> &#8211; the column/row location of a tile in a given TileSet; see this <a href="http://wiki.osgeo.org/index.php/Image:Tms.png">image</a> for more information</li>
<li><strong>TileMap</strong> &#8211; the entire &#8220;map&#8221;; a collection of TileSets at different scales</li>
<li><strong>Bounding Box</strong> &#8211; the geographic extent of the entire TileMap described by it&#8217;s minimum and maximum X/Y coordinates</li>
</ul>
<p>The next post will provide a simple example of a TileMap and then we will start using TileMaps in XNA.</p>
]]></content:encoded>
			<wfw:commentRss>http://spatialhorizons.com/2007/07/15/map-tiles-1-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
