In the last post, I downloaded some elevation data from the GTOPO digital elevation model and loaded it into a SQL Server table. In this post, I’m now going to select a subset of that data in order to create a terrain map of a particular Bing Maps tile.
The Bing Maps Tile System
As you probably already know, Bing Maps are constructed from a set of raster “tiles” – prerendered 256px x 256px gif, jpg, or png images that form the background of each map. There are different sets of tiles that correspond to the different styles of map.
Here’s a few examples:
Road Map Tile
Aerial Map Tile
Ordnance Survey Map Tile
Every tile is numbered with a quadkey – a unique identifier that exactly describes the position and zoom level of where that tile should be placed. I’m not going to explain the quadkey system here, because there’s already an excellent article on MSDN.
The important fact is that, by knowing only the quadkey of a tile, it is possible to determine the exact coordinate boundaries of every corner of that tile. In SQL Server, that means we can construct a POLYGON that represents the extent of that tile, and retrieve any data that lies on the tile (or, in this example, the elevation data that corresponds to the terrain of that tile). The following method demonstrates how to return a SqlGeography polygon from a Bing Maps quadkey:
Now, I just need to choose a particular tile whose terrain to examine…. I’ve chosen the tile at zoom level 6 that portrays most of Scotland – my ancestral home and also home to some interesting geographic features (i.e. mountains and lochs!). Here’s the tile viewed using Bing Maps’ road map style:
The quadkey for this tile is 031133 and, using the method above, I can calculate the corresponding SqlGeography as:
POLYGON((-5.625 55.7765730186677, 0 55.7765730186677, 0 58.8137417157078, –5.625 58.8137417157078, -5.625 55.7765730186677))
Therefore, we can retrieve the relevant GTOPO30 elevation data for this tile from SQL Server using the following query:
SELECT * FROM W020N90 WHERE geog4326.STIntersects(geography::STPolyFromText(‘POLYGON((-5.625 55.7765730186677, 0 55.7765730186677, 0 58.8137417157078, –5.625 58.8137417157078, -5.625 55.7765730186677))’, 4326) = 1;
Here’s the results:
In the next post, I’ll use this elevation data to create a 3d surface onto which to overlay the Bing Maps tile image.