This project has moved. For the latest updates, please go here.

Using Bing/Google Static Maps API

Aug 1, 2013 at 3:00 AM
I'm interested in using the XAML Map Control in our application, but we'd like to use Google/Bing maps legally, which seems to require the use of their static APIs. Is there a way to use them with your control?

Thanks,
Mike
Coordinator
Aug 1, 2013 at 6:30 AM
I'm afraid the answer is no. Although technically possible, both providers disallow direct access to their map tile servers.
Aug 1, 2013 at 6:00 PM
After doing some research, I've found that Bing provides an API for retrieving the tile url if you give an API key. I haven't found anything equivalent for Google, and they have stated that they have no interest in providing a legit way of accessing their tile servers.

Here's the REST API call for retrieving the current url. According to the documentation, you're supposed to call it each time you load your application or when you switch map types.

http://dev.virtualearth.net/REST/V1/Imagery/Metadata/Aerial?output=xml&key=[API key here]

The only thing I had to do is modify the placeholders for quadkey and tile server subdomain. It'd be great if this could be provided as an option in XAMLMapControl.
Coordinator
Aug 2, 2013 at 7:22 AM
Edited Aug 2, 2013 at 3:31 PM
Could you please provide a link to the documentation?

When I execute the above web request with my Bing Maps API key, I do indeed get a proper image URL. However, the Copyright disclaimer in the response message says
Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.
Looks like something that may not be used without express written permission.
Aug 2, 2013 at 6:01 PM
I found it at http://msdn.microsoft.com/en-us/library/ff701716.aspx. It's a part of the Bing Maps REST API. As far as I can tell, every call into that API has that copyright notice on it. Most likely I'll have to enter into an agreement with Microsoft to use these APIs after the evaluation period according to the TOS at http://www.microsoft.com/maps/product/terms.html.
Coordinator
Aug 2, 2013 at 7:02 PM
Edited Aug 3, 2013 at 9:04 AM
Mike, what about having a local derived TileLayer class in your application that does everything you need. You may start with this:
public class BingMapsTileLayer : TileLayer
{
    public enum MapMode
    {
        Road, Aerial, AerialWithLabels
    }

    private string uriFormat;

    public BingMapsTileLayer()
    {
        TileSource = new TileSource();
        MinZoomLevel = 1;
        MaxZoomLevel = 21;
        Culture = CultureInfo.CurrentCulture.Name;
    }

    public MapMode Mode { get; set; }
    public string Culture { get; set; }
    public string ApiKey { get; set; }

    protected override void UpdateTiles(int zoomLevel, Int32Rect grid)
    {
        if (uriFormat == null && !string.IsNullOrWhiteSpace(ApiKey))
        {
            var uri = string.Format(
                "http://dev.virtualearth.net/REST/V1/Imagery/Metadata/{0}?output=xml&key={1}",
                Mode, ApiKey);

            try
            {
                var request = (HttpWebRequest)WebRequest.Create(uri);

                using (var response = (HttpWebResponse)request.GetResponse())
                using (var responseStream = response.GetResponseStream())
                using (var xmlReader = new XmlTextReader(responseStream))
                {
                    xmlReader.ReadToFollowing("ImageUrl");

                    uriFormat = xmlReader.ReadElementContentAsString()
                        .Replace("{subdomain}", "t{i}")
                        .Replace("{quadkey}", "{q}")
                        .Replace("{culture}", Culture);

                    TileSource.UriFormat = uriFormat;
                }
            }
            catch (Exception ex)
            {
                Trace.TraceWarning("Requesting {0} failed: {1}", uri, ex.Message);
            }
        }

        base.UpdateTiles(zoomLevel, grid);
    }

    protected override void ClearTiles()
    {
        base.ClearTiles();
        uriFormat = null;
    }
}
It does not yet handle the <ImageUrlSubdomains> part of the response and simply assumes that it's always t0 to t3.

Use it in XAML like this:
<local:BingMapsTileLayer
    SourceName="Bing Maps"
    Description="Bing Maps - © {y} Microsoft Corporation"
    Mode="Road" ApiKey="..."/>
<local:BingMapsTileLayer
    SourceName="Bing Images"
    Description="Bing Maps - © {y} Microsoft Corporation"
    Background="Black" Foreground="White"
    Mode="Aerial" ApiKey="..."/>
<local:BingMapsTileLayer
    SourceName="Bing Hybrid"
    Description="Bing Maps - © {y} Microsoft Corporation"
    Background="Black" Foreground="White"
    Mode="AerialWithLabels" ApiKey="..."/>
Sep 18, 2014 at 12:46 PM
I can shed some light on this topic. Bing Maps does allow the tiles to be accessed in custom applications like this. However there is a specific process that needs to be done. Instead of hardcoding tile URL's which will break over time as the URL's are regularly changed, you have to call the imagery metadata REST service as others have mentioned. This should be done either when the app loads or when the user presses the button to display a Bing Maps tile layer for the first time. This call only needs to be done once per application load, per layer. That way if when running the app once you flip back an fourth between layers a bunch of time you only generate a limited number of transactions against the services. Accessing the tiles in this way is allowed by Bing Maps (I'm a Program Manager on the Bing Maps Customer Advisory Team).

Google Maps does not allow access to their tiles outside of their map controls.
Marked as answer by ClemensF on 10/16/2014 at 8:03 AM
Coordinator
Sep 20, 2014 at 11:06 AM
Edited Sep 20, 2014 at 1:11 PM
Thanks rbrundritt for pointing that out. I'll think about adding a special Bing Maps TileLayer as shown above to the Map Control Library.

However, the imagery metadata response still contains the copyright notice
Copyright © 2014 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.
which makes me think that although you say that "Bing Maps does allow the tiles to be accessed in custom applications" you still need express written permission from Microsoft Corporation to actually do that.

Or does the successful acquisition of a Bing Maps API Key somehow include this express permission?