using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using KGIS.Framework.Utils.ExtensionMethod;
namespace Kingo.PluginServiceInterface.Helper
{
///
/// 多边形边界对齐工具(针对ArcEngine 10.2.2优化版本)
/// 主要功能:调整目标多边形的顶点坐标,使其与相邻几何体的边界对齐
/// 优化重点:空间索引结构、COM对象管理、批量坐标操作
///
public static class PolygonBoundaryAligner
{
#region 公共常量与接口
private const double DEFAULT_TOLERANCE = 0.001; // 默认捕捉容差(地图单位)
private static readonly object _syncRoot = new object(); // 线程安全锁
#endregion
#region 主入口方法
///
/// 对齐多边形边界的主方法
///
/// 目标多边形
/// 相邻几何体集合
/// 捕捉容差(默认0.001)
/// 调整后的多边形
public static IGeometry AlignPolygonBoundary(IGeometry target, List adjacentGeometries, double tolerance = DEFAULT_TOLERANCE)
{
// 参数校验
ValidateParameters(target, adjacentGeometries);
// 克隆原始几何体(避免修改输入参数)
IPolygon originalPolygon = (IPolygon)((IClone)target).Clone();
IPolygon newPolygon = new PolygonClass();
newPolygon.SpatialReference = originalPolygon.SpatialReference;
try
{
// 步骤1:收集相邻几何体的边界要素
List adjacentBoundaries = CollectAdjacentBoundaries(adjacentGeometries);
// 步骤2:构建空间索引(顶点索引和线段索引)
ITopologicalOperator topological = originalPolygon as ITopologicalOperator;
var (vertexIndex, segmentIndex) = BuildSpatialIndexes(adjacentBoundaries, topological.Boundary, tolerance);
if (vertexIndex.IsEmpty && segmentIndex.IsEmpty)
{
return target;
//(vertexIndex, segmentIndex) = BuildSpatialIndexes(adjacentBoundaries, tolerance);
}
// 步骤3:调整多边形顶点
//IPointCollection points = (IPointCollection)originalPolygon;
List points = new List();
IGeometryCollection geometryCollection = (IGeometryCollection)originalPolygon;
for (int i = 0; i < geometryCollection.GeometryCount; i++)
{
IRing ring = (IRing)geometryCollection.get_Geometry(i);
IPointCollection ringPoints = (IPointCollection)ring;
points.Add(ringPoints);
}
newPolygon = AdjustWithLegacyMethod(points, vertexIndex, segmentIndex, tolerance, adjacentBoundaries);
// 步骤4:拓扑验证与简化
EnsureTopologyValidity(ref newPolygon);
return (IGeometry)newPolygon;
}
catch (Exception ex)
{
throw ex;
}
finally
{
// 显式释放COM对象(重要!防止内存泄漏)
SafeReleaseComObject(originalPolygon);
}
}
#endregion
#region 核心处理逻辑
///
/// 获取调整后的所有环(外环+内环)
///
private static IEnumerable GetAdjustedRings(IPolygon polygon, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
{
IGeometryCollection geomColl = (IGeometryCollection)polygon;
for (int i = 0; i < geomColl.GeometryCount; i++)
{
if (geomColl.get_Geometry(i) is IRing ring && !ring.IsEmpty)
{
yield return AdjustRingVertices(ring, vertexIndex, segmentIndex, tolerance, boundaries);
}
}
}
private static IPolygon AdjustRingVertices(IRing ring, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
{
// 获取点集合接口(兼容10.2.2)
IPointCollection points = (IPointCollection)ring;
return AdjustWithLegacyMethod(new List { points }, vertexIndex, segmentIndex, tolerance, boundaries);
}
///
/// 兼容方法:传统逐个点操作(ArcEngine 10.0 以下备用)
///
private static IPolygon AdjustWithLegacyMethod(List allPoints, VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex, double tolerance, List boundaries)
{
IPolygon newPolygon = new PolygonClass();
IGeometryCollection newGeomColl = (IGeometryCollection)newPolygon;
for (int k = 0; k < allPoints.Count; k++)
{
int pointCount = allPoints[k].PointCount;
bool modified = false;
var coords = new List<(double X, double Y)>();
for (int i = 0; i < pointCount; i++)
{
IPoint p = allPoints[k].get_Point(i);
//string aa1 = GeometryConvertHelper.ConvertIGeoemtryToWKT(p);
try
{
coords.Add((p.X, p.Y));
}
finally
{
Marshal.ReleaseComObject(p);
}
}
// 坐标调整逻辑
Dictionary keyValuePairs = new Dictionary();
for (int i = 0; i < coords.Count; i++)
{
var (x, y) = coords[i];
var snappedPoints = vertexIndex.FindAllVertices(x, y, tolerance).Distinct().ToList();
if (snappedPoints != null && snappedPoints.Count == 2)
{
double distSq0 = (coords[i].X - snappedPoints[0].X) * (coords[i].X - snappedPoints[0].X) + (coords[i].Y - snappedPoints[0].Y) * (coords[i].Y - snappedPoints[0].Y);
double distSq1 = (coords[i].X - snappedPoints[1].X) * (coords[i].X - snappedPoints[1].X) + (coords[i].Y - snappedPoints[1].Y) * (coords[i].Y - snappedPoints[1].Y);
if (distSq0 > distSq1)
{
coords[i] = snappedPoints[1];
keyValuePairs.Add(i, snappedPoints[0]);
}
else
{
coords[i] = snappedPoints[0];
keyValuePairs.Add(i, snappedPoints[1]);
}
continue;
}
var snappedPoint = vertexIndex.FindClosestVertex(x, y, tolerance);
if (snappedPoint == null)
{
snappedPoint = segmentIndex.FindClosestPoint(x, y, tolerance);
}
else
{
var currents = coords.Where(current => current.X != x && current.Y != y).ToList();
var coordscoords = currents.FirstOrDefault(kvp => Math.Abs(kvp.X - x) < 0.001 && Math.Abs(kvp.Y - y) < 0.001);
if ((coords.Contains(snappedPoint.Value) && coords[0] != snappedPoint.Value) || (coordscoords.X != 0 && coordscoords.Y != 0))
{
snappedPoint = segmentIndex.FindClosestPoint(x, y, tolerance);
}
}
if (snappedPoint.HasValue)
{
if (coords.Contains(snappedPoint.Value) && coords[0] != snappedPoint.Value)
{
int firstIndex = coords.Select((item, idx) => new { item, idx }).
FirstOrDefault(pair => pair.item.X == snappedPoint.Value.X && pair.item.Y == snappedPoint.Value.Y)?.idx ?? -1;
if (firstIndex != -1 && i > firstIndex)
{
coords[i] = (0, 0);
continue;
}
}
var currents = coords.Where(current => current.X != x && current.Y != y).ToList();
var coordscoords = currents.FirstOrDefault(kvp => Math.Abs(kvp.X - x) < 0.1 && Math.Abs(kvp.Y - y) < 0.1);
//var dSnappedPoint = CalculateDistance(snappedPoint.Value.X, snappedPoint.Value.Y, x, y);
//var dCoordscoords = CalculateDistance(coordscoords.X, coordscoords.Y, x, y);
//var gap = Math.Abs(dSnappedPoint - dCoordscoords);
//if (coordscoords.X != 0 && coordscoords.Y != 0 && dSnappedPoint > dCoordscoords && gap > 0.001)
// continue;
coords[i] = snappedPoint.Value;
modified = true;
}
}
// 更新坐标
if (modified)
{
allPoints[k].RemovePoints(0, pointCount);
IPoint newPoint = new PointClass();
if (keyValuePairs.Count > 0)
{
foreach (var item in keyValuePairs)
{
coords.Insert(item.Key, item.Value);
}
}
foreach (var (X, Y) in coords)
{
if (X == 0 || Y == 0) continue;
newPoint.PutCoords(X, Y);
allPoints[k].AddPoint(newPoint);
}
Marshal.ReleaseComObject(newPoint);
}
newGeomColl.AddGeometry((IGeometry)allPoints[k]);
string aa = GeometryConvertHelper.ConvertIGeoemtryToWKT(newPolygon);
Addnode(newPolygon, boundaries);
}
return newPolygon;
//IGeometryCollection geomColl = (IGeometryCollection)newPolygon;
//for (int i = 0; i < geomColl.GeometryCount; i++)
//{
// IGeometry geometry = geomColl.get_Geometry(i);
// IRing ring1 = geometry as IRing;
// if (ring1 == null || ring1.IsEmpty || ring1.Length < 0.01) continue;
// return ring1;
//}
//return null;
}
public static double CalculateDistance(double x1, double y1, double x2, double y2)
{
// 计算坐标差值的平方和
double deltaX = x2 - x1;
double deltaY = y2 - y1;
double distanceSquared = deltaX * deltaX + deltaY * deltaY;
// 开平方根得到距离(使用Math.Sqrt)
return Math.Sqrt(distanceSquared);
}
#endregion
#region 空间索引构建
private static (VertexSpatialIndex vertexIndex, SegmentSpatialIndex segmentIndex) BuildSpatialIndexes(List boundaries, IGeometry targetBoundary, double tolerance)
{
double xRange = targetBoundary.Envelope.XMax - targetBoundary.Envelope.XMin;
double yRange = targetBoundary.Envelope.YMax - targetBoundary.Envelope.YMin;
int totalVertices = boundaries.Sum(g => (g as IPointCollection)?.PointCount ?? 0);
double density = totalVertices / (xRange * yRange); // 顶点密度(点/单位面积)
double baseCellSize = Math.Max(xRange, yRange) / 100;
double cellSize = density > 100 ? baseCellSize / 2 : // 高密度:缩小网格
density < 10 ? baseCellSize * 2 : // 低密度:扩大网格
baseCellSize;
var vertexIndex = new VertexSpatialIndex(cellSize);
var segmentIndex = new SegmentSpatialIndex(cellSize);
double maxDistance = tolerance * 20; // 设定最大距离阈值
int threshold = Math.Max(Environment.ProcessorCount * 100, 1000); // 最小阈值1000
foreach (var geom in boundaries)
{
if (geom is IPointCollection pointColl)
{
if (pointColl.PointCount > threshold)
{
Parallel.For(0, pointColl.PointCount, i =>
{
IPoint point = pointColl.get_Point(i);
try
{
double distance = CalculateDistance(point, targetBoundary);
if (distance <= maxDistance)
{
vertexIndex.AddPoint(point); // 线程安全
}
}
finally
{
Marshal.ReleaseComObject(point);
}
});
}
else
{
for (int i = 0; i < pointColl.PointCount; i++)
{
IPoint point = pointColl.get_Point(i);
try
{
// 计算点到目标边界的距离
double distance = CalculateDistance(point, targetBoundary);
if (distance <= maxDistance)
{
vertexIndex.AddPoint(point);
}
}
finally
{
Marshal.ReleaseComObject(point);
}
}
}
}
if (geom is ISegmentCollection segColl)
{
for (int i = 0; i < segColl.SegmentCount; i++)
{
ISegment segment = segColl.get_Segment(i);
try
{
IPolyline polyline1 = new PolylineClass();
polyline1.FromPoint = segment.FromPoint;
polyline1.ToPoint = segment.ToPoint;
polyline1.SpatialReference = targetBoundary.SpatialReference;
double distancepolyline1 = CalculateDistance(polyline1, targetBoundary);
if (distancepolyline1 <= maxDistance && distancepolyline1 >= 0)
{
segmentIndex.AddSegment(segment);
}
}
catch
{
}
finally
{
Marshal.ReleaseComObject(segment);
}
}
}
}
return (vertexIndex, segmentIndex);
}
// 计算几何体到目标边界的距离
private static double CalculateDistance(IGeometry geom, IGeometry targetBoundary)
{
if (geom == null || targetBoundary == null) return double.MaxValue;
//if (geom is IPoint point && targetBoundary is IPolygon polygon)
//{
// return CalculateDistanceLocal(point, polygon); // 本地计算
//}
// 其他类型回退到COM调用
try
{
IProximityOperator proximityOp = (IProximityOperator)targetBoundary;
return proximityOp.ReturnDistance(geom);
}
catch
{
return double.MaxValue;
}
}
#endregion
#region 空间索引实现类
///
/// 顶点空间索引(使用双层字典的网格索引)
/// 优化点:提高网格查询速度,减少距离计算次数
///
private class VertexSpatialIndex
{
private readonly Dictionary>> _grid;
private readonly double _cellSize;
private int _totalPoints = 0;
public bool IsEmpty => _totalPoints == 0;
public VertexSpatialIndex(double cellSize)
{
_cellSize = cellSize;
_grid = new Dictionary>>();
}
///
/// 添加顶点到索引(自动网格化)
///
public void AddPoint(IPoint point)
{
long xCell = (long)(point.X / _cellSize);
long yCell = (long)(point.Y / _cellSize);
lock (_syncRoot)
{
if (!_grid.TryGetValue(xCell, out var yDict))
{
yDict = new Dictionary>();
_grid[xCell] = yDict;
}
if (!yDict.TryGetValue(yCell, out var points))
{
points = new List<(double X, double Y)>();
yDict[yCell] = points;
}
// 去重逻辑:检查容差范围内是否已有重复点
bool isDuplicate = false;
double toleranceSq = _cellSize * _cellSize; // 基于网格精度的容差
foreach (var p in points)
{
double dx = p.X - point.X;
double dy = p.Y - point.Y;
if (dx * dx + dy * dy <= toleranceSq) // 平方距离比较(避免开方)
{
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
points.Add((point.X, point.Y));
_totalPoints++;
}
}
}
///
/// 查找最近顶点(带容差范围)
///
public (double X, double Y)? FindClosestVertex(double x, double y, double tolerance)
{
long centerX = (long)(x / _cellSize);
long centerY = (long)(y / _cellSize);
int radius = (int)Math.Ceiling(tolerance / _cellSize);
double minDist = tolerance * tolerance;
(double X, double Y)? closest = null;
// 网格搜索范围扩展
for (long dx = -radius; dx <= radius; dx++)
{
if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
for (long dy = -radius; dy <= radius; dy++)
{
if (!yDict.TryGetValue(centerY + dy, out var points)) continue;
foreach (var (pX, pY) in points)
{
double dxVal = pX - x;
double dyVal = pY - y;
double distSq = dxVal * dxVal + dyVal * dyVal;
if (distSq < minDist)
{
minDist = distSq;
closest = (pX, pY);
}
}
}
}
return closest;
}
///
/// 根据坐标获取相邻范围内的所有点
///
///
///
///
///
public List<(double X, double Y)> FindAllVertices(double x, double y, double tolerance)
{
long centerX = (long)(x / _cellSize);
long centerY = (long)(y / _cellSize);
int radius = (int)Math.Ceiling(tolerance / _cellSize);
var result = new List<(double X, double Y)>();
double toleranceSq = tolerance * tolerance;
// 遍历邻近网格
for (long dx = -radius; dx <= radius; dx++)
{
if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
for (long dy = -radius; dy <= radius; dy++)
{
if (!yDict.TryGetValue(centerY + dy, out var points)) continue;
// 筛选所有容差内的点
foreach (var (pX, pY) in points)
{
double distSq = (pX - x) * (pX - x) + (pY - y) * (pY - y);
if (distSq <= toleranceSq)
{
result.Add((pX, pY));
}
}
}
}
return result;
}
}
///
/// 线段空间索引(使用网格索引+包围盒预计算)
/// 优化点:减少不必要的线段距离计算
///
private class SegmentSpatialIndex
{
private readonly Dictionary>> _grid;
private readonly List _allSegments;
private readonly double _cellSize;
public bool IsEmpty => _grid.Count == 0;
public SegmentSpatialIndex(double cellSize)
{
_cellSize = cellSize;
_grid = new Dictionary>>();
_allSegments = new List();
}
///
/// 添加线段到索引(自动计算影响网格)
///
public void AddSegment(ISegment segment)
{
var segData = new SegmentData(segment.FromPoint.X, segment.FromPoint.Y, segment.ToPoint.X, segment.ToPoint.Y);
lock (_syncRoot)
{
_allSegments.Add(segData); // 全局列表存储引用
// 计算网格范围
long minXCell = (long)(Math.Min(segData.StartX, segData.EndX) / _cellSize);
long maxXCell = (long)(Math.Max(segData.StartX, segData.EndX) / _cellSize);
long minYCell = (long)(Math.Min(segData.StartY, segData.EndY) / _cellSize);
long maxYCell = (long)(Math.Max(segData.StartY, segData.EndY) / _cellSize);
// 添加到所有覆盖的网格(引用传递,无副本)
for (long x = minXCell; x <= maxXCell; x++)
{
for (long y = minYCell; y <= maxYCell; y++)
{
if (!_grid.TryGetValue(x, out var yDict))
{
yDict = new Dictionary>();
_grid[x] = yDict;
}
if (!yDict.TryGetValue(y, out var list))
{
list = new List();
yDict[y] = list;
}
// 避免重复添加(若外部可能重复调用AddSegment)
if (!list.Contains(segData))
{
list.Add(segData);
}
}
}
}
}
///
/// 查找最近线段点(两阶段查询:先网格后全局)
///
public (double X, double Y)? FindClosestPoint(double x, double y, double tolerance)
{
long centerX = (long)(x / _cellSize);
long centerY = (long)(y / _cellSize);
int radius = (int)Math.Ceiling(tolerance / _cellSize);
var candidates = new HashSet();
double minDist = tolerance * tolerance;
(double X, double Y)? closest = null;
// 阶段1:收集附近网格中的候选线段
for (long dx = -radius; dx <= radius; dx++)
{
if (!_grid.TryGetValue(centerX + dx, out var yDict)) continue;
for (long dy = -radius; dy <= radius; dy++)
{
if (yDict.TryGetValue(centerY + dy, out var segList))
{
foreach (var seg in segList)
{
candidates.Add(seg);
}
}
}
}
// 阶段2:如果附近没有候选,则遍历全部线段
if (candidates.Count == 0)
{
candidates = new HashSet(_allSegments);
}
// 计算最近点
foreach (var seg in candidates)
{
var (cx, cy, distSq) = CalculateClosestPoint(x, y, seg);
if (distSq < minDist)
{
minDist = distSq;
closest = (cx, cy);
}
}
return closest;
}
///
/// 计算点到线段的最短距离(向量投影法)
///
private static (double X, double Y, double DistanceSq) CalculateClosestPoint(
double x, double y, SegmentData seg)
{
double dx = seg.EndX - seg.StartX;
double dy = seg.EndY - seg.StartY;
double lengthSq = dx * dx + dy * dy;
// 处理零长度线段
if (lengthSq < 1e-10)
{
double distSq1 = (x - seg.StartX) * (x - seg.StartX) + (y - seg.StartY) * (y - seg.StartY);
return (seg.StartX, seg.StartY, distSq1);
}
// 计算投影参数
double t = ((x - seg.StartX) * dx + (y - seg.StartY) * dy) / lengthSq;
t = Math.Max(0, Math.Min(1, t)); // 限制在线段范围内
double projX = seg.StartX + t * dx;
double projY = seg.StartY + t * dy;
double distSq = (x - projX) * (x - projX) + (y - projY) * (y - projY);
return (projX, projY, distSq);
}
///
/// 线段数据结构(引用类型)
///
private sealed class SegmentData
{
public double StartX { get; }
public double StartY { get; }
public double EndX { get; }
public double EndY { get; }
public SegmentData(double sx, double sy, double ex, double ey)
{
StartX = sx;
StartY = sy;
EndX = ex;
EndY = ey;
}
}
}
#endregion
#region 辅助方法
///
/// 参数有效性校验
///
private static void ValidateParameters(IGeometry target, List adjacentGeometries)
{
if (target == null)
throw new ArgumentNullException(nameof(target), "目标几何体不能为空");
if (adjacentGeometries == null)
throw new ArgumentNullException(nameof(adjacentGeometries), "相邻几何体集合不能为空");
if (target.GeometryType != esriGeometryType.esriGeometryPolygon)
throw new ArgumentException("目标几何体必须是多边形类型");
}
///
/// 收集相邻几何体的边界要素(多线程安全)
///
private static List CollectAdjacentBoundaries(IEnumerable geometries)
{
var boundaries = new ConcurrentBag(); // 线程安全集合
Parallel.ForEach(geometries.Where(g => g?.IsEmpty == false), geom =>
{
switch (geom.GeometryType)
{
case esriGeometryType.esriGeometryPolygon:
var polyColl = (IGeometryCollection)geom;
for (int i = 0; i < polyColl.GeometryCount; i++)
{
if (polyColl.get_Geometry(i) is IRing ring && !ring.IsEmpty)
{
ring.SpatialReference = geom.SpatialReference;
boundaries.Add(ring); // 线程安全添加
}
}
break;
case esriGeometryType.esriGeometryPolyline:
boundaries.Add(geom);
break;
}
});
return boundaries.ToList(); // 转换为普通列表
}
///
/// 确保多边形拓扑有效性
///
private static void EnsureTopologyValidity(ref IPolygon polygon)
{
ITopologicalOperator topoOp = (ITopologicalOperator)polygon;
if (!topoOp.IsSimple)
{
topoOp.Simplify();
}
// 二次验证几何完整性
if (polygon.IsEmpty)
{
throw new InvalidOperationException("拓扑简化导致几何体无效");
}
}
///
/// 安全释放COM对象(带空值检查)
///
private static void SafeReleaseComObject(object comObj)
{
if (comObj != null && Marshal.IsComObject(comObj))
{
Marshal.ReleaseComObject(comObj);
}
}
#endregion
#region MyRegion
private static void Addnode(IPolygon newPolygon, List adjacentGeometries)
{
double maxDistance = 0.1; // 设定最大距离阈值
//待插入节点坐标及索引
Dictionary insertionPoints = new Dictionary();
//原始图形的点坐标及索引
Dictionary originalpoints = new Dictionary();
List polylines = new List();
var coords = new List<(double X, double Y)>();
try
{
IPointCollection points = (IPointCollection)newPolygon;
var pointCount = points.PointCount;
for (int i = 0; i < pointCount; i++)
{
IPoint p = points.get_Point(i);
try
{
coords.Add((p.X, p.Y));
originalpoints.Add(i, (p.X, p.Y));
}
finally
{
Marshal.ReleaseComObject(p);
}
}
if (newPolygon is ISegmentCollection segColl)
{
for (int i = 0; i < segColl.SegmentCount; i++)
{
ISegment segment = segColl.get_Segment(i);
try
{
IPolyline polyline1 = new PolylineClass();
polyline1.FromPoint = segment.FromPoint;
polyline1.ToPoint = segment.ToPoint;
polyline1.SpatialReference = newPolygon.SpatialReference;
polylines.Add(polyline1);
}
finally
{
Marshal.ReleaseComObject(segment);
}
}
}
bool isbreak = false;
foreach (IGeometry geom in adjacentGeometries)
{
if (geom is IPointCollection pointColl)
{
for (int i = 0; i < pointColl.PointCount; i++)
{
IPoint point = pointColl.get_Point(i);
try
{
foreach (var polyline in polylines)
{
double distance = CalculateDistance(point, polyline);
if (distance == 0 || distance > 1) continue;
double distanceToPoint = CalculateDistance(point, polyline.ToPoint);
double distanceFromPoint = CalculateDistance(point, polyline.FromPoint);
if (distance == distanceToPoint || distance == distanceFromPoint) continue;
if ((distance < 0.01 && (distanceToPoint < 0.01) || distanceFromPoint < 0.01))
continue;
if (distance <= maxDistance && distance.ToDouble(5) > 0.00001)
{
if (coords.Contains((point.X, point.Y))) continue;
var coordscoords = coords.FirstOrDefault(kvp => Math.Abs(kvp.X - point.X) < 0.1 && Math.Abs(kvp.Y - point.Y) < 0.1);
if (coordscoords.X != 0 && coordscoords.Y != 0) continue;
IPoint ToPoint = polyline.ToPoint;
var keyValuePair2 = originalpoints.FirstOrDefault(kvp => Math.Abs(kvp.Value.X - ToPoint.X) < 0.0001 && Math.Abs(kvp.Value.Y - ToPoint.Y) < 0.0001);
var pointindex = keyValuePair2.Equals(default(KeyValuePair)) ? -1 : keyValuePair2.Key;
if (insertionPoints.ContainsKey(pointindex)) continue;
insertionPoints.Add(pointindex, (point.X, point.Y));
isbreak = true;
break;
}
}
if (isbreak) break;
}
finally
{
Marshal.ReleaseComObject(point);
}
}
}
if (isbreak) break;
}
if (insertionPoints.Count > 0)
{
foreach (var item in insertionPoints)
coords.Insert(item.Key, item.Value);
points.RemovePoints(0, pointCount);
IPoint newPoint = new PointClass();
foreach (var (X, Y) in coords)
{
newPoint.PutCoords(X, Y);
points.AddPoint(newPoint);
}
Marshal.ReleaseComObject(newPoint);
Addnode(newPolygon, adjacentGeometries);
}
}
catch (Exception)
{
throw;
}
}
#endregion
}
}