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

227 lines
10 KiB

6 months ago
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 { }
}
}
}