In the v3 version of the Virtual Earth API, we added support for custom Tile Layers, which allows you to add your own custom imagery and overlays on the map. 

One of our developers, Jaya Bhatia blogged about Tile Layers with the v3 Virtual Earth API awhile back.  In the v5 Virtual Earth API, we have now simplified working with custom Tile Layers. 

To create custom tiles for Virtual Earth, you can use MSR MapCruncher.  Check out the step by step tutorial and a 5 minute demo video of how to use MSR MapCruncher to generate tiles.

Once you have generated your tiles and hosted them somewhere, you are ready to create a v5 Virtual Earth API mashup with your tile layer.

For this example, I am using the tiles Jaya generated for her original example from a Seattle Metro Transit System Map.

To load your custom tiles in the Virtual Earth v5 API, you first need to create a VETileSourceSpecification with a string ID and a URL to your custom layer.

var tileSource = new VETileSourceSpecification("SeattleTransit", "http://jbhatia1.members.winisp.net/SeattleTransit/%4.png");

The URL to the tile source can have special characters which will be substituted when tiles are loaded.  '%4' is used to substitute the tile name using the Virtual Earth naming convention. MSR Map Cruncher generates tiles using the Virtual Earth naming convention, so we can use '%4' as a placeholder for the the name of the tile files.

You can then set other optional properties for the tile layer on your VETileSourceSpecification object:

tileSource.Bounds = [new VELatLongRectangle(new VELatLong(49,-123),new VELatLong(47,-121))];
tileSource.MinZoomLevel = 2;
tileSource.MaxZoomLevel = 16;
tileSource.Opacity = 0.6;
tileSource.ZIndex = 100;

In the above sample, I set the Bounds property which is an array of VELatLongRectangles which specify the coverage area of your tile layer. The MinZoomLevel and MaxZoomLevel properties specify the zoom level ranges where your tiles exist.  Using the Bounds, MinZoomLevel, and MaxZoomLevel can be used to restrict where your tile layer is displayed and also improves performance because it will prevent unnecessary attempts to load tiles where they do not exist.

The Opacity property allows you to specify the transparency of the tile layer. The value can range from 0 to 1, where 0 is completely transparent and 1 is opaque.

The ZIndex property allows you to specify the z-index for the tiles in the tile layer and allows you to control which tile layers appear over other tile layers.

Once you have finished creating the VETileSourceSpecification, you can call AddTileLayer on the VEMap to add your tiles to the map.  The second parameter indicates whether or not to immediately show the tile layer.  In this case, it is set to true so the tile layer will be immediately visible.

map.AddTileLayer(tileSource, true);

Here is a link to the complete working example:

Virtual Earth API Tile Layer Sample

For more information regarding the Virtual Earth APIs, see the Virtual Earth Interactive SDK.