|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using ESRI.ArcGIS.Geodatabase;
|
|
|
|
|
using ESRI.ArcGIS.Geometry;
|
|
|
|
|
using OSGeo.OGR;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Model:生成要素五要素帮助类
|
|
|
|
|
* Description:生成要素五要素帮助类
|
|
|
|
|
* Author:高山
|
|
|
|
|
* Finished:2017年12月4日
|
|
|
|
|
*/
|
|
|
|
|
namespace Kingo.RuleCheck.CheckHelper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 生成要素五要素帮助类:周长面积比,最小角度,长轴和短轴比,质心坐标,椭球面积
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class GenerateAttributeHelper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 检查国家标准数据库面图层是否存在五要素字段,不存在则创建
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="databaseType"></param>
|
|
|
|
|
/// <param name="connect"></param>
|
|
|
|
|
public static void CheckExtFiled(IFeatureClass pFeatureClass)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IClass pClass = pFeatureClass as IClass;
|
|
|
|
|
if (pFeatureClass.Fields.FindField("MinAngle_Extra") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "MinAngle_Extra";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("CenterPointX_Extra") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "CenterPointX_Extra";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("CenterPointY_Extra") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "CenterPointY_Extra";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("CKB_Extra") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "CKB_Extra";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("MJZCB_Extra") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "MJZCB_Extra";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("MJ_EXTRA") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "MJ_EXTRA";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("ZC_EXTRA") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeDouble;
|
|
|
|
|
fieldEdit2.Name_2 = "ZC_EXTRA";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
if (pFeatureClass.Fields.FindField("PointCount") < 0)
|
|
|
|
|
{
|
|
|
|
|
IField field = new FieldClass();
|
|
|
|
|
IFieldEdit2 fieldEdit2 = field as IFieldEdit2;
|
|
|
|
|
fieldEdit2.Type_2 = esriFieldType.esriFieldTypeInteger;
|
|
|
|
|
fieldEdit2.Name_2 = "PointCount";
|
|
|
|
|
pClass.AddField(field);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("新建五要素字段异常:" + ex.Message.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 设置要素属性值(地类图斑属性继承)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pFeatureClass">要赋值的图层</param>
|
|
|
|
|
/// <param name="pFeature">是否覆盖原有值:如果五要素字段有值,是否覆盖</param>
|
|
|
|
|
public static void SetFeatureAttribute(IFeatureClass pFeatureClass, bool isCoverData = true)
|
|
|
|
|
{
|
|
|
|
|
if (pFeatureClass == null)
|
|
|
|
|
return;
|
|
|
|
|
IFeature pFeature = null;
|
|
|
|
|
IFeatureCursor pCursor = null;
|
|
|
|
|
//DataSource ds = null;
|
|
|
|
|
//Layer layer = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//周长
|
|
|
|
|
double zc = 0;
|
|
|
|
|
//面积
|
|
|
|
|
double mj = 0;
|
|
|
|
|
int mj_extraFieldID = pFeatureClass.FindField("MJ_EXTRA");
|
|
|
|
|
int zc_extraFieldID = pFeatureClass.FindField("ZC_EXTRA");
|
|
|
|
|
int centerpointx_extraFieldID = pFeatureClass.FindField("CenterPointX_Extra");
|
|
|
|
|
int centerpointy_extraFieldID = pFeatureClass.FindField("CenterPointY_Extra");
|
|
|
|
|
int ckb_extraFieldID = pFeatureClass.FindField("CKB_Extra");
|
|
|
|
|
int mjzcb_extraFieldID = pFeatureClass.FindField("MJZCB_Extra");
|
|
|
|
|
int minangle_extraFieldID = pFeatureClass.FindField("MinAngle_Extra");
|
|
|
|
|
int pointcount_extraFieldID = pFeatureClass.FindField("PointCount");
|
|
|
|
|
int count = 0;
|
|
|
|
|
if (isCoverData)
|
|
|
|
|
{
|
|
|
|
|
count = pFeatureClass.FeatureCount(null);
|
|
|
|
|
pCursor = pFeatureClass.Search(null, true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IQueryFilter pQueryFilter = new QueryFilter()
|
|
|
|
|
{
|
|
|
|
|
WhereClause = " MJ_EXTRA IS NULL OR ZC_EXTRA IS NULL OR CenterPointX_Extra IS NULL OR CenterPointY_Extra IS NULL OR CKB_Extra IS NULL OR MJZCB_Extra IS NULL OR MinAngle_Extra IS NULL"
|
|
|
|
|
};
|
|
|
|
|
pCursor = pFeatureClass.Search(pQueryFilter, true);
|
|
|
|
|
count = pFeatureClass.FeatureCount(pQueryFilter);
|
|
|
|
|
}
|
|
|
|
|
if (count <= 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#region gdal计算最小角度 RegisterAll();
|
|
|
|
|
//RegisterAll();
|
|
|
|
|
//ds = Ogr.Open(Env.Instance.Project.GetProjMDBPath(), 0);
|
|
|
|
|
//if (ds != null && ds.GetLayerCount() >= 0)
|
|
|
|
|
//{
|
|
|
|
|
// OSGeo.OGR.Envelope envelope = new OSGeo.OGR.Envelope();
|
|
|
|
|
// layer = ds.GetLayerByName((pFeatureClass as FeatureClass).BrowseName);
|
|
|
|
|
// layer.GetExtent(envelope, 1);
|
|
|
|
|
//}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
while ((pFeature = pCursor.NextFeature()) != null)
|
|
|
|
|
{
|
|
|
|
|
if (pFeature.Shape == null || pFeature.Shape.IsEmpty)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//pFeature.Shape.SpatialReference = Env.Instance.KMap.GetMap().SpatialReference;
|
|
|
|
|
//图斑面积赋值(计算图斑椭球面积)
|
|
|
|
|
mj = RuleCommon.GetArea(pFeature.ShapeCopy);
|
|
|
|
|
pFeature.set_Value(mj_extraFieldID, mj);
|
|
|
|
|
//周长
|
|
|
|
|
ITopologicalOperator topo = pFeature.ShapeCopy as ITopologicalOperator;
|
|
|
|
|
IPolyline line = topo.Boundary as IPolyline;
|
|
|
|
|
zc = line.Length;
|
|
|
|
|
pFeature.set_Value(zc_extraFieldID, zc);
|
|
|
|
|
//IArea area = pFeature.ShapeCopy as IArea;
|
|
|
|
|
////质心坐标X
|
|
|
|
|
//pFeature.set_Value(centerpointx_extraFieldID, area.LabelPoint.X);
|
|
|
|
|
////质心坐标Y
|
|
|
|
|
//pFeature.set_Value(centerpointy_extraFieldID, area.LabelPoint.X);
|
|
|
|
|
//长宽比
|
|
|
|
|
IEnvelope env = pFeature.ShapeCopy.Envelope;
|
|
|
|
|
if (env.Width > env.Height)
|
|
|
|
|
{
|
|
|
|
|
pFeature.set_Value(ckb_extraFieldID, env.Width / (env.Height == 0D ? 1D : env.Height));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pFeature.set_Value(ckb_extraFieldID, env.Height / (env.Width == 0D ? 1D : env.Width));
|
|
|
|
|
}
|
|
|
|
|
//周长面积比
|
|
|
|
|
pFeature.set_Value(mjzcb_extraFieldID, mj / (zc == 0D ? 1D : zc));
|
|
|
|
|
string jsonGeometry = string.Empty;
|
|
|
|
|
double angle = CommonHelper.GetMinAngle(pFeature.ShapeCopy, out jsonGeometry);
|
|
|
|
|
//if (layer != null && angle <= 0)
|
|
|
|
|
//{
|
|
|
|
|
// OSGeo.OGR.Feature feature = layer.GetFeature(pFeature.OID);
|
|
|
|
|
// if (feature != null)
|
|
|
|
|
// {
|
|
|
|
|
// //最小角度
|
|
|
|
|
// angle = ConvertWkt(feature.GetGeometryRef());
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
pFeature.set_Value(minangle_extraFieldID, angle);
|
|
|
|
|
|
|
|
|
|
//设置点数量
|
|
|
|
|
pFeature.set_Value(pointcount_extraFieldID, (pFeature.ShapeCopy as IPointCollection).PointCount);
|
|
|
|
|
pFeature.Store();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("设置要素属性异常:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
//if (ds != null)
|
|
|
|
|
//{
|
|
|
|
|
// ds.Dispose();
|
|
|
|
|
// ds = null;
|
|
|
|
|
//}
|
|
|
|
|
//if (layer != null)
|
|
|
|
|
//{
|
|
|
|
|
// layer.Dispose();
|
|
|
|
|
//}
|
|
|
|
|
if (pFeature != null)
|
|
|
|
|
{
|
|
|
|
|
pFeature = null;
|
|
|
|
|
}
|
|
|
|
|
if (pCursor != null)
|
|
|
|
|
{
|
|
|
|
|
Marshal.ReleaseComObject(pCursor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private static void RegisterAll()
|
|
|
|
|
{
|
|
|
|
|
// 注册所有的驱动
|
|
|
|
|
Ogr.RegisterAll();
|
|
|
|
|
// 为了支持中文路径,请添加下面这句代码
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
|
|
|
|
|
// 为了使属性表字段支持中文,请添加下面这句
|
|
|
|
|
//Gdal.SetConfigOption("SHAPE_ENCODING", "NO");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取要素最小角度
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="geometry"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static double ConvertWkt(Geometry geometry)
|
|
|
|
|
{
|
|
|
|
|
double rstAngle = -1;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string wkt = "";
|
|
|
|
|
geometry.ExportToWkt(out wkt);
|
|
|
|
|
if (wkt.StartsWith("POLYGON"))
|
|
|
|
|
{
|
|
|
|
|
string wktN = wkt.Replace("POLYGON ((", "").Replace("))", "");
|
|
|
|
|
string[] strs = wktN.Replace("),(", "@").Split('@');
|
|
|
|
|
for (int i = 0; i < strs.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
string[] strsP = strs[i].Split(',');
|
|
|
|
|
for (int j = 0; j < strsP.Length - 1; j++)
|
|
|
|
|
{
|
|
|
|
|
string[] strF = null;
|
|
|
|
|
string[] strC = strsP[j].ToString().Split(' ');
|
|
|
|
|
string[] strS = null;
|
|
|
|
|
if (j == 0)
|
|
|
|
|
{
|
|
|
|
|
strF = strsP[strsP.Length - 2].ToString().Split(' ');
|
|
|
|
|
strS = strsP[j + 1].ToString().Split(' ');
|
|
|
|
|
}
|
|
|
|
|
else if (j == strsP.Length - 2)
|
|
|
|
|
{
|
|
|
|
|
strF = strsP[j - 1].ToString().Split(' ');
|
|
|
|
|
strS = strsP[strsP.Length - 1].ToString().Split(' ');
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strF = strsP[j - 1].ToString().Split(' ');
|
|
|
|
|
strS = strsP[j + 1].ToString().Split(' ');
|
|
|
|
|
}
|
|
|
|
|
double angle = GetAngle(Convert.ToDouble(strC[0]), Convert.ToDouble(strC[1]), Convert.ToDouble(strF[0]), Convert.ToDouble(strF[1]), Convert.ToDouble(strS[0]), Convert.ToDouble(strS[1]));
|
|
|
|
|
if (rstAngle == -1)
|
|
|
|
|
{
|
|
|
|
|
rstAngle = angle;
|
|
|
|
|
}
|
|
|
|
|
else if (rstAngle > angle)
|
|
|
|
|
{
|
|
|
|
|
rstAngle = angle;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return rstAngle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 计算面要素最小夹角
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取最小夹角
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="geometry"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static double GetMinAngle(ESRI.ArcGIS.Geometry.IGeometry geometry)
|
|
|
|
|
{
|
|
|
|
|
ESRI.ArcGIS.Geometry.IGeometryFactory3 factory = new ESRI.ArcGIS.Geometry.GeometryEnvironment() as ESRI.ArcGIS.Geometry.IGeometryFactory3;
|
|
|
|
|
byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[];
|
|
|
|
|
Geometry gdalGeometry = Geometry.CreateFromWkb(b);
|
|
|
|
|
return GetAngle(gdalGeometry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetAngle(Geometry geometry)
|
|
|
|
|
{
|
|
|
|
|
string wkt = "";
|
|
|
|
|
geometry.ExportToWkt(out wkt);
|
|
|
|
|
double rstAngle = -1;
|
|
|
|
|
double sumAngle = 0;
|
|
|
|
|
if (wkt.StartsWith("POLYGON"))
|
|
|
|
|
{
|
|
|
|
|
//StringBuilder sb = new StringBuilder("POLYGON (");
|
|
|
|
|
string wktN = wkt.Replace("POLYGON ((", "").Replace("))", "");
|
|
|
|
|
string[] strs = wktN.Replace("),(", "@").Split('@');
|
|
|
|
|
for (int i = 0; i < strs.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
string[] strsP = strs[i].Split(',');
|
|
|
|
|
for (int j = 0; j < strsP.Length; j++)
|
|
|
|
|
{
|
|
|
|
|
string[] strF = strsP[j].ToString().Split(' ');
|
|
|
|
|
string[] strC = null;
|
|
|
|
|
string[] strS = null;
|
|
|
|
|
if (j == strsP.Length - 2)
|
|
|
|
|
{
|
|
|
|
|
strC = strsP[j + 1].ToString().Split(' ');
|
|
|
|
|
strS = strsP[0].ToString().Split(' ');
|
|
|
|
|
if (strC[0] == strS[0] && strC[1] == strS[1])
|
|
|
|
|
{
|
|
|
|
|
strS = strsP[1].ToString().Split(' ');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (j == strsP.Length - 1)
|
|
|
|
|
{
|
|
|
|
|
strC = strsP[0].ToString().Split(' ');
|
|
|
|
|
strS = strsP[1].ToString().Split(' ');
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
strC = strsP[j + 1].ToString().Split(' ');
|
|
|
|
|
strS = strsP[j + 2].ToString().Split(' ');
|
|
|
|
|
}
|
|
|
|
|
double angle = GetAngle(Convert.ToDouble(strC[0]), Convert.ToDouble(strC[1]), Convert.ToDouble(strF[0]), Convert.ToDouble(strF[1]), Convert.ToDouble(strS[0]), Convert.ToDouble(strS[1]));
|
|
|
|
|
sumAngle += angle;
|
|
|
|
|
if (rstAngle == -1)
|
|
|
|
|
{
|
|
|
|
|
rstAngle = angle;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (angle < rstAngle)
|
|
|
|
|
{
|
|
|
|
|
rstAngle = angle;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return rstAngle;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static double GetAngle(double cenX, double cenY, double firstX, double firstY, double secondX, double secondY)
|
|
|
|
|
{
|
|
|
|
|
double ma_x = firstX - cenX;
|
|
|
|
|
double ma_y = firstY - cenY;
|
|
|
|
|
double mb_x = secondX - cenX;
|
|
|
|
|
double mb_y = secondY - cenY;
|
|
|
|
|
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);
|
|
|
|
|
double cosM = v1 / (ma_val * mb_val);
|
|
|
|
|
double angleAMB = Math.Acos(cosM) * 180 / Math.PI;
|
|
|
|
|
return angleAMB;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|