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;
    }