Bing Maps提供的路由功能服务(RouteService)可以实现多方位的计算地图上的路线指示,路径行程等功能,比如说实现驾驶路线和地点,旅游航线等。可以通过该服务的地址(
http://dev.virtualearth.net/WebServices/v1/RouteService/RouteService.svc)添加该服务的Web服务引用。
路由功能服务提供了两个方法,分别是CalculateRoute()和CalculateRoutesFormMajorRoads(),其实现的功能分别如下:
1、CalculateRoute:计算路径并返回指定的路径行程,以及路径的其他相关路径数据(包括道路名称,行程方法等等)。
2、CalculateRoutesFormMajorRoads:计算指定地理位置点或路径方向,以及附近的道路信息。
为了更加清楚的介绍路由功能服务的接口使用方法,下面将通过一个实例来介绍路由服务接口的详细应用。需要实现从成都到重庆的路由检索,然后标记处从成都到重庆的路程行程图和中途经度地市的行程点。
通过前面对路由功能服务(RouteService)添加了服务引用,Silverlight客户端就会自动生成该服务的客户端代理对象,在实现上面所提出的实例需求前先对RouteServiceClient进行一下封装,并指定了调用接口完成后事件处理函数:client_CalculateRouteCompleted。如下代码块:
private
RouteServiceClient client;
public RouteServiceClient Client
{
get
{
if (client == null )
{
bool uriScheme = !Application.Current.IsRunningOutOfBrowser && HtmlPage.Document.DocumentUri.Scheme.Equals(Uri.UriSchemeHttps);
BasicHttpBinding binding = new BasicHttpBinding(uriScheme ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None);
binding.MaxReceivedMessageSize = int .MaxValue;
binding.MaxBufferSize = int .MaxValue;
UriBuilder uri = new UriBuilder("http://dev.virtualearth.net/webservices/v1/RouteService/RouteService.svc" );
if (uriScheme)
{
uri.Scheme = Uri.UriSchemeHttps;
uri.Port = -1 ;
}
client=new RouteServiceClient(binding,new EndpointAddress(uri.Uri));
//调用完成后的事件处理函数
client.CalculateRouteCompleted +=new EventHandler<CalculateRouteCompletedEventArgs> (client_CalculateRouteCompleted);
}
return client;
}
}
public RouteServiceClient Client
{
get
{
if (client == null )
{
bool uriScheme = !Application.Current.IsRunningOutOfBrowser && HtmlPage.Document.DocumentUri.Scheme.Equals(Uri.UriSchemeHttps);
BasicHttpBinding binding = new BasicHttpBinding(uriScheme ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None);
binding.MaxReceivedMessageSize = int .MaxValue;
binding.MaxBufferSize = int .MaxValue;
UriBuilder uri = new UriBuilder("http://dev.virtualearth.net/webservices/v1/RouteService/RouteService.svc" );
if (uriScheme)
{
uri.Scheme = Uri.UriSchemeHttps;
uri.Port = -1 ;
}
client=new RouteServiceClient(binding,new EndpointAddress(uri.Uri));
//调用完成后的事件处理函数
client.CalculateRouteCompleted +=new EventHandler<CalculateRouteCompletedEventArgs> (client_CalculateRouteCompleted);
}
return client;
}
}
路由检索接口的调用非常简单,要想检索出那几个地点之间的路径行程只需要将地点所对应地理位置坐标(经度和纬度)传递给路由请求对象就可以了。详细如下代码块:
private void btnCalculateRoute_Click(object
sender, RoutedEventArgs e)
{
var request = new RouteRequest();
request.Credentials = new Credentials();
request.Credentials.ApplicationId = "AkzZURoD0H2Sle6Nq_DE7pm7F3xOc8S3CjDTGNWkz1EFlJJkcwDKT1KcNcmYVINU" ;
//设置开始、结束坐标点
var waypoints = new System.Collections.ObjectModel.ObservableCollection<Waypoint>
{
new Waypoint(){Description="成都",Location=new Location(){Latitude=30.6666587469201,Longitude=104.062021177233 }},
new Waypoint(){Description="重庆",Location=new Location(){Latitude=29.5076372217973,Longitude=106.489384971208 }},
};
request.Waypoints = waypoints;
request.ExecutionOptions = new ExecutionOptions();
request.ExecutionOptions.SuppressFaults = true ;
request.Options = new RouteOptions();
request.Options.RoutePathType = RoutePathType.Points;
Client.CalculateRouteAsync(request);
}
{
var request = new RouteRequest();
request.Credentials = new Credentials();
request.Credentials.ApplicationId = "AkzZURoD0H2Sle6Nq_DE7pm7F3xOc8S3CjDTGNWkz1EFlJJkcwDKT1KcNcmYVINU" ;
//设置开始、结束坐标点
var waypoints = new System.Collections.ObjectModel.ObservableCollection<Waypoint>
{
new Waypoint(){Description="成都",Location=new Location(){Latitude=30.6666587469201,Longitude=104.062021177233 }},
new Waypoint(){Description="重庆",Location=new Location(){Latitude=29.5076372217973,Longitude=106.489384971208 }},
};
request.Waypoints = waypoints;
request.ExecutionOptions = new ExecutionOptions();
request.ExecutionOptions.SuppressFaults = true ;
request.Options = new RouteOptions();
request.Options.RoutePathType = RoutePathType.Points;
Client.CalculateRouteAsync(request);
}
如上代码块中定义,通过构造好了成都和重庆的两点地理坐标给路由请求对象(RouteRequest)的路径途经点(Waypoint),然后调用路由功能服务接口方法实现路径行程线检索。最终接口的返回值就交给了上面RouteServiceClient中封装过程中指定的结果处理事件函数去处理了,这里需要分析清楚几点。
1、在接口请求完成事件处理函数里能够获取到请求响应结果(RouteResponse),包括状态,规则,路径点等一系列结果参数。
2、可以通过规则检测或获取两点或多个路程点之间的路径点数量。
3、知道路径点(既经过点的地理位置坐标),可以通过在地图上绘制不估计值线条表示出路线图。
4、可以在路径点上通过某种特殊的符号标记为路径是通过了该路径点的,比如用圆形、三角形或者一张有特殊意义的图片等。
5、总结上面四点得出结论,通过调用路径检索接口得到路径点坐标后,通过在地图上绘制路径线路图,并在路径点上通过圆形标记。
通过上面的分析,几乎已经将下面要做的事情用汉语描述清楚了,下面代码块则是实现上面五点的程序代码:
private void client_CalculateRouteCompleted(object
sender, CalculateRouteCompletedEventArgs e)
{
RouteResponse routeResponse = e.Result;
try
{
if (e.Result.ResponseSummary.StatusCode != ResponseStatusCode.Success)
{
MessageBox.Show("错误的路由状态" );
}
else if (e.Result.Result.Legs.Count == 0 )
{
MessageBox.Show("没找到路由规则" );
}
else
{
//初始化路线线路点坐标及其他属性
MapPolyline line = new MapPolyline();
line.Locations = new LocationCollection();
line.Stroke = new SolidColorBrush(Colors.Blue);
line.Opacity = 0.66 ;
line.StrokeThickness = 5 ;
foreach (var point in e.Result.Result.RoutePath.Points)
{
line.Locations.Add(new Location(point.Latitude, point.Longitude));
}
RouteLayer.Children.Add(line);
//记录开始点和结束点
LocationRect rect = new LocationRect(line.Locations[0], line.Locations[line.Locations.Count - 1 ]);
//遍历处理服务调用接口中的路程行程点,将各个行程点上绘制一个红色圆形标记
foreach (var item in e.Result.Result.Legs[0 ].Itinerary)
{
Ellipse ellipse = new Ellipse() { Width = 10, Height = 10, Fill = new SolidColorBrush(Colors.Red), Opacity = 0.66, Tag = item };
Location location = new Location(item.Location.Latitude, item.Location.Longitude);
MapLayer.SetPosition(ellipse, location);
MapLayer.SetPositionOrigin(ellipse, PositionOrigin.Center);
RouteLayer.Children.Add(ellipse);
}
map.SetView(rect);
}
}
catch (Exception)
{
MessageBox.Show("路由解析过程中出现异常" );
}
}
{
RouteResponse routeResponse = e.Result;
try
{
if (e.Result.ResponseSummary.StatusCode != ResponseStatusCode.Success)
{
MessageBox.Show("错误的路由状态" );
}
else if (e.Result.Result.Legs.Count == 0 )
{
MessageBox.Show("没找到路由规则" );
}
else
{
//初始化路线线路点坐标及其他属性
MapPolyline line = new MapPolyline();
line.Locations = new LocationCollection();
line.Stroke = new SolidColorBrush(Colors.Blue);
line.Opacity = 0.66 ;
line.StrokeThickness = 5 ;
foreach (var point in e.Result.Result.RoutePath.Points)
{
line.Locations.Add(new Location(point.Latitude, point.Longitude));
}
RouteLayer.Children.Add(line);
//记录开始点和结束点
LocationRect rect = new LocationRect(line.Locations[0], line.Locations[line.Locations.Count - 1 ]);
//遍历处理服务调用接口中的路程行程点,将各个行程点上绘制一个红色圆形标记
foreach (var item in e.Result.Result.Legs[0 ].Itinerary)
{
Ellipse ellipse = new Ellipse() { Width = 10, Height = 10, Fill = new SolidColorBrush(Colors.Red), Opacity = 0.66, Tag = item };
Location location = new Location(item.Location.Latitude, item.Location.Longitude);
MapLayer.SetPosition(ellipse, location);
MapLayer.SetPositionOrigin(ellipse, PositionOrigin.Center);
RouteLayer.Children.Add(ellipse);
}
map.SetView(rect);
}
}
catch (Exception)
{
MessageBox.Show("路由解析过程中出现异常" );
}
}
程序代码里使用到的RouteLayer是在地图控件里加入了一个MapLaye图层,r专门用来呈现的路径行程图和路径标记,直接使用Bing Maps Silverlight Control提供的MapLayer,如下代码块:
<m:Map CredentialsProvider="Bing Maps 开发 Key" x:Name="map">
<m:MapLayer x:Name="RouteLayer">m:MapLayer>
m:Map>
<m:MapLayer x:Name="RouteLayer">m:MapLayer>
m:Map>
编译运行最终的效果如下图所示:
如果您想了解更多关于Bing Maps地图服务的知识,请查询:
MSDN:
http://msdn.microsoft.com/en-us/library/cc980922.aspx
Bing Maps开发站:
http://www.microsoft.com/maps/developers/
Bing Maps开发SDK:
http://msdn.microsoft.com/en-us/library/dd877180.aspx