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 { /// /// 图斑图形检查-建库图层-国家质检 /// public class TBTXCheck_JK : RuleCheckBase_DTB { private List dataCheckResults = new List(); public TBTXCheck_JK() { var list = GetConfigList("SLSJDataCheck_DTB"); if (list.Count > 0) ruleMethodNames = list; } private List ruleMethodNames = new List() { "TXJC00","TXJC01", "TXJC02","TXJC03", "TXJC04","TXJC05","TXJC06" }; public override List ExcuteCheck(string sourePath, IWorkspace workspace) { return null; } public override List ExcuteCheck(string sourePath, Dictionary dicFeatureClass) { return null; } public override List ExcuteCheck(IWorkspace workspace, List layerNames, List dataSetNames) { return this.StartCheck(workspace, ruleMethodNames, layerNames, dataSetNames); } public override List ExcuteCheck(string tbbsm, string sourePath, Dictionary 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 TXJC00() { dataCheckResults = new List(); try { //自相交/多部件/短线段 CheckGeometry(SLFeatureCk); } catch (Exception ex) { LogAPI.Debug("变更数据检查异常:" + ex); } return dataCheckResults; } public List TXJC01() { dataCheckResults = new List(); 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 TXJC02() { dataCheckResults = new List(); 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 TXJC03() { dataCheckResults = new List(); 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 TXJC04() { dataCheckResults = new List(); 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 TXJC05() { dataCheckResults = new List(); 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 TXJC06() { dataCheckResults = new List(); try { //地类图斑变更层平均节点密度大于1米小于70米 List Segmentslength = new List(); 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度,或局部图形狭长的情况) /// /// 检查单个图形 /// /// /// 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); } } /// /// 获取最小角度 /// /// /// 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 rings = new List(); 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; } /// /// 计算角度 /// /// /// /// /// 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 } }