Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for Qt

Find closest facility to an incident (interactive)

Sample Viewer View Sample on GitHub

Find a route to the closest facility from a location.

Use case

Quickly and accurately determining the most efficient route between a location and a facility is a frequently encountered task. For example, a paramedic may need to know which hospital in the vicinity offers the possibility of getting an ambulance patient critical medical care in the shortest amount of time. Solving for the closest hospital to the ambulance's location using an impedance of "travel time" would provide this information.

How to use the sample

Click near any of the hospitals and a route will be displayed from that clicked location to the nearest hospital.

How it works

  1. Create a ClosestFacilityTask using an Url from an online service.
  2. Get a ClosestFacilityParameters from this task, using createDefaultParameters.
  3. Add a list of facilities to the task parameters, using ClosestFacilityParameters.setFacilities.
  4. Add an incident to the parameters, using ClosestFacilityParameters.setIncidents(.
  5. Get the ClosestFacilityResult from solving the task with parameters: , ClosestFacilityTask.solveClosestFacility.
  6. Get the ranked list of the indices of the closest facilities to the incident, ClosestFacilityResult.rankedFacilities.
  7. Get the index of the closest facility (e.g. the first index in the ranked list).
  8. Find the closest facility route, ClosestFacilityResult.route.
  9. Display the route on the MapView:
  • create a Graphic from the route geometry, route.routeGeometry.
  • add graphic to GraphicsOverlay which is attached to the mapview.

Relevant API

  • ClosestFacilityParameters
  • ClosestFacilityResult
  • ClosestFacilityRoute
  • ClosestFacilityTask
  • Facility
  • Graphic
  • GraphicsOverlay
  • Incident
  • MapView

Tags

incident, network analysis, route, search

Sample Code

import QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.ArcGISRuntime 100.9

Rectangle {
    id: rootRectangle
    clip: true
    width: 800
    height: 600
    
    property bool busy: false
    property string message: ""
    property var facilities: []
    property var facilityParams: null

    // Map view UI presentation at top
    MapView {
        id: mapView

        anchors.fill: parent

        Map {
            BasemapStreets {}

            initialViewpoint: ViewpointCenter {
                Point {
                    x: -13041154
                    y: 3858170
                    spatialReference: SpatialReference { wkid: 3857 }
                }
                targetScale: 1e5
            }

            onLoadStatusChanged: {
                createFacilities();
                task.load();
            }
        }

        GraphicsOverlay {
            id: facilitiesOverlay

            SimpleRenderer {
                PictureMarkerSymbol {
                    url: "https://static.arcgis.com/images/Symbols/SafetyHealth/Hospital.png"
                    height: 30
                    width: 30
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3042129900625112E7
                    y: 3860127.9479775648
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3042129900625112E7
                    y: 3860127.9479775648
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3042193400557665E7
                    y: 3862448.873041752
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3046882875518233E7
                    y: 3862704.9896770366
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3040539754780494E7
                    y: 3862924.5938606677
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3042571225655518E7
                    y: 3858981.773018156
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3039784633928463E7
                    y: 3856692.5980474586
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }

            Graphic {
                geometry: Point {
                    x: -1.3049023883956768E7
                    y: 3861993.789732541
                    spatialReference: SpatialReference { wkid: 3857 }
                }
            }
        }

        GraphicsOverlay {
            id: resultsOverlay
        }

        onMouseClicked: {
            if (busy === true)
                return;

            if (facilityParams === null)
                return;

            resultsOverlay.graphics.clear();

            const incidentGraphic = ArcGISRuntimeEnvironment.createObject("Graphic", {
                                                                              geometry: mouse.mapPoint,
                                                                              symbol: incidentSymbol
                                                                          });
            resultsOverlay.graphics.append(incidentGraphic);

            solveRoute(mouse.mapPoint);
        }
    }

    SimpleMarkerSymbol {
        id: incidentSymbol
        style: Enums.SimpleMarkerSymbolStyleCross
        color: "black"
        size: 20
    }

    SimpleLineSymbol {
        id: routeSymbol
        style: Enums.SimpleLineSymbolStyleSolid
        color: "blue"
        width: 2.0
    }

    ClosestFacilityTask {
        id: task
        url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/ClosestFacility"

        onLoadStatusChanged: {
            if (loadStatus !== Enums.LoadStatusLoaded)
                return;

            setupRouting();
        }

        onCreateDefaultParametersStatusChanged: {
            if (createDefaultParametersStatus !== Enums.TaskStatusCompleted)
                return;

            busy = false;
            facilityParams = createDefaultParametersResult;
            facilityParams.setFacilities(facilities);
        }

        onSolveClosestFacilityStatusChanged: {
            if (solveClosestFacilityStatus !== Enums.TaskStatusCompleted)
                return;

            busy = false;

            if (solveClosestFacilityResult === null || solveClosestFacilityResult.error)
                message = "Incident not within San Diego Area!";

            const rankedList = solveClosestFacilityResult.rankedFacilityIndexes(0);
            const closestFacilityIdx = rankedList[0];

            const incidentIndex = 0; // 0 since there is just 1 incident at a time
            const route = solveClosestFacilityResult.route(closestFacilityIdx, incidentIndex);

            const routeGraphic = ArcGISRuntimeEnvironment.createObject("Graphic", {
                                                                           geometry: route.routeGeometry,
                                                                           symbol: routeSymbol
                                                                       });
            resultsOverlay.graphics.append(routeGraphic);
        }

        onErrorChanged: message = error.message;
    }

    BusyIndicator {
        anchors.centerIn: parent
        running: busy
    }

    Dialog {
        modal: true
        x: Math.round(parent.width - width) / 2
        y: Math.round(parent.height - height) / 2
        standardButtons: Dialog.Ok
        title: "Route Error"
        visible: text.length > 0
        property alias text : textLabel.text
        Text {
            id: textLabel
            text: message
        }
    }

    function createFacilities() {
        facilitiesOverlay.graphics.forEach(graphic => facilities.push(ArcGISRuntimeEnvironment.createObject("Facility", {
                                                                                                                geometry: graphic.geometry
                                                                                                            })));
    }


    function setupRouting() {
        busy = true;
        message = "";
        task.createDefaultParameters();
    }

    function solveRoute(incidentPoint) {
        const incident = ArcGISRuntimeEnvironment.createObject("Incident", {geometry: incidentPoint});
        facilityParams.setIncidents( [ incident ] );

        busy = true;
        message = "";
        task.solveClosestFacility(facilityParams);
    }
}