In a previous post, I explained how to replace the base tile layer in the Bing Maps Silverlight control with an ESRI tile layer. In this post, I’ll show how to do the same but using the Bing Maps AJAX v7 control. You can use this technique to use the Bing Maps AJAX control, but replace the Bing imagery with OSM tiles or the ESRI tile layers used in the previous Silverlight post, as well as many other tile sources.

The first step is to specify not to load the default Bing Maps tile layer. Do this by specifying the mercator MapTypeId in the options passed to the constructor when you first initialise the map:

mapTypeId: Microsoft.Maps.MapTypeId.mercator

The next step is to create a new TileSource. The uriConstructor of the TileSource must return the correct URI for a requested tile. If your tile provider names its tiles according to the default Bing Maps quadkey numbering system, then the uriConstructor can be a simple string using the {quadkey} placeholder. This will be replaced with the appropriate quadkey when the tile is requested:

However, for OSM tiles, or any other tile providers that not follow the basic quadkey numbering system, we instead need a function to construct the appropriate URI for each tile. I’ll do this in a function called getTilePath, and I’ll specify this in the TileSource uriConstructor as follows:

The getTilePath function will return a string with the appropriate URI for the requested tile. For OSM tiles, a typical tile looks like http://tile.openstreetmap.org/zoom/x/y.png. The function to create this tile is therefore:

It’s not documented in the API – that’s why I’m writing about it here 😉 I don’t just write out stuff from MSDN on this blog, y’know!
If you open up veapicore.js you can look at the getUriConstructor method – it basically accepts a tile object, which has properties x and y to represent the row and column at which that tile should be placed on the map.

Hi alastaira,
do you know if possible to make the map control work in disconnected mode?
We are servicing our own tiles using a lightweight web server hosted on the same machine (http://localhost/blabla); however it looks like the map control stop displaying tiles whenever the machine is disconnected from the internet. (we verified that the map control continue to request the tiles from the localhost, but they are not displayed for some reason.)

We are in the process of implementing something similar using the Bing Maps AJAX Control version 7, and I was wondering whether you know of any JS function to redraw the “Map” view, refresh a specific “TileLayer” or even refresh a specific Tile.

This functionality is very useful for those cases where you need to manually update the a TileLayer in the current map view, knowing that the underlying source data of your tiles has changed.

Alastaira, I stumbled upon your code while searching for an answer I am in need of. Reading the API for Bing AJAX V7 I cannot find a way to use dynamic overlays on the map. Just as ESRI services offer tiled map services, it also has the ability to have dynamically created layers that can have conditional queries passed in to allow one to manipulate the data.

If you know of any sources I could look at, or have any knowledge of how I might solve this, I would be very grateful!

By “dynamic” overlays, you mean tile layers that are created from data at runtime (eg based on data retireved from a DB query, or similar)?
Yes, you can do this – what you need to do is create a custom tile layer, but instead of pointing it at a directory or pre-rendered PNG/JPG tiles, you point it at a custom tile handler – an .ASHX or .PHP file, say. You pass parameters to the handler with the quadkey of the tile you want to create, and other settings to customise the tile and choose what features are rendered etc. The handler uses the quadkey to retrieve and render the features that lie within the bounds of this tile from the database and generates an image on the fly (using, say, the System.Drawing classes in .NET, or GDI in PHP), and returns the image to Bing Maps.