/// <summary> /// Get the active geodatabase fom the active map /// </summary> /// <returns>Geodatabase</returns> private static Geodatabase GetGeodatabaseFromActiveMap() { UtilityNetwork un = GetUtilityNetworkFromActiveMap(); if (un != null) { return(un.GetDatastore() as Geodatabase); } return(null); }
/// <summary> /// Retrieve the Utility Network from a map /// </summary> /// <param name="SearchMap">Map</param> /// <param name="SearchConnection">Connection to the database</param> /// <param name="UN">The utility Network found</param> /// <param name="SubnetLayers">Subnetwork layer list</param> /// <param name="NameFieldSubNet">Subnetwork field name</param> /// <returns>true if found</returns> internal static bool GetUNFromMap(Map SearchMap, string SearchConnection, ref UtilityNetwork UN, ref List <FeatureLayer> SubnetLayers, ref string NameFieldSubNet) { UtilityNetwork unSearch = GetUtilityNetworkFromActiveMap(SearchMap); if (unSearch == null) { return(false); } bool bFound = false; string unConnect = ((Geodatabase)unSearch.GetDatastore()).GetConnectionString(); bFound = (unConnect == SearchConnection); if (bFound) { if (UN == null) { UN = unSearch; } Table subnetTable = UN.GetSystemTable(SystemTableType.Subnetworks); IReadOnlyList <Field> listField; if (String.IsNullOrEmpty(NameFieldSubNet)) { listField = subnetTable.GetDefinition().GetFields(); Field FieldSubNetName = listField.FirstOrDefault(a => a.Name.ToLower() == "subnetworkname"); NameFieldSubNet = FieldSubNetName?.Name; } IReadOnlyList <Layer> listLayers = SearchMap.GetLayersAsFlattenedList(); foreach (Layer l in listLayers) { if (l is FeatureLayer fl && fl.ShapeType == esriGeometryType.esriGeometryPolyline) { listField = fl.GetTable().GetDefinition().GetFields(); Field field = listField.FirstOrDefault(a => a.Name.ToLower() == "subnetworkcontrollernames"); // only subnetwork table contains tiername if (field != null) { SubnetLayers.Add(fl); } } } } return(bFound && SubnetLayers.Count > 0); }
/// <summary> /// GenerateReport /// /// This routine takes a feature layer that references a feature class that participates in a utility network. /// It returns a set of data to display on the UI thread. /// /// /// </summary> public LoadTraceResults GenerateReport(Layer selectedLayer) { // Create a new results object. We use this class to pass back a set of data from the worker thread to the UI thread LoadTraceResults results = new LoadTraceResults(); // Initialize a number of geodatabase objects using (UtilityNetwork utilityNetwork = UtilityNetworkUtils.GetUtilityNetworkFromLayer(selectedLayer)) { if (utilityNetwork == null) { results.Message = "Please select a utility network layer."; results.Success = false; } else { using (Geodatabase utilityNetworkGeodatabase = utilityNetwork.GetDatastore() as Geodatabase) using (UtilityNetworkDefinition utilityNetworkDefinition = utilityNetwork.GetDefinition()) using (Geodatabase defaultGeodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(Project.Current.DefaultGeodatabasePath)))) using (TraceManager traceManager = utilityNetwork.GetTraceManager()) { // First check to make sure we have a feature service workspace. Utility Network functionality requires this. if (utilityNetworkGeodatabase.GetGeodatabaseType() != GeodatabaseType.Service) { results.Message = "A feature service workspace connection is required."; results.Success = false; return(results); } // Get a row from the starting points table in the default project workspace. This table is created the first time the user creates a starting point // If the table is missing or empty, a null row is returned using (Row startingPointRow = GetStartingPointRow(defaultGeodatabase, ref results)) { if (startingPointRow != null) { // Convert starting point row into network element Element startingPointElement = GetElementFromPointRow(startingPointRow, utilityNetwork, utilityNetworkDefinition); // Obtain a tracer object DownstreamTracer downstreamTracer = traceManager.GetTracer <DownstreamTracer>(); // Get the network attributes that we will use in our trace using (NetworkAttribute phasesNetworkAttribute = GetAttribute(utilityNetworkDefinition, PhaseAttributeNames)) using (NetworkAttribute loadNetworkAttribute = GetAttribute(utilityNetworkDefinition, LoadAttributeNames)) using (NetworkAttribute deviceStatusNetworkAttribute = GetAttribute(utilityNetworkDefinition, DeviceStatusAttributeNames)) { if (phasesNetworkAttribute == null || loadNetworkAttribute == null || deviceStatusNetworkAttribute == null) { results.Success = false; results.Message = "This add-in requires network attributes for phase, service load, and device status.\n"; return(results); } // Get the Tier for Medium Voltage Radial DomainNetwork electricDomainNetwork = utilityNetworkDefinition.GetDomainNetwork(ElectricDomainNetwork); Tier mediumVoltageTier = electricDomainNetwork.GetTier(MediumVoltageTier); // Set up the trace configuration TraceConfiguration traceConfiguration = new TraceConfiguration(); // Configure the trace to use the electric domain network traceConfiguration.DomainNetwork = electricDomainNetwork; // Take the default TraceConfiguration from the Tier for Traversability Traversability tierTraceTraversability = mediumVoltageTier.TraceConfiguration.Traversability; traceConfiguration.Traversability.FunctionBarriers = tierTraceTraversability.FunctionBarriers; traceConfiguration.IncludeBarriersWithResults = mediumVoltageTier.TraceConfiguration.IncludeBarriersWithResults; traceConfiguration.Traversability.Scope = tierTraceTraversability.Scope; ConditionalExpression baseCondition = tierTraceTraversability.Barriers as ConditionalExpression; // Create a condition to only return features that have the service point category ConditionalExpression servicePointCategoryCondition = new CategoryComparison(CategoryOperator.IsEqual, ServicePointCategory); // Create function to sum loads on service points where phase = A ConditionalExpression aPhaseCondition = new NetworkAttributeComparison(phasesNetworkAttribute, Operator.DoesNotIncludeTheValues, APhase); Add aPhaseLoad = new Add(loadNetworkAttribute, servicePointCategoryCondition); // Create function to sum loads on service points where phase = B ConditionalExpression bPhaseCondition = new NetworkAttributeComparison(phasesNetworkAttribute, Operator.DoesNotIncludeTheValues, BPhase); Add bPhaseLoad = new Add(loadNetworkAttribute, servicePointCategoryCondition); // Create function to sum loads on service points where phase = C ConditionalExpression cPhaseCondition = new NetworkAttributeComparison(phasesNetworkAttribute, Operator.DoesNotIncludeTheValues, CPhase); Add cPhaseLoad = new Add(loadNetworkAttribute, servicePointCategoryCondition); // Set the output condition to only return features that have the service point category traceConfiguration.OutputCondition = servicePointCategoryCondition; // Create starting point list and trace argument object List <Element> startingPointList = new List <Element>() { startingPointElement }; TraceArgument traceArgument = new TraceArgument(startingPointList); traceArgument.Configuration = traceConfiguration; // Trace on the A phase traceConfiguration.Traversability.Barriers = new Or(baseCondition, aPhaseCondition); traceConfiguration.Functions = new List <Function>() { aPhaseLoad }; traceArgument.Configuration = traceConfiguration; try { IReadOnlyList <Result> resultsA = downstreamTracer.Trace(traceArgument); ElementResult elementResult = resultsA.OfType <ElementResult>().First(); results.NumberServicePointsA = elementResult.Elements.Count; FunctionOutputResult functionOutputResult = resultsA.OfType <FunctionOutputResult>().First(); results.TotalLoadA = (double)functionOutputResult.FunctionOutputs.First().Value; } catch (ArcGIS.Core.Data.GeodatabaseUtilityNetworkException e) { //No A phase connectivity to source if (!e.Message.Equals("No subnetwork source was discovered.")) { results.Success = false; results.Message += e.Message; } } // Trace on the B phase traceConfiguration.Traversability.Barriers = new Or(baseCondition, bPhaseCondition); traceConfiguration.Functions = new List <Function>() { bPhaseLoad }; traceArgument.Configuration = traceConfiguration; try { IReadOnlyList <Result> resultsB = downstreamTracer.Trace(traceArgument); ElementResult elementResult = resultsB.OfType <ElementResult>().First(); results.NumberServicePointsB = elementResult.Elements.Count; FunctionOutputResult functionOutputResult = resultsB.OfType <FunctionOutputResult>().First(); results.TotalLoadB = (double)functionOutputResult.FunctionOutputs.First().Value; } catch (ArcGIS.Core.Data.GeodatabaseUtilityNetworkException e) { // No B phase connectivity to source if (!e.Message.Equals("No subnetwork source was discovered.")) { results.Success = false; results.Message += e.Message; } } // Trace on the C phase traceConfiguration.Traversability.Barriers = new Or(baseCondition, cPhaseCondition); traceConfiguration.Functions = new List <Function>() { cPhaseLoad }; traceArgument.Configuration = traceConfiguration; try { IReadOnlyList <Result> resultsC = downstreamTracer.Trace(traceArgument); ElementResult elementResult = resultsC.OfType <ElementResult>().First(); results.NumberServicePointsC = elementResult.Elements.Count; FunctionOutputResult functionOutputResult = resultsC.OfType <FunctionOutputResult>().First(); results.TotalLoadC = (double)functionOutputResult.FunctionOutputs.First().Value; } catch (ArcGIS.Core.Data.GeodatabaseUtilityNetworkException e) { // No C phase connectivity to source if (!e.Message.Equals("No subnetwork source was discovered.")) { results.Success = false; results.Message += e.Message; } } } // append success message to the output string results.Message += "Trace successful."; results.Success = true; } } } } } return(results); }
private string ValidateChangedFeatures(Layer layer) { StringBuilder resultString = new StringBuilder(); // Get utility network and geodatabase using (UtilityNetwork utilityNetwork = UtilityNetworkUtils.GetUtilityNetworkFromLayer(layer)) using (Geodatabase geodatabase = utilityNetwork.GetDatastore() as Geodatabase) { // Determine what to validate // File geodatabase - validate everything, synchronously // Default version - validate everything, asynchronously // Branch version - validate changes only, synchronously bool shouldValidateEverything; bool runAsync; if (!geodatabase.IsVersioningSupported()) { shouldValidateEverything = true; runAsync = false; } else { using (VersionManager versionManager = geodatabase.GetVersionManager()) using (Version currentVersion = versionManager.GetCurrentVersion()) { if (IsDefaultVersion(currentVersion)) { shouldValidateEverything = true; runAsync = true; } else { shouldValidateEverything = false; runAsync = false; } } } // If we validating everything, get an envelope from the dirty areas table EnvelopeBuilderEx envelopeBuilder = new EnvelopeBuilderEx(layer.GetSpatialReference()); if (shouldValidateEverything) { using (Table dirtyAreaTable = utilityNetwork.GetSystemTable(SystemTableType.DirtyAreas)) using (RowCursor rowCursor = dirtyAreaTable.Search()) { envelopeBuilder = GetExtentFromRowCursor(envelopeBuilder, rowCursor); } } // else get an envelope using version differences else { using (VersionManager versionManager = geodatabase.GetVersionManager()) using (Version currentVersion = versionManager.GetCurrentVersion()) using (Version defaultVersion = currentVersion.GetParent()) using (Geodatabase defaultGeodatabase = defaultVersion.Connect()) using (UtilityNetwork defaultUtilityNetwork = defaultGeodatabase.OpenDataset <UtilityNetwork>(utilityNetwork.GetName())) using (Table dirtyAreaTable = utilityNetwork.GetSystemTable(SystemTableType.DirtyAreas)) using (Table defaultDirtyAreaTable = defaultUtilityNetwork.GetSystemTable(SystemTableType.DirtyAreas)) using (DifferenceCursor inserts = dirtyAreaTable.Differences(defaultDirtyAreaTable, DifferenceType.Insert)) { envelopeBuilder = GetExtentFromDifferenceCursor(envelopeBuilder, inserts); } } // Run validate topology on our envelope Envelope extent = envelopeBuilder.ToGeometry(); ValidationResult result = utilityNetwork.ValidateNetworkTopologyInEditOperation(extent, runAsync ? ServiceSynchronizationType.Asynchronous : ServiceSynchronizationType.Synchronous); if (result.HasErrors) { resultString.AppendLine("Errors found."); } else { resultString.AppendLine("No errors found."); } } return(resultString.ToString()); }