Silverlight MapControl CTP and Custom Tile Sources


Silverlight Map Conntrol
Fig 1 – Example of Silverlight Map Control. Yahoo base tiles with GeoWebCache overlay

Microsoft just released their new Silverlight Virtual Earth MapControl CTP. This isn’t a release version yet, still just a CTP for developers to play with. It is a beautiful map control, and if you can log on to sharepoint you can see Microsoft’s interactive SDK demo here:

https://sharepoint.connect.microsoft.com/silverlightmapcontrolctp/iSDK/default.htm

Silverlight Map Conntrol Interactive page
Fig 2 – Screen shot of the Silverlight Map Control CTP interactive SDK demo

This control takes advantage of the DeepZoom type of tile interface for very smooth pan and zoom navigation with an addictive elastic feel. Here is an example: Changing View Settings. The CTP version doesn’t handle this as smoothly as the examples at this Live Lab example. If you find this interesting, you can read more about change of view handling algorithms described in this paper on multiscale viewing.

Map navigation is very much like the DeepEarth codeplex project I wrote about recently: MapTiles, Pyramids, and DeepEarth Only Microsoft’s new VE Map Control incorporates a lot more features. For example you can add a video MediaElement directly onto a map lat,long location like this:

Silverlight Map Conntrol Video
Fig 3 – Silverlight VE Map Control CTP with Video overlay

Lots of similar whizz bang features are demonstrated in the interactive SDK demo. However, I’m more interested in seeing how I can use this for a small experimental project. In this project I want to demonstrate use of a base map with overlay tracks from vehicles. The track data is currently served from a PostgresSQL/PostGIS table which would be a bother to access through Linq or an .asmx. I wanted something quick and easy.

First off I noticed that the interactive demo showed some examples of tile overlays. This is interesting and got me looking into what other tile sources might be used. Chris Pietschmann has a set of articles that explored just the thing here: http://pietschsoft.com/post/2009/03/Virtual-Earth-Silverlight-Overlay-OpenStreetMap2c-OpenAerialMap-and-Yahoo-Map-Imagery-using-Custom-Tile-Layers!.aspx

Chris provides some templates for adding base map tiles from OSM, Yahoo, and OpenAerial. It is really quite simple. First in the code behind you simply add a class to wrap a tile source Uri builder:

    public class OpenStreetMapTileSource : Microsoft.VirtualEarth.MapControl.TileSource
    {
     public OpenStreetMapTileSource()
       : base(“http://tile.openstreetmap.org/{2}/{0}/{1}.png”)
     {
     }

     public override Uri GetUri(int x, int y, int zoomLevel)
     {
      return new Uri(String.Format(this.UriFormat, x, y, zoomLevel));
     }
   }

In the GetUri override you are just taking the tileX, tileY, and zoomLevel furnished by the MapControl and substituting them into the url string used to populate your MapControl Layer. Then when this TileSource is added to the MapControl as a Child tile layer source it will use your GetUri to build the required tile urls:

  <m:Map Name=”MainMap”>
    <!– Set the MapMode to show no VE base tiles –>
    <m:Map.Mode>
      <mc:MercatorMode />
    </m:Map.Mode>

    <m:Map.Children>
      <m:MapTileLayer>
        <m:MapTileLayer.TileSources>
          <local:OpenStreetMapTileSource></local:OpenStreetMapTileSource>
        </m:MapTileLayer.TileSources>
      </m:MapTileLayer>
      <m:MapTileLayer>
        <m:MapTileLayer.TileSources>
          <local:ExampleOutputTileSource></local:ExampleOutputTileSource>
        </m:MapTileLayer.TileSources>
      </m:MapTileLayer>
    </m:Map.Children>
  </m:Map>

Not a lot of work here. However, I wanted to extend this idea to include a tile source from my PostGIS DB. The simplest aproach was to use Geoserver, which incorporates GeoWebCache. GeoWebCache is a tile caching tool that first builds, and then saves tiles as users grab them. What I needed was a way to setup my tilesource to point at a GeoWebCache service for the PostGIS vehicle track data.

GeoWebCache services are all readily available for use once I added a DataStore and FeatureType for my PostGIS track table. Remember to check the ‘enable cache’ checkbox and add some ‘cache time’ before submitting a FeatureType. Geoserver also adds a seed option to prebuild all of the tiles for a selected FeatureType. The resulting gwc cache is a subdirectory tile scheme located in the geoserver data directory: C:\geoserver-data\gwc\geo_exacteroutput\EPSG_4326_09\02_09\0070_0312.png

Geoserver 1.72 installs with a GeoWebCache Service for virutal earth, /gwc/service/ve. In order to use this service I needed to furnish a quadkey. Quadkeys are interesting numbers that efficiently encode zoomLevel, tilex, and tiley position into a single number. Micrsoft MSDN has a useful article and sample code – example of calculating VE quadkeys. This is similar to the map tile service over at google, only their quadkey uses letters instead of numbers to encode the quadkey source tile. http://kh.google.com/kh?v=3&t=trtsqtqsqqqt

I used Microsoft’s example code to calculate quadkeys from the tileX, tileY, and zoomLevels kindly furnished by the MapControl resulting in this TileSource class:

  public class ExampleOutputTileSource : Microsoft.VirtualEarth.MapControl.TileSource
  {
    public ExampleOutputTileSource()
      : base(“http://localhost:80/geoserver72/gwc/service/ve?quadkey={0}&format=image/png&transparent=true&layers=geo:exampleoutput”)
    {
    }

    public override Uri GetUri(int tileX, int tileY, int levelOfDetail)
    {
     StringBuilder quadKey = new StringBuilder();
      for (int i = levelOfDetail; i > 0; i–)
      {
        char digit = ’0′;
        int mask = 1 << (i – 1);
        if ((tileX & mask) != 0)
        {
          digit++;
        }
        if ((tileY & mask) != 0)
        {
          digit++;
          digit++;
        }
        quadKey.Append(digit);
      }
      return new Uri(String.Format(this.UriFormat, quadKey));
    }
  }

The GetUri override provides urls that look like this:

http://localhost:80/geoserver72/gwc/service/ve?quadkey=0223000332&format=image/png&layers=geo:exampleoutput

Plugging this into a browser gets me a tile of the data from my PostGIS table.

After recieving a helpful hint from Arne over on the GeoWebCache mailing list, I was aso able to use the GeoWebCache service for google maps named ‘gmaps.’ The gmaps service doesn’t need a quadkey, and the GetUri is consequently a bit simpler:

  public class exampleOutputTileSource : Microsoft.VirtualEarth.MapControl.TileSource
  {
    public ExacterOutputTileSource()
     : base(“http://localhost/geoserver72/gwc/service/gmaps?layers=geo:exampleoutput&zoom={2}&x={0}&y={1}”)
   {
   }

   public override Uri GetUri(int x, int y, int zoomLevel)
   {
     return new Uri(String.Format(this.UriFormat, x, y, zoomLevel));
   }
  }

Summary:

Silverlight VE Map Control is easy to use and has a lot of features that developers want to see, however, one of the issues that is still unclear is the licensing. Tile navigation consumes tons of tiles and the transaction costs can pile up quickly with this kind of interface. There are some noises that the release version will come with a different approach to license pricing.

One interesting item to come out of my experiments is the realization that VE tiles aren’t required to use the viewing features of this control. By watching the http calls in Fiddler you can see the calls to ve tiles are eliminated by setting Map Mode to an empty MercatorMode. This means that transaction costs can be eliminated or at least reduced by using the VE MapControl with a different background source such as Open Street Map or Open Aerial. Routing and geocoding services will still require VE transactions, but far fewer than the tiles. If the USGS, JPL, and NOAA start furnishing tile pyramids for their data we might see lots of alternative tile backgrounds. Often clients want to use their own higher resolution or more specialized accurate base. Using Custom Tile sources, VE Map Control is able to meet this need.

Comments are closed.