3 空间拓扑运算
之前的文章:基于C#的ArcEngine二次开发22:要素拓扑检查
3.1 概述
拓扑关系是指描述地理对象的空间位置关系
要点说明:
- 拓扑要求在同一要素集下的要素类之间的关系的集合,故要参与拓扑运算的所有要素类,必须在同一要素集内【即必须具有相同的空间参考】
- 每个要素集只能参与一个拓扑,但是一个拓扑可以定义多个规则
- Coverage和GeoDatabase可以建立拓扑,但是shape格式数据无法建立拓扑
3.2 在GeoDatabase中进行拓扑检查
打开FeatureDataset,将其强转为ITopologyContainer,根据拓扑的名称打开ITopology
// For example, featureDatasetName = "Landbase." // topologyName = "Landbase_topology". public ITopology OpenTopologyFromFeatureWorkspace(IFeatureWorkspace featureWorkspace, String featureDatasetName, String topologyName) { // Open the feature dataset and cast it to ITopologyContainer. IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset (featureDatasetName); ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset; // Open the topology and return it. ITopology topology = topologyContainer.get_TopologyByName(topologyName); return topology; }
ITopology.State用来检查在一个拓扑中存在的错误,他将返回一个esriTopologyState.枚举变量,如果拓扑被验证有效且找到错误,将返回esriTSAnalyzedWithErrors
可以使用ITopologyRuleContainer访问拓扑规则,由Topology类实现。ITopologyRuleContainer有几种方法可用于基于要素类的ID或要素类的特定子类型查看拓扑的规则。下面为查询一个Topology中包含的所有拓扑规则的示例:
public void DisplayTypesForEachRule(ITopology topology) { // Cast the topology to ITopologyRuleContainer and get the rule enumerator. ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology; IEnumRule enumRule = topologyRuleContainer.Rules; // Iterate through each rule. enumRule.Reset(); IRule rule = null; while ((rule = enumRule.Next()) != null) { // Cast to ITopology and display the rule type. ITopologyRule topologyRule = (ITopologyRule)rule; Console.WriteLine("Rule type: {0}", topologyRule.TopologyRuleType); } }
可以将Topology转换为IErrorFeatureContainer接口,该接口具有可用于返回与拓扑关联的错误功能的属性。给定拓扑错误功能,可以通过ITopologyErrorFeature 接口检查以下属性:
违反规则
错误中涉及的要素类
几何误差
错误中涉及的功能的功能ID
如果错误已被标记为异常
IErrorFeatureContainer上的每个属性都需要一个空间参考参数。对于大多数用户,这将是拓扑的空间参考。
以下代码示例显示了获取拓扑空间参考的最快方法:
public ISpatialReference GetSpatialReferenceFromTopology(ITopology topology) { IGeoDataset geoDataset = (IGeoDataset)topology; return geoDataset.SpatialReference; }
IErrorFeatureContainer接口上有四个属性。所述 IErrorFeatureContainer.ErrorFeatures属性返回错误的枚举设有属于随附的程度内的指定拓扑规则。以下代码示例显示如何获取有关拓扑范围的错误功能:
// Given the topology and specific topology rule, return the error features for that rule. public void DisplayErrorFeaturesForRule(ITopology topology, ITopologyRule topologyRule) { // Cast to required interfaces and get the spatial reference. IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology; IGeoDataset geoDataset = (IGeoDataset)topology; ISpatialReference spatialReference = geoDataset.SpatialReference; // Get an enumerator for the error features. IEnumTopologyErrorFeature enumTopologyErrorFeature = errorFeatureContainer.get_ErrorFeatures(spatialReference, topologyRule, geoDataset.Extent, true, false); // Display the origin IDs for each of the error features. ITopologyErrorFeature topologyErrorFeature = null; while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null) { Console.WriteLine("Origin feature OID: {0}", topologyErrorFeature.OriginOID); } }
该 IErrorFeatureContainer.ErrorFeaturesByGeometryType属性返回一个特定几何类型的所有错误的功能。请参见以下代码示例,该示例将具有指定几何类型的每个错误特征的ID属性写入控制台:
public void DisplayErrorFeatureByGeometryType(ITopology topology, esriGeometryType geometryType) { // Cast to required interfaces and get the spatial reference. IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology; IGeoDataset geoDataset = (IGeoDataset)topology; ISpatialReference spatialReference = geoDataset.SpatialReference; // Get all errors that have the specified geometry type. IEnumTopologyErrorFeature enumTopologyErrorFeature = errorFeatureContainer.get_ErrorFeaturesByGeometryType(spatialReference, geometryType, false); // Display each error feature (if any exist) and display their properties. ITopologyErrorFeature topologyErrorFeature = null; while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null) { Console.WriteLine("Error Feature Origin Class ID: {0}", topologyErrorFeature.OriginClassID); Console.WriteLine("Error Feature Origin Feature ID: {0}", topologyErrorFeature.OriginOID); Console.WriteLine("Error Feature Dest. Class ID: {0}", topologyErrorFeature.DestinationClassID); Console.WriteLine("Error Feature Dest. Feature ID: {0}", topologyErrorFeature.DestinationOID); } }
与IErrorFeatureContainer.ErrorFeatures属性类似,IErrorFeatureContainer.ErrorFeaturesByGeometryType属性的最终参数是布尔值,它指示是否应返回错误或异常。请参阅以下内容:
如果设置为false(如前面的代码示例中所示),则仅返回错误功能。
如果设置为true,则仅返回异常。
IErrorFeatureContainer.ErrorFeaturesByRuleType属性返回错误的枚举特征属于在所提供的范围指定的拓扑规则类型。请注意,这与IErrorFeatureContainer.ErrorFeatures属性有何不同,因为不需要引用ITopologyRule,而是需要引用esriTopologyRuleType枚举的值。这也与其他属性的不同之处在于,未指定任何特定规则。因此,如果多个规则具有相同的规则类型,则将返回每个规则的错误特征。请参见以下代码示例:
public void DisplayErrorFeatureByRuleType(ITopology topology, esriTopologyRuleType topologyRuleType) { // Cast to required interfaces and get the spatial reference. IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology; IGeoDataset geoDataset = (IGeoDataset)topology; ISpatialReference spatialReference = geoDataset.SpatialReference; // Return all errors for the supplied rule in the given extent, then retrieve the first one. IEnumTopologyErrorFeature enumTopologyErrorFeature = errorFeatureContainer.get_ErrorFeaturesByRuleType(spatialReference, topologyRuleType, geoDataset.Extent, true, false); // Get the first error feature (if any exist) and display its properties. ITopologyErrorFeature topologyErrorFeature = enumTopologyErrorFeature.Next(); if (topologyErrorFeature != null) { Console.WriteLine("Error Feature Origin Class ID: {0}", topologyErrorFeature.OriginClassID); Console.WriteLine("Error Feature Origin Feature ID: {0}", topologyErrorFeature.OriginOID); Console.WriteLine("Error Feature Dest. Class ID: {0}", topologyErrorFeature.DestinationClassID); Console.WriteLine("Error Feature Dest. Feature ID: {0}", topologyErrorFeature.DestinationOID); } }
3.3 ITopologicalOperator
在10.1中该接口已经更新到ITopologicalOperator5
基本代码:
//为几何图形建立缓冲区 IGeometry pGeo = pFeature.ShapeCopy; ITopologicalOperator pTopo = pGeo as ITopologicalOperator; pTopo.Buffer(0.5); //判断其他图形是否在该缓冲区内 IRelationalOperator pRelate = pOtherFeature.ShapeCopy as IRelationalOperator ; pRelate.Contains(pRelate);