ArcGIS Engine空间分析之拓扑分析的实现
簡單介紹:
拓撲學是一門研究幾何圖形位置關系的科學。
GIS所關注的拓撲主要集中在拓撲關系——存在于地理實體間的拓撲關系。
拓撲關系在GIS中起著描述兩個地理實體的相對空間位置的重要作用。它是GIS空間實體之間最重要的關系之一,在GIS空間數據建模、空間查詢、空間分析、空間推理、制圖綜合等過程中起著重要的作用。拓撲關系對GIS具有以下重要意義:
(1)不需要利用坐標或者計算距離,能夠清楚地反映某一要素與另一要素的空間位置關系。
(2)某些空間分析功能是基于拓撲關系而實現的。例如,要求某條河流的流域面積、流經的城市,查詢有哪些國家與某個國家相鄰等等。
(3)在進行某些空間分析之前必須檢查數據的拓撲關系的合理性。這樣的空間分析功能有計算最佳路徑、緩沖分析、裁剪、建立封閉多邊形等。
拓撲元素是拓撲關系的描述單元。
GeoDatabase數據模型包括一般性的常見3類要素類:點狀要素類、線狀要素類和面狀要素類。
在二維空間中,它們分別對應的是3種拓撲元素,即結點、弧和面域(多邊形)。
拓撲關系是不考慮度量和方向的空間實體之間的空間關系,它講究的是拓撲元素彼此間的相對位置關系。
拓撲鄰接、拓撲關聯、拓撲包含是三種最基本的拓撲關系。
最終效果圖:
對于拓撲分析,其思路可以概括如下:
①創建拓撲數據集
②設置拓撲參數(拓撲規則)
③檢查拓撲錯誤
④顯示拓撲結果
①創建拓撲數據集
/// <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獲得ExtentIGeoDataset 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) {//實例化拓撲為nullITopology 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變為trueFlag = true;//返回nullreturn null;}//返回創建的myTopologyreturn 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轉換為ITopologyContainerITopologyContainer 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的ExtentIPolygon 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二次開發,如果有不對的地方,請多多包涵!
總結
以上是生活随笔為你收集整理的ArcGIS Engine空间分析之拓扑分析的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js中颜色的判断和颜色表
- 下一篇: docker pull 镜像失败