Using Bing Maps Imagery, Geocode, and Route services

Bing Maps hosts rich map imagery and data as well as robust search, location, and routing services. The ArcGIS API for Windows Phone integrates Bing Maps imagery, geocoding, and routing services in the ESRI.ArcGIS.Client.Bing.dll assembly. Once you have a Bing Maps key, you can begin working with Bing Maps services in your application. See the Bing Maps samples in the Interactive SDK samples for code and implementation techniques presented here.

Working with the Bing Maps Imagery service

The Bing Maps Imagery service provides access to cached tiles of map data available in the Web Mercator projection (WKID: 102113). The ArcGIS API for Windows Phone includes Bing Maps Imagery service support in a TileLayer component, which can be added to the Layers collection of a Map. The following example shows the XAML for a simple Map that contains a single Bing Maps TileLayer. See the Creating a map topic for information on how to create a map and reference its layer collection. The Bing Maps TileLayer class is included in the ESRI.ArcGIS.Client.Bing.dll in the ESRI.ArcGIS.Client.Bing namespace. You also need to get a Bing Maps key.

NoteNote:

You need references to the ESRI.ArcGIS.Client and ESRI.ArcGIS.Client.Bing assemblies to use the code in this topic. In addition, you need to include XML namespace references for both the ESRI.ArcGIS.Client namespace in the ESRI.ArcGIS.Client assembly and the ESRI.ArcGIS.Client.Bing namespace in the ESRI.ArcGIS.Client.Bing assembly as attributes on the phone:PhoneApplicationPage element.

<esri:Map x:Name="MyMap">
    <esri:Map.Layers>
        <bing:TileLayer ID="BingLayerRoad" LayerStyle="Road" 
            ServerType="Production"
            Token="this-is-my-BingMapsKey" />               
    </esri:Map.Layers>
</esri:Map>
CautionCaution:

You need to provide your Bing Maps key in the Token attribute—the code will not run successfully with the placeholder key used.

The ID attribute must be set to a unique value and will be used to access the layer in the code-behind. The LayerStyle attribute can be set to one of three options: Road, Aerial, and AerialWithLabels. The ServerType attributes defines your access license to Bing Maps services: Staging or Production. Bing Maps keys only work with Production services, so the Staging option is only of interest if you are still using a Bing Maps token.

Working with the Bing Maps Geocode service

The Bing Maps Geocode service provides worldwide coverage for matching addresses, places, and landmarks to locations on the globe, as well as returning information for a specified location. Locations are returned in geographic coordinate system (GCS) World Geodetic System 1984 ([WGS84] WKID: 4326).

CautionCaution:

Microsoft's Bing Maps API Terms of Use specify that all Bing Maps Geocode service results must be displayed on a Bing Maps basemap.

The ArcGIS API for Windows Phone includes a Geocoder class to manage interaction with the Bing Maps Geocode service. The class is not represented in XAML. Instead, it is always created and used in the code-behind. The following code shows how to create a Geocoder, specify the Bing Maps key with the constructor, and call the appropriate method for the operation: Geocode or ReverseGeocode. The event handler to process results from either operation is defined as a method parameter (in the following example, MyGeocode_Complete and MyReverseGeocode_Complete, respectively).

NoteNote:

You will need using statements for the ESRI.ArcGIS.Client.Bing and ESRI.ArcGIS.Client.Bing.GeocodeService namespaces to use the code in the following Geocode service examples.

Geocoder geocoder = new Geocoder("this-is-my-BingMapsKey");
geocoder.ServerType = ServerType.Production;

// Geocode. 
geocoder.Geocode(MyAddress, Geocode_Complete);

// Reverse geocode.
geocoder.ReverseGeocode(MyMapPoint, ReverseGeocode_Complete);

Geocoding

Input to a geocode operation is comma delimited and can contain a street address (for example, 901 N 1st Ave, Tucson, AZ), place name, (for example, Annapolis, MD), or a landmark name (for example, Prospect Park). All inputs are used to determine the location with the best match. For example, Big Ben returns a location in London, UK, whereas Big Ben, US returns locations in the United States that contain Big Ben in their name, such as Big Bend Park, OR. Bing Maps geocode operations use a confidence value to determine how sure the service is in the results returned to the client. The Geocoder uses the highest minimum confidence value permitted by the Bing Maps Geocode service, which means only the most accurate matches are returned.

Results from a geocode operation are returned in a GeocodeResponse, a class defined by the Bing Maps Web Services SDK. Each response may contain one or more GeocodeResult instances, one for each match. The GeocodeResult contains the name or address of the match location, a bounding box, administrative type description, and so on. You can iterate through each GeocodeResult instance to create graphics for display in an ArcGIS API for Windows Phone Map control. Locations are returned in the GCS WGS84 (WKID: 4326).

TipTip:

A Transform utility class is included with the Bing Maps implementation of the ArcGIS API for Windows Phone to convert between geographic WGS84 (WKID: 4326) and Web Mercator (WKID: 102113). The conversion is managed completely on the client. To transform geometry to or from a different coordinate system, use another resource (for example, use an ArcGIS Server Geometry service via a Geometry task).

The following code example demonstrates how to add results to a graphics layer displayed on a Bing Maps basemap:

private void Geocode_Complete(object sender, GeocodeCompletedEventArgs args)
{
    GeocodeResponse geocodeResponse = args.Result;

    if (geocodeResponse.Results.Count == 0)
        return;

    GraphicsLayer graphicsLayer = 
        MyMap.Layers["GeocodeResultsGraphicsLayer"] as GraphicsLayer;

    foreach (GeocodeResult geocodeResult in geocodeResponse.Results)
    {
        ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic();

        // Optional: transform point from geographic to the Web Mercator  
        //           projection the current map uses.
        MapPoint geographicPoint = 
            new MapPoint(geocodeResult.Locations[0].Longitude, 
                         geocodeResult.Locations[0].Latitude,
                         new SpatialReference(4326));

        graphic.Geometry = ESRI.ArcGIS.Client.Bing.Transform.GeographicToWebMercator(geographicPoint);
        graphic.Symbol = LayoutRoot.Resources["CircleSymbol"] as Symbol;
        graphic.Attributes.Add("DisplayName", geocodeResult.DisplayName);

        graphicsLayer.Graphics.Add(graphic);
    }
}
NoteNote:

You need the following to use the preceding code:

  • Using statements for the ESRI.ArcGIS.Client.Geometry and ESRI.ArcGIS.Client.Symbols namespaces.
  • A SimpleMarkerSymbol with the key CircleSymbol in your XAML. See Symbols and renderers for details on adding a symbol.
  • A GraphicsLayer with ID GeocodeResultsGraphicsLayer. See Creating a graphics layer.

Reverse geocoding

Input to a reverse geocode operation is a map location used to match known geographic entities. Currently, only street addresses are returned. With regard to the Geocoder class, the location is a MapPoint with a spatial reference in geographic WGS84 (WKID: 4326) or Web Mercator (WKID: 102113).

Results from a reverse geocode operation are returned in a GeocodeResponse, a class defined by the Bing Maps Web Services SDK. Each response may contain one or more GeocodeResult instances, one for each match. In most cases, you'll be interested in the closest street address and actual match location, both available in the GeocodeResult. The following code example demonstrates how to retrieve the street address (display name) of the first match result and show it in a message box:

private void ReverseGeocode_Complete(object sender, ReverseGeocodeCompletedEventArgs args)
{
    string response;
    if (args.Result.Results.Count == 0)
        response = "No results found";
    else
    {
        GeocodeResult result = args.Result.Results[0];
        response = result.DisplayName;
    }
    MessageBox.Show(response);
}

Working with the Bing Maps Route service

The Bing Maps Route service provides route calculation and itinerary creation between specified locations. Routes are returned as a set of coordinates in geographic WGS84 (WKID: 4326). The ArcGIS API for Windows Phone includes a Routing class to manage interaction with the Bing Maps Route service. As with the Geocoder, the class is not represented in XAML, but rather is always created and used in the code-behind.

Routing

Input to a routing operation consists of the stops to visit. Each stop must be specified as a MapPoint with a SpatialReference of Web Mercator (WKID: 102113) or WGS84 (WKID: 4326), and included in a collection that implements IEnumerable (for example, a List). The route returned passes through stops in the specified order. Furthermore, the route service offers options for optimizing by travel time or distance, accounting for traffic, and getting driving or walking directions. These options are made available as properties of the Routing class.

The following code shows how to create a Routing instance, specify the Bing Maps key with the constructor, specify routing options, and execute the operation. The event handler to process results is defined as a method parameter (in the following example, MyRoute_Complete).

// Instantiate Routing class and specify server type (production for Bing Maps keys).
Routing routing = new Routing("this-is-my-BingMapsKey");
routing.ServerType = ServerType.Production;

// Set routing options.
routing.Optimization = RouteOptimization.MinimizeTime;
routing.TrafficUsage = TrafficUsage.None;
routing.TravelMode = TravelMode.Driving;

// Execute routing operation.
routing.Route(WayPoints, Route_Complete);
NoteNote:

You need the following to use the preceding code:

  • Using statements for the ESRI.ArcGIS.Client.Bing and ESRI.ArcGIS.Client.Bing.RouteService namespaces.
  • A defined a list of MapPoints, named WayPoints.
  • A valid Bing Maps key. See Getting a Bing Maps key.
  • A Route_Complete event handler, as shown in the following example.

Results from a route operation are returned in a RouteResponse, which is a class defined by the Bing Maps Web Services SDK. Each response contains one RouteResult instance. The RouteResult contains the coordinates of the points along the calculated route in a RoutePath, the route's distance and travel time in a RouteSummary, and the description, distance, and travel time for each leg of the route in an array of RouteLegs. To display the route in an ArcGIS API for Windows Phone Map control, you can iterate through each point of the RoutePath instance to create a Polyline geometry, which can then be wrapped in a Graphic. Locations along the route are returned in the GCS WGS84 (WKID: 4326).

TipTip:

A Transform utility class is included with the Bing Maps implementation of the ArcGIS API for Windows Phone to convert between geographic WGS84 (WKID: 4326) and Web Mercator (WKID: 102113). The conversion is managed completely on the client. To transform geometry to or from a different coordinate system, use another resource (for example, use an ArcGIS Server Geometry service via a Geometry task).

The following code example demonstrates how to add a route to a graphics layer displayed on a Bing Maps basemap:

private void Route_Complete(object sender, CalculateRouteCompletedEventArgs args)
{
    // Get the coordinates along the route.
    RoutePath routePath = args.Result.Result.RoutePath;

    // Instantiate a Polyline to hold the route geometry.
    ESRI.ArcGIS.Client.Geometry.Polyline line = 
        new ESRI.ArcGIS.Client.Geometry.Polyline();
    line.Paths.Add(new ESRI.ArcGIS.Client.Geometry.PointCollection());

    // Traverse route coordinate pairs.
    foreach (ESRI.ArcGIS.Client.Bing.RouteService.Location location in routePath.Points)
    {
        // Create a point from the coordinates.
        MapPoint routePoint = new MapPoint(location.Longitude, location.Latitude);
        // Transform the point to Web Mercator and add to the route polyline.
        // The transformation only applies when using a Web Mercator basemap.
        line.Paths[0].Add(ESRI.ArcGIS.Client.Bing.Transform.GeographicToWebMercator(routePoint));
    }

    // Wrap the route in a graphic and add it to a graphics layer.
    Graphic graphic = new Graphic()
    {
        Geometry = line,
        Symbol = LayoutRoot.Resources["RoutePathSymbol"] as Symbol
    };
    GraphicsLayer graphicsLayer = MyMap.Layers["RouteResultsGraphicsLayer"] as GraphicsLayer;
    graphicsLayer.Graphics.Add(graphic);
}
NoteNote:

You need the following to use the preceding code:

  • Using statements for the ESRI.ArcGIS.Client, ESRI.ArcGIS.Client.Geometry, ESRI.ArcGIS.Client.Bing.RouteService, and ESRI.ArcGIS.Client.Symbols namespaces.
  • A SimpleLineSymbol with the key RoutePathSymbol in your XAML. See Symbols and renderers for details on adding a symbol.
  • A GraphicsLayer with an ID of RouteResultsGraphicsLayer. See Creating a graphics layer.

1/23/2012