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

557 lines
24 KiB

6 months ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.Utils;
namespace Kingo.RuleCheck.XJRuleCheck
{
/// <summary>
/// 图斑图形检查-建库图层-国家质检
/// </summary>
public class TBTXCheck_JK : RuleCheckBase_DTB
{
private List<RuleEntity> dataCheckResults = new List<RuleEntity>();
public TBTXCheck_JK()
{
var list = GetConfigList("SLSJDataCheck_DTB");
if (list.Count > 0)
ruleMethodNames = list;
}
private List<string> ruleMethodNames = new List<string>()
{
"TXJC00","TXJC01", "TXJC02","TXJC03",
"TXJC04","TXJC05","TXJC06"
};
public override List<RuleEntity> ExcuteCheck(string sourePath, IWorkspace workspace)
{
return null;
}
public override List<RuleEntity> ExcuteCheck(string sourePath, Dictionary<string, IFeatureClass> dicFeatureClass)
{
return null;
}
public override List<RuleEntity> ExcuteCheck(IWorkspace workspace, List<string> layerNames, List<string> dataSetNames)
{
return this.StartCheck(workspace, ruleMethodNames, layerNames, dataSetNames);
}
public override List<RuleEntity> ExcuteCheck(string tbbsm, string sourePath, Dictionary<string, IFeatureClass> dicFeatureClass)
{
return null;
}
private void LogicCheck(string RuleContent, string ErrorTip, string ErrorType, string RuleCode, string RuleName)
{
dataCheckResults.Add(
new RuleEntity()
{
CheckObject = ((IDataset)this.SLFeatureCk.Class).Name,
ErrorId = this.SLFeatureCk.Value[SLFeatureCk.Class.FindField("BSM")].ToString(),
BGFWBSM = this.SLFeatureCk.Value[SLFeatureCk.Class.FindField("BSM")].ToString(),
ErrorTip = RuleContent,
ErrorType = ErrorType,
RuleCode = RuleCode,
RuleName = RuleName,
RuleContent = ErrorTip
});
}
public List<RuleEntity> TXJC00()
{
dataCheckResults = new List<RuleEntity>();
try
{
//自相交/多部件/短线段
CheckGeometry(SLFeatureCk);
}
catch (Exception ex)
{
LogAPI.Debug("变更数据检查异常:" + ex);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC01()
{
dataCheckResults = new List<RuleEntity>();
try
{
IPointCollection polygonVertices = null;
IPointCollection lineVertices = null;
ITopologicalOperator3 pTopology = null;
IPolygon4 polygon = null;
IGeometryBag bag = null;
try
{
polygonVertices = new PolygonClass();
lineVertices = SLFeatureCk.ShapeCopy as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections)
{
string RuleContent = "要素存在自相交!";
string ErrorTip = "图形自相交错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形自相交检查");
}
}
}
catch (Exception ex)
{
LogAPI.Debug("检查图形自相交错误异常:" + ex);
throw ex;
}
finally
{
if (polygonVertices != null)
Marshal.ReleaseComObject(polygonVertices);
if (lineVertices != null)
Marshal.ReleaseComObject(lineVertices);
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
if (polygon != null)
Marshal.ReleaseComObject(polygon);
if (bag != null)
Marshal.ReleaseComObject(bag);
}
}
catch (Exception ex)
{
LogAPI.Debug("变更数据检查异常:" + ex);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC02()
{
dataCheckResults = new List<RuleEntity>();
try
{
IPointCollection polygonVertices = null;
IPointCollection lineVertices = null;
ITopologicalOperator3 pTopology = null;
IPolygon4 polygon = null;
IGeometryBag bag = null;
try
{
polygonVertices = new PolygonClass();
lineVertices = SLFeatureCk.ShapeCopy as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (reason == esriNonSimpleReasonEnum.esriNonSimpleShortSegments)
{
string RuleContent = "要素存在短线段!";
string ErrorTip = "图形短线段错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形短线段检查");
}
}
}
catch (Exception ex)
{
LogAPI.Debug("检查单个图形异常:" + ex);
throw ex;
}
finally
{
if (polygonVertices != null)
Marshal.ReleaseComObject(polygonVertices);
if (lineVertices != null)
Marshal.ReleaseComObject(lineVertices);
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
if (polygon != null)
Marshal.ReleaseComObject(polygon);
if (bag != null)
Marshal.ReleaseComObject(bag);
}
}
catch (Exception ex)
{
LogAPI.Debug("变更数据检查异常:" + ex);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC03()
{
dataCheckResults = new List<RuleEntity>();
try
{
IPointCollection polygonVertices = null;
IPointCollection lineVertices = null;
ITopologicalOperator3 pTopology = null;
IPolygon4 polygon = null;
IGeometryBag bag = null;
try
{
polygonVertices = new PolygonClass();
lineVertices = SLFeatureCk.ShapeCopy as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (reason == esriNonSimpleReasonEnum.esriNonSimpleUnclosedRing)//存在不闭合的环
{
polygon = SLFeatureCk.ShapeCopy as IPolygon4;
bag = polygon.ExteriorRingBag;//获取多边形的所有外环
if ((bag as IGeometryCollection).GeometryCount > 1)
{
string RuleContent = "要素存在组合图斑(多部件)!";
string ErrorTip = "图形多部件错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形多部件检查");
}
}
}
}
catch (Exception ex)
{
LogAPI.Debug("检查单个图形异常:" + ex);
throw ex;
}
finally
{
if (polygonVertices != null)
Marshal.ReleaseComObject(polygonVertices);
if (lineVertices != null)
Marshal.ReleaseComObject(lineVertices);
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
if (polygon != null)
Marshal.ReleaseComObject(polygon);
if (bag != null)
Marshal.ReleaseComObject(bag);
}
}
catch (Exception ex)
{
LogAPI.Debug("变更数据检查异常:" + ex);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC04()
{
dataCheckResults = new List<RuleEntity>();
ITopologicalOperator topo = null;
IPolyline line1 = null;
IGeometry geo = null;
ITopologicalOperator topo2 = null;
IPolyline line2 = null;
try
{
//地类图斑变更层要素所有角度均应大于10度,同时不存在局部狭长图形
topo = SLFeatureCk.ShapeCopy as ITopologicalOperator;
line1 = topo.Boundary as IPolyline;
double length1 = line1.Length;
int pointCount1 = (SLFeatureCk.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))
{
string RuleContent = "要素存在局部狭长图形!";
string ErrorTip = "图形局部狭长错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形局部狭长检查");
}
}
catch (Exception ex)
{
LogAPI.Debug("检查地类图斑变更层平均节点密度大于1米小于70米异常:" + ex);
}
finally
{
if (topo != null)
Marshal.ReleaseComObject(topo);
if (line1 != null)
Marshal.ReleaseComObject(line1);
if (topo2 != null)
Marshal.ReleaseComObject(topo2);
if (line2 != null)
Marshal.ReleaseComObject(line2);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC05()
{
dataCheckResults = new List<RuleEntity>();
try
{
IGeometry refgeometry = null;
//图形尖锐角错误
double angle = GetMinAngle(SLFeatureCk.ShapeCopy, ref refgeometry);//获取图形的最小角度
if (angle < 10)
{
string RuleContent = "要素存在尖锐角!";
string ErrorTip = "图形尖锐角错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形尖锐角检查");
}
if (refgeometry != null)
Marshal.ReleaseComObject(refgeometry);
}
catch (Exception ex)
{
LogAPI.Debug("检查地类图斑变更层平均节点密度大于1米小于70米异常:" + ex);
}
return dataCheckResults;
}
public List<RuleEntity> TXJC06()
{
dataCheckResults = new List<RuleEntity>();
try
{
//地类图斑变更层平均节点密度大于1米小于70米
List<double> Segmentslength = new List<double>();
IGeometryCollection _GeoColl = SLFeatureCk.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)
{
string RuleContent = "地类图斑变更层平均节点密度大于1米小于70米!";
string ErrorTip = "图形节点密度错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形节点密度检查");
}
}
catch (Exception ex)
{
LogAPI.Debug("检查图形节点密度错误异常:" + ex);
}
return dataCheckResults;
}
#region 要素不存在尖锐角和局部狭长图形(即不允许存在一个角度小于10度,或局部图形狭长的情况)
/// <summary>
/// 检查单个图形
/// </summary>
/// <param name="pGeometry"></param>
/// <returns></returns>
private void CheckGeometry(IFeature pfeature)
{
IPointCollection polygonVertices = null;
IPointCollection lineVertices = null;
ITopologicalOperator3 pTopology = null;
IPolygon4 polygon = null;
IGeometryBag bag = null;
try
{
int idxBGBSM = pfeature.Fields.FindField("BSM");
int idxBGArea = pfeature.Fields.FindField("SHAPE_AREA");
polygonVertices = new PolygonClass();
lineVertices = pfeature.ShapeCopy as IPointCollection;
polygonVertices.AddPointCollection(lineVertices);
pTopology = polygonVertices as ITopologicalOperator3;
esriNonSimpleReasonEnum reason = esriNonSimpleReasonEnum.esriNonSimpleOK;
pTopology.IsKnownSimple_2 = false;
if (!pTopology.get_IsSimpleEx(out reason))
{
if (reason == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections)//自相交
{
string RuleContent = "要素存在自相交!";
string ErrorTip = "图形自相交错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形自相交检查");
}
if (reason == esriNonSimpleReasonEnum.esriNonSimpleUnclosedRing)//存在不闭合的环
{
polygon = pfeature.ShapeCopy as IPolygon4;
bag = polygon.ExteriorRingBag;//获取多边形的所有外环
if ((bag as IGeometryCollection).GeometryCount > 1)
{
string RuleContent = "要素存在组合图斑(多部件)!";
string ErrorTip = "图形多部件错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形多部件检查");
}
}
if (reason == esriNonSimpleReasonEnum.esriNonSimpleShortSegments)
{
string RuleContent = "要素存在短线段!";
string ErrorTip = "图形短线段错误!";
string ErrorType = "一类错误";
LogicCheck(RuleContent, ErrorTip, ErrorType, "TXSXJC", "图形短线段检查");
}
}
}
catch (Exception ex)
{
LogAPI.Debug("检查单个图形异常:" + ex);
throw ex;
}
finally
{
if (polygonVertices != null)
Marshal.ReleaseComObject(polygonVertices);
if (lineVertices != null)
Marshal.ReleaseComObject(lineVertices);
if (pTopology != null)
Marshal.ReleaseComObject(pTopology);
if (polygon != null)
Marshal.ReleaseComObject(polygon);
if (bag != null)
Marshal.ReleaseComObject(bag);
}
}
/// <summary>
/// 获取最小角度
/// </summary>
/// <param name="pGeo"></param>
/// <returns></returns>
private static double GetMinAngle(IGeometry pGeo, ref IGeometry refgeometry)
{
double result = -1;
IPolygon4 poly4 = null;
ITopologicalOperator topo = null;
GeometryBag geoBag = null;
IGeometryCollection geoCollection = null;
IGeometryCollection geometryCollection = null;
IPointCollection pointCollection = 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));
}
}
}
geometryCollection = new Polyline() as IGeometryCollection;
pointCollection = new Path();
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;
pointCollection.AddPoint(p1);
pointCollection.AddPoint(p2);
pointCollection.AddPoint(p3);
geometryCollection.AddGeometry(pointCollection as IGeometry);
refgeometry = geometryCollection as IGeometry;
refgeometry.SpatialReference = pGeo.SpatialReference;
}
else
{
if (result > angle)
{
result = angle;
pointCollection.AddPoint(p1);
pointCollection.AddPoint(p2);
pointCollection.AddPoint(p3);
geometryCollection.AddGeometry(pointCollection as IGeometry);
refgeometry = geometryCollection as IGeometry;
refgeometry.SpatialReference = pGeo.SpatialReference;
}
}
}
}
}
catch (Exception ex)
{
LogAPI.Debug("获取最小角度异常:" + ex);
throw ex;
}
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
}
}