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

281 lines
11 KiB

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<string, System.Data.DataTable> GetData(IGeometry geometry,IFeatureLayer featureLayer)
{
Dictionary<string, System.Data.DataTable> list = new Dictionary<string, System.Data.DataTable>();
try {
List<string> 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<string> 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<MinLength)
{
MinLength = pSeg.Length;
}
polyline.AddSegment(pSeg, ref missing, ref missing);
}
IPolyline pGeo = polyline as IPolyline;
AvgLength=pGeo.Length/segmentCollction.SegmentCount;
return pGeo;
}
/// <summary>
/// 获取要素的最小角度
/// </summary>
/// <param name="geometry">要素</param>
/// <returns></returns>
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<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 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;
}
}
}