Dictionary <string, bool> GetFeatureClassExistsMap(ProSymbolUtilities.SupportedStandardsType standard, Geodatabase gdb = null) { EGDBPrefixName = string.Empty; _egdbConnectionString = string.Empty; if (gdb != null) { GeodatabaseType gdbType = gdb.GetGeodatabaseType(); if (gdbType == GeodatabaseType.RemoteDatabase) { // if an SDE/EGDB, then feature class name format will differ: // Database + User + Feature Class Name DatabaseConnectionProperties dbcps = gdb.GetConnector() as DatabaseConnectionProperties; if (dbcps != null) { EGDBPrefixName = dbcps.Database + "." + dbcps.User + "."; // Also save this connection string to identify this EGDB later _egdbConnectionString = ((Datastore)gdb).GetConnectionString(); } } } Dictionary <string, bool> featureClassExists = new Dictionary <string, bool>(); List <SymbolSetMapping> symbolSetMapping = null; switch (standard) { case ProSymbolUtilities.SupportedStandardsType.app6b: symbolSetMapping = _symbolSetMappingAPP6B; break; case ProSymbolUtilities.SupportedStandardsType.app6d: symbolSetMapping = _symbolSetMappingAPP6D; break; case ProSymbolUtilities.SupportedStandardsType.mil2525b: symbolSetMapping = _symbolSetMapping2525B; break; case ProSymbolUtilities.SupportedStandardsType.mil2525c: symbolSetMapping = _symbolSetMapping2525C; break; default: symbolSetMapping = _symbolSetMapping2525D; break; } foreach (SymbolSetMapping mapping in symbolSetMapping) { string featureClassName = EGDBPrefixName + mapping.FeatureClassName; if (!featureClassExists.ContainsKey(featureClassName)) { featureClassExists.Add(featureClassName, false); } } return(featureClassExists); }
/// <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); }
Dictionary <string, bool> GetFeatureClassExistsMap(ProSymbolUtilities.SupportedStandardsType standard, Geodatabase gdb = null) { string prefixName = string.Empty; _egdbConnectionString = string.Empty; if (gdb != null) { GeodatabaseType gdbType = gdb.GetGeodatabaseType(); if (gdbType == GeodatabaseType.RemoteDatabase) { // if an SDE/EGDB, then feature class name format will differ: // Database + User + Feature Class Name DatabaseConnectionProperties dbcps = gdb.GetConnector() as DatabaseConnectionProperties; if (dbcps != null) { prefixName = dbcps.Database + "." + dbcps.User + "."; // Also save this connection string to identify this EGDB later _egdbConnectionString = ((Datastore)gdb).GetConnectionString(); } } } Dictionary <string, bool> featureClassExists = new Dictionary <string, bool>(); if (standard == ProSymbolUtilities.SupportedStandardsType.mil2525c_b2) { // 2525c_b2 featureClassExists.Add(prefixName + "Activities", false); featureClassExists.Add(prefixName + "Air", false); featureClassExists.Add(prefixName + "ControlMeasuresAreas", false); featureClassExists.Add(prefixName + "ControlMeasuresLines", false); featureClassExists.Add(prefixName + "ControlMeasuresPoints", false); featureClassExists.Add(prefixName + "Installations", false); featureClassExists.Add(prefixName + "LandEquipment", false); featureClassExists.Add(prefixName + "METOCAreas", false); featureClassExists.Add(prefixName + "METOCLines", false); featureClassExists.Add(prefixName + "METOCPoints", false); featureClassExists.Add(prefixName + "SeaSubsurface", false); featureClassExists.Add(prefixName + "SeaSurface", false); featureClassExists.Add(prefixName + "SIGINT", false); featureClassExists.Add(prefixName + "Space", false); featureClassExists.Add(prefixName + "Units", false); } else { // 2525d featureClassExists.Add(prefixName + "Activities", false); featureClassExists.Add(prefixName + "Air", false); featureClassExists.Add(prefixName + "AirMissile", false); featureClassExists.Add(prefixName + "Civilian", false); featureClassExists.Add(prefixName + "ControlMeasuresAreas", false); featureClassExists.Add(prefixName + "ControlMeasuresLines", false); featureClassExists.Add(prefixName + "ControlMeasuresPoints", false); featureClassExists.Add(prefixName + "Cyberspace", false); featureClassExists.Add(prefixName + "Installations", false); featureClassExists.Add(prefixName + "LandEquipment", false); featureClassExists.Add(prefixName + "METOCAreasAtmospheric", false); featureClassExists.Add(prefixName + "METOCAreasOceanographic", false); featureClassExists.Add(prefixName + "METOCLinesAtmospheric", false); featureClassExists.Add(prefixName + "METOCLinesOceanographic", false); featureClassExists.Add(prefixName + "METOCPointsAtmospheric", false); featureClassExists.Add(prefixName + "METOCPointsOceanographic", false); featureClassExists.Add(prefixName + "MineWarfare", false); featureClassExists.Add(prefixName + "SeaSubsurface", false); featureClassExists.Add(prefixName + "SeaSurface", false); featureClassExists.Add(prefixName + "SIGINT", false); featureClassExists.Add(prefixName + "Space", false); featureClassExists.Add(prefixName + "SpaceMissile", false); featureClassExists.Add(prefixName + "Units", false); } return(featureClassExists); }
// TODO: we may be able to deprecate this method (GDBContainsSchema) and use the method above (GDBContainsMilitaryOverlay) public async Task <bool> GDBContainsSchema(GDBProjectItem gdbProjectItem, ProSymbolUtilities.SupportedStandardsType standard) { bool isSchemaComplete = await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run <bool>(() => { if (gdbProjectItem == null) { return(false); } using (Datastore datastore = gdbProjectItem.GetDatastore()) { // Unsupported datastores (non File GDB and non Enterprise GDB) will be of type UnknownDatastore if (datastore is UnknownDatastore) { return(false); } Geodatabase geodatabase = datastore as Geodatabase; if (geodatabase == null) { return(false); } // Set up Fields to check List <string> fieldsToCheck = new List <string>(); if (ProSymbolUtilities.IsLegacyStandard(standard)) { fieldsToCheck.Add("extendedfunctioncode"); } else { // 2525d / app6d fieldsToCheck.Add("symbolset"); fieldsToCheck.Add("symbolentity"); } // Reset schema data model exists to false for each feature class Dictionary <string, bool> featureClassExists = GetFeatureClassExistsMap(standard, geodatabase); IReadOnlyList <FeatureClassDefinition> featureClassDefinitions = geodatabase.GetDefinitions <FeatureClassDefinition>(); bool stopLooking = false; foreach (FeatureClassDefinition featureClassDefinition in featureClassDefinitions) { // Stop looking after the first feature class not found if (stopLooking) { return(false); } string featureClassName = featureClassDefinition.GetName(); if (featureClassExists.ContainsKey(featureClassName)) { // Feature Class Exists. Check for fields bool fieldsExist = true; // Don't do this for remote databases (too slow) if (geodatabase.GetGeodatabaseType() != GeodatabaseType.RemoteDatabase) { foreach (string fieldName in fieldsToCheck) { IEnumerable <Field> foundFields = featureClassDefinition.GetFields().Where(x => x.Name == fieldName); if (foundFields.Count() < 1) { fieldsExist = false; return(false); } } } featureClassExists[featureClassName] = fieldsExist; } else { // Key doesn't exist, so ignore } } foreach (KeyValuePair <string, bool> pair in featureClassExists) { if (pair.Value == false) { return(false); } } // If here, schema is complete // Save geodatabase path to use as the selected database _databaseName = gdbProjectItem.Path; _schemaExists = true; _standard = standard; return(true); } }); return(isSchemaComplete); }