You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							318 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
	
	
							318 lines
						
					
					
						
							13 KiB
						
					
					
				using System; | 
						|
using System.Collections.Generic; | 
						|
using System.Data; | 
						|
using System.IO; | 
						|
using System.Linq; | 
						|
using System.Runtime.InteropServices; | 
						|
using System.Text; | 
						|
using System.Threading; | 
						|
using ESRI.ArcGIS.esriSystem; | 
						|
using ESRI.ArcGIS.Geodatabase; | 
						|
using ESRI.ArcGIS.Geometry; | 
						|
 | 
						|
namespace Kingo.PluginServiceInterface.Helper | 
						|
{ | 
						|
    /// <summary> | 
						|
    /// 拓扑帮助类 | 
						|
    /// </summary> | 
						|
    public class DataCheckTopologyHelper | 
						|
    { | 
						|
        /// <summary> | 
						|
        /// 返回true表示面图层内存在重叠 | 
						|
        /// </summary> | 
						|
        /// <param name="lstTopologyRule"></param> | 
						|
        /// <param name="m_Workspace"></param> | 
						|
        /// <param name="lstFeatureClassTabelName"></param> | 
						|
        /// <param name="objectName"></param> | 
						|
        /// <returns></returns> | 
						|
        public static bool CreateTopology(List<ITopologyRule> lstTopologyRule, IWorkspace m_Workspace, List<string> lstFeatureClassTabelName, string objectName = "TDBZSJJ") | 
						|
        { | 
						|
            double tolerance = 0.0001; | 
						|
            IFeatureDataset pFeatDS = null; | 
						|
            ISchemaLock schemalock = null; | 
						|
            ITopology topology = null; | 
						|
            try | 
						|
            { | 
						|
                if (m_Workspace == null) | 
						|
                    throw new Exception("获取默认工作空间为空!"); | 
						|
 | 
						|
                pFeatDS = GetFeatureDatasetByName(m_Workspace, objectName); | 
						|
                if (pFeatDS == null) | 
						|
                { | 
						|
                    throw new Exception("当前工程数据中不存在【" + objectName + "】"); | 
						|
                } | 
						|
                //--------------------------- | 
						|
                //判断当前要素集有没有锁 | 
						|
                schemalock = (ISchemaLock)pFeatDS; | 
						|
                schemalock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); | 
						|
 | 
						|
                //获取拓扑 Topology 是否存在 | 
						|
                CheckTopologyExist(m_Workspace, pFeatDS, "TopologyDataCheck"); | 
						|
                //开始创建拓扑 | 
						|
                topology = CreateTopology(pFeatDS, "TopologyDataCheck", tolerance); | 
						|
                if (topology == null) | 
						|
                    throw new Exception("创建拓扑失败"); | 
						|
                //添加要素类到拓扑中 | 
						|
                List<IFeatureClass> lstFeatureClass = new List<IFeatureClass>(); | 
						|
                foreach (string featureClassName in lstFeatureClassTabelName) | 
						|
                { | 
						|
                    IFeatureClass pFatureClass = (m_Workspace as IFeatureWorkspace).OpenFeatureClass(featureClassName); | 
						|
                    string inFeatureClassPath = System.IO.Path.Combine((pFatureClass as IDataset).Workspace.PathName, pFatureClass.FeatureDataset.Name, featureClassName); | 
						|
                    topology.AddClass(pFatureClass, 1, 1, 1, false); | 
						|
                    lstFeatureClass.Add(pFatureClass); | 
						|
                } | 
						|
                foreach (ITopologyRule topologyRule in lstTopologyRule) | 
						|
                { | 
						|
                    //把topology对象强制转换到ITopologyRuleContainer对象,然后添加拓扑规则 | 
						|
                    ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology; | 
						|
                    if (topologyRuleContainer.get_CanAddRule(topologyRule)) | 
						|
                    { | 
						|
                        topologyRuleContainer.AddRule(topologyRule); | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        throw new ArgumentException("无法将指定的规则添加到拓扑中"); | 
						|
                    } | 
						|
                } | 
						|
                // 获取验证拓扑的范围并且验证拓扑 | 
						|
                IGeoDataset geoDataset = (IGeoDataset)topology; | 
						|
                IEnvelope envelope = geoDataset.Extent; | 
						|
                ValidateTopology(topology, envelope); | 
						|
                bool b = FindAllErrorFeatures(topology, envelope, lstFeatureClass); | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(geoDataset); | 
						|
                foreach (IFeatureClass item in lstFeatureClass) | 
						|
                { | 
						|
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(item); | 
						|
                } | 
						|
                foreach (ITopologyRule rule in lstTopologyRule) | 
						|
                { | 
						|
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(rule); | 
						|
                } | 
						|
                return b; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw new Exception("拓扑检查发生异常:" + ex.Message.ToString()); | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
                if (topology != null) | 
						|
                { | 
						|
                    Marshal.ReleaseComObject(topology); | 
						|
                } | 
						|
                if (m_Workspace != null && pFeatDS != null) | 
						|
                { | 
						|
                    //获取拓扑 Topology 是否存在,存在则删除 | 
						|
                    CheckTopologyExist(m_Workspace, pFeatDS, "TopologyDataCheck"); | 
						|
                } | 
						|
                if (schemalock != null) | 
						|
                { | 
						|
                    schemalock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock); | 
						|
                    Marshal.ReleaseComObject(schemalock); | 
						|
                } | 
						|
                if (pFeatDS != null) | 
						|
                { | 
						|
                    Marshal.ReleaseComObject(pFeatDS); | 
						|
                } | 
						|
                if (m_Workspace != null) | 
						|
                { | 
						|
                    Marshal.ReleaseComObject(m_Workspace); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 判断拓扑是否存在,存在则删除 | 
						|
        /// </summary> | 
						|
        /// <param name="m_Workspace">工作空间</param> | 
						|
        /// <param name="pFeatDS">要素集</param> | 
						|
        /// <param name="topologyName">拓扑名称</param> | 
						|
        private static void CheckTopologyExist(IWorkspace m_Workspace, IFeatureDataset pFeatDS, string topologyName) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                if (m_Workspace == null || pFeatDS == null) | 
						|
                { | 
						|
                    return; | 
						|
                } | 
						|
                bool bTopExists = (m_Workspace as IWorkspace2).get_NameExists(esriDatasetType.esriDTTopology, topologyName); | 
						|
                if (bTopExists) | 
						|
                { | 
						|
                    //删除已存在拓扑 | 
						|
                    ITopologyContainer topologyContainer = (ITopologyContainer)pFeatDS; | 
						|
                    if (topologyContainer != null) | 
						|
                    { | 
						|
                        ITopology topologyTemp = topologyContainer.get_TopologyByName(topologyName); | 
						|
                        if (topologyTemp != null) | 
						|
                        { | 
						|
                            //删除拓扑 | 
						|
                            IDataset pDatasetTemp = (IDataset)topologyTemp; | 
						|
                            pDatasetTemp.Delete(); | 
						|
                            Marshal.ReleaseComObject(pDatasetTemp); | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw new Exception("删除拓扑失败:" + ex.Message.ToString()); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 创建拓扑 | 
						|
        /// </summary> | 
						|
        /// <param name="pFtDs"></param> | 
						|
        /// <param name="pTopologyName"></param> | 
						|
        /// <param name="clusterTolerance"></param> | 
						|
        /// <returns></returns> | 
						|
        private static ITopology CreateTopology(IFeatureDataset pFtDs, string pTopologyName, double clusterTolerance = 0) | 
						|
        { | 
						|
            if (pFtDs == null) | 
						|
                return null; | 
						|
            ISchemaLock schemaLock = (ISchemaLock)pFtDs; | 
						|
            try | 
						|
            { | 
						|
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); | 
						|
                // 创建拓扑 | 
						|
                ITopologyContainer2 topologyContainer = (ITopologyContainer2)pFtDs; | 
						|
                ITopology topology = topologyContainer.CreateTopology(pTopologyName, clusterTolerance == 0 ? topologyContainer.DefaultClusterTolerance : clusterTolerance, -1, ""); | 
						|
                return topology; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw new Exception("创建拓扑异常:" + ex.Message.ToString()); | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 通过名称获取要素集 | 
						|
        /// </summary> | 
						|
        /// <param name="workspace"></param> | 
						|
        /// <param name="dsName"></param> | 
						|
        /// <returns></returns> | 
						|
        public static IFeatureDataset GetFeatureDatasetByName(IWorkspace workspace, string dsName) | 
						|
        { | 
						|
            string strFeatureDSName = ""; | 
						|
            IFeatureDataset pResultFDS = null; | 
						|
            IEnumDataset pEnumDS = workspace.get_Datasets(esriDatasetType.esriDTFeatureDataset); | 
						|
            pEnumDS.Reset(); | 
						|
            IDataset pDS = pEnumDS.Next(); | 
						|
            while (!(pDS == null)) | 
						|
            { | 
						|
                strFeatureDSName = GetFeatureObjectName(pDS.Name); | 
						|
                if (strFeatureDSName.Equals(dsName)) | 
						|
                { | 
						|
                    pResultFDS = (IFeatureDataset)pDS; | 
						|
                    break; | 
						|
                } | 
						|
                pDS = pEnumDS.Next(); | 
						|
            } | 
						|
            System.Runtime.InteropServices.Marshal.ReleaseComObject(pEnumDS); | 
						|
            return pResultFDS; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 去掉".",得到名称缩写 | 
						|
        /// </summary> | 
						|
        /// <param name="objectName"></param> | 
						|
        /// <returns></returns> | 
						|
        private static string GetFeatureObjectName(string objectName) | 
						|
        { | 
						|
            int index = objectName.LastIndexOf("."); | 
						|
            if (index >= 0) | 
						|
            { | 
						|
                return objectName.Substring(index + 1); | 
						|
            } | 
						|
            else | 
						|
            { | 
						|
                return objectName; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 检查建立的拓扑 | 
						|
        /// </summary> | 
						|
        /// <param name="topology"></param> | 
						|
        /// <param name="envelope"></param> | 
						|
        private static void ValidateTopology(ITopology topology, IEnvelope envelope) | 
						|
        { | 
						|
            // Get the dirty area within the provided envelope. | 
						|
            IPolygon locationPolygon = new Polygon() as IPolygon; | 
						|
            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); | 
						|
            } | 
						|
            System.Runtime.InteropServices.Marshal.ReleaseComObject(locationPolygon); | 
						|
            System.Runtime.InteropServices.Marshal.ReleaseComObject(polygon); | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 给定拓扑和查找的范围,返回所有的拓扑错误要素 | 
						|
        /// </summary> | 
						|
        /// <param name="topology"></param> | 
						|
        /// <param name="searchExtent"></param> | 
						|
        public static bool FindAllErrorFeatures(ITopology topology, IEnvelope searchExtent, List<IFeatureClass> lstFeatureClass) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                //获取坐标系 | 
						|
                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) | 
						|
                    { | 
						|
                        if (topologyErrorFeature.OriginOID <= 0) | 
						|
                        { | 
						|
                            if (topologyErrorFeature == null || (topologyErrorFeature as IFeature).ShapeCopy.IsEmpty) | 
						|
                            { | 
						|
                                continue; | 
						|
                            } | 
						|
                            IGeometryCollection geometryCollection = (topologyErrorFeature as IFeature).ShapeCopy as IGeometryCollection; | 
						|
                            if (geometryCollection == null) | 
						|
                            { | 
						|
                                continue; | 
						|
                            } | 
						|
 | 
						|
                        } | 
						|
                        GC.Collect(); | 
						|
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(topologyErrorFeature); | 
						|
                        return true; | 
						|
                    } | 
						|
                } | 
						|
                return false; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
                //强制回收 | 
						|
                GC.Collect(); | 
						|
                GC.WaitForFullGCComplete(); | 
						|
            } | 
						|
        } | 
						|
    } | 
						|
}
 | 
						|
 |