Trace a utility network

In ArcGIS, utility networks offer a framework for modeling utility systems, such as electric, gas, water, storm water, wastewater, and telecommunications systems. Each utility network shows how features are connected and how dynamic devices are configured. This topic describes how to build ArcGIS Runtime apps that can trace the flow of resources, such as gas, water, and electricity, through its network. For an overview of utility networks, see ArcGIS Pro's help topic What is a utility network?.

You can explore how a network is affected by real-world events such as storms, outages, or equipment failure, by asking questions such as:

  • How is my utility's network connected?
  • What path does electricity/gas/water take in order to reach a specific neighborhood?
  • If a device is disabled, what section of the network will be out of power?

To help answer these questions, ArcGIS Runtime supports the following utility trace types:

  • **Upstream—**In a source-based network (gas or electric), an upstream trace is against the flow and toward the source, such as a circuit breaker or generator (subnetwork controller). In a sink-based network (sewer or storm water), an upstream trace is against the flow and away from the sink such as a sewage treatment (subnetwork controller). For more information, see ArcGIS Pro's help discussion on upstream traces.
  • **Downstream—**In a source-based network, a downstream trace is with the flow and away from the source, such as a circuit breaker or generator. In a sink-based network, a downstream trace is with the flow and toward the sink. For more information, see ArcGIS Pro's help discussion on downstream traces.
  • **Subnetwork—**A trace that discovers all features participating in a subnetwork. This trace type is useful for validating whether subnetworks, such as circuits or zones, are defined or edited appropriately. The trace begins at one or more starting points and spans outward along connected features to find subnetwork controllers that are traversable. A subnetwork trace stops when it encounters a barrier, when it encounters a feature that is not traversable, or when there are no more connected features. For more information see ArcGIS Pro's help discussion on subnetwork trace.
  • **Isolation—**A trace used to determine the minimum set of operable assets (point and line features) required to stop a network's resource from traveling/flowing, effectively isolating an area of the network. For instance, when a leak occurs on a water network, particular valves must be closed to eliminate water flow at the leak location. This prevents damage and allows field crews to safely start the repair process. For more information, see ArcGIS Pro's help discussion on locating isolating features.
  • **Connected—**A trace that begins at one or more starting points and spans outward radially along connected features. A trace stops when a barrier is encountered or there are no more connected features. Can be used for validating newly edited features to ensure they are connected as expected. For more information, see ArcGIS Pro's help discussions on connectivity and finding connected features.
  • **Shortest path—**Identify the shortest path between two starting points using a shortest path trace. The shortest path is calculated using a numeric network attribute such as shape length. Cost- or distance-based paths can both be achieved using this type of trace. For more information, see Discover the shortest path tool in the ArcGIS Pro help.
  • **Loops—**Loops are areas of the network where flow direction is ambiguous. Within a loop, resources can flow in either direction. Loops are expected with mesh networks but usually indicate error conditions in radial networks. You can also discover loops using a shortest path trace. For more information, see Discover network loops in the ArcGIS Pro help.

To trace a utility network you need to:

  1. Use ArcGIS Pro to create a utility network.

  2. In ArcGIS Runtime, access the utility network.

  3. Define the trace parameters:

    a. Decide which trace type to perform.

    b. Define the starting and barrier locations.

    c. Specify the trace configuration.

  4. Run the trace.

  5. Examine the results.

Access a utility network

Utility networks are implemented in service-based geodatabases as network controller datasets. These datasets contain a network's service feature tables along with the network's domains, sources, tiers, assets, terminals, rules and associations. This utility network is accessible via these service feature tables stored in a single feature service.

You can display and share a complete utility network with a user via a web map if the map includes one feature layer for every network source.

Diagram of objects loaded when loading a utility network with a map with layers for all network sources.

To display and share the utility network, create a utility network object from a feature service URL and a web map that contains all the layers that participate in the utility network.

The feature service provides access to the topological network in the utility network. So, you could provide a map that contains just a subset of the feature layers, for a specific workflow. Any tracing would be performed using the full topological network provided by the feature service. If you need to add additional utility network layers you can create them from the individual network sources, as required. You can also access a utility network and run a trace completely without a map. Just provide the feature service URL when you create the utility network. If needed, you can create a completely new map by creating feature layers from the network sources.

ArcGIS Runtime supports Utility Network version 2 and later that is provided from ArcGIS Pro 2.2 and later. For details see utility network upgrade history.

Load the utility network

The utility network follows the loadable pattern described in Loading resources asynchronously. Loading the utility network loads the entire utility network schema (information about the datasets that participate in the network). Once loaded, your app can navigate this network schema to discover the domain networks it contains and any further details about the network.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
utilityNetwork.loadAsync();
if (utilityNetwork.getLoadStatus() == LoadStatus.LOADED) {
  utilityNetwork.addDoneLoadingListener(() -> {
    System.out.println("The Utility Network schema version is " + utilityNetwork.getDefinition().getSchemaVersion());
  });
} else {
  new Alert(Alert.AlertType.ERROR, "Error loading Utility Network.").show();
}

Define the trace parameters

Trace parameters define how the trace analysis proceeds across the utility network. These are the essential trace parameters:

  1. Trace type
  2. Start and barrier locations
  3. Trace configuration

Trace type

ArcGIS Runtime supports the trace types described above (upstream, downstream, and so on).

Use the utility trace type to create the parameters

Create a set of UtilityTraceParameters by providing a UtilityTraceType of UPSTREAM, along with a collection of starting locations (if known at this stage).

Use dark colors for code blocksCopy
1
UtilityTraceParameters utilityTraceParameters = new UtilityTraceParameters(UtilityTraceType.UPSTREAM, startingLocations);

Start and barrier locations

Each trace requires one or more locations from which to initiate the trace. Optionally, you can also include barrier locations. Starting and barrier locations are defined using instances of UtilityElement which are added to the trace configuration's starting locations and barriers collection respectively.

You can create a starting location using steps like the following:

  1. Create a UtilityElement using a feature.

    Use dark colors for code blocksCopy
    1
    2
    // create the element from a feature
    UtilityElement utilityElement = utilityNetwork.createElement(arcGISFeature, null);
    1. If the feature represents a line, you can optionally specify a location along the line to use as the starting location. This value is expressed as a percentage of the length of the line, beginning from the line's from point.

      Call the setfractionAlongEdge() method to set a value that defines the location of the point along the line.

      Use dark colors for code blocksCopy
      1
      2
      3
      4
      5
      6
      // Determine how far the starting point is located along the line
      Polyline polyline = (Polyline) GeometryEngine.removeZ(geometry);
      double fraction = GeometryEngine.fractionAlong(polyline, mapPoint, -1.0);
      if (!Double.isNaN(fraction)) {
        utilityElement.setFractionAlongEdge(fraction);
      }
    2. If the feature represents a device with terminals, you must specify which terminal you want to use as the starting point.

      Use dark colors for code blocksCopy
      1
      2
      3
      4
      5
      6
      7
      8
      UtilityTerminalConfiguration terminalConfiguration = utilityElement.getAssetType().getTerminalConfiguration();
       if (terminalConfiguration != null) {
         List utilityTerminals = terminalConfiguration.getTerminals();
         if (!utilityTerminals.isEmpty()) {
           UtilityTerminal utilityTerminal = utilityTerminals.get(0);
           utilityElement.setTerminal(utilityTerminal);
         }
       }
  2. Add the utility element to the utility trace parameters’ list of starting locations, which is returned by getStartingLocations().

    Use dark colors for code blocksCopy
    1
    utilityTraceParameters.getStartingLocations().add(utilityElement);
  3. If you need to add a barrier, complete step 1 above then add the utility element representing a barrier to the utility trace parameters’ list of barriers, which is returned by getBarriers().

Trace configuration

If you don't want to use the trace configuration as created in ArcGIS Pro, you can either modify it or you can override it with settings you specify with ArcGIS Runtime. A trace configuration is set on the UtilityTraceParameters .

These settings allow you to do things like:

  • Stop the trace at protective devices if they are open. For example, the flow of electricity in a network will be stopped if a fuse is open.
  • Control the types of features traced. For example, trace only pipes with a diameter greater than six inches.
  • Filter the types of features returned as trace results. For example, only return elements identified by the trace that represent wooden poles.
  • Define functions to run calculations on network attributes associated with traced features. For example, the sum of the length of all the wire traced. Several functions can be specified for a trace.
  • Request different types of trace results. These can include geometry (for easy display on the map), network elements (if you need more information about individual features), and output functions (for calculating values based on network attributes).

Each trace configuration manages basic properties such as:

  • Include barriers in trace results
  • Include containers in trace results
  • Include content in trace results
  • Include structures in trace results
  • Add filter barriers (required for isolation traces)
  • Ignore barriers if they are the starting points
  • Domain network
  • Source tier

For more advanced properties, such as traversability, output filters, propagators, and target tiers, see the advanced trace configuration section.

When a utility network administrator creates a new tier in ArcGIS Pro, a subnetwork trace configuration is created and populated as described in Configure a trace.

You can choose if your app uses the trace configuration as defined by an administrator, a modified version of the configuration, or your own trace configuration.

Use a trace configuration defined in a utility network tier

To obtain the trace configuration from a utility network tier, you need to know the name of the domain network and the tier.

  1. Obtain the utility network definition from the utility network.
  2. Get the domain network from the utility network definition.
  3. Obtain the tier from the domain network.
  4. Pass the tier's trace configuration to the utility trace parameters.
  5. Modify any of these properties as required.

The following example illustrates using the preceding steps to get the configuration for a tier in 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

    if (utilityNetwork.getLoadStatus() == LoadStatus.LOADED) {
        utilityNetwork.addDoneLoadingListener(() -> {

          // get the domain network called "ElectricDistribution"
          UtilityDomainNetwork utilityDomainNetwork = utilityNetwork.getDefinition().getDomainNetwork("ElectricDistribution");
          if (utilityDomainNetwork != null){

            // get the tier called "Medium Voltage Radial"
            UtilityTier utilityTier = utilityDomainNetwork.getTier("Medium Voltage Radial");
            if (utilityTier != null){

              // get the tier's trace configuration and then set the configuration on the trace parameters
              UtilityTraceConfiguration utilityTraceConfiguration = utilityTier.getDefaultTraceConfiguration();
              utilityTraceParameters.setTraceConfiguration(utilityTraceConfiguration);
            }
            else  System.out.println("Specified utility tier not found");
            }
          else System.out.println("Specified utility network domain not found");
        });
      }

Create your own trace configuration

  1. Create a utility trace configuration.

  2. If you are running an upstream, downstream, or subnetwork trace then you must set the domain network as follows:

    a. Obtain the domain network from the utility network definition.

    b. Pass the domain network to the utility trace configuration.

  3. Modify any of the other properties, as required.

  4. Pass the utility trace configuration to the utility trace parameters.

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    if (utilityNetwork.getLoadStatus() == LoadStatus.LOADED) {
      utilityNetwork.addDoneLoadingListener(() -> {
        // create the utility trace configuration
        UtilityTraceConfiguration traceConfiguration = new UtilityTraceConfiguration();
    
        // set the network domain called "ElectricDistribution" on the utility trace configuration
        UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.getDefinition();
        UtilityDomainNetwork utilityDomainNetwork = utilityNetworkDefinition.getDomainNetwork("ElectricDistribution");
        if (utilityDomainNetwork != null) {
          traceConfiguration.setDomainNetwork(utilityDomainNetwork);
    
          // modify other parameters, as required, here...
          // and then set the trace configuration on the utility trace parameters
          utilityTraceParameters.setTraceConfiguration(traceConfiguration);
        } else System.out.println("Specified utility domain network not found.");
      });
    }

Named trace configurations

With ArcGIS Runtime version 100.11 or later, you can use named trace configurations. A named trace configuration is a set of tracing parameters that is built with ArcGIS Pro, stored on ArcGIS Enterprise, and published with a web map. Named trace configurations allow you to create utility applications that are independent of individual customer data models. Using this workflow, tracing capabilities can be configured rather than customized.

Run the trace

Run the trace by calling the trace method on the utility network object. Use the utility trace parameters defined in the previous section. Depending on the trace parameters, results may be returned as one or more trace result types: utility element, output function, or geometry. If not specified, utility element trace results are returned by default.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ListenableFuture> utilityTraceResultsListenableFuture;
utilityTraceResultsListenableFuture = utilityNetwork.traceAsync(utilityTraceParameters);
utilityTraceResultsListenableFuture.addDoneListener(() -> {
  try {
    List utilityTraceResults = utilityTraceResultsListenableFuture.get();
    if (utilityTraceResults.get(0) != null) {
      if (utilityTraceResults.get(0) instanceof UtilityElementTraceResult) {
        UtilityElementTraceResult utilityElementTraceResult = (UtilityElementTraceResult) utilityTraceResults.get(0);
        List elements = utilityElementTraceResult.getElements();
        if (!elements.isEmpty()) {
          // check if there are any elements in the first trace result
          System.out.println("Count of utility elements in first trace result is: " + elements.size());
          // process trace results here
        }

If the trace fails you can examine why. For example, failure could be due to dirty areas in the network topology.

Examine the results

Depending on what you need to do with the results, you can work with the appropriate return type you configured in the trace parameters. You may have the following types of results 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 type of trace results.
  • 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.

Work with 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.

  1. Filter the utility element trace results to find those that are part of the map, and group them by network source name.

  2. For every group (network source with utility elements), make sure there is a layer in the map for the features. Next find the features corresponding to the utility elements.

    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
    // get the first result of the utility trace and then the elements in that result
    utilityElementTraceResult = (UtilityElementTraceResult) utilityTraceResults.get(0);
    utilityElements = utilityElementTraceResult.getElements();
    
    // group together utility elements that have the same network source
    List utilityElementsWithSameNetworkSource;
    if (!utilityElements.isEmpty()) {
      // make a HashMap of key-value pairs where key is the name of a UtilityNetworkSource and
      // value is a list of utility elements in that UtilityNetworkSource
      HashMap> hashMap = new HashMap<>();
      for (UtilityElement utilityElement : utilityElements) {
        String utilityNetworkSourceName = utilityElement.getNetworkSource().getName();
    
        // if utilityNetworkSourceName is already a key, get the corresponding list of elements
        if (hashMap.containsKey(utilityNetworkSourceName)) {
          utilityElementsWithSameNetworkSource = hashMap.get(utilityNetworkSourceName);
        }
    
        // if utilityNetworkSourceName is not a key, create a new list of elements
        else {
          utilityElementsWithSameNetworkSource = new ArrayList<>();
        }
    
        // add current utility element to the list of elements
        utilityElementsWithSameNetworkSource.add(utilityElement);
        // update the hashMap with the new/modified key-value pair
        hashMap.put(utilityNetworkSourceName, utilityElementsWithSameNetworkSource);
      }
      // ensure that the features' layer exists in the map
      for (Map.Entry> entry : hashMap.entrySet()) {
        FeatureLayer layer = (FeatureLayer) map.getOperationalLayers().get(0);
        if (layer.getFeatureTable().getTableName().equals(entry.getKey())) {
          // get the features that correspond to the elements
          ListenableFuture> arcGISFeatureListListenableFuture;
          arcGISFeatureListListenableFuture = utilityNetwork.fetchFeaturesForElementsAsync(entry.getValue());
          arcGISFeatureListListenableFuture.addDoneListener(() -> {
            try {
              List arcGISFeatureList = arcGISFeatureListListenableFuture.get();
            } catch (InterruptedException | ExecutionException e) {
              e.printStackTrace();
            }
          });
        }
      }
    } else
      System.out.println("First trace result is empty");
  3. Select the features that correspond to the trace result or process as required.

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    arcGISFeatureListListenableFuture = utilityNetwork.fetchFeaturesForElementsAsync(entry.getValue());
    arcGISFeatureListListenableFuture.addDoneListener(() -> {
      try {
        List arcGISFeatureList = arcGISFeatureListListenableFuture.get();
        // select features to highlight result
        for (ArcGISFeature arcGISFeature : arcGISFeatureList){
          layer.selectFeature(arcGISFeature);
        }
      } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
      }
    });

Work with 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.

  1. Get the geometry results from the trace results. Depending on how the trace parameters were defined (which result types were requested), there may be more than one result type.

  2. 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.

Work with 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.

Advanced trace configuration

Traversability

As you trace a topological network you can examine a number of 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 UtilityTraceConfiguration class. You can set conditions or constraints to this trace using barrier and function barrier properties (described below).

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 may be defined with trace parameters, which are defined 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")
    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    UtilityTraceConfiguration traceConfiguration = new UtilityTraceConfiguration();
    UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.getDefinition();
    UtilityNetworkAttribute lifecycleNetworkAttribute = utilityNetworkDefinition.getNetworkAttribute("Lifecycle");
    
    // create a network attribute comparison that stops traversal if Lifecycle != 4
    UtilityNetworkAttributeComparison inDesignNetworkAttributeComparison = new UtilityNetworkAttributeComparison(lifecycleNetworkAttribute, UtilityAttributeComparisonOperator.NOT_EQUAL, 4);
    
    // create a network attribute comparison to stop traversal if Lifecycle != 8
    UtilityNetworkAttributeComparison inServiceNetworkAttributeComparison = new UtilityNetworkAttributeComparison(lifecycleNetworkAttribute, UtilityAttributeComparisonOperator.NOT_EQUAL, 8);
    
    // combine these two comparison together with AND
    UtilityTraceAndCondition lifecycleFilter = new UtilityTraceAndCondition(inDesignNetworkAttributeComparison, inServiceNetworkAttributeComparison);
    
    // final condition stops traversal if Lifecycle != 4 and Lifecycle != 8
    UtilityTraversability utilityTraversability = traceConfiguration.getTraversability();
    if (utilityTraversability != null)
      utilityTraversability.setBarriers(lifecycleFilter);
  • 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.

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
// create a network attribute object for the Shape length network attribute from the utility network definition
UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.getDefinition();
UtilityNetworkAttribute shapeLengthNetworkAttribute = utilityNetworkDefinition.getNetworkAttribute("Shape length");

// create a function that adds up shape length
UtilityTraceFunction lengthFunction = new UtilityTraceFunction(UtilityTraceFunctionType.ADD, shapeLengthNetworkAttribute);

// create a function barrier that stops traversal after 1000 meters
UtilityTraceFunctionBarrier distanceBarrier = new UtilityTraceFunctionBarrier(lengthFunction, UtilityAttributeComparisonOperator.GREATER_THAN, 1000.0);

UtilityTraceConfiguration traceConfiguration = new UtilityTraceConfiguration();

// set this function barrier
UtilityTraversability utilityTraversability = traceConfiguration.getTraversability();
if (utilityTraversability != null)
  utilityTraversability.getFunctionBarriers().add(distanceBarrier);

For more information see connectivity and traversability in the ArcGIS Pro documentation.

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 get 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 all 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, you would 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. You should use a trace filter instead.

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).

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 in which phase is represented as a bitset network attribute (one bit per phase), and overhead electrical devices are represented with one device per phase. You could use a bitset network attribute to ensure the trace results include valid paths that are 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 be returned 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 TraceConfiguration 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 you could 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 they 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 only return elements that belong to the "Plastic PE pipe" asset type and also have a diameter of 12 inches and a pressure of 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
// get a network attribute object for the "Phases Normal" attribute from the utility network definition
UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.getDefinition();
UtilityNetworkAttribute networkAttribute = utilityNetworkDefinition.getNetworkAttribute("Phases Normal");

// create a propagator to propagate the attribute using a Bitwise And function
UtilityPropagator propagator;
propagator = new UtilityPropagator(networkAttribute, UtilityPropagatorFunctionType.BITWISE_AND, UtilityAttributeComparisonOperator.INCLUDES_ANY, 7);

UtilityTraceConfiguration traceConfiguration = new UtilityTraceConfiguration();

// assign the propagator to the trace configuration
traceConfiguration.getPropagators().add(propagator);

For more information see propagators.

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 call the setTargetTier() method on the 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 then it can 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 whether to call setValidateConsistency(false) on the UtilityTraceConfiguration. You can optionally display a warning to the user if a dirty area is encountered.

Get associated utility elements

Associations model the following types of relationships between two utility network elements:

AssociationDescriptionGeometry supported
ConnectivityModels the connectivity between two junctions that don't have geometric coincidence (are not in the same x, y and z location). A transformer may be connected to a fuse, for example.Yes
Structural attachmentModels equipment attached to structures. A transformer bank may be attached to a pole, for example.Yes
ContainmentModels assets that contain other assets. A vault may contain valves and pipes, for example.No

An association is defined between two UtilityElement objects. You can identify which UtilityElements are associated with a given UtilityElement using one of the getAssociationsAsync() methods on the UtilityNetwork.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// get the elements associated with a single utility element (using containment)
ListenableFuture> utilityAssociationListListenableFuture;
utilityAssociationListListenableFuture = utilityNetwork.getAssociationsAsync(utilityElement, UtilityAssociationType.CONTAINMENT);
utilityAssociationListListenableFuture.addDoneListener(() -> {
  try {
    List utilityAssociations;
    utilityAssociations = utilityAssociationListListenableFuture.get();
    if (!utilityAssociations.isEmpty() ) {
      for (UtilityAssociation association : utilityAssociations) {
        UtilityElement fromElement = association.getFromElement();
        UtilityElement toElement = association.getToElement();
      }
    }
  } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
});

If the association represents a connectivity or structural attachment association, it may include a geometry value (polyline) representing the connection relationship between a from element and a to element. You can use the geometry to visualize the association as a graphic in the map.

If you want to find all the valid associations within a specific extent, call the getAssociationsAsync() method and provide an envelope that defines the specific extent.

Association graphics showing connectivity in red and structural attachment in green

For more information see ArcGIS Pro's help topic Associations.

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