Ejemplo n.º 1
0
        // ValidateDataModel - This sample is hard-wired to a particular version of the Naperville data model.
        // This routine checks to make sure we are using the correct one
        private bool ValidateDataModel(UtilityNetwork utilityNetwork)
        {
            bool dataModelIsValid = false;

            try
            {
                using (UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.GetDefinition())

                    using (NetworkSource transformerBankNetworkSource = GetNetworkSource(utilityNetworkDefinition, AssemblyNetworkSourceName))
                        using (AssetGroup transformerBankAssetGroup = transformerBankNetworkSource.GetAssetGroup(TransformerBankAssetGroupName))
                            using (AssetType transformerBankAssetType = transformerBankAssetGroup.GetAssetType(TransformerBankAssetTypeName))

                                // Transformer
                                using (NetworkSource deviceNetworkSource = GetNetworkSource(utilityNetworkDefinition, DeviceNetworkSourceName))
                                    using (AssetGroup transformerAssetGroup = deviceNetworkSource.GetAssetGroup(TransformerAssetGroupName))
                                        using (AssetType transformerAssetType = transformerAssetGroup.GetAssetType(TransformerAssetTypeName))

                                            // Arrester
                                            using (AssetGroup arresterAssetGroup = deviceNetworkSource.GetAssetGroup(ArresterAssetGroupName))
                                                using (AssetType arresterAssetType = arresterAssetGroup.GetAssetType(ArresterAssetTypeName))

                                                    // Fuse
                                                    using (AssetGroup fuseAssetGroup = deviceNetworkSource.GetAssetGroup(FuseAssetGroupName))
                                                        using (AssetType fuseAssetType = fuseAssetGroup.GetAssetType(FuseAssetTypeName))
                                                        {
                                                            // Find the upstream terminal on the transformer
                                                            TerminalConfiguration terminalConfiguration = transformerAssetType.GetTerminalConfiguration();
                                                            Terminal upstreamTerminal = null;
                                                            foreach (Terminal terminal in terminalConfiguration.Terminals)
                                                            {
                                                                if (terminal.IsUpstreamTerminal)
                                                                {
                                                                    upstreamTerminal = terminal;
                                                                    break;
                                                                }
                                                            }

                                                            // Find the terminal on the fuse
                                                            Terminal fuseTerminal = fuseAssetType.GetTerminalConfiguration().Terminals[0];

                                                            // Find the terminal on the arrester
                                                            Terminal arresterTerminal = arresterAssetType.GetTerminalConfiguration().Terminals[0];

                                                            // All of our asset groups and asset types exist.  Now we have to check for rules.

                                                            IReadOnlyList <Rule> rules = utilityNetworkDefinition.GetRules();
                                                            if (ContainmentRuleExists(rules, transformerBankAssetType, transformerAssetType) &&
                                                                ContainmentRuleExists(rules, transformerBankAssetType, fuseAssetType) &&
                                                                ContainmentRuleExists(rules, transformerBankAssetType, arresterAssetType) &&
                                                                ConnectivityRuleExists(rules, transformerAssetType, upstreamTerminal, fuseAssetType, fuseTerminal) &&
                                                                ConnectivityRuleExists(rules, fuseAssetType, fuseTerminal, arresterAssetType, arresterTerminal))
                                                            {
                                                                dataModelIsValid = true;
                                                            }
                                                        }
            }
            catch { }

            return(dataModelIsValid);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This routine takes a row from the starting (or barrier) point table and converts it to a [Network] Element that we can use for tracing
        /// </summary>
        /// <param name="pointRow">The Row (either starting point or barrier point)</param>
        /// <param name="utilityNetwork">Utility Network to be used</param>
        /// <param name="definition">Utility Network definition to be used</param>
        /// <returns>newly created element</returns>
        private static Element GetElementFromPointRow(Row pointRow,
                                                      UtilityNetwork utilityNetwork, UtilityNetworkDefinition definition)
        {
            // Fetch the SourceID, AssetGroupCode, AssetType, GlobalID, and TerminalID values from the starting point row
            int    sourceID     = (int)pointRow[PointsSourceIDFieldName];
            int    assetGroupID = (int)pointRow[PointsAssetGroupFieldName];
            int    assetTypeID  = (int)pointRow[PointsAssetTypeFieldName];
            Guid   globalID     = new Guid(pointRow[PointsGlobalIDFieldName].ToString());
            int    terminalID   = (int)pointRow[PointsTerminalFieldName];
            double percentAlong = (double)pointRow[PointsPercentAlong];

            // Fetch the NetworkSource, AssetGroup, and AssetType objects
            NetworkSource networkSource = definition.GetNetworkSources().First(x => x.ID == sourceID);
            AssetGroup    assetGroup    = networkSource.GetAssetGroups().First(x => x.Code == assetGroupID);
            AssetType     assetType     = assetGroup.GetAssetTypes().First(x => x.Code == assetTypeID);

            // Fetch the Terminal object from the ID
            Terminal terminal = null;

            if (assetType.IsTerminalConfigurationSupported())
            {
                TerminalConfiguration terminalConfiguration = assetType.GetTerminalConfiguration();
                terminal = terminalConfiguration.Terminals.First(x => x.ID == terminalID);
            }

            // Create and return a FeatureElement object
            // If we have an edge, set the PercentAlongEdge property; otherwise set the Terminal property
            if (networkSource.Type == SourceType.Edge)
            {
                Element element = utilityNetwork.CreateElement(assetType, globalID);
                element.PercentAlongEdge = percentAlong;
                return(element);
            }
            else
            {
                Element element = utilityNetwork.CreateElement(assetType, globalID, terminal);
                return(element);
            }
        }
        /// <summary>
        /// GetNetworkElementFromStartingPoint
        ///
        /// This routine takes a row from the starting point table and converts it to a NetworkElement that we can use for tracing
        ///
        /// </summary>
        ///

        private Element GetElementFromStartingPointRow(Row startingPointRow, UtilityNetwork utilityNetwork, UtilityNetworkDefinition definition)
        {
            // Fetch the SourceID, AssetGroupCode, AssetType, GlobalID, and TerminalID values from the starting point row

            object vSourceID = startingPointRow[StartingPointsSourceIDFieldName];
            int    sourceID  = (int)vSourceID;

            object vAssetGroupID = startingPointRow[StartingPointsAssetGroupFieldName];
            int    assetGroupID  = (int)vAssetGroupID;

            object vAssetTypeID = startingPointRow[StartingPointsAssetTypeFieldName];
            int    assetTypeID  = (int)vAssetTypeID;

            object vGlobalID = startingPointRow[StartingPointsGlobalIDFieldName];
            Guid   globalID  = new Guid(vGlobalID.ToString());

            object vTerminalID = startingPointRow[StartingPointsTerminalFieldName];
            int    terminalID  = (int)vTerminalID;

            // Fetch the NetworkSource, AssetGroup, and AssetType objects

            NetworkSource networkSource = definition.GetNetworkSources().First(x => x.ID == sourceID);
            AssetGroup    assetGroup    = networkSource.GetAssetGroups().First(x => x.Code == assetGroupID);
            AssetType     assetType     = assetGroup.GetAssetTypes().First(x => x.Code == assetTypeID);

            // Fetch the Terminal object from the ID
            Terminal terminal = null;

            if (assetType.IsTerminalConfigurationSupported())
            {
                TerminalConfiguration terminalConfiguration = assetType.GetTerminalConfiguration();
                terminal = terminalConfiguration.Terminals.First(x => x.ID == terminalID);
            }

            // Create and return a Element object

            return(utilityNetwork.CreateElement(assetType, globalID, terminal));
        }
        private static void ExecuteTrace(Guid traceStartGuid, string geodatabasePath)
        {
            using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(geodatabasePath))))
            {
                IReadOnlyList <UtilityNetworkDefinition> utilityNetworkDefinitions = geodatabase.GetDefinitions <UtilityNetworkDefinition>();

                string utilityNetworkName = string.Empty;

                if (utilityNetworkDefinitions.Count < 0 || utilityNetworkDefinitions.Count > 1)
                {
                    return;
                }

                // Get utility network name from the dataset
                foreach (UtilityNetworkDefinition definition in utilityNetworkDefinitions)
                {
                    utilityNetworkName = definition.GetName();

                    Console.WriteLine($"Utility network name: {utilityNetworkName}");
                    definition.Dispose();
                }

                // Open utility network
                using (UtilityNetwork utilityNetwork = geodatabase.OpenDataset <UtilityNetwork>(utilityNetworkName))
                    using (UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.GetDefinition())
                    {
                        using (NetworkSource networkSource = utilityNetworkDefinition.GetNetworkSource("ElectricDevice"))
                            using (AssetGroup assetGroup = networkSource.GetAssetGroup("Medium Voltage Transformer"))
                                using (AssetType assetType = assetGroup.GetAssetType("Overhead Single Phase"))
                                {
                                    DomainNetwork      domainNetwork      = utilityNetworkDefinition.GetDomainNetwork("Electric");
                                    Tier               sourceTier         = domainNetwork.GetTier("Electric Distribution");
                                    TraceConfiguration traceConfiguration = sourceTier.GetTraceConfiguration();

                                    // Get downstream side of the terminal
                                    Terminal terminal = null;
                                    if (assetType.IsTerminalConfigurationSupported())
                                    {
                                        TerminalConfiguration    terminalConfiguration = assetType.GetTerminalConfiguration();
                                        IReadOnlyList <Terminal> terminals             = terminalConfiguration.Terminals;
                                        terminal = terminals.First(t => !t.IsUpstreamTerminal);
                                    }

                                    // Create an element to begin a trace
                                    Element startingPointElement = utilityNetwork.CreateElement(assetType, traceStartGuid, terminal);

                                    List <Element> startingPoints = new List <Element>();
                                    startingPoints.Add(startingPointElement);


                                    // Get trace manager
                                    using (TraceManager traceManager = utilityNetwork.GetTraceManager())
                                    {
                                        // Set trace configurations
                                        TraceArgument traceArgument = new TraceArgument(startingPoints);
                                        traceArgument.Configuration = traceConfiguration;

                                        // Get downstream tracer
                                        Tracer tracer = traceManager.GetTracer <DownstreamTracer>();

                                        // Execuate downstream trace
                                        IReadOnlyList <Result> traceResults = tracer.Trace(traceArgument);

                                        // Display trace results in console
                                        foreach (Result result in traceResults)
                                        {
                                            if (result is ElementResult)
                                            {
                                                ElementResult           elementResult = result as ElementResult;
                                                IReadOnlyList <Element> elements      = elementResult.Elements;

                                                Console.WriteLine("Trace result elements:");
                                                foreach (Element element in elements)
                                                {
                                                    Console.WriteLine($"\t OID: {element.ObjectID}, Name:{element.AssetType.Name}");
                                                }
                                            }
                                            else if (result is FunctionOutputResult)
                                            {
                                                FunctionOutputResult           functionResult  = result as FunctionOutputResult;
                                                IReadOnlyList <FunctionOutput> functionOutputs = functionResult.FunctionOutputs;

                                                Console.WriteLine("Trace result function outputs:");
                                                foreach (FunctionOutput functionOut in functionOutputs)
                                                {
                                                    Console.WriteLine($"\t Function result:{functionOut.Value}, name: {functionOut.Function}");
                                                }
                                            }
                                            else if (result is AggregatedGeometryResult)
                                            {
                                                AggregatedGeometryResult aggResults = result as AggregatedGeometryResult;
                                                Polyline   aggregatedLine           = aggResults.Line as Polyline;
                                                Multipoint aggregatedPoint          = aggResults.Point as Multipoint;
                                                Polygon    aggregatedPolygon        = aggResults.Polygon as Polygon;
                                            }
                                        }
                                    }
                                }
                    }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Called when the sketch finishes. This is where we will create the sketch operation and then execute it.
        /// </summary>
        /// <param name="geometry">The geometry created by the sketch.</param>
        /// <returns>A Task returning a Boolean indicating if the sketch complete event was successfully handled.</returns>
        protected override async Task <bool> OnSketchCompleteAsync(Geometry geometry)
        {
            if (geometry == null)
            {
                return(false);
            }

            // Create an edit operation
            var createOperation = new EditOperation();

            createOperation.Name = "Create Transformer Bank";
            createOperation.SelectNewFeatures = true;

            bool   success      = false;
            string errorMessage = "";

            await QueuedTask.Run(() =>
            {
                Map map = GetMap();

                using (UtilityNetwork utilityNetwork = GetUtilityNetwork())
                {
                    if (utilityNetwork == null)
                    {
                        errorMessage = "Please select a layer that participates in a utility network.";
                    }
                    else
                    {
                        using (UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.GetDefinition())

                            // Get the NetworkSource, AssetGroup, and AssetTypes for all of the features we want to create
                            // If this was production code, you would want to check the return values to make sure that these asset groups and asset types existed.

                            // TransformerBank
                            using (NetworkSource transformerBankNetworkSource = utilityNetworkDefinition.GetNetworkSource(AssemblyNetworkSourceName))
                                using (AssetGroup transformerBankAssetGroup = transformerBankNetworkSource.GetAssetGroup(TransformerBankAssetGroupName))
                                    using (AssetType transformerBankAssetType = transformerBankAssetGroup.GetAssetType(TransformerBankAssetTypeName))

                                        // Transformer
                                        using (NetworkSource deviceNetworkSource = utilityNetworkDefinition.GetNetworkSource(DeviceNetworkSourceName))
                                            using (AssetGroup transformerAssetGroup = deviceNetworkSource.GetAssetGroup(TransformerAssetGroupName))
                                                using (AssetType transformerAssetType = transformerAssetGroup.GetAssetType(TransformerAssetTypeName))

                                                    // Arrester
                                                    using (AssetGroup arresterAssetGroup = deviceNetworkSource.GetAssetGroup(ArresterAssetGroupName))
                                                        using (AssetType arresterAssetType = arresterAssetGroup.GetAssetType(ArresterAssetTypeName))

                                                            // Fuse
                                                            using (AssetGroup fuseAssetGroup = deviceNetworkSource.GetAssetGroup(FuseAssetGroupName))
                                                                using (AssetType fuseAssetType = fuseAssetGroup.GetAssetType(FuseAssetTypeName))
                                                                {
                                                                    MapPoint clickPoint = geometry as MapPoint;

                                                                    // Create a transformer bank
                                                                    Layer transformerBankLayer      = GetLayerForEdit(map, AssemblyNetworkSourceName, TransformerBankAssetGroupName);
                                                                    RowToken token                  = createOperation.CreateEx(transformerBankLayer, CreateAttributes(transformerBankAssetGroup, transformerBankAssetType, clickPoint));
                                                                    RowHandle transformerBankHandle = new RowHandle(token);

                                                                    // Create three transformers, one for each phase
                                                                    Layer transformerLayer = GetLayerForEdit(map, DeviceNetworkSourceName, TransformerAssetGroupName);

                                                                    MapPoint transformerPointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, YOffset);
                                                                    token = createOperation.CreateEx(transformerLayer, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointA, APhase));
                                                                    RowHandle transformerHandleA = new RowHandle(token);

                                                                    MapPoint transformerPointB = CreateOffsetMapPoint(clickPoint, 0, YOffset);
                                                                    token = createOperation.CreateEx(transformerLayer, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointB, BPhase));
                                                                    RowHandle transformerHandleB = new RowHandle(token);

                                                                    MapPoint transformerPointC = CreateOffsetMapPoint(clickPoint, XOffset, YOffset);
                                                                    token = createOperation.CreateEx(transformerLayer, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointC, CPhase));
                                                                    RowHandle transformerHandleC = new RowHandle(token);

                                                                    // Create containment associations between the bank and the transformers
                                                                    ContainmentAssociationDescription containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, transformerHandleA, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, transformerHandleB, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, transformerHandleC, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    // Create three arresters, one for each phase
                                                                    Layer arresterLayer = GetLayerForEdit(map, DeviceNetworkSourceName, ArresterAssetGroupName);

                                                                    MapPoint arresterPointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, 2 * YOffset);
                                                                    token = createOperation.CreateEx(arresterLayer, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointA, APhase));
                                                                    RowHandle arresterHandlA = new RowHandle(token);

                                                                    MapPoint arresterPointB = CreateOffsetMapPoint(clickPoint, 0, 2 * YOffset);
                                                                    token = createOperation.CreateEx(arresterLayer, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointB, BPhase));
                                                                    RowHandle arresterHandleB = new RowHandle(token);

                                                                    MapPoint arresterPointC = CreateOffsetMapPoint(clickPoint, XOffset, 2 * YOffset);
                                                                    token = createOperation.CreateEx(arresterLayer, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointC, CPhase));
                                                                    RowHandle arresterHandleC = new RowHandle(token);

                                                                    // Create containment associations between the bank and the arresters
                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, arresterHandlA, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, arresterHandleB, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, arresterHandleC, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    // Find the high-side terminal for transformers
                                                                    TerminalConfiguration transformerTerminalConfiguration = transformerAssetType.GetTerminalConfiguration();
                                                                    IReadOnlyList <Terminal> terminals = transformerTerminalConfiguration.Terminals;
                                                                    Terminal highSideTerminal          = terminals.First(x => x.IsUpstreamTerminal == true);
                                                                    long highSideTerminalID            = highSideTerminal.ID;

                                                                    // Connect the high-side transformer terminals to the arresters (connect the A-phase transformer to the A-phase arrester, and so on)
                                                                    ConnectivityAssociationDescription connectivityAssociationDescription = new ConnectivityAssociationDescription(transformerHandleA, highSideTerminalID, arresterHandlA);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    connectivityAssociationDescription = new ConnectivityAssociationDescription(transformerHandleB, highSideTerminalID, arresterHandleB);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    connectivityAssociationDescription = new ConnectivityAssociationDescription(transformerHandleC, highSideTerminalID, arresterHandleC);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    // Create three fuses, one for each phase
                                                                    Layer fuseLayer = GetLayerForEdit(map, DeviceNetworkSourceName, FuseAssetGroupName);

                                                                    MapPoint fusePointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, 3 * YOffset);
                                                                    token = createOperation.CreateEx(fuseLayer, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointA, APhase));
                                                                    RowHandle fuseHandleA = new RowHandle(token);

                                                                    MapPoint fusePointB = CreateOffsetMapPoint(clickPoint, 0, 3 * YOffset);
                                                                    token = createOperation.CreateEx(fuseLayer, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointB, BPhase));
                                                                    RowHandle fuseHandleB = new RowHandle(token);

                                                                    MapPoint fusePointC = CreateOffsetMapPoint(clickPoint, XOffset, 3 * YOffset);
                                                                    token = createOperation.CreateEx(fuseLayer, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointC, CPhase));
                                                                    RowHandle fuseHandleC = new RowHandle(token);

                                                                    // Create containment associations between the bank and the fuses
                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, fuseHandleA, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, fuseHandleB, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    containmentAssociationDescription = new ContainmentAssociationDescription(transformerBankHandle, fuseHandleC, false);
                                                                    createOperation.Create(containmentAssociationDescription);

                                                                    // Create connectivity associations between the fuses and the arresters (connect the A-phase fuse the A-phase arrester, and so on)
                                                                    connectivityAssociationDescription = new ConnectivityAssociationDescription(fuseHandleA, arresterHandlA);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    connectivityAssociationDescription = new ConnectivityAssociationDescription(fuseHandleB, arresterHandleB);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    connectivityAssociationDescription = new ConnectivityAssociationDescription(fuseHandleC, arresterHandleC);
                                                                    createOperation.Create(connectivityAssociationDescription);

                                                                    // Execute the edit operation, which creates all of the rows and associations
                                                                    success = createOperation.Execute();

                                                                    if (!success)
                                                                    {
                                                                        errorMessage = createOperation.ErrorMessage;
                                                                    }
                                                                }
                    }
                }
            });

            if (!success)
            {
                MessageBox.Show(errorMessage, "Create Transformer Bank Tool");
            }
            return(success);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Called when the sketch finishes. This is where we will create the sketch operation and then execute it.
        /// </summary>
        /// <param name="geometry">The geometry created by the sketch.</param>
        /// <returns>A Task returning a Boolean indicating if the sketch complete event was successfully handled.</returns>
        protected override async Task <bool> OnSketchCompleteAsync(Geometry geometry)
        {
            if (geometry == null)
            {
                return(false);
            }

            // Create an edit operation
            var createOperation = new EditOperation()
            {
                Name = "Create Transformer Bank",
                SelectNewFeatures = true
            };

            bool   success      = false;
            string errorMessage = "";

            await QueuedTask.Run(() =>
            {
                Map map = GetMap();

                using (UtilityNetwork utilityNetwork = GetUtilityNetwork())
                {
                    if (utilityNetwork == null)
                    {
                        errorMessage = "Please select a layer that participates in a utility network.";
                    }
                    else
                    {
                        if (!ValidateDataModel(utilityNetwork))
                        {
                            errorMessage = "This sample is designed for a different utility network data model";
                        }
                        else
                        {
                            using (UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.GetDefinition())
                                // Get the NetworkSource, FeatureClass, AssetGroup, and AssetTypes for all of the features we want to create
                                // The existence of these values has already been confirmed in the ValidateDataModel() routine

                                // TransformerBank
                                using (NetworkSource transformerBankNetworkSource = GetNetworkSource(utilityNetworkDefinition, AssemblyNetworkSourceName))
                                    using (FeatureClass transformerBankFeatureClass = utilityNetwork.GetTable(transformerBankNetworkSource) as FeatureClass)
                                        using (AssetGroup transformerBankAssetGroup = transformerBankNetworkSource.GetAssetGroup(TransformerBankAssetGroupName))
                                            using (AssetType transformerBankAssetType = transformerBankAssetGroup.GetAssetType(TransformerBankAssetTypeName))

                                                // Transformer
                                                using (NetworkSource deviceNetworkSource = GetNetworkSource(utilityNetworkDefinition, DeviceNetworkSourceName))
                                                    using (FeatureClass deviceFeatureClass = utilityNetwork.GetTable(deviceNetworkSource) as FeatureClass)
                                                        using (AssetGroup transformerAssetGroup = deviceNetworkSource.GetAssetGroup(TransformerAssetGroupName))
                                                            using (AssetType transformerAssetType = transformerAssetGroup.GetAssetType(TransformerAssetTypeName))

                                                                // Arrester
                                                                using (AssetGroup arresterAssetGroup = deviceNetworkSource.GetAssetGroup(ArresterAssetGroupName))
                                                                    using (AssetType arresterAssetType = arresterAssetGroup.GetAssetType(ArresterAssetTypeName))

                                                                        // Fuse
                                                                        using (AssetGroup fuseAssetGroup = deviceNetworkSource.GetAssetGroup(FuseAssetGroupName))
                                                                            using (AssetType fuseAssetType = fuseAssetGroup.GetAssetType(FuseAssetTypeName))
                                                                            {
                                                                                MapPoint clickPoint = geometry as MapPoint;

                                                                                // Create a transformer bank

                                                                                RowToken token = createOperation.CreateEx(transformerBankFeatureClass, CreateAttributes(transformerBankAssetGroup, transformerBankAssetType, clickPoint));
                                                                                RowHandle transformerBankHandle = new RowHandle(token);

                                                                                // Create three transformers, one for each phase

                                                                                MapPoint transformerPointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointA, APhase));
                                                                                RowHandle transformerHandleA = new RowHandle(token);

                                                                                MapPoint transformerPointB = CreateOffsetMapPoint(clickPoint, 0, YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointB, BPhase));
                                                                                RowHandle transformerHandleB = new RowHandle(token);

                                                                                MapPoint transformerPointC = CreateOffsetMapPoint(clickPoint, XOffset, YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(transformerAssetGroup, transformerAssetType, transformerPointC, CPhase));
                                                                                RowHandle transformerHandleC = new RowHandle(token);

                                                                                // Create containment associations between the bank and the transformers
                                                                                AssociationDescription containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, transformerHandleA, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, transformerHandleB, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, transformerHandleC, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                // Find the high-side terminal for transformers
                                                                                TerminalConfiguration transformerTerminalConfiguration = transformerAssetType.GetTerminalConfiguration();
                                                                                IReadOnlyList <Terminal> terminals = transformerTerminalConfiguration.Terminals;
                                                                                Terminal highSideTerminal          = terminals.First(x => x.IsUpstreamTerminal == true);
                                                                                long highSideTerminalID            = highSideTerminal.ID;

                                                                                // Create three fuses, one for each phase

                                                                                MapPoint fusePointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, 2 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointA, APhase));
                                                                                RowHandle fuseHandleA = new RowHandle(token);

                                                                                MapPoint fusePointB = CreateOffsetMapPoint(clickPoint, 0, 2 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointB, BPhase));
                                                                                RowHandle fuseHandleB = new RowHandle(token);

                                                                                MapPoint fusePointC = CreateOffsetMapPoint(clickPoint, XOffset, 2 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(fuseAssetGroup, fuseAssetType, fusePointC, CPhase));
                                                                                RowHandle fuseHandleC = new RowHandle(token);

                                                                                // Create containment associations between the bank and the fuses
                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, fuseHandleA, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, fuseHandleB, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, fuseHandleC, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                // Connect the high-side transformer terminals to the fuses (connect the A-phase transformer to the A-phase fuse, and so on)
                                                                                AssociationDescription connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, transformerHandleA, highSideTerminalID, fuseHandleA);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, transformerHandleB, highSideTerminalID, fuseHandleB);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, transformerHandleC, highSideTerminalID, fuseHandleC);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                // Create three arresters, one for each phase

                                                                                MapPoint arresterPointA = CreateOffsetMapPoint(clickPoint, -1 * XOffset, 3 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointA, APhase));
                                                                                RowHandle arresterHandleA = new RowHandle(token);

                                                                                MapPoint arresterPointB = CreateOffsetMapPoint(clickPoint, 0, 3 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointB, BPhase));
                                                                                RowHandle arresterHandleB = new RowHandle(token);

                                                                                MapPoint arresterPointC = CreateOffsetMapPoint(clickPoint, XOffset, 3 * YOffset);
                                                                                token = createOperation.CreateEx(deviceFeatureClass, CreateDeviceAttributes(arresterAssetGroup, arresterAssetType, arresterPointC, CPhase));
                                                                                RowHandle arresterHandleC = new RowHandle(token);

                                                                                // Create containment associations between the bank and the arresters
                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, arresterHandleA, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, arresterHandleB, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                containmentAssociationDescription = new AssociationDescription(AssociationType.Containment, transformerBankHandle, arresterHandleC, false);
                                                                                createOperation.Create(containmentAssociationDescription);

                                                                                // Create connectivity associations between the fuses and the arresters (connect the A-phase fuse the A-phase arrester, and so on)
                                                                                connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, fuseHandleA, arresterHandleA);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, fuseHandleB, arresterHandleB);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                connectivityAssociationDescription = new AssociationDescription(AssociationType.JunctionJunctionConnectivity, fuseHandleC, arresterHandleC);
                                                                                createOperation.Create(connectivityAssociationDescription);

                                                                                // Execute the edit operation, which creates all of the rows and associations
                                                                                success = createOperation.Execute();

                                                                                if (!success)
                                                                                {
                                                                                    errorMessage = createOperation.ErrorMessage;
                                                                                }
                                                                            }
                        }
                    }
                }
            });

            if (!success)
            {
                MessageBox.Show(errorMessage, "Create Transformer Bank Tool");
            }
            return(success);
        }
        /// <summary>
        /// Fill the dictionary with Element Id, Properties
        /// </summary>
        /// <param name="Diagram">Network Diagram</param>
        /// <param name="theSources">List of network sources</param>
        /// <param name="SourceID">Source Id</param>
        /// <param name="IsEdge">Flag for edges treatement</param>
        /// <returns>Dictionary</returns>
        private static Dictionary <int, Dictionary <string, string> > FillSources(NetworkDiagram Diagram, IReadOnlyList <NetworkSource> theSources, int SourceID, bool IsEdge = false)
        {
            Dictionary <int, Dictionary <string, string> > AttributesByEID = new Dictionary <int, Dictionary <string, string> >();

            NetworkSource source = theSources.FirstOrDefault(a => a.ID == SourceID);

            if (source != null)
            {
                string[] attributeNames;
                if (IsEdge)
                {
                    attributeNames = new string[4] {
                        "Asset group", "Asset type", "Strand Group Color", "Strand Color"
                    }
                }
                ;
                else
                {
                    attributeNames = new string[2] {
                        "Asset group", "Asset type"
                    }
                };

                string  content        = Diagram.GetSourceAttributeValues(attributeNames: attributeNames, sourceName: source.Name, useCodedValueNames: true);
                JObject attributesList = JObject.Parse(content);
                JToken  elements;

                if (IsEdge)
                {
                    elements = attributesList["edges"];
                    if (!(elements == null || !elements.Any()))
                    {
                        foreach (var element in elements)
                        {
                            int id = (int)element["id"];
                            if (!AttributesByEID.TryGetValue(id, out Dictionary <string, string> IdProperties))
                            {
                                IdProperties = new Dictionary <string, string>();
                                AttributesByEID.Add(id, IdProperties);
                            }

                            if (element["attributes"] is JObject attributes)
                            {
                                IdProperties.Add("Asset group", attributes["Asset group"].ToString());
                                IdProperties.Add("Asset type", attributes["Asset type"].ToString());
                                IdProperties.Add("Strand Group Color", attributes["Strand Group Color"].ToString());
                                IdProperties.Add("Strand Color", attributes["Strand Color"].ToString());
                            }
                        }
                    }
                }
                else
                {
                    elements = attributesList["containers"];
                    if (!(elements == null || !elements.Any()))
                    {
                        foreach (var element in elements)
                        {
                            int id = (int)element["id"];
                            if (!AttributesByEID.TryGetValue(id, out Dictionary <string, string> IdProperties))
                            {
                                IdProperties = new Dictionary <string, string>();
                                AttributesByEID.Add(id, IdProperties);
                            }
                            if (element["attributes"] is JObject attributes)
                            {
                                IdProperties.Add("Asset group", attributes["Asset group"].ToString());
                                IdProperties.Add("Asset type", attributes["Asset type"].ToString());
                            }
                        }
                    }

                    elements = attributesList["junctions"];
                    if (!(elements == null || !elements.Any()))
                    {
                        foreach (var element in elements)
                        {
                            int id = (int)element["id"];
                            if (!AttributesByEID.TryGetValue(id, out Dictionary <string, string> IdProperties))
                            {
                                IdProperties = new Dictionary <string, string>();
                                AttributesByEID.Add(id, IdProperties);
                            }
                            if (element["attributes"] is JObject attributes)
                            {
                                IdProperties.Add("Asset group", attributes["Asset group"].ToString());
                                IdProperties.Add("Asset type", attributes["Asset type"].ToString());
                            }
                        }
                    }
                }
            }

            return(AttributesByEID);
        }