空间拓扑描述的是自然界地理对象的空间位置关系-相邻,重合,连通等,是地理对象空间属性的一部分.目前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.
V 2 ArcEngine中拓扑的使用- -
拓扑(ITopology)的使用包括
1.建立拓扑
2.验证拓扑
3.编辑过程中保证拓扑的正确
4.查询系统中存在的拓扑
1.首先 来看看建立拓扑
Topology实现了ITopology这个接口 但是给类是不能用来创建对象的。
必须要通过调用 ITopologyContainer::CreateTopology这个方法来建立一个Topology
FeatureDataset 实现了ITopologyContainer这个接口。那么 这就是说拓扑只能在一个
FeatureDataset的范围内建立。而不能独立存在于Workspace中。这样做的原因是需要保证
参与同一个拓扑的FeatureClass具有同一个投影坐标系统。 建立拓扑后需要将ObjectClass
加入到拓扑中去。这样这个拓扑就可以用来验证这几个ObjectClass 的对象之间的关系了。
验证关系就要有规则,规则是由ITopologyRule来表达的。ITopologyRule必须要被
加入到一个ITopologyRuleContainer中去。而Topology实现了这个接口。
一个ITopologyRule用来表达两个ObjectClass的对象之间的某个关系。
具体代码参看接口就可以了。
2.验证拓扑
ITopology有一个方法 ValidateTopology 用来验证指定区域内的拓扑。需要注意 没有版本
的拓扑可以在 任何时候验证。而有版本的拓扑必须在编辑回话中验证。
3.拓扑编辑
1.移动共用点
1.首先需要打开拓扑 建立拓扑图(ITopologyGraph)
代码如下:
//topoLayer 是一个打开的拓扑图层
ITopologyGraph pTG=topoLayer.Topology.Cache;
pTG.Build(pA.Extent,false);
2.然后 需要获得当前节点或者边 这个操作要使用拓扑图的点击测试
ITopologyElement topeEle
pTG.HitTest(... ref topeEle);
这个方法在点击测试成功的时候返回true.而且会通过topeEle这个ref 参数将选中的元素(点或者边)
返回.
3.还有一种获取节点的方法
首先调用拓扑图的Select方法 选中点击测试的元素(pTG.Select)
然后可以查询拓扑图的选中节点集合 就可以找到该节点(pTG.NodeSelection)
4.为该元素使用一个Feedback.
//其中 pNode 就是当前节点 sr 是参考坐标系 可以使用null
//还有给Feedback设置Display
m_pNodeFeedback =pTG.GetSplitMoveNodeFeedback(pNode,false,sr);
m_pNodeFeedback.Display= activeView.ScreenDisplay;
5.在鼠标移动的时候 调用Feedback的MoveTo 方法。
if(m_pNodeFeedback!=null)
{
//activeView 是活动的试图
//首先要把将点坐标转换为地图中的坐标。
//然后调用MoveTo 方法
IPoint pt=activeView.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);
m_pNodeFeedback.MoveTo(pt);
}
6.在鼠标释放的时候
//获取拓扑图
ITopologyGraph pTG=topoLayer.Topology.Cache;
//转换坐标
IPoint pt=pA.ScreenDisplay.DisplayTransformation.ToMapPoint(X,Y);
//获得正在做拓扑编辑的元素
ITopologyNode pTN=(ITopologyNode)m_pTopoElement;
//实施拓扑编辑
pTG.SplitMoveNode(pTN,pt,false);
//提交拓扑编辑结果
IEnvelope pE;
pTG.Post(out pE);
4.查询系统中的拓扑
还是ITopologyContainer 这个接口 这个接口有FeatureDataset这个唯一的实现。
CreateTopology 建立一个新的拓扑
DefaultClusterTolerance The default cluster tolerance as per the topology engine.
MaximumClusterTolerance The maximal cluster tolerance as per the topology engine.
MinimumClusterTolerance The minimal cluster tolerance as per the topology engine.
Topology 通过索引打开拓扑.
TopologyByID 通过ID打开拓扑.
TopologyByName 通过名字打开拓扑
TopologyCount 拓扑的数目