A few weeks back my good friend, colleague and Microsoft trainer par excellence, Elias Markelis asked me to do a joint webinar on Windows Phone and Bing Maps, part of Microsoft’s Live Virtual Academy series. The idea being that since I am the ‘GIS guy’ I will talk a bit more about the spatial / map aspects and not just the code.
(BTW, you can also find the full webinar at http://www.techdays.gr/videos/4056.html but take note: The slides are in English but seminar was delivered in Greek.)
Elias has now written a 3-part blog post to cover most of the things we talked about in the webinar: You can find the links here:
- Windows Phone location awareness– the basics
- Windows Phone location awareness– geocoding
- Windows Phone location awareness– routing
These are very detailed step-by-step guides on how to develop your first Windows phone map-based app, utilizing the Geocoding and Routing Services, GPS, the emulator and lots of other goodies to get you started.
But this is the code only. In this post, which can be thought as an ‘addendum’ to Elias’ series, I would talk about how Bing Maps work, their tile system, scales and projection systems. The post is mainly geared towards Silverlight and Windows Phone developers who never worked with GIS and mapping systems before. GIS gurus, feel free to skip directly to the code!
Should I care? Just show me some code!
Well, you should care really. Understanding the tile system and projections would make a huge difference in real-world applications where you would invariably need to integrate with other spatial data in different formats. For example you may have to display geometry data from a SQL Server Database, or add a WMS layer. In any of these cases, you would need to understand terms like ‘projection system’, ‘geographic coordinates’ and ‘map scales’. And also understand how these apply in Bing Maps.
But fear not, its not going to be ALL theory. I would also show you how to develop a Bing Maps app which will help you visualize some of the theory and maths behind Bing Maps.
The Basics – Bing Maps tile system
Now, before I start, I should point out that there is an excellent article in MSDN which explains the Bing Maps Tile System in great detail, including all the maths behind it. It even includes all the C# code that implements it. In actual fact, I would be using bits of this code in my own example. But here, I will just give you the basics to get you started in the form of a list of simple, clear statements. So here it goes:
- Bing Maps uses a single map projection system called Mercator. The projection is necessary since Bing Maps displays the whole earth, the earth, well, is round, so in order to see it a screen (which, you know, is flat) we have to ‘project’ it. The image below depicts this concept. (This is not the Mercator projection BTW, just a peeled orange ).
- To accurately locate a point or any other feature on the map, the WGS84 Spatial Reference System (SRID) is used which uses geographic coordinates (Latitude and Longitude denoted also as φ,λ). This is the same SRID used by the GPS devices (see the link here?)
- Map scale is another feature of any map. It denotes the ratio between a real-world distance and the map distance at a specified unit. For example a map at a scale of 1:100,000 with map units in meters, means that a meter measured on the map (or you screen) is a 100,000m in the real world. One of the things to point out here is that scale only makes sense and applies on maps on a screen or on paper. Data itself does not have scale.For example, the question of what is the scale of a point at coordinates 40,2345, 22.87361 does not make sense!
- In very simple terms Bing Maps maps the world using satellite images stitched together. As you can appreciate, these are terrabytes of data we are talking about.To optimize performance these images are divided into tiles of 256×256 pixels each.
- Bing Maps has the concept of zoom levels. There are 23 zoom levels where 1 displays the whole earth and 23 zooms at street level. When you zoom in or out at a different zoom level, different tiles (and hence satellite images) are displayed.
- Tiles have their own coordinate system (a “Tile XY coordinate”) which can also be denoted as a single string called a quadkey. As explained in the Bing Maps Tile System article:
To optimize the indexing and storage of tiles, the two-dimensional tile XY coordinates are combined into one-dimensional strings called quadtree keys, or “quadkeys” for short. Each quadkey uniquely identifies a single tile at a particular level of detail…
The example below displays the quadkeys for Levels 1-3 (image from the same article):
Some code (at last)
Just to ‘visualize’ what we talked about, we will create a Windows Phone application with Bing Maps which will accomplish a few simple tasks:
- Double-tapping the map will display the quadkey value of the current tile in a message box.
- Panning the map, will display the latitude, longitude coordinates in a textblock.
- The map will also draw the tiles used in the current map extent and display their quadkey value
To start off with, start a new Windows Phone 7 project in Visual Studio 2010 and add the maps control I won’t go into any details on how to do this, there are a lot of articles abound. You can try Elias’ Windows Phone location awareness– the basics or one of mine Sterling Database for Windows Phone 7, Silverlight and Bing Maps
We will now add 3 event handlers to the map control. One for double-tapping on the map, one for mouse move and one for the ViewChangeEnd which fires when the map has finished zooming or panning. Our XAML file should now look like this:
The MouseMove event handler is listed below:
Our DoubleTap handler follows. It basically picks up the Latitude, Longitude location the user tapped on the map, converts them to pixel coordinates, then to Tile coordinates and then to the quadkey value. All the conversion functions can be found in the (yes, you guessed it) MSDN article mentioned above.
Ok, for the time being leave our last event handler (ViewChangeEnd) empty and compile and run the project. Zoom and pan the map to an area you are interested in. Notice that while panning the geographic coordinates are getting updated in the text block.
Now double click/tap at different areas of the screen. A message box should appear displaying the quadkey of the current tile
That’s ok. Useful-ish. But you have to \guess’ where the different tiles are. What we will do next is display the actual tiles on the map as rectangles and also display the corresponding quadkeys. And we will wire this functionality in the ViewChangEnd event, so it runs only when the map has finished rendering.
The logic behind the drawing of the tiles is pretty simple: Find the extent of the current map (min & max coordinates) and then ‘loop’ or ‘sweep’ the map, 256pixels at a time to get to the next tile, calculating the rectangle (tile) at each iteration and draw this rectangle on the map.
I implemented this ‘sweeping’ using three loops, one by latitude, one by longitude and one ‘diagonal’ where both latitude and longitude were iterated by 256 pixels. Now, I am pretty sure there is a by far smarter way of achieving the same result but its getting late and this was the easiest way I could come up with.
The relevant code is listed below:
Now compile and run the app again. This time you should be able to see the tiles appearing as red rectangles every time you pan and zoom the map with the quadkey displaying inside as in the image below.
Hope this example clears up a few things about Bing Maps and how they work. You can download the full application from http://www.box.com/s/ppovoyfbuiqf304qod8b
Enjoy coding! – PV