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.
226 lines
10 KiB
226 lines
10 KiB
using ESRI.ArcGIS.DataSourcesGDB; |
|
using ESRI.ArcGIS.Geodatabase; |
|
using ESRI.ArcGIS.Geometry; |
|
using KGIS.Framework.AE.ExtensionMethod; |
|
using KGIS.Framework.Maps; |
|
using KGIS.Framework.Utils; |
|
using Kingo.PluginServiceInterface; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Runtime.InteropServices; |
|
|
|
namespace Kingo.Plugin.DataCheck |
|
{ |
|
public class JCCZCDYDDataCheck : IDataCheck |
|
{ |
|
public event CheckDataPr DataCheckComplate; |
|
List<CheckResult> dataCheckResults = null; |
|
|
|
public string IDataCheckName { get => "JCCZCDYDDataCheck"; } |
|
|
|
public void FeatureCheck(object pParm) |
|
{ |
|
JCDLTB_Topology(); |
|
DataCheckComplate?.Invoke(dataCheckResults, pParm as CheckParametr); |
|
} |
|
|
|
public void FeatureClassCheck(object pParm) |
|
{ |
|
JCDLTB_Topology(); |
|
DataCheckComplate?.Invoke(dataCheckResults, pParm as CheckParametr); |
|
} |
|
|
|
private void JCDLTB_Topology() |
|
{ |
|
try |
|
{ |
|
dataCheckResults = new List<CheckResult>(); |
|
ProjectInfo projectInfo = (MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo); |
|
IFeatureWorkspace featureWorkspace = null; |
|
IEnvelope envelope = null; |
|
ITopology topology = null; |
|
checkTopologyError(projectInfo.ProjDir + "\\PrjDB.gdb", "基础数据", "JC_CZCDYD", "TopologyCheck_CZCDYD", ref featureWorkspace, ref envelope); |
|
topology = OpenTopologyFromFeatureWorkspace(featureWorkspace, "基础数据", "TopologyCheck_CZCDYD"); |
|
FindAllErrorFeatures(topology, envelope); |
|
} |
|
catch (Exception ex) |
|
{ |
|
LogAPI.Debug($"基础地类图斑拓扑检查异常:{ex.Message}"); |
|
throw ex; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 检查要素层中存在的拓扑错误 |
|
/// </summary> |
|
/// <param name="wsPath">工作空间名称</param> |
|
/// <param name="dsPath">数据集名称</param> |
|
/// <param name="feaPath">要素类名称</param> |
|
/// <param name="topologyName">拓扑要素层名,拓扑检查结果记录在该层中</param> |
|
public void checkTopologyError(string wsPath, string dsPath, string feaPath, string topologyName, ref IFeatureWorkspace featureWorkspace, ref IEnvelope envelope) |
|
{ |
|
// Open the workspace and the required datasets. |
|
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory"); |
|
//ESRI.ArcGIS.DataSourcesGDB |
|
IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass(); //new AccessWorkspaceFactory(); |
|
//1. 打开数据集文件 |
|
IWorkspace workspace = workspaceFactory.OpenFromFile(wsPath, 0); |
|
featureWorkspace = (IFeatureWorkspace)workspace; |
|
//2. 打开数据集文件 |
|
IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(dsPath); |
|
//3. 向拓扑集中添加要素层 |
|
IFeatureClass LRDLlayer = featureWorkspace.OpenFeatureClass(feaPath); |
|
//4. 设置拓扑处理对数据集的独占权限 |
|
ISchemaLock schemaLock = (ISchemaLock)featureDataset;//注意此时不能使用ArcGIS再打开这个数据集 |
|
|
|
IWorkspaceFactory2 ipWsFactory = new FileGDBWorkspaceFactoryClass(); |
|
//关闭资源锁定 |
|
IWorkspaceFactoryLockControl ipWsFactoryLock; |
|
ipWsFactoryLock = (IWorkspaceFactoryLockControl)ipWsFactory; |
|
if (ipWsFactoryLock.SchemaLockingEnabled) |
|
{ |
|
ipWsFactoryLock.DisableSchemaLocking(); |
|
} |
|
try |
|
{ |
|
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); |
|
//5. 拓扑处理 |
|
//5.1 创建拓扑容器 |
|
ITopologyContainer2 topologyContainer = featureDataset as ITopologyContainer2; |
|
//5.2 向拓扑容器中添加拓扑结果层 |
|
//判断当前命名的拓扑是否存在,如果存在,删除 |
|
bool bTopExists = (featureDataset.Workspace as IWorkspace2).get_NameExists(esriDatasetType.esriDTTopology, topologyName); |
|
if (bTopExists) |
|
{ |
|
ITopology topologyTemp = topologyContainer.get_TopologyByName(topologyName); |
|
//删除拓扑 |
|
IDataset pDatasetTemp = (IDataset)topologyTemp; |
|
pDatasetTemp.Delete(); |
|
Marshal.ReleaseComObject(pDatasetTemp); |
|
} |
|
ITopology2 topology = topologyContainer.CreateTopology(topologyName, topologyContainer.DefaultClusterTolerance, -1, "") as ITopology2; |
|
//5.3 添加参与拓扑运算的数据层 |
|
topology.AddClass(LRDLlayer, 5, 1, 1, false); |
|
|
|
//5.4 添加拓扑规则 |
|
AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, "面与面不重叠", LRDLlayer); |
|
//AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoGaps, "面之间不存在间隙", LRDLlayer); |
|
//5.5 拓扑验证 |
|
IGeoDataset geoDataset = (IGeoDataset)topology; |
|
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); |
|
} |
|
//MessageBox.Show("拓扑检查完毕", "提示信息"); |
|
} |
|
|
|
/// <summary> |
|
/// 增加拓扑规则 |
|
/// </summary> |
|
/// <param name="topology">拓扑集</param> |
|
/// <param name="ruleType">拓扑规则</param> |
|
/// <param name="ruleName">规则名称</param> |
|
/// <param name="featureClass">要素类</param> |
|
public void AddRuleToTopology(ITopology topology, esriTopologyRuleType ruleType, |
|
String ruleName, IFeatureClass featureClass) |
|
{ |
|
// Create a topology rule. |
|
ITopologyRule topologyRule = new TopologyRuleClass(); |
|
topologyRule.TopologyRuleType = ruleType; |
|
topologyRule.Name = ruleName; |
|
topologyRule.OriginClassID = featureClass.FeatureClassID; |
|
topologyRule.AllOriginSubtypes = true; |
|
|
|
// 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("无法将指定的规则添加到拓扑中."); |
|
} |
|
} |
|
|
|
//拓扑有效性检查 |
|
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); |
|
} |
|
} |
|
|
|
//打开拓扑 |
|
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 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(); |
|
ESRI.ArcGIS.Geodatabase.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) |
|
{ |
|
IFeature pFeature = topologyErrorFeature as IFeature; |
|
if (pFeature != null) |
|
{ |
|
dataCheckResults.Add(new CheckResult() |
|
{ |
|
ErrorDesc = "要素存在拓扑错误!", |
|
Synopsis = "要素存在拓扑错误!", |
|
ErrorCode = "200500", |
|
ErrorLayer = IDataCheckName, |
|
ObjectID = pFeature.OID, |
|
ErrorType = EnumErrorType.错误, |
|
ErrorArea = pFeature.ShapeCopy.ToJson() |
|
}); |
|
} |
|
} |
|
} |
|
try |
|
{ |
|
IDataset pDatasetTemp = (IDataset)topology; |
|
pDatasetTemp.Delete(); |
|
Marshal.ReleaseComObject(pDatasetTemp); |
|
} |
|
catch { } |
|
} |
|
} |
|
}
|
|
|