How to: Implement a Route Calculator Using GIS Providers
- 5 minutes to read
This example demonstrates how to create a calculating routes application using GIS services.
Follow the steps below.
- Add an ImageTilesLayer object to the MapControl.Layers collection and assign an instance of the BingMapDataProvider class to the ImageLayer.DataProvider property. Specify the valid Bing key using the BingMapDataProvider.BingKey property.
- Add a VectorLayer object to the MapControl.Layers collection and assign a MapItemStorage object to the VectorLayer.Data property.
- Add an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingSearchDataProvider to the InformationLayer.DataProvider property. Create a handler of the BingSearchDataProvider.SearchCompleted event. Specify the valid Bing key using the BingMapDataProviderBase.BingKey property.
- Add an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingGeocodeDataProvider to the InformationLayer.DataProvider property. Create a handler of the BingGeocodeDataProvider.LocationInformationReceived event. Specify the valid Bing key using the BingMapDataProviderBase.BingKey property.
- Add an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingRouteDataProvider to the InformationLayer.DataProvider property. Create a handler of the BingRouteDataProvider.RouteCalculated event. Specify the valid Bing key using the BingMapDataProviderBase.BingKey property.
For each information layer data provider set the InformationDataProviderBase.GenerateLayerItems property value to False.
The following XAML demonstrates this in code.
<dxm:MapControl> <dxm:ImageTilesLayer> <dxm:ImageTilesLayer.DataProvider> <dxm:BingMapDataProvider BingKey="{Binding Source={StaticResource bingKey}}"/> </dxm:ImageTilesLayer.DataProvider> </dxm:ImageTilesLayer> <dxm:VectorLayer EnableSelection="False" EnableHighlighting="False"> <dxm:MapItemStorage x:Name="storage"/> </dxm:VectorLayer> <dxm:InformationLayer> <dxm:InformationLayer.DataProvider> <dxm:BingSearchDataProvider BingKey="{Binding Source={StaticResource bingKey}}" GenerateLayerItems="False" SearchCompleted="SearchCompleted"/> </dxm:InformationLayer.DataProvider> </dxm:InformationLayer> <dxm:InformationLayer> <dxm:InformationLayer.DataProvider> <dxm:BingGeocodeDataProvider BingKey="{Binding Source={StaticResource bingKey}}" GenerateLayerItems="False" LocationInformationReceived="LocationInformationReceived"/> </dxm:InformationLayer.DataProvider> </dxm:InformationLayer> <dxm:InformationLayer> <dxm:InformationLayer.DataProvider> <dxm:BingRouteDataProvider x:Name="routeProvider" BingKey="{Binding Source={StaticResource bingKey}}" GenerateLayerItems="False" RouteCalculated="RouteCalculated"/> </dxm:InformationLayer.DataProvider> </dxm:InformationLayer> </dxm:MapControl>
Create a helper class, which allows you to convert MapPushpin objects to RouteWaypoint and store the route using a MapPolyline object. Create a private member of this class in the MainWindow class.
class RoutingHelper { List<MapPushpin> pushpins = new List<MapPushpin>(); MapPolyline route = new MapPolyline() { Stroke = new SolidColorBrush(Color.FromArgb(0xFF, 0x8A, 0xFB, 0xFF)), StrokeStyle = new StrokeStyle() { Thickness = 3 } }; List<RouteWaypoint> waypoints = new List<RouteWaypoint>(); char currentLatter = 'A'; public List<MapPushpin> Pushpins { get { return pushpins; } } public List<RouteWaypoint> Waypoints { get { return waypoints; } } public MapPolyline Route { get { return route; } set { route = value; } } public int Count { get { return pushpins.Count; } } public void BuildRoute(IEnumerable<GeoPoint> points) { route.Points.Clear(); foreach (GeoPoint point in points) route.Points.Add(point); } public void AddItem(MapPushpin pushpin) { pushpins.Add(pushpin); waypoints.Add(new RouteWaypoint( ((LocationInformation)pushpin.Information).DisplayName, (GeoPoint)pushpin.Location) ); pushpin.Text = (currentLatter++).ToString(); } public void Clear() { route.Points.Clear(); pushpins.Clear(); waypoints.Clear(); currentLatter = 'A'; } }
Handle BingSearchDataProvider.SearchCompleted, BingGeocodeDataProvider.LocationInformationReceived and BingRouteDataProvider.RouteCalculated events. Also handle the MapPushpin.MouseLeftButtonDown event to add a location to waypoints.
private void LocationInformationReceived(object sender, LocationInformationReceivedEventArgs e) { if ((e.Cancelled) && (e.Result.ResultCode != RequestResultCode.Success)) return; GenerateItems(e.Result.Locations); } private void SearchCompleted(object sender, BingSearchCompletedEventArgs e) { if (e.Cancelled || (e.RequestResult.ResultCode != RequestResultCode.Success)) return; if (e.RequestResult.SearchResults.Count != 0) GenerateItems(e.RequestResult.SearchResults); else GenerateItems(new LocationInformation[] { e.RequestResult.SearchRegion }); } private void RouteCalculated(object sender, BingRouteCalculatedEventArgs e) { if (e.Cancelled) return; if (e.CalculationResult.ResultCode != RequestResultCode.Success) return; helper.BuildRoute(e.CalculationResult.RouteResults[0].RoutePath); UpdateStorage(); } void GenerateItems(IEnumerable<LocationInformation> locations) { UpdateStorage(); foreach (var location in locations) { MapPushpin pushpin = new MapPushpin() { Location = location.Location, Information = location }; pushpin.MouseLeftButtonDown += pushpin_MouseLeftButtonDown; storage.Items.Add(pushpin); } } void UpdateStorage() { storage.Items.Clear(); storage.Items.Add(helper.Route); foreach (MapPushpin pushpin in helper.Pushpins) storage.Items.Add(pushpin); } void pushpin_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MapPushpin pushpin = sender as MapPushpin; if (pushpin == null) return; e.Handled = true; helper.AddItem(pushpin); routeProvider.CalculateRoute(helper.Waypoints); pushpin.MouseLeftButtonDown -= pushpin_MouseLeftButtonDown; }
Note
If you run the application, and see a window with the following error message: ”The specified Bing Maps key is invalid. To create a developer account, refer to https://www.microsoft.com/en-us/maps/create-a-bing-maps-key”, refer to the following tutorial: How to: Get a Bing Maps Key.