Service area

View inQMLC++
View on GitHub
Sample viewer app

Find the service area within a network from a given point.

screenshot

Use case

A service area shows locations that can be reached from a facility based off a certain impedance, such as travel time or distance. Barriers can increase impedance by either adding to the time it takes to pass through the barrier or by altogether preventing passage.

You might calculate the region around a hospital in which ambulances can service in 30 min or less.

How to use sample

  • In order to find any services areas at least one ServiceAreaFaciltiy needs to be added.
  • To add a facility, select "Facility" from the combo-box then click anywhere on the MapView.
  • To add a barrier, select "Barrier" from the combo-box and click multiple locations on the MapView to draw a barrier.
  • To start a new line in a distinct location, click "new barrier"
  • To show service areas around facilities that were added, click the "Solve" button.
  • The "Reset" button, clears all graphics and resets the ServiceAreaTask.

How it works

  1. Create a new ServiceAreaTask from a network service.
  2. Create default ServiceAreaParameters from the service area task.
  3. Set the parameters to return polygons (true) to return all service areas.
  4. Add a ServiceAreaFacility to the parameters.
  5. Get the ServiceAreaResult by solving the service area task using the parameters.
  6. Get any ServiceAreaPolygons that were returned, serviceAreaResult.getResultPolygons(facilityIndex).
  7. Display the service area polygons as graphics in a GraphicsOverlay on the MapView.

Relevant API

  • PolylineBarrier
  • ServiceAreaFacility
  • ServiceAreaParameters
  • ServiceAreaPolygon
  • ServiceAreaResult
  • ServiceAreaTask

Tags

barriers, facilities, impedance, logistics, routing

Sample Code

ServiceArea.qmlServiceArea.cppServiceArea.h
                                                                                                                                                   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// [WriteFile Name=ServiceArea, Category=Routing]
// [Legal]
// Copyright 2017 Esri.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]

import QtQuick 2.6
import QtQuick.Controls 2.2
import Esri.Samples 1.0

ServiceAreaSample {
    id: rootRectangle
    clip: true
    width: 800
    height: 600

    // add a mapView component
    MapView {
        id: mapView
        anchors.fill: parent
        objectName: "mapView"

        Rectangle {
            anchors.centerIn: solveRow
            radius: 8
            height: solveRow.height + (16)
            width: solveRow.width + (16)
            color: "lightgrey"
            border.color: "darkgrey"
            border.width: 2
            opacity: 0.75
        }

        Row {
            id: solveRow
            anchors {
                bottom: mapView.attributionTop
                horizontalCenter: parent.horizontalCenter
                margins: 15
            }
            spacing: 8

            Button {
                id: serviceAreasButton
                text: "Solve"
                enabled: !busy

                onClicked: solveServiceArea();
            }

            Button {
                text: "Reset"
                enabled: !busy
                onClicked: {
                    reset();
                }
            }
        }
    }

    Rectangle {
        anchors.centerIn: editRow
        radius: 8
        height: editRow.height + (16)
        width: editRow.width + (16)
        color: "lightgrey"
        border.color: "darkgrey"
        border.width: 2
        opacity: 0.75
    }

    Row {
        id: editRow
        anchors {
            top: parent.top
            left: parent.left
            margins: 24
        }
        spacing: 8

        ComboBox {
            id: modeComboBox
            model: ["Facility", "Barrier"]

            property int modelWidth: 0
            width: modelWidth + leftPadding + rightPadding + indicator.width

            onCurrentTextChanged: {
                if (currentText === "Facility")
                    setFacilityMode();
                else
                    setBarrierMode();
            }

            Component.onCompleted : {
                for (let i = 0; i < model.length; ++i) {
                    metrics.text = model[i];
                    modelWidth = Math.max(modelWidth, metrics.width);
                }
            }
            TextMetrics {
                id: metrics
                font: modeComboBox.font
            }
        }

        Button {
            id: newBarrierButton
            visible: modeComboBox.currentText === "Barrier"
            text: "new barrier"
            enabled: visible

            onClicked: {
                newBarrier();
            }
        }
    }

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

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.