How to Find Routes Between Locations Using ArcGIS Map SDK in Qt

Routing and directions with ArcGIS Map SDK - Manya Technologies

Routing between two or more locations is a fundamental GIS functionality widely used in logistics, transportation, fleet management, and navigation applications. Using the ArcGIS Runtime SDK for Qt, developers can integrate routing capabilities directly into their applications, providing real-time navigation with optional traffic-aware routing.

In this blog post, we will walk you through a working example of how to calculate and display routes on a map, using Qt C++ and ArcGIS Map SDK.


Use Cases

  1. Fleet and Logistics Management – Calculate optimal delivery routes with real-time traffic integration.
  2. Navigation Applications – Enable end-users to get directions between locations.
  3. Emergency Services – Determine the fastest route to an incident with traffic-aware routing.
  4. Tourism Apps – Guide users to points of interest efficiently.

Solution: Implementing Routing with ArcGIS SDK

We will create a Qt C++ application that:

  • Displays a map using MapQuickView.
  • Lets the user select a start and end point with a click.
  • Calculates and displays the route between those points.
  • Shows turn-by-turn directions.

Below is the working code example:

#include <ArcGISRuntime.h>
using namespace Esri::ArcGISRuntime;

Rootand_dir::Rootand_dir(QObject *parent /* = nullptr */)
    : QObject(parent)
    , m_map(new Map(BasemapStyle::ArcGISStreets, this))
    , m_currentState(RouteBuilderStatus::NotStarted)
{
    setupRouteTask();
}

Rootand_dir::~Rootand_dir() = default;

MapQuickView* Rootand_dir::mapView() const { return m_mapView; }

void Rootand_dir::setMapView(MapQuickView* mapView)
{
    if (!mapView || m_mapView == mapView) return;

    m_mapView = mapView;
    m_mapView->setMap(m_map);
    setupViewpoint();
    emit mapViewChanged();
}

void Rootand_dir::setupViewpoint()
{
    const Point center(77.5775, 12.9629, SpatialReference::wgs84());
    const Viewpoint viewpoint(center, 144447.638572);
    m_mapView->setViewpointAsync(viewpoint);

    connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouse) {
        const Point mapPoint = m_mapView->screenToLocation(mouse.position().x(), mouse.position().y());
        switch (m_currentState) {
            case RouteBuilderStatus::NotStarted:
                resetState();
                m_currentState = RouteBuilderStatus::SelectedStart;
                m_startGraphic->setGeometry(mapPoint);
                break;
            case RouteBuilderStatus::SelectedStart:
                m_currentState = RouteBuilderStatus::SelectedStartAndEnd;
                m_endGraphic->setGeometry(mapPoint);
                findRoute();
                break;
            default: break;
        }
    });

    m_graphicsOverlay = new GraphicsOverlay(this);
    m_mapView->graphicsOverlays()->append(m_graphicsOverlay);

    // Setup symbols for start, end, and route line
    SimpleLineSymbol* startOutline = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 2, this);
    SimpleMarkerSymbol* startSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Diamond, QColor("orange"), 12, this);
    startSymbol->setOutline(startOutline);
    m_startGraphic = new Graphic(this); m_startGraphic->setSymbol(startSymbol);

    SimpleLineSymbol* endOutline = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("red"), 2, this);
    SimpleMarkerSymbol* endSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("green"), 12, this);
    endSymbol->setOutline(endOutline);
    m_endGraphic = new Graphic(this); m_endGraphic->setSymbol(endSymbol);

    SimpleLineSymbol* lineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor("blue"), 4, this);
    m_lineGraphic = new Graphic(this); m_lineGraphic->setSymbol(lineSymbol);

    m_graphicsOverlay->graphics()->append({m_startGraphic, m_endGraphic, m_lineGraphic});
}

void Rootand_dir::setupRouteTask()
{
    m_routeTask = new RouteTask(QUrl("https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World"), this);

    m_routeTask->createDefaultParametersAsync().then(this, [this](const RouteParameters& params) {
        m_routeParameters = params;
    });
}

void Rootand_dir::findRoute()
{
    if (m_routeTask->loadStatus() != LoadStatus::Loaded || m_routeParameters.isEmpty())
        return;

    m_routeParameters.setReturnDirections(true);
    m_routeParameters.clearStops();
    m_routeParameters.setStops({ Stop(Point(m_startGraphic->geometry())), Stop(Point(m_endGraphic->geometry())) });

    m_routeTask->solveRouteAsync(m_routeParameters).then(this, [this](const RouteResult& routeResult) {
        const Route route = routeResult.routes().at(0);
        m_lineGraphic->setGeometry(route.routeGeometry());
        m_currentState = RouteBuilderStatus::NotStarted;

        m_directions = route.directionManeuvers(this);
        emit directionsChanged();
    });
}

Routing With Traffic Awareness

ArcGIS Online and certain premium services allow traffic-based routing. To enable it:

  1. Use a traffic-enabled RouteTask endpoint.
  2. Set m_routeParameters.setReturnTraffic(true) before solving the route.
  3. This will adjust route directions dynamically based on live traffic conditions.

Conclusion

Using the ArcGIS Runtime SDK for Qt, it’s straightforward to create interactive routing applications with start/end selection, turn-by-turn directions, and traffic-aware route calculation. This can be used for standalone desktop applications, embedded devices, or cloud-based GIS solutions.

At Manya Technologies, we specialize in building custom GIS applications using ArcGIS, CesiumJS, Qt, and cloud platforms. Whether it’s real-time routing, 3D map visualization, or fleet management applications, we deliver scalable and robust solutions tailored to your needs.

📩 Contact us to discuss your next GIS or navigation application: https://manyatechnologies.com/

Scroll to Top