Skip to content

UtilityNetworkTraceTool Doesn't Load when Adding Utility Network As Layer, Not via Webmap #732

@AmrEldib

Description

@AmrEldib

We have a client who's working with the UtilityNetworkTraceTool control. The control supports loading networks and named trace configurations from a web map.
However, when trying to add the utility network as a layer, the control doesn't fully load.

Does the control support this approach? What methods/properties need to be called/set to make this happen?
Or, is there a bug in this behavior?

The control is initially not loaded.
Image

Then, the user clicks "Add data" to load the layer, which is loaded (as well as the utility network).
The control reacts (a loading symbol briefly appears, then the control is back).
Image

However, the user needs to switch tabs to see that the control has loaded.
Then, you can see that no Trace Types were loaded.

Image

Here's the code (XAML file renamed to txt to allow uploading).
Use the dotnet-samples. Under src\MAUI\Maui.Samples\Samples, you can add a new folder (named "UtilityNetworkTrace" for example), then place the files there.

UtilityNetworkTraceToolSample.xaml.txt

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="Toolkit.SampleApp.Maui.Samples.UtilityNetworkTraceToolSample"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:esriTK="clr-namespace:Esri.ArcGISRuntime.Toolkit.Maui;assembly=Esri.ArcGISRuntime.Toolkit.Maui"
    xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui"
    Title="UtilityNetworkTraceTool">
    <ContentPage.Resources>
        <Style TargetType="Grid">
            <Setter Property="Background" Value="{AppThemeBinding Dark=#353535, Light=#F8F8F8}" />
        </Style>
    </ContentPage.Resources>


    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition  />
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <esriUI:MapView Grid.Row="0"  x:Name="MyMapView" />
            <Button Grid.Row="1"  x:Name="LoadDataButton" Text="Load Data" Clicked="LoadDataButton_Clicked"  Margin="10"/>
        </Grid>
        <VerticalStackLayout Grid.Column="1">
            <esriTK:UtilityNetworkTraceTool GeoView="{Binding Source={x:Reference MyMapView}}" x:Name="MyTraceTool"/>
        </VerticalStackLayout>
    </Grid>
</ContentPage>

UtilityNetworkTraceToolSample.xaml.cs

using Esri.ArcGISRuntime;
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Security;
using Esri.ArcGISRuntime.UtilityNetworks;
using Microsoft.Maui.ApplicationModel;
using System.Diagnostics;

namespace Toolkit.SampleApp.Maui.Samples
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    [ArcGIS.Samples.Shared.Attributes.Sample(name: "UtilityNetworkTraceTool Issue", category: "UtilityNetworkTraceTool Issue", description: "Use named trace configurations defined in a web map to perform connected trace operations and compare results.", instructions: "Tap on one or more features while 'Add starting locations' or 'Add barriers' is selected. When a junction feature is identified, you may be prompted to select a terminal. When an edge feature is identified, the distance from the tapped location to the beginning of the edge feature will be computed. Select the type of trace using the drop down menu. Tap 'Trace' to initiate a trace on the network. Tap 'Reset' to clear the trace parameters and start over.",
        tags: new[] { "condition barriers", "downstream trace", "network analysis", "subnetwork trace", "toolkit", "trace configuration", "traversability", "upstream trace", "utility network", "validate consistency" })]
    public partial class UtilityNetworkTraceToolSample : ContentPage
    {
        private const string WebmapURL = "https://www.arcgis.com/home/item.html?id=471eb0bf37074b1fbb972b1da70fb310";

        public UtilityNetworkTraceToolSample()
        {
            InitializeComponent();

            MyTraceTool.UtilityNetworkChanged += MyTraceTool_UtilityNetworkChanged;
            MyTraceTool.UtilityNetworkTraceCompleted += MyTraceTool_UtilityNetworkTraceCompleted;
            AuthenticationManager.Current.ChallengeHandler = new ChallengeHandler(Challenge);
            Initialize();
        }

        private void MyTraceTool_UtilityNetworkTraceCompleted(object? sender, Esri.ArcGISRuntime.Toolkit.Maui.UtilityNetworkTraceCompletedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine($"Trace completed {e}");
        }

        private void MyTraceTool_UtilityNetworkChanged(object? sender, Esri.ArcGISRuntime.Toolkit.Maui.UtilityNetworkChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine($"Network changed. New selection: {e.UtilityNetwork?.Name}");
        }

        private async void Initialize()
        {
            try
            {

                var basemapLayer = new ArcGISVectorTiledLayer(new Uri("https://www.arcgis.com/home/item.html?id=86f556a2d1fd468181855a35e344567f"));
                await basemapLayer.LoadAsync();
                var map = new Esri.ArcGISRuntime.Mapping.Map(SpatialReferences.WebMercator) { Basemap = new Basemap(basemapLayer) };
                //var map = new Esri.ArcGISRuntime.Mapping.Map(new Uri(WebmapURL));

                MyMapView.Map = map;
                //MyTraceTool.GeoView = MyMapView;         
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }


        public async Task<Credential> Challenge(CredentialRequestInfo info)
        {
            try
            {
                // WARNING: Never hardcode login information in a production application. This is done solely for the sake of the sample.
                string sampleServer7User = "viewer01";
                string sampleServer7Pass = "I68VGU^nMurF";

                return await AccessTokenCredential.CreateAsync(info.ServiceUri, sampleServer7User, sampleServer7Pass);
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private async void LoadDataButton_Clicked(object sender, EventArgs e)
        {
            MyMapView.Map.OperationalLayers.Clear();
            var parentUrl = "https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectricV5/FeatureServer";
            var parentUri = new Uri(parentUrl);
            
            var serviceGeodatabase = new ServiceGeodatabase(parentUri);

            await serviceGeodatabase.LoadAsync();
            if (serviceGeodatabase.LoadStatus != LoadStatus.Loaded)
            {
                Debug.WriteLine("serviceGeodatabase didn't load");
                return;
            }
            try
            {

                // Add the UN to the map BEFORE loading it — the map must own it
                // and only unloaded UtilityNetworks can be added to Map.UtilityNetworks
                var un = new UtilityNetwork(serviceGeodatabase);
                
                //MainThread.BeginInvokeOnMainThread(() => MyMapView.Map.UtilityNetworks.Add(un));
                MyMapView.Map.UtilityNetworks.Add(un);

                //FOR SOME REASON ALL THE LAYERS FROM THE SERVICEGEODATABASE WONT LOAD ON THE MAP
                foreach (var layerInfo in serviceGeodatabase.ServiceInfo.LayerInfos)
                {
                    try
                    {
                        var serviceFeatureTable = serviceGeodatabase.GetTable((long)layerInfo.Id);
                        if (serviceFeatureTable == null) continue;

                        if (serviceFeatureTable.LoadStatus != LoadStatus.Loaded)
                            await serviceFeatureTable.LoadAsync();
                        if (serviceFeatureTable.LayerInfo == null) continue;

                        var subTypeFeatureLayer = new SubtypeFeatureLayer(serviceFeatureTable);
                        if (subTypeFeatureLayer.LoadStatus != LoadStatus.Loaded)
                            await subTypeFeatureLayer.LoadAsync();

                        //MainThread.BeginInvokeOnMainThread(() => MyMapView.Map.OperationalLayers.Add(subTypeFeatureLayer));
                        MyMapView.Map.OperationalLayers.Add(subTypeFeatureLayer);
                    }
                    catch
                    {
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"Error: {ex}");
            }
            finally
            {
                //MyTraceTool.GeoView = MyMapView;
                
            }
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions