Chris Pietschmann

husband, father, hacker, entrepreneur, futurist, innovator, autodidact

NAVIGATION - SEARCH

Bing Maps Silverlight CTP: Using Tile Layers to Overlay Custom Map Imagery

One of the features that the Virtual Earth JavaScript Control has is the ability to add custom Tile Layers to overlay your own custom imagery over the map. The Virtual Earth Silverlight control also supports this feature.

This was written for the Bing Maps Silverlight CTP Release.

Before I begin to explain how to add custom Tile Layers to the Map it’s important to note that you can still use the MapCruncher tool to generate Map Imagery Tiles to be used with the custom Tile Layers. The specifics of using the MapCruncher tool to generate Map Imagery Tiles isn’t within the scope of this article. You can find a tutorial on how to use MapCruncher here: http://research.microsoft.com/en-us/um/redmond/projects/mapcruncher/tutorial/version3.0docs/index.htm

Add Custom Tile Layer using Code

VEJS_006_CustomTileLayerOnce you have some custom Map Imagery Tiles generated from using MapCruncher, you can then add them using an instance of the LocationRectTileSource object and adding it to a MapTileLayer on the Map.

To do this we will following the below steps:

  1. Create a MapTileLayer object
  2. Create a LocationRect object that defines the bounding rectangle for our map tile overlay
  3. Create a LocationRectTileSource
    1. Point it to the Uri of our custom Map Imagery Tiles
    2. Set the Minimum and Maximum Zoom Levels (ZoomRange) that the imagery is to be visible within
    3. Set the Bouding Rectangle to the LocationRect object we previously created
  4. Add the LocationRectTileSource to the MapTileLayer’s TileSources collection property
  5. Set the MapTileLayer’s Opacity to the desired value
  6. Add the MapTileLayer to the Children collection of the Map

Here’s some sample code that will add a custom Tile Layer using the imagery that the JavaScript Map Controls SDK uses as an example for this same thing:

// Create a Tile Layer that will display our custom Map Imagery Tiles
var customTileLayer = new MapTileLayer();

// Define the Bounding Rectangle
LocationRect boundingRect = new LocationRect(
    new Location(49, -123), 
    new Location(47, -121)
);

// Create a LocationRectTileSource
LocationRectTileSource customTileSource = new LocationRectTileSource();

// Set the Uri for the custom Map Imagery Tiles
customTileSource.UriFormat = "http://dev.live.com/virtualearth/sdk/layers/lidar/{0}.png";

// Set the Min and Max Zoom Levels that the imagery is to be visible within
customTileSource.ZoomRange = new Range<double>(10, 18);

// The bounding rectangle area that the tile overaly is valid in.
customTileSource.BoundingRectangle = boundingRect;

// Add the Tile Source to the Tile Layer
customTileLayer.TileSources.Add(customTileSource);

// Set the Tile Layer Opacity to a desired value
customTileLayer.Opacity = 0.7;

Map1.Children.Add(customTileLayer);

 

Hide Virtual Earth Imagery From Being Displayed

Sometimes you may want to hide the Virtual Earth Imagery from being displayed altogether. To do this all you need to do is set the Map’s Mode property to a new instance of the MercatorMode object. Doing this allows you to show only your custom map imagery.

Using XAML:

<UserControl x:Class="VirtualEarthSilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:Microsoft.VirtualEarth.MapControl;assembly=Microsoft.VirtualEarth.MapControl"
    xmlns:mc="clr-namespace:Microsoft.VirtualEarth.MapControl.Core;assembly=Microsoft.VirtualEarth.MapControl"
    Width="800" Height="600">
    <Grid x:Name="LayoutRoot" Background="White">
        <m:Map Name="Map1">
            <m:Map.Mode>
                <mc:MercatorMode></mc:MercatorMode>
            </m:Map.Mode>
        </m:Map>
    </Grid>
</UserControl>

 

Using Code:

Map1.Mode = new Microsoft.VirtualEarth.MapControl.Core.MercatorMode();

 

A little more intuitively

Alternatively, you can also create your own EmptyMapMode object that inherits from the MercatorMode object. This way your code will be a little more intuitive to read.

Here’s example of doing this:

<UserControl x:Class="VirtualEarthSilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:Microsoft.VirtualEarth.MapControl;assembly=Microsoft.VirtualEarth.MapControl"
    xmlns:local="clr-namespace:VirtualEarthSilverlightApplication1"
    Width="800" Height="600">
    <Grid x:Name="LayoutRoot" Background="White">
        <m:Map Name="Map1">
            <m:Map.Mode>
                <local:EmptyMapMode></local:EmptyMapMode>
            </m:Map.Mode>
        </m:Map>
    </Grid>
</UserControl>

 

As you notice above, since our custom EmptyMapMode object is contained within the “VirtualEarthSilverlightApplication1” namespace, we need to add that namespace to the XAML file in order to use it.

And, here’s the EmptyMapMode object shown in use above:

public class EmptyMapMode :Microsoft.VirtualEarth.MapControl.Core.MercatorMode
{
}

 

Conclusion

If you are familiar with the JavaScript Map Control you can see that it’s pretty much just as simple to overly your own custom map imagery tiles on the map. One thing to note is that the LocationRectTileSource inherits from the TileSource object; so presumably you could inherit from the TileSource object yourself to create write code that pulls in map imagery from any source using your own custom TileSource object.

Next Tutorial/Article: Overlay OpenStreetMap, OpenAerialMap and Yahoo Maps Imagery using Custom Tile Layers!

Previous Tutorial/Article: Adding Media (Images, Video, etc.) to the Map

blog comments powered by Disqus