森林草原湿地荒漠调查
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.
 
 
 

104 lines
4.5 KiB

using System;
using System.Collections.Generic;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.AE.ExtensionMethod;
using KGIS.Framework.AE;
namespace Kingo.PluginServiceInterface.Helper
{
public class PolygonNarrowCheck
{
public static bool CheckNarrowArea1(IGeometry geometry)
{
bool isSharpAngle = false;
try
{
if (geometry == null || geometry.IsEmpty) return isSharpAngle;
ITopologicalOperator topo = geometry as ITopologicalOperator;
IPolyline line1 = topo.Boundary as IPolyline;
double length1 = line1.Length;
int pointCount1 = (geometry as IPointCollection).PointCount;
IGeometry geo = topo.Buffer(-0.05);
ITopologicalOperator topo2 = geo as ITopologicalOperator;
IPolyline line2 = topo2.Boundary as IPolyline;
double length2 = line2.Length;
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))
return true;
}
catch (Exception)
{
}
finally
{
//GC.Collect();
}
return isSharpAngle;
}
// 经验阈值判断(8倍安全系数)
const double safetyFactor = 8.0;
const double bufferDistance = -0.05; // 单位取决于空间参考
public static bool CheckNarrowArea(IGeometry geometry)
{
// 返回值表示是否检测到狭窄区域,默认为false
bool isNarrowAreaDetected = false;
try
{
// 输入校验:确保几何体非空且有效
if (geometry == null || geometry.IsEmpty)
return isNarrowAreaDetected;
// 类型检查:确保支持拓扑操作
if (!(geometry is ITopologicalOperator topoOperator))
return isNarrowAreaDetected;
// 获取原始边界并验证类型
var originalBoundary = topoOperator.Boundary as IPolyline;
if (originalBoundary == null)
return isNarrowAreaDetected;
// 计算原始几何参数
double originalLength = originalBoundary.Length;
int vertexCount = (geometry as IPointCollection)?.PointCount ?? 0;
// 顶点数不足3时无法构成有效多边形
if (vertexCount < 3)
return isNarrowAreaDetected;
// 执行负缓冲操作(缩小几何体)
IGeometry bufferedGeometry = topoOperator.Buffer(bufferDistance);
// 检查缓冲后几何有效性
if (bufferedGeometry?.IsEmpty != false)
return isNarrowAreaDetected;
// 获取缓冲后边界并验证类型
if (!(bufferedGeometry is ITopologicalOperator bufferedTopo))
return isNarrowAreaDetected;
var bufferedBoundary = bufferedTopo.Boundary as IPolyline;
if (bufferedBoundary == null)
return isNarrowAreaDetected;
// 计算缓冲后长度差异
double deltaLength = originalLength - bufferedBoundary.Length;
// 计算平均内角半角(几何修正)
double avgHalfAngle = 90.0 * (vertexCount - 2) / vertexCount;
// 角度接近直角时跳过计算(避免tan(90°))
if (avgHalfAngle >= 89.999)
return isNarrowAreaDetected;
// 计算拐角缩短长度
double tanValue = Math.Tan(avgHalfAngle * Math.PI / 180.0);
double cornerReduction = 2 * Math.Abs(bufferDistance) / tanValue;
// 计算总预期缩短长度
double totalExpectedReduction = cornerReduction * vertexCount;
isNarrowAreaDetected = deltaLength > safetyFactor * totalExpectedReduction;
}
catch (Exception ex)
{
// 异常处理(建议记录日志)
// Debug.WriteLine($"几何检测异常: {ex.Message}");
return false;
}
return isNarrowAreaDetected;
}
}
}