Trace configuration

Using ArcGIS Pro, a utility network can be created and configured manually using the suite of geoprocessing tools available in the Utility Network Tools toolbox. The Trace Configuration toolset in that toolbox contains tools to create named trace configurations in your utility network. Named trace configurations allow you to configure and store the properties of complex traces. Your ArcGIS Maps SDK for Qt app can read named trace configurations when performing traces with a utility network.

While you can create trace configurations on demand (programmatically), these are typically configured ahead of time and stored as a named trace configuration. A common workflow is to read a named trace configuration from the utility network and update its properties as needed for a particular trace.

Trace configuration from a tier

When the administrator configures the subnetwork trace, a default trace configuration can be obtained from a utility network tier with the names of the domain network and the tier.

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Get the utility network definition from the utility network
    UtilityNetworkDefinition* utilityNetworkDefinition = utilityNetwork->definition();

    // Get the utility domain network from the utility network definition for the name "Gas"
    UtilityDomainNetwork* utilityDomainNetwork = utilityNetworkDefinition->domainNetwork("Gas");

    // Get the utility tier from the utility domain network for the tier name "Pipe Distribution System"
    UtilityTier* utilityTier = utilityDomainNetwork->tier("Pipe Distribution System");

    // For the utility trace parameters, set the trace configuration to the utility tier's default trace configuration
    utilityTraceParameters->setTraceConfiguration(utilityTier->defaultTraceConfiguration());

Named trace configurations

Support for named trace configurations is available in ArcGIS Enterprise 10.9 or later. The same set of configurations can be made available to all desktop, web, and mobile users. Administrators can also choose to share a subset of these with a web map to provide configurations specific to those contents.

The following code shows how to get named trace configurations from a specific creator with a particular tag and then run a trace with a configuration matching this search criteria.

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Create a utility named trace configuration query parameters
    UtilityNamedTraceConfigurationQueryParameters* utilityNamedTraceConfigurationQueryParameters = new
        UtilityNamedTraceConfigurationQueryParameters(this);

    // Get the QStringList of creators from the utility named trace configuration query parameters and
    // add the creator named "unadmin"
    QStringList qstringlistCreators = utilityNamedTraceConfigurationQueryParameters->creators();
    qstringlistCreators.append("unadmin");

    // Get the QStringList of tags from the utility named trace configuration query parameters and add
    // the tag named "electric"
    QStringList qstringlistTags = utilityNamedTraceConfigurationQueryParameters->tags();
    qstringlistTags.append("electric");

    // Get the QList of utility named trace configurations from the utility network via the
    // queryNamedTraceConfigurationsAsync method (QFuture)
    utilityNetwork->queryNamedTraceConfigurationsAsync(utilityNamedTraceConfigurationQueryParameters, this).then
        (this, [utilityNetwork, startingUtilityElement, this]
    (QList<UtilityNamedTraceConfiguration*> utilityNamedTraceConfigurations)
    {
        // Get the first utility named trace configuration
        UtilityNamedTraceConfiguration* utilityNamedTraceConfiguration = utilityNamedTraceConfigurations.first();

        // Create a QList of utility elements and add the startingUtilityElement
        QList<UtilityElement*> utilityElements;
        utilityElements.append(startingUtilityElement);

        // Create a utility trace parameters from the utility named trace configuration and QList of
        // utility elements
        UtilityTraceParameters* utilityTraceParameters = new UtilityTraceParameters(utilityNamedTraceConfiguration,
                                                                                    utilityElements, this);

        // Get the QList of utility trace results from the utility network via the traceAsync method (QFuture)
        utilityNetwork->traceAsync(utilityTraceParameters, this).then(this,[]
        (QList<UtilityTraceResult*> utilityTraceResults)
        {
            // TODO: process the utility trace results
        });
    });

An online utility network from a web map source may return a smaller subset of named trace configurations published for this utility network and applicable only to this 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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // When the map has provided the utility network trace configurations, continue processing
    connect (map, &Map::namedTraceConfigurationsFromUtilityNetworkCompleted, this,
            [this, aUtilityElement, utilityNetwork](const QUuid&,
            const QList<UtilityNamedTraceConfiguration*>& namedTraceConfigurationsResults)
    {
        // Obtain the first utility named trace configuration from the results
        UtilityNamedTraceConfiguration* utilityNamedTraceConfiguration = namedTraceConfigurationsResults.first();

        // Get the name of the utility named trace configuration
        QString utilityNamedTraceConfigurationName = utilityNamedTraceConfiguration->name();

        // Only process further unless the name is "SubnetworkTraceWithFunctions"
        if (utilityNamedTraceConfigurationName == "SubnetworkTraceWithFunctions")
        {
            // Create a QList of utility elements and add the aUtilityElement
            QList<UtilityElement*> utilityElements;
            utilityElements.append(aUtilityElement);

            // Create a utility trace parameters from the utility named trace configuration and QList of
            // utility elements
            UtilityTraceParameters* utilityTraceParameters = new UtilityTraceParameters(
                utilityNamedTraceConfiguration, utilityElements, this);

            // Get the QList of utility trace results from the utility network via the traceAsync
            // method (QFuture)
            utilityNetwork->traceAsync(utilityTraceParameters, this).then(this,[]
            (QList<UtilityTraceResult*> utilityTraceResults)
            {
                // TODO: process the utility trace results
            });
        }
    });

    // Call the function to get the list of all utility network trace configurations in the utility
    // network's map
    map->namedTraceConfigurationsFromUtilityNetwork(utilityNetwork);

Trace configuration properties

A trace configuration can define things like:

  • The domain network on which the trace will run

  • Traversability barriers

  • A filter for the type of assets included in the results

  • Whether the results should include things like content in containers, structure features, and feature or condition barriers

  • Functions to compute while performing the trace

Trace configuration settings are exposed as properties on the UtilityTraceConfiguration class.

Traversability

As you trace a topological network, you can examine several constraints or conditions that could stop the trace. For example, you can stop tracing the network if:

  • A water valve is closed
  • An electric switch is open
  • A distance of 1000 m is reached
  • The gas pipe is made of plastic

The ability for a trace to traverse the topological network is defined by the UtilityTraversability in the UtilityTraceConfiguration class. You can set conditions or constraints for this trace using barriers and function barrier properties.

Barriers and function barriers used as traversability constraints are defined using a condition, such as a valve being closed, encountering a particular material type, reaching a specified threshold along the trace, and so on. This contrasts with barriers that are defined with trace parameters using utility network elements, often selected interactively by the user.

Barriers

Set up a trace barrier by comparing the value of an asset's attribute or by examining the existence of a UtilityCategory. You can compare them individually or combine them with boolean And/Or operations into complex filters.

  • Use the UtilityNetworkAttributeComparison class to compare an element's network attribute. For example, compare an attribute value to:
    • A specific value (for example, "DeviceStatus not equal to 4"), and/or
    • Another network attribute on the same element (for example, "SeasonalDeviceStatus" or "NormalDeviceStatus")
  • Check a utility element's asset type to see whether that asset type (and thus the element) is included in a specific category using the UtilityCategoryComparison class.
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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Get the utility network definition from the utility network
    UtilityNetworkDefinition* utilityNetworkDefinition = utilityNetwork->definition();

    // Get the "Lifecycle" utility network attribute from the utility network definition
    UtilityNetworkAttribute* lifecycleUtilityNetworkAttribute = utilityNetworkDefinition->networkAttribute("Lifecycle");

    // End the function if the "Lifecycle" utility network attribute is NULL
    if (lifecycleUtilityNetworkAttribute == NULL) {return;}

    // Create a utility network attribute comparison that stops traversal if "Lifecycle" <> 4)
    UtilityNetworkAttributeComparison* inDesignUtilityNetworkAttributeComparison = new UtilityNetworkAttributeComparison(
        lifecycleUtilityNetworkAttribute, UtilityAttributeComparisonOperator::NotEqual, 4, this);

    // Create a utility network attribute comparison to stop traversal if "Lifecycle" <> 8
    UtilityNetworkAttributeComparison* inServiceUtilityNetworkAttributeComparison = new UtilityNetworkAttributeComparison(
        lifecycleUtilityNetworkAttribute, UtilityAttributeComparisonOperator::NotEqual, 8, this);

    // Combine the two utility network attribute comparisons together with "And" to make a new utility trace and condition
    UtilityTraceAndCondition* lifecycleUtilityTraceAndCondition = new UtilityTraceAndCondition(
        inDesignUtilityNetworkAttributeComparison, inServiceUtilityNetworkAttributeComparison, this);

    // Get the utility transversability from the utility trace configuration
    UtilityTraversability* utilityTraversability = utilityTraceConfiguration->traversability();

    // Final condition stops traversal if Lifecycle <> 4 and Lifecycle <> 8
    utilityTraversability->setBarriers(lifecycleUtilityTraceAndCondition);

Function barriers

You can create a function barrier to terminate network traversal whenever a function expression evaluates to true. The function barrier compares the current results of a function and a given value. For example, you can use the function barrier to stop traversal after the trace traverses 1000 meters along the network.

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Get the utility network definition from the utility network
    UtilityNetworkDefinition* utilityNetworkDefinition = utilityNetwork->definition();

    // Get the "Shape length" utility network attribute from the utility network definition
    UtilityNetworkAttribute* shapelengthUtilityNetworkAttribute = utilityNetworkDefinition->networkAttribute("Shape length");

    // End the function if the "Shape length" utility network attribute is NULL
    if (shapelengthUtilityNetworkAttribute == NULL) {return;}

    // Create a utility trace function using the utility trace function type of "Add" and the
    // "Shape length" utility network attribute
    UtilityTraceFunction* shapelengthUtilityTraceFunction = new UtilityTraceFunction(
        UtilityTraceFunctionType::Add, shapelengthUtilityNetworkAttribute, this);

    // Create a utility trace function barrier that stops traversal after 1000 meters
    UtilityTraceFunctionBarrier* utilityTraceFunctionBarrier = new UtilityTraceFunctionBarrier(
        shapelengthUtilityTraceFunction, UtilityAttributeComparisonOperator::GreaterThan, 1000.0, this);

    // Get the utility transversability from the utility trace configuration
    UtilityTraversability* utilityTraversability = utilityTraceConfiguration->traversability();

    // Get the utility trace function barrier list model from the utility transversability
    UtilityTraceFunctionBarrierListModel* utilityTraceFunctionBarrierListModel = utilityTraversability->functionBarriers();

    // Add the utility trace function barrier to the utility trace function barrier list model
    utilityTraceFunctionBarrierListModel->append(utilityTraceFunctionBarrier);

Trace filters

Filters are a mechanism to stop tracing when returning results. They do not stop traversability to the controller.

A trace filter and traversability both have properties for defining barriers, function barriers, and scope. These properties work the same way in both classes. What makes them different is when they are applied and how they affect the trace.

While both traversability and trace filter can terminate a trace, they have slightly different use cases. In upstream and downstream traces, traversability is considered first because it determines the subnetwork controller and the flow direction of tracing. If the controller's type is source-based, the flow direction is away from the identified subnetwork controller. If the controller's type is sink-based, the flow direction is toward the controller. Once the starting location, subnetwork controller, and flow direction are established, the features that are traversable are then evaluated against the trace filter criteria.

If you want a trace to find the next upstream protective device in an electrical network, for example, create a UtilityCategoryComparison where 'Protective Device' category exists. If you set this barrier on traversability, the trace will fail; it will be unable to find a subnetwork controller to determine which direction is upstream. Instead, use a trace filter.

Trace filter barriers can be used to configure isolation traces. An isolation trace allows you to isolate a portion of the network using filter barriers. An upstream trace configured to use isolation valves as filter barriers will determine the boundary of the isolation zone, from which you can determine which customers are affected (out of service).

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Get the utility network definition from the utility network
    UtilityNetworkDefinition* utilityNetworkDefinition = utilityNetwork->definition();

    // Get the utility network source from the utility network definition of "Gas Line"
    UtilityNetworkSource* networNetworkSource = utilityNetworkDefinition->networkSource("Gas Line");

    // Get the utility asset group from the utility network source of "Distribution Pipe"
    UtilityAssetGroup* utilityAssetGroup = networNetworkSource->assetGroup("Distribution Pipe");

    // Get the utility asset type from the utility asset group of "Bare Steel"
    UtilityAssetType* utilityAssetType = utilityAssetGroup->assetType("Bare Steel");

    // Define the GUID for the utility element
    QUuid quuid("{B903103D-8933-4383-8C7B-A77FC705F32D}");

    // Get the utility element from the utility network with utility asset type and utiity element GUID
    UtilityElement* utilityElement = utilityNetwork->createElementWithAssetType(utilityAssetType, quuid);

    // Create a QList of utility elements and add the utility element
    QList<UtilityElement*> utilityElements;
    utilityElements.append(utilityElement);

    // Create a utility trace parameters using the utility trace type of "Isolation" and the QList
    // of utility elements
    UtilityTraceParameters* utilityTraceParameters = new UtilityTraceParameters(
        UtilityTraceType::Isolation, utilityElements, this);

    // Get the QList of utility categories from the utility network definition
    QList<UtilityCategory*> utilityCategories = utilityNetworkDefinition->categories();

    // Obtain the utility category with the name "IsolationDevice" from the QList of utility categories
    auto resultIterator = std::find_if(utilityCategories.begin(), utilityCategories.end(), [](UtilityCategory* c)
    {return c->name() == "IsolationDevice";});
    if (resultIterator == std::end(utilityCategories))
        return;
    UtilityCategory* foundUtilityCategory = (*resultIterator);

    // Create a utility category comparison using the found utility category, and the utility cagegory
    // comparison operator of "Exists"
    UtilityCategoryComparison* utilityCategoryComparison = new UtilityCategoryComparison(
        foundUtilityCategory, UtilityCategoryComparisonOperator::Exists, this);

    // Get the utility network attribute from the utility network definition where the network
    // attribute is "Accessible"
    UtilityNetworkAttribute* utilityNetworkAttribute = utilityNetworkDefinition->networkAttribute("Accessible");

    // Create a utility network attribute comparison using the utility network attribute, utility attribute
    // comparision operator of "Equal", and the value of 1 for the node in the trace
    UtilityNetworkAttributeComparison* utilityNetworkAttributeComparison = new UtilityNetworkAttributeComparison(
        utilityNetworkAttribute, UtilityAttributeComparisonOperator::Equal, 1, this);

    // Create a utility trace and condition using the utility category comparision, and the utility
    // network attribute comparison
    UtilityTraceAndCondition* utilityTraceAndCondition = new UtilityTraceAndCondition(
        utilityCategoryComparison, utilityNetworkAttributeComparison, this);

    // Create a utility trace filter and set the barriers to the utility trace and condition
    UtilityTraceFilter* utilityTraceFilter = new UtilityTraceFilter(this);
    utilityTraceFilter->setBarriers(utilityTraceAndCondition);

    // Create a utility trace configuration and set the filer to the utility trace filter and set the include
    // isolated features to `true`
    UtilityTraceConfiguration* utilityTraceConfiguration = new UtilityTraceConfiguration(this);
    utilityTraceConfiguration->setFilter(utilityTraceFilter);
    utilityTraceConfiguration->setIncludeIsolatedFeatures(true);

    // Get the QList of utility trace results from the utility network via the traceAsync method (QFuture)
    utilityNetwork->traceAsync(utilityTraceParameters, this).then(this, []
    (QList<UtilityTraceResult*> utilityTraceResults)
    {
        // TODO: process the utility trace results
    });

Bitset network attributes

Bitset network attributes are only applicable to upstream and downstream trace types. They can be used to add special logic during a trace so the trace is more reflective of real world scenarios.

There are cases where traces need to be aware that a network attribute is a bitset that controls traversability. For example, you might have an electrical network where phase is represented as a bitset network attribute (one bit per phase), and overhead electrical devices are represented with one device per phase. Use a bitset network attribute to ensure that trace results include valid paths specified in the network attribute, not all paths.

Nearest neighbor

The nearest neighbor filter, UtilityNearestNeighbor, allows you to return a specified number of features from the starting location of the trace. When assigned to a UtilityTraceFilter, it will return a number of features of a certain type within a given distance.

A network attribute that represents travel cost is used to define the distance, which is typically shape length. Other attributes may be more useful depending on circumstances. For example, if you are searching for the "nearest" vault in an underground structure network, you may prefer a geographically distant vault that is connected via a duct bank rather than a closer one through a direct-buried trench (since excavating the trench is more costly). In this case a different attribute that represents the cost per segment should be used.

The type of features to return can be specified by utility category, asset type, or both. A valid UtilityNearestNeighbor therefore, will have a cost network attribute, a count greater than 0, and at least one specified category or asset type.

Output filters

Output filters allow you to filter the type of elements returned as the result of a trace. When performing a trace on a utility network, you can limit the results to a specific asset type or output condition. An output filter screens every feature encountered during a trace to check if it meets the filter criteria. Only elements that satisfy these criteria are included in the trace result. For example, returning only protective devices from a trace of an electrical network.

There are two types of output filters available with the UtilityTraceConfiguration class:

  • Output asset types—Returns only the specified asset types in the trace results. For example, to create a pole report for an electric network, use an output asset type filter to only return poles in the results.

  • Output conditions—Supports network categories and network attributes. In an output condition, the name of the network attribute, an operator, and a value that is valid for the network attribute are specified. Returns only elements that fulfill a condition. This is the same type of condition used in traversability, and can perform comparisons against network attributes, categories, or both.

Trace output filters are applied after all other tracing calculations, including traversal, filters, and function calculation. Features that don't meet the filter criteria are still traced but are not included in the results. Both asset type and output condition filters can be used for the same trace. As an example, you could create an output filter to return only elements that belong to the "Plastic PE pipe" asset type, have a diameter of 12 inches, and a pressure greater than 80 PSI.

Propagators

A propagator defines the propagation of a network attribute along a traversal and provides a filter to stop traversal. Propagators are only applicable to subnetwork-based traces (subnetwork, upstream, or downstream). One example is electric phase propagation, where open devices along the network will restrict some phases from continuing along the trace.

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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    // Get the utility network definition from the utility network
    UtilityNetworkDefinition* utilityNetworkDefinition = utilityNetwork->definition();

    // Get the utility network attribute from the utility network definition of "Phase Normal"
    UtilityNetworkAttribute* utilityNetworkAttribute = utilityNetworkDefinition->networkAttribute("Phases Normal");

    // Create a  utility propagator using the utility network attribute, utility propagator function type of
    // "BitwiseAnd", and a value (7) for comparision when executing the trace
    UtilityPropagator* utilityPropagator = new UtilityPropagator(
        utilityNetworkAttribute, UtilityPropagatorFunctionType::BitwiseAnd,
        UtilityAttributeComparisonOperator::IncludesAny, 7, this);

    // Get the utility propagator list model from the utility trace configuration
    UtilityPropagatorListModel* utilityPropagatorListModel = utilityTraceConfiguration->propagators();

    // Add the utlity propagator to the utility propagator list model
    utilityPropagatorListModel->append(utilityPropagator);

Target tiers

All upstream and downstream traces can operate across the current tier (source tier). If you want your upstream or downstream trace to continue into another tier, you can specify the target tier on UtilityTraceConfiguration.

Tracing considerations

Dirty areas

All tracing operations rely on a topological index that is built from the utility network. If the network has been edited but the topology is out of date, it may contain dirty areas. For more information, see ArcGIS Pro's discussion validate the network topology. If the topological network has dirty areas, you can adopt a different approach depending on your app's purpose:

  • If the app must trace with the latest data (for example, an outage management app), an error should be returned to the user if it encounters a dirty area.
  • If the app can trace with a network that is out of sync with the feature (for example, a pole inspection app), then you should consider toggling the validate consistency setting to false on the UtilityTraceConfiguration. You can optionally display a warning to the user if a dirty area is encountered.

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