From b9c0b18793a54d9f151590eb54b01964519bd534 Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Wed, 19 Nov 2025 15:54:23 -0800 Subject: [PATCH 01/10] implement the utility load report --- lib/samples/create_load_report/README.md | 61 +++ .../create_load_report/README.metadata.json | 58 +++ .../create_load_report.dart | 447 ++++++++++++++++++ .../create_load_report/create_load_report.png | Bin 0 -> 57577 bytes 4 files changed, 566 insertions(+) create mode 100644 lib/samples/create_load_report/README.md create mode 100644 lib/samples/create_load_report/README.metadata.json create mode 100644 lib/samples/create_load_report/create_load_report.dart create mode 100644 lib/samples/create_load_report/create_load_report.png diff --git a/lib/samples/create_load_report/README.md b/lib/samples/create_load_report/README.md new file mode 100644 index 00000000..1fb4c0c0 --- /dev/null +++ b/lib/samples/create_load_report/README.md @@ -0,0 +1,61 @@ +# Create load report + +Create a simple electric distribution report that displays the count of customers and total load per phase by tracing downstream from a given point. + +![](create_load_report.png) + +## Use case + +You can use a load report to display the customers per phase as well as the load per phase based on a chosen starting point in a utility network. Load reports are used for electric load restoration and balancing. + +## How to use the sample + +Select phases to be included in the report. Press the "Run Report" button to initiate a downstream trace on the network and create a load report. Pressing "Run Report" again will generate a new load report. Deselect all phases and press the "Reset" button to clear the report. + +## How it works + +1. Create a `ServiceGeodatabase` with a feature service URL. +2. Create and load a `UtilityNetwork` using the service geodatabase, then get an asset type, tier, network attributes, and category by their names. +3. Create a `UtilityElement` from the asset type to use as the starting location for the trace. +4. Create a `UtilityTraceConfiguration` from the utility tier. +5. Create a `UtilityCategoryComparison` where "ServicePoint" category exists. +6. Reset the `functions` property of the trace configuration with a new `UtilityTraceFunction` adding a "Service Load" network attribute where this category comparison applies. This will limit the function results. +7. Set `outputCondition` with the category comparison to limit the element results. +8. Get a base condition from the utility tier's default trace configuration. +9. Create `UtilityTraceParameters` passing in `downstream` utility trace type and the default starting location. Set its `traceConfiguration` property with the trace configuration above. +10. Populate a list of phases using the network attribute's `codedValues` property. +11. When the "Run Report" button is tapped, run a trace for every checked `CodedValue` in the phases list. Do this by creating a `UtilityTraceOrCondition` with the base condition and a `UtilityNetworkAttributeComparison` where the "Phases Current" network attribute does not include the coded value. +12. Display the count of "Total Customers" using the `elements` property of the result, and the result of "Total Load" using the first and only output in `functionOutputs` property. + +## Relevant API + +* UtilityAssetType +* UtilityCategoryComparison +* UtilityDomainNetwork +* UtilityElement +* UtilityElementTraceResult +* UtilityNetwork +* UtilityNetworkAttribute +* UtilityNetworkAttributeComparison +* UtilityNetworkDefinition +* UtilityNetworkSource +* UtilityTerminal +* UtilityTier +* UtilityTraceConfiguration +* UtilityTraceFunction +* UtilityTraceParameters +* UtilityTraceResult +* UtilityTraceType +* UtilityTraversability + +## About the data + +The [Naperville electrical](https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectric/FeatureServer) network feature service, hosted on ArcGIS Online (authentication required: this is handled within the sample code), contains a utility network used to run the subnetwork-based trace shown in this sample. + +## Additional information + +Using utility network on ArcGIS Enterprise 10.8 requires an ArcGIS Enterprise member account licensed with the [Utility Network user type extension](https://enterprise.arcgis.com/en/portal/latest/administer/windows/license-user-type-extensions.htm#ESRI_SECTION1_41D78AD9691B42E0A8C227C113C0C0BF). Please refer to the [utility network services documentation](https://enterprise.arcgis.com/en/server/latest/publish-services/windows/utility-network-services.htm). + +## Tags + +condition barriers, downstream trace, network analysis, subnetwork trace, trace configuration, traversability, upstream trace, utility network, validate consistency \ No newline at end of file diff --git a/lib/samples/create_load_report/README.metadata.json b/lib/samples/create_load_report/README.metadata.json new file mode 100644 index 00000000..a2da2f5f --- /dev/null +++ b/lib/samples/create_load_report/README.metadata.json @@ -0,0 +1,58 @@ +{ + "category": "Utility Networks", + "description": "Create a simple electric distribution report that displays the count of customers and total load per phase by tracing downstream from a given point.", + "ignore": false, + "images": ["create_load_report.png"], + "keywords": [ + "condition barriers", + "downstream trace", + "network analysis", + "subnetwork trace", + "trace configuration", + "traversability", + "upstream trace", + "utility network", + "validate consistency", + "UtilityAssetType", + "UtilityCategoryComparison", + "UtilityDomainNetwork", + "UtilityElement", + "UtilityElementTraceResult", + "UtilityNetwork", + "UtilityNetworkAttribute", + "UtilityNetworkAttributeComparison", + "UtilityNetworkDefinition", + "UtilityNetworkSource", + "UtilityTerminal", + "UtilityTier", + "UtilityTraceConfiguration", + "UtilityTraceFunction", + "UtilityTraceParameters", + "UtilityTraceResult", + "UtilityTraceType", + "UtilityTraversability" + ], + "redirect_from": [], + "relevant_apis": [ + "UtilityAssetType", + "UtilityCategoryComparison", + "UtilityDomainNetwork", + "UtilityElement", + "UtilityElementTraceResult", + "UtilityNetwork", + "UtilityNetworkAttribute", + "UtilityNetworkAttributeComparison", + "UtilityNetworkDefinition", + "UtilityNetworkSource", + "UtilityTerminal", + "UtilityTier", + "UtilityTraceConfiguration", + "UtilityTraceFunction", + "UtilityTraceParameters", + "UtilityTraceResult", + "UtilityTraceType", + "UtilityTraversability" + ], + "snippets": ["create_load_report.dart"], + "title": "Create load report" +} diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart new file mode 100644 index 00000000..dd097cdb --- /dev/null +++ b/lib/samples/create_load_report/create_load_report.dart @@ -0,0 +1,447 @@ +// Copyright 2025 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 +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// 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. +// + +import 'dart:async'; +import 'dart:math'; + +import 'package:arcgis_maps/arcgis_maps.dart'; +import 'package:arcgis_maps_sdk_flutter_samples/common/common.dart'; +import 'package:arcgis_maps_sdk_flutter_samples/common/token_challenger_handler.dart'; +import 'package:flutter/material.dart'; + +class CreateLoadReport extends StatefulWidget { + const CreateLoadReport({super.key}); + + @override + State createState() => _CreateLoadReportState(); +} + +class _CreateLoadReportState extends State + with SampleStateSupport { + // The utility network instance. + late UtilityNetwork _utilityNetwork; + // The starting location for the trace. + late UtilityElement _startingLocation; + // The utility tier. + UtilityTier? _utilityTier; + // The phases current attribute. + UtilityNetworkAttribute? _phasesNetworkAttribute; + // The load attribute. + UtilityNetworkAttribute? _loadAttribute; + // The base condition for the trace. + UtilityTraceConditionalExpression? _baseCondition; + // The trace parameters. + late UtilityTraceParameters _traceParameters; + // The phase data list. + List<_PhaseData> _phaseDataList = []; + // The phase coded values. + late List _phaseCodedValues; + + // A flag when the utility network is loaded and other properties are initialized. + var _ready = false; + // A flag to indicate if the report is ready to run. + bool _readyRun = false; + // An error message to display. + String _errorMessage = ''; + + @override + void initState() { + super.initState(); + + // Set up authentication for the sample server. + // Note: Never hardcode login information in a production application. + // This is done solely for the sake of the sample. + ArcGISEnvironment + .authenticationManager + .arcGISAuthenticationChallengeHandler = TokenChallengeHandler( + 'viewer01', + 'I68VGU^nMurF', + ); + + unawaited(_initUtilityNetwork()); + } + + @override + void dispose() { + // Remove the TokenChallengeHandler and erase any credentials that were generated. + ArcGISEnvironment + .authenticationManager + .arcGISAuthenticationChallengeHandler = + null; + ArcGISEnvironment.authenticationManager.arcGISCredentialStore.removeAll(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: SafeArea( + child: Container( + padding: const EdgeInsets.fromLTRB(10, 20, 10, 10), + child: Stack( + children: [ + if (_phaseDataList.isNotEmpty) + Column( + spacing: 20, + children: [ + // The data table displaying the load report. + dataTableWidget(), + // A row of buttons: reset and run report. + Row( + spacing: 20, + children: [ + ElevatedButton( + onPressed: _ready ? reset : null, + child: const Text('Reset'), + ), + ElevatedButton( + onPressed: _readyRun ? runReport : null, + child: const Text('Run Report'), + ), + ], + ), + // Instructions text. + Text( + 'Select the phase(s) and click the "Run Report" button \nto create the load report', + style: Theme.of(context).textTheme.bodyMedium, + ), + // An error message display. + Visibility( + visible: _errorMessage.isNotEmpty, + child: Text( + _errorMessage, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.customErrorStyle, + ), + ), + ], + ) + else + LoadingIndicator( + visible: !_ready, + text: 'Initializing utility network...', + ), + ], + ), + ), + ), + ); + } + + /// Returns a widget displaying the load report data table. + Widget dataTableWidget() { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: SingleChildScrollView( + child: DataTable( + columnSpacing: 12, // spacing between constrained columns + columns: const [ + DataColumn( + label: SizedBox( + width: 100, + child: Text('Phase', overflow: TextOverflow.ellipsis), + ), + ), + DataColumn( + label: SizedBox( + width: 110, + child: Text('Customers', overflow: TextOverflow.ellipsis), + ), + ), + DataColumn( + label: SizedBox( + width: 100, + child: Text('Load (kW)', overflow: TextOverflow.ellipsis), + ), + ), + ], + rows: [ + for (final phaseData in _phaseDataList) + DataRow( + onSelectChanged: (value) => setState(() { + phaseData.selected = value ?? false; + if (!phaseData.selected) { + // Reset customers and load when not selected. + phaseData.customers = 0; + phaseData.load = 0; + } + _readyRun = _phaseDataList + .any((phaseData) => phaseData.selected); + }), + selected: phaseData.selected, + cells: [ + DataCell(Text(phaseData.phase)), + DataCell( + Text( + phaseData.customers > 0 + ? phaseData.customers.toString() + : 'N/A', + ), + ), + DataCell( + Text( + phaseData.load > 0 ? phaseData.load.toString() : 'N/A', + ), + ), + ], + ), + ], + ), + ), + ); + } + + /// Initializes the utility network and related properties. + Future _initUtilityNetwork() async { + setState(() => _ready = false); + try { + // Create a service geodatabase from the Naperville Electric feature service. + final serviceGeodatabase = ServiceGeodatabase.withUri( + Uri.parse( + 'https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectric/FeatureServer', + ), + ); + await serviceGeodatabase.load(); + // Initialize the utility network with the service geodatabase. + _utilityNetwork = UtilityNetwork(serviceGeodatabase); + await _utilityNetwork.load(); + + // Get the network source, asset group, and asset type for the starting location. + final networkSource = _utilityNetwork.definition?.networkSources + .firstWhere((ns) => ns.name == 'Electric Distribution Device'); + final assetGroup = networkSource?.assetGroups.firstWhere( + (ag) => ag.name == 'Circuit Breaker', + ); + final assetType = assetGroup?.assetTypes.firstWhere( + (at) => at.name == 'Three Phase', + ); + final terminal = assetType?.terminalConfiguration?.terminals.firstWhere( + (t) => t.name == 'Load', + ); + final globalId = Guid.fromString( + '{1CAF7740-0BF4-4113-8DB2-654E18800028}', + ); + + // Create the default starting location. + _startingLocation = _utilityNetwork.createElementWithAssetType( + assetType!, + globalId: globalId!, + terminal: terminal, + ); + + // Get the utility tier. + _utilityTier = _utilityNetwork.definition?.domainNetworks + .firstWhere((definition) => definition.name == 'ElectricDistribution') + .tiers + .firstWhere((tier) => tier.name == 'Medium Voltage Radial'); + + // Get the default trace configuration as the base condition. + _baseCondition = + _utilityTier! + .getDefaultTraceConfiguration()! + .traversability! + .barriers! + as UtilityTraceConditionalExpression; + + // Create downstream trace parameters with function outputs. + _traceParameters = UtilityTraceParameters( + UtilityTraceType.downstream, + startingLocations: [_startingLocation], + ); + // Specify the result types to include elements and function outputs. + _traceParameters.resultTypes.addAll([ + UtilityTraceResultType.elements, + UtilityTraceResultType.functionOutputs, + ]); + // Assign the trace configuration to trace parameters. + _traceParameters.traceConfiguration = _createTraceConfiguration(); + + // Create a list of possible phases from a given network attribute + _phaseCodedValues = _createPhaseList(); + + // Set the ready state variable to true to enable the sample UI. + setState(() { + _phaseDataList = getPhaseDataList(); + _ready = true; + _readyRun = true; + }); + } on Exception catch (e) { + if (!mounted) return; + setState(() { + _ready = true; + _errorMessage = 'Initialization failed: $e'; + }); + } + } + + /// Returns a default TraceConfiguration for the utility network. + UtilityTraceConfiguration _createTraceConfiguration() { + final traceConfig = _utilityTier?.getDefaultTraceConfiguration(); + + //Service Category for counting total customers + final servicePointCategory = _getServiceCategoryByName('ServicePoint'); + + //The load attribute for counting total load. + _loadAttribute = _utilityNetwork.definition?.networkAttributes.firstWhere( + (attr) => attr.name == 'Service Load', + ); + + // Create a comparison to check the existence of service points. + final serviceCategoryComparison = UtilityCategoryComparison.withCategory( + servicePointCategory, + comparisonOperator: UtilityCategoryComparisonOperator.exists, + ); + final addLoadAttributeFunction = UtilityTraceFunction( + UtilityTraceFunctionType.add, + networkAttribute: _loadAttribute!, + condition: serviceCategoryComparison, + ); + traceConfig?.functions.clear(); + + // Create function input and output condition. + traceConfig?.functions.add(addLoadAttributeFunction); + traceConfig?.outputCondition = serviceCategoryComparison; + + // Set to false to ensure that service points with incorrect phasing + // (which therefore act as barriers) are not counted with results. + traceConfig?.includeBarriers = false; + + return traceConfig!; + } + + /// Returns the utility category with the given name. + UtilityCategory _getServiceCategoryByName(String name) { + final categories = _utilityNetwork.definition?.categories.where( + (category) => category.name == name, + ); + return categories!.first; + } + + /// Returns the list of coded phase values for the phases current attribute. + /// If the attribute domain is not a coded value domain, returns an empty list. + List _createPhaseList() { + _phasesNetworkAttribute = _utilityNetwork.definition?.networkAttributes + .firstWhere((attr) => attr.name == 'Phases Current'); + + final domain = _phasesNetworkAttribute?.domain; + return domain is CodedValueDomain ? domain.codedValues : const []; + } + + /// Runs the load report for the selected phase names. + Future runReport() async { + setState(() => _readyRun = false); + + final selectedPhaseNames = _phaseDataList + .where((phaseData) => phaseData.selected) + .map((phaseData) => phaseData.phase) + .toList(); + + // Active coded values matching selection. + final activeValues = _phaseCodedValues + .where((cv) => selectedPhaseNames.contains(cv.name)) + .toList(); + + if (activeValues.isEmpty) { + return; + } + + for (final codedValue in activeValues) { + setUtilityTraceOrConditionWithCodedValue(codedValue); + final phaseData = _phaseDataList.firstWhere( + (phaseData) => phaseData.phase == codedValue.name, + ); + + final results = await _utilityNetwork.trace(_traceParameters); + for (final elementTraceResult in results) { + if (elementTraceResult is UtilityElementTraceResult) { + // Get the total customers from the UtilityElementTraceResult + final distinctIds = elementTraceResult.elements + .map((e) => e.objectId) + .toSet(); + phaseData.customers = distinctIds.length; + } else if (elementTraceResult is UtilityFunctionTraceResult) { + // Get the total load from the UtilityFunctionTraceResult + final functionResult = + elementTraceResult.functionOutputs.first.result as double; + phaseData.load = functionResult; + } + } + } + setState(() => _readyRun = true); + } + + /// Prepares trace parameters for a single phase. + void setUtilityTraceOrConditionWithCodedValue(CodedValue codedValue) { + if (_phasesNetworkAttribute == null || _baseCondition == null) { + setErrorMessage( + 'Trace cannot be run: network attribute or base condition is null.', + ); + return; + } + // Create a conditional expression with the CodedValue + final phaseAttributeComparison = + UtilityNetworkAttributeComparison.withValue( + networkAttribute: _phasesNetworkAttribute!, + comparisonOperator: + UtilityAttributeComparisonOperator.doesNotIncludeAny, + value: codedValue.code, + ); + + // Chain it with the base condition using an OR operator. + final orCondition = UtilityTraceOrCondition( + leftExpression: _baseCondition!, + rightExpression: phaseAttributeComparison!, + ); + _traceParameters.traceConfiguration?.traversability?.barriers = orCondition; + } + + /// Resets the phase data list to its initial state. + void reset() { + setState(() { + _errorMessage = ''; + _readyRun = false; + // Reset each phase data object. + for (final p in _phaseDataList) { + p.customers = 0; + p.load = 0; + p.selected = false; + } + }); + } + + /// Sets the error message to display. + void setErrorMessage(String message) { + setState(() { + _errorMessage = message; + }); + } + + /// Returns a sorted list of phase data objects. + List<_PhaseData> getPhaseDataList() { + final phaseList = + _phaseCodedValues.map((cv) => _PhaseData(cv.name)).toList() + ..sort((a, b) => a.phase.compareTo(b.phase)); + return phaseList; + } +} + +/// A data class representing phase information. +class _PhaseData { + _PhaseData(this.phase); + final String phase; + bool selected = false; + int customers = 0; + double load = 0; +} diff --git a/lib/samples/create_load_report/create_load_report.png b/lib/samples/create_load_report/create_load_report.png new file mode 100644 index 0000000000000000000000000000000000000000..70a14157d655e36bb75e5b0b137727d9ea5ed363 GIT binary patch literal 57577 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 WN3%hRgkZmMLqk Date: Wed, 19 Nov 2025 16:00:30 -0800 Subject: [PATCH 02/10] self-review update --- lib/samples/create_load_report/README.md | 4 ++-- lib/samples/create_load_report/create_load_report.dart | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/samples/create_load_report/README.md b/lib/samples/create_load_report/README.md index 1fb4c0c0..09f0b178 100644 --- a/lib/samples/create_load_report/README.md +++ b/lib/samples/create_load_report/README.md @@ -2,7 +2,7 @@ Create a simple electric distribution report that displays the count of customers and total load per phase by tracing downstream from a given point. -![](create_load_report.png) +![Image of create utility network load report](create_load_report.png) ## Use case @@ -58,4 +58,4 @@ Using utility network on ArcGIS Enterprise 10.8 requires an ArcGIS Enterprise me ## Tags -condition barriers, downstream trace, network analysis, subnetwork trace, trace configuration, traversability, upstream trace, utility network, validate consistency \ No newline at end of file +condition barriers, downstream trace, network analysis, subnetwork trace, trace configuration, traversability, upstream trace, utility network, validate consistency diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index dd097cdb..b861e0f0 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -14,7 +14,6 @@ // import 'dart:async'; -import 'dart:math'; import 'package:arcgis_maps/arcgis_maps.dart'; import 'package:arcgis_maps_sdk_flutter_samples/common/common.dart'; From 9b8ee646dad042e3dfc32e1de70bbed0410b8d1d Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Wed, 19 Nov 2025 16:05:00 -0800 Subject: [PATCH 03/10] Update lib/samples/create_load_report/create_load_report.dart Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/samples/create_load_report/create_load_report.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index b861e0f0..0d5c954d 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -289,10 +289,10 @@ class _CreateLoadReportState extends State UtilityTraceConfiguration _createTraceConfiguration() { final traceConfig = _utilityTier?.getDefaultTraceConfiguration(); - //Service Category for counting total customers + // Service Category for counting total customers final servicePointCategory = _getServiceCategoryByName('ServicePoint'); - //The load attribute for counting total load. + // The load attribute for counting total load. _loadAttribute = _utilityNetwork.definition?.networkAttributes.firstWhere( (attr) => attr.name == 'Service Load', ); From 768f7e81160f464d8908d692c055f01db72f87c4 Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Wed, 19 Nov 2025 16:10:46 -0800 Subject: [PATCH 04/10] add the error message. --- lib/samples/create_load_report/create_load_report.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index 0d5c954d..db2c31e9 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -353,6 +353,7 @@ class _CreateLoadReportState extends State .toList(); if (activeValues.isEmpty) { + setErrorMessage('No phases selected for the report.'); return; } From d12d5742e186e1c7f6c7c11e24a639bd3e06ecfa Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Thu, 20 Nov 2025 08:58:53 -0800 Subject: [PATCH 05/10] remove the init value --- lib/samples/create_load_report/create_load_report.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index db2c31e9..31461903 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -274,7 +274,6 @@ class _CreateLoadReportState extends State setState(() { _phaseDataList = getPhaseDataList(); _ready = true; - _readyRun = true; }); } on Exception catch (e) { if (!mounted) return; From fe49350214c8d7f414982d31220ab2de5da6dedc Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Fri, 21 Nov 2025 09:34:16 -0800 Subject: [PATCH 06/10] review update. --- .../create_load_report.dart | 70 ++++++++----------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index 31461903..9d4ea2fa 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -34,13 +34,13 @@ class _CreateLoadReportState extends State // The starting location for the trace. late UtilityElement _startingLocation; // The utility tier. - UtilityTier? _utilityTier; + late UtilityTier _utilityTier; // The phases current attribute. - UtilityNetworkAttribute? _phasesNetworkAttribute; + late UtilityNetworkAttribute _phasesNetworkAttribute; // The load attribute. - UtilityNetworkAttribute? _loadAttribute; + late UtilityNetworkAttribute _loadAttribute; // The base condition for the trace. - UtilityTraceConditionalExpression? _baseCondition; + late UtilityTraceConditionalExpression _baseCondition; // The trace parameters. late UtilityTraceParameters _traceParameters; // The phase data list. @@ -51,9 +51,9 @@ class _CreateLoadReportState extends State // A flag when the utility network is loaded and other properties are initialized. var _ready = false; // A flag to indicate if the report is ready to run. - bool _readyRun = false; + var _readyRun = false; // An error message to display. - String _errorMessage = ''; + var _errorMessage = ''; @override void initState() { @@ -145,7 +145,7 @@ class _CreateLoadReportState extends State scrollDirection: Axis.horizontal, child: SingleChildScrollView( child: DataTable( - columnSpacing: 12, // spacing between constrained columns + columnSpacing: 12, columns: const [ DataColumn( label: SizedBox( @@ -241,14 +241,14 @@ class _CreateLoadReportState extends State ); // Get the utility tier. - _utilityTier = _utilityNetwork.definition?.domainNetworks + _utilityTier = _utilityNetwork.definition!.domainNetworks .firstWhere((definition) => definition.name == 'ElectricDistribution') .tiers .firstWhere((tier) => tier.name == 'Medium Voltage Radial'); // Get the default trace configuration as the base condition. _baseCondition = - _utilityTier! + _utilityTier .getDefaultTraceConfiguration()! .traversability! .barriers! @@ -276,7 +276,6 @@ class _CreateLoadReportState extends State _ready = true; }); } on Exception catch (e) { - if (!mounted) return; setState(() { _ready = true; _errorMessage = 'Initialization failed: $e'; @@ -286,54 +285,53 @@ class _CreateLoadReportState extends State /// Returns a default TraceConfiguration for the utility network. UtilityTraceConfiguration _createTraceConfiguration() { - final traceConfig = _utilityTier?.getDefaultTraceConfiguration(); + final traceConfig = _utilityTier.getDefaultTraceConfiguration()!; - // Service Category for counting total customers + // Service Category for counting total customers. final servicePointCategory = _getServiceCategoryByName('ServicePoint'); // The load attribute for counting total load. - _loadAttribute = _utilityNetwork.definition?.networkAttributes.firstWhere( + _loadAttribute = _utilityNetwork.definition!.networkAttributes.firstWhere( (attr) => attr.name == 'Service Load', ); // Create a comparison to check the existence of service points. final serviceCategoryComparison = UtilityCategoryComparison.withCategory( - servicePointCategory, + servicePointCategory!, comparisonOperator: UtilityCategoryComparisonOperator.exists, ); final addLoadAttributeFunction = UtilityTraceFunction( UtilityTraceFunctionType.add, - networkAttribute: _loadAttribute!, + networkAttribute: _loadAttribute, condition: serviceCategoryComparison, ); - traceConfig?.functions.clear(); + traceConfig.functions.clear(); // Create function input and output condition. - traceConfig?.functions.add(addLoadAttributeFunction); - traceConfig?.outputCondition = serviceCategoryComparison; - + traceConfig.functions.add(addLoadAttributeFunction); + traceConfig.outputCondition = serviceCategoryComparison; // Set to false to ensure that service points with incorrect phasing // (which therefore act as barriers) are not counted with results. - traceConfig?.includeBarriers = false; + traceConfig.includeBarriers = false; - return traceConfig!; + return traceConfig; } /// Returns the utility category with the given name. - UtilityCategory _getServiceCategoryByName(String name) { - final categories = _utilityNetwork.definition?.categories.where( + UtilityCategory? _getServiceCategoryByName(String name) { + final category = _utilityNetwork.definition?.categories.firstWhere( (category) => category.name == name, ); - return categories!.first; + return category; } /// Returns the list of coded phase values for the phases current attribute. /// If the attribute domain is not a coded value domain, returns an empty list. List _createPhaseList() { - _phasesNetworkAttribute = _utilityNetwork.definition?.networkAttributes + _phasesNetworkAttribute = _utilityNetwork.definition!.networkAttributes .firstWhere((attr) => attr.name == 'Phases Current'); - final domain = _phasesNetworkAttribute?.domain; + final domain = _phasesNetworkAttribute.domain; return domain is CodedValueDomain ? domain.codedValues : const []; } @@ -365,13 +363,13 @@ class _CreateLoadReportState extends State final results = await _utilityNetwork.trace(_traceParameters); for (final elementTraceResult in results) { if (elementTraceResult is UtilityElementTraceResult) { - // Get the total customers from the UtilityElementTraceResult + // Get the total customers from the UtilityElementTraceResult. final distinctIds = elementTraceResult.elements .map((e) => e.objectId) .toSet(); phaseData.customers = distinctIds.length; } else if (elementTraceResult is UtilityFunctionTraceResult) { - // Get the total load from the UtilityFunctionTraceResult + // Get the total load from the UtilityFunctionTraceResult. final functionResult = elementTraceResult.functionOutputs.first.result as double; phaseData.load = functionResult; @@ -383,25 +381,19 @@ class _CreateLoadReportState extends State /// Prepares trace parameters for a single phase. void setUtilityTraceOrConditionWithCodedValue(CodedValue codedValue) { - if (_phasesNetworkAttribute == null || _baseCondition == null) { - setErrorMessage( - 'Trace cannot be run: network attribute or base condition is null.', - ); - return; - } - // Create a conditional expression with the CodedValue + // Create a conditional expression with the CodedValue. final phaseAttributeComparison = UtilityNetworkAttributeComparison.withValue( - networkAttribute: _phasesNetworkAttribute!, + networkAttribute: _phasesNetworkAttribute, comparisonOperator: UtilityAttributeComparisonOperator.doesNotIncludeAny, value: codedValue.code, - ); + )!; // Chain it with the base condition using an OR operator. final orCondition = UtilityTraceOrCondition( - leftExpression: _baseCondition!, - rightExpression: phaseAttributeComparison!, + leftExpression: _baseCondition, + rightExpression: phaseAttributeComparison, ); _traceParameters.traceConfiguration?.traversability?.barriers = orCondition; } From bf048b80a984fa9106ca78620b6f999008e2468d Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Fri, 21 Nov 2025 09:52:44 -0800 Subject: [PATCH 07/10] review update --- .../create_load_report/create_load_report.dart | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index 9d4ea2fa..b99ef703 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -176,8 +176,9 @@ class _CreateLoadReportState extends State phaseData.customers = 0; phaseData.load = 0; } - _readyRun = _phaseDataList - .any((phaseData) => phaseData.selected); + _readyRun = _phaseDataList.any( + (phaseData) => phaseData.selected, + ); }), selected: phaseData.selected, cells: [ @@ -231,12 +232,12 @@ class _CreateLoadReportState extends State ); final globalId = Guid.fromString( '{1CAF7740-0BF4-4113-8DB2-654E18800028}', - ); + )!; // Create the default starting location. _startingLocation = _utilityNetwork.createElementWithAssetType( assetType!, - globalId: globalId!, + globalId: globalId, terminal: terminal, ); @@ -248,10 +249,7 @@ class _CreateLoadReportState extends State // Get the default trace configuration as the base condition. _baseCondition = - _utilityTier - .getDefaultTraceConfiguration()! - .traversability! - .barriers! + _utilityTier.getDefaultTraceConfiguration()!.traversability!.barriers! as UtilityTraceConditionalExpression; // Create downstream trace parameters with function outputs. From 3bdc1f4c27ac5c26f1bca268c0ed323d91dd62e8 Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Fri, 21 Nov 2025 10:05:21 -0800 Subject: [PATCH 08/10] review update --- lib/samples/create_load_report/create_load_report.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index b99ef703..98fc8eaf 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -44,7 +44,7 @@ class _CreateLoadReportState extends State // The trace parameters. late UtilityTraceParameters _traceParameters; // The phase data list. - List<_PhaseData> _phaseDataList = []; + var _phaseDataList = <_PhaseData>[]; // The phase coded values. late List _phaseCodedValues; From 225708429fce290363d3bcf607a636a40b9c70b0 Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Fri, 21 Nov 2025 10:10:55 -0800 Subject: [PATCH 09/10] review update --- lib/samples/create_load_report/create_load_report.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index 98fc8eaf..885637d0 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -69,7 +69,7 @@ class _CreateLoadReportState extends State 'I68VGU^nMurF', ); - unawaited(_initUtilityNetwork()); + _initUtilityNetwork(); } @override From 878b9b66a70a9d49cb65ec2532371a2c251b00ac Mon Sep 17 00:00:00 2001 From: Changan Shi Date: Fri, 21 Nov 2025 14:45:00 -0800 Subject: [PATCH 10/10] review update --- .../create_load_report.dart | 75 +++++++++---------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/lib/samples/create_load_report/create_load_report.dart b/lib/samples/create_load_report/create_load_report.dart index 885637d0..797c37cf 100644 --- a/lib/samples/create_load_report/create_load_report.dart +++ b/lib/samples/create_load_report/create_load_report.dart @@ -91,47 +91,47 @@ class _CreateLoadReportState extends State padding: const EdgeInsets.fromLTRB(10, 20, 10, 10), child: Stack( children: [ - if (_phaseDataList.isNotEmpty) - Column( - spacing: 20, - children: [ - // The data table displaying the load report. - dataTableWidget(), - // A row of buttons: reset and run report. - Row( - spacing: 20, - children: [ - ElevatedButton( - onPressed: _ready ? reset : null, - child: const Text('Reset'), - ), - ElevatedButton( - onPressed: _readyRun ? runReport : null, - child: const Text('Run Report'), - ), - ], - ), - // Instructions text. - Text( - 'Select the phase(s) and click the "Run Report" button \nto create the load report', - style: Theme.of(context).textTheme.bodyMedium, - ), - // An error message display. - Visibility( - visible: _errorMessage.isNotEmpty, + Column( + spacing: 20, + children: [ + // The data table displaying the load report. + dataTableWidget(), + // A row of buttons: reset and run report. + Row( + spacing: 20, + children: [ + ElevatedButton( + onPressed: _ready ? reset : null, + child: const Text('Reset'), + ), + ElevatedButton( + onPressed: _readyRun ? runReport : null, + child: const Text('Run Report'), + ), + ], + ), + // Instructions text. + Text( + 'Select the phase(s) and click the "Run Report" button \nto create the load report', + style: Theme.of(context).textTheme.bodyMedium, + ), + // An error message display. + Visibility( + visible: _errorMessage.isNotEmpty, + child: Expanded( child: Text( _errorMessage, - overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.customErrorStyle, ), ), - ], - ) - else - LoadingIndicator( - visible: !_ready, - text: 'Initializing utility network...', - ), + ), + ], + ), + // a loading indicator while the utility network is initializing. + LoadingIndicator( + visible: !_ready, + text: 'Initializing utility network...', + ), ], ), ), @@ -213,7 +213,6 @@ class _CreateLoadReportState extends State 'https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectric/FeatureServer', ), ); - await serviceGeodatabase.load(); // Initialize the utility network with the service geodatabase. _utilityNetwork = UtilityNetwork(serviceGeodatabase); await _utilityNetwork.load(); @@ -276,7 +275,7 @@ class _CreateLoadReportState extends State } on Exception catch (e) { setState(() { _ready = true; - _errorMessage = 'Initialization failed: $e'; + _errorMessage = 'Initialization failed: \n$e'; }); } }