一、实现代码
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("请先停止编辑!");
}
}
}
}
}