Use Local Server

Run local geoprocessing services

Local geoprocessing service instances are created from geoprocessing packages (.gpkx files), authored and packaged using ArcGIS Pro. When packaging a geoprocessing result in ArcGIS Pro for use with Local Server, use the Package Result geoprocessing tool and ensure the Support ArcGIS Runtime option in the Parameters pane is checked. If this option is unchecked the geoprocessing package will not support creating a local service.

To run a local geoprocessing service, create and start the local service then use the URL property to create a GeoprocessingTask.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // Create a local geoprocessing service from the path provided to the .gpkx file.
    m_localGPService = new LocalGeoprocessingService(m_dataPath + "/gpkx/Contour.gpkx", this);

    // Check if the static local server instance is valid.
    if (LocalServer::isInstallValid())
    {
        // Call a custom function that creates a geoprocessing task.
        connectSignals();

        // Check if the local server has started
        // and start it if needed.
        if (LocalServer::status() == LocalServerStatus::Started)

            m_localGPService->start();
        else
            LocalServer::start();
    }

Once started, the Url of the LocalGeoprocessingService can be used to create a GeoprocessingTask.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // This connection creates a GeoProcessing task from the local geoprocesing service.
    connect(m_localGPService, &LocalGeoprocessingService::statusChanged, this, [this]()
    {
        // Check if the static local service has started.
        if (m_localGPService->status() == LocalServerStatus::Started)
        {
            // Create a geoprocessing task using the provided url.
            m_gpTask = new GeoprocessingTask(QUrl(m_localGPService->url().toString()
                        + "/Contour"), this);

            // Notify the app that local server task is running.
            m_isReady = true;
            emit isReadyChanged();
        }
    });

Access output data from local geoprocessing services

When running geoprocessing tools in the context of Local Server, the recommended approach for output data is to write the output data to a specific location on the local file system instead of returning a parameter of type GeoprocessingDataFile and using the GetFileAsync method to return the content via http. You can derive the location in your application code or it can be defined by the script/model using one of the follow approaches:

  • Expose an input parameter in the script/model representing the path where the output should be written to the local file system. Your application code should calculate/derive the location and pass that into the task input parameters.

  • Calculate/derive a path within the script/model where the output will be written to the local file system and return that as an output parameter in the script/model. The application code would then retrieve the location form the task output parameters.

Create and display local map services

Local map service instances are created from map packages (.mpkx files), authored and packaged using ArcGIS Pro. When packaging a map package in ArcGIS Pro, use the Package Map geoprocessing tool and ensure the Support ArcGIS Runtime option in the Parameters pane is checked. If this option is unchecked the map package will not support creating a local service.

To display a local map service, create and start the local service, then use the URL property to create an ArcGIS map image layer and add to the map.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // The following code assumes the local server install is valid and
    // the local server status is started.

    // Create a local map service from an mpkx file.
    LocalMapService* localMapService = new LocalMapService(m_dataDir
                                        + "/mpkx/RelationshipID.mpkx", this);

    // This connection ensures the local map service has started. If it has
    // started, create an ArcGIS Map image layer and add it to the map.
    connect(localMapService, &LocalMapService::statusChanged, this, [localMapService, this]()
    {
        // Check if the local server status is started, and return if not.
        if (localMapService->status() != LocalServerStatus::Started)
        {return;}

        // Create an ArcGIS map image layer from the local map service url.
        ArcGISMapImageLayer* mapImageLayer = new ArcGISMapImageLayer(QUrl(localMapService->url()), this);

        // Add the ArcGIS map image layer to the map's operational layers (layer list model).
        m_map->operationalLayers()->append(mapImageLayer);
    });

    // Attempt to start the local map service.
    localMapService->start();

Create and display local feature services

Local feature service instances are created from map packages (.mpkx files), authored and packaged using ArcGIS Pro. When packaging a map package in ArcGIS Pro, use the Package Map geoprocessing tool and ensure the Support ArcGIS Runtime option in the Parameters pane is checked. If this option is unchecked the map package will not support creating a local service.

To display a local feature service, create and start the local service, then use the URL property to create a feature layer and add to the map or to query the feature service use the URL to create a service feature table.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // The following code assumes the Local Server install is valid and
    // the local server status is started.

    // Create a local feature service from an mpkx file.
    LocalFeatureService* featureService = new LocalFeatureService(m_dataDir
                                          + "/mpkx/PointsofInterestZMvalues.mpkx", this);

    // This connection creates a feature layer from a service feature table. Then add the
    // feature layer to the map.
    connect(featureService, &LocalFeatureService::statusChanged, this, [featureService, this]()
    {
        // Create service feature table from the local feature service.
        ServiceFeatureTable* serviceFeatureTable = new ServiceFeatureTable(
            QUrl(featureService->url().toString() + "/0"), this);

        // Create a feature layer from the service feature table.
        FeatureLayer* featureLayer = new FeatureLayer(serviceFeatureTable, this);

        // Add the feature layer to the map (via the map's operational layers (layer list model)).
        m_map->operationalLayers()->append(featureLayer);
    });

    // Attempt to start the local feature service.
    featureService->start();

Manage local services

When using the Local Server you are effectively a server administrator. You choose which services to create, determine the server-side properties of the services, and manage the service life cycles. Unlike online services, where all the service parameters are predefined by the service publisher, you must specify the local service settings via the API based on how your application needs to interact with the local service.

The API provides a class to represent each service type, allowing you to set the source content, such as a map or geoprocessing package; set the service properties; and manage the service life cycle by starting and stopping the service as required by your workflow. Services must be set up with the appropriate package type to begin with, and then they can be started. Once the service has started, you can obtain its URL and use it in other API classes such as layers and tasks. For example, you can use the URL of a local map service to create an ArcGISMapImageLayer. If your application no longer requires the service, you can choose to stop specific services via the API, which will allow the system to reclaim any memory used by those services.

When creating local geoprocessing services to run geoprocessing tools and models, you must choose whether the service will run synchronously (SynchronousExecute), asynchronously (AsynchronousSubmit), or asynchronously with a dedicated local map service instance to draw the result (AsynchronousSubmitWithMapServiceResult). Once the service is running, it is not possible to change the execution type. Note that although the terms synchronous and asynchronous are used, these actually refer to the internal infrastructure the Local Server uses to manage these services, and from an API perspective the execution is always asynchronous. The decision is typically based on the type of analysis or processing that will be performed and the result type. If the tool will take less than a few seconds to run, the SynchronousExecute type is recommended. If the tool will take longer and you would like to be able to determine the progress via the API, and perhaps report this to the user, the AsynchronousSubmit type is recommended. In some cases, your analysis might return such a large number of features that it would be inadvisable to obtain the features directly and display them as graphics, and better to instead render them in a result map service. Additionally, raster datasets and raster layers are not directly supported as output data types and instead must be rendered in a result map service. In both these latter cases, you should choose the AsynchronousSubmitWithMapServiceResult execution type.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // Create a local geoprocessing service using the path to the .gpkx file.
    m_localGPService = new LocalGeoprocessingService(m_dataPath + "/gpkx/Contour.gpkx", this);

    // Set the service type to AsynchronousSubmitWithMapServerResult.
    m_localGPService->setServiceType(GeoprocessingServiceType::AsynchronousSubmitWithMapServerResult);

Administer the Local Server instance

LocalServer follows the singleton pattern which means there will be only one instance of LocalServer in your application. Use the LocalServer static property Instance to set instance-wide properties, such as the AppDataPath where geoprocessing and map packages will be extracted, or to access the collection of local services. Starting local services will automatically start the Local Server instance. Alternatively, for fine-grained control you can explcitly start the Local Server instance, for example to validate the license and installation before creating any local services.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // Set the temp & app data path for the local server.
    LocalServer::setTempDataPath(m_tempDirPath);
    LocalServer::setAppDataPath(m_tempDirPath);

    // This connection updates a hypothetical UI when the local server status
    // changes but is not necessary.
    // You can also check the local server status at any time with `LocalServer::status()`.
    connect(LocalServer::instance(), &LocalServer::statusChanged, this, [this]()
    {
        // Append current local server status to the status string m_serverStatus
        // and update a hypothetical UI.
        switch (LocalServer::status())
        {
        case LocalServerStatus::Starting:
        {
            m_serverStatus.append("Server Status: STARTING\n");
            break;
        }
        case LocalServerStatus::Started:
        {
            m_serverStatus.append("Server Status: STARTED\n");
            m_isServerRunning = true;
            emit isServerRunningChanged();
            break;
        }
        case LocalServerStatus::Stopping:
        {
            m_serverStatus.append("Server Status: STOPPING\n");
            break;
        }
        case LocalServerStatus::Stopped:
        {
            m_serverStatus.append("Server Status: STOPPED\n");
            m_isServerRunning = false;
            emit isServerRunningChanged();
            break;
        }
        case LocalServerStatus::Failed:
        {
            m_serverStatus.append("Server Status: FAILED\n");
            break;
        }
        default:
            break;
        }
        emit serverStatusChanged();
    });

    // Ensure the local server is properly installed.
    if (LocalServer::isInstallValid())

    {
        // Starts the local server asynchronously.
        // Note: Calling this method on a server that is running has no effect.
        LocalServer::start();
    }

When an application is closed the Local Server will automatically shutdown. You can also control this shutdown explicitly by calling LocalServer::stop(), for example if you want to stop the Local Server while your application continues running.

Use dark colors for code blocksCopy
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    // Shuts down the local server asynchronously.
    // Note: Calling this method on a server that is stopping or stopped has no effect.
    LocalServer::stop();

Debug information for Local Server

There are times when you would like access to additional debug information on services running in the Local Server and on the interaction between the API and the local service, just as you might do with remote services. This API and the Local Server SDK provide facilities for debugging. These are disabled by default. It is important to note the distinction between the Local Server instance within the SDK installation on your development machine and the Local Server deployment you create for your application. The SDK installation includes all components, including several features that can help you debug local services whereas a deployed instance of the Local Server will have debugging options disabled by default to minimize the disk footprint and to ensure the security of the Local Server.

Debug settings are administered via the Local Server Utility application. This is automatically included in the SDK installation of the Local Server but must be explicitly included in a deployment when specifying options in the configuration manifest file. The Local Server Utility provides you with the ability to control how applications work with the Local Server. You can choose to enable HTTP traffic to be viewed in a network monitoring tool, select the default port range to avoid conflicts with other applications, select the log level, and provide error reports.

The Local Server Utility can be accessed from the Windows Start menu or can be located in the Local Server SDK installation folder that can be found in C:\Program Files\ArcGIS SDKs\LocalServer200.x\64\bin\LocalServerUtility.exe (where x is the current release number).

 Utility

Local Server REST Services Directory

Local Server provides a services directory like the ArcGIS REST API Services Directory available with ArcGIS Enterprise and ArcGIS Online. It allows you to browse the service metadata of local services runing on the Local Server instance and obtain information that can be useful when developing applications. The Services Directory is a view of the Local Server REST API in HTML format. You can use this to discover how to write code to run your services.

The services directory can be accessed via the Local Server URL. The Local Server instance in the SDK installation includes the HTML server pages by default, while a deployment of the Local Server does not. This setting is controlled via the Local Server Utility setting Generate HTML Server Pages checkbox. Another setting in the Local Server Utility that determines how you work with the services directory is the Add Random Prefix to Server URLs option. If disabled, the Local Server will have a consistent URL each time it is started by your application, making it easier for you to work with the services directory between debugging sessions. Although local services cannot be accessed outside the local machine by any other user or application, the random prefix is enabled by default to provide additional security from applications running on the local machine.

 REST directory

Supported raster formats

Local Server supports the raster file formats supported by ArcGIS Pro.

Next steps

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