Work with trace results

Depending on what you need to do with the results, you can work with the appropriate return type you configured in the parameters. The following types of results may be returned when executing the trace:

  • Elements—Element results provide the that are found by a trace. Use these results when you need access to individual utility elements, their corresponding , and their . This is the default trace result type.

  • Geometry—Geometry results contains multipart geometries that represent the union of the for all elements returned. These results are best for displaying the trace result on a map.

  • Functions—A function is a trace configuration that allows you to run calculations on network attributes associated with traced features. A function output is returned for every function defined in the configuration.

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
var traceResults = await utilityNetwork.TraceAsync(traceParameters);

foreach (var result in traceResults)
{
    if (result.Warnings.Count > 0)
        Debug.WriteLine($"Trace Result Warnings:\n\t{string.Join("\n", result.Warnings)}");

    if (result.NearestNeighborResult != UtilityNearestNeighborResult.NotApplicable)
        Debug.WriteLine($"Nearest Neighbor: {result.NearestNeighborResult}");
}

Element results

If you need fine-grained access to the results, such as the ability to work with individual from the , you need to obtain the corresponding for these elements from the utility element results.

You can use the element's to match its against the layer's table by instance or name.

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
if (traceResult is UtilityElementTraceResult elementResult)
{
    foreach (var layer in MainMapView.Map.OperationalLayers.OfType<FeatureLayer>())
    {
        var elements = elementResult.Elements.Where(el => el.NetworkSource.FeatureTable == layer.FeatureTable);
        if (!elements.Any())
            continue;

        var features = await utilityNetwork.GetFeaturesForElementsAsync(elements);
        if (!features.Any())
            continue;

        layer.SelectFeatures(features);
    }
}

Function results

If function results are included, they will contain a UtilityTraceFunctionOutput for every UtilityTraceFunction that was defined in the UtilityTraceConfiguration. Each UtilityTraceFunctionOutput contains the original function definition as well as the function result.

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
if (traceResult is UtilityFunctionTraceResult functionResult)
{
    foreach (var functionOutput in functionResult.FunctionOutputs)
    {
        Debug.WriteLine($"{functionOutput.Function.FunctionType} on " +
            $"'{functionOutput.Function.NetworkAttribute.Name}':\n\t" +
            $"{functionOutput.Result}");
    }
}

If the function includes a condition, you can summarize this expression GetExpression(functionOutput.Function.Condition) using the following helper methods:

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
private static string GetExpression(UtilityTraceCondition? expression)
{
    if (expression is null)
        return string.Empty;

    if (expression is UtilityCategoryComparison categoryComparison)
        return $"`{categoryComparison.Category.Name}` {categoryComparison.ComparisonOperator}";

    if (expression is UtilityNetworkAttributeComparison attributeComparison)
    {
        var value = GetValue(attributeComparison.NetworkAttribute.DataType, attributeComparison.Value);
        if (attributeComparison.NetworkAttribute.Domain is CodedValueDomain codedValueDomain)
            value = codedValueDomain.CodedValues.FirstOrDefault(c => value?.Equals(GetValue(attributeComparison.NetworkAttribute.DataType, c.Code)) == true)?.Name;
        return $"`{attributeComparison.NetworkAttribute.Name}` {attributeComparison.ComparisonOperator}  {value}";
    }

    if (expression is UtilityTraceAndCondition andCondition)
        return $"({GetExpression(andCondition.LeftExpression)} AND {GetExpression(andCondition.RightExpression)})";

    if (expression is UtilityTraceOrCondition orCondition)
        return $"({GetExpression(orCondition.LeftExpression)} OR {GetExpression(orCondition.RightExpression)})";

    return string.Empty;
}

private static object? GetValue(UtilityNetworkAttributeDataType type, object? value)
{
    if (value is null)
        return value;

    switch (type)
    {
        case UtilityNetworkAttributeDataType.Boolean:
            return System.Convert.ToBoolean(value);
        case UtilityNetworkAttributeDataType.Double:
            return System.Convert.ToDouble(value);
        case UtilityNetworkAttributeDataType.Float:
            return System.Convert.ToSingle(value);
        case UtilityNetworkAttributeDataType.Integer:
            return System.Convert.ToInt32(value);
        default:
            break;
    }
    return value;
}

Geometry results

Geometry results make it easy to display the result as in the . At most, geometry results will contain three (multipart) geometries: one , one , and one . Each geometry represents the union of the geometry of the results of that spatial type. The UtilityGeometryTraceResult exposes the geometry result for each potential geometry type. If the result does not include a certain geometry type, the corresponding property will be null.

Get the geometry results from the trace results. Depending how the trace parameters were defined (i.e. which result types were requested), there may be more than one result type. Create a new graphic for each geometry in the geometry results, check if there's any need to reproject to the map's , use a symbology appropriate for the geometry type, and add them to a graphics overlay in the map view.

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
if (traceResult is UtilityGeometryTraceResult geometryResult)
{
    if (geometryResult.Multipoint is Multipoint multipoint)
    {
        if (MainMapView.SpatialReference != null &&
            multipoint.SpatialReference != MainMapView.SpatialReference &&
            GeometryEngine.Project(multipoint, MainMapView.SpatialReference) is Multipoint projectedMultipoint)
            multipoint = projectedMultipoint;

        var graphic = new Graphic(multipoint, pointSymbol);
        overlay.Graphics.Add(graphic);
    }

    if (geometryResult.Polyline is Polyline polyline)
    {
        if (MainMapView.SpatialReference != null &&
            polyline.SpatialReference != MainMapView.SpatialReference &&
            GeometryEngine.Project(polyline, MainMapView.SpatialReference) is Polyline projectedPolyline)
            polyline = projectedPolyline;

        var graphic = new Graphic(polyline, lineSymbol);
        overlay.Graphics.Add(graphic);
    }

    if (geometryResult.Polygon is Polygon polygon)
    {
        if (MainMapView.SpatialReference != null &&
            polygon.SpatialReference != MainMapView.SpatialReference &&
            GeometryEngine.Project(polygon, MainMapView.SpatialReference) is Polygon projectedPolygon)
            polygon = projectedPolygon;

        var graphic = new Graphic(polygon, fillSymbol);
        overlay.Graphics.Add(graphic);
    }
}

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

You can no longer sign into this site. Go to your ArcGIS portal or the ArcGIS Location Platform dashboard to perform management tasks.

Your ArcGIS portal

Create, manage, and access API keys and OAuth 2.0 developer credentials, hosted layers, and data services.

Your ArcGIS Location Platform dashboard

Manage billing, monitor service usage, and access additional resources.

Learn more about these changes in the What's new in Esri Developers June 2024 blog post.

Close