How to: Implement a Route Calculator Using GIS Providers
- 6 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 an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingSearchDataProvider to the InformationLayer.DataProvider property. Set the LayerBase.Name property of the layer to SearchLayer.
- Add an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingGeocodeDataProvider to the InformationLayer.DataProvider property. Set the LayerBase.Name property of the layer to GeocodeLayer.
- Add an InformationLayer object to the MapControl.Layers collection and assign an instance of the BingRouteDataProvider to the InformationLayer.DataProvider property. Set the LayerBase.Name property of the layer to RouteLayer.
- For each information layers’ data provider, specify the valid Bing key using the BingMapDataProviderBase.BingKey property and set the InformationDataProviderBase.GenerateLayerItems property value to false.
Create a helper, which allows you to convert MapPushpin objects to RouteWaypoint and store the route using a MapPolyline object.
class RoutingHelper { List<MapPushpin> pushpins = new List<MapPushpin>(); MapPolyline route = new MapPolyline() { StrokeWidth = 4, SelectedStrokeWidth = 4, Stroke = Color.FromArgb(0xFF, 0xFE, 0x72, 0xFF) }; 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'; } }
Prepare properties and members of the form class as follows.
InformationLayer SearchLayer { get { return (InformationLayer)mapControl1.Layers["SearchLayer"]; } } BingSearchDataProvider SearchProvider { get { return (BingSearchDataProvider)SearchLayer.DataProvider; } } InformationLayer GeocodeLayer { get { return (InformationLayer)mapControl1.Layers["GeocodeLayer"]; } } BingGeocodeDataProvider GeocodeProvider { get { return (BingGeocodeDataProvider)GeocodeLayer.DataProvider; } } InformationLayer RouteLayer { get { return (InformationLayer)mapControl1.Layers["RouteLayer"]; } } BingRouteDataProvider RouteProvider { get { return (BingRouteDataProvider)RouteLayer.DataProvider; } } VectorItemsLayer ItemsLayer { get { return (VectorItemsLayer)mapControl1.Layers["ItemsLayer"]; } } MapItemStorage Storage { get { return (MapItemStorage)ItemsLayer.Data; } } RoutingHelper helper = new RoutingHelper();
Handle BingSearchDataProvider.SearchCompleted, BingGeocodeDataProvider.LocationInformationReceived and BingRouteDataProvider.RouteCalculated events.
SearchProvider.SearchCompleted += SearchProvider_SearchCompleted; GeocodeProvider.LocationInformationReceived += GeocodeProvider_LocationInformationReceived; RouteProvider.RouteCalculated += RouteProvider_RouteCalculated; void GenerateItems(IEnumerable<LocationInformation> locations) { UpdateStorage(); foreach (var location in locations) { MapPushpin pushpin = new MapPushpin() { Location = location.Location, Information = location }; 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 SearchProvider_SearchCompleted(object sender, BingSearchCompletedEventArgs e) { if (e.Cancelled || (e.RequestResult.ResultCode != RequestResultCode.Success)) return; if (e.RequestResult.SearchResults.Count != 0) GenerateItems(e.RequestResult.SearchResults); } void GeocodeProvider_LocationInformationReceived(object sender, LocationInformationReceivedEventArgs e) { if (e.Cancelled) return; GenerateItems(e.Result.Locations); } void RouteProvider_RouteCalculated(object sender, BingRouteCalculatedEventArgs e) { if (e.Cancelled) return; if (e.CalculationResult.ResultCode == RequestResultCode.Success) { helper.BuildRoute(e.CalculationResult.RouteResults[0].RoutePath); UpdateStorage(); } }
Handle the MapControl.MapItemClick event to add data to the helper.
void CalculateRoute() { if (helper.Count < 2) return; RouteProvider.CalculateRoute(helper.Waypoints); } private void mapControl1_MapItemClick(object sender, MapItemClickEventArgs e) { MapPushpin pushpin = e.Item as MapPushpin; if (pushpin == null) return; if (helper.Pushpins.Contains(pushpin)) return; helper.AddItem(pushpin); CalculateRoute(); e.Handled = true; }