軟件環境:arcengine9.3 +vs2008
這兩天弄個拓撲檢查的東西,看了一下Esri的ArcEngine官方help,如下:本來想翻譯完的,但是由於時間的問題,只翻譯了前面的幾段。大家勿噴
Development licensing | Deployment licensing |
---|---|
ArcEditor | ArcEditor |
ArcInfo | ArcInfo |
Engine Developer Kit | Engine Runtime: Geodatabase Update |
- ESRI.ArcGIS.DataSourcesGDB
- ESRI.ArcGIS.Geodatabase
- ESRI.ArcGIS.Geometry
- ESRI.ArcGIS.esriSystem
- System.Runtime.InteropServices
In this topic
- Creating a topology in the geodatabase
- Initial topology creation
- Topology name
- X,Y–cluster tolerance
- Z–cluster tolerance
- Maximum generated error count and configuration keywords
- Add feature classes to a topology
- Add rules to a topology
- Validate the topology
- Complete Code Example
Each topology has one associated topology graph. The topology graph is a planar representation of the geometries in the feature classes participating in a geodatabase topology. If accessing the topology graph directly to work with topology primitives such as edges and nodes is required, see the article How to access the topology graph.
When new features are created, edited, or deleted, the topology is responsible for creating or modifying a dirty area that will encompass the envelope of the feature. A dirty area is a special type of feature where the state of the topology is unknown. Features that are covered by dirty areas can still be edited and queried, but their topological relationships cannot be guaranteed to be correct. A dirty area must be validated to discover the topology of its underlying features and guarantee their correctness.
創建一個拓撲在geodatabase
可以創建拓撲結構在使用ITopologyContainer geodatabase.CreateTopology和ITopologyContainer2.CreateTopologyEx方法,它們都有一個ITopology返回
類型。一旦創建拓撲,ITopology.AddClass和ITopologyRuleContainer.AddRule方法可以用來添加類和拓撲規則.。
每個拓撲有一個相關聯的拓撲圖形。拓撲圖形是參與拓撲的要素類中的平面幾何圖形表示的。如果訪問拓撲圖形直接處理拓撲基元如必需的邊緣和節
點,請參閱文章How to access the topology graph.
當新的特性創建、編輯或刪除,拓撲是負責創建或修改一個骯髒的區域將包括信封的特性
The following screen shot shows an example of how dirty areas and topology errors work in a topology:
Each topology has one inherent rule—esriTRTFeatureLargerThanClusterTolerance—to identify features that are less than the defined cluster tolerance for the topology.
to the tolerance of the feature dataset, which is generally 0.001 meters, or the equivalent
in the units of the spatial reference. Values that are smaller than the default cluster tolerance or larger than the ITopologyContainer.MaximumClusterTolerance property are not permitted.
[C#]
// featureDataset is an IFeatureDataset where the topology will be located // specifyZClusterTolerance is a System.Boolean whether a ZClusterTolerance has been specified // topologyName is a String with the topology's name // Cast the feature dataset to the ITopologyContainer2 interface to create a new topology. ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset; ITopology topology = null; if (specifyZClusterTolerance) { topology = topologyContainer.CreateTopologyEx(topologyName, topologyContainer.DefaultClusterTolerance, topologyContainer.DefaultZClusterTolerance, - 1, ""); } else { topology = topologyContainer.CreateTopology(topologyName, topologyContainer.DefaultClusterTolerance, - 1, ""); }
[VB.NET]
' featureDataset is an IFeatureDataset where the topology will be located ' specifyZClusterTolerance is a System.Boolean whether a ZClusterTolerance has been specified ' topologyName is a String with the topology's name ' Cast the feature dataset to the ITopologyContainer2 interface to create a new topology. Dim topologyContainer As ITopologyContainer2 = CType(featureDataset, ITopologyContainer2) Dim topology As ITopology = Nothing If specifyZClusterTolerance Then topology = topologyContainer.CreateTopologyEx(topologyName, topologyContainer.DefaultClusterTolerance, topologyContainer.DefaultZClusterTolerance, -1, "") Else topology = topologyContainer.CreateTopology(topologyName, topologyContainer.DefaultClusterTolerance, -1, "") End If
[C#]
// ITopology.AddClass(IClass class, double weight, int xyRank, int zRnk, Boolean EventNotificationOnValidate) topology.AddClass(featureClass, weight, xyRank, zRank, false);
[VB.NET]
' ITopology.AddClass(IClass class, double weight, int xyrank, int zrank, Boolean EventNotificationOnValidate) topology.AddClass(featureClass, weight, xyRank, zRank, False)
[C#]
public void AddRuleToTopology(ITopology topology, esriTopologyRuleType ruleType, String ruleName, IFeatureClass featureClass) { // Create a new topology rule. ITopologyRule topologyRule = new TopologyRuleClass(); topologyRule.TopologyRuleType = ruleType; topologyRule.Name = ruleName; topologyRule.OriginClassID = featureClass.FeatureClassID; topologyRule.AllOriginSubtypes = true; // Cast the topology to the ITopologyRuleContainer interface and add the rule. ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology; if (topologyRuleContainer.get_CanAddRule(topologyRule)) { topologyRuleContainer.AddRule(topologyRule); } else { throw new ArgumentException("Could not add specified rule to the topology."); } }
[VB.NET]
Public Sub AddRuleToTopology(ByVal topology As ITopology, ByVal ruleType As esriTopologyRuleType, ByVal ruleName As String, ByVal featureClass As IFeatureClass) ' Create a new topology rule. Dim topologyRule As ITopologyRule = New TopologyRuleClass() topologyRule.TopologyRuleType = ruleType topologyRule.Name = ruleName topologyRule.OriginClassID = featureClass.FeatureClassID topologyRule.AllOriginSubtypes = True ' Cast the topology to the ITopologyRuleContainer interface and add the rule. Dim topologyRuleContainer As ITopologyRuleContainer = CType(topology, ITopologyRuleContainer) If topologyRuleContainer.CanAddRule(topologyRule) Then topologyRuleContainer.AddRule(topologyRule) Else Throw New ArgumentException("Could not add specified rule to the topology.") End If End Sub
[C#]
public void AddRuleToTopology(ITopology topology, esriTopologyRuleType ruleType, String ruleName, IFeatureClass originClass, int originSubtype, IFeatureClass destinationClass, int destinationSubtype) { // Create a new topology rule. ITopologyRule topologyRule = new TopologyRuleClass(); topologyRule.TopologyRuleType = ruleType; topologyRule.Name = ruleName; topologyRule.OriginClassID = originClass.FeatureClassID; topologyRule.AllOriginSubtypes = false; topologyRule.OriginSubtype = originSubtype; topologyRule.DestinationClassID = destinationClass.FeatureClassID; topologyRule.AllDestinationSubtypes = false; topologyRule.DestinationSubtype = destinationSubtype; // Cast the topology to the ITopologyRuleContainer interface and add the rule. ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology; if (topologyRuleContainer.get_CanAddRule(topologyRule)) { topologyRuleContainer.AddRule(topologyRule); } else { throw new ArgumentException("Could not add specified rule to the topology."); } }
[VB.NET]
Public Sub AddRuleToTopology(ByVal topology As ITopology, ByVal ruleType As esriTopologyRuleType, ByVal ruleName As String, ByVal originClass As IFeatureClass, ByVal originSubtype As Integer, ByVal destinationClass As IFeatureClass, ByVal destinationSubtype As Integer) ' Create a new topology rule. Dim topologyRule As ITopologyRule = New TopologyRuleClass() topologyRule.TopologyRuleType = ruleType topologyRule.Name = ruleName topologyRule.OriginClassID = originClass.FeatureClassID topologyRule.AllOriginSubtypes = False topologyRule.OriginSubtype = originSubtype topologyRule.DestinationClassID = destinationClass.FeatureClassID topologyRule.AllDestinationSubtypes = False topologyRule.DestinationSubtype = destinationSubtype ' Cast the topology to the ITopologyRuleContainer interface and add the rule. Dim topologyRuleContainer As ITopologyRuleContainer = CType(topology, ITopologyRuleContainer) If topologyRuleContainer.CanAddRule(topologyRule) Then topologyRuleContainer.AddRule(topologyRule) Else Throw New ArgumentException("Could not add specified rule to the topology.") End If End Sub
[C#]
public void ValidateTopology(ITopology topology, IEnvelope envelope) { // Get the dirty area within the provided envelope. IPolygon locationPolygon = new PolygonClass(); ISegmentCollection segmentCollection = (ISegmentCollection)locationPolygon; segmentCollection.SetRectangle(envelope); IPolygon polygon = topology.get_DirtyArea(locationPolygon); // If a dirty area exists, validate the topology. if (!polygon.IsEmpty) { // Define the area to validate and validate the topology. IEnvelope areaToValidate = polygon.Envelope; IEnvelope areaValidated = topology.ValidateTopology(areaToValidate); } }
[VB.NET]
Public Sub ValidateTopology(ByVal topology As ITopology, ByVal envelope As IEnvelope) ' Get the dirty area within the provided envelope. Dim locationPolygon As IPolygon = New PolygonClass() Dim segmentCollection As ISegmentCollection = CType(locationPolygon, ISegmentCollection) segmentCollection.SetRectangle(envelope) Dim polygon As IPolygon = topology.DirtyArea(locationPolygon) ' If a dirty area exists, validate the topology. If (Not polygon.IsEmpty) Then ' Define the area to validate and validate the topology. Dim areaToValidate As IEnvelope = polygon.Envelope Dim areaValidated As IEnvelope = topology.ValidateTopology(areaToValidate) End If End Sub
[C#]
public void CreateTopology() { // Open the workspace and the required datasets. IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass(); IWorkspace workspace = workspaceFactory.OpenFromFile(@ "C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb", 0); IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace; IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset("Landbase"); IFeatureClass blocksFC = featureWorkspace.OpenFeatureClass("Blocks"); IFeatureClass parcelsFC = featureWorkspace.OpenFeatureClass("Parcels"); // Attempt to acquire an exclusive schema lock on the feature dataset. ISchemaLock schemaLock = (ISchemaLock)featureDataset; try { schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); // Create the topology. ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset; ITopology topology = topologyContainer.CreateTopology("Landbase_Topology", topologyContainer.DefaultClusterTolerance, - 1, ""); // Add feature classes and rules to the topology. topology.AddClass(blocksFC, 5, 1, 1, false); topology.AddClass(parcelsFC, 5, 1, 1, false); AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, "No Block Overlap", blocksFC); AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaCoveredByAreaClass, "ResParcels Covered by ResBlocks", parcelsFC, 1, blocksFC, 1); // Get an envelope with the topology's extents and validate the topology. IGeoDataset geoDataset = (IGeoDataset)topology; IEnvelope envelope = geoDataset.Extent; ValidateTopology(topology, envelope); } catch (COMException comExc) { throw new Exception(String.Format( "Error creating topology: {0} Message: {1}", comExc.ErrorCode, comExc.Message), comExc); } finally { schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock); } }
[VB.NET]
Public Sub CreateTopology() ' Open the workspace and the required datasets. Dim workspaceFactory As IWorkspaceFactory = New FileGDBWorkspaceFactoryClass() Dim workspace As IWorkspace = workspaceFactory.OpenFromFile("C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb", 0) Dim featureWorkspace As IFeatureWorkspace = CType(workspace, IFeatureWorkspace) Dim featureDataset As IFeatureDataset = featureWorkspace.OpenFeatureDataset("Landbase") Dim blocksFC As IFeatureClass = featureWorkspace.OpenFeatureClass("Blocks") Dim parcelsFC As IFeatureClass = featureWorkspace.OpenFeatureClass("Parcels") ' Attempt to acquire an exclusive schema lock on the feature dataset. Dim schemaLock As ISchemaLock = CType(featureDataset, ISchemaLock) Try schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock) ' Create the topology. Dim topologyContainer As ITopologyContainer2 = CType(featureDataset, ITopologyContainer2) Dim topology As ITopology = topologyContainer.CreateTopology("Landbase_Topology", topologyContainer.DefaultClusterTolerance, -1, "") ' Add feature classes and rules to the topology. topology.AddClass(blocksFC, 5, 1, 1, False) topology.AddClass(parcelsFC, 5, 1, 1, False) AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, "No Block Overlap", blocksFC) AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaCoveredByAreaClass, "ResParcels Covered by ResBlocks", parcelsFC, 1, blocksFC, 1) ' Get an envelope with the topology's extents and validate the topology. Dim geoDataset As IGeoDataset = CType(topology, IGeoDataset) Dim envelope As IEnvelope = geoDataset.Extent ValidateTopology(topology, envelope) Catch comExc As COMException Throw New Exception(String.Format("Error creating topology: {0} Message: {1}", comExc.ErrorCode, comExc.Message), comExc) Finally schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock) End Try End Sub
See Also:
How to access the topology graphHow to check for topology error features in a geodatabase topology
How to listen to the OnValidate event for a geodatabase topology