using Kingo.Plugin.EngineEditor.helper; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using KGIS.Framework.Utils; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using System.Runtime.InteropServices; using OSGeo.OGR; namespace Kingo.Plugin.EngineEditor.Unit { public class GeoOverCheck { public static Dictionary GetData(IGeometry geometry,IFeatureLayer featureLayer) { Dictionary list = new Dictionary(); try { List GeoOvercolumn = ConfigHelper.GetResultsCatalog(Unit.CheckTypeEnum.GeoOverInfor); DataTable data = new DataTable(); foreach (string name in GeoOvercolumn) { data.Columns.Add(new System.Data.DataColumn(name, typeof(string))); } GetGeoOver(geometry, featureLayer,ref data); list.Add("图斑压盖", data); List Checkcolumn = ConfigHelper.GetResultsCatalog(Unit.CheckTypeEnum.GeoCheckInfor); DataTable table = new DataTable(); foreach (string name in Checkcolumn) { table.Columns.Add(new System.Data.DataColumn(name, typeof(string))); } GetGeoCheck(geometry, featureLayer,ref table); list.Add("图形规范性", table); return list; } catch (Exception ex) { LogAPI.Debug(ex); return list; } } public static void GetGeoOver(IGeometry pGeometry, IFeatureLayer featureLayer,ref DataTable dt) { try { IIdentify indentify = featureLayer as IIdentify; if (indentify == null) return ; IArray pIDs = indentify.Identify(pGeometry); if (pIDs == null || pIDs.Count == 0) return; for (int index = 0; index < pIDs.Count; index++) { DataRow row = dt.NewRow(); IFeatureIdentifyObj pFeatIdObj = pIDs.get_Element(index) as IFeatureIdentifyObj; IRowIdentifyObject pRowObj = pFeatIdObj as IRowIdentifyObject; IFeature iF = pRowObj.Row as IFeature; foreach (DataColumn column in dt.Columns) { int inde = iF.Fields.FindField(column.ColumnName); if (inde > -1) { row[column.ColumnName] = iF.Value[inde]; } } dt.Rows.Add(row); } } catch (Exception ex) { LogAPI.Debug(ex); } } public static void GetGeoCheck(IGeometry pGeometry, IFeatureLayer featureLayer, ref DataTable dt) { double minleng = 0; double maxleng = 0; double avgleng = 0; double zc = 0; IPolyline polyline = null; IArea area = pGeometry as IArea; double mj = area.Area; try { DataRow row = dt.NewRow(); polyline= DealWithPolyline(pGeometry, ref minleng,ref maxleng,ref avgleng); zc = polyline.Length; row["检查项"] = "最小点间距"; row["值"] = Math.Round(minleng, 2); row["是否通过"] = minleng > 1 ? "通过":"不通过" ; dt.Rows.Add(row); row = dt.NewRow(); row["检查项"] = "最大点间距"; row["值"] = Math.Round(maxleng, 2); row["是否通过"] = maxleng>70?"不通过":"通过"; dt.Rows.Add(row); row = dt.NewRow(); row["检查项"] = "平均点间距"; row["值"] = Math.Round(avgleng, 2); row["是否通过"] = avgleng>1&&avgleng<50?"通过":"不通过"; dt.Rows.Add(row); row = dt.NewRow(); row["检查项"] = "最小角度"; double angle = 0; angle = GetMinAngle(pGeometry); row["值"] = Math.Round(angle, 2); row["是否通过"] = angle < 15?"不通过":"通过" ; dt.Rows.Add(row); row = dt.NewRow(); row["检查项"] = "面积"; row["值"] = Math.Round(mj, 2); row["是否通过"] = mj > 0?"通过":"不通过"; dt.Rows.Add(row); row = dt.NewRow(); row["检查项"] = "狭长图斑"; //row["是否通过"] = mj / (zc == 0D ? 1D : zc) > 20 ? "通过":"不通过" ; row["是否通过"] = "通过"; dt.Rows.Add(row); } catch (Exception ex) { LogAPI.Debug(ex); } finally { //if (polyline != null) //{ // Marshal.ReleaseComObject(polyline); //} //if (area != null) //{ // Marshal.ReleaseComObject(area); //} } } private static IPolyline DealWithPolyline(IGeometry geometry,ref double MinLength,ref double MaxLength,ref double AvgLength) { IPolygon polygon = geometry as IPolygon; ISegmentCollection segmentCollction = polygon as ISegmentCollection; ISegmentCollection polyline = new Polyline() as ISegmentCollection; object missing = Type.Missing; for (int m = 0; m < segmentCollction.SegmentCount; m++) { ISegment pSeg = segmentCollction.get_Segment(m); if (MinLength==0 || MaxLength==0) { MinLength = pSeg.Length; MaxLength = pSeg.Length; } else if (pSeg.Length>MaxLength) { MaxLength = pSeg.Length; } else if (pSeg.Length /// 获取要素的最小角度 /// /// 要素 /// public static double GetMinAngle(IGeometry pGeo) { double rstAngle = -1; try { if (pGeo == null || pGeo.IsEmpty) return rstAngle; IPolygon4 poly4 = pGeo as IPolygon4; ITopologicalOperator topo = poly4 as ITopologicalOperator; if (topo != null) { topo.Simplify(); } GeometryBag geoBag = poly4.ExteriorRingBag as GeometryBag; if (geoBag == null) return rstAngle; IGeometryCollection 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 ESRI.ArcGIS.Geometry.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 (rstAngle == -1) { rstAngle = angle; } else { if (rstAngle > angle) { rstAngle = angle; } } } } } catch (Exception ex) { throw ex; } return rstAngle; } public 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; } } }