ArcEngine 拓扑检查 总结

2024-08-28 13:18
文章标签 总结 检查 拓扑 arcengine

本文主要是介绍ArcEngine 拓扑检查 总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ArcEngine 拓扑检查 总结

本文大部分内容参考AO帮助文档和ArcMap帮助文档,大家实际使用中遇到的问题也可以在本帖下方留言交流,谢谢!

欢迎浏览,拒绝转载!


拓扑基础知识

  1. 拓扑的基础知识

拓扑检查常用的方法

调用GP工具(CheckGeometry)检查数据的几何

  • CheckGeometry的相关说明
    CheckGeometry工具官方说明链接地址
  • CheckGeometry质检项
    这里写图片描述
  • CheckGeometry调用示例代码
ESRI.ArcGIS.Geoprocessor.Geoprocessor geoProcessor = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
ESRI.ArcGIS.DataManagementTools.CheckGeometry checkGeometryTool = new ESRI.ArcGIS.DataManagementTools.CheckGeometry();
checkGeometryTool.in_features = otherPara[0];
checkGeometryTool.out_table = otherPara[1];
IGeoProcessorResult gpResult = geoProcessor.Execute(checkGeometryTool, null) as IGeoProcessorResult;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 建议使用范围
    有效的输入格式包括 shapefile 以及存储在个人地理数据库或文件地理数据库中的要素类。而 SDE 地理数据库则会在上传几何时自动检查每个几何的有效性;因此,检查几何和修复几何工具无需用于 SDE
    缺点:使用该GP工具会生成检查结果图层,检查的几何错误种类相对固定,对于复杂的拓扑错误不支持。
    优点:代码相对简单,适合对拓扑检查规则不是很复杂的入库级别的检查。

调用ITopologicalOperator5接口进行拓扑检查

  • ITopologicalOperator5接口相关说明
    Provides access to members for constructing new geometries based upon topological relationships between existing geometries.
    这里写图片描述
  • ITopologicalOperator5常用方法
    这里写图片描述
  • ITopologicalOperator5示例代码
IPointCollection polygonVertices = new PolygonClass();
IPointCollection lineVertices = pGeometry as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
ITopologicalOperator3 pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections;    //自相交
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{   if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections){//记录拓扑错误}
}
  • 参考资料
    ArcEngine 空间分析相关代码
  • 建议使用范围
    这个接口类似ArcMap中编辑工具条中的验证功能,只能针对要素进行逐个检查,个人觉得如果图层中要素不多的话 可以使用此接口进行拓扑检查,如果图层中要素比较多,数据量比较大,建议使用GP工具或者创建拓扑进行检查,个人建议仅供参考,如果异议请留言!

通过接口创建拓扑进行拓扑检查

  • 拓扑基础知识
    一个拓扑可以添加多个拓扑图层,一个要素数据集可以拥有多个拓扑,但是一个要素类(图层)只能在一个拓扑中并且只有简单的要素类才能添加到拓扑中进行拓扑检查。
    参考链接:ArcObjects Topology官方教材
  • 常用接口
    ITopologyContainer2接口:
    这里写图片描述

  • 创建拓扑
    用到的方法:
    1.ITopologyContainer.CreateTopology
    2.ITopologyContainer2.CreateTopologyEx
    这两个方法的返回类型都是ITopology 对象
    示例代码1:

// featureDataset is an IFeatureDataset where the topology will be located.
// specifyZClusterTolerance is a System.Boolean whether a ZClusterTolerance has been specified.
// topologyName is a string with the topology's name.// Cast the feature dataset to the ITopologyContainer2 interface to create a topology.
//下面代码大概意思是如果需要z容差用CreateTopologyEx方法,不需要z容差用CreateTopology方法
ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset;
ITopology topology = null;
if (specifyZClusterTolerance)
{topology = topologyContainer.CreateTopologyEx(topologyName,topologyContainer.DefaultClusterTolerance,topologyContainer.DefaultZClusterTolerance,  - 1, "");
}else
{topology = topologyContainer.CreateTopology(topologyName,topologyContainer.DefaultClusterTolerance,  - 1, "");
}
  • 示例代码2:

    IFeatureDataset featureDataset = featureClass.FeatureDataset;
    ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset;
    if (topologyContainer == null)
    {return true;
    }
    //判断当前命名的拓扑是否存在,如果存在,删除
    bool bTopExists = (featureDataset.Workspace as IWorkspace2).get_NameExists(esriDatasetType.esriDTTopology, sTopologyName);
    if (bTopExists)
    {ITopology topologyTemp = topologyContainer.get_TopologyByName(sTopologyName);//删除拓扑IDataset pDatasetTemp = (IDataset)topologyTemp;pDatasetTemp.Delete();Marshal.ReleaseComObject(pDatasetTemp);
    }//创建一个新的拓扑
    if (dTolerance == -1)
    {dTolerance = topologyContainer.DefaultClusterTolerance;
    }
    //ITopology topology = topologyContainer.CreateTopology(sTopologyName, topologyContainer.DefaultClusterTolerance, -1, "");
    ITopology topology = topologyContainer.CreateTopology(TopologyName, dTolerance, -1, "");
      • 添加图层和拓扑规则
        用到的方法:
        1.ITopology.AddClass
        2.ITopologyRuleContainer.AddRule

        示例代码1:

      //添加拓扑图层
      topology.AddClass(featureClass, weight, xyRank, zRank, false);
      //添加拓扑规则
      public 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;//把topology对象强制转换到ITopologyRuleContainer对象,然后添加拓扑规则ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;if (topologyRuleContainer.get_CanAddRule(topologyRule)){topologyRuleContainer.AddRule(topologyRule);}else{throw new ArgumentException("Could not add specified rule to the topology.");}
      }

      示例代码2:The following code example demonstrates how to create a topology rule between two feature classes, specify it at the subtype level for the destination, and add it to the topology:

      public void AddRuleToTopology(ITopology topology, esriTopologyRuleType ruleType,String ruleName, IFeatureClass originClass, int originSubtype, IFeatureClassdestinationClass, int destinationSubtype)
      {// Create a topology rule.ITopologyRule topologyRule = new TopologyRuleClass();topologyRule.TopologyRuleType = ruleType;topologyRule.Name = ruleName;topologyRule.OriginClassID = originClass.FeatureClassID;topologyRule.AllOriginSubtypes = false;topologyRule.OriginSubtype = originSubtype;topologyRule.DestinationClassID = destinationClass.FeatureClassID;topologyRule.AllDestinationSubtypes = false;topologyRule.DestinationSubtype = destinationSubtype;// Cast the topology to the ITopologyRuleContainer interface and add the rule.ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;if (topologyRuleContainer.get_CanAddRule(topologyRule)){topologyRuleContainer.AddRule(topologyRule);}else{throw new ArgumentException("Could not add specified rule to the topology.");}
      }
      • 验证拓扑
        用到的方法:
        1.ITopology.ValidateTopology

        示例代码1:

      public void ValidateTopology(ITopology topology, IEnvelope envelope)
      {// Get the dirty area within the provided envelope.IPolygon locationPolygon = new PolygonClass();ISegmentCollection segmentCollection = (ISegmentCollection)locationPolygon;segmentCollection.SetRectangle(envelope);IPolygon polygon = topology.get_DirtyArea(locationPolygon);// If a dirty area exists, validate the topology.if (!polygon.IsEmpty){// Define the area to validate and validate the topology.IEnvelope areaToValidate = polygon.Envelope;IEnvelope areaValidated = topology.ValidateTopology(areaToValidate);}
      }

      示例代码2:完整的创建拓扑函数

      public void CreateTopology()
      {// Open the workspace and the required datasets.Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);IWorkspace workspace = workspaceFactory.OpenFromFile(@"C:\arcgis\ArcTutor\BuildingaGeodatabase\Montgomery.gdb", 0);IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset("Landbase");IFeatureClass blocksFC = featureWorkspace.OpenFeatureClass("Blocks");IFeatureClass parcelsFC = featureWorkspace.OpenFeatureClass("Parcels");// Attempt to acquire an exclusive schema lock on the feature dataset.ISchemaLock schemaLock = (ISchemaLock)featureDataset;try{schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);// 创建拓扑ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset;ITopology topology = topologyContainer.CreateTopology("Landbase_Topology",topologyContainer.DefaultClusterTolerance,  - 1, "");//添加要素类到拓扑中topology.AddClass(blocksFC, 5, 1, 1, false);topology.AddClass(parcelsFC, 5, 1, 1, false);AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, "No Block Overlap", blocksFC);AddRuleToTopology(topology,esriTopologyRuleType.esriTRTAreaCoveredByAreaClass, "ResParcels Covered by ResBlocks", parcelsFC, 1, blocksFC, 1);// 获取验证拓扑的范围并且验证拓扑IGeoDataset geoDataset = (IGeoDataset)topology;IEnvelope envelope = geoDataset.Extent;ValidateTopology(topology, envelope);}catch (COMException comExc){throw new Exception(String.Format("Error creating topology: {0} Message: {1}", comExc.ErrorCode,comExc.Message), comExc);}finally{schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);}
      }
      • 读取拓扑结果
        通过 ITopology.State属性可以用来检查“拓扑中的错误要素是否存在”,他返回一个esriTopologyState枚举对象,如果拓扑已经被验证过并且发现了拓扑错误,那么返回 esriTSAnalyzedWithErrors 。
        这里写图片描述
        用到的接口:
        1.ITopology
        2.ITopologyRuleContainer
        3.IErrorFeatureContainer
        4.ITopologyErrorFeature
        示例代码1:
      //打开拓扑
      public ITopology OpenTopologyFromFeatureWorkspace(IFeatureWorkspace featureWorkspace,String featureDatasetName, String topologyName)
      {//打开数据集IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(featureDatasetName);//获取拓扑容器ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset;//打开拓扑ITopology topology = topologyContainer.get_TopologyByName(topologyName);return topology;
      }//显示拓扑规则
      public void DisplayTypesForEachRule(ITopology topology)
      {ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;IEnumRule enumRule = topologyRuleContainer.Rules;// 遍历拓扑规则.    enumRule.Reset();    IRule rule = null;while ((rule = enumRule.Next()) != null)    {ITopologyRule topologyRule = (ITopologyRule)rule;Console.WriteLine("Rule type: {0}", topologyRule.TopologyRuleType);}
      }
      

      1)根据拓扑错误读取错误要素
      主要利用属性:IErrorFeatureContainer.ErrorFeatures

      //给定拓扑和拓扑规则,返回指定规则的错误要素
      public void DisplayErrorFeaturesForRule(ITopology topology, ITopologyRule topologyRule)
      {IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology;IGeoDataset geoDataset = (IGeoDataset)topology;ISpatialReference spatialReference = geoDataset.SpatialReference;//遍历含有拓扑错误的要素IEnumTopologyErrorFeature enumTopologyErrorFeature =errorFeatureContainer.get_ErrorFeatures(spatialReference, topologyRule,geoDataset.Extent, true, false);// 显示每个错误要素的原始IDITopologyErrorFeature topologyErrorFeature = null;while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null){Console.WriteLine("Origin feature OID: {0}", topologyErrorFeature.OriginOID);}
      }

      2)根据几何读取错误要素
      主要利用属性:IErrorFeatureContainer.ErrorFeaturesByGeometryType

      //给定拓扑和几何类型,返回指定规则的错误要素
      public void DisplayErrorFeatureByGeometryType(ITopology topology, esriGeometryTypegeometryType)
      {//获取坐标系IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology;IGeoDataset geoDataset = (IGeoDataset)topology;ISpatialReference spatialReference = geoDataset.SpatialReference;//遍历拓扑错误IEnumTopologyErrorFeature enumTopologyErrorFeature =errorFeatureContainer.get_ErrorFeaturesByGeometryType(spatialReference,geometryType, false);//显示错误要素的信息ITopologyErrorFeature topologyErrorFeature = null;while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null){Console.WriteLine("Error Feature Origin Class ID: {0}",topologyErrorFeature.OriginClassID);Console.WriteLine("Error Feature Origin Feature ID: {0}",topologyErrorFeature.OriginOID);Console.WriteLine("Error Feature Dest. Class ID: {0}",topologyErrorFeature.DestinationClassID);Console.WriteLine("Error Feature Dest. Feature ID: {0}",topologyErrorFeature.DestinationOID);}
      }

      3)根据拓扑规则类型读取错误要素
      主要利用属性: IErrorFeatureContainer.ErrorFeaturesByRuleType

      //给定拓扑和拓扑规则类型,返回指定规则的错误要素
      public void DisplayErrorFeatureByRuleType(ITopology topology, esriTopologyRuleTypetopologyRuleType)
      {//获取坐标系IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology;IGeoDataset geoDataset = (IGeoDataset)topology;ISpatialReference spatialReference = geoDataset.SpatialReference;//返回指定范围内所有的错误要素,然后检索在第一个错误要素上IEnumTopologyErrorFeature enumTopologyErrorFeature =errorFeatureContainer.get_ErrorFeaturesByRuleType(spatialReference,topologyRuleType, geoDataset.Extent, true, false);// 如果存在则获取第一个错误要素并且显示它的属性ITopologyErrorFeature topologyErrorFeature = enumTopologyErrorFeature.Next();if (topologyErrorFeature != null){Console.WriteLine("Error Feature Origin Class ID: {0}",topologyErrorFeature.OriginClassID);Console.WriteLine("Error Feature Origin Feature ID: {0}",topologyErrorFeature.OriginOID);Console.WriteLine("Error Feature Dest. Class ID: {0}",topologyErrorFeature.DestinationClassID);Console.WriteLine("Error Feature Dest. Feature ID: {0}",topologyErrorFeature.DestinationOID);}
      }

      4)单独访问错误要素
      主要利用属性:IErrorFeatureContainer.ErrorFeature
      相关参数说明:
      GeometryType—Geometry type of the error feature requested
      OriginClassID—Class ID of the feature class to which the rule is applied
      OriginOID—ObjectID of the origin feature causing the error
      DestinationClassID—Class ID of the feature class in which the rule interacts
      DestinationOID—ObjectID of the destination feature causing the error

      //返回面互相压盖拓扑错误的要素
      public ITopologyErrorFeature GetErrorFeatureForNoOverlapRule(ITopology topology, IFeatureClass featureClass, int originFeatureOID, int destFeatureOID)
      {// 获取坐标系IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology;IGeoDataset geoDataset = (IGeoDataset)topology;ISpatialReference spatialReference = geoDataset.SpatialReference;// 找到拓扑错误要素并返回ITopologyErrorFeature topologyErrorFeature = errorFeatureContainer.get_ErrorFeature(spatialReference, esriTopologyRuleType.esriTRTAreaNoOverlap,esriGeometryType.esriGeometryPolygon, featureClass.FeatureClassID, originFeatureOID, featureClass.FeatureClassID, destFeatureOID);return topologyErrorFeature;
      }

      5)根据范围读取拓扑错误要素

      //给定拓扑和查找的范围,返回所有的拓扑错误要素
      public void FindAllErrorFeatures(ITopology topology, IEnvelope searchExtent)
      {//获取坐标系IErrorFeatureContainer errorFeatureContainer = (IErrorFeatureContainer)topology;IGeoDataset geoDataset = (IGeoDataset)topology;ISpatialReference spatialReference = geoDataset.SpatialReference;ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;//遍历拓扑规则IEnumRule enumRule = topologyRuleContainer.Rules;enumRule.Reset();IRule rule = null;while ((rule = enumRule.Next()) != null){//获取当前拓扑规则的拓扑错误并遍历ITopologyRule topologyRule = (ITopologyRule)rule;IEnumTopologyErrorFeature enumTopologyErrorFeature = errorFeatureContainer.get_ErrorFeatures(spatialReference, topologyRule, searchExtent, true, true);ITopologyErrorFeature topologyErrorFeature = null;while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null){//显示错误要素的信息Console.WriteLine("Class ID: {0} Object ID: {0} IsException {0}", topologyErrorFeature.OriginClassID, topologyErrorFeature.OriginOID,topologyErrorFeature.IsException);}}
      }
      • 拓扑验证监听
        这块就不赘述了,请参考AO本地文档!
        这里写图片描述

      • 建议使用范围
        对拓扑规则要求比较多的、比较细的、图层数据量较大的优先考虑创建拓扑,个人建议仅供参考,如果异议请留言!

      • 注意事项
        创建拓扑时需要考虑COM对象的释放,如果释放不干净创建的拓扑可能会删除不掉。如果觉得麻烦还可以拷贝数据再创建拓扑获取拓扑错误,个人建议仅供参考,如果异议请留言!

      通过拓扑工具箱GP调用进行拓扑检查

      • 拓扑工具箱
        拓扑常用的GP工具位置:Data Management Tools ->Topology
        这里写图片描述
        具体每个工具是干什么的,不懂的看看翻译、看看帮助,这块我就不赘述了。

      本文大部分内容参考AO帮助文档和ArcMap帮助文档,大家实际使用中遇到的问题也可以在本帖下方留言交流,谢谢!

      欢迎浏览,拒绝转载!

这篇关于ArcEngine 拓扑检查 总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114872

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa