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. |
{
static void ValidateTopology()
{
using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb"))))
using (ArcGIS.Core.Data.Topology.Topology topology = geodatabase.OpenDataset<ArcGIS.Core.Data.Topology.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()));
}
}
}
{
static void MarkAndUnmarkAsErrors(ArcGIS.Core.Data.Topology.Topology topology)
{
// 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.");
}
}
}
{
static void FindClosestElement()
{
using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(@"C:\TestData\GrandTeton.gdb"))))
using (ArcGIS.Core.Data.Topology.Topology topology = geodatabase.OpenDataset<ArcGIS.Core.Data.Topology.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);
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 Home, Pro, Enterprise (64 bit)