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