An array of analysis and tracing options usually begin with or include a utility element in the result. This element corresponds to a network feature or object that contains additional information such as a terminal or fraction along value that affects the analysis. For example, the utility element's terminal may limit the number of connectivity associations or change the direction of a trace, while its fraction along value may return a partial geometry from a trace.
This utility element may be created from a feature or asset type with a global id. The feature may be a result of a query or identify operation on a layer or table that is part of the utility network.
Utility element from a feature
You may query for a specific feature using any of its fields or geometry or interactively identify a feature in a map view. When using identify, the feature may be found in the GeoElement
list immediately under IdentifyLayerResult
when part of a FeatureLayer
or from sublayerResults
when part of a SubtypeFeatureLayer
.
val queryParameters = QueryParameters().apply {
whereClause = "GlobalId like '{BBF6A59A-C5CE-468A-8DFD-6198F5F3A99E}'"
}
val queryResult = featureTable.queryFeatures(queryParameters).getOrElse { error ->
return logErr("Error querying features: ${error.message}")
}
val feature = queryResult.first()
val identifyLayerResult = mapViewProxy.identify(
layer = distributionLineFeatureLayer,
screenCoordinate = screenCoordinate,
tolerance = 10.dp,
returnPopupsOnly = false
).getOrElse { error ->
return showError(error.message.toString())
}
// Identify the first feature of the feature layer.
val firstFeatureLayerFeature = identifyLayerResult.geoElements.first() as ArcGISFeature
// Get the first sublayer from the sublayerResults. Then identify the first feature in the sublayer.
if (identifyLayerResult.sublayerResults.isNotEmpty()) {
val firstSublayerResult = identifyLayerResult.sublayerResults.first()
val firstSublayerFeature = firstSublayerResult.geoElements.first() as ArcGISFeature
}
firstSublayerFeature.load().onFailure {
return showError("Failed to load feature.")
}
// Create a utility element for the feature.
val utilityElement: UtilityElement = utilityNetwork.createElementOrNull(firstSublayerFeature)
?: return showError("Failed to create a utility element.")
Utility element from an asset type
An asset type can come from another utility element or be derived from a feature in the utility network, except from a subnet line table that does not have an asset type. You can use the feature's table name to get its network source. Use the network source and the feature's subtype to get its asset group. From the asset group, you can select an asset type by name or code.
// Get the asset type from an element.
val assetType = otherElement.assetType
// Make a new utility element from the asset type and global ID.
val element = utilityNetwork.createElementOrNull(
assetType = assetType,
globalId = globalId
)
// Get the network source with the specified name.
val tableName = feature.featureTable?.tableName.toString()
val networkSource =
utilityNetwork.definition?.getNetworkSource(networkSourceName = tableName)
?: return showError("Failed to get the network source using feature table name.")
// Get the asset group with the subtype name.
val featureSubTypeName = feature.getFeatureSubtype()?.name
?: return showError("Feature has no subtype.")
val assetGroup = networkSource.getAssetGroup(featureSubTypeName)
?: return showError("Failed to get the asset group")
// Get an asset type from a feature's asset type code.
val assetTypeCode = feature.attributes["ASSETTYPE"] as Short
val featureAssetType = assetGroup.assetTypes.first { utilityAssetType ->
utilityAssetType.code == assetTypeCode.toInt()
}
// Make a new utility element with the feature's asset type.
val element = utilityNetwork.createElementOrNull(
assetType = featureAssetType,
globalId = globalId
)
// Get the asset type by name.
val networkSource =
utilityNetwork.definition?.getNetworkSource(networkSourceName = "Electric Distribution Device")
?: return showError("Failed to get network source by name.")
val assetGroup = networkSource.getAssetGroup(assetGroupName = "Service Point")
?: return showError("Failed to get asset group by name.")
val lowVoltageAssetType = assetGroup.getAssetType(name = "Single Phase Low Voltage Meter")
?: return showError("Failed to get asset type by name.")
// Make a new utility element with the low voltage asset type.
val element = utilityNetwork.createElementOrNull(
assetType = lowVoltageAssetType,
globalId = globalId
)
Utility element properties
A terminal is required when a UtilityElement
that supports more than one terminal is used in a trace and optional when used to get associations. Terminals impact traces and connectivity associations.
// Get the terminals for the feature.
utilityElement.apply {
terminal = assetType.terminalConfiguration?.terminals?.first()
}
If the feature represents a line, you can optionally specify a location along the line to use as a trace location. This value is a percentage of the length of the line, beginning from the line's 'from' point.
Use UtilityElement.fractionAlongEdge
to define the location of the point along the line.
The following example uses the GeometryEngine
to get the fraction of a tap location along the line.
UtilityNetworkSourceType.Edge -> {
val lineGeometry = arcGISFeature.geometry as Polyline
utilityElement.fractionAlongEdge = GeometryEngine.fractionAlong(
line = GeometryEngine.createWithZ(geometry = lineGeometry, z = null),
point = tappedPoint,
tolerance = -1.0
)