空间拓扑描述的是自然界地理对象的空间位置关系-相邻,重合,连通等,是地理对象空间属性的一部分.目前ESRI提供的数据存储方式中,Coverage和GeoDatabase能够建立拓扑,Shape格式的数据不能建立拓扑.
1. GeoDataBase建立拓扑的基础
1).GeoDatabase实现拓扑的基础是”几何重合”,Geodatabase中的地理对象都是实体存储,主要是根据节点坐标是否重合来判断地理要素之间是否存在某种拓扑关系
2).拓扑只能在要素集(FeatureDataset)中创建,参加创建拓扑的所有要素类(FeatureClass)必须具有相同的空间参考
3).参与拓扑创建的必须是简单要素类,注记类(Annoca),尺寸和几何网络要素类不能参与拓扑的创建
4)单个要素集可以创建多个拓扑
2. GeoDatabase拓扑中的重要概念
1).规则:表达要素之间的空间关系,ESRI提供了27中拓扑关系(见后面附表)
2).拓扑容限.决定在多大范围内要素能够被捕捉在一起(也称为聚类容限(cluster tolerance))
3).拓扑等级 控制在拓扑验证的过程中节点移动的级别.这时候,等级低的要素类将向等级高的要素类移动,最高级别为1,最低级别为-50
4).脏区(dirty area):脏区就是参与拓扑创建时被修改的地理要素(增,删,改)的区域
5).错误要素(Error Feature):只要素类中不符合拓扑规则的要素或者要素的一部分
3. 使用拓扑的详细步骤及代码
1).创建拓扑
ITopology是一个不可创建类,创建拓扑需通过调用ITopologyContainer:CreateTopology方法来建立拓扑,拓扑的规则要用ITopologyRule接口来表达,必须加到ITopologyRuleContainer中.
public void CreateTopology(IFeatureDataset featuredataset, string topologyName,esriTopologyRuleType rulename,double clusterTolerance,int classID)
{
try
{
ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset;
ITopology topology=topologyContainer.CreateTopology(topologyName, clusterTolerance, -1, "");
IFeatureClassContainer featureclassContainer = (IFeatureClassContainer)featureDataset;
ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;
ITopologyRule topologyRule = new TopologyRuleClass();
topologyRule.TopologyRuleType = rulename;
topologyRule.OriginClassID = classID;
if (topologyRuleContainer.get_CanAddRule(topologyRule))
{
topologyRuleContainer.AddRule(topologyRule);
}
}
catch (COMException ex)
{
MessageBox.Show(ex.Message);
}
}
2).验证拓扑
通过调用ITopology:ValidateTopology 方法来验证指定区域内的拓扑,没有版本的拓扑可以在任何时候验证,指定版本的拓扑必须在编辑会话中验证
例如验证整个区域的拓扑的代码片段,假设已经存在创建好的拓扑ITopology topo
IGeoDataset geodataset=(IGeoDataset) topo;
topo. ValidateTopology(geodataset. Extent.Envelope);
3).编辑拓扑
拓扑编辑的两个重要方面就是:共享点和共享边的编辑
采用的主要接口: ITopologyGraph, ITopologyNode, ITopologyEdge, IDisplayFeedback
ITopologyLayer
以移动共享点为例
一、打开拓扑,建立拓扑图(ITopologyGraph)
//topoLayer 是一个打开的拓扑图层
ITopologyGraph topoGraph =topoLayer.Topology.Cache;
topoGraph.Build(extent,false);//extent是数据集的区域
二、.使用HitTest方法取得要移动的点(ITopologyElement对象)
ITopologyElement node;
topoGraph.HitTest(….,ref node);
如果HitTest方法返回一个True,反之返回一个False
三、使用IMovePointFeedback在鼠标移动时,移动点
四、.鼠标释放时
//获取拓扑图
ITopologyGraph topoGraph =topoLayer.Topology.Cache;
//转换坐标
IPoint point=mapcontrol.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);
//获得正在做拓扑编辑的元素
ITopologyNode topoNode=(ITopologyNode)topoElement;//移动的ITopologyElement对象
//实施拓扑编辑
topoGraph.SplitMoveNode(topoNode, poin,false);
//提交拓扑编辑结果
IEnvelope envelope;
topoGraph.Post(out envelope);
4).查询系统中的拓扑
将ITopologyContainer这个接口转换为IFeatureDataset接口,然后查询即可
4. 参考资料
1. 探讨GIS中拓扑实现的原理 刑超等 ESRI中国通讯22期
2. ArcEngine9.0的开发帮助
3. ESRI中国社区
附图-ESRI的拓扑规则
esriTRTAny |
任何拓扑规则. 查询拓扑的时候用 |
esriTRTFeatureLargerThanClusterTolerance |
地理要素小于聚类容限被删除 |
esriTRTAreaNoGaps |
面是封闭的 |
esriTRTAreaNoOverlap |
面不相交 |
esriTRTAreaCoveredByAreaClass |
The rule is an area covered by area class rule. |
esriTRTAreaAreaCoverEachOther |
两个区域完全重合 |
esriTRTAreaCoveredByArea |
一个区域被另一个区域覆盖 |
esriTRTAreaNoOverlapArea |
一个面没有相交的面 |
esriTRTLineCoveredByAreaBoundary |
线被区域的边线覆盖 |
esriTRTPointCoveredByAreaBoundary |
点在面的边界上 |
esriTRTPointProperlyInsideArea |
点完全在面内 |
esriTRTLineNoOverlap |
无重合的线 |
esriTRTLineNoIntersection |
无相交的线 |
esriTRTLineNoDangles |
无摇摆的线 |
esriTRTLineNoPseudos |
线不存在伪节点 |
esriTRTLineCoveredByLineClass |
The rule is a line covered by line class rule. |
esriTRTLineNoOverlapLine |
The rule is a line-no overlap line rule. |
esriTRTPointCoveredByLine |
点被线覆盖 |
esriTRTPointCoveredByLineEndpoint |
点被线的尾节点覆盖 |
esriTRTAreaBoundaryCoveredByLine |
一个面的边界被线覆盖 |
esriTRTAreaBoundaryCoveredByAreaBoundary |
一个面的边界被另一个面的边界覆盖 |
esriTRTLineNoSelfOverlap |
不存在自重合的线 |
esriTRTLineNoSelfIntersect |
不存在自相交的线 |
esriTRTLineNoIntersectOrInteriorTouch |
The rule is a line-no intersect or interior touch rule. |
esriTRTLineEndpointCoveredByPoint |
线的尾节点被点覆盖 |
esriTRTAreaContainPoint |
面包含点 |
esriTRTLineNoMultipart |
The rule is a line cannot be multipart rule. |