ArcGIS Engine - 拓扑处理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、实现代码

using Com.XXW.NTSL.EditorManagement;
using Com.XXW.NTSL.Framework;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataManagementTools;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geoprocessor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Com.XXW.NTSL.SpaceManagement
{
    public partial class HandleTopology : Form
    {
        private ITopology Topology;
        private ISpatialReference pSpatialReference;
        private EditorToolBar editorToolBar;
        private IEnvelope Envelope = null;
        private IFeatureLayer EditLayer;

        public HandleTopology(ILayer TopoLayer)
        {
            InitializeComponent();

            //获取空间坐标系
            IGeoDataset pGeoDataset = TopoLayer as IGeoDataset;
            pSpatialReference = pGeoDataset.SpatialReference;

            ITopologyLayer pTopologyLayer = TopoLayer as ITopologyLayer;
            Topology = pTopologyLayer.Topology;
        }

        /// <summary>
        /// Load事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleTopology_Load(object sender, EventArgs e)
        {
            //获取拓扑错误信息
            PRV_GetRule(Topology);
        }

        /// <summary>
        /// 获取拓扑规则
        /// </summary>
        /// <param name="Topology"></param>
        private void PRV_GetRule(ITopology Topology)
        {
            if (Topology != null)
            {
                ITopologyRuleContainer pTopologyRuleContainer = Topology as ITopologyRuleContainer;
                IEnumRule pEnumRule = pTopologyRuleContainer.Rules;
                IRule pRule = pEnumRule.Next();
                while (pRule != null)
                {
                    ITopologyRule pTopologyRule = pRule as ITopologyRule;
                    PRV_GetError(Topology, pTopologyRule);

                    pRule = pEnumRule.Next();
                }
            }
            else
            {
                MessageBox.Show("请先构建拓扑!", "提示");
            }
            
        }

        /// <summary>
        /// 获取拓扑错误信息
        /// </summary>
        /// <param name="Topology"></param>
        /// <param name="IN_TopologyRule"></param>
        private void PRV_GetError(ITopology Topology, ITopologyRule IN_TopologyRule)
        {
            if (Topology != null)
            {
                IEnvelope Temp_Envolope = (this.Topology as IGeoDataset).Extent;
                IErrorFeatureContainer Temp_ErrorContainer = Topology as IErrorFeatureContainer;

                //获取所有信息
                IEnumTopologyErrorFeature Temp_EnumErrorFeature = Temp_ErrorContainer.get_ErrorFeatures(pSpatialReference, IN_TopologyRule, Temp_Envolope, true, true);
                ITopologyErrorFeature Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
                while (Temp_ErrorFeature != null)
                {
                    //添加规则
                    DataGridViewRow Row = new DataGridViewRow();
                    
                    //获取ID
                    DataGridViewTextBoxCell textboxcell = new DataGridViewTextBoxCell();
                    textboxcell.Value = Temp_ErrorFeature.ErrorID;
                    Row.Cells.Add(textboxcell);

                    //获取规则类型
                    DataGridViewTextBoxCell textboxcell2 = new DataGridViewTextBoxCell();
                    textboxcell2.Value = IN_TopologyRule.Name;
                    Row.Cells.Add(textboxcell2);

                    //获取要素1
                    IFeatureClass pFeatureClassA = GetFeatureClassByFeatureDataset(Topology, IN_TopologyRule.OriginClassID, null);
                    ILayer pLayerA = GetLayerByFeatureClass(pFeatureClassA);
                    DataGridViewTextBoxCell textboxcell3 = new DataGridViewTextBoxCell();
                    textboxcell3.Value = pLayerA.Name;
                    Row.Cells.Add(textboxcell3);

                    if (IN_TopologyRule.OriginClassID != IN_TopologyRule.DestinationClassID)
                    {
                        //获取要素2
                        IFeatureClass pFeatureClassB = GetFeatureClassByFeatureDataset(Topology, IN_TopologyRule.DestinationClassID, null);
                        ILayer pLayerB = GetLayerByFeatureClass(pFeatureClassB);
                        DataGridViewTextBoxCell textboxcell4 = new DataGridViewTextBoxCell();
                        textboxcell4.Value = pLayerB.Name;
                        Row.Cells.Add(textboxcell4);
                    }
                    else
                    {
                        DataGridViewTextBoxCell textboxcell5 = new DataGridViewTextBoxCell();
                        textboxcell5.Value = "";
                        Row.Cells.Add(textboxcell5);
                    }

                    dataTopologyRule.Rows.Add(Row);
                    Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
                }
                
            }
            else
            {
                MessageBox.Show("请先构建拓扑!" ,"提示");
            }
        }

        /// <summary>
        /// 根据ClassID或AliasName获取数据集中要素类
        /// </summary>
        /// <param name="Topology"></param>
        /// <param name="ClassID"></param>
        /// <returns></returns>
        private IFeatureClass GetFeatureClassByFeatureDataset(ITopology Topology, int ClassID, string AliasName)
        {
            IFeatureClass pFeatureClass = null;
            //获取拓扑要素数据集
            IFeatureDataset pFeatureDataset = Topology.FeatureDataset;
            List<IFeatureClass> FeatureDatasetList = GetAllFeatureClass(pFeatureDataset);

            if (ClassID != 0)
            {
                for (int i = 0; i < FeatureDatasetList.Count; i++)
                {
                    if (FeatureDatasetList[i].FeatureClassID == ClassID)
                    {
                        pFeatureClass = FeatureDatasetList[i];
                        break;
                    }
                }
            }

            if (AliasName != null)
            {
                for (int i = 0; i < FeatureDatasetList.Count; i++)
                {
                    if (FeatureDatasetList[i].AliasName == AliasName)
                    {
                        pFeatureClass = FeatureDatasetList[i];
                        break;
                    }
                }
            }
            

            return pFeatureClass;
        }

        /// <summary>
        /// 根据要素类获取图层
        /// </summary>
        /// <param name="FeatureClass"></param>
        /// <returns></returns>
        private ILayer GetLayerByFeatureClass(IFeatureClass FeatureClass)
        {
            ILayer pLayer = null;

            if (FeatureClass != null)
            {
                //获取主窗体
                MainForm mainForm = MainForm.GetInstance();

                //获取全部图层
                List<ILayer> LayerList = mainForm.GetAllLayer(mainForm.Map);

                for (int l = 0; l < LayerList.Count; l++)
                {
                    IFeatureLayer pFeatureLayer = LayerList[l] as IFeatureLayer;
                    if (pFeatureLayer != null)
                    {
                        IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
                        if (FeatureClass.AliasName == pFeatureClass.AliasName)
                        {
                            pLayer = LayerList[l];
                            break;
                        }
                    }

                }
            }

            return pLayer;
        }

        /// <summary>
        /// 获取所有要素类
        /// </summary>
        /// <param name="featureDataset">要素集</param>
        /// <returns>要素类列表</returns>
        private static List<IFeatureClass> GetAllFeatureClass(IFeatureDataset featureDataset)
        {
            IFeatureClassContainer featureClassContainer = (IFeatureClassContainer)featureDataset;
            IEnumFeatureClass enumFeatureClass = featureClassContainer.Classes;
            IFeatureClass featureClass = enumFeatureClass.Next();

            List<IFeatureClass> featureClassList = new List<IFeatureClass>();
            while (featureClass != null)
            {
                featureClassList.Add(featureClass);
                featureClass = enumFeatureClass.Next();
            }
            return featureClassList;
        }

        /// <summary>
        /// 错误列表选择事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataTopologyRule_SelectionChanged(object sender, EventArgs e)
        {
            if (dataTopologyRule.RowCount != 0)
            {
                string nameA = dataTopologyRule.SelectedRows[0].Cells[2].Value.ToString();
                string nameB = dataTopologyRule.SelectedRows[0].Cells[3].Value.ToString();

                checkedFeatureClass.Properties.Items.Clear();
                checkedFeatureClass.Properties.Items.Add(nameA);
                checkedFeatureClass.SelectedIndex = 0;
                if (nameB != "")
                {
                    checkedFeatureClass.Properties.Items.Add(nameB);
                }

            }
            
        }

        /// <summary>
        /// 双击定位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataTopologyRule_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //获取主窗体
            MainForm mainForm = MainForm.GetInstance();

            //获取选择规则和错误ID
            string rule = (string)dataTopologyRule.SelectedRows[0].Cells[1].Value;
            int ErrorID = (int)dataTopologyRule.SelectedRows[0].Cells[0].Value;

            if (rule != "" &&  ErrorID != 0)
            {
                //通过指定信息获取拓扑错误要素
                ITopologyErrorFeature Temp_ErrorFeature = GetErrorFeature(Topology, rule, ErrorID);
                IFeature pFeature = Temp_ErrorFeature as IFeature;
                IGeometry pGeometry = pFeature.Shape;
                IEnvelope pEnvelope = pGeometry.Envelope;
                if (pGeometry.GeometryType != esriGeometryType.esriGeometryPoint)
                {
                    pEnvelope.Expand(1.5, 1.5, true);
                }
                else
                {
                    pEnvelope.Expand(5, 5, false);
                }

                pEnvelope.Expand(1.5, 1.5, true);

                //缩放到拓扑错误要素
                mainForm.MapControl.Extent = pEnvelope;

                //同步范围
                Envelope = pEnvelope;
            }
           
        }

        /// <summary>
        /// 通过指定信息获取拓扑错误要素
        /// </summary>
        /// <param name="Topology"></param>
        /// <param name="rule">拓扑规则</param>
        /// <param name="ErrorID">错误ID</param>
        private ITopologyErrorFeature GetErrorFeature(ITopology Topology, string rule, int ErrorID)
        {
            if (Topology != null)
            {
                if (rule == null || rule == "" || ErrorID == 0) return null;

                //获取拓扑规则
                ITopologyRuleContainer pTopologyRuleContainer = Topology as ITopologyRuleContainer;
                IEnumRule pEnumRule = pTopologyRuleContainer.Rules;
                IRule pRule = pEnumRule.Next();
                while (pRule != null)
                {
                    ITopologyRule pTopologyRule = pRule as ITopologyRule;
                    if (pTopologyRule.Name == rule)
                    {
                        //获取规则下的错误要素
                        IEnvelope Temp_Envolope = (this.Topology as IGeoDataset).Extent;
                        IErrorFeatureContainer Temp_ErrorContainer = Topology as IErrorFeatureContainer;

                        //获取所有信息
                        IEnumTopologyErrorFeature Temp_EnumErrorFeature = Temp_ErrorContainer.get_ErrorFeatures(pSpatialReference, pTopologyRule, Temp_Envolope, true, true);
                        ITopologyErrorFeature Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
                        while (Temp_ErrorFeature != null)
                        {
                            if (Temp_ErrorFeature.ErrorID == ErrorID)
                            {
                                return Temp_ErrorFeature;
                            }

                            Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
                        }
                    }

                    pRule = pEnumRule.Next();
                }

                return null;
            }
            else
            {
                MessageBox.Show("请先构建拓扑!", "提示");
                return null;
            }
        }

        /// <summary>
        /// 编辑按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkEdit_Click(object sender, EventArgs e)
        {
            //获取主窗体
            MainForm mainForm = MainForm.GetInstance();

            //获取编辑图层名称
            string LayerName = checkedFeatureClass.Text;

            //根据名称获取图层
            ILayer Layer = mainForm.GetLayerByName(mainForm.Map, LayerName);
            IFeatureLayer FeatureLayer = Layer as IFeatureLayer;
            IFeatureClass FeatureClass = FeatureLayer.FeatureClass;

            //获取到要素数据集中要素类
            IFeatureClass DatasetClass = GetFeatureClassByFeatureDataset(Topology, 0, FeatureClass.AliasName);

            //判断编辑图层是否存在
            if (FeatureClass.FeatureClassID != DatasetClass.FeatureClassID)
            {
                IFeatureLayer DatasetLayer = new FeatureLayerClass();
                DatasetLayer.FeatureClass = DatasetClass;
                DatasetLayer.Name = DatasetClass.AliasName;

                //添加图层
                mainForm.Map.AddLayer(DatasetLayer);
                mainForm.Map.MoveLayer(DatasetLayer, 1);
                EditLayer = DatasetLayer;
            }
            else
            {
                EditLayer = FeatureLayer;
            }

            //判断要素类的编辑状态
            if (!ISEdit(EditLayer.FeatureClass))
            {
                //开启编辑
                editorToolBar = new EditorToolBar(EditLayer);
                editorToolBar.Show();

                //启用验证
                checkPresent.Enabled = true;
                checkAll.Enabled = true;
                export.Enabled = false;
            }
            else
            {
                //停止编辑
                editorToolBar.StopEditing();
                editorToolBar.Close();

                //关闭验证
                checkPresent.Enabled = false;
                checkAll.Enabled = false;
                export.Enabled = true;

            }
            
        }

        /// <summary>
        /// 验证当前
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkPresent_Click(object sender, EventArgs e)
        {
            //拓扑验证
            PRV_ValidateTopology(Topology, Envelope);
        }

        /// <summary>
        /// 验证全部
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkAll_Click(object sender, EventArgs e)
        {
            //获取拓扑要素类范围
            IGeoDataset geoDataset = (IGeoDataset)Topology;

            IPolygon searchArea = new PolygonClass();

            ISegmentCollection segmentCollection = (ISegmentCollection)searchArea;

            segmentCollection.SetRectangle(geoDataset.Extent);

            IPolygon dirtyArea = Topology.get_DirtyArea(searchArea);

            IEnvelope dirtyAreaEnvelope = dirtyArea.Envelope;

            //拓扑验证
            PRV_ValidateTopology(Topology, dirtyAreaEnvelope);
        }

        /// <summary>
        /// 拓扑验证
        /// </summary>
        /// <param name="Topology">拓扑要素</param>
        /// <param name="Envelope">验证范围</param>
        private void PRV_ValidateTopology(ITopology Topology, IEnvelope Envelope)
        {
            if (Envelope != null)
            {
                //获取主窗体
                MainForm mainForm = MainForm.GetInstance();

                //等待处理
                mainForm.ShowWaitInfo("正在进行,请等待", "拓扑验证...");

                //停止编辑
                editorToolBar.StopEditing();

                //拓扑验证
                Topology.ValidateTopology(Envelope);

                //启动编辑
                editorToolBar.StatrEditing();

                //清空列表
                while (dataTopologyRule.Rows.Count != 0)
                {
                    dataTopologyRule.Rows.RemoveAt(0);
                }

                //重载拓扑错误信息
                PRV_GetRule(Topology);

                //关闭等待窗口
                mainForm.CloseWaitInfo();

                //刷新地图
                mainForm.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, Envelope);

                MessageBox.Show("验证完成!");

            }
        }

        /// <summary>
        /// 判断要素类是否在编辑
        /// </summary>
        /// <param name="pFeatureClass"></param>
        /// <returns></returns>
        public bool ISEdit(IFeatureClass pFeatureClass)
        {

            IDatasetEdit pDataEdit = pFeatureClass as IDatasetEdit;

            return pDataEdit.IsBeingEdited();

        }

        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void export_Click(object sender, EventArgs e)
        {
			if (EditLayer != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Title = "导出要素";
                saveFileDialog.Filter = "shape文件(*.shp)|*.shp";
                saveFileDialog.InitialDirectory = Configuration.Environment.WorkPath;
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    //获取主窗体
                    MainForm mainForm = MainForm.GetInstance();

                    //等待处理
                    mainForm.ShowWaitInfo("正在进行,请等待", "导出数据...");

                    //获得文件路径
                    string localFilePath = saveFileDialog.FileName.ToString();

                    //获取文件路径
                    string out_GDBPathName = localFilePath.Substring(0, localFilePath.LastIndexOf("\\"));

                    //获取文件名
                    string out_FeatureName = localFilePath.Substring(localFilePath.LastIndexOf("\\") + 1);

					//判断文件是否存在               
                    if (System.IO.File.Exists(localFilePath))
                    {
                        //获取工程工作空间
                        IWorkspaceFactory pWorkspaceFactory = new ShapefileWorkspaceFactory();
                        IFeatureWorkspace pFeaWorkspace = pWorkspaceFactory.OpenFromFile(out_GDBPathName, 0) as IFeatureWorkspace;

                        IFeatureClass pFCChecker = pFeaWorkspace.OpenFeatureClass(out_FeatureName);
                        if (pFCChecker != null)
                        {
                            IDataset pds = pFCChecker as IDataset;
                            pds.Delete();
                        }
                    }

                    //导出要素类
                    AddFeatureClass(EditLayer.FeatureClass, out_GDBPathName, out_FeatureName);

                    //关闭等待窗口
                    mainForm.CloseWaitInfo();

                    MessageBox.Show("导出成功!","提示");
                }
            }
            else
            {
                MessageBox.Show("图层未编辑!","提示");
            }
        }

	    /// <summary>
        /// 导出要素类
        /// </summary>
        /// <param name="pFeatureClass">要素类</param>
        /// <param name="out_GDBPathName">输出要素类路径</param>
        /// <param name="out_FeatureName">输出名称</param>
        private void AddFeatureClass(IFeatureClass pFeatureClass, string out_GDBPathName, string out_FeatureName)
        {
            //数据集添加要素
            Geoprocessor GP = new Geoprocessor();
            try
            {
                FeatureClassToFeatureClass featureClassToFeatureClass = new FeatureClassToFeatureClass();
                featureClassToFeatureClass.in_features = pFeatureClass;
                featureClassToFeatureClass.out_path = out_GDBPathName;
                featureClassToFeatureClass.out_name = out_FeatureName;
                GP.OverwriteOutput = false;
                IGeoProcessorResult pResult = new GeoProcessorResult();
                GP.Execute(featureClassToFeatureClass, null);
            }
            catch (Exception ex)
            {
                object sev = null;
                MessageBox.Show(GP.GetMessages(ref sev));
            }
        }

        /// <summary>
        /// 窗口关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleTopology_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (EditLayer != null)
            {
                if (ISEdit(EditLayer.FeatureClass))
                {
                    e.Cancel = true;

                    MessageBox.Show("请先停止编辑!");
                }
            }
            
        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王八八。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值