/// <summary> /// Draw the result of an optimized routing request on the map /// </summary> private void DrawOptimizedRoute(CloudRoutingOptimizationResult optimizedRoutingResult) { // Get the routing feature layer from the MapView InMemoryFeatureLayer routingLayer = (InMemoryFeatureLayer)mapView.FindFeatureLayer("Routing Layer"); // Clear the previous features from the routing layer routingLayer.InternalFeatures.Clear(); // Create a collection to hold the route segments. These include information like distance, duration, warnings, and instructions for turn-by-turn routing List <CloudRoutingSegment> routeSegments = new List <CloudRoutingSegment>(); //// CloudRoutingOptimizationResult.TspResult.VisitSequences is an ordered array of integers //// Each integer corresponds to the index of the corresponding waypoint in the original set of waypoints passed into the query //// For example, if the second element in 'VisitSequences' is '3', the second stop on the route is originalWaypointArray[3] int index = 0; // Add the route visit points and route segments to the map foreach (int waypointIndex in optimizedRoutingResult.TspResult.VisitSequences) { Dictionary <string, string> columnValues = new Dictionary <string, string>(); // Get the order of the stops and label the point // '0' represents the start/end point of the route for a round trip route, so we change the label to indicate that for readability columnValues.Add("SequenceNumber", (index == 0 || index == optimizedRoutingResult.TspResult.VisitSequences.Count - 1 ? "Start/End Point" : "Stop " + index)); PointShape waypoint = routingWaypoints[waypointIndex]; // Add the point to the map routingLayer.InternalFeatures.Add(new Feature(waypoint, columnValues)); // Increment the index for labeling purposes index++; } foreach (CloudRoutingRoute route in optimizedRoutingResult.TspResult.Routes) { routingLayer.InternalFeatures.Add(new Feature(route.Shape)); routeSegments.AddRange(route.Segments); } //// Set the data source for the list box to the route segments lsbRouteSegments.ItemsSource = routeSegments; //// Set the map extent to the newly displayed route routingLayer.Open(); mapView.CurrentExtent = RectangleShape.ScaleUp(routingLayer.GetBoundingBox(), 20).GetBoundingBox(); routingLayer.Close(); mapView.Refresh(); }
/// <summary> /// Make a request to the ThinkGeo Cloud for an optimized route /// </summary> private async Task <CloudRoutingOptimizationResult> GetOptimizedRoute() { // Set up options for the TSP routing request CloudRoutingOptimizationOptions options = new CloudRoutingOptimizationOptions(); // Enable turn-by-turn so we get turn by turn instructions options.TurnByTurn = true; // A specific starting and ending location can be specified, if desired. // For this example, any point can be used as the start and end options.Destination = CloudRoutingTspFixDestinationCoordinate.Any; options.Source = CloudRoutingTspFixSourceCoordinate.Any; // The 'roundtrip' option specifies whether the route returns to the starting point or not options.Roundtrip = true; // Send the TSP routing request CloudRoutingOptimizationResult optimizedRoutingResult = await routingCloudClient.GetOptimizedRouteAsync(routingWaypoints, 3857, options); return(optimizedRoutingResult); }
/// <summary> /// Perform routing using the RoutingCloudClient through a preset set of waypoints /// </summary> private async void RouteWaypoints() { // Show a loading graphic to let users know the request is running loadingIndicator.IsRunning = true; loadingLayout.IsVisible = true; // Run the optimized routing query CloudRoutingOptimizationResult optimizedRoutingResult = await GetOptimizedRoute(); // Hide the loading graphic loadingIndicator.IsRunning = false; loadingLayout.IsVisible = false; // Handle an exception returned from the service if (optimizedRoutingResult.Exception != null) { await DisplayAlert("Alert", optimizedRoutingResult.Exception.Message, "OK"); return; } // Draw the result on the map DrawOptimizedRoute(optimizedRoutingResult); }