年度变更建库软件5.0版本
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.

319 lines
13 KiB

4 months ago
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();
}
}
}
}