在从';GeoCodeService';在Windows Phone 7.1应用程序中使用Bing地图

本文关键字:地图 应用程序 Bing Phone GeoCodeService Windows 在从 | 更新日期: 2023-09-27 18:24:55

我正在开发一个windows phone应用程序,我需要在其中显示定位两个不同位置的地图,并显示这两个位置之间的路线和方向。我从json Web服务中获得TO和FROM地址行,我需要使用它向"GeoCodeService"发送位置请求。

为了实现上述目标,我正在使用Bing地图-"GeoCodeService"、"GeoRouteService",并尝试使用以下代码。在运行应用程序时,我得到了一个NullReferenceException,同时从GeoCodeService得到了回调响应。

由于我在开发Windows手机应用程序方面是个新手,所以我没有使用完整的MVVM模式。然而,我可以从Json Web服务获得数据,但无法从GeoCodeService获得结果,将它们绑定到我的地图。

以下是我的xaml代码:

<controls:PivotItem Header="Map">
    <StackPanel Orientation="Vertical">
        <maps:Map x:Name="bingMap"
                  Center="50.851041,4.361572"
                  ZoomLevel="10"
                  CredentialsProvider="{StaticResource MapCredentials}">
            <maps:MapPolyline Locations="{Binding RoutePoints, Converter={StaticResource locationConverter}}"
                  Stroke="#FF0000FF"
                  StrokeThickness="5" />
            <maps:Pushpin Location="{Binding StartPoint, Converter={StaticResource locationConverter}}"
                  Content="Start" />
            <maps:Pushpin Location="{Binding EndPoint, Converter={StaticResource locationConverter}}"
                  Content="End" />
        </maps:Map>
        <StackPanel Orientation="Horizontal"
                    VerticalAlignment="Bottom">
            <Button Margin="80,0,0,0"
                    x:Name="btnputodo"
                    Click="btnputodo_Click"
                    HorizontalAlignment="Left"
                    FontFamily="Verdana"
                    FontSize="18"
                    VerticalAlignment="Bottom"
                    BorderBrush="Transparent"
                    Height="60"
                    Content="Pu to Do"
                    Width="150"
                    Background="White"
                    Foreground="Black"/>
            <Button x:Name="btnmyloctopu"
                    Click="btnmyloctopu_Click"
                    HorizontalAlignment="Left"
                    FontFamily="Verdana"
                    FontSize="18"
                    VerticalAlignment="Bottom"
                    BorderBrush="Transparent"
                    Height="60"
                    Content="Loc to Pu"
                    Width="150"
                    Background="White"
                    Foreground="Black"/>
        </StackPanel>
    </StackPanel>
</controls:PivotItem>
<controls:PivotItem Header="Directions">
    <ListBox ItemsSource="{Binding Itinerary, Converter={StaticResource itineraryConverter}}"
             Grid.RowSpan="2"
             ItemTemplate="{StaticResource ItineraryItemComplete}" />
</controls:PivotItem>

下面是我的xaml.cs代码(后面的代码):

private Location toLocation;
private Location fromLocation;
private Address from;
public Address From
{
    get { return from; }
    set
    {
        from = value;
        Change("From");
    }
}
private Address to;
public Address To
{
    get { return to; }
    set
    {
        to = value;
        Change("To");
    }
}
private Location startPoint;
public Location StartPoint
{
    get { return startPoint; }
    set
    {
        startPoint = value;
        Change("StartPoint");
    }
}
private Location endPoint;
public Location EndPoint
{
    get { return endPoint; }
    set
    {
        endPoint = value;
        Change("EndPoint");
    }
}
private ObservableCollection<Location> routePoints;
public ObservableCollection<Location> RoutePoints
{
    get { return routePoints; }
    set
    {
        routePoints = value;
        Change("RoutePoints");
    }
}
private ObservableCollection<ItineraryItem> itinerary;
public ObservableCollection<ItineraryItem> Itinerary
{
    get
    {
        return itinerary;
    }
    set
    {
        itinerary = value;
        Change("Itinerary");
    }
}
public event PropertyChangedEventHandler PropertyChanged;
private void Change(string property)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public event EventHandler RouteResolved;
private void RaiseRouteResolved()
{
    if (RouteResolved != null)
        RouteResolved(this, EventArgs.Empty);
}
private void btnputodo_Click(object sender, RoutedEventArgs e)
{
    foreach (var dictionary in pickdrops)
    {
        if (dictionary.Key == "pickups")
        {
            locate = dictionary.Value;
            this.From = new Address();
            this.From.AddressLine = locate;
            this.From.Locality = this.From.AdminDistrict = this.From.CountryRegion = this.From.District = this.From.PostalCode = this.From.PostalTown = string.Empty;
            ResolveRoute();
        }
        if (dictionary.Key == "drops")
        {
            locate = dictionary.Value;
            this.To= new Address();
            this.To.AddressLine = locate;
            this.To.Locality = this.To.AdminDistrict = this.To.CountryRegion = this.To.District = this.To.PostalCode = this.To.PostalTown = string.Empty;
            ResolveRoute1();
        }
    }
}

public void ResolveRoute()
{
    GetGeoLocation(From, (l) => fromLocation = l);
}
public void ResolveRoute1()
{
    GetGeoLocation1(To, (l) => toLocation = l);
}
private void GetGeoLocation1(Address address, Action<Utils.WP7.Bing.BingGeo.GeocodeLocation> callBack)
{
    var geoRequest = new GeocodeRequest();
    geoRequest.Credentials = new Credentials();
    geoRequest.Credentials.ApplicationId = App.BingApiKey;
    geoRequest.Address = address;
        var geoClient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
    geoClient.GeocodeCompleted += (s, e) =>
    {
        string statusCode =  e.Result.ResponseSummary.StatusCode.ToString();
        string ss = e.Result.Results == null ? "EMPTY" : "OK";
        if (e.Result.Results != null && e.Result.Results.Count > 0)
        {
            string dd = e.Result.Results[0].Locations[0].Latitude.ToString(); 
        }
        // Am getting Exception at the below statement -->
        callBack(e.Result.Results.FirstOrDefault().Locations.FirstOrDefault());
        // <---
        LocationLoaded();
    };
    geoClient.GeocodeAsync(geoRequest);
}
private void GetGeoLocation(Address address, Action<Utils.WP7.Bing.BingGeo.GeocodeLocation> callBack)
{
    var geoRequest = new GeocodeRequest();
    geoRequest.Credentials = new Credentials();
    geoRequest.Credentials.ApplicationId = App.BingApiKey;
    geoRequest.Address  = address;

    var geoClient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
    geoClient.GeocodeCompleted += (s, e) =>
    {
        callBack(e.Result.Results.FirstOrDefault().Locations.FirstOrDefault());
        LocationLoaded();
    };
    geoClient.GeocodeAsync(geoRequest);
}

private void LocationLoaded()
{
    if (fromLocation != null && toLocation != null)
    {
        var fromWaypoint = new Waypoint();
        fromWaypoint.Description = "From";
        fromWaypoint.Location = new Microsoft.Phone.Controls.Maps.Platform.Location();
        fromWaypoint.Location.Altitude = fromLocation.Altitude;
        fromWaypoint.Location.Latitude = fromLocation.Latitude;
        fromWaypoint.Location.Longitude = fromLocation.Longitude;
        var toWaypoint = new Waypoint();
        toWaypoint.Description = "To";
        toWaypoint.Location = new Microsoft.Phone.Controls.Maps.Platform.Location();
        toWaypoint.Location.Altitude = toLocation.Altitude;
        toWaypoint.Location.Latitude = toLocation.Latitude;
        toWaypoint.Location.Longitude = toLocation.Longitude;
        var routeRequest = new RouteRequest();
        routeRequest.Credentials = new Microsoft.Phone.Controls.Maps.Credentials();
        routeRequest.Credentials.ApplicationId = App.BingApiKey;
        routeRequest.Waypoints = new System.Collections.ObjectModel.ObservableCollection<Waypoint>();
        routeRequest.Waypoints.Add(fromWaypoint);
        routeRequest.Waypoints.Add(toWaypoint);
        routeRequest.Options = new RouteOptions();
        routeRequest.Options.RoutePathType = RoutePathType.Points;
        routeRequest.UserProfile = new Utils.WP7.Bing.BingRoute.UserProfile();
        routeRequest.UserProfile.DistanceUnit = Utils.WP7.Bing.BingRoute.DistanceUnit.Kilometer;
        var routeClient = new RouteServiceClient("BasicHttpBinding_IRouteService");
        routeClient.CalculateRouteCompleted += new EventHandler<CalculateRouteCompletedEventArgs>(OnRouteComplete);
        routeClient.CalculateRouteAsync(routeRequest);
    }
}
private void OnRouteComplete(object sender, CalculateRouteCompletedEventArgs e)
{
    if (e.Result != null && e.Result.Result != null && e.Result.Result.Legs != null & e.Result.Result.Legs.Any())
    {
        var result = e.Result.Result;
        var legs = result.Legs.FirstOrDefault();
        StartPoint = legs.ActualStart;
        EndPoint = legs.ActualEnd;
        RoutePoints = result.RoutePath.Points;
        Itinerary = legs.Itinerary;

    }
}

在从';GeoCodeService';在Windows Phone 7.1应用程序中使用Bing地图

我认为您的问题与如何从请求中提取结果数据有关。

首先,我看到你正在以这种方式检查你的参数是否是NULL值:

if (e.Result.Results != null && e.Result.Results.Count > 0)
    (... some logic here ...)

但我认为这样做更好:

 if(e.Error == null)
     // HERE YOU'D WANT TO MANAGE A REQUEST EXCEPTION
     // (FOR EXAMPLE AN UNPREDICTABLE PROBLEM OF THE BING WEB SERVICE!)
     // e.Error is an Exception class
 else
 {
     // Get the first result received:
     var geoResult = (from r in e.Result.Results
                     orderby (int)r.Confidence ascending // USE THIS CLAUSE TO SORT THE RESULT BY CONFIDENCE, OTHERWISE REMOVE IT!
                     select r).FirstOrDefault();
     // DO I HAVE A VALID RESULT?
     if (geoResult != null)
     {
         // I DO HAVE A VALID RESULT FOR GEOCODING!!
         // Defined a new point location for storing my information:
         Location currentLocation = new Location();
         // Set the coordinates:
         currentLocation.Latitude = geoResult.Locations[0].Latitude;
         currentLocation.Longitude = geoResult.Locations[0].Longitude;
         // Your problem was here:
         callBack(currentLocation.Locations[0]);
         // ...NEXT SOME SAMPLE CODE...
         // Set the point on the Bing map with a certain level of zoom:
         GeoLocationMap.SetView(currentLocation, 10);
         // Set the location of the visual pin on the map!
         GeoLocationMapPushpin.Location = currentLocation;
     }
 }

希望这能有所帮助!