Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Perform valve isolation trace

This code sample is available for these platforms:
View Sample on GitHub

Run a filtered trace to locate operable features that will isolate an area from the flow of network resources.

Image of a utility network with an isolation trace applied to it

Use case

Determine the set of operable features required to stop a network's resource, effectively isolating an area of the network. For example, you can choose to return only accessible and operable valves: ones that are not paved over or rusted shut.

How to use the sample

Create and set the configuration's filter barriers by selecting a category. Check or uncheck 'Include Isolated Features'. Click 'Trace' to run a subnetwork-based isolation trace.

How it works

  1. Create a MapView.
  2. Create and load a UtilityNetwork with a feature service URL.
  3. Create a Map that contains FeatureLayer(s) that are part of this utility network.
  4. Create a default starting location from a given asset type and global id.
  5. Add a GraphicsOverlay with a Graphic that represents this starting location.
  6. Populate the choice list for the 'Filter Barrier: Category exists' from UtilityNetworkDefinition.Categories.
  7. Get a default UtilityTraceConfiguration from a given tier in a domain network. Set it's Filter with a new UtilityTraceFilter.
  8. When 'Trace' is clicked,
    • Create a new UtilityCategoryComparison with the selected category and UtilityCategoryComparisonOperator.Exists.
    • Assign this condition to TraceFilter.Barriers from the default configuration from step 7. Update this configuration's IncludeIsolatedFeatures property.
    • Create a UtilityTraceParameters with UtilityTraceType.Isolation and default starting location from step 4.
    • Set its TraceConfiguration with this configuration and then, run a UtilityNetwork.TraceAsync.
  9. For every FeatureLayer in the map, select the features returned by GetFeaturesForElementsAsync from the elements matching their NetworkSource.Name with the layer's FeatureTable.Name.

Relevant API

  • UtilityCategory
  • UtilityCategoryComparison
  • UtilityCategoryComparisonOperator
  • UtilityDomainNetwork
  • UtilityElement
  • UtilityElementTraceResult
  • UtilityNetwork
  • UtilityNetworkDefinition
  • UtilityTier
  • UtilityTraceFilter
  • UtilityTraceParameters
  • UtilityTraceResult
  • UtilityTraceType

About the data

The Naperville gas network feature service, hosted on ArcGIS Online, contains a utility network used to run the isolation trace shown in this sample.


category comparison, condition barriers, isolated features, network analysis, subnetwork trace, trace configuration, trace filter, utility network

Sample Code

        <esriUI:MapView x:Name="MyMapView" />
            Style="{StaticResource BorderStyle}">
            <Grid x:Name="FilterOptions">
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                    Text="Choose Category for Filter Barrier:" />
                            <TextBlock Text="{Binding Name}" />
                    Content="Include Isolated Features" />
                    Content="Trace" />
            Visibility="Visible" />
// Copyright 2020 Esri.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
// language governing permissions and limitations under the License.

using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.UI;
using Esri.ArcGISRuntime.UtilityNetworks;
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Popups;
using Windows.UI.Xaml;

namespace ArcGISRuntime.UWP.Samples.PerformValveIsolationTrace
        name: "Perform valve isolation trace",
        category: "Utility network",
        description: "Run a filtered trace to locate operable features that will isolate an area from the flow of network resources.",
        instructions: "Create and set the configuration's filter barriers by selecting a category. Check or uncheck 'Include Isolated Features'. Click 'Trace' to run a subnetwork-based isolation trace.",
        tags: new[] { "category comparison", "condition barriers", "isolated features", "network analysis", "subnetwork trace", "trace configuration", "trace filter", "utility network" })]
    public partial class PerformValveIsolationTrace
        // Feature service for an electric utility network in Naperville, Illinois.
        private const string FeatureServiceUrl = "";
        private const int LineLayerId = 3;
        private const int DeviceLayerId = 0;
        private UtilityNetwork _utilityNetwork;

        // For creating the default trace configuration.
        private const string DomainNetworkName = "Pipeline";
        private const string TierName = "Pipe Distribution System";
        private UtilityTraceConfiguration _configuration;

        // For creating the default starting location.
        private const string NetworkSourceName = "Gas Device";
        private const string AssetGroupName = "Meter";
        private const string AssetTypeName = "Customer";
        private const string GlobalId = "{98A06E95-70BE-43E7-91B7-E34C9D3CB9FF}";
        private UtilityElement _startingLocation;

        public PerformValveIsolationTrace()

        private async void Initialize()
                // Disable the UI.
                FilterOptions.Visibility = Visibility.Collapsed;

                // Create and load the utility network.
                _utilityNetwork = await UtilityNetwork.CreateAsync(new Uri(FeatureServiceUrl));

                // Create a map with layers in this utility network.
                MyMapView.Map = new Map(Basemap.CreateStreetsNightVector());
                MyMapView.Map.OperationalLayers.Add(new FeatureLayer(new Uri($"{FeatureServiceUrl}/{LineLayerId}")));
                MyMapView.Map.OperationalLayers.Add(new FeatureLayer(new Uri($"{FeatureServiceUrl}/{DeviceLayerId}")));

                // Get a trace configuration from a tier.
                UtilityDomainNetwork domainNetwork = _utilityNetwork.Definition.GetDomainNetwork(DomainNetworkName) ?? throw new ArgumentException(DomainNetworkName);
                UtilityTier tier = domainNetwork.GetTier(TierName) ?? throw new ArgumentException(TierName);
                _configuration = tier.TraceConfiguration;

                // Create a trace filter.
                _configuration.Filter = new UtilityTraceFilter();

                // Get a default starting location.
                UtilityNetworkSource networkSource = _utilityNetwork.Definition.GetNetworkSource(NetworkSourceName) ?? throw new ArgumentException(NetworkSourceName);
                UtilityAssetGroup assetGroup = networkSource.GetAssetGroup(AssetGroupName) ?? throw new ArgumentException(AssetGroupName);
                UtilityAssetType assetType = assetGroup.GetAssetType(AssetTypeName) ?? throw new ArgumentException(AssetTypeName);
                Guid globalId = Guid.Parse(GlobalId);
                _startingLocation = _utilityNetwork.CreateElement(assetType, globalId);

                // Create a graphics overlay.
                GraphicsOverlay overlay = new GraphicsOverlay();

                // Display starting location.
                IEnumerable<ArcGISFeature> elementFeatures = await _utilityNetwork.GetFeaturesForElementsAsync(new List<UtilityElement> { _startingLocation });
                MapPoint startingLocationGeometry = elementFeatures.FirstOrDefault().Geometry as MapPoint;
                Symbol symbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Cross, System.Drawing.Color.LimeGreen, 25d);
                Graphic graphic = new Graphic(startingLocationGeometry, symbol);

                // Set the starting viewpoint.
                await MyMapView.SetViewpointAsync(new Viewpoint(startingLocationGeometry, 3000));

                // Build the choice list for categories populated with the `Name` property of each `UtilityCategory` in the `UtilityNetworkDefinition`.
                Categories.ItemsSource = _utilityNetwork.Definition.Categories;
                Categories.SelectedItem = _utilityNetwork.Definition.Categories.First();

                // Enable the UI.
                FilterOptions.Visibility = Visibility.Visible;
            catch (Exception ex)
                await new MessageDialog(ex.Message, ex.GetType().Name).ShowAsync();
                LoadingBar.Visibility = Visibility.Collapsed;

        private async void OnTrace(object sender, RoutedEventArgs e)
                LoadingBar.Visibility = Visibility.Visible;

                // Clear previous selection from the layers.
                MyMapView.Map.OperationalLayers.OfType<FeatureLayer>().ToList().ForEach(layer => layer.ClearSelection());

                if (Categories.SelectedItem is UtilityCategory category)
                    // NOTE: UtilityNetworkAttributeComparison or UtilityCategoryComparison with Operator.DoesNotExists
                    // can also be used. These conditions can be joined with either UtilityTraceOrCondition or UtilityTraceAndCondition.
                    UtilityCategoryComparison categoryComparison = new UtilityCategoryComparison(category, UtilityCategoryComparisonOperator.Exists);

                    // Add the filter barrier.
                    _configuration.Filter.Barriers = categoryComparison;

                // Set the include isolated features property.
                _configuration.IncludeIsolatedFeatures = IncludeIsolatedFeatures.IsChecked == true;

                // Build parameters for isolation trace.
                UtilityTraceParameters parameters = new UtilityTraceParameters(UtilityTraceType.Isolation, new[] { _startingLocation });
                parameters.TraceConfiguration = _configuration;

                // Get the trace result from trace.
                IEnumerable<UtilityTraceResult> traceResult = await _utilityNetwork.TraceAsync(parameters);
                UtilityElementTraceResult elementTraceResult = traceResult?.FirstOrDefault() as UtilityElementTraceResult;

                // Select all the features from the result.
                if (elementTraceResult?.Elements?.Count > 0)
                    foreach (FeatureLayer layer in MyMapView.Map.OperationalLayers.OfType<FeatureLayer>())
                        IEnumerable<UtilityElement> elements = elementTraceResult.Elements.Where(element => element.NetworkSource.Name == layer.FeatureTable.TableName);
                        IEnumerable<Feature> features = await _utilityNetwork.GetFeaturesForElementsAsync(elements);
            catch (Exception ex)
                await new MessageDialog(ex.Message, ex.GetType().Name).ShowAsync();
                LoadingBar.Visibility = Visibility.Collapsed;