Bing Maps基于位置的操作
文章信息
本文描述应用程序使用Windows Phone基于位置服务的基本任务。
Contents |
介绍
本文中描述了基于位置服务需要的一些基本函数
- 获取当前位置
- 反转位置地理编码以获得地址(可用于显示给客户)
- 地址地理编码以获得地图位置
- 计算位置之间的路线
- 在地图上显示所有这些
本文附上演示如何在WP应用程序中完成这些任务的示例代码File:BingMapsSample.zip
预备知识
请添加引用
- Microsoft.Phone.Controls.Maps
- Microsoft.Phone.Controls.Toolkit
- System.Device
- System.Device.Location
然后添加服务引用到Bing 地图SOAP地理编码服务和路径服务: http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc?wsdl http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/mex
获取当前位置
确定当前位置所有你需要的在每一台Windows Phone上不必联网都可用。你需要创建一个GeoCoordinateWatcher示例并且附加到StatusChanged 和 PositionChanged 事件中。设定多久一个通知的阈值是很重要的。通知太多会降低性能/电池电量。然后你调用一个异步调用立即返回Start(),但是结果返回在上述事件中。 参考Location Overview for Windows Phone 和How to: Get Data from the Location Service for Windows Phone.
private void GetCurrentLocation()
{ // get current location by asking WP location service
if (watcher == null)
{
watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
watcher.Start();
}
}
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{ // status of the location service has changed - stop if disabled
if (e.Status == GeoPositionStatus.Disabled)
{
watcher.Stop();
watcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
watcher = null;
}
}
void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{ // the current position has changed - we need only one so we stop the service now
watcher.Stop();
watcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
watcher = null;
//...//
}
反转地理编码当前位置
既然我们已经引用了Bing 地图SOAP地理编码服务,你可以调用地理编码和反转地理编码函数。你就可以使用地理编码从位置坐标获取街道地址和使用反转地理编码从坐标获取地址。 调用这些函数需要联网. 以下代码初始化了服务,然后建立一个使用当前位置的反转地理编码调用获取当前地址。 创建一个请求,你需要赋予你的Bing 地图证书。你可以从Bing 地图门户网站免费获取用于非商业Windows Phone应用程序的证书。 参考Getting a Bing Maps Key 和 GeocodeServiceClient.ReverseGeocode 方法. 请不要忘了在MainPage.xaml.cs输入你的Bing MapsKey到BingMapsKey值中
// initialize geocode service
GeocodeServiceClient gc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
// reverse geocode the location to get a displayable address
gc.ReverseGeocodeCompleted += new EventHandler<ReverseGeocodeCompletedEventArgs>(gc_ReverseGeocodeCompleted);
ReverseGeocodeRequest rreq = new ReverseGeocodeRequest();
rreq.Credentials = new Credentials();
rreq.Credentials.ApplicationId = BingMapsKey;
rreq.Location = e.Position.Location;
gc.ReverseGeocodeAsync(rreq);
地理编码地址
现在调用这个服务用于地理编码来获得德国诺基亚分支机构地址的坐标。在一次强调,证书需要初始化。 两个地理编码调用同时发出SOAP编码服务。 那一个调用先完成这是无法确定的。 同样参考GeocodeServiceClient.Geocode 方法。
// concurrently geocode an address in Germany
destination = e.Position.Location;
gc.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs>(gc_GeocodeCompleted);
GeocodeRequest req = new GeocodeService.GeocodeRequest();
req.Credentials = new Credentials();
req.Credentials.ApplicationId = BingMapsKey;
req.Query = "Balcke-Dürr-Allee 2, 40882 Ratingen, Germany";
gc.GeocodeAsync(req);
计算路线
为了计算路线,您需要再次初始化路径服务,然后设置的请求。请求参数包括Bing Maps Key,options和waypoint列表。在这种情况下,waypoint的地缘位置是诺基亚分支地理编码您当前所在的位置。在option中RoutePathType是很重要的,因为它告诉服务返回所有中间路线点,这样就可以显示一条路径线。 路径完成后,CalculateRouteCompleted事件被调用。返回RouteResult。 RouteResult包含行走距离及持续时间和路线的详细说明。
// initialize call
RouteServiceClient rc = new RouteServiceClient("BasicHttpBinding_IRouteService");
rc.CalculateRouteCompleted += new EventHandler<CalculateRouteCompletedEventArgs>(rc_CalculateRouteCompleted);
RouteRequest req = new RouteRequest();
req.Credentials = new Credentials();
req.Credentials.ApplicationId = BingMapsKey;
req.Options = new RouteOptions();
req.Options.Mode = TravelMode.Driving;
req.Options.RoutePathType = RoutePathType.Points;
req.UserProfile = new BingMapsSample.RouteService.UserProfile() { DistanceUnit = BingMapsSample.RouteService.DistanceUnit.Kilometer };
// setup the waypoints
Waypoint wpStart = new Waypoint();
wpStart.Location = start;
wpStart.Description = "Nokia DE";
req.Waypoints = new System.Collections.ObjectModel.ObservableCollection<Waypoint>();
req.Waypoints.Add(wpStart);
Waypoint wpEnd = new Waypoint();
wpEnd.Location = destination;
wpEnd.Description = "Me";
req.Waypoints.Add(wpEnd);
// display start and destination with pushpins
map1.Children.Clear();
Pushpin p = new Pushpin();
p.Location = wpStart.Location;
p.Content = wpStart.Description;
p.Background = new SolidColorBrush(Colors.Red);
map1.Children.Add(p);
p = new Pushpin();
p.Location = wpEnd.Location;
p.Content = wpEnd.Description;
p.Background = new SolidColorBrush(Colors.Blue);
map1.Children.Add(p);
// start the route calculation
rc.CalculateRouteAsync(req);
在地图中显示
在地图中显示路线
添加一个地图元素到MainPage.xaml代码中 呼叫路径服务之前,两个图钉添加到地图上以标记起始位置和目的位置。 当路线计算完成后,对结果进行分析和构造一个MapPolyline对象,其包含的路径点。 最后的操作是放大缩小地图查看的路线的边界矩形。
void rc_CalculateRouteCompleted(object sender, CalculateRouteCompletedEventArgs e)
{
// get summary of the route
RouteResult rr = e.Result.Result;
tbDist.Text = rr.Summary.Distance.ToString() + " km";
tbTime.Text = (rr.Summary.TimeInSeconds / 60).ToString() + " min.";
SolidColorBrush brItinerary = new SolidColorBrush(Colors.Green);
SolidColorBrush brLeg = new SolidColorBrush(Colors.Red);
List<GeoCoordinate> pts = new List<GeoCoordinate>();
// create a line object from the route points
MapPolyline line = new MapPolyline();
line.Stroke = brItinerary;
line.StrokeThickness = 5;
line.Locations = new LocationCollection();
foreach (var pt in rr.RoutePath.Points)
line.Locations.Add(pt);
// show the line in the map and zoom to its bounds
map1.Children.Add(line);
map1.SetView(rr.Summary.BoundingRectangle);
}
下载示例代码
本文中说明的示例代码可用,在这里下载



Hamishwillee - Notes on linking
Please do not link to files on wiki using the external format - http ..../image/whatever. Instead use internal format [[File:yourfilename.zip]] or [[Media:yourfilename.zip]]
If you are linking to wiki to an article, again, please use internal format not external format [[Name of Article]]hamishwillee 08:25, 6 November 2012 (EET)