|
|
|
|
using ESRI.ArcGIS.Carto;
|
|
|
|
|
using ESRI.ArcGIS.DataSourcesGDB;
|
|
|
|
|
using ESRI.ArcGIS.Geodatabase;
|
|
|
|
|
using ESRI.ArcGIS.Geometry;
|
|
|
|
|
using ESRI.ArcGIS.Geoprocessing;
|
|
|
|
|
using ESRI.ArcGIS.Geoprocessor;
|
|
|
|
|
using KGIS.Framework.AE;
|
|
|
|
|
using KGIS.Framework.AE.Enum;
|
|
|
|
|
using KGIS.Framework.AE.ExtensionMethod;
|
|
|
|
|
using KGIS.Framework.AE.GPHelper;
|
|
|
|
|
using KGIS.Framework.Maps;
|
|
|
|
|
using KGIS.Framework.Utils;
|
|
|
|
|
using Kingo.PluginServiceInterface;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
|
|
namespace Kingo.Plugin.DataCheck
|
|
|
|
|
{
|
|
|
|
|
public class JCDLTBDataCheck : IDataCheck
|
|
|
|
|
{
|
|
|
|
|
public event CheckDataPr DataCheckComplate;
|
|
|
|
|
List<CheckResult> dataCheckResults = null;
|
|
|
|
|
|
|
|
|
|
public string IDataCheckName { get => "JCDLTBDataCheck"; }
|
|
|
|
|
|
|
|
|
|
public void FeatureCheck(object pParm)
|
|
|
|
|
{
|
|
|
|
|
FeatureClassCheck(pParm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FeatureClassCheck(object pParm)
|
|
|
|
|
{
|
|
|
|
|
dataCheckResults = new List<CheckResult>();
|
|
|
|
|
string topologyName = "TopologyCheck_DLTB";
|
|
|
|
|
JCDLTB_Topology(topologyName);
|
|
|
|
|
//DLTBRangeDatacheck(topologyName);
|
|
|
|
|
//Thread.Sleep(3000);
|
|
|
|
|
(pParm as CheckParametr).CheckResults = dataCheckResults;
|
|
|
|
|
DataCheckComplate?.Invoke(dataCheckResults, pParm as CheckParametr);
|
|
|
|
|
}
|
|
|
|
|
private ProjectInfo projectInfo = (MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo);
|
|
|
|
|
private void JCDLTB_Topology(string topologyName)
|
|
|
|
|
{
|
|
|
|
|
IFeatureWorkspace featureWorkspace = null;
|
|
|
|
|
IEnvelope envelope = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
checkTopologyError(topologyName, ref featureWorkspace, ref envelope);
|
|
|
|
|
FindAllErrorFeatures(topologyName, 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 topologyName, ref IFeatureWorkspace featureWorkspace, ref IEnvelope envelope)
|
|
|
|
|
{
|
|
|
|
|
IFeatureLayer JCFC = MapsManager.Instance.MapService.GetFeatureLayerByLayerName("地类图斑");
|
|
|
|
|
//1. 打开数据集文件
|
|
|
|
|
IWorkspace workspace = (JCFC.FeatureClass as FeatureClass).Workspace;
|
|
|
|
|
featureWorkspace = (IFeatureWorkspace)workspace;
|
|
|
|
|
//2. 打开数据集文件
|
|
|
|
|
IFeatureDataset featureDataset = JCFC.FeatureClass.FeatureDataset;
|
|
|
|
|
//3. 向拓扑集中添加要素层
|
|
|
|
|
IFeatureClass LRDLlayer = JCFC.FeatureClass;
|
|
|
|
|
//4. 设置拓扑处理对数据集的独占权限
|
|
|
|
|
ISchemaLock schemaLock = (ISchemaLock)featureDataset;
|
|
|
|
|
IWorkspaceFactory2 ipWsFactory = new FileGDBWorkspaceFactoryClass();
|
|
|
|
|
ITopologyContainer2 topologyContainer = featureDataset as ITopologyContainer2;
|
|
|
|
|
//判断拓扑是否存在
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
//关闭资源锁定
|
|
|
|
|
IWorkspaceFactoryLockControl ipWsFactoryLock;
|
|
|
|
|
ipWsFactoryLock = (IWorkspaceFactoryLockControl)ipWsFactory;
|
|
|
|
|
if (ipWsFactoryLock.SchemaLockingEnabled)
|
|
|
|
|
{
|
|
|
|
|
ipWsFactoryLock.DisableSchemaLocking();
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
|
|
|
|
|
//5. 拓扑处理
|
|
|
|
|
//5.1 创建拓扑容器
|
|
|
|
|
//5.2 向拓扑容器中添加拓扑结果层
|
|
|
|
|
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, null);
|
|
|
|
|
AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoGaps, "图层内部面和面之间不允许存在缝隙", LRDLlayer, null);
|
|
|
|
|
//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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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, IFeatureClass destinationClass)
|
|
|
|
|
{
|
|
|
|
|
ITopologyRule topologyRule = new TopologyRuleClass();
|
|
|
|
|
topologyRule.TopologyRuleType = ruleType;
|
|
|
|
|
topologyRule.Name = ruleName;
|
|
|
|
|
topologyRule.OriginClassID = featureClass.FeatureClassID;
|
|
|
|
|
topologyRule.AllOriginSubtypes = true;
|
|
|
|
|
|
|
|
|
|
if (destinationClass != null)
|
|
|
|
|
{
|
|
|
|
|
topologyRule.DestinationClassID = destinationClass.FeatureClassID;
|
|
|
|
|
topologyRule.AllDestinationSubtypes = true;
|
|
|
|
|
}
|
|
|
|
|
ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;
|
|
|
|
|
if (topologyRuleContainer.get_CanAddRule(topologyRule))
|
|
|
|
|
{
|
|
|
|
|
topologyRuleContainer.AddRule(topologyRule);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException(string.Format("不能添加{0}规则到拓扑里面,请检查此规则是否正确。", ruleName));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//拓扑有效性检查
|
|
|
|
|
public void ValidateTopology(ITopology topology, IEnvelope envelope)
|
|
|
|
|
{
|
|
|
|
|
IPolygon locationPolygon = new PolygonClass();
|
|
|
|
|
ISegmentCollection segmentCollection = (ISegmentCollection)locationPolygon;
|
|
|
|
|
segmentCollection.SetRectangle(envelope);
|
|
|
|
|
IPolygon polygon = topology.get_DirtyArea(locationPolygon);
|
|
|
|
|
IEnvelope areaToValidate = polygon.Envelope;
|
|
|
|
|
IEnvelope areaValidated = topology.ValidateTopology(areaToValidate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//给定拓扑和查找的范围,返回所有的拓扑错误要素
|
|
|
|
|
public void FindAllErrorFeatures(string topologyName, IEnvelope searchExtent)
|
|
|
|
|
{
|
|
|
|
|
IFeatureLayer JCFC = MapsManager.Instance.MapService.GetFeatureLayerByLayerName("地类图斑");
|
|
|
|
|
IFeatureDataset featureDataset = JCFC.FeatureClass.FeatureDataset;
|
|
|
|
|
ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset;
|
|
|
|
|
ITopology topology = topologyContainer.get_TopologyByName(topologyName);
|
|
|
|
|
//获取坐标系
|
|
|
|
|
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;
|
|
|
|
|
var count = 0;
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if (topologyRule.Name == "图层内部面和面之间不允许存在缝隙" && count == 0)
|
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
dataCheckResults.Add(new CheckResult()
|
|
|
|
|
{
|
|
|
|
|
ErrorDesc = topologyRule.Name == "图层内部面和面之间不允许重叠" ? $"{topologyRule.Name}【{topologyErrorFeature.OriginOID}/{topologyErrorFeature.DestinationOID}】" : topologyRule.Name,
|
|
|
|
|
Synopsis = topologyRule.Name,
|
|
|
|
|
ErrorCode = "2001000300000014",
|
|
|
|
|
ErrorLayer = IDataCheckName,
|
|
|
|
|
ObjectID = topologyRule.Name == "图层内部面和面之间不允许重叠" ? topologyErrorFeature.OriginOID : pFeature.OID,
|
|
|
|
|
ErrorType = EnumErrorType.错误,
|
|
|
|
|
ErrorCategory = "Graphic",
|
|
|
|
|
ErrorArea = pFeature.Shape.ToJson()
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IDataset pDatasetTemp = (IDataset)topology;
|
|
|
|
|
pDatasetTemp.Delete();
|
|
|
|
|
Marshal.ReleaseComObject(pDatasetTemp);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 基础地类图斑与基础行政区范围检查
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void DLTBRangeDatacheck(string topologyName)
|
|
|
|
|
{
|
|
|
|
|
GPParamClass gPParamClass = new GPParamClass();
|
|
|
|
|
ITopology2 topology = null;
|
|
|
|
|
IFeatureLayer featureLayer = null;
|
|
|
|
|
IEnvelope envelope = null;
|
|
|
|
|
IWorkspaceFactory pFtWsFct = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IFeatureLayer Fc_JCDLTB = MapsManager.Instance.MapService.GetFeatureLayerByLayerName("地类图斑");
|
|
|
|
|
IFeatureLayer Fc_JCCJDCQ = MapsManager.Instance.MapService.GetFeatureLayerByLayerName("村级调查区");
|
|
|
|
|
|
|
|
|
|
string gdbFolder = Directory.GetCurrentDirectory() + "\\Temp\\JCDLTBTempFile";
|
|
|
|
|
if (!Directory.Exists(gdbFolder))
|
|
|
|
|
Directory.CreateDirectory(gdbFolder);
|
|
|
|
|
try
|
|
|
|
|
{ DelectDirect(gdbFolder); }
|
|
|
|
|
catch { }
|
|
|
|
|
pFtWsFct = new FileGDBWorkspaceFactory();
|
|
|
|
|
string path = System.IO.Path.Combine(gdbFolder, Guid.NewGuid().ToString());
|
|
|
|
|
pFtWsFct.Create(path, "TempGDB", null, 0);
|
|
|
|
|
string TempfilePath = System.IO.Path.Combine(path, "TempGDB.gdb");//临时数据存放路径
|
|
|
|
|
IWorkspaceAPI wsAPI = new WorkspaceAPI(TempfilePath, WorkspaceTypeEnum.GDBFile);
|
|
|
|
|
IFeatureClassAPI DLTBAPI = wsAPI.CreateFeatureClass("DLTB", (Fc_JCDLTB.FeatureClass as IGeoDataset).SpatialReference, Fc_JCDLTB.FeatureClass.Fields);
|
|
|
|
|
IFeatureClassAPI fcAPI = new FeatureClassAPI(Fc_JCDLTB.FeatureClass);
|
|
|
|
|
fcAPI.FcToFc(DLTBAPI.FeatureClass, null, false);
|
|
|
|
|
|
|
|
|
|
IFeatureDataset featureDataset = Fc_JCDLTB.FeatureClass.FeatureDataset;
|
|
|
|
|
ITopologyContainer2 topologyContainer = featureDataset as ITopologyContainer2;
|
|
|
|
|
//判断拓扑是否存在
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
gPParamClass = new GPParamClass()
|
|
|
|
|
{
|
|
|
|
|
FirstFeatureLayer = Fc_JCDLTB,
|
|
|
|
|
OutFeatureClassPath = TempfilePath + "\\JCDLTB_Dissolve",
|
|
|
|
|
IsGetOutPutFeature = true,
|
|
|
|
|
ListDissolveFiledName = new List<string>() { "ZLDWDM", "ZLDWMC" },
|
|
|
|
|
};
|
|
|
|
|
GeoprocessorHelper.DissolveAnalysis(gPParamClass, ref featureLayer);
|
|
|
|
|
ISchemaLock schemaLock = (ISchemaLock)featureDataset;//注意此时不能使用ArcGIS再打开这个数据集
|
|
|
|
|
IWorkspaceFactory2 ipWsFactory = new FileGDBWorkspaceFactoryClass();
|
|
|
|
|
IWorkspaceFactoryLockControl ipWsFactoryLock = (IWorkspaceFactoryLockControl)ipWsFactory;
|
|
|
|
|
if (ipWsFactoryLock.SchemaLockingEnabled)
|
|
|
|
|
{
|
|
|
|
|
ipWsFactoryLock.DisableSchemaLocking();
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
|
|
|
|
|
topology = topologyContainer.CreateTopology(topologyName, topologyContainer.DefaultClusterTolerance, -1, "") as ITopology2;
|
|
|
|
|
//拓扑规则 必须添加同一个数据集中的数据
|
|
|
|
|
topology.AddClass(featureLayer.FeatureClass, 5, 1, 1, false);
|
|
|
|
|
topology.AddClass(Fc_JCCJDCQ.FeatureClass, 5, 1, 1, false);
|
|
|
|
|
AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaAreaCoverEachOther, "基础地类图斑同一坐落必须与基础村级调查区完全重合", Fc_JCCJDCQ.FeatureClass, featureLayer.FeatureClass);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
FindAllErrorFeatures(topologyName, envelope);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LogAPI.Debug($"基础地类图斑拓扑检查异常:{ex.Message}");
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region DelectDirect
|
|
|
|
|
private static void DelectDirect(string srcPath)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
DirectoryInfo dir = new DirectoryInfo(srcPath);
|
|
|
|
|
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
|
|
|
|
|
foreach (FileSystemInfo i in fileinfo)
|
|
|
|
|
{
|
|
|
|
|
if (i is DirectoryInfo) //判断是否文件夹
|
|
|
|
|
{
|
|
|
|
|
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
|
|
|
|
|
subdir.Delete(true); //删除子目录和文件
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
File.Delete(i.FullName); //删除指定文件
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|