簡單介紹:html
拓撲學是一門研究幾何圖形位置關係的科學。網絡
GIS所關注的拓撲主要集中在拓撲關係——存在於地理實體間的拓撲關係。函數
拓撲關係在GIS中起着描述兩個地理實體的相對空間位置的重要做用。它是GIS空間實體之間最重要的關係之一,在GIS空間數據建模、空間查詢、空間分析、空間推理、製圖綜合等過程當中起着重要的做用。拓撲關係對GIS具備如下重要意義:
(1)不須要利用座標或者計算距離,可以清楚地反映某一要素與另外一要素的空間位置關係。
(2)某些空間分析功能是基於拓撲關係而實現的。例如,要求某條河流的流域面積、流經的城市,查詢有哪些國家與某個國家相鄰等等。
(3)在進行某些空間分析以前必須檢查數據的拓撲關係的合理性。這樣的空間分析功能有計算最佳路徑、緩衝分析、裁剪、創建封閉多邊形等。post
拓撲元素是拓撲關係的描述單元。this
GeoDatabase數據模型包括通常性的常見3類要素類:點狀要素類、線狀要素類和麪狀要素類。url
在二維空間中,它們分別對應的是3種拓撲元素,即結點、弧和麪域(多邊形)。spa
拓撲關係是不考慮度量和方向的空間實體之間的空間關係,它講究的是拓撲元素彼此間的相對位置關係。3d
拓撲鄰接、拓撲關聯、拓撲包含是三種最基本的拓撲關係。指針
最終效果圖:code
對於拓撲分析,其思路能夠歸納以下:
①建立拓撲數據集
②設置拓撲參數(拓撲規則)
③檢查拓撲錯誤
④顯示拓撲結果
①建立拓撲數據集
/// <summary> /// 建立拓撲數據集 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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; }
一些參數:
/// <summary> /// 判斷拓撲數據集是否存在,true表示存在拓撲數據集,false表示拓撲數據集爲空 /// </summary> private bool Flag = false;
class Global { public static string GdbPath = Application.StartupPath + @"\網絡分析\網絡分析.mdb"; public static IWorkspace pWorkSpace; public static ITopology GlobalTopology; }
若是要建立拓撲數據集,調用create_topology函數
/// <summary> /// 建立拓撲數據集(前提是要素集內沒有數據集) /// </summary> /// <param name="myWSp">工做空間</param> /// <param name="FtDSName">要素集名稱</param> /// <param name="TopologyName">拓撲數據集名</param> /// <returns></returns> 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函數
/// <summary> /// 打開拓撲數據集(若是拓撲數據集已經建立) /// </summary> /// <param name="featureWorkspace">工做空間</param> /// <param name="featureDatasetName">普通數據集</param> /// <param name="topologyName">拓撲集名</param> /// <returns>返回拓撲數據集</returns> 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);
/// <summary> /// 向拓撲數據集中添加拓撲元素 /// </summary> /// <param name="myTopology">拓撲數據集</param> /// <param name="DSName">數據集名</param> /// <param name="FtName">要素名</param> /// <param name="pFtClass">輸出參與拓撲的單個元素</param> 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);
/// <summary> /// 添加單個要素的拓撲規則 /// </summary> /// <param name="topology">拓撲數據集</param> /// <param name="ruleType">拓撲規則</param> /// <param name="ruleName">規則名稱</param> /// <param name="featureClass">參與制定規則的要素</param> 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);
/// <summary> /// 驗證拓撲錯誤 /// </summary> /// <param name="topology">拓撲集</param> /// <param name="envelope">t拓撲集的Extent</param> 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); } }
④顯示拓撲結果
/// <summary> /// 顯示拓撲結果 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> 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二次開發,若是有不對的地方,請多多包涵!