Return Value
An ArcGIS.Core.Geometry.Envelope representing the maximum extent of the union of all the feature classes that participate in the Topology.
Exception | Description |
---|---|
ArcGIS.Core.Data.Exceptions.GeodatabaseException | A geodatabase-related exception has occurred. |
public void ValidateTopology() { using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb")))) using (Topology topology = geodatabase.OpenDataset<Topology>("Backcountry_Topology")) { // If the topology currently does not have dirty areas, calling Validate() returns an empty envelope. ValidationResult result = topology.Validate(new ValidationDescription(topology.GetExtent())); Console.WriteLine($"'AffectedArea' after validating a topology that has not been edited => {result.AffectedArea.ToJson()}"); // Now create a feature that purposely violates the "PointProperlyInsideArea" topology rule. This action will // create dirty areas. Feature newFeature = null; try { // Fetch the feature in the Campsites feature class whose objectID is 2. Then create a new geometry slightly // altered from this and use it to create a new feature. using (Feature featureViaCampsites2 = GetFeature(geodatabase, "Campsites", 2)) { Geometry currentGeometry = featureViaCampsites2.GetShape(); Geometry newGeometry = GeometryEngine.Instance.Move(currentGeometry, (currentGeometry.Extent.XMax / 8), (currentGeometry.Extent.YMax / 8)); using (FeatureClass campsitesFeatureClass = featureViaCampsites2.GetTable()) using (FeatureClassDefinition definition = campsitesFeatureClass.GetDefinition()) using (RowBuffer rowBuffer = campsitesFeatureClass.CreateRowBuffer()) { rowBuffer[definition.GetShapeField()] = newGeometry; geodatabase.ApplyEdits(() => { newFeature = campsitesFeatureClass.CreateRow(rowBuffer); }); } } // After creating a new feature in the 'Campsites' participating feature class, the topology's state should be // "Unanalyzed" because it has not been validated. Console.WriteLine($"The topology state after an edit has been applied => {topology.GetState()}"); // Now validate the topology. The result envelope corresponds to the dirty areas. result = topology.Validate(new ValidationDescription(topology.GetExtent())); Console.WriteLine($"'AffectedArea' after validating a topology that has just been edited => {result.AffectedArea.ToJson()}"); // After Validate(), the topology's state should be "AnalyzedWithErrors" because the topology currently has errors. Console.WriteLine($"The topology state after validate topology => {topology.GetState()}"); // If there are no dirty areas, the result envelope should be empty. result = topology.Validate(new ValidationDescription(topology.GetExtent())); Console.WriteLine($"'AffectedArea' after validating a topology that has just been validated => {result.AffectedArea.ToJson()}"); } finally { if (newFeature != null) { geodatabase.ApplyEdits(() => { newFeature.Delete(); }); newFeature.Dispose(); } } // Validate again after deleting the newly-created feature. topology.Validate(new ValidationDescription(topology.GetExtent())); } } private Feature GetFeature(Geodatabase geodatabase, string featureClassName, long objectID) { using (FeatureClass featureClass = geodatabase.OpenDataset<FeatureClass>(featureClassName)) { QueryFilter queryFilter = new QueryFilter() { ObjectIDs = new List<long>() { objectID } }; using (RowCursor cursor = featureClass.Search(queryFilter)) { System.Diagnostics.Debug.Assert(cursor.MoveNext()); return (Feature)cursor.Current; } } }
// Get all the errors due to features violating the "PointProperlyInsideArea" topology rule. using (TopologyDefinition topologyDefinition = topology.GetDefinition()) { TopologyRule pointProperlyInsideAreaRule = topologyDefinition.GetRules().First(rule => rule.RuleType == TopologyRuleType.PointProperlyInsideArea); ErrorDescription errorDescription = new ErrorDescription(topology.GetExtent()) { TopologyRule = pointProperlyInsideAreaRule }; IReadOnlyList<TopologyError> errorsDueToViolatingPointProperlyInsideAreaRule = topology.GetErrors(errorDescription); Console.WriteLine($"There are {errorsDueToViolatingPointProperlyInsideAreaRule.Count} feature violating the 'PointProperlyInsideArea' topology rule."); // Mark all errors from features violating the 'PointProperlyInsideArea' topology rule as exceptions. foreach (TopologyError error in errorsDueToViolatingPointProperlyInsideAreaRule) { topology.MarkAsException(error); } // Now verify all the errors from features violating the 'PointProperlyInsideArea' topology rule have indeed been // marked as exceptions. // // By default, ErrorDescription is initialized to ErrorType.ErrorAndException. Here we want ErrorType.ErrorOnly. errorDescription = new ErrorDescription(topology.GetExtent()) { ErrorType = ErrorType.ErrorOnly, TopologyRule = pointProperlyInsideAreaRule }; IReadOnlyList<TopologyError> errorsAfterMarkedAsExceptions = topology.GetErrors(errorDescription); Console.WriteLine($"There are {errorsAfterMarkedAsExceptions.Count} feature violating the 'PointProperlyInsideArea' topology rule after all the errors have been marked as exceptions."); // Finally, reset all the exceptions as errors by unmarking them as exceptions. foreach (TopologyError error in errorsDueToViolatingPointProperlyInsideAreaRule) { topology.UnmarkAsException(error); } IReadOnlyList<TopologyError> errorsAfterUnmarkedAsExceptions = topology.GetErrors(errorDescription); Console.WriteLine($"There are {errorsAfterUnmarkedAsExceptions.Count} feature violating the 'PointProperlyInsideArea' topology rule after all the exceptions have been reset as errors."); }
public void FindClosestElement() { using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb")))) using (Topology topology = geodatabase.OpenDataset<Topology>("Backcountry_Topology")) { // Build a topology graph using the extent of the topology dataset. topology.BuildGraph(topology.GetExtent(), (topologyGraph) => { MapPoint queryPointViaCampsites12 = null; using (Feature campsites12 = GetFeature(geodatabase, "Campsites", 12)) { queryPointViaCampsites12 = campsites12.GetShape() as MapPoint; } double searchRadius = 1.0; TopologyElement topologyElementViaCampsites12 = topologyGraph.FindClosestElement<TopologyElement>( queryPointViaCampsites12, searchRadius); System.Diagnostics.Debug.Assert( topologyElementViaCampsites12 != null, "There should be a topology element corresponding to 'queryPointViaCampsites12' within the 'searchRadius' units."); IReadOnlyList<FeatureInfo> parentFeatures = topologyElementViaCampsites12.GetParentFeatures(); Console.WriteLine("The parent features that spawn 'topologyElementViaCampsites12' are:"); foreach (FeatureInfo parentFeature in parentFeatures) { Console.WriteLine($"\t{parentFeature.FeatureClassName}; OID: {parentFeature.ObjectID}"); } TopologyNode topologyNodeViaCampsites12 = topologyGraph.FindClosestElement<TopologyNode>(queryPointViaCampsites12, searchRadius); if (topologyNodeViaCampsites12 != null) { // There exists a TopologyNode nearest to the query point within searchRadius units. } TopologyEdge topologyEdgeViaCampsites12 = topologyGraph.FindClosestElement<TopologyEdge>(queryPointViaCampsites12, searchRadius); if (topologyEdgeViaCampsites12 != null) { // There exists a TopologyEdge nearest to the query point within searchRadius units. } }); } }
Target Platforms: Windows 11, Windows 10