使用方式#
TopologyChecker topocheck = new TopologyChecker(mainlogyDataSet);
topocheck.PUB_TopoBuild("testTopo2");
topocheck.PUB_AddFeatureClass(null);
topocheck.PUB_AddRuleToTopology(TopologyChecker.TopoErroType.点要素之间不相交, (topocheck.PUB_GetAllFeatureClass())[2], (topocheck.PUB_GetAllFeatureClass())[0]);
axMapControl1.Map.AddLayer(topocheck.PUB_GetTopoLayer());
axMapControl1.ActiveView.Refresh();
实现类代码:注意修改命名空间#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.DataManagementTools;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace EngineWindowsApplication1
{
class TopologyChecker//功能:构建拓扑,拓扑检测
{
Geoprocessor GP_Tool = new Geoprocessor();
ITopology Topology;
IFeatureDataset FeatureDataset_Main;
List<IFeatureClass> LI_FeatureClass = new List<IFeatureClass>();
List<string> LI_AllErrorInfo = new List<string>();
ITopologyLayer L_TopoLayer;
#region 辅助函数
public ILayer PUB_GetTopoLayer()
{
if (L_TopoLayer == null)
{
L_TopoLayer = new TopologyLayerClass();
L_TopoLayer.Topology = Topology;
}
return L_TopoLayer as ILayer;
}
public TopologyChecker(IFeatureDataset IN_MainlogyDataSet)
{
FeatureDataset_Main = IN_MainlogyDataSet;
if (LI_FeatureClass.Count != 0)
LI_FeatureClass.Clear();
PUB_GetAllFeatureClass();
}
public List<IFeatureClass> PUB_GetAllFeatureClass()
{
if (LI_FeatureClass.Count == 0)
{
IFeatureClassContainer Temp_FeatureClassContainer = (IFeatureClassContainer)FeatureDataset_Main;
IEnumFeatureClass Temp_EnumFeatureClass = Temp_FeatureClassContainer.Classes;
IFeatureClass Temp_FeatureClass = Temp_EnumFeatureClass.Next();
while (Temp_FeatureClass != null)
{
LI_FeatureClass.Add(Temp_FeatureClass);
Temp_FeatureClass = Temp_EnumFeatureClass.Next();
}
if (LI_FeatureClass.Count == 0)
{
MessageBox.Show("空数据集!");
}
}
return LI_FeatureClass;
}
#endregion
#region 构建拓扑
public void PUB_TopoBuildWithGP(string IN_TopoName, double IN_Tolerance = 0.001)
{
IWorkspace FeatureWorkSpace = FeatureDataset_Main.Workspace;
ITopologyWorkspace TopoWorkSpace = FeatureWorkSpace as ITopologyWorkspace;
try
{
Topology = TopoWorkSpace.OpenTopology(IN_TopoName);
MessageBox.Show("已存在该拓扑,无法添加!");
}
catch
{
CreateTopology Topotool = new CreateTopology();
Topotool.in_dataset = FeatureDataset_Main; ;
Topotool.out_name = IN_TopoName;
Topotool.in_cluster_tolerance = IN_Tolerance;
try
{
GP_Tool.Execute(Topotool, null);
Topology = TopoWorkSpace.OpenTopology(IN_TopoName);
}
catch (COMException comExc)
{
MessageBox.Show(String.Format("拓扑创建出错: {0} 描述: {1}", comExc.ErrorCode, comExc.Message));
}
}
}
public void PUB_TopoBuild(string IN_TopoName, double IN_Tolerance = 0.001)
{
ITopologyContainer topologyContainer = (ITopologyContainer)FeatureDataset_Main;
try
{
Topology = topologyContainer.get_TopologyByName(IN_TopoName);
MessageBox.Show("已存在该拓扑,无法添加!");
}
catch
{
try
{
Topology = topologyContainer.CreateTopology(IN_TopoName, IN_Tolerance, -1, "");
}
catch (COMException comExc)
{
MessageBox.Show(String.Format("拓扑创建出错: {0} 描述: {1}", comExc.ErrorCode, comExc.Message));
}
}
}
#endregion
#region 添加要素类
public void PUB_AddFeatureClassWithGP(List<IFeatureClass> IN_TopologyClass, int IN_XYRank = 1, int IN_ZRank = 1)
{
if (Topology != null)
{
AddFeatureClassToTopology Temp_AddClassToTopo = new AddFeatureClassToTopology();
Temp_AddClassToTopo.in_topology = Topology;
Temp_AddClassToTopo.xy_rank = IN_XYRank;
Temp_AddClassToTopo.z_rank = IN_ZRank;
if (IN_TopologyClass == null)
{
IN_TopologyClass = LI_FeatureClass;
}
foreach (IFeatureClass EachFeatureCLS in IN_TopologyClass)
{
if (LI_FeatureClass.Contains(EachFeatureCLS))
{
Temp_AddClassToTopo.in_featureclass = EachFeatureCLS;
try
{
GP_Tool.Execute(Temp_AddClassToTopo, null);
}
catch (COMException comExc)
{
MessageBox.Show(String.Format(((FeatureClass)EachFeatureCLS).Name + ":添加失败。 描述: {0}", comExc.Message));
}
}
else
{
MessageBox.Show("该要素类不属于目标要素集,无法添加!");
}
}
}
else
{
MessageBox.Show("请先构建拓扑");
}
}
public void PUB_AddFeatureClass(List<IFeatureClass> IN_TopologyClass, int IN_XYRank = 1, int IN_ZRank = 1, double IN_Weight = 5)
{
if (Topology != null)
{
if (IN_TopologyClass == null)
{
IN_TopologyClass = LI_FeatureClass;
}
foreach (IFeatureClass EachFeatureCLS in IN_TopologyClass)
{
if (LI_FeatureClass.Contains(EachFeatureCLS))
{
try
{
Topology.AddClass(EachFeatureCLS as IClass, IN_Weight, IN_XYRank, IN_ZRank, false);
}
catch (COMException comExc)
{
MessageBox.Show(String.Format(((FeatureClass)EachFeatureCLS).Name + ":添加失败。 描述: {0}", comExc.Message));
}
}
else
{
MessageBox.Show("该要素类不属于目标要素集,无法添加!");
}
}
}
else
{
MessageBox.Show("请先构建拓扑");
}
}
#endregion
#region 添加规则并检验
private void PRV_ValidateTopologyWithGP()
{
try
{
ValidateTopology Temp_Validate = new ValidateTopology(Topology);
GP_Tool.Execute(Temp_Validate, null);
}
catch
{
MessageBox.Show("无法完成检测!");
}
}
public void PUB_AddRuleToTopology(TopoErroType IN_RuleType, IFeatureClass IN_FeatureClass)
{
if (Topology != null)
{
ITopologyRule Temp_TopologyRule = new TopologyRuleClass();
Temp_TopologyRule.TopologyRuleType = PRV_ConvertTopologyRuleType(IN_RuleType);
Temp_TopologyRule.Name = IN_RuleType.ToString();
Temp_TopologyRule.OriginClassID = IN_FeatureClass.FeatureClassID;
Temp_TopologyRule.AllOriginSubtypes = true;
PRV_AddRuleTool(Temp_TopologyRule);
}
else
{
MessageBox.Show("请先构建拓扑");
}
}
public void PUB_AddRuleToTopology(TopoErroType IN_RuleType, IFeatureClass IN_FeatureClassA, IFeatureClass IN_FeatureClassB)
{
if (Topology != null)
{
ITopologyRule Temp_TopologyRule = new TopologyRuleClass();
Temp_TopologyRule.TopologyRuleType = PRV_ConvertTopologyRuleType(IN_RuleType);
Temp_TopologyRule.Name = IN_RuleType.ToString();
Temp_TopologyRule.OriginClassID = IN_FeatureClassA.FeatureClassID;
Temp_TopologyRule.DestinationClassID = IN_FeatureClassB.FeatureClassID;
Temp_TopologyRule.AllOriginSubtypes = true;
Temp_TopologyRule.AllDestinationSubtypes = true;
PRV_AddRuleTool(Temp_TopologyRule);
}
else
{
MessageBox.Show("请先构建拓扑");
}
}
private void PRV_AddRuleTool(ITopologyRule IN_TopologyRule)
{
ITopologyRuleContainer Temp_TopologyRuleContainer = (ITopologyRuleContainer)Topology;
try
{
Temp_TopologyRuleContainer.get_CanAddRule(IN_TopologyRule);
try
{
Temp_TopologyRuleContainer.DeleteRule(IN_TopologyRule);
Temp_TopologyRuleContainer.AddRule(IN_TopologyRule);
}
catch
{
Temp_TopologyRuleContainer.AddRule(IN_TopologyRule);
}
}
catch
{
MessageBox.Show("不支持添加");
}
PRV_ValidateTopologyWithGP();
PUB_GetTopoLayer();
PRV_GetError(IN_TopologyRule);
}
private void PRV_GetError(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(((IGeoDataset)FeatureDataset_Main).SpatialReference, IN_TopologyRule, Temp_Envolope, true, true);
ITopologyErrorFeature Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
while (Temp_ErrorFeature != null)
{
IFeature Temp_Feature = Temp_ErrorFeature as IFeature;
string Temp_ErrorInfo;
if (Temp_ErrorFeature.DestinationClassID != 0)
{
Temp_ErrorInfo = Temp_ErrorFeature.OriginOID + "," + Temp_ErrorFeature.DestinationOID;
}
else
Temp_ErrorInfo = Temp_ErrorFeature.OriginOID.ToString();
LI_AllErrorInfo.Add(Temp_ErrorInfo);
MessageBox.Show("错误:" + PRV_RecorverTopologyRuleType((int)(Temp_ErrorFeature.TopologyRuleType)) + "\r\n错误ID:" + Temp_ErrorInfo);
Temp_ErrorFeature = Temp_EnumErrorFeature.Next();
}
}
else
{
MessageBox.Show("请先构建拓扑");
}
}
public List<string> PUB_GetErrorInfo()
{
return LI_AllErrorInfo;
}
#region 规则翻译
private esriTopologyRuleType PRV_ConvertTopologyRuleType(TopoErroType IN_TopoRuleType)
{
esriTopologyRuleType Temp_TopoRuleType;
switch (IN_TopoRuleType)
{
case TopoErroType.面要素之间无空隙:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaNoGaps;
break;
case TopoErroType.任何规则:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAny;
break;
case TopoErroType.要素大于最小容差:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTFeatureLargerThanClusterTolerance;
break;
case TopoErroType.面要素间无重叠:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaNoOverlap;
break;
case TopoErroType.第二个图层面要素必须被第一个图层任一面要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaCoveredByAreaClass;
break;
case TopoErroType.面要素必须只包含一个点要素:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaContainOnePoint;
break;
case TopoErroType.两图层面要素必须互相覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaAreaCoverEachOther;
break;
case TopoErroType.第一个图层面要素必须被第一个图层任一面要素包含:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaCoveredByArea;
break;
case TopoErroType.图层间面要素不能相互覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaNoOverlapArea;
break;
case TopoErroType.线要素必须跟面图层边界的一部分或全部重叠:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineCoveredByAreaBoundary;
break;
case TopoErroType.点要素必须落在面要素边界上:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTPointCoveredByAreaBoundary;
break;
case TopoErroType.点要素必须落在面要素内:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTPointProperlyInsideArea;
break;
case TopoErroType.线要素间不能有相互重叠部分:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoOverlap;
break;
case TopoErroType.线要素之间不能相交:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoIntersection;
break;
case TopoErroType.线要素不允许有悬挂点:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoDangles;
break;
case TopoErroType.线要素不允许有假节点:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoPseudos;
break;
case TopoErroType.第一个图层线要素应被第二个线图层线要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineCoveredByLineClass;
break;
case TopoErroType.第一个图层线要素不被第二个线图层线要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoOverlapLine;
break;
case TopoErroType.点要素应被线要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTPointCoveredByLine;
break;
case TopoErroType.点要素应在线要素的端点上:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTPointCoveredByLineEndpoint;
break;
case TopoErroType.面要素边界必须被线要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaBoundaryCoveredByLine;
break;
case TopoErroType.面要素的边界必须被另一面要素边界覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaBoundaryCoveredByAreaBoundary;
break;
case TopoErroType.线要素不能自重叠:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoSelfOverlap;
break;
case TopoErroType.线要素不能自相交:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoSelfIntersect;
break;
case TopoErroType.线要素间不能重叠和相交:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoIntersectOrInteriorTouch;
break;
case TopoErroType.线要素端点必须被点要素覆盖:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineEndpointCoveredByPoint;
break;
case TopoErroType.面要素内必须包含至少一个点要素:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAreaContainPoint;
break;
case TopoErroType.线不能是多段:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoMultipart;
break;
case TopoErroType.点要素之间不相交:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTPointDisjoint;
break;
case TopoErroType.线要素必须不相交:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoIntersectLine;
break;
case TopoErroType.线必须不相交或内部接触:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTLineNoIntersectOrInteriorTouchLine;
break;
default:
Temp_TopoRuleType = esriTopologyRuleType.esriTRTAny;
break;
}
return Temp_TopoRuleType;
}
public enum TopoErroType
{
任何规则=-1,
要素大于最小容差 = 0,
面要素之间无空隙 = 1,
面要素间无重叠 = 3,
第二个图层面要素必须被第一个图层任一面要素覆盖 = 4,
两图层面要素必须互相覆盖 = 5,
第一个图层面要素必须被第一个图层任一面要素包含 = 7,
图层间面要素不能相互覆盖 = 8,
线要素必须跟面图层边界的一部分或全部重叠 = 10,
线要素必须在面内=11,
点要素必须落在面要素边界上 = 13,
点要素必须落在面要素内 = 15,
面要素必须只包含一个点要素=16,
线要素间不能有相互重叠部分 = 19,
线要素之间不能相交 = 20,
线要素不允许有悬挂点 = 21,
线要素不允许有假节点 = 22,
第一个图层线要素应被第二个线图层线要素覆盖 = 26,
第一个图层线要素不被第二个线图层线要素覆盖 = 28,
点要素应被线要素覆盖 = 29,
点要素应在线要素的端点上 = 31,
点要素之间不相交=34,
点要素重合点要素=35,
面要素边界必须被线要素覆盖 = 37,
面要素的边界必须被另一面要素边界覆盖 = 38,
线要素不能自重叠 = 39,
线要素不能自相交 = 40,
线要素间不能重叠和相交 = 41,
线要素端点必须被点要素覆盖 = 42,
面要素内必须包含至少一个点要素 = 43,
线不能是多段 = 44,
线要素必须不相交=45,
线必须不相交或内部接触=46
};
private string PRV_RecorverTopologyRuleType(int IN_TopoType)
{
string Temp_ErrorDiscripe=Enum.GetName(typeof(TopoErroType), IN_TopoType);
if (Temp_ErrorDiscripe == null)
return (IN_TopoType.ToString());
else
return Temp_ErrorDiscripe;
}
#endregion
#endregion
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?