Depending on what you need to do with the results, you can work with the appropriate return type you configured in the trace parameters. The following types of results may be returned when executing the trace:
-
Elements—Element results provide the utility elements that are found by a trace. Use these results when you need access to individual utility elements, their corresponding features, and their attributes. This is the default trace result type.
-
Geometry—Geometry results contains multipart geometries that represent the union of the geometry 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.
// Execute the trace with these parameters.
coroutineScope.launch {
// Run the utility trace and get the results.
utilityNetwork.trace(parameters).onFailure { error ->
showError("Error tracing utility network: ${error.message}")
}.onSuccess { utilityTraceResults: List<UtilityTraceResult> ->
utilityTraceResults.forEach { utilityTraceResult ->
when (utilityTraceResult) {
// Access the utility elements for a utility element trace result.
is UtilityElementTraceResult -> {
val utilityElementTraceResult = utilityTraceResult
examineElementResults(utilityElementTraceResult.elements)
}
// Access the geometries for a geometry trace result.
// Use the multipoint, polygon, and polyline properties of the UtilityGeometryTraceResult instance.
is UtilityGeometryTraceResult -> {
val utilityGeometryTraceResult = utilityTraceResult
examineGeometryResults(utilityGeometryTraceResult)
}
// Access the function outputs for a function trace result.
is UtilityFunctionTraceResult -> {
val utilityGeometryTraceResult = utilityTraceResult
examineFunctionResults(utilityGeometryTraceResult.functionOutputs)
}
}
}
}
}
Element results
If you need fine-grained access to the results, such as the ability to work with individual utility elements from the trace, you need to obtain the corresponding features for these elements from the utility element results.
You can use the element's network source to match its table against the layer's table by instance or name.
// check if there are any elements in the result
if (utilityElements.isNotEmpty()) {
// Get the result features from each network source layer in the map.
map.operationalLayers.filterIsInstance<FeatureLayer>().forEach { featureLayer ->
// Clear previous selection.
featureLayer.clearSelection()
// Filter out the result elements that are part of the feature table.
val elements = utilityElements.filter { utilityElement ->
utilityElement.networkSource.name == featureLayer.featureTable?.tableName
}
utilityNetwork.getFeaturesForElements(elements).onFailure {
showError("Error getting features for elements.")
}.onSuccess { features ->
// Highlight features.
featureLayer.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.
utilityFunctionOutputs.forEach { utilityTraceFunctionOutput ->
// Get the original function (as defined in the trace configuration).
val utilityTraceFunction = utilityTraceFunctionOutput.function
val networkAttribute = utilityTraceFunction.networkAttribute
val functionType = utilityTraceFunction.functionType
}
Geometry results
Geometry results make it easy to display the trace result as graphics in the map view. At most, geometry results will contain three (multipart) geometries: one multipoint, one polyline, and one polygon. 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 spatial reference, use a symbology appropriate for the geometry type, and add them to a graphics overlay in the map view.
when (utilityTraceResult) {
is UtilityGeometryTraceResult -> examineGeometryResults(utilityTraceResult)
If geometry results are found, create a new graphic for each geometry in the geometry results and add them to a graphics overlay in the map view. If the result does not include a geometry type, it will be null.
// If there are no features of a particular geometry type, it will be null.
// Add each geometry to the graphics overlay.
utilityGeometryTraceResult.polygon?.let { polygon ->
graphicsOverlay.graphics.add(Graphic(polygon))
}
utilityGeometryTraceResult.polyline?.let { polyline ->
graphicsOverlay.graphics.add(Graphic(polyline))
}
utilityGeometryTraceResult.multipoint?.let { multipoint ->
graphicsOverlay.graphics.add(Graphic(multipoint))
}