using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using KGIS.Framework.AE; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Kingo.Plugin.DataCheck { public static class GeometryAPI { #region 计算两条线段(包含延长线)的交点 /// /// 计算两条线段(包含延长线)的交点 /// /// /// /// public static IPoint GetIntersectPoint(IPolyline pLine1, IPolyline pLine2) { IPoint result = null; var x1 = pLine1.FromPoint.X; var x2 = pLine1.ToPoint.X; var y1 = pLine1.FromPoint.Y; var y2 = pLine1.ToPoint.Y; var x3 = pLine2.FromPoint.X; var x4 = pLine2.ToPoint.X; var y3 = pLine2.FromPoint.Y; var y4 = pLine2.ToPoint.Y; var b1 = (y2 - y1) * x1 + (x1 - x2) * y1; var b2 = (y4 - y3) * x3 + (x3 - x4) * y3; var D = (x2 - x1) * (y4 - y3) - (x4 - x3) * (y2 - y1); var D1 = b2 * (x2 - x1) - b1 * (x4 - x3); var D2 = b2 * (y2 - y1) - b1 * (y4 - y3); var x0 = D1 / D; var y0 = D2 / D; result = new PointClass() { X = x0, Y = y0 }; //} return result; } /// /// 计算两点连线和另一条线段的交点(待验证) /// /// /// /// /// private static IPoint GetIntersectPoint3(IPoint pointStart, IPoint pointEnd, IPolyline targetGeo) { //要返回的延长线终点 IPoint returnPoint = null; IPoint ans, v1, v2; //延长线的长度:用来判断取延长线长度短的点 double distance = double.MaxValue; if (targetGeo != null) { IGeometryCollection geoCollection = targetGeo as IGeometryCollection; for (int i = 0; i < geoCollection.GeometryCount; i++) { IPointCollection points = geoCollection.get_Geometry(i) as IPointCollection; for (int j = 0; j < points.PointCount - 1; j++) { v1 = points.get_Point(j); v2 = points.get_Point(j + 1); if (parallel(pointStart, pointEnd, v1, v2) || !intersect_in(pointStart, pointEnd, v1, v2)) { continue; } else { ans = intersection(pointStart, pointEnd, v1, v2); IPolyline polylineOld = new PolylineClass(); polylineOld.FromPoint = pointStart; polylineOld.ToPoint = pointEnd; polylineOld.SpatialReference = targetGeo.SpatialReference; IPolyline polylineNew = new PolylineClass(); polylineNew.FromPoint = pointEnd; polylineNew.ToPoint = ans; polylineNew.SpatialReference = targetGeo.SpatialReference; if (FeatureAPI.IsInterSect(polylineOld as IPolyline, polylineNew as IPolyline)) { continue; } //延长线的长度:取延长线长度短的点 if (polylineNew.Length < distance) { distance = polylineNew.Length; returnPoint = ans; returnPoint.SpatialReference = targetGeo.SpatialReference; } else { continue; } } } } return returnPoint; } return null; } /// /// 计算来给你调线段的交点(不包含延长线上的点) /// /// /// /// public static IPoint GetIntersectPoint2(IPolyline pLine1, IPolyline pLine2) { IPoint result = new PointClass(); try { ITopologicalOperator pTopo = pLine1 as ITopologicalOperator; result = pTopo.Intersect(pLine2, esriGeometryDimension.esriGeometry0Dimension) as IPoint; return result; } catch (Exception ex) { throw ex; } } /// /// 判两线段相交,包括端点和部分重合 /// /// /// /// /// /// static bool intersect_in(IPoint u1, IPoint u2, IPoint v1, IPoint v2) { if (!dots_inline(u1, u2, v1) || !dots_inline(u1, u2, v2)) { return !same_side(u1, u2, v1, v2) || !same_side(v1, v2, u1, u2); } return dot_online_in(u1, v1, v2) || dot_online_in(u2, v1, v2) || dot_online_in(v1, u1, u2) || dot_online_in(v2, u1, u2); } /// /// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!) /// /// /// /// /// /// static IPoint intersection(IPoint u1, IPoint u2, IPoint v1, IPoint v2) { IPoint ret = new PointClass(); ret.X = u1.X; ret.Y = u1.Y; ret.SpatialReference = u1.SpatialReference; double t = ((u1.X - v1.X) * (v1.Y - v2.Y) - (u1.Y - v1.Y) * (v1.X - v2.X)) / ((u1.X - u2.X) * (v1.Y - v2.Y) - (u1.Y - u2.Y) * (v1.X - v2.X)); ret.X += (u2.X - u1.X) * t; ret.Y += (u2.Y - u1.Y) * t; return ret; } /// /// 计算交叉乘积(P1-P0)x(P2-P0) /// /// /// /// /// static double xmult(IPoint p1, IPoint p2, IPoint p0) { return (p1.X - p0.X) * (p2.Y - p0.Y) - (p2.X - p0.X) * (p1.Y - p0.Y); } /// /// 判点是否在线段上,包括端点 /// /// /// /// /// static bool dot_online_in(IPoint p, IPoint l1, IPoint l2) { double d_xmult = xmult(p, l1, l2); if (((d_xmult > 0 && d_xmult < 1e-8) || (d_xmult < 0 && -d_xmult < 1e-8)) && (l1.X - p.X) * (l2.X - p.X) == 0 && (l1.Y - p.Y) * (l2.Y - p.Y) == 0) { return true; } return false; } /// /// 判两点在线段同侧,点在线段上返回0 /// /// /// /// /// /// static bool same_side(IPoint p1, IPoint p2, IPoint l1, IPoint l2) { return xmult(l1, p1, l2) * xmult(l1, p2, l2) > 1e-8 ? true : false; } /// /// 判两直线平行 /// /// /// /// /// /// static bool parallel(IPoint u1, IPoint u2, IPoint v1, IPoint v2) { return (u1.X - u2.X) * (v1.Y - v2.Y) - (v1.X - v2.X) * (u1.Y - u2.Y) == 0 ? true : false; } /// /// 判三点共线 /// /// /// /// /// static bool dots_inline(IPoint p1, IPoint p2, IPoint p3) { double d_xmult = xmult(p1, p2, p3); if ((d_xmult > 0 && d_xmult < 1e-8) || (d_xmult < 0 && -d_xmult < 1e-8)) { return true; } return false; } #endregion #region 计算两点间距离 public static double TwoPointDistance(IPoint p1, IPoint p2) { double result = -1; result = Math.Abs(Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2))); return result; } #endregion /// /// 获取线段延长线上的点 /// /// /// /// public static IPoint GetExtendedLinePoint(IPolyline pLine, double pLength) { IPoint result = null; double relativeX = pLine.ToPoint.X - pLine.FromPoint.X; double relativeY = pLine.ToPoint.Y - pLine.FromPoint.Y; double hypotenuse = Math.Sqrt(Math.Pow(relativeX, 2) + Math.Pow(relativeY, 2)); double x = relativeX / hypotenuse * pLength; double y = relativeY / hypotenuse * pLength; result = new PointClass() { X = pLine.ToPoint.X + x, Y = pLine.ToPoint.Y + y }; return result; } public static IGeometry UnionGeometry(IGeometry geo1, IGeometry geo2) { IGeometry result = null; try { ITopologicalOperator topo = geo2 as ITopologicalOperator; topo.Simplify(); topo = geo1 as ITopologicalOperator; topo.Simplify(); result = topo.Union(geo2); } catch (Exception ex) { throw ex; } return result; } public static bool IsEqualGeo(IGeometry geo1, IGeometry geo2) { bool result = false; try { IRelationalOperator relat = geo1 as IRelationalOperator; result = relat.Equals(geo2); } catch (Exception ex) { throw ex; } return result; } public static IPolyline GetSegment(IGeometry pGeo, IPoint pPoint, int position = 0) { IPolyline result = new PolylineClass(); if (pGeo == null) return result; if (pGeo.IsEmpty) return result; object o = Type.Missing; try { IHitTest tempLine = null; if (pGeo.GeometryType == esriGeometryType.esriGeometryPolygon) { tempLine = (pGeo as ITopologicalOperator).Boundary as IHitTest; } else if (pGeo.GeometryType == esriGeometryType.esriGeometryPolyline) { tempLine = pGeo as IHitTest; } if (tempLine == null) return result; double DbHitDis = 0; var ptDelete = new PointClass(); int LngPrtIdx = 0; int segIndex = 0; bool BoolHitRt = false; bool Hittest = tempLine.HitTest(pPoint, 1, esriGeometryHitPartType.esriGeometryPartBoundary, ptDelete, ref DbHitDis, ref LngPrtIdx, ref segIndex, ref BoolHitRt); if (Hittest) { ISegmentCollection newSegCol = (ISegmentCollection)result; IGeometryCollection pGeocoll = tempLine as IGeometryCollection; ISegmentCollection lineSegCol = (ISegmentCollection)pGeocoll.Geometry[LngPrtIdx]; ISegment segment = lineSegCol.Segment[segIndex]; if (position == 1) { if (lineSegCol.SegmentCount > segIndex + 1) { segment = lineSegCol.Segment[segIndex + 1]; } else { segment = lineSegCol.Segment[lineSegCol.SegmentCount - 1]; } } else if (position == -1) { if (segIndex == 0) { segment = lineSegCol.Segment[lineSegCol.SegmentCount - 1]; } else { segment = lineSegCol.Segment[segIndex - 1]; } } newSegCol.AddSegment(segment, ref o, ref o); newSegCol.SegmentsChanged(); result = newSegCol as IPolyline; } } catch (Exception ex) { throw ex; } return result; } public static int GetSegmentIndex(IGeometry pGeo, IPoint pPoint, int position = 0) { int result = -1; if (pGeo == null) return result; if (pGeo.IsEmpty) return result; object o = Type.Missing; try { IHitTest tempLine = null; if (pGeo.GeometryType == esriGeometryType.esriGeometryPolygon) { tempLine = (pGeo as ITopologicalOperator).Boundary as IHitTest; } else if (pGeo.GeometryType == esriGeometryType.esriGeometryPolyline) { tempLine = pGeo as IHitTest; } if (tempLine == null) return result; double DbHitDis = 0; var ptDelete = new PointClass(); int LngPrtIdx = 0; int segIndex = 0; bool BoolHitRt = false; bool Hittest = tempLine.HitTest(pPoint, 1, esriGeometryHitPartType.esriGeometryPartBoundary, ptDelete, ref DbHitDis, ref LngPrtIdx, ref segIndex, ref BoolHitRt); if (Hittest) { result = segIndex; } } catch (Exception ex) { throw ex; } return result; } /// /// 获取一条直线上的所有连续的线段 /// /// /// /// public static List GetSegmentsOfStraightLine(IPolyline pLine, IFeatureLayer pLayer) { List result = new List(); try { //result.Add(pLine); IPoint centerPoint = new PointClass() { X = (pLine.FromPoint.X + pLine.ToPoint.X) / 2, Y = (pLine.FromPoint.Y + pLine.ToPoint.Y) / 2 }; double angle = getAngle360(pLine.FromPoint, pLine.ToPoint); List features = FeatureAPI.Identify(centerPoint, pLayer); GetSegmentsOfStraightLine2(angle, centerPoint, pLayer, features, ref result); IPolyline temp = new PolylineClass() { FromPoint = result[0].ToPoint, ToPoint = result[0].FromPoint }; centerPoint = GetExtendedLinePoint(temp, 0.1); //centerPoint= features = FeatureAPI.Identify(centerPoint, pLayer); angle = getAngle360(temp.FromPoint, temp.ToPoint); GetSegmentsOfStraightLine2(angle, centerPoint, pLayer, features, ref result); //GetSegmentsOfStraightLine(angle, pLine.ToPoint, pLayer, ref result, 1); //GetSegmentsOfStraightLine(angle, pLine.FromPoint, pLayer, ref result, -1); } catch (Exception ex) { throw ex; } return result; } private static void GetSegmentsOfStraightLine2(double pAngle, IPoint pPoint, IFeatureLayer pLayer, List pFeatures, ref List pReturnLines, int position = 0) { int num = pReturnLines.Count; while (pFeatures.Count > 0) { IGeometry geo = pFeatures[0].ShapeCopy; pFeatures.Remove(pFeatures[0]); IPolyline line = GetSegment(geo, pPoint); if (line.Length == 0) break; double tempAngle = getAngle360(line.FromPoint, line.ToPoint); while (Math.Abs(pAngle - tempAngle) < 3) { pFeatures.Clear(); if (pReturnLines.FirstOrDefault(f => f.Length == line.Length) != null) break; pReturnLines.Add(line); pPoint = GetExtendedLinePoint(line, 0.1); IPolyline tempLine = GetSegment(geo, pPoint); if (tempLine.Length == 0) break; tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint); if (Math.Abs(pAngle - tempAngle) > 0.1) { pPoint = GetExtendedLinePoint(line, 0.1); } else { line = tempLine; } } while (Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 3) { pFeatures.Clear(); if (pReturnLines.FirstOrDefault(f => f.Length == line.Length) != null) break; pReturnLines.Add(line); IPolyline temp = new PolylineClass() { FromPoint = line.ToPoint, ToPoint = line.FromPoint }; pPoint = GetExtendedLinePoint(temp, 0.1); IPolyline tempLine = GetSegment(geo, pPoint, -1); if (tempLine.Length == 0) break; tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint); if (Math.Abs(Math.Abs(pAngle - tempAngle) - 180) > 0.1) { pPoint = GetExtendedLinePoint(temp, 0.1); } else { line = tempLine; } } } if (num != pReturnLines.Count) { List features = FeatureAPI.Identify(pPoint, pLayer); GetSegmentsOfStraightLine2(pAngle, pPoint, pLayer, features, ref pReturnLines); } } public static IPolyline GetLineByAngle(IPoint pPoint, double pAngle, IFeatureLayer pLayer) { IPolyline line = null; try { List features = FeatureAPI.Identify(pPoint, pLayer); double referAngle = 360; foreach (var item in features) { IPolyline tempLine = GetSegment(item.ShapeCopy, pPoint); double tempAngle = getAngle360(tempLine.FromPoint, tempLine.ToPoint); double angleDiff = Math.Round(Math.Abs(Math.Abs(tempAngle - pAngle) - 90), 2); double angleDiff2 = Math.Round(Math.Abs(Math.Abs(Math.Abs(tempAngle - pAngle) - 180) - 90), 2); bool pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01); if (referAngle > angleDiff && pointOnSegment) { referAngle = angleDiff; line = tempLine; } if (referAngle > angleDiff2 && pointOnSegment) { referAngle = angleDiff2; line = tempLine; } if (Math.Abs(pAngle - tempAngle) < 1 || Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 1) { tempLine = GetSegment(item.ShapeCopy, pPoint, 1); pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01); double tempAngle2 = getAngle360(tempLine.FromPoint, tempLine.ToPoint); angleDiff = Math.Abs(Math.Abs(tempAngle2 - pAngle) - 90); angleDiff2 = Math.Abs(Math.Abs(Math.Abs(tempAngle2 - pAngle) - 180) - 90); if (referAngle > angleDiff && pointOnSegment) { referAngle = angleDiff; line = tempLine; } if (referAngle > angleDiff2 && pointOnSegment) { referAngle = angleDiff2; line = tempLine; } } if (Math.Abs(pAngle - tempAngle) < 1 || Math.Abs(Math.Abs(pAngle - tempAngle) - 180) < 1) { tempLine = GetSegment(item.ShapeCopy, pPoint, -1); pointOnSegment = IsPointOnSegment(pPoint, tempLine, 0.01); double tempAngle2 = getAngle360(tempLine.FromPoint, tempLine.ToPoint); angleDiff = Math.Abs(Math.Abs(tempAngle2 - pAngle) - 90); angleDiff2 = Math.Abs(Math.Abs(Math.Abs(tempAngle2 - pAngle) - 180) - 90); if (referAngle > angleDiff && pointOnSegment) { referAngle = angleDiff; line = tempLine; } if (referAngle > angleDiff2 && pointOnSegment) { referAngle = angleDiff2; line = tempLine; } } } } catch (Exception ex) { throw ex; } return line; } /// /// 判断点pPoint,是否和pLine在同一条直线上 /// /// /// /// /// public static bool IsPointOnLine(IPoint pPoint, IPolyline pLine, double delta) { double xa = pLine.FromPoint.X - pLine.ToPoint.X; double ya = pLine.FromPoint.Y - pLine.ToPoint.Y; double xb = pPoint.X - pLine.ToPoint.X; double yb = pPoint.Y - pLine.ToPoint.Y; return (Math.Abs(yb / xb - ya / xa) <= delta); } /// /// 判断点pPoint,是否在pLine上 /// /// /// /// /// public static bool IsPointOnSegment(IPoint pPoint, IPolyline pLine, double delta) { double xa = Math.Round(pLine.FromPoint.X - pLine.ToPoint.X, 5); double ya = Math.Round(pLine.FromPoint.Y - pLine.ToPoint.Y, 5); double xb = Math.Round(pPoint.X - pLine.ToPoint.X, 5); double yb = Math.Round(pPoint.Y - pLine.ToPoint.Y, 5); if (xb == 0 && yb == 0) return true; return (Math.Abs(yb / xb - ya / xa) < delta && Math.Round(Math.Min(pLine.ToPoint.X, pLine.FromPoint.X), 5) <= Math.Round(pPoint.X, 5) && Math.Round(Math.Max(pLine.ToPoint.X, pLine.FromPoint.X), 5) >= Math.Round(pPoint.X, 5) && Math.Round(Math.Min(pLine.ToPoint.Y, pLine.FromPoint.Y), 5) <= Math.Round(pPoint.Y, 5) && Math.Round(Math.Max(pLine.ToPoint.Y, pLine.FromPoint.Y), 5) >= Math.Round(pPoint.Y, 5)); } //判断点是否在线上,在返回1,不在返回0 public static bool IsPointOnSegment(ICurve pSegment, IPoint Q) { double maxx, minx, maxy, miny; maxx = pSegment.FromPoint.X > pSegment.ToPoint.X ? pSegment.FromPoint.X : pSegment.ToPoint.X; //矩形的右边长 minx = pSegment.FromPoint.X > pSegment.ToPoint.X ? pSegment.ToPoint.X : pSegment.FromPoint.X; //矩形的左边长 maxy = pSegment.FromPoint.Y > pSegment.ToPoint.Y ? pSegment.FromPoint.Y : pSegment.ToPoint.Y; //矩形的上边长 miny = pSegment.FromPoint.Y > pSegment.ToPoint.Y ? pSegment.ToPoint.Y : pSegment.FromPoint.Y; //矩形的下边长 if (((Q.X - pSegment.FromPoint.X) * (pSegment.ToPoint.Y - pSegment.FromPoint.Y) == (pSegment.ToPoint.X - pSegment.FromPoint.X) * (Q.Y - pSegment.FromPoint.Y)) && (Q.X >= minx && Q.X <= maxx) && (Q.Y >= miny && Q.Y <= maxy)) return true; else return false; } public static double getAngle(IPoint p1, IPoint p2) { //两点的x、y值 double x = p2.X - p1.X; double y = p2.Y - p1.Y; double hypotenuse = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)); //斜边长度 double cos = x / hypotenuse; double radian = Math.Acos(cos); //求出弧度 double angle = 180 / (Math.PI / radian); //用弧度算出角度 if (y < 0) { angle = -angle; } else if ((y == 0) && (x < 0)) { angle = 180; } return angle; } public static double getAngle360(IPoint p1, IPoint p2) { //两点的x、y值 double x = p2.X - p1.X; double y = p2.Y - p1.Y; double hypotenuse = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)); //斜边长度 double cos = y / hypotenuse; double radian = Math.Acos(cos); //求出弧度 double angle = 180 / (Math.PI / radian); //用弧度算出角度 if (x < 0) { //angle = -angle; } else if (x > 0) { angle = 360 - angle; } return angle; } /// /// 垂足 /// /// /// /// public static IPoint GetCrossPnt(ICurve line, IPoint pnt) { double dAngle360 = getAngle360(line.FromPoint, line.ToPoint); IPoint pt1 = line.FromPoint; IPoint pt2 = line.ToPoint; if (line.Length == 0) return null; if (pt1.X == pt2.X || dAngle360 == 180 || dAngle360 == 0) { IPoint ptCross = new PointClass(); ptCross.X = pt1.X; ptCross.Y = pnt.Y; return ptCross; } else { double A = (pt1.Y - pt2.Y) / (pt1.X - pt2.X); double B = (pt1.Y - A * pt1.X); /// > 0 = ax +b -y;  对应垂线方程为 -x -ay + m = 0;(m为系数)             /// > A = a; B = b; double m = pnt.X + A * pnt.Y; /// 求两直线交点坐标 IPoint ptCross = new PointClass(); ptCross.X = ((m - A * B) / (A * A + 1)); ptCross.Y = (A * ptCross.X + B); return ptCross; } } public static IPolyline UnionLine(List pGeometry) { try { if (pGeometry == null || pGeometry.Count == 0) return null; if (pGeometry.Count == 1) return pGeometry[0]; IPolyline baseGeo = pGeometry[0]; double angle1 = getAngle360(baseGeo.FromPoint, baseGeo.ToPoint); //IGeometry target = FeatureCopy(baseFeature); ITopologicalOperator2 topo = baseGeo as ITopologicalOperator2; foreach (IPolyline f in pGeometry) { IPolyline tempLine = new PolylineClass(); if (f != baseGeo) { double angle2 = getAngle360(f.FromPoint, f.ToPoint); if (Math.Abs(Math.Abs(angle1 - angle2) - 180) < 1) { tempLine.FromPoint = f.ToPoint; tempLine.ToPoint = f.FromPoint; } else { tempLine = f; } ITopologicalOperator2 topolog = tempLine as ITopologicalOperator2; topolog.Simplify(); topo.Simplify(); topo = topo.Union(tempLine) as ITopologicalOperator2; } } if (!topo.IsSimple) { topo.Simplify(); } //target.Shape = topo as IGeometry; return topo as IPolyline; } catch (Exception ex) { throw ex; } } public static double GetPointOnLineLeftOrRight(IPolyline line, IPoint pnt) { return (line.FromPoint.X - pnt.X) * (line.ToPoint.Y - pnt.Y) - (line.FromPoint.Y - pnt.Y) * (line.ToPoint.X - pnt.X); } /// /// 重构Geometry /// /// 原始Geometry /// 重构后的Geometry public static IGeometry ResetGeometry(IGeometry pGeometry, Point pPoint = null) { try { if (pGeometry == null) return null; //外接矩形左上角的点 Point UpperLeft = pPoint; if (UpperLeft == null) { UpperLeft = new Point(); UpperLeft.X = pGeometry.Envelope.XMin; UpperLeft.Y = pGeometry.Envelope.YMax; UpperLeft.SpatialReference = pGeometry.SpatialReference; } ITopologicalOperator topologicalOperator = pGeometry as ITopologicalOperator; if (topologicalOperator == null) return null; topologicalOperator.Simplify(); //外环图形 GeometryBag ExterGeometryBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).ExteriorRingBag as GeometryBag; if (ExterGeometryBag == null) return null; IGeometryCollection ExterRingGeometryCollection = ExterGeometryBag as IGeometryCollection; IGeometryCollection geometry = new ESRI.ArcGIS.Geometry.PolygonClass() as IGeometryCollection; //List geometry = new List(); for (int g = 0; g < ExterRingGeometryCollection.GeometryCount; g++) { IGeometry ExterGeometry = ExterRingGeometryCollection.get_Geometry(g); IGeometry newGeo = ResetPointCollection(ExterGeometry, UpperLeft) as IGeometry; if (newGeo == null) continue; geometry.AddGeometry(newGeo); //内环图形 IGeometryBag InteriorBag = (topologicalOperator as ESRI.ArcGIS.Geometry.IPolygon4).get_InteriorRingBag(ExterGeometry as IRing); if (InteriorBag == null) continue; IGeometryCollection InteriorRingGeometryCollection = InteriorBag as IGeometryCollection; if (InteriorRingGeometryCollection == null) continue; for (int IG = 0; IG < InteriorRingGeometryCollection.GeometryCount; IG++) { IGeometry interiorGeo = InteriorRingGeometryCollection.get_Geometry(IG); if (interiorGeo == null) continue; IGeometry newInteriorGeo = ResetPointCollection(interiorGeo, UpperLeft) as IGeometry; if (newInteriorGeo == null) continue; geometry.AddGeometry(newInteriorGeo); } } //ITopologicalOperator iTopological = geometry as ITopologicalOperator; //if (iTopological == null) return null; //iTopological.Simplify(); return geometry as IGeometry; } catch (Exception ex) { throw ex; } } /// /// 界址点重新排列 /// /// 原始图形 /// 原始Geometry外接矩形左上角的点 /// private static IPointCollection ResetPointCollection(IGeometry pGeo, Point pUpperLeftPoint) { if (pGeo == null) return null; IPointCollection pointCollection = pGeo as IPointCollection; if (pointCollection == null) return null; //图形的起始点 IPoint startPoint = null; //图形的起始点在原图形中的顺序号 int index = 0; double length = double.MaxValue; #region 获取图形的起始点 for (int p = 0; p < pointCollection.PointCount; p++) { IPoint tempPoint = pointCollection.get_Point(p); Polyline line = new PolylineClass(); line.AddPoint(pUpperLeftPoint); line.AddPoint(tempPoint); if (length > (line as IPolyline).Length) { length = (line as IPolyline).Length; startPoint = tempPoint; index = p; } } #endregion ESRI.ArcGIS.Geometry.IPointCollection poins = new ESRI.ArcGIS.Geometry.Ring() as ESRI.ArcGIS.Geometry.IPointCollection; #region 按照新的起始点重新排列图形 for (int i = 0; i < pointCollection.PointCount; i++) { IPoint point = null; if (index + i < pointCollection.PointCount) { point = pointCollection.get_Point(index + i); } else { if (index + i == pointCollection.PointCount) { continue; } point = pointCollection.get_Point(Math.Abs(pointCollection.PointCount - (index + i))); } point.SpatialReference = pGeo.SpatialReference; poins.AddPoint(point); } #endregion startPoint.SpatialReference = pGeo.SpatialReference; if (index != 0) poins.AddPoint(startPoint); return poins; } } }