简单介绍: 拓扑学是一门研究几何图形位置关系的科学。 GIS所关注的拓扑主要集中在拓扑关系——存在于地理实体间的拓扑关系。 拓扑关系在GIS中起着描述两个地理实体的相对空间位置的重要作用。它是GIS空间实体之间最重要的关系之一,在GIS空间数据建模、空间查询、空间分析、空间推理、制图综合等过程中起着重要的作用。拓扑关系对GIS具有以下重要意义: (1)不需要利用坐标或者计算距离,能够清楚地反映某一要素与另一要素的空间位置关系。 (2)某些空间分析功能是基于拓扑关系而实现的。例如,要求某条河流的流域面积、流经的城市,查询有哪些国家与某个国家相邻等等。 (3)在进行某些空间分析之前必须检查数据的拓扑关系的合理性。这样的空间分析功能有计算最佳路径、缓冲分析、裁剪、建立封闭多边形等。 拓扑元素是拓扑关系的描述单元。 GeoDatabase数据模型包括一般性的常见3类要素类:点状要素类、线状要素类和面状要素类。 在二维空间中,它们分别对应的是3种拓扑元素,即结点、弧和面域(多边形)。 拓扑关系是不考虑度量和方向的空间实体之间的空间关系,它讲究的是拓扑元素彼此间的相对位置关系。 拓扑邻接、拓扑关联、拓扑包含是三种最基本的拓扑关系。 最终效果图: 对于拓扑分析,其思路可以概括如下: ①创建拓扑数据集 ②设置拓扑参数(拓扑规则) ③检查拓扑错误 ④显示拓扑结果 ①创建拓扑数据集 复制代码 /// /// 创建拓扑数据集 /// /// /// private void btnCreateTopo_Click(object sender, EventArgs e) { //设置指针处于等待状 this.Cursor = Cursors.WaitCursor; //创建拓扑数据集(前提是要素集内没有数据集) Global.GlobalTopology = create_topology(Global.pWorkSpace, "Road_Analysis", "Topology_Dataset"); //如果Flag为true则打开 if (Flag) { //打开拓扑数据集 Global.GlobalTopology = OpenToplogyFromFeatureWorkspace((IFeatureWorkspace)Global.pWorkSpace, "Road_Analysis", "Topology_Dataset"); //Flag为true表示已经存在拓扑数据集 MessageBox.Show("已经存在拓扑数据集"); //设置指针为默认状态 this.Cursor = Cursors.Default; //返回 return; } //创建要素类 IFeatureClass pTempFt = null; //向拓扑数据集中添加拓扑元素,可以添加多个 AddSingleElement(Global.GlobalTopology, "Road_Analysis", "南宁路网", out pTempFt); //添加单个要素的拓扑规则, 相同图层内的先不能相交 AddRuleToTopology(Global.GlobalTopology, esriTopologyRuleType.esriTRTLineNoIntersection, "NoIntersection", pTempFt); //Global.GlobalTopology将强转为IGeoDataset获得Extent IGeoDataset GDS = Global.GlobalTopology as IGeoDataset; //调用自定义方法添加拓扑规则 ValidateTopology(Global.GlobalTopology, GDS.Extent); MessageBox.Show("拓扑数据集创建成功!"); this.Cursor = Cursors.Default; } 复制代码 一些参数: 复制代码 /// /// 判断拓扑数据集是否存在,true表示存在拓扑数据集,false表示拓扑数据集为空 /// private bool Flag = false; 复制代码 复制代码 class Global { public static string GdbPath = Application.StartupPath + @"\网络分析\网络分析.mdb"; public static IWorkspace pWorkSpace; public static ITopology GlobalTopology; } 复制代码 如果要创建拓扑数据集,调用create_topology函数 复制代码 /// /// 创建拓扑数据集(前提是要素集内没有数据集) /// /// 工作空间 /// 要素集名称 /// 拓扑数据集名 /// public ITopology create_topology(IWorkspace myWSp, string FtDSName, string TopologyName) { //实例化拓扑为null ITopology myTopology = null; try { //将工作空间强转成要素工作空间 IFeatureWorkspace pFtWsp = myWSp as IFeatureWorkspace; //通过要素工作空间打开名字为"FtDSName"的要素数据集 IFeatureDataset myFDS = pFtWsp.OpenFeatureDataset(FtDSName); //将要素数据集放在要素类容器中 IFeatureClassContainer myFCContainer = myFDS as IFeatureClassContainer; //将要素类容器强转成拓扑容器 ITopologyContainer myTopologyContainer = myFDS as ITopologyContainer; //通过拓扑容器创建一个新的拓扑 myTopology = myTopologyContainer.CreateTopology(TopologyName, myTopologyContainer.DefaultClusterTolerance, -1, ""); } catch (Exception ee) { //MessageBox.Show(ee.Message); //如果拓扑已经存在,则将Flag变为true Flag = true; //返回null return null; } //返回创建的myTopology return myTopology; } 复制代码 注:如果创建拓扑出现问题,请参考【已解决】ArcGIS Engine无法创建拓扑的问题(CreateTopology) 如果拓扑数据集已经存在,调用OpenToplogyFromFeatureWorkspace函数 复制代码 /// /// 打开拓扑数据集(如果拓扑数据集已经创建) /// /// 工作空间 /// 普通数据集 /// 拓扑集名 /// 返回拓扑数据集 private ITopology OpenToplogyFromFeatureWorkspace(IFeatureWorkspace featureWorkspace, string featureDatasetName, string topologyName) { //打开特征数据集 IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName); //将featureDataset转换为ITopologyContainer ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset; //ITopology get_TopologyByName(string Name); //打开拓扑 ITopology topology = topologyContainer.get_TopologyByName(topologyName); //返回拓扑 return topology; } 复制代码 ②设置拓扑参数(拓扑规则) 复制代码 //向拓扑数据集中添加拓扑元素,可以添加多个 AddSingleElement(Global.GlobalTopology, "Road_Analysis", "南宁路网", out pTempFt); 复制代码 复制代码 /// /// 向拓扑数据集中添加拓扑元素 /// /// 拓扑数据集 /// 数据集名 /// 要素名 /// 输出参与拓扑的单个元素 private void AddSingleElement(ITopology myTopology, string DSName, string FtName, out IFeatureClass pFtClass) { //打开工作空间 IFeatureWorkspace pFtWsp = Global.pWorkSpace as IFeatureWorkspace; //打开数据集 IFeatureDataset myFDS = pFtWsp.OpenFeatureDataset(DSName); //在数据集中打开要素 IFeatureClassContainer myFCContainer = myFDS as IFeatureClassContainer; IFeatureClass pTempFt = myFCContainer.get_ClassByName(FtName); pFtClass = pTempFt; //调用ITopology.AddClass方法添加要素 myTopology.AddClass(pTempFt, 5, 1, 1, false); } 复制代码 复制代码 //添加单个要素的拓扑规则, 相同图层内的先不能相交 AddRuleToTopology(Global.GlobalTopology, esriTopologyRuleType.esriTRTLineNoIntersection, "NoIntersection", pTempFt); 复制代码 复制代码 /// /// 添加单个要素的拓扑规则 /// /// 拓扑数据集 /// 拓扑规则 /// 规则名称 /// 参与制定规则的要素 private void AddRuleToTopology(ITopology topology, esriTopologyRuleType ruleType, string ruleName, IFeatureClass featureClass) { //实例化拓扑规则 ITopologyRule topologyRule = new TopologyRuleClass(); //拓扑规则 topologyRule.TopologyRuleType = ruleType; //规则名称 topologyRule.Name = ruleName; //规则面向的要素类 topologyRule.OriginClassID = featureClass.FeatureClassID; topologyRule.AllOriginSubtypes = true; ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology; if (topologyRuleContainer.get_CanAddRule(topologyRule)) { //调用.AddRule方法添加规则 topologyRuleContainer.AddRule(topologyRule); } else { MessageBox.Show("规则添加失败, 不适用于拓扑集"); } } 复制代码 ③检查拓扑错误 复制代码 //验证拓扑错误 ValidateTopology(Global.GlobalTopology, GDS.Extent); 复制代码 复制代码 /// /// 验证拓扑错误 /// /// 拓扑集 /// t拓扑集的Extent private void ValidateTopology(ITopology topology, IEnvelope envelope) { //实例化一个Polygon存储Topology的Extent IPolygon localPolygon = new PolygonClass(); //获取Topology的外接矩形 ISegmentCollection segmentCollection = (ISegmentCollection)localPolygon; segmentCollection.SetRectangle(envelope); //赋值Topology的阴影区域 IPolygon polygon = topology.get_DirtyArea(localPolygon); if (!polygon.IsEmpty) { //赋值参数并Validate拓扑错误 IEnvelope areaToValidate = polygon.Envelope; IEnvelope areaValidated = topology.ValidateTopology(areaToValidate); } } 复制代码 ④显示拓扑结果 复制代码 /// /// 显示拓扑结果 /// /// /// private void btnDisplayTopo_Click(object sender, EventArgs e) { //防止没有拓扑而创建图层对象 if(Flag) { //设置指针处于等待状 this.Cursor = Cursors.WaitCursor; //新建一个拓扑图层 ITopologyLayer pTpLayer = new TopologyLayerClass(); //将Global.GlobalTopology赋值给当前的拓扑图层的拓扑 pTpLayer.Topology = Global.GlobalTopology; //拓扑图层强转成图层 ILayer pLayer = (ILayer)pTpLayer; //将图层名字命名为"Topology_Dataset" pLayer.Name = "Topology_Dataset"; //将图层加到axMapControl1上 axMapControl1.AddLayer(pLayer); //设置指针为默认状态 this.Cursor = Cursors.Default; } } 复制代码 总结: 谢谢观看!本人初学GIS二次开发,如果有不对的地方,请多多包涵!https://www.cnblogs.com/edcoder/p/11808555.html