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

1016 lines
50 KiB

4 months ago
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE;
using KGIS.Framework.AE.Enum;
using KGIS.Framework.AE.ExtensionMethod;
using KGIS.Framework.AE.GPHelper;
using KGIS.Framework.DBOperator;
using KGIS.Framework.Maps;
using KGIS.Framework.Utils;
using KGIS.Framework.Utils.ExtensionMethod;
using Kingo.PluginServiceInterface;
using Kingo.PluginServiceInterface.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace KDataCheck
{
public class DataCheckHelper
{
List<string> sqlList = null;
public void ZLDataCheck(IDGParameter pParam)
{
IRDBHelper rdbHelper = null;
IRDBHelper rdbHelp = null;
try
{
bool isFirstDataCheck = true;
string mOutLocation = pParam.OutLocation;
var mOutLocation_GDBName = string.Empty;
string mPrjDbPath = pParam.PrjDbPath;
string dbPath = pParam.TempdbPath;
string strParm = string.Empty;
DBLayerSourceHelper mLayerSource = OpenDB(pParam.PrjInfo, pParam.CheckType == "BGDB");
if (mLayerSource == null) return;
ESRI.ArcGIS.Geometry.ISpatialReference sp = (mLayerSource.BgTbLayer.FeatureClass as IGeoDataset).SpatialReference;
ESRI.ArcGIS.Geometry.IPRJSpatialReferenceGEN gen1 = (ESRI.ArcGIS.Geometry.IPRJSpatialReferenceGEN)sp;
string str1;
int int1;
#region 规则筛选
rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + mPrjDbPath, DatabaseType.SQLite);
string Sqlwhere = " where 1=2 ";
if (pParam.CheckType == "BGDB")
{
Sqlwhere = " where BGIsSelect=true and BGLayerName NOTNULL ";
mOutLocation_GDBName = mOutLocation + "\\BGDBCheckResult.gdb";
}
else if (pParam.CheckType == "ZLDB")
{
Sqlwhere = " where ZLIsSelect=true and BGLayerName ISNULL AND RuleType='图形拓扑' ";
mOutLocation_GDBName = mOutLocation + "\\ZLDBCheckResult.gdb";
}
DataTable dataTable = rdbHelper.ExecuteDatatable("tab", $" SELECT * from CheckingRule {Sqlwhere} ", true);
if (dataTable == null || dataTable.Rows.Count == 0) return;
foreach (DataRow row in dataTable.Rows)
{
string sql = row["ImplementSQL"].ToTrim();
if (isFirstDataCheck == true && !row["ImplementSQL"].ToTrim().ToLower().Contains("select")
&& !string.IsNullOrEmpty(row["ImplementSQL"].ToTrim())
&& !row["ImplementSQL"].ToTrim().Contains("SameGraphic")
&& !row["ImplementSQL"].ToTrim().Contains("SameBSM")
&& !row["ImplementSQL"].ToTrim().Contains("LMFWGXKD")
&& !row["ImplementSQL"].ToTrim().Contains("SameGDPDJB")
&& !row["ImplementSQL"].ToTrim().Contains("Topology_JCDLTB")
&& !row["ImplementSQL"].ToTrim().Contains("LineNoDangles")
&& !row["ImplementSQL"].ToTrim().Contains("CheckGraphic")
&& !row["ImplementSQL"].ToTrim().Contains("Irregular")
&& !row["ImplementSQL"].ToTrim().Contains("Localslenderness")
&& !row["ImplementSQL"].ToTrim().Contains("NodeDensity")
&& !row["ImplementSQL"].ToTrim().Contains("SameAttribute"))
{
isFirstDataCheck = false;
gen1.ExportSpatialReferenceToPRJ(out str1, out int1);
if (pParam.CheckType == "ZLDB")
{
IVariantArray parameters = new VarArrayClass();
parameters.Add(pParam.PrjInfo.ZLDatabase);
parameters.Add(mOutLocation);
parameters.Add("ZLDBCheckResult");
parameters.Add(dbPath);
parameters.Add(mLayerSource.GxTbLayer);
parameters.Add(pParam.CheckType);
strParm = KGIS.Framework.AE.GeoDBAPI.SerialzedPersist(parameters);
}
else if (pParam.CheckType == "BGDB")
{
IVariantArray parameters = new VarArrayClass();
parameters.Add(mLayerSource.JcTbLayer);//基础地类图斑
parameters.Add(mLayerSource.BgTbLayer);//变更图斑
parameters.Add("1=1");//过滤条件
parameters.Add(mOutLocation);//输出路径
parameters.Add("BGDBCheckResult");//输出GDB名称
parameters.Add(dbPath);//输出DB路径
parameters.Add("10");//最小面积
parameters.Add(str1);//坐标系
parameters.Add(pParam.CheckType);
strParm = KGIS.Framework.AE.GeoDBAPI.SerialzedPersist(parameters);
}
if (string.IsNullOrEmpty(strParm))
{
Console.WriteLine("参数为空!");
return;
}
GPHelper.Instance.ExeGPForProces(strParm, pParam.CheckType);
break;
}
}
sqlList = new List<string>();
string LayerName = string.Empty; //变更图斑图层名称
string Alias = string.Empty;//别名
rdbHelp = RDBFactory.CreateDbHelper("Data Source=" + dbPath, DatabaseType.SQLite);
var ImplementSQL = string.Empty;
var RuleCode = string.Empty;
var RuleType = string.Empty;
var RuleName = string.Empty;
foreach (DataRow row in dataTable.Rows)
{
if (sqlList.Count > 10000)
{
InsertSQLiteData(mPrjDbPath, sqlList);
sqlList.Clear();
}
ImplementSQL = row["ImplementSQL"].ToTrim();//执行语句
RuleCode = row["RuleCode"].ToTrim();//规则编码
RuleType = row["RuleType"].ToTrim();//规则类别
RuleName = row["RuleName"].ToTrim();//规则名称
try
{
if (pParam.CheckType == "BGDB" || pParam.CheckType == "JCDB")
{
LayerName = row["BGLayerName"].ToTrim().Split('_')[0];
Alias = row["BGLayerName"].ToTrim().Split('_')[1];
}
else if (pParam.CheckType == "ZLDB")
{
LayerName = row["ZLLayerName"].ToTrim().Split('_')[0];
Alias = row["ZLLayerName"].ToTrim().Split('_')[1];
}
switch (ImplementSQL)
{
#region Topology
case "Topology"://相互重叠
GetTopologySqlite(mOutLocation_GDBName, rdbHelp, LayerName, RuleCode, RuleName, RuleType, pParam.CheckType == "ZLDB" ? pParam.PrjInfo.ZLDatabase : pParam.PrjInfo.BGDatabase);
break;
#endregion
#region Union
case "Union"://碎多边形
//sqlList.AddRange(GetUnionResult(DLTBBG, JC_DLTB, RuleCode, TempfilePath));
GetUnionSqlite(mOutLocation_GDBName, RuleCode, RuleName, RuleType);
break;
#endregion
#region Topology_JCDLTB
case "Topology_JCDLTB":
break;
#endregion
#region CheckGraphic
case "CheckGraphic"://自相交-多部件
CheckGraphic(RuleCode, RuleName, LayerName, pParam.CheckType == "ZLDB" ? pParam.PrjInfo.ZLDatabase : pParam.PrjInfo.BGDatabase);
break;
#endregion
#region Irregular
case "Irregular"://地类图斑更新层内不存在不规则图斑(除地类1001、1002、1006、1009、1107、1109外,其余地类满足面积/周长<0.2,并且有一个角度小于20)
Irregular(RuleCode, RuleName, LayerName, pParam.CheckType == "ZLDB" ? pParam.PrjInfo.ZLDatabase : pParam.PrjInfo.BGDatabase);
break;
#endregion
#region Localslenderness
case "Localslenderness"://地类图斑更新层要素所有角度均应大于10度,同时不存在局部狭长图形
Localslenderness(RuleCode, RuleName, LayerName, pParam.CheckType == "ZLDB" ? pParam.PrjInfo.ZLDatabase : pParam.PrjInfo.BGDatabase);
break;
#endregion
#region NodeDensity
case "NodeDensity"://地类图斑更新层平均节点密度大于1米小于70米
NodeDensity(RuleCode, RuleName, LayerName, pParam.CheckType == "ZLDB" ? pParam.PrjInfo.ZLDatabase : pParam.PrjInfo.BGDatabase);
break;
#endregion
#region SameAttribute
case "SameAttribute"://村级调查区更新层ZLDWDM、MSSM相同的多个调查区空间不能相邻
break;
#endregion
case "SameGraphic":
break;
case "SameBSM":
break;
case "LMFWGXKD":
break;
case "SameGDPDJB":
break;
case "LineNoDangles":
break;
#region default
default:
break;
#endregion
}
}
catch (Exception ex)
{
continue;
}
}
#endregion
InsertSQLiteData(mPrjDbPath, sqlList);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
if (rdbHelper != null && rdbHelper.State != System.Data.ConnectionState.Closed)
rdbHelper.DisConnect();
if (rdbHelp != null && rdbHelp.State != System.Data.ConnectionState.Closed)
rdbHelp.DisConnect();
}
}
private void GetTopologySqlite(string mOutLocation_GDBName, IRDBHelper rdbHelper, string LayerName, string RuleCode, string RuleName, string RuleType, string ZLBasePath)
{
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(mOutLocation_GDBName, WorkspaceTypeEnum.GDBFile);
List<IFeatureClass> featureClasses = workspaceAPI.GetAllFeatureClass(esriDatasetType.esriDTAny);
if (featureClasses == null) return;
IFeatureClass findFeatureClass = featureClasses.FirstOrDefault(a => a.AliasName == LayerName);
if (findFeatureClass == null)
{
findFeatureClass = featureClasses.FirstOrDefault(a => a.AliasName == "JCDLTB");
if (LayerName != "DLTB" || findFeatureClass == null)
{
//从ZLGDB文件中获取
GetTopology(ZLBasePath, LayerName, RuleCode, RuleName);
return;
}
}
int currentClassID = 0;
foreach (IFeatureClass featureClasse in featureClasses)
{
if (featureClasse.AliasName == LayerName)
{
currentClassID = featureClasse.FeatureClassID;
break;
}
else if (LayerName == "DLTB" && featureClasse.AliasName == "JCDLTB")
{
currentClassID = featureClasse.FeatureClassID;
break;
}
}
var dltbbg = new WorkspaceAPI(ZLBasePath, WorkspaceTypeEnum.GDBFile).OpenFeatureClass(LayerName);
var bsm = dltbbg.FeatureClass.FindField("BSM");
IFeatureClass featureClass = featureClasses[0];
IFeatureDataset featureDataset = featureClass.FeatureDataset;
ITopologyContainer topologyContainer = (ITopologyContainer)featureDataset;
ITopology topology = topologyContainer.get_TopologyByName("Dataset_Topo");
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;
IEnvelope searchExtent = geoDataset.Extent;
while ((rule = enumRule.Next()) != null)
{
//获取当前拓扑规则的拓扑错误并遍历
ITopologyRule topologyRule = (ITopologyRule)rule;
if (LayerName == "DLTB")
{
if (topologyRule.TopologyRuleType != esriTopologyRuleType.esriTRTAreaNoOverlap && topologyRule.TopologyRuleType != esriTopologyRuleType.esriTRTAreaNoGaps) continue;
}
else if (topologyRule.TopologyRuleType != esriTopologyRuleType.esriTRTAreaNoOverlap) continue;
IEnumTopologyErrorFeature enumTopologyErrorFeature = errorFeatureContainer.get_ErrorFeatures(spatialReference, topologyRule, searchExtent, true, true);
ITopologyErrorFeature topologyErrorFeature = null;
while ((topologyErrorFeature = enumTopologyErrorFeature.Next()) != null)
{
if (topologyErrorFeature.OriginClassID != currentClassID) continue;
IFeature pFeature = topologyErrorFeature as IFeature;
if (pFeature != null && !pFeature.Shape.IsEmpty)
{
//sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) " +
// $"VALUES ('{topologyErrorFeature.DestinationOID}', '{SearchBSM(rdbHelper, LayerName, topologyErrorFeature.DestinationOID.ToString())}', '{LayerName}', '{RuleCode}', '{RuleName}','{RuleType}','{pFeature.Shape.ToJson()}','{mOutLocation_GDBName}');");
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) " +
$"VALUES ('{topologyErrorFeature.DestinationOID}', '{dltbbg.GetFeature(topologyErrorFeature.OriginOID).Value[bsm].ToString()}-{dltbbg.GetFeature(topologyErrorFeature.DestinationOID).Value[bsm].ToString()}', '{LayerName}', '{RuleCode}', '{RuleName}','{RuleType}','{pFeature.Shape.ToJson()}','{mOutLocation_GDBName}');");
}
}
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
}
private void GetTopology(string TempfilePath, string LayerName, string ErrorCode, string ErrorName)
{
IEnvelope envelope = null;
string topologyName = $"TopologyCheck_{LayerName}";
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(TempfilePath, WorkspaceTypeEnum.GDBFile);
var featureClassAPI = workspaceAPI.OpenFeatureClass(LayerName);
TopologyVerification(topologyName, featureClassAPI.FeatureClass, esriTopologyRuleType.esriTRTAreaNoOverlap, ref envelope);
FindAllError(topologyName, envelope, featureClassAPI.FeatureClass, LayerName, ErrorCode, ErrorName, TempfilePath);
}
catch (Exception ex)
{
throw ex;
}
}
private void TopologyVerification(string topologyName, IFeatureClass featureClass, esriTopologyRuleType esriTopologyRuleType, ref IEnvelope envelope)
{
//1. 打开数据集文件
IWorkspace workspace = (featureClass as FeatureClass).Workspace;
//2. 打开数据集文件
IFeatureDataset featureDataset = featureClass.FeatureDataset;
//3. 向拓扑集中添加要素层
IFeatureClass LRDLlayer = 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();
}
ITopology2 topology = null;
try
{
schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
//5. 拓扑处理
//5.1 创建拓扑容器
//5.2 向拓扑容器中添加拓扑结果层
topology = topologyContainer.CreateTopology(topologyName, topologyContainer.DefaultClusterTolerance, -1, "") as ITopology2;
//5.3 添加参与拓扑运算的数据层
topology.AddClass(LRDLlayer, 5, 1, 1, false);
//5.4 添加拓扑规则
string ruleName = "图层内部面和面之间不允许重叠";
AddRuleToTopology(topology, esriTopologyRuleType, ruleName, LRDLlayer, null);
//AddRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, "图层内部面和面之间不允许重叠", LRDLlayer, null);
//5.5 拓扑验证
IGeoDataset geoDataset = (IGeoDataset)topology;
envelope = geoDataset.Extent;
ValidateTopology(topology, envelope);
}
catch (COMException comExc)
{
if (topology != null)
{
IDataset pDatasetTemp = (IDataset)topology;
pDatasetTemp.Delete();
}
throw new Exception(String.Format("Error creating topology: {0} Message: {1}", comExc.ErrorCode, comExc.Message), comExc);
}
finally
{
schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}
}
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 FindAllError(string topologyName, IEnvelope searchExtent, IFeatureClass featureClass, string ErrorLayer, string ErrorCode, string ErrorName, string path)
{
IFeatureDataset featureDataset = 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;
List<string> bsmlist = new List<string>();
var count = 0;
var dltbbg = new WorkspaceAPI(path, WorkspaceTypeEnum.GDBFile).OpenFeatureClass(ErrorLayer);
var bsm = featureClass.FindField("BSM");
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;
}
if (pFeature != null && !pFeature.Shape.IsEmpty)
{
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) " +
$"VALUES ('{topologyErrorFeature.DestinationOID}', '{dltbbg.GetFeature(topologyErrorFeature.OriginOID).Value[bsm].ToString()}-{dltbbg.GetFeature(topologyErrorFeature.DestinationOID).Value[bsm].ToString()}', '{ErrorLayer}', '{ErrorCode}', '{ErrorName}','{""}','{pFeature.Shape.ToJson()}','{path}');");
}
}
}
}
try
{
IDataset pDatasetTemp = (IDataset)topology;
pDatasetTemp.Delete();
Marshal.ReleaseComObject(pDatasetTemp);
}
catch { }
}
private void GetUnionSqlite(string mOutLocation_GDBName, string RuleCode, string RuleName, string RuleType)
{
IFeature pfeature = null;
IFeatureCursor pCursor = null;
try
{
IWorkspaceAPI workspaceUnionAPI = new WorkspaceAPI(mOutLocation_GDBName, WorkspaceTypeEnum.GDBFile);
IFeatureClassAPI featureUnionClass = workspaceUnionAPI.OpenFeatureClass("DLTBBG_Err");
pCursor = featureUnionClass.FeatureClass.Search(null, true);
int FID_DLTBBG = featureUnionClass.FeatureClass.FindField("FID_DLTBBG");
int BSM_DLTBBG = featureUnionClass.FeatureClass.FindField("BSM");
int FID_JCDLTB = featureUnionClass.FeatureClass.FindField("FID_JCDLTB");
int BSM_JCDLTB = featureUnionClass.FeatureClass.FindField("BSM_1");
while ((pfeature = pCursor.NextFeature()) != null)
{
//if (pfeature.Value[FID_DLTBBG].ToString() != "-1")
//{
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath,MultipartOID)" +
$" VALUES ('{pfeature.Value[FID_DLTBBG]}', '{pfeature.Value[BSM_DLTBBG]}', 'DLTBBG', '{RuleCode}', '{RuleName}', '{RuleType}', '{pfeature.Shape.ToJson()}','{mOutLocation_GDBName}','{pfeature.OID}');");
//}
//else
//{
// sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath,MultipartOID)" +
// $" VALUES ('{pfeature.Value[BSM_DLTBBG]}', '{pfeature.Value[BSM_JCDLTB]}', 'DLTB', '{RuleCode}', '{RuleName}', '{RuleType}', '{pfeature.Shape.ToJson()}','{mOutLocation_GDBName}','{pfeature.OID}');");
//}
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
finally
{
if (pfeature != null)
Marshal.ReleaseComObject(pfeature);
if (pCursor != null)
Marshal.ReleaseComObject(pCursor);
GC.Collect();
}
}
#region private
private DBLayerSourceHelper OpenDB(ProjectInfo pPrjarm, bool isBGCheck)
{
DBLayerSourceHelper result = new DBLayerSourceHelper();
try
{
LayerCfg layerInfo = null;
if (pPrjarm != null && !string.IsNullOrWhiteSpace(pPrjarm.TempData))
{
byte[] contentArray = Convert.FromBase64String(pPrjarm.TempData);
string LayerCfg = System.Text.Encoding.Default.GetString(contentArray);
layerInfo = KGIS.Framework.Utils.SerializeAPI.DeserializeToObject<LayerCfg>(LayerCfg);
}
if (layerInfo == null)
{
throw new Exception("Err:获取图层信息失败!");
}
//FileInfo fileInfo = new FileInfo(parm.PrjInfo.BGDatabase);
string PathBgDB = pPrjarm.BGDatabase;// Path.Combine(, "BGDB" + ".gdb");
string PathZLDB = pPrjarm.ZLDatabase;
string PathNMDB = pPrjarm.NMDatabase;// System.IO.Path.Combine(fileInfo.DirectoryName, "NMDB" + ".gdb");
result.BgWsAPI = new WorkspaceAPI(PathBgDB, WorkspaceTypeEnum.GDBFile);
if (result.BgWsAPI.CurrentWorkspace == null)
{
Console.WriteLine("打开变更数据库失败!");
return result;
}
result.ZlWsAPI = new WorkspaceAPI(PathZLDB, WorkspaceTypeEnum.GDBFile);
if (!isBGCheck && result.ZlWsAPI.CurrentWorkspace == null)
{
Console.WriteLine("打开增量数据库失败!");
return result;
}
result.NmWsAPI = new WorkspaceAPI(PathNMDB, WorkspaceTypeEnum.GDBFile);
LayerCfg JCLayerInfo = layerInfo.Layers.FirstOrDefault(f => f.LayerName == "年初数据");
if (JCLayerInfo == null)
{
throw new Exception("Err:获取年初数据库失败!");
}
List<LayerCfg> NcList = JCLayerInfo.GetAllItem();
//if (parm.ExeDLTB)
//{
LayerCfg _JcTBLayerInfo = NcList.FirstOrDefault(f => f.LayerName == "地类图斑");
result.JcTbLayer = result.OpenLayer(_JcTBLayerInfo);
if (result.JcTbLayer == null)
{
throw new Exception("Err:获取年初地类图斑数据失败!");
}
LayerCfg _JcPdtLayerInfo = NcList.FirstOrDefault(f => f.LayerName == "坡度图");
result.JcPdtLayer = result.OpenLayer(_JcPdtLayerInfo);
if (result.JcPdtLayer == null)
{
//throw new Exception("Err:获取年初坡度图数据失败!");
}
result.BgTbLayer = result.OpenLayer(result.BgWsAPI, "DLTBBG");
result.GxTbLayer = result.OpenLayer(result.ZlWsAPI, "DLTBGX");
//}
return result;
}
catch (Exception ex)
{
throw ex;
}
}
public void InsertSQLiteData(string dbPath, List<string> sqlList)
{
try
{
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + dbPath))
{
conn.Open();
using (SQLiteTransaction pTrans = conn.BeginTransaction())
{
using (SQLiteCommand cmd = new SQLiteCommand(conn))
{
for (int i = 0; i < sqlList.Count(); i++)
{
cmd.CommandText = sqlList[i];
cmd.ExecuteNonQuery();
}
pTrans.Commit();
}
}
conn.Close();
}
}
catch (Exception ex)
{
LogAPI.Debug("写入检查列表时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
}
#endregion
#region 地类图斑更新层平均节点密度大于1米小于70米
private void NodeDensity(string Check_RuleCode, string Check_RuleName, string Check_LayerName, string Temppath)
{
IFeature pfeature = null;
IFeatureCursor pCursor = null;
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(Temppath, WorkspaceTypeEnum.GDBFile);
var featureClass = workspaceAPI.OpenFeatureClass(Check_LayerName);
pCursor = featureClass.FeatureClass.Search(null, true);
int iBSM = featureClass.FeatureClass.FindField("BSM");
string strBSM = string.Empty;
while ((pfeature = pCursor.NextFeature()) != null)
{
List<double> Segmentslength = new List<double>();
IGeometryCollection _GeoColl = pfeature.ShapeCopy as IGeometryCollection;
for (int i = 0; i < _GeoColl.GeometryCount; i++)
{
ISegmentCollection _segmColl = _GeoColl.Geometry[i] as ISegmentCollection;
for (int j = 0; j < _segmColl.SegmentCount; j++)
{
Segmentslength.Add(_segmColl.Segment[j].Length);
}
}
if (Segmentslength.Average() > 70 || Segmentslength.Average() < 1)
{
if (iBSM != -1)
strBSM = pfeature.Value[iBSM].ToString();
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) VALUES ('{pfeature.OID}', '{strBSM}', '{Check_LayerName}', '{Check_RuleCode}', '{Check_RuleName}','图形拓扑','{pfeature.Shape.ToJson()}','{Temppath}');");
}
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
finally
{
if (pfeature != null)
Marshal.ReleaseComObject(pfeature);
if (pCursor != null)
Marshal.ReleaseComObject(pCursor);
GC.Collect();
}
}
#endregion
#region 要素不存在尖锐角和局部狭长图形(即不允许存在一个角度小于10度,或局部图形狭长的情况)
private void Localslenderness(string Check_RuleCode, string Check_RuleName, string Check_LayerName, string Temppath)
{
IFeature pfeature = null;
IFeatureCursor pCursor = null;
IGeometry geo = null;
ITopologicalOperator topo2 = null;
IPolyline line2 = null;
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(Temppath, WorkspaceTypeEnum.GDBFile);
var featureClass = workspaceAPI.OpenFeatureClass(Check_LayerName);
pCursor = featureClass.FeatureClass.Search(null, true);
int iBSM = featureClass.FeatureClass.FindField("BSM");
string strBSM = string.Empty;
while ((pfeature = pCursor.NextFeature()) != null)
{
double angle = GetMinAngle(pfeature.ShapeCopy);//获取图形的最小角度
ITopologicalOperator topo = pfeature.ShapeCopy as ITopologicalOperator;
IPolyline line1 = topo.Boundary as IPolyline;
double length1 = line1.Length;
int pointCount1 = (pfeature.ShapeCopy as IPointCollection).PointCount;
geo = topo.Buffer(-0.05);
topo2 = geo as ITopologicalOperator;
line2 = topo2.Boundary as IPolyline;
double length2 = line2.Length;
int pointCount2 = (geo as IPointCollection).PointCount - 1;
double delta_length = length1 - length2;
double avg_halfangle = 180 * (pointCount1 - 1 - 2) / (pointCount1 - 1) / 2;
double conner_normal_length = 2 * 0.05 / Math.Tan(avg_halfangle * (Math.PI / 180));
if ((delta_length > 8 * conner_normal_length * (pointCount1 - 1)) || angle < 10)
{
if (iBSM != -1)
strBSM = pfeature.Value[iBSM].ToString();
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) VALUES ('{pfeature.OID}', '{strBSM}', '{Check_LayerName}', '{Check_RuleCode}', '{Check_RuleName}','图形拓扑','{pfeature.Shape.ToJson()}','{Temppath}');");
}
if (topo != null)
Marshal.ReleaseComObject(topo);
if (line1 != null)
Marshal.ReleaseComObject(line1);
if (topo2 != null)
Marshal.ReleaseComObject(topo2);
if (line2 != null)
Marshal.ReleaseComObject(line2);
if (geo != null)
Marshal.ReleaseComObject(geo);
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
finally
{
if (pfeature != null)
Marshal.ReleaseComObject(pfeature);
if (pCursor != null)
Marshal.ReleaseComObject(pCursor);
GC.Collect();
}
}
/// <summary>
/// 获取最小角度
/// </summary>
/// <param name="pGeo"></param>
/// <returns></returns>
private static double GetMinAngle(IGeometry pGeo)
{
double result = -1;
IPolygon4 poly4 = null;
ITopologicalOperator topo = null;
GeometryBag geoBag = null;
IGeometryCollection geoCollection = null;
try
{
if (pGeo == null || pGeo.IsEmpty)
return result;
poly4 = pGeo as IPolygon4;
topo = poly4 as ITopologicalOperator;
if (topo != null)
topo.Simplify();
geoBag = poly4.ExteriorRingBag as GeometryBag;
if (geoBag == null) return result;
geoCollection = geoBag as IGeometryCollection;
List<IGeometry> rings = new List<IGeometry>();
for (int j = 0; j < geoCollection.GeometryCount; j++)
{
IGeometry geo = geoCollection.get_Geometry(j);
rings.Add(geo);
//内环图形
IGeometryBag InteriorBag = (pGeo as IPolygon4).get_InteriorRingBag(geo as IRing);
if (InteriorBag != null)
{
IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection;
for (int IR = 0; IR < InteriorRingGeometryCollection.GeometryCount; IR++)
{
rings.Add(InteriorRingGeometryCollection.get_Geometry(IR));
}
}
}
foreach (IGeometry ring in rings)
{
if (ring.IsEmpty) continue;
IPointCollection points = ring as IPointCollection;
int num = points.PointCount - 1;
for (int i = 0; i < num; i++)
{
IPoint p1 = null;
IPoint p2 = points.get_Point(i);
IPoint p3 = null;
if (i == 0)
{
p1 = points.get_Point(num - 1);
p3 = points.get_Point(i + 1);
}
else if (i == num - 1)
{
p1 = points.get_Point(i - 1);
p3 = points.get_Point(0);
}
else
{
p1 = points.get_Point(i - 1);
p3 = points.get_Point(i + 1);
}
double angle = GetAngle(p2, p1, p3);
if (result == -1)
{
result = angle;
}
else
{
if (result > angle)
result = angle;
}
Marshal.ReleaseComObject(p1);
Marshal.ReleaseComObject(p2);
Marshal.ReleaseComObject(p3);
}
Marshal.ReleaseComObject(ring);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (poly4 != null)
Marshal.ReleaseComObject(poly4);
if (topo != null)
Marshal.ReleaseComObject(topo);
if (geoBag != null)
Marshal.ReleaseComObject(geoBag);
if (geoCollection != null)
Marshal.ReleaseComObject(geoCollection);
}
return result;
}
/// <summary>
/// 计算角度
/// </summary>
/// <param name="cenPoint"></param>
/// <param name="firstPoint"></param>
/// <param name="secondPoint"></param>
/// <returns></returns>
private static double GetAngle(IPoint cenPoint, IPoint firstPoint, IPoint secondPoint)
{
double ma_x = firstPoint.X - cenPoint.X;
double ma_y = firstPoint.Y - cenPoint.Y;
double mb_x = secondPoint.X - cenPoint.X;
double mb_y = secondPoint.Y - cenPoint.Y;
double v1 = (ma_x * mb_x) + (ma_y * mb_y);
double ma_val = Math.Sqrt(ma_x * ma_x + ma_y * ma_y);
double mb_val = Math.Sqrt(mb_x * mb_x + mb_y * mb_y);
if (ma_val * mb_val == 0)
{
return -1;
}
double cosM = v1 / (ma_val * mb_val);
double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
return angleAMB;
}
#endregion
#region 地类图斑更新层内不存在不规则图斑(除地类1001、1002、1006、1009、1107、1109外,其余地类满足面积/周长<0.2,并且有一个角度小于20)
private void Irregular(string Check_RuleCode, string Check_RuleName, string Check_LayerName, string Temppath)
{
IFeature pfeature = null;
IFeatureCursor pCursor = null;
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(Temppath, WorkspaceTypeEnum.GDBFile);
var featureClass = workspaceAPI.OpenFeatureClass(Check_LayerName);
pCursor = featureClass.FeatureClass.Search(null, true);
int iBSM = featureClass.FeatureClass.FindField("BSM");
int iDLBM = featureClass.FeatureClass.FindField("DLBM");
int iSHAPE_Area = featureClass.FeatureClass.FindField("SHAPE_Area");
int iSHAPE_Length = featureClass.FeatureClass.FindField("SHAPE_Length");
string strBSM = string.Empty;
while ((pfeature = pCursor.NextFeature()) != null)
{
if ("1001,1002,1006,1009,1107,1109".Contains(pfeature.Value[iDLBM].ToString())) continue;
double angle = GetMinAngle(pfeature.ShapeCopy);//获取图形的最小角度
var SHAPE_Area = pfeature.Value[iSHAPE_Area].ToDouble();
var SHAPE_Length = pfeature.Value[iSHAPE_Length].ToDouble();
if (SHAPE_Area / SHAPE_Length < 0.2 && angle < 20)
{
if (iBSM != -1)
strBSM = pfeature.Value[iBSM].ToString();
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) VALUES ('{pfeature.OID}', '{strBSM}', '{Check_LayerName}', '{Check_RuleCode}', '{Check_RuleName}','图形拓扑','{pfeature.Shape.ToJson()}','{Temppath}');");
}
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
finally
{
if (pfeature != null)
Marshal.ReleaseComObject(pfeature);
if (pCursor != null)
Marshal.ReleaseComObject(pCursor);
GC.Collect();
}
}
#endregion
#region 自相交-多部件
private void CheckGraphic(string Check_RuleCode, string Check_RuleName, string Check_LayerName, string Temppath)
{
IFeature pfeature = null;
IFeatureCursor pCursor = null;
try
{
IWorkspaceAPI workspaceAPI = new WorkspaceAPI(Temppath, WorkspaceTypeEnum.GDBFile);
var featureClass = workspaceAPI.OpenFeatureClass(Check_LayerName);
pCursor = featureClass.FeatureClass.Search(null, true);
int iBSM = featureClass.FeatureClass.FindField("BSM");
string strBSM = string.Empty;
while ((pfeature = pCursor.NextFeature()) != null)
{
if (Check_RuleName.Contains("自相交"))
{
if (JudgeSelfIntersect(pfeature.ShapeCopy))
{
if (iBSM != -1)
strBSM = pfeature.Value[iBSM].ToString();
IPolygon4 polygon = pfeature.ShapeCopy as IPolygon4;
IGeometryBag bag = polygon.ExteriorRingBag;
if ((bag as IGeometryCollection).GeometryCount > 1)
{
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) VALUES ('{pfeature.OID}', '{strBSM}', '{Check_LayerName}', '{Check_RuleCode}', '{Check_RuleName}','图形拓扑','{pfeature.Shape.ToJson()}','{Temppath}');");
}
}
}
else if (Check_RuleName.Contains("组合图斑"))
{
IPointCollection polygonVertices = new PolygonClass();
IPointCollection lineVertices = pfeature.ShapeCopy as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
ITopologicalOperator3 pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (iBSM != -1)
strBSM = pfeature.Value[iBSM].ToString();
if (reason == esriNonSimpleReasonEnum.esriNonSimpleUnclosedRing)
{
IPolygon4 polygon = pfeature.Shape as IPolygon4;
IGeometryBag bag = polygon.ExteriorRingBag;
if ((bag as IGeometryCollection).GeometryCount > 1)
{
if (!JudgeSelfIntersect(pfeature.ShapeCopy))
sqlList.Add($"INSERT INTO DataCheckResults(OBJECTID, BSM, ErrorLayer, ErrorCode, ErrorName,RuleType,ErrorArea,RepairfilePath) VALUES ('{pfeature.OID}', '{strBSM}', '{Check_LayerName}', '{Check_RuleCode}', '{Check_RuleName}','图形拓扑','{pfeature.Shape.ToJson()}','{Temppath}');");
}
}
}
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
if (lineVertices != null)
Marshal.ReleaseComObject(lineVertices);
if (polygonVertices != null)
Marshal.ReleaseComObject(polygonVertices);
}
}
}
catch (Exception ex)
{
LogAPI.Debug("数据检查时发生异常,异常信息如下:");
LogAPI.Debug(ex);
return;
}
finally
{
if (pfeature != null)
Marshal.ReleaseComObject(pfeature);
if (pCursor != null)
Marshal.ReleaseComObject(pCursor);
GC.Collect();
}
}
#endregion
private bool JudgeSelfIntersect(IGeometry geometry)
{
ITopologicalOperator3 pTopology = null;
try
{
pTopology = (geometry as ITopologicalOperator3).Boundary as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections) return true;
else return false;
}
return false;
}
catch
{
return false;
}
finally
{
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
}
}
}
}