Showing Open Source maps on Windows Phone 7 with the Bing Maps Control

2 minute read

My previous post, which caused a bit of a stirrup and got me over 1000 page hits on that one page alone in less than 46 hours, led to the question if I could provide an example of how to use data from Open Source map servers on the web in Bing Maps. This is more useful than Google Maps, since Google’s TOS most likely does not allow accessing their data they way I showed, and an application doing so violates section 3.1 of the Windows Phone 7 Application Certification Requirements, which clearly state that allowed content includes “Copyrighted content that is used with permission”, which I obviously do not have and most likely never will. Unless Google wants to code me a Windows Phone 7 app for them. Hello? Anyone reading along there at Mountain View? ;-)

So anyway, as long as my personal Google Maps for Windows Phone 7 is not going to hit the Marketplace, the Bing Maps MercatorMode can very well be used to show other tile maps, and by popular request I show you how to use data from Mapnik and Osmarender:

MapnikOsmarender

The possibility should come as no surprise, since I showed something like this earlier, only then with a plain ole’ MultiScaleImage. All you need to do is, once again, write a class again that descends from Microsoft.Phone.Controls.Maps.TileSource and overrides

Uri GetUri(int x, int y, int zoomLevel)

like I showed in my previous post. And these are even simpler than the Google Maps tilesource. First, Mapnik:

using System;

namespace LocalJoost.TileSource
{
  public class MapnikTileSource : Microsoft.Phone.Controls.Maps.TileSource
  {
    public MapnikTileSource()
    {
      UriFormat = "http://{0}.tile.openstreetmap.org/{1}/{2}/{3}.png";
      _rand = new Random();
    }

    private readonly Random _rand;
    private readonly static string[] TilePathPrefixes =
        new[] { "a", "b", "c" };

    private string Server
    {
      get
      {
        return TilePathPrefixes[_rand.Next(3)];
      }
    }
   
    public override Uri GetUri(int x, int y, int zoomLevel)
    {
      if (zoomLevel > 0)
      {
        var url = string.Format(UriFormat, Server, zoomLevel, x, y);
        return new Uri(url);
      }
      return null;
    }
  }
}

and second, Osmarender

using System;

namespace LocalJoost.TileSource
{
  public class OsmaRenderTileSource : Microsoft.Phone.Controls.Maps.TileSource
  {
    public OsmaRenderTileSource()
    {
      UriFormat = "http://{0}.tah.openstreetmap.org/Tiles/tile/{1}/{2}/{3}.png";
      _rand = new Random();
    }

    private readonly Random _rand;
    private readonly static string[] TilePathPrefixes =
        new[] { "a", "b", "c", "d", "e", "f" };

    private string Server
    {
      get
      {
        return TilePathPrefixes[_rand.Next(6)];
       }
    }

    public override Uri GetUri(int x, int y, int zoomLevel)
    {
      if (zoomLevel > 0)
      {
        var url = string.Format(UriFormat, Server, zoomLevel, x, y);
        return new Uri(url);
      }
      return null;
    }
  }
}

As you see, no rocket science. How to use this classes in XAML is explained in my previous post, and I am not going to repeat that here..

The odd thing is that the Bing Maps logo stays visible, although no Bing Maps data is being used. Notice that the open source maps are displayed in design mode too. So, use any tile server out there that you can legally access and have fun mapping…. although I must admit that is most likely interesting for hardcore GIS fans only, since both servers are considerably slower than Bing – especially OsmaRender, which does some odd things cutting the Netherlands in half, as you see. But still, if not anything else, it shows off the power and versatility of the Bing Maps control pretty well.

For the lazy people, a complete solution – including the Google stuff – can be downloaded here.