Export (0) Print
Expand All

Using the REST and Spatial Data Services

Bing

The Bing Maps REST Services and Bing Spatial Data Services provide functionality such as geocoding, points of interest (POI) searches, and routing that you can add to your Bing Maps WPF Control application. This topic shows how to create a simple application that performs a POI search and displays the results on a map.

The application performs this task by using the following steps:

  1. User inputs a location and distance from that location to search.

  2. Bing Maps REST Services Locations API is used to geocode the location.

  3. Bing Spatial Data Services Query API is used to search for points of interest near the location.

  4. The POI information is displayed and pushpins are added to the map.

The following sections describe parts of the application. The complete code sample is also provided.

User Interface

The following XAML code provides controls for the user to select a POI type, input a location and select a distance to search. It also sets up the framework for displaying the POI information and the map.

<Window x:Class="RESTandWPFwithXML.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
        Title="MainWindow" 
        Height="500" Width="800">
    <Window.Resources>
      <Style x:Key="LabelStyle" TargetType="Label">
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="FontSize" Value="12"/>
      </Style>
        <Style x:Key="BlueLabel" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
            <Setter Property="Foreground" Value="#FF0E6EDC"/>
        </Style>
        <Style   x:Key="RedLabel" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
            <Setter Property="Foreground" Value="#FFA42E2E"/>
        </Style>
        <Style x:Key="AddressStyle" TargetType="Label" >
            <Setter Property="Padding" Value="10px 0 0 0"/>
            <Setter Property="Margin" Value="0 0 0 0"  />
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="115"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Canvas Name="SearchParameters" Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,36,0"> 
            <Label Style="{StaticResource RedLabel}" >Search and Map Entities Near a Location</Label>
            <Label Canvas.Left="0" Canvas.Top="24" Foreground="#FF0E6EDC" AllowDrop="True" FontWeight="Bold" Content="Search for"></Label>
            <Label Style="{StaticResource LabelStyle}" AllowDrop="True" Canvas.Left="0" Canvas.Top="49" 
                   Content="Within" FontWeight="Bold" Foreground="#FF0E6EDC" /> 
            <ComboBox Canvas.Left="50" Name="Distance" Canvas.Top="53" Height="20"   >
                <ComboBoxItem IsSelected="True">1</ComboBoxItem>
                <ComboBoxItem>2</ComboBoxItem>
                <ComboBoxItem>5</ComboBoxItem>
            </ComboBox>
            <TextBox Height="25" Name="SearchNearby" Width="175" Text="Insert location" Canvas.Left="138" Canvas.Top="52"  />
            <Label Style="{StaticResource BlueLabel}" Canvas.Left="90" Canvas.Top="49" Content="km of " Height="28" Name="label1" />
            <Button Click="Search_Click" Width="59" Height="24" Grid.ColumnSpan="2" Margin="0,77,251,39" HorizontalAlignment="Right" Canvas.Left="319" Canvas.Top="-25">Search</Button>
            <ComboBox Name="EntityType" Canvas.Left="73" Canvas.Top="29" Height="21"  Width="117" >
                <ComboBoxItem Tag="7011" IsSelected="True">Hotel</ComboBoxItem>
                <ComboBoxItem Tag="5800">Restaurant</ComboBoxItem>
                <ComboBoxItem Tag="7999">Tourist Attraction</ComboBoxItem>
            </ComboBox>        
        </Canvas>
        
        <StackPanel Grid.Row="1" Grid.Column="0">
            <Label Name="ErrorMessage" Visibility="Collapsed" ></Label>
            <ScrollViewer Name="SearchResults" Visibility="Collapsed" Height="300">
                <StackPanel Name="AddressList" ></StackPanel>
            </ScrollViewer>
        </StackPanel>
        <StackPanel Grid.Row="1"
               Grid.Column="1" >
            <m:Map Visibility="Hidden" x:Name="myMap"
               CredentialsProvider="Insert_Your_Bing_Maps_Key" Height="300" Width="300" />
            <Label Name="myMapLabel" Visibility="Hidden" HorizontalAlignment="Center" >Use + and - to zoom in and out</Label>
        </StackPanel>

    </Grid>
</Window>


Geocoding using the REST Services

The following code-behind method creates a Bing Maps REST Services Find a Location by Query request to geocode (get the latitude and longitude coordinates) of the location requested by the user. The response contains one or more locations. The application chooses the top location for the POI search.

// Geocode an address and return a latitude and longitude
public XmlDocument Geocode(string addressQuery)
{
    //Create REST Services geocode request using Locations API
    string geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" + addressQuery + "?o=xml&key=" + BingMapsKey;


    //Make the request and get the response
    XmlDocument geocodeResponse = GetXmlResponse(geocodeRequest);

    return (geocodeResponse);
}



This code-behind method is used to submit both Bing Maps REST Services and Bing Spatial Data Services requests and retrieve an XML response.

// Submit a REST Services or Spatial Data Services request and return the response
private XmlDocument GetXmlResponse(string requestUrl)
{
    System.Diagnostics.Trace.WriteLine("Request URL (XML): " + requestUrl);
    HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(String.Format("Server error (HTTP {0}: {1}).",
            response.StatusCode,
            response.StatusDescription));
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(response.GetResponseStream());
        return xmlDoc;
    }
}

Searching for POI using the Spatial Data Services

The following code-behind method extracts the top location from the REST Services geocode response, and then uses it to create a Bing Spatial Data Services Query by Area request to search the NAVTEQNA data source for points of interest near the specified location. XPath queries are used to extract information from the responses. To use XPath queries with the Bing Maps REST Services, you must create an XmlNamespaceManager and add the URL for the REST Services data schema.

//Search for POI near a point
private void FindandDisplayNearbyPOI(XmlDocument xmlDoc)
{
    //Get location information from geocode response 

    //Create namespace manager
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
    nsmgr.AddNamespace("rest", "http://schemas.microsoft.com/search/local/ws/rest/v1");

    //Get all locations in the response and then extract the coordinates for the top location
    XmlNodeList locationElements = xmlDoc.SelectNodes("//rest:Location", nsmgr);
    if (locationElements.Count == 0)
    {
        ErrorMessage.Visibility = Visibility.Visible;
        ErrorMessage.Content = "The location you entered could not be geocoded.";
    }
    else
    {
        //Get the geocode points that are used for display (UsageType=Display)
        XmlNodeList displayGeocodePoints =
                locationElements[0].SelectNodes(".//rest:GeocodePoint/rest:UsageType[.='Display']/parent::node()", nsmgr);
        string latitude = displayGeocodePoints[0].SelectSingleNode(".//rest:Latitude", nsmgr).InnerText;
        string longitude = displayGeocodePoints[0].SelectSingleNode(".//rest:Longitude", nsmgr).InnerText;
        ComboBoxItem entityTypeID = (ComboBoxItem)EntityType.SelectedItem;
        ComboBoxItem distance = (ComboBoxItem)Distance.SelectedItem;

        //Create the Bing Spatial Data Services request to get nearby POI
        string findNearbyPOIRequest = "http://spatial.virtualearth.net/REST/v1/data/f22876ec257b474b82fe2ffcb8393150/NavteqNA/NavteqPOIs?spatialfilter=nearby("
        + latitude + "," + longitude + "," + distance.Content + ")"
        + "&$filter=EntityTypeID%20EQ%20'" + entityTypeID.Tag + "'&$select=EntityID,DisplayName,__Distance,Latitude,Longitude,AddressLine,Locality,AdminDistrict,PostalCode&$top=10"
        + "&key=" + BingMapsKey;

        //Submit the Bing Spatial Data Services request and retrieve the response
        XmlDocument nearbyPOI = GetXmlResponse(findNearbyPOIRequest);

        //Center the map at the geocoded location and display the results
        myMap.Center = new Location(Convert.ToDouble(latitude), Convert.ToDouble(longitude));
        myMap.ZoomLevel = 12;
        DisplayResults(nearbyPOI);
        
    }
}

Displaying the POI information

The following code-behind method uses XPath queries to retrieve and display the name and address information for each POI that is returned. In addition, pushpins for each POI are added to the map. The XAML structures that display this content are made visible during this step.

//Show the POI address information and insert pushpins on the map
private void DisplayResults(XmlDocument nearbyPOI)
{
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(nearbyPOI.NameTable);
    nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
    nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
    nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom");

    //Get the the entityID for each POI entity in the response
    XmlNodeList displayNameList = nearbyPOI.SelectNodes("//d:DisplayName", nsmgr);
            
    //Provide entity information and put a pushpin on the map.
    if (displayNameList.Count == 0)
    {
        ErrorMessage.Content = "No results were found for this location.";
        ErrorMessage.Visibility = Visibility.Visible;
    }
    else
    {
        XmlNodeList addressLineList = nearbyPOI.SelectNodes("//d:AddressLine", nsmgr);
        XmlNodeList localityList = nearbyPOI.SelectNodes("//d:Locality", nsmgr);
        XmlNodeList adminDistrictList = nearbyPOI.SelectNodes("//d:AdminDistrict", nsmgr);
        XmlNodeList postalCodeList = nearbyPOI.SelectNodes("//d:PostalCode", nsmgr);
        XmlNodeList latitudeList = nearbyPOI.SelectNodes("//d:Latitude", nsmgr);
        XmlNodeList longitudeList = nearbyPOI.SelectNodes("//d:Longitude", nsmgr);
        for (int i = 0; i < displayNameList.Count; i++)
        {
            AddLabel(AddressList, "[" + Convert.ToString(i + 1) + "] " + displayNameList[i].InnerText);
            AddLabel(AddressList, addressLineList[i].InnerText);
            AddLabel(AddressList, localityList[i].InnerText + ", " + adminDistrictList[i].InnerText);
            AddLabel(AddressList, postalCodeList[i].InnerText);
            AddLabel(AddressList, "");
            AddPushpinToMap(Convert.ToDouble(latitudeList[i].InnerText), Convert.ToDouble(longitudeList[i].InnerText), Convert.ToString(i + 1));
        }
        SearchResults.Visibility = Visibility.Visible;
        myMap.Visibility = Visibility.Visible;
        myMapLabel.Visibility = Visibility.Visible;
        myMap.Focus(); //allows '+' and '-' to zoom the map
    }

}

Complete Code Sample

The following sections contain the complete code sample.

XAML

<Window x:Class="RESTandWPFwithXML.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
        Title="MainWindow" 
        Height="500" Width="800">
    <Window.Resources>
      <Style x:Key="LabelStyle" TargetType="Label">
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="FontSize" Value="12"/>
      </Style>
        <Style x:Key="BlueLabel" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
            <Setter Property="Foreground" Value="#FF0E6EDC"/>
        </Style>
        <Style   x:Key="RedLabel" TargetType="Label" BasedOn="{StaticResource LabelStyle}">
            <Setter Property="Foreground" Value="#FFA42E2E"/>
        </Style>
        <Style x:Key="AddressStyle" TargetType="Label" >
            <Setter Property="Padding" Value="10px 0 0 0"/>
            <Setter Property="Margin" Value="0 0 0 0"  />
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="115"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Canvas Name="SearchParameters" Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,36,0"> 
            <Label Style="{StaticResource RedLabel}" >Search and Map Entities Near a Location</Label>
            <Label Canvas.Left="0" Canvas.Top="24" Foreground="#FF0E6EDC" AllowDrop="True" FontWeight="Bold" Content="Search for"></Label>
            <Label Style="{StaticResource LabelStyle}" AllowDrop="True" Canvas.Left="0" Canvas.Top="49" 
                   Content="Within" FontWeight="Bold" Foreground="#FF0E6EDC" /> 
            <ComboBox Canvas.Left="50" Name="Distance" Canvas.Top="53" Height="20"   >
                <ComboBoxItem IsSelected="True">1</ComboBoxItem>
                <ComboBoxItem>2</ComboBoxItem>
                <ComboBoxItem>5</ComboBoxItem>
            </ComboBox>
            <TextBox Height="25" Name="SearchNearby" Width="175" Text="Insert location" Canvas.Left="138" Canvas.Top="52"  />
            <Label Style="{StaticResource BlueLabel}" Canvas.Left="90" Canvas.Top="49" Content="km of " Height="28" Name="label1" />
            <Button Click="Search_Click" Width="59" Height="24" Grid.ColumnSpan="2" Margin="0,77,251,39" HorizontalAlignment="Right" Canvas.Left="319" Canvas.Top="-25">Search</Button>
            <ComboBox Name="EntityType" Canvas.Left="73" Canvas.Top="29" Height="21"  Width="117" >
                <ComboBoxItem Tag="7011" IsSelected="True">Hotel</ComboBoxItem>
                <ComboBoxItem Tag="5800">Restaurant</ComboBoxItem>
                <ComboBoxItem Tag="7999">Tourist Attraction</ComboBoxItem>
            </ComboBox>        
        </Canvas>
        
        <StackPanel Grid.Row="1" Grid.Column="0">
            <Label Name="ErrorMessage" Visibility="Collapsed" ></Label>
            <ScrollViewer Name="SearchResults" Visibility="Collapsed" Height="300">
                <StackPanel Name="AddressList" ></StackPanel>
            </ScrollViewer>
        </StackPanel>
        <StackPanel Grid.Row="1"
               Grid.Column="1" >
            <m:Map Visibility="Hidden" x:Name="myMap"
               CredentialsProvider="Insert_Your_Bing_Maps_Key" Height="300" Width="300" />
            <Label Name="myMapLabel" Visibility="Hidden" HorizontalAlignment="Center" >Use + and - to zoom in and out</Label>
        </StackPanel>

    </Grid>
</Window>


C# Code-behind

using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Maps.MapControl.WPF;
using Microsoft.Maps.MapControl.WPF.Design;
using System.Xml;
using System.Net;
using System.Xml.XPath;

namespace RESTandWPFwithXML
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        string BingMapsKey = "Insert_Your_Bing_Maps_Key";

        public MainWindow()
        {
            InitializeComponent();
        }



        // Geocode an address and return a latitude and longitude
        public XmlDocument Geocode(string addressQuery)
        {
            //Create REST Services geocode request using Locations API
            string geocodeRequest = "http://dev.virtualearth.net/REST/v1/Locations/" + addressQuery + "?o=xml&key=" + BingMapsKey;

            //Make the request and get the response
            XmlDocument geocodeResponse = GetXmlResponse(geocodeRequest);

            return (geocodeResponse);
        }


        // Submit a REST Services or Spatial Data Services request and return the response
        private XmlDocument GetXmlResponse(string requestUrl)
        {
            System.Diagnostics.Trace.WriteLine("Request URL (XML): " + requestUrl);
            HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                if (response.StatusCode != HttpStatusCode.OK)
                    throw new Exception(String.Format("Server error (HTTP {0}: {1}).",
                    response.StatusCode,
                    response.StatusDescription));
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(response.GetResponseStream());
                return xmlDoc;
            }
        }

        //Search for POI near a point
        private void FindandDisplayNearbyPOI(XmlDocument xmlDoc)
        {
            //Get location information from geocode response 

            //Create namespace manager
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("rest", "http://schemas.microsoft.com/search/local/ws/rest/v1");

            //Get all geocode locations in the response 
            XmlNodeList locationElements = xmlDoc.SelectNodes("//rest:Location", nsmgr);
            if (locationElements.Count == 0)
            {
                ErrorMessage.Visibility = Visibility.Visible;
                ErrorMessage.Content = "The location you entered could not be geocoded.";
            }
            else
            {
                //Get the geocode location points that are used for display (UsageType=Display)
                XmlNodeList displayGeocodePoints =
                        locationElements[0].SelectNodes(".//rest:GeocodePoint/rest:UsageType[.='Display']/parent::node()", nsmgr);
                string latitude = displayGeocodePoints[0].SelectSingleNode(".//rest:Latitude", nsmgr).InnerText;
                string longitude = displayGeocodePoints[0].SelectSingleNode(".//rest:Longitude", nsmgr).InnerText;
                ComboBoxItem entityTypeID = (ComboBoxItem)EntityType.SelectedItem;
                ComboBoxItem distance = (ComboBoxItem)Distance.SelectedItem;

                //Create the Bing Spatial Data Services request to get the user-specified POI entity type near the selected point  
                string findNearbyPOIRequest = "http://spatial.virtualearth.net/REST/v1/data/f22876ec257b474b82fe2ffcb8393150/NavteqNA/NavteqPOIs?spatialfilter=nearby("
                + latitude + "," + longitude + "," + distance.Content + ")"
                + "&$filter=EntityTypeID%20EQ%20'" + entityTypeID.Tag + "'&$select=EntityID,DisplayName,__Distance,Latitude,Longitude,AddressLine,Locality,AdminDistrict,PostalCode&$top=10"
                + "&key=" + BingMapsKey;

                //Submit the Bing Spatial Data Services request and retrieve the response
                XmlDocument nearbyPOI = GetXmlResponse(findNearbyPOIRequest);

                //Center the map at the geocoded location and display the results
                myMap.Center = new Location(Convert.ToDouble(latitude), Convert.ToDouble(longitude));
                myMap.ZoomLevel = 12;
                DisplayResults(nearbyPOI);

            }
        }


        //Add label element to application
        private void AddLabel(Panel parent, string labelString)
        {
            Label dname = new Label();
            dname.Content = labelString;
            dname.Style = (Style)FindResource("AddressStyle");
            parent.Children.Add(dname);
        }

        //Add a pushpin with a label to the map
        private void AddPushpinToMap(double latitude, double longitude, string pinLabel)
        {
            Location location = new Location(latitude, longitude);
            Pushpin pushpin = new Pushpin();
            pushpin.Content = pinLabel;
            pushpin.Location = location;
            myMap.Children.Add(pushpin);
        }

        //Show the POI address information and insert pushpins on the map
        private void DisplayResults(XmlDocument nearbyPOI)
        {
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(nearbyPOI.NameTable);
            nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
            nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
            nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom");

            //Get the the entityID for each POI entity in the response
            XmlNodeList displayNameList = nearbyPOI.SelectNodes("//d:DisplayName", nsmgr);

            //Provide entity information and put a pushpin on the map.
            if (displayNameList.Count == 0)
            {
                ErrorMessage.Content = "No results were found for this location.";
                ErrorMessage.Visibility = Visibility.Visible;
            }
            else
            {
                XmlNodeList addressLineList = nearbyPOI.SelectNodes("//d:AddressLine", nsmgr);
                XmlNodeList localityList = nearbyPOI.SelectNodes("//d:Locality", nsmgr);
                XmlNodeList adminDistrictList = nearbyPOI.SelectNodes("//d:AdminDistrict", nsmgr);
                XmlNodeList postalCodeList = nearbyPOI.SelectNodes("//d:PostalCode", nsmgr);
                XmlNodeList latitudeList = nearbyPOI.SelectNodes("//d:Latitude", nsmgr);
                XmlNodeList longitudeList = nearbyPOI.SelectNodes("//d:Longitude", nsmgr);
                for (int i = 0; i < displayNameList.Count; i++)
                {
                    AddLabel(AddressList, "[" + Convert.ToString(i + 1) + "] " + displayNameList[i].InnerText);
                    AddLabel(AddressList, addressLineList[i].InnerText);
                    AddLabel(AddressList, localityList[i].InnerText + ", " + adminDistrictList[i].InnerText);
                    AddLabel(AddressList, postalCodeList[i].InnerText);
                    AddLabel(AddressList, "");
                    AddPushpinToMap(Convert.ToDouble(latitudeList[i].InnerText), Convert.ToDouble(longitudeList[i].InnerText), Convert.ToString(i + 1));
                }
                SearchResults.Visibility = Visibility.Visible;
                myMap.Visibility = Visibility.Visible;
                myMapLabel.Visibility = Visibility.Visible;
                myMap.Focus(); //allows '+' and '-' to zoom the map
            }

        }

        //Search for POI elements when the Search button is clicked
        private void Search_Click(object sender, RoutedEventArgs e)
        {
            //Clear prior search
            myMap.Visibility = Visibility.Hidden;
            myMapLabel.Visibility = Visibility.Collapsed;
            myMap.Children.Clear();
            SearchResults.Visibility = Visibility.Collapsed;
            AddressList.Children.Clear();
            ErrorMessage.Visibility = Visibility.Collapsed;


            //Get latitude and longitude coordinates for specified location
            XmlDocument searchResponse = Geocode(SearchNearby.Text);

            //Find and display points of interest near the specified location
            FindandDisplayNearbyPOI(searchResponse);
        }


    }
}


Visual Basic Code-behind

Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Maps.MapControl.WPF
Imports Microsoft.Maps.MapControl.WPF.Design
Imports System.Xml
Imports System.Net
Imports System.Xml.XPath

Namespace RESTandWPFwithXML
    ''' <summary>
    ''' Interaction logic for MainWindow.xaml
    ''' </summary>
    Partial Public Class MainWindow
        Inherits Window

        Private BingMapsKey As String = "Insert_Your_Bing_Maps_Key"

        Public Sub New()
            InitializeComponent()
        End Sub



        ' Geocode an address and return a latitude and longitude
        Public Function Geocode(ByVal addressQuery As String) As XmlDocument
            'Create REST Services geocode request using Locations API
            Dim geocodeRequest As String = "http://dev.virtualearth.net/REST/v1/Locations/" & addressQuery & "?o=xml&key=" & BingMapsKey

            'Make the request and get the response
            Dim geocodeResponse As XmlDocument = GetXmlResponse(geocodeRequest)

            Return (geocodeResponse)
        End Function


        ' Submit a REST Services or Spatial Data Services request and return the response
        Private Function GetXmlResponse(ByVal requestUrl As String) As XmlDocument
            System.Diagnostics.Trace.WriteLine("Request URL (XML): " & requestUrl)
            Dim request As HttpWebRequest = TryCast(WebRequest.Create(requestUrl), HttpWebRequest)
            Using response As HttpWebResponse = TryCast(request.GetResponse(), HttpWebResponse)
                If response.StatusCode <> HttpStatusCode.OK Then
                    Throw New Exception(String.Format("Server error (HTTP {0}: {1}).", response.StatusCode, response.StatusDescription))
                End If
                Dim xmlDoc As New XmlDocument()
                xmlDoc.Load(response.GetResponseStream())
                Return xmlDoc
            End Using
        End Function

        'Search for POI near a point
        Private Sub FindandDisplayNearbyPOI(ByVal xmlDoc As XmlDocument)
            'Get location information from geocode response 

            'Create namespace manager
            Dim nsmgr As New XmlNamespaceManager(xmlDoc.NameTable)
            nsmgr.AddNamespace("rest", "http://schemas.microsoft.com/search/local/ws/rest/v1")

            'Get all locations in the response and then extract the coordinates for the top location
            Dim locationElements As XmlNodeList = xmlDoc.SelectNodes("//rest:Location", nsmgr)
            If locationElements.Count = 0 Then
                ErrorMessage.Visibility = Visibility.Visible
                ErrorMessage.Content = "The location you entered could not be geocoded."
            Else
                'Get the geocode points that are used for display (UsageType=Display)
                Dim displayGeocodePoints As XmlNodeList = locationElements(0).SelectNodes(".//rest:GeocodePoint/rest:UsageType[.='Display']/parent::node()", nsmgr)
                Dim latitude As String = displayGeocodePoints(0).SelectSingleNode(".//rest:Latitude", nsmgr).InnerText
                Dim longitude As String = displayGeocodePoints(0).SelectSingleNode(".//rest:Longitude", nsmgr).InnerText
                Dim entityTypeID As ComboBoxItem = CType(EntityType.SelectedItem, ComboBoxItem)
                Dim distance As ComboBoxItem = CType(Distance.SelectedItem, ComboBoxItem)

                'Create the Bing Spatial Data Services request to get nearby POI
                Dim findNearbyPOIRequest As String = "http://spatial.virtualearth.net/REST/v1/data/f22876ec257b474b82fe2ffcb8393150/NavteqNA/NavteqPOIs?spatialfilter=nearby(" & latitude & "," & longitude & "," & distance.Content & ")" & "&$filter=EntityTypeID%20EQ%20'" & entityTypeID.Tag & "'&$select=EntityID,DisplayName,__Distance,Latitude,Longitude,AddressLine,Locality,AdminDistrict,PostalCode&$top=10" & "&key=" & BingMapsKey

                'Submit the Bing Spatial Data Services request and retrieve the response
                Dim nearbyPOI As XmlDocument = GetXmlResponse(findNearbyPOIRequest)

                'Center the map at the geocoded location and display the results
                myMap.Center = New Location(Convert.ToDouble(latitude), Convert.ToDouble(longitude))
                myMap.ZoomLevel = 12
                DisplayResults(nearbyPOI)

            End If
        End Sub

        'Add label element to application
        Private Sub AddLabel(ByVal parent As Panel, ByVal labelString As String)
            Dim dname As New Label()
            dname.Content = labelString
            dname.Style = CType(FindResource("AddressStyle"), Style)
            parent.Children.Add(dname)
        End Sub

        'Add a pushpin with a label to the map
        Private Sub AddPushpinToMap(ByVal latitude As Double, ByVal longitude As Double, ByVal pinLabel As String)
            Dim location As New Location(latitude, longitude)
            Dim pushpin As New Pushpin()
            pushpin.Content = pinLabel
            pushpin.Location = location
            myMap.Children.Add(pushpin)
        End Sub

        'Show the POI address information and insert pushpins on the map
        Private Sub DisplayResults(ByVal nearbyPOI As XmlDocument)
            Dim nsmgr As New XmlNamespaceManager(nearbyPOI.NameTable)
            nsmgr.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices")
            nsmgr.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")
            nsmgr.AddNamespace("a", "http://www.w3.org/2005/Atom")

            'Get the the entityID for each POI entity in the response
            Dim displayNameList As XmlNodeList = nearbyPOI.SelectNodes("//d:DisplayName", nsmgr)

            'Provide entity information and put a pushpin on the map.
            If displayNameList.Count = 0 Then
                ErrorMessage.Content = "No results were found for this location."
                ErrorMessage.Visibility = Visibility.Visible
            Else
                Dim addressLineList As XmlNodeList = nearbyPOI.SelectNodes("//d:AddressLine", nsmgr)
                Dim localityList As XmlNodeList = nearbyPOI.SelectNodes("//d:Locality", nsmgr)
                Dim adminDistrictList As XmlNodeList = nearbyPOI.SelectNodes("//d:AdminDistrict", nsmgr)
                Dim postalCodeList As XmlNodeList = nearbyPOI.SelectNodes("//d:PostalCode", nsmgr)
                Dim latitudeList As XmlNodeList = nearbyPOI.SelectNodes("//d:Latitude", nsmgr)
                Dim longitudeList As XmlNodeList = nearbyPOI.SelectNodes("//d:Longitude", nsmgr)
                For i As Integer = 0 To displayNameList.Count - 1
                    AddLabel(AddressList, "[" & Convert.ToString(i + 1) & "] " & displayNameList(i).InnerText)
                    AddLabel(AddressList, addressLineList(i).InnerText)
                    AddLabel(AddressList, localityList(i).InnerText & ", " & adminDistrictList(i).InnerText)
                    AddLabel(AddressList, postalCodeList(i).InnerText)
                    AddLabel(AddressList, "")
                    AddPushpinToMap(Convert.ToDouble(latitudeList(i).InnerText), Convert.ToDouble(longitudeList(i).InnerText), Convert.ToString(i + 1))
                Next i
                SearchResults.Visibility = Visibility.Visible
                myMap.Visibility = Visibility.Visible
                myMapLabel.Visibility = Visibility.Visible
                myMap.Focus() 'allows '+' and '-' to zoom the map
            End If

        End Sub


        'Search for POI elements when the Search button is clicked
        Private Sub Search_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            'Clear prior search
            myMap.Visibility = Visibility.Hidden
            myMapLabel.Visibility = Visibility.Collapsed
            myMap.Children.Clear()
            SearchResults.Visibility = Visibility.Collapsed
            AddressList.Children.Clear()
            ErrorMessage.Visibility = Visibility.Collapsed


            'Get latitude and longitude coordinates for specified location
            Dim searchResponse As XmlDocument = Geocode(SearchNearby.Text)

            'Find and display points of interest near the specified location
            FindandDisplayNearbyPOI(searchResponse)
        End Sub


    End Class



Show:
© 2014 Microsoft