Local server services

View on GitHub
Sample viewer app

Demonstrates how to start and stop the Local Server and start and stop a local map, feature, and geoprocessing service running on the Local Server.

screenshot

Use case

For executing offline geoprocessing tasks in your ArcGIS Runtime apps via an offline (local) server.

How to use the sample

Click Start Local Server to start the Local Server. Click Stop Local Server to stop the Local Server.

The Map Service combo box lets you to pick a local service that is available.

After browsing for the desired file, click Start Service to start the selected service.

When the running service's url appears, select it and click Open Url. To stop this running service, click Stop Service.

How it works

  1. Create it with LocalServer::instance and use LocalServer::start() to start the server asynchronously.
  2. LocalServer::statusChanged() fires whenever the running status of the Local Server changes. Wait for the server to be in the LocalServerStatus::Started state.
  3. Create and run a local service. Here is an example of running a LocalMapService:

    • new LocalMapService(Url) creates a local map service with the given URL path to map package (mpkx file).
    • LocalMapService::start() starts the service asynchronously.
    • The service is added to the LocalServer automatically.

To stop a LocalServer and stop any LocalServices that are added to it:

  1. Get any services that are currently running on the local server with LocalServer::services().
  2. Loop through all services and stop the selected service (from the dropdown) if it is started.
  3. Use LocalService::status() to check if the service's status is LocalServerStatus::Started.
  4. LocalService::stop() stops the service asynchronously.
  5. LocalService::statusChanged() fires whenever the running status of the local service has changed. Wait for all services to be in the LocalServerStatus::Stopped state.
  6. Stop the local server with LocalServer::stop().

Relevant API

  • LocalFeatureService
  • LocalGeoprocessingService
  • LocalMapService
  • LocalServer
  • LocalServerStatus
  • LocalService

Offline Data

Read more about how to set up the sample's offline data here.

Link Local Location
PointsOfInterest map package <userhome>/ArcGIS/Runtime/Data/mpkx/PointsofInterest.mpkx
Contour geoprocessing package <userhome>/ArcGIS/Runtime/Data/gpkx/Contour.gpkx

Additional information

Local Server can be downloaded for Windows and Linux platforms. Local Server is not supported on macOS.

Tags

feature, geoprocessing, local services, map, server, service

Sample Code

LocalServerServices.qmlLocalServerServices.cppLocalServerServices.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// [WriteFile Name=LocalServerServices, Category=LocalServer]
// [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 Qt.labs.platform 1.0
import Esri.Samples 1.0

LocalServerServicesSample {
    id: localServerServicesSample

    Column {
        spacing: 10
        anchors.fill: parent
        anchors.margins: 15

        Row {
            id: topRow
            spacing: 10

            Button {
                id: startButton
                text: "Start Local Server"
                width: localServerServicesSample.width * 0.475

                onClicked: {
                    startLocalServer();
                }
            }

            Button {
                id: stopButton
                text: "Stop Local Server"
                width: localServerServicesSample.width * 0.475
                enabled: isServerRunning & !isServiceRunning

                onClicked: {
                    stopLocalServer();
                }
            }
        }

        Row {
            spacing: 10

            ComboBox {
                id: servicesCombo
                property int modelWidth: 0
                width: modelWidth + leftPadding + rightPadding + indicator.width

                enabled: isServerRunning
                model: ["Map Service", "Feature Service", "Geoprocessing Service"]

                onCurrentIndexChanged: {
                    filePathText.text = "";
                }

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

                TextMetrics {
                    id: metrics
                    font: servicesCombo.font
                }
            }

            TextField {
                id: filePathText
                placeholderText: "Browse for a file."
                selectByMouse: true
                width: startServiceButton.width - (40)
            }

            Button {
                id: fileDialogButton
                text: "..."
                width: 30
                enabled: isServerRunning

                onClicked: {
                    fileDialog.visible = true;
                }
            }
        }

        Row {
            spacing: 10

            Button {
                id: startServiceButton
                text: "Start Service"
                width: localServerServicesSample.width * 0.475
                enabled: isServerRunning

                onClicked: {
                    startService(servicesCombo.currentText, filePathText.text);
                }
            }

            Button {
                id: stopServiceButton
                text: "Stop Service"
                width: localServerServicesSample.width * 0.475
                enabled: isServiceRunning

                onClicked: {
                    if (servicesList.length === 1)
                        stopService(servicesList[0]);
                    else
                        stopService(servicesView.currentValue);
                }
            }
        }

        TextArea {
            id: serverStatusTextArea
            width: startButton.width + servicesCombo.width + (10)
            height: 200
            text: serverStatus
        }

        Text {
            text: "List of Running Services"
        }

        ListView {
            id: servicesView
            width: startButton.width + servicesCombo.width + (10)
            height: 200
            model: servicesList.length
            delegate: servicesDelegate
            property string currentValue: ""
            onCurrentIndexChanged: currentValue = servicesList[currentIndex]
        }
    }


    Button {
        anchors {
            right: parent.right
            bottom: parent.bottom
            margins: 10
        }
        text: "Open Url"
        visible: servicesView.model > 0

        onClicked: {
            openURL(servicesView.currentValue);
        }
    }

    Component {
        id: servicesDelegate

        Rectangle {
            id: rect
            width: parent.width
            height: 35
            color: ListView.isCurrentItem ? "lightsteelblue" : "white"

            Text {
                text: servicesList[index]
                anchors {
                    left: parent.left
                    right: parent.right
                    verticalCenter: parent.verticalCenter
                    leftMargin: 5
                }
                elide: Text.ElideLeft
                font.pixelSize: 14

                MouseArea {
                    anchors.fill: parent
                    cursorShape: Qt.PointingHandCursor
                    onClicked: servicesView.currentIndex = index;
                }
            }
        }
    }

    FileDialog {
        id: fileDialog
        title: "Please choose a file"
        folder: dataPath
        nameFilters: servicesCombo.currentIndex === 0 || servicesCombo.currentIndex === 1 ? ["Map Packages (*.mpk *.mpkx)", "All files (*)"] : ["Geoprocessing Packages (*gpk *.gpkx)", "All files (*)"]
        onAccepted: {
            filePathText.text = file;
        }
    }
}

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