Arcgis Engine的拓扑检查类

2023-10-11 21:45

//Arcgis Engine的拓扑检查类
//转载至https://www.dnf01.com/ParanoiaApe/p/8729315.html
//主要添加构建Topology ,向拓扑添加元素、添加规则、输出拓扑错误的功能。 ? .PUB_AddFeatureClass(null); // 将本元素中的所有元素添加到拓扑中
// 添加规则
www.dnf01.com_addruletotopology (TopologyChecker.topoerrotype.ass ()) [2], (Topocheck.P​​UB_GetAllFeatureClass())[0]);
                                                                                                                                                       ​​​​ axMapControl1.ActiveView.Refresh();

使用系统;
使用 System.Collections;
使用 System.Collections.Generic;
使用 System.Linq;地理信息系统。地理数据库;
使用 ESRI.ArcGIS.DataSourcesGDB;
使用 ESRI.ArcGIS.Geometry;
u唱 ESRI.ArcGIS.Carto;
使用 ESRI.ArcGIS.Geoprocessor;
使用 ESRI.ArcGIS.DataManagementTools;
使用 System.Windows.Forms;
使用 System.Runtime.InteropServices;

namespace EngineWindowsApplication1
{ class TopologyChecker//功能:构建拓扑,拓扑检测
{

    Geoprocessor GP_Tool = new Geoprocessor();//GP运行工具
    ITopology Topology;//生成的拓扑
     IFeatureDataset FeatureDataset_Main;//拓扑所在的要素数据集所属 列表 LI_FeatureClass = new List();//要素数据集中包含的所有要素类
List LI_AllErrorInfo = new List();//记录所有错误信息
ITopologyLay呃 L_TopoLayer ;//记录拓扑的层

                /// 拓扑层Ilayer
                            PUB_GetTopoLayer()
L_TopoLayer = new TopologyLayerClass();
               L_TopoLayer.Topology = 拓扑;返回 L_TopoLayer 作为 ILayer;
}

                                                                      '' ' ' ' ' s     ‐输入要素数据集
      public TopologyChecker(IFeatureDataset IN_MainlogyDataSet)
    {
            FeatureDataset_Main = IN_Mainlogy数据集;
                                                                                                                                                                                    ‐ ‐‐‐‐ ?

                                                                                                                                                                                                                                                                                                       PUB_GetAllFeatureClass()
IFeatureClassContainer Temp_FeatureClassContainer = (IFeatureClassContainer)FeatureDataset_Main;
                IEnumFeatureClass Temp_EnumFeatureClass = Temp_FeatureClassContainer.Classes;
                IFeatureClass Temp_FeatureClass = Temp_www.dnf01.com();

 

                while (Temp_FeatureClass != null)
                {
                    LI_FeatureClass.Add(Temp_FeatureClass);
                    Temp_FeatureClass = Temp_www.dnf01.com();
                }
                if (LI_FeatureClass.Count == 0 )
                {
www.dnf01.com("数据集为空!");

                                                                                                                                                     的返回 LI_FeatureClass 的;

               #region 构建拓扑

                                                                                                                                                                                              // / 构造数据集中的拓扑(GP方法)
                                         ///
/// 拓扑容差,可选,默认 0.001
Public void pub_topobuildwithgp (string in_toponame, double in_tolate = 0.001) {
iWorkspace FeatureWorkWorkspaceData = FeatureData set_main.Workspace;
itopologyworkSpaceSpaceSpace = FeatureworkSpace as itOPOLOGYWORKSPACE; ​www.dnf01.com("该拓扑已存在,无法添加!");
}
                                                                                                                                                                                                                                            ​CreateTopology Topotool = new CreateTopology(); //拓扑GP工具
                      www.dnf01.com_dataset = FeatureDataset_Main; www.dnf01.com_cluster_tolerance = IN_Tolerance;
Try
{ L gp_tool.execute (Topotool, NULL);
拓扑 = TopoworkSpace.opentopology (in_toponame);
}
(COMEXCEPTION COMEXC) {
message www.dnf01.com(String.Format("创建拓扑时出错:{0}说明:{1}", comExc.ErrorCode, comExc.Message));

//////// 在数据集中构建拓扑
/////// ,生成拓扑名称
/// 拓扑容差,可选,默认 0.001 Public void pub_topobuild (String in_toponame, Double in_TOLARANCE = 0.001) {
{
ITopologyContainer topologyContainer = (ITopologyContainer)FeatureDataset_Main;
try//如果同名拓扑不存在,则添加
{
Topology = topologyContainer.get _TopologyByName(IN_TopoName);
         消息框.Show( “拓扑已存在,无法添加!”); Om Catch (COMEXCEPTION COMEXC)
{
​​}
          }

          #endregion

           #region 添加要素类

                                                                                                                                                                                                                                                           。对此数据集中的所有要素类
输入 null /// XY 级别,默认值为 1。可选。
      /// Z 级别,默认为 1。可选。 " if (拓扑!= null)
AddFeatureClassToTopology Temp_AddClassToTopo = new AddFeatureClassToTopology();
                Temp_www.dnf01.com_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_www.dnf01.com_featureclass = EachFeatureCLS;
                        尝试
                        {
GP_Tool.Execute(Temp_AddClassToTopo, null);自描述:{0}", comExc.Message));
                                                                                                              
                                                                                                                                                                                                                                                                   );
                                                                                                                            {
www.dnf01.com("请先构建拓扑");


                                                                                       。对此数据集中的所有要素类
输入 null /// XY 级别,默认值为 1。可选。
      /// Z 级别,默认为 1。可选。
/// 权重,默认为 5。可选。​如果(拓扑!= null)
                                               (IN_TopologyClass == null)
                                                                                                                                                                                                                                                                 ​                                                                                                                                                 LI_FeatureClass。 Contains(EachFeatureCLS))//只能添加同一特征数据集中的特征
                                                                                                                                                       {
Topology.AddClass(EachFeatureCLS as IClass, IN_Weight, IN_XYRank, IN_ZRank, false); * .名称 + ":添加失败。说明: {0}", comExc.Message));
                                       else
                                                                                                                                                                                                                                                                                            自 目标功能集以来无法添加!");
                                         else
                                                                                                                                                                                                               

                                                             添加规则并验证
                                                                                                                          尝试
ValidateTopology Temp_Validate = new ValidateTopology(Topology);
                         catch
                                                                                                                                                                                                                   |

|                     /// 添加规则要素类 ; {
ITopologyRule Temp_TopologyRule = new TopologyRuleClass();                  Temp_www.dnf01.com = IN_RuleType.ToString();
                                   FeatureClassID;
                          Temp_TopologyRule.AllOriginSubtypes = true; }
                                                                                                                                                                                                                                                                                                            
        }

                                                                                                                                                                                                                                       /// 第一个元素
                                                                                                             {
if (Topology != null)
            {
                ITopologyRule Temp_TopologyRule = new TopologyRuleClass();
          参数     // 设置
                Temp_TopologyRule.TopologyRuleType = PRV_ConvertTopologyRuleType(IN_RuleType);
                Temp_www.dnf01.com = 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
            {
                www.dnf01.com("请先构建拓扑") ;
            }
   
        }

 

        //规则添加工具
        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
                {
                    www.dnf01.com("不支持添加");
                }
                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_www.dnf01.com();
                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);//将错误信息加入List
                    www.dnf01.com("错误:" + PRV_RecorverTopologyRuleType((int)(Temp_ErrorFeature.TopologyRuleType)) + "\r\n错误ID:" + Temp_ErrorInfo);
                    Temp_ErrorFeature = Temp_www.dnf01.com();
                }
            }
            else
            {
                www.dnf01.com("请先构建拓扑");
            }
        }

 

        ///


        /// 提取所有拓扑错误信息
        ///

        /// 错误信息集合
        public List PUB_GetErrorInfo()
        {
            return LI_AllErrorInfo;
        }

 

        #region 规则翻译

 

        //根据错误的中文描述转换成esri拓扑枚举
        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
        };

 

        //根据错误ID获取对应描述
        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
      
    }
}