publicstatic UtilityNetwork GetUtilityNetworkFromTable(Tabletable){UtilityNetworkutilityNetwork=null;if(table.IsControllerDatasetSupported()){// Tables can belong to multiple controller datasets, but at most one of them will be a UtilityNetworkIReadOnlyList<Dataset>controllerDatasets= table.GetControllerDatasets();foreach(Dataset controllerDataset in controllerDatasets){if(controllerDataset is UtilityNetwork){utilityNetwork= controllerDataset as UtilityNetwork;}else{
controllerDataset.Dispose();}}}returnutilityNetwork;}
Get a Utility Network from a Layer
// This routine obtains a utility network from a FeatureLayer, SubtypeGroupLayer, or UtilityNetworkLayerpublicstatic UtilityNetwork GetUtilityNetworkFromLayer(Layerlayer){UtilityNetworkutilityNetwork=null;if(layer is UtilityNetworkLayer){UtilityNetworkLayerutilityNetworkLayer= layer as UtilityNetworkLayer;utilityNetwork= utilityNetworkLayer.GetUtilityNetwork();}elseif(layer is SubtypeGroupLayer){CompositeLayercompositeLayer= layer as CompositeLayer;utilityNetwork= GetUtilityNetworkFromLayer(compositeLayer.Layers.First());}elseif(layer is FeatureLayer){FeatureLayerfeatureLayer= layer as FeatureLayer;using(FeatureClassfeatureClass= featureLayer.GetFeatureClass()){if(featureClass.IsControllerDatasetSupported()){IReadOnlyList<Dataset>controllerDatasets=newList<Dataset>();controllerDatasets= featureClass.GetControllerDatasets();foreach(Dataset controllerDataset in controllerDatasets){if(controllerDataset is UtilityNetwork){utilityNetwork= controllerDataset as UtilityNetwork;}else{
controllerDataset.Dispose();}}}}}returnutilityNetwork;}
Elements
Fetching a Row from an Element
// usage : using (var row = FetchRowFromElement(...))publicstatic Row FetchRowFromElement(UtilityNetworkutilityNetwork,Elementelement){// Get the table from the elementusing(Tabletable= utilityNetwork.GetTable(element.NetworkSource)){// Create a query filter to fetch the appropriate rowQueryFilterqueryFilter=new QueryFilter(){ObjectIDs=newList<long>(){ element.ObjectID }};// Fetch and return the rowusing(RowCursorrowCursor= table.Search(queryFilter)){if(rowCursor.MoveNext()){return rowCursor.Current;}returnnull;}}}
// Create edit operationEditOperationeditOperation=new EditOperation();
editOperation.Name ="Create structural attachment association";// Create a RowHandle for the poleElementpoleElement= utilityNetwork.CreateElement(poleAssetType, poleGlobalID);RowHandlepoleRowHandle=new RowHandle(poleElement, utilityNetwork);// Create a RowHandle for the transformer bankElementtransformerBankElement= utilityNetwork.CreateElement(transformerBankAssetType, transformerBankGlobalID);RowHandletransformerBankRowHandle=new RowHandle(transformerBankElement, utilityNetwork);// Attach the transformer bank to the poleAssociationDescriptionstructuralAttachmentAssociationDescription=new AssociationDescription(AssociationType.Attachment, poleRowHandle, transformerBankRowHandle);
editOperation.Create(structuralAttachmentAssociationDescription);
editOperation.Execute();
Create utility network features and associations in a single edit operation
// Create an EditOperationEditOperationeditOperation=new EditOperation();
editOperation.Name ="Create pole; create transformer bank; attach transformer bank to pole";// Create the transformer bankRowTokentransformerBankToken= editOperation.Create(transformerBankLayer, transformerBankAttributes);// Create a poleRowTokenpoleToken= editOperation.Create(poleLayer, poleAttributes);// Create a structural attachment association between the pole and the transformer bankRowHandlepoleHandle=new RowHandle(poleToken);RowHandletransformerBankHandle=new RowHandle(transformerBankToken);AssociationDescriptionpoleAttachment=new AssociationDescription(AssociationType.Attachment, poleHandle, transformerBankHandle);
editOperation.Create(poleAttachment);// Execute the EditOperation
editOperation.Execute();
Traverse Associations
Get traverse associations result from downward traversal
publicstaticvoidGetTraverseAssociationsResultFromDownwardTraversal(UtilityNetworkutilityNetwork,IReadOnlyList<Element>startingElements){// Set downward traversal with maximum depthTraverseAssociationsDescriptiontraverseAssociationsDescription=new TraverseAssociationsDescription(TraversalDirection.Descending);// Get traverse associations result from the staring element up to maximum depthTraverseAssociationsResulttraverseAssociationsResult= utilityNetwork.TraverseAssociations(startingElements, traverseAssociationsDescription);// Get associations participated in traversalIReadOnlyList<Association>associations= traverseAssociationsResult.Associations;}
Get traverse associations result from upward traversal with depth limit
publicstaticvoidGetTraverseAssociationsResultFromUpwardTraversalWithDepthLimit(UtilityNetworkutilityNetwork,IReadOnlyList<Element>startingElements){// List of fields whose values will be fetched as name-values pairs during association traversal operationList<string>additionalFieldsToFetch=newList<string>{"ObjectId","AssetName","AssetGroup","AssetType"};// Set downward traversal with maximum depth level of 3 TraverseAssociationsDescriptiontraverseAssociationsDescription=new TraverseAssociationsDescription(TraversalDirection.Ascending,3){AdditionalFields=additionalFieldsToFetch};// Get traverse associations result from the staring element up to depth level 3TraverseAssociationsResulttraverseAssociationsResult= utilityNetwork.TraverseAssociations(startingElements, traverseAssociationsDescription);// List of associations participated in traversalIReadOnlyList<Association>associations= traverseAssociationsResult.Associations;// KeyValue mapping between involved elements and their field name-values //At 2.x - IReadOnlyDictionary<Element, IReadOnlyList<AssociationElementFieldValue>> associationElementValuePairs = traverseAssociationsResult.AdditionalFieldValues;IReadOnlyDictionary<Element,IReadOnlyList<FieldValue>>associationElementValuePairs=
traverseAssociationsResult.AdditionalFieldValues;foreach(KeyValuePair<Element,IReadOnlyList<FieldValue>> keyValuePair in associationElementValuePairs){// Element Elementelement= keyValuePair.Key;// List of field names and their values //At 2.x - IReadOnlyList<AssociationElementFieldValue> elementFieldValues = keyValuePair.Value;IReadOnlyList<FieldValue>elementFieldValues= keyValuePair.Value;}}
Subnetworks and Tiers
Find a Tier given a Domain Network name and Tier name
Life cycle for a simple radial subnetwork with one controller
// Create a subnetwork named "Radial1" with a single controller// elementR1 represents the device that serves as the subnetwork controller (e.g., circuit breaker)SubnetworksubnetworkRadial1= subnetworkManager.EnableControllerInEditOperation(mediumVoltageTier, elementR1,"Radial1","R1","my description","my notes");// ...// Update the subnetwork and refresh the map
subnetworkRadial1.Update();
MapView.Active.Redraw(true);// ...// At some point, a subnetwork will need to be deleted.// First step is to disable the controller
subnetworkManager.DisableControllerInEditOperation(elementR1);// At this point, the subnetwork is deleted, but all of the rows that have been labeled with the subnetwork ID need to be updated
subnetworkRadial1.Update();
MapView.Active.Redraw(true);// The final step is to notify external systems (if any) by exporting the subnetworkSubnetworkExportOptionssubnetworkExportOptions=new SubnetworkExportOptions(){SetAcknowledged=true,IncludeDomainDescriptions=true,IncludeGeometry=true,ServiceSynchronizationType= ServiceSynchronizationType.Asynchronous,SubnetworkExportResultTypes=newList<SubnetworkExportResultType>(){
SubnetworkExportResultType.Features
}// Set networks attributes and attribute fields to export//ResultNetworkAttributes = new List<NetworkAttribute>(networkAttributes),//ResultFieldsByNetworkSourceID = new Dictionary<int, List<string>>()// { { electricDevice.ID, new List<string>() { "AssetID" } } }};
subnetworkRadial1.Export(new Uri($"{Path.GetTempPath()}SubnetworkExportResult.json"), subnetworkExportOptions);
Life cycle for a mesh subnetwork with multiple controllers
// Create a subnetwork named "Mesh1" from three controllers// elementM1, elementM2, and elementM3 represent the devices that serve as subnetwork controllers (e.g., network protectors)
subnetworkManager.EnableController(lowVoltageMeshTier, elementM1,"Mesh1","M1","my description","my notes");
subnetworkManager.EnableController(lowVoltageMeshTier, elementM2,"Mesh1","M2","my description","my notes");SubnetworksubnetworkMesh1= subnetworkManager.EnableController(lowVoltageMeshTier, elementM3,"Mesh1","M3","my description","my notes");
subnetworkMesh1.Update();
MapView.Active.Redraw(true);// ...// When deleting the subnetwork, each controller must be disabled before the subnetwork itself is deleted
subnetworkManager.DisableControllerInEditOperation(elementM1);
subnetworkManager.DisableControllerInEditOperation(elementM2);
subnetworkManager.DisableControllerInEditOperation(elementM3);// After the subnetwork is deleted, all of the rows that have been labeled with the subnetwork ID need to be updated
subnetworkMesh1.Update();
MapView.Active.Redraw(true);// The final step is to notify external systems (if any) by exporting the subnetworkSubnetworkExportOptionssubnetworkExportOptions=new SubnetworkExportOptions(){SetAcknowledged=true,IncludeDomainDescriptions=true,IncludeGeometry=true,ServiceSynchronizationType= ServiceSynchronizationType.Asynchronous,SubnetworkExportResultTypes=newList<SubnetworkExportResultType>(){
SubnetworkExportResultType.Features
}// Set networks attributes and attribute fields to export//ResultNetworkAttributes = new List<NetworkAttribute>(networkAttributes),//ResultFieldsByNetworkSourceID = new Dictionary<int, List<string>>()// { { electricDevice.ID, new List<string>() { "AssetID" } } }};
subnetworkMesh1.Export(new Uri($"{Path.GetTempPath()}SubnetworkExportResult.json"), subnetworkExportOptions);
Life cycle for a multifeed radial subnetwork with two controllers
// Create a subnetwork named "R2, R3" from two controllers// elementR2 and elementR3 represent the devices that serve as subnetwork controllers (e.g., circuit breakers)
subnetworkManager.EnableControllerInEditOperation(mediumVoltageTier, elementR2,"R2, R3","R2","my description","my notes");
subnetworkManager.EnableControllerInEditOperation(mediumVoltageTier, elementR3,"R2, R3","R3","my description","my notes");// If the tie switch between them is opened, the original subnetwork controllers must be disabled and re-enabled with different names// This will create two new subnetworks, named "R2" and "R3"
subnetworkManager.DisableControllerInEditOperation(elementR2);
subnetworkManager.DisableControllerInEditOperation(elementR3);SubnetworksubnetworkR2= subnetworkManager.EnableControllerInEditOperation(mediumVoltageTier, elementR2,"R2","R2","my description","my notes");SubnetworksubnetworkR3= subnetworkManager.EnableControllerInEditOperation(mediumVoltageTier, elementR3,"R3","R3","my description","my notes");
subnetworkR2.Update();
subnetworkR3.Update();
MapView.Active.Redraw(true);
IReadOnlyList<Element>startingPointList=newList<Element>();// Code to fill in list of starting points goes here...TraceArgumenttraceArgument=new TraceArgument(startingPointList);TraceConfigurationtraceConfiguration=new TraceConfiguration();// Code to fill in trace configuration goes here...
traceArgument.Configuration =traceConfiguration;
Create a Condition to compare a Network Attribute against a set of values
// Create a NetworkAttribute object for the Lifecycle network attribute from the UtilityNetworkDefinitionusing(NetworkAttributelifecycleNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("Lifecycle")){// Create a NetworkAttributeComparison that stops traversal if Lifecycle <> "In Design" (represented by the constant InDesign)NetworkAttributeComparisoninDesignNetworkAttributeComparison=new NetworkAttributeComparison(lifecycleNetworkAttribute, Operator.NotEqual, InDesign);// Create a NetworkAttributeComparison to stop traversal if Lifecycle <> "In Service" (represented by the constant InService)NetworkAttributeComparisoninServiceNetworkAttributeComparison=new NetworkAttributeComparison(lifecycleNetworkAttribute, Operator.NotEqual, InService);// Combine these two comparisons together with "And"AndlifecycleFilter=new And(inDesignNetworkAttributeComparison, inServiceNetworkAttributeComparison);// Final condition stops traversal if Lifecycle <> "In Design" and Lifecycle <> "In Service"
traceConfiguration.Traversability.Barriers =lifecycleFilter;}
Create a Function
// Get a NetworkAttribute object for the Load network attribute from the UtilityNetworkDefinitionusing(NetworkAttributeloadNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("Load")){// Create a function to sum the LoadAddsumLoadFunction=new Add(loadNetworkAttribute);// Add this function to our trace configuration
traceConfiguration.Functions =newList<Function>(){ sumLoadFunction };}
Create a FunctionBarrier
// Create a NetworkAttribute object for the Shape length network attribute from the UtilityNetworkDefinitionusing(NetworkAttributeshapeLengthNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("Shape length")){// Create a function that adds up shape lengthAddlengthFunction=new Add(shapeLengthNetworkAttribute);// Create a function barrier that stops traversal after 1000 feetFunctionBarrierdistanceBarrier=new FunctionBarrier(lengthFunction, Operator.GreaterThan,1000.0);// Set this function barrier
traceConfiguration.Traversability.FunctionBarriers =newList<FunctionBarrier>(){ distanceBarrier };}
Create an output condition
// Create an output category to filter the trace results to only include// features with the "Service Point" category assigned
traceConfiguration.OutputCondition =new CategoryComparison(CategoryOperator.IsEqual,"Service Point");
Create a Propagator
// Get a NetworkAttribute object for the Phases Normal attribute from the UtilityNetworkDefinitionusing(NetworkAttributenormalPhaseAttribute= utilityNetworkDefinition.GetNetworkAttribute("Phases Normal")){// Create a propagator to propagate the Phases Normal attribute downstream from the source, using a Bitwise And function// Allow traversal to continue as long as the Phases Normal value includes any of the ABC phases// (represented by the constant ABCPhase)PropagatorphasePropagator=new Propagator(normalPhaseAttribute, PropagatorFunction.BitwiseAnd, Operator.IncludesAny, ABCPhase);// Assign this propagator to our trace configuration
traceConfiguration.Propagators =newList<Propagator>(){ phasePropagator };}
Using Function Results
// Get the FunctionOutputResult from the trace resultsFunctionOutputResultfunctionOutputResult= traceResults.OfType<FunctionOutputResult>().First();// First() can be used here if only one Function was included in the TraceConfiguration.Functions collection.// Otherwise you will have to search the list for the correct FunctionOutput object.FunctionOutputfunctionOutput= functionOutputResult.FunctionOutputs.First();// Extract the total load from the GlobalValue propertydoubletotalLoad=(double)functionOutput.Value;
Fetch a named trace configuration by name
private NamedTraceConfiguration GetNamedTraceConfigurationsByName(UtilityNetworkutilityNetwork,stringconfigurationName="WaterNetwork"){// Query to find named trace configurationsNamedTraceConfigurationQuerynamedTraceConfigurationQuery=new NamedTraceConfigurationQuery {Names=newList<string>{ configurationName }};// Get the trace manager from the utility networkusing(TraceManagertraceManager= utilityNetwork.GetTraceManager()){// A set of named trace configurations specified by the named traced configuration query IReadOnlyList<NamedTraceConfiguration>namedTraceConfigurations= traceManager.GetNamedTraceConfigurations(namedTraceConfigurationQuery);NamedTraceConfigurationwaterConfiguration= namedTraceConfigurations.First(f => f.Description.Equals(configurationName));returnwaterConfiguration;}}
Fetch named trace configurations from a utility network layer
private NamedTraceConfiguration GetNamedTraceConfigurationsFromUtilityNetworkLayer(UtilityNetworkLayerutilityNetworkLayer,stringconfigurationName="WaterNetwork"){// Get all named trace configurations in the utility networkIReadOnlyList<NamedTraceConfiguration>namedTraceConfigurations= utilityNetworkLayer.GetNamedTraceConfigurations();foreach(NamedTraceConfiguration namedTraceConfiguration in namedTraceConfigurations){if(namedTraceConfiguration.Name ==configurationName){returnnamedTraceConfiguration;}}returnnull;}
Trace a utility network using a named trace configuration
privatevoidTraceUtilityNetworkUsingNamedTraceConfiguration(UtilityNetworkutilityNetwork,NamedTraceConfigurationnamedTraceConfiguration,ElementstartElement){// Get the trace manager from the utility networkusing(TraceManagertraceManager= utilityNetwork.GetTraceManager()){// Get a tracer from the trace manager using the named trace configurationTracerupstreamTracer= traceManager.GetTracer(namedTraceConfiguration);// Trace argument holding the trace input parametersTraceArgumentupstreamTraceArgument=new TraceArgument(namedTraceConfiguration,newList<Element>{ startElement });// Trace results IReadOnlyList<Result>upstreamTraceResults= upstreamTracer.Trace(upstreamTraceArgument);}}
Trace a utility network with the digitized direction
privatevoidTraceWithDigitizedDirection(UtilityNetworkutilityNetwork,ElementstartElement){usingTraceManagertraceManager= utilityNetwork.GetTraceManager();// Trace configuration with digitized direction TraceConfigurationtraceConfiguration=new TraceConfiguration(){IncludeIsolatedFeatures=true,IncludeBarriersWithResults=true,UseDigitizedDirection=true};// Trace argumentList<Element>startElements=newList<Element>{ startElement };TraceArgumenttraceArgument=new TraceArgument(startElements);
traceArgument.Configuration =traceConfiguration;// ResultsDownstreamTracerdownstreamTracer= traceManager.GetTracer<DownstreamTracer>();IReadOnlyList<Result>traceResults= downstreamTracer.Trace(traceArgument);foreach(Result traceResult in traceResults){// Iterate trace results}}
Export a utility network trace as a JSON file
privatevoidExportUtilityNetworkTraceAsJSON(UtilityNetworkutilityNetwork){using(TraceManagertraceManager= utilityNetwork.GetTraceManager())using(UtilityNetworkDefinitionutilityNetworkDefinition= utilityNetwork.GetDefinition())using(NetworkSourcedeviceNetworkSource= GetNetworkSource(utilityNetworkDefinition,"GasDevice")as NetworkSource)using(FeatureClassdistributionDeviceFeatureClass= utilityNetwork.GetTable(deviceNetworkSource)as FeatureClass)using(FeatureClassDefinitiondistributionDeviceDefinition= distributionDeviceFeatureClass.GetDefinition())using(AssetGroupdeviceAssetGroup= deviceNetworkSource.GetAssetGroup("Regulator"))using(AssetTypedeviceAssetType= deviceAssetGroup.GetAssetType("Pressure Reducing"))using(NetworkAttributedeviceStatusNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("DeviceStatus"))using(NetworkAttributeaccessibleNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("Accessible")){// Domain and tier informationDomainNetworkdomainNetwork= utilityNetworkDefinition.GetDomainNetwork("Gas");TierpipeDistributionSystemTier= domainNetwork.GetTier("Pipe Distribution");// Start elementsElementstartingPoint1= utilityNetwork.CreateElement(deviceAssetType, Guid.Parse("{28CF437E-950C-41B7-B839-8BC45570DE40}"));ElementstartingPoint2= utilityNetwork.CreateElement(deviceAssetType, Guid.Parse("{63C22828-7BC9-49ED-A14A-A596559B6CB3}"));
startingPoint1.Terminal = startingPoint1.AssetType.GetTerminalConfiguration().Terminals.First(x => x.IsUpstreamTerminal);
startingPoint2.Terminal = startingPoint2.AssetType.GetTerminalConfiguration().Terminals.First(x => x.IsUpstreamTerminal);List<Element>startingPoints=newList<Element>(){ startingPoint1, startingPoint2 };List<Element>barriers=newList<Element>();// Set up trace filter: DeviceStatus = Open (1) AND Accessible = 1NetworkAttributeComparisonstatusNetworkAttributeComparison=new NetworkAttributeComparison(deviceStatusNetworkAttribute, Operator.Equal,1);NetworkAttributeComparisonnetworkAttributeComparison=new NetworkAttributeComparison(accessibleNetworkAttribute, Operator.Equal,1);// Set trace configuration TraceConfigurationtraceConfiguration=new TraceConfiguration
{AllowIndeterminateFlow=true,IgnoreBarriersAtStartingPoints=false,IncludeBarriersWithResults=true,IncludeContainers=true,IncludeContent=true,IncludeIsolatedFeatures=false,IncludeUpToFirstSpatialContainer=false};
traceConfiguration.Filter.Barriers =new And(statusNetworkAttributeComparison, networkAttributeComparison);
traceConfiguration.DomainNetwork =domainNetwork;
traceConfiguration.SourceTier =pipeDistributionSystemTier;// Attribute fields of a network sourceList<string>deviceFields= distributionDeviceDefinition.GetFields().Select(f => f.Name).ToList();// Network attributes List<string>networkattributeNames=newList<string>();IReadOnlyList<NetworkAttribute>networkAttributes= utilityNetworkDefinition.GetNetworkAttributes();foreach(NetworkAttribute networkAttribute in networkAttributes){
networkattributeNames.Add(networkAttribute.Name);}// Result TypesList<ResultType>resultTypeList=newList<ResultType>(){ ResultType.Feature };// Resutl OptionsResultOptionsresultOptions=new ResultOptions(){IncludeGeometry=true,NetworkAttributes=networkattributeNames,ResultFields=newDictionary<NetworkSource,List<string>>(){{ deviceNetworkSource, deviceFields }}};// Trace ArgumentsTraceArgumenttraceArgument=new TraceArgument(startingPoints){Barriers=barriers,Configuration=traceConfiguration,ResultTypes=resultTypeList,ResultOptions=resultOptions};ConnectedTracerconnectedTracer= traceManager.GetTracer<ConnectedTracer>();// Set export options TraceExportOptionsexportOptions=new TraceExportOptions(){ServiceSynchronizationType= ServiceSynchronizationType.Asynchronous,IncludeDomainDescriptions=true,};// Path to export JSONstringjsonPath=$"{Path.GetTempPath()}TraceResults.json";UrijsonUri=new Uri(jsonPath);// Export
connectedTracer.Export(jsonUri, traceArgument, exportOptions);stringjsonAbsolutePath= HttpUtility.UrlDecode(jsonUri.AbsolutePath);if(jsonUri.IsFile && File.Exists(jsonAbsolutePath)){// Work with the JSON results}}
NetworkSource GetNetworkSource(UtilityNetworkDefinitionunDefinition,stringname){IReadOnlyList<NetworkSource>allSources= unDefinition.GetNetworkSources();foreach(NetworkSource source in allSources){if(name.Contains("Partitioned Sink")){if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())||
source.Name.Replace("","").ToUpper().Contains(name.Replace("Partitioned Sink","Part_Sink").Replace("","").ToUpper())){returnsource;}}if(name.Contains("Hierarchical Sink")){if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())||
source.Name.Replace("","").ToUpper().Contains(name.Replace("Hierarchical Sink","Hier_Sink").Replace("","").ToUpper())){returnsource;}}if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())){returnsource;}}returnnull;}}
Fetch features and network attributes from a utility network during trace
privatevoidFetchFeaturesAndAttributes(UtilityNetworkutilityNetwork){using(TraceManagertraceManager= utilityNetwork.GetTraceManager())using(UtilityNetworkDefinitionutilityNetworkDefinition= utilityNetwork.GetDefinition())using(NetworkSourcedeviceNetworkSource= GetNetworkSource(utilityNetworkDefinition,"GasDevice")as NetworkSource)using(FeatureClassdistributionDeviceFeatureClass= utilityNetwork.GetTable(deviceNetworkSource)as FeatureClass)using(FeatureClassDefinitiondistributionDeviceDefinition= distributionDeviceFeatureClass.GetDefinition())using(AssetGroupdeviceAssetGroup= deviceNetworkSource.GetAssetGroup("Regulator"))using(AssetTypedeviceAssetType= deviceAssetGroup.GetAssetType("Pressure Reducing"))using(NetworkAttributedeviceStatusNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("DeviceStatus"))using(NetworkAttributeaccessibleNetworkAttribute= utilityNetworkDefinition.GetNetworkAttribute("Accessible")){// Domain and tier informationDomainNetworkdomainNetwork= utilityNetworkDefinition.GetDomainNetwork("Gas");TierpipeDistributionSystemTier= domainNetwork.GetTier("Pipe Distribution");// Start elementsElementstartingPoint1= utilityNetwork.CreateElement(deviceAssetType, Guid.Parse("{28CF437E-950C-41B7-B839-8BC45570DE40}"));ElementstartingPoint2= utilityNetwork.CreateElement(deviceAssetType, Guid.Parse("{63C22828-7BC9-49ED-A14A-A596559B6CB3}"));
startingPoint1.Terminal = startingPoint1.AssetType.GetTerminalConfiguration().Terminals.First(x => x.IsUpstreamTerminal);
startingPoint2.Terminal = startingPoint2.AssetType.GetTerminalConfiguration().Terminals.First(x => x.IsUpstreamTerminal);List<Element>startingPoints=newList<Element>(){ startingPoint1, startingPoint2 };List<Element>barriers=newList<Element>();// Set up trace filter: DeviceStatus = Open (1) AND Accessible = 1NetworkAttributeComparisonstatusNetworkAttributeComparison=new NetworkAttributeComparison(deviceStatusNetworkAttribute, Operator.Equal,1);NetworkAttributeComparisonnetworkAttributeComparison=new NetworkAttributeComparison(accessibleNetworkAttribute, Operator.Equal,1);// Set trace configuration TraceConfigurationtraceConfiguration=new TraceConfiguration
{AllowIndeterminateFlow=true,IgnoreBarriersAtStartingPoints=false,IncludeBarriersWithResults=true,IncludeContainers=true,IncludeContent=true,IncludeIsolatedFeatures=false,IncludeUpToFirstSpatialContainer=false};
traceConfiguration.Filter.Barriers =new And(statusNetworkAttributeComparison, networkAttributeComparison);
traceConfiguration.DomainNetwork =domainNetwork;
traceConfiguration.SourceTier =pipeDistributionSystemTier;// Attribute fields of a network sourceList<string>deviceFields= distributionDeviceDefinition.GetFields().Select(f => f.Name).ToList();// Network attributes List<string>networkattributeNames=newList<string>();IReadOnlyList<NetworkAttribute>networkAttributes= utilityNetworkDefinition.GetNetworkAttributes();foreach(NetworkAttribute networkAttribute in networkAttributes){
networkattributeNames.Add(networkAttribute.Name);}// Result TypesList<ResultType>resultTypeList=newList<ResultType>(){ ResultType.Feature };// Resutl OptionsResultOptionsresultOptions=new ResultOptions(){IncludeGeometry=true,NetworkAttributes=networkattributeNames,ResultFields=newDictionary<NetworkSource,List<string>>(){{ deviceNetworkSource, deviceFields }}};// Trace ArgumentsTraceArgumenttraceArgument=new TraceArgument(startingPoints){Barriers=barriers,Configuration=traceConfiguration,ResultTypes=resultTypeList,ResultOptions=resultOptions};// Tracer ConnectedTracerconnectedTracer= traceManager.GetTracer<ConnectedTracer>();// Async trace resultIReadOnlyList<Result>traceResults= connectedTracer.Trace(traceArgument, ServiceSynchronizationType.Asynchronous);// Iterate trace resultsforeach(Result traceResult in traceResults){if(traceResult is FeatureElementResult featureElementResult){IReadOnlyList<FeatureElement>featureElements= featureElementResult.FeatureElements;}}}// Helper inline function
NetworkSource GetNetworkSource(UtilityNetworkDefinitionunDefinition,stringname){IReadOnlyList<NetworkSource>allSources= unDefinition.GetNetworkSources();foreach(NetworkSource source in allSources){if(name.Contains("Partitioned Sink")){if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())||
source.Name.Replace("","").ToUpper().Contains(name.Replace("Partitioned Sink","Part_Sink").Replace("","").ToUpper())){returnsource;}}if(name.Contains("Hierarchical Sink")){if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())||
source.Name.Replace("","").ToUpper().Contains(name.Replace("Hierarchical Sink","Hier_Sink").Replace("","").ToUpper())){returnsource;}}if(source.Name.Replace("","").ToUpper().Contains(name.Replace("","").ToUpper())){returnsource;}}returnnull;}}
Get selected features from a list of elements
privatevoidFeatureSelectionsFromTrace(UtilityNetworkutilityNetwork,TraceArgumenttraceArgument){// Get the trace manager from the utility networkusing(TraceManagertraceManager= utilityNetwork.GetTraceManager()){UpstreamTracertracer= traceManager.GetTracer<UpstreamTracer>();IReadOnlyList<Result>tracerResults= tracer.Trace(traceArgument);foreach(Result traceResult in tracerResults){if(traceResult is ElementResult elementResult){IReadOnlyList<Element>elements= elementResult.Elements;// Feature selection from a list of elementsIReadOnlyList<Selection>selections= utilityNetwork.GetFeaturesForElements(elements);}}}}
Network Diagrams
Get the Diagram Manager
using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// Todo - do something}
Get Network Diagrams
using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// get all the diagramsIReadOnlyList<NetworkDiagram>diagrams= diagramManager.GetNetworkDiagrams();// get a diagram by nameNetworkDiagramdiagram= diagramManager.GetNetworkDiagram(diagrameName);// get diagrams by extentdiagrams= diagramManager.GetNetworkDiagrams(extentOfInterest);// get diagrams from a set of utility network feature GlobalIDsdiagrams= diagramManager.GetNetworkDiagrams(globalIDs);// get diagrams from a set of utility network feature GlobalIDs within an extentdiagrams= diagramManager.GetNetworkDiagrams(extentOfInterest, globalIDs);}
Get a list of Network Diagrams with inconsistent ConsistencyState
publicList<NetworkDiagram>GetInconsistentDiagrams(UtilityNetworkutilityNetwork){// Get the DiagramManager from the utility networkusing(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){List<NetworkDiagram>myList=newList<NetworkDiagram>();// Loop through the network diagrams in the diagram managerforeach(NetworkDiagram diagram in diagramManager.GetNetworkDiagrams()){NetworkDiagramInfodiagramInfo= diagram.GetDiagramInfo();// If the diagram is not a system diagram and is in an inconsistent state, add it to our listif(!diagramInfo.IsSystem && diagram.GetConsistencyState()!= NetworkDiagramConsistencyState.DiagramIsConsistent){
myList.Add(diagram);}else{
diagram.Dispose();// If we are not returning it we need to Dispose it}}returnmyList;}}
Open a diagram pane from a Network Diagram
// Create a diagram layer from a NetworkDiagram (myDiagram)DiagramLayerdiagramLayer=await QueuedTask.Run<DiagramLayer>(()=>{// Create the diagram mapvarnewMap= MapFactory.Instance.CreateMap(myDiagram.Name, ArcGIS.Core.CIM.MapType.NetworkDiagram, MapViewingMode.Map);if(newMap==null)returnnull;// Open the diagram mapvarmapPane= ArcGIS.Desktop.Core.ProApp.Panes.CreateMapPaneAsync(newMap, MapViewingMode.Map);if(mapPane==null)returnnull;//Add the diagram to the mapreturn newMap.AddDiagramLayer(myDiagram);});
Get Diagram from DiagramLayer
publicvoidGetDiagram(DiagramLayerdiagramLayer){// note - methods need to run on MCTNetworkDiagramdiagram= diagramLayer.GetNetworkDiagram();// get the consistency state from the layerDiagramLayerConsistencyStatedlState= diagramLayer.ConsistencyState;// or from the diagramNetworkDiagramConsistencyStatendState= diagram.GetConsistencyState();}
Get Diagram Templates
publicvoidRetrieveDiagramTemplates(UtilityNetworkutilityNetwork){using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// get all templatesIReadOnlyList<DiagramTemplate>templates= diagramManager.GetDiagramTemplates();// get a template by nameDiagramTemplatetemplate= diagramManager.GetDiagramTemplate(templateName);}}
Get Network Diagrams from a Diagram Template
publicvoidGetNetworkDiagramFromDiagramTemplates(UtilityNetworkutilityNetwork){using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// get the first templatesDiagramTemplatetemplate= diagramManager.GetDiagramTemplates().FirstOrDefault();// get the network diagrams fromt he templateIEnumerable<NetworkDiagram>diagrams= template.GetNetworkDiagrams();// or get a network diagram by nameNetworkDiagramdiagram= template.GetNetworkDiagram(diagrameName);}}
Create a Network Diagram
publicvoidCreateNetworkDiagram(UtilityNetworkutilityNetwork,IEnumerable<Guid>globalIDs){using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// get the templateDiagramTemplatetemplate= diagramManager.GetDiagramTemplate(templateName);// create the diagramNetworkDiagramdiagram= diagramManager.CreateNetworkDiagram(template, globalIDs);}}
Get Network Diagram Information as JSON string
publicvoidGetDiagramContent(UtilityNetworkutilityNetwork){using(DiagramManagerdiagramManager= utilityNetwork.GetDiagramManager()){// get a diagram by nameNetworkDiagramdiagram= diagramManager.GetNetworkDiagram(templateName);stringjson_content= diagram.GetContent(true,true,true,true);}}
Get Diagram Elements
publicvoidGetDiagramElements(MapViewmapView,NetworkDiagramnetworkDiagram){// Create a DiagramElementQueryByExtent to retrieve diagram element junctions whose extent// intersects the active map extentDiagramElementQueryByExtentelementQuery=new DiagramElementQueryByExtent();
elementQuery.ExtentOfInterest = MapView.Active.Extent;
elementQuery.AddContents =false;
elementQuery.QueryDiagramJunctionElement =true;
elementQuery.QueryDiagramEdgeElement =false;
elementQuery.QueryDiagramContainerElement =false;// Use this DiagramElementQueryByExtent as an argument to the QueryDiagramElements methodDiagramElementQueryResultresult= networkDiagram.QueryDiagramElements(elementQuery);// get the container, junction, edge elements// in this case result.DiagramJunctionElements and result.DiagramEdgeElements will be empty // since elementQuery.QueryDiagramEdgeElement and elementQuery.QueryDiagramContainerElement are set to falseIReadOnlyList<DiagramContainerElement>containerElements= result.DiagramContainerElements;IReadOnlyList<DiagramJunctionElement>junctionElements= result.DiagramJunctionElements;IReadOnlyList<DiagramEdgeElement>edgeElements= result.DiagramEdgeElements;}
Get Diagram Aggregations
publicvoidGetDiagramAggregation(NetworkDiagramnetworkDiagram){IReadOnlyList<DiagramAggregation>aggregations= networkDiagram.GetAggregations();foreach(var aggregation in aggregations){vartype= aggregation.AggregationType;}}
Find Diagram Features for a set of utility network rows
Find Initial Network Rows Used to create a Network Diagram
publicvoidFindInitialNetworkRows(NetworkDiagramdiagram){IReadOnlyList<FindResultItem>rows= diagram.FindInitialNetworkRows();foreach(var findRow in rows){longobjectID= findRow.ObjectID;Guidguid= findRow.GlobalID;GeometryTypegeometryType= findRow.GeometryType;intsourceID= findRow.SourceID;}}
Change the Layout of a Network Diagram
publicvoidDiagramElementQueryResultAndNetworkDiagramSubsetClasses(Geodatabasegeodatabase,DiagramManagerdiagramManager,stringdiagramName){// Retrieve a diagramusing(NetworkDiagramdiagramTest= diagramManager.GetNetworkDiagram(diagramName)){// Create a DiagramElementQueryByElementTypes query object to get the diagram elements we want to work withDiagramElementQueryByElementTypesquery=new DiagramElementQueryByElementTypes();
query.QueryDiagramJunctionElement =true;
query.QueryDiagramEdgeElement =true;
query.QueryDiagramContainerElement =true;// Retrieve those diagram elementsDiagramElementQueryResultelements= diagramTest.QueryDiagramElements(query);// Create a NetworkDiagramSubset object to edit this set of diagram elementsNetworkDiagramSubsetsubset=new NetworkDiagramSubset();
subset.DiagramJunctionElements = elements.DiagramJunctionElements;
subset.DiagramEdgeElements = elements.DiagramEdgeElements;
subset.DiagramContainerElements = elements.DiagramContainerElements;// Edit the shapes of the diagram elements - left as an exercise for the student
TranslateDiagramElements(subset);// Save the new layout of the diagram elements
diagramTest.SaveLayout(subset,true);}}
Editing Network Diagram
publicvoidEditDiagram(NetworkDiagramdiagram,List<Guid>globalIDs){// These routines generate their own editing transaction, and therefore cannot be wrapped// in a separate transaction. Because the editing performed by these routines cannot// be undone, thise routines can also not be called within an editing session. All// edits in the current edit session must be saved or discarded before calling these// routines.// refresh the diagram - synchronizes it based on the latest network topology
diagram.Update();// append features to the diagram
diagram.Append(globalIDs);// overite the diagram with a set of features
diagram.Overwrite(globalIDs);NetworkDiagramInfoinfo= diagram.GetDiagramInfo();if(info.CanExtend){
diagram.Extend(NetworkDiagramExtendType.ExtendByContainment);// or extend for only a set of utility network globalIDs
diagram.Extend(NetworkDiagramExtendType.ExtendByContainment, globalIDs);}// delete a diagran
diagram.Delete();}