Display driving directions

Whether your ArcGIS Runtime app is connected or disconnected, your users can get driving directions in the form of a route on a map, turn-by-turn instructions, or both. Driving directions can be for a route between two locations (known as stops) or they can be for a number of other route types, such as:

  • A multiple stop route—A route from one location to multiple stops. For credit usage calculation (ArcGIS Online), this route is known as Simple Directions unless you want the algorithm to re-sequence the stops in the optimal order (shortest distance or shortest time), in which case the route is known as Optimized Directions. You may know these optimized directions as the traveling salesman problem.
  • A route with time windows—A route to some stops that have specific times of the day they need to be reached by the driver.
  • A route with barriers—A route that prevents traversal of some streets due to barriers (for example, street closures) or that reduces the traversal speed of some streets.
  • Drive time—Drive time refers to calculating the area that can be reached within a specified travel time or travel distance along a street network based on travel mode.

Tip:

If you'd like a ready-to-use and regularly updated network dataset (and locator) for performing offline geocoding and routing, you can license StreetMap Premium data (in mobile map package format). For details, see Add StreetMap Premium data.

Displaying driving directions is just one of many capabilities known as network analysis capabilities. You can use network analysis capabilities via geoprocessing tools with Local Server if you've purchased both the Advanced ArcGIS Runtime license and the Analysis extension license for ArcGIS Runtime. These geoprocessing tools, which are in the Network Analyst toolbox, can be used while disconnected:

  • The Build Network tool in the Network Dataset toolset—Each newly created or recently changed network dataset must be built so that it can be used. Building the dataset performs such actions as creating network elements, establishing connectivity, and assigning values to the network attributes.
  • The Solve Vehicle Routing Problem tool in the Server toolset—Helps you find the best routes for a fleet of vehicles, where each vehicle services multiple stops.
  • The Generate Service Areas in the Server toolset—A service area is a region that encompasses all streets that can be accessed within a given distance or travel time from one or more facilities. For example, a three-minute, drive-time polygon around a grocery store can determine which residents are able to reach the store within three minutes and are thus more likely to shop there.
  • The Make Service Area Layer tool in the Analysis toolset—Helps you the area of accessibility within a given cutoff cost from a facility location

Other network analysis capabilities include origin-destination (OD) cost matrix and location-allocation, which your app can consume through a geoprocessing service via a GeoprocessingTask.

To display driving directions, you typically follow these steps:

  1. Create a RouteTask and RouteParameters that you'll use to reference the routing service.

    The code below sets up the route task and starts to define the parameters to be used to solve the route.

    // create the route task pointing to an online service
    m_routeTask = new RouteTask(QUrl("http://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/Route"), this);
    
    
    // connect to loadStatusChanged signal
    connect(m_routeTask, &RouteTask::loadStatusChanged, this, [this](LoadStatus loadStatus)
    {
      if (loadStatus == LoadStatus::Loaded)
      {
        // Request default parameters once the task is loaded
        m_routeTask->createDefaultParameters();
      }
    });

  2. Create the stops. If you want users to be able to type in an address or place name, then either:
    • Use a service that includes a locator, such as http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer.
    • Set up your own address locator using ArcGIS Desktop. If you set up your own address locator, you can serve it via ArcGIS Online, ArcGIS Server, or ArcGIS Enterprise portal for connected workflows or you can create a locator package from it for disconnected workflows.

    In either case your app consumes the locator via a LocatorTask, as described in Search for places.

    You can also use the user's current location as the from- or to- location.

    For simplicity, the code below uses two pre-defined stops instead of using a locator/having the user select the stops. These stops are added to the route parameters.

    // create the stop graphics' geometry
    Point stop1Geometry(-13041171, 3860988, SpatialReference(3857));
    Point stop2Geometry(-13041693, 3856006, SpatialReference(3857));
    
    
    // create the stop graphics' symbols
    auto stop1Symbol = getPictureMarkerSymbol(QUrl("qrc:/Samples/Routing/FindRoute/pinA.png"));
    auto stop2Symbol = getPictureMarkerSymbol(QUrl("qrc:/Samples/Routing/FindRoute/pinB.png"));
    
    
    // create the stop graphics
    auto stop1Graphic = new Graphic(stop1Geometry, stop1Symbol, this);
    auto stop2Graphic = new Graphic(stop2Geometry, stop2Symbol, this);
    
    
    // add to the overlay
    m_stopsGraphicsOverlay->graphics()->append(stop1Graphic);
    m_stopsGraphicsOverlay->graphics()->append(stop2Graphic);

  3. Solve the route. You do this using the solveRoute method of the route task, passing in the parameters containing your route stops.

    First, connect slots for the signals createDefaultParametersCompleted and solveRouteCompleted.

    // connect to createDefaultParametersCompleted signal
    connect(m_routeTask, &RouteTask::createDefaultParametersCompleted, this, [this](QUuid, RouteParameters routeParameters)
    {
      // Store the resulting route parameters
      m_routeParameters = routeParameters;
    });
    
    
    // connect to solveRouteCompleted signal
    connect(m_routeTask, &RouteTask::solveRouteCompleted, this, [this](QUuid, RouteResult routeResult)
    {
      // Add the route graphic once the solve completes
      Route generatedRoute = routeResult.routes().at(0);
      Graphic* routeGraphic = new Graphic(generatedRoute.routeGeometry(), this);
      m_routeGraphicsOverlay->graphics()->append(routeGraphic);
    
    
      // set the direction maneuver list model
      m_directions = generatedRoute.directionManeuvers(this);
      emit directionsChanged();
    
    
      // emit that the route has solved successfully
      emit solveRouteComplete();
    });

    Then, solve the route.

    void FindRoute::solveRoute()
    {
      if (m_routeTask->loadStatus() == LoadStatus::Loaded)
      {
        if (!m_routeParameters.isEmpty())
        {
          // set parameters to return directions
          m_routeParameters.setReturnDirections(true);
           // clear previous stops from the parameters
          m_routeParameters.clearStops();
           // set the stops to the parameters
          Stop stop1(m_stopsGraphicsOverlay->graphics()->at(0)->geometry());
          stop1.setName("Origin");
          Stop stop2(m_stopsGraphicsOverlay->graphics()->at(1)->geometry());
          stop2.setName("Destination");
          m_routeParameters.setStops(QList<Stop>() << stop1 << stop2);
           // solve the route with the parameters
          m_routeTask->solveRoute(m_routeParameters);
        }
      }
    }

  4. Do one or both of the following to prepare for displaying the resulting route when it's created:
    • To display the resulting route lines on the map, create a GraphicsOverlay and read the geometry of the route from the route result, as shown in the previous code snippet.
    • You can get turn-by-turn directions by listing each DirectionManeuver from the route result. Each step of the route is represented in a DirectionManeuver and the class contains time, distance, geometry, and direction text describing each maneuver.

      You can use a ListView QML component to display the directions as a list.

      ListView {
          id: directionsView
          anchors {
              fill: parent
              margins: 5 * scaleFactor
          }
          header: Component {
              Text {
                  height: 40 * scaleFactor
                  text: "Directions:"
                  font.pixelSize: 22 * scaleFactor
              }
          }
      
      
          // set the model to the DirectionManeuverListModel returned from the route
          model: findRouteSample.directions
          delegate: directionDelegate
      }

How much will my routing app cost?

The cost points to consider when creating your routing app are the following:

  • You might need a paid deployment plan.
    • If you want to deploy an app that you charge users for and your app uses ArcGIS Online, then you must purchases a paid deployment plan.
    • If you want to deploy an app that uses more than 50 ArcGIS Online credits per month, then you must purchase a paid deployment plan.
  • If you want to deploy an app that uses more ArcGIS Online credits than the number of credits that came with your ArcGIS Developer Subscription, then you'll need to do one of the following:
    • Purchase credits as you use them
    • Purchase a deployment plan
    • Use named users and pass the cost of credits on to those users
  • Named users in a production environment have a cost associated with them. This is not necessarily your cost, as the developer. Whoever owns the organization on ArcGIS Online or whoever owns the license for ArcGIS Enterprise portal pays for the named users.
  • If your app consumes services hosted by ArcGIS Server or ArcGIS Enterprise portal, then there is a cost (not necessarily to you, the developer) for licensing ArcGIS Server or ArcGIS Enterprise portal in order to host those services.
  • If your app uses a Basic, Standard, Advanced, or Analysis license level of ArcGIS Runtime, then you must purchase that license. If your app runs offline, you may have to purchase deployment packs. For a list of capabilities and the license level they require, see Licensing capabilities in "License your app."