Depending on what you need to do with the results, you can work with the appropriate return type you configured in the trace A trace is an action that analyzes the paths in a utility network and returns features based on connectivity or traversability from the specified starting points. Learn more parameters. The following types of results may be returned when executing the trace:

  • Elements—Element results provide the utility elements A utility element is an entity in a utility network that corresponds to a feature or a part of a feature (for example, a terminal inside a device). Learn more that are found by a trace. Use these results when you need access to individual utility elements, their corresponding features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more , and their attributes Attributes are fields and values for a single feature or non-spatial record. They are typically stored in a database or service such as a feature service. Learn more . This is the default trace result type.

  • Geometry—Geometry results contains multipart geometries that represent the union of the geometry A geometry is a geometric shape, such as a point, polyline, or polygon, that contains one or more coordinates and a spatial reference. Learn more 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.

// Get the QList of utility trace results from the utility network via the
// trace async method (QFuture).
utilityNetwork->traceAsync(traceParameters).then(this, [utilityNetwork]
(QFuture<QList<UtilityTraceResult *>>)
{
// Get the utility trace result list model from the utility network.
UtilityTraceResultListModel* traceResults = utilityNetwork->traceResult();
// Test if the utility trace result list model has content.
if (traceResults->isEmpty())
return;
// Get the first utility element trace result from the utility trace result list model.
UtilityElementTraceResult* elementTraceResult = static_cast<UtilityElementTraceResult*>
(traceResults->first());
// Test to ensure we have at least one element in the utility element trace result.
if (elementTraceResult->elements().count() > 0)
{
// Process the results ...
}
});

Element results

If you need fine-grained access to the results, such as the ability to work with individual utility elements A utility element is an entity in a utility network that corresponds to a feature or a part of a feature (for example, a terminal inside a device). Learn more from the trace A trace is an action that analyzes the paths in a utility network and returns features based on connectivity or traversability from the specified starting points. Learn more , you need to obtain the corresponding features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more for these elements from the utility element results.

You can use the element’s network source A network source is a feature table whose features comprise one of a utility network's datasets. Learn more to match its table A table is a non-spatial dataset in a feature service. All records in a table share the same set of fields. Learn more against the layer’s table by instance or name.

// Get the QList of utility elements from the list of utility elements (via a cast).
const QList<UtilityElement*> utilityElements = static_cast<UtilityElementTraceResult*>
(elementTraceResult)->elements(this);
// Get the result features from each network source layer in the map.
for (Layer* layer : *m_map->operationalLayers())
{
// Test if we have a feature layer from the operational layer (via a cast).
if (FeatureLayer* featureLayer = dynamic_cast<FeatureLayer*>(layer))
{
// Create a list of elements that belong to this layer.
QList<UtilityElement*> layerElements;
// Loop thru each utility element in the QList of utility elements.
for (UtilityElement* utilityElement : utilityElements)
{
// Select the elements that belong to this layer.
if (utilityElement->networkSource()->name() == featureLayer->
featureTable()->tableName())
{
layerElements.append(utilityElement);
}
}
// Continue if no matching elements are found.
if (layerElements.isEmpty())
continue;
// Get the QList of features from the utility network via the features for elements
// async method (QFuture).
utilityNetwork->featuresForElementsAsync(layerElements).then(this, [featureLayer,
utilityNetwork](QFuture<QList<ArcGISFeature *>>)
{
// Select the features in this layer.
featureLayer->selectFeatures(utilityNetwork->featuresForElementsResult()->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.

// Get the utility trace result list model from the utility network.
UtilityTraceResultListModel* traceResults = utilityNetwork->traceResult();
// Loop thru each utility trace result in the utility trace result list model.
for (UtilityTraceResult* result : *traceResults)
{
// Test if we have a vaild utility function trace result (not null) from the tility trace result.
if (UtilityFunctionTraceResult* functionResult = dynamic_cast<UtilityFunctionTraceResult*>(result))
{
// Loop thru each utility trace function output in the QList of utility trace function outputs,
for (UtilityTraceFunctionOutput* output : functionResult->functionOutputs())
{
// Get the original function (as defined in the trace configuration).
UtilityTraceFunction* function = output->function();
// Get the function type: Add, Average, Count, Min, Max, Subtract.
UtilityTraceFunctionType functionTypeEnum = function->functionType();
const QString functionTypeName = QList{"Add", "Average", "Count", "Max", "Min", "Subtract"}
.at((int)functionTypeEnum);
// Get the network attribute that was used in the function.
UtilityNetworkAttribute* networkAttribute = function->networkAttribute();
// Build a string to show the function description and result.
// For example: "Service Load (Add) = 378100".
const QString message = QString("%1 (%2) = %3").arg(networkAttribute->name(),
functionTypeName, output->result().toString());
// Add each output message to a list.
functionOutputMessages(message);
}
}
}

Geometry results

Geometry results make it easy to display the trace A trace is an action that analyzes the paths in a utility network and returns features based on connectivity or traversability from the specified starting points. Learn more result as graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more in the map view A map view is a user interface that displays map layers and graphics in 2D. It controls the area (extent) of the map that is visible and supports user interactions such as pan and zoom. Learn more . At most, geometry results will contain three (multipart) geometries: one multipoint A multipoint is a type of geometry that contains an array of points and a spatial reference. Point coordinates are expressed as x,y values. Each coordinate can also optionally include a z value for height and/or a m value for measure (typically used in linear referencing). Learn more , one polyline A polyline is a type of geometry containing ordered point coordinates and a spatial reference. Learn more , and one polygon A polygon is a type of geometry containing an array of rings and a spatial reference. Each ring contains an array of point coordinates, where the first and last point are the same. Learn more . 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 A spatial reference is a set of parameters, typically defined by a WKID, that define the coordinate system and spatial properties for geographic data. Applications use a spatial reference to correctly display the position of geographic data in a map or scene. Learn more , use a symbology appropriate for the geometry type, and add them to a graphics overlay in the map view.

// Get the utility trace result list model from the utility network.
UtilityTraceResultListModel* traceResults = utilityNetwork->traceResult();
// Get the iterator from the trace results.
auto geometryTraceResultIterator = std::find_if(traceResults->begin(),
traceResults->end(), [](UtilityTraceResult* traceResult)
{
return traceResult->traceResultObjectType() ==
UtilityTraceResultObjectType::UtilityGeometryTraceResult;
});
// Test if the we are at the end of the iterator.
if (geometryTraceResultIterator == traceResults->end())
return;
// Get the utility geometry trace result from the iterator (via a cast).
UtilityGeometryTraceResult* geometryTraceResult = static_cast<UtilityGeometryTraceResult*>
(*geometryTraceResultIterator);

If geometry results are found, create a new graphic A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more 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.

// Test of the utility geometry trace result is not null.
if (geometryTraceResult)
{
// Test if the polygon is valid on the the utility geometry trace result.
if (geometryTraceResult->polygon().isValid())
// Add a new polygon based graphic to the graphics overly.
graphicsOverlay->graphics()->append(new Graphic(geometryTraceResult->polygon(), this));
// Test if the polyline is valid on the the utility geometry trace result.
if (!geometryTraceResult->polyline().isValid())
// Add a new polyline based graphic to the graphics overly.
graphicsOverlay->graphics()->append(new Graphic(geometryTraceResult->polyline(), this));
// Test if the multi point is valid on the the utility geometry trace result.
if (!geometryTraceResult->multipoint().isValid())
// Add a new multi point based graphic to the graphics overly.
graphicsOverlay->graphics()->append(new Graphic(geometryTraceResult->multipoint(), this));
}