using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace KGIS.PlatformPlugin.Commands.Tools.TraceTool { public static class PolylineEx { public static IPolygon Buffer(this IPolyline pPolyline, double dLeftRadius, double dRightRadius, int nBufferType) { IBufferConstruction bufferConstruction = new BufferConstructionClass(); IBufferConstructionProperties2 bufferConstructionProperties = bufferConstruction as IBufferConstructionProperties2; IDoubleArray doubleArray = new DoubleArrayClass(); bufferConstructionProperties.EndOption = (esriBufferConstructionEndEnum)nBufferType; if (dLeftRadius > 0.0 && dRightRadius == 0.0) { bufferConstructionProperties.SideOption = esriBufferConstructionSideEnum.esriBufferLeft; doubleArray.Add(dLeftRadius); } else { if (dLeftRadius == 0.0 && dRightRadius > 0.0) { bufferConstructionProperties.SideOption = esriBufferConstructionSideEnum.esriBufferRight; doubleArray.Add(dRightRadius); } else { bufferConstructionProperties.SideOption = esriBufferConstructionSideEnum.esriBufferFull; doubleArray.Add(dLeftRadius); doubleArray.Add(dRightRadius); } } bufferConstructionProperties.UnionOverlappingBuffers = true; bufferConstructionProperties.GenerateCurves = true; IGeometryCollection geometryCollection = new GeometryBagClass(); IGeometryCollection arg_A7_0 = geometryCollection; object value = System.Reflection.Missing.Value; object value2 = System.Reflection.Missing.Value; arg_A7_0.AddGeometry(pPolyline, ref value, ref value2); IGeometryCollection geometryCollection2 = new GeometryBagClass(); bufferConstruction.ConstructBuffersByDistances2(geometryCollection as IEnumGeometry, doubleArray, geometryCollection2); IGeometry geometry = geometryCollection2.get_Geometry(0); return geometry as IPolygon; } public static IPolygon BufferFlat(this IPolyline pPolyline, double dLeftRadius, double dRightRadius) { IConstructCurve constructCurve = new PolylineClass(); IConstructCurve arg_1C_0 = constructCurve; double arg_1C_2 = -dLeftRadius; object value = System.Reflection.Missing.Value; object value2 = System.Reflection.Missing.Value; arg_1C_0.ConstructOffset(pPolyline, arg_1C_2, ref value, ref value2); IConstructCurve constructCurve2 = new PolylineClass(); IConstructCurve arg_3C_0 = constructCurve2; object value3 = System.Reflection.Missing.Value; object value4 = System.Reflection.Missing.Value; arg_3C_0.ConstructOffset(pPolyline, dRightRadius, ref value3, ref value4); (constructCurve2 as IPolyline).ReverseOrientation(); IPointCollection pointCollection = constructCurve as IPointCollection; IPointCollection newPoints = constructCurve2 as IPointCollection; pointCollection.AddPointCollection(newPoints); IPointCollection pointCollection2 = new PolygonClass(); pointCollection2.AddPointCollection(pointCollection); IPointCollection arg_8B_0 = pointCollection2; IPoint arg_8B_1 = pointCollection.get_Point(0); object value5 = System.Reflection.Missing.Value; object value6 = System.Reflection.Missing.Value; arg_8B_0.AddPoint(arg_8B_1, ref value5, ref value6); IPolygon polygon = pointCollection2 as IPolygon; polygon.SimplifyPreserveFromTo(); return polygon; } public static IPolyline AddVertex(this IPolyline pPolyline, IPoint iPoint) { if (pPolyline == null) { return null; } bool flag = false; int num = -1; int num2 = -1; pPolyline.SplitAtPoint(iPoint, true, false, out flag, out num, out num2); return pPolyline; } public static IPolygon ToPolygon(this IPolyline pPolyline) { if (pPolyline == null || !pPolyline.IsClosed) { return null; } ITopologicalOperator topologicalOperator = pPolyline as ITopologicalOperator; topologicalOperator.Simplify(); if (!pPolyline.IsClosed) { return null; } ISegmentCollection segmentCollection = pPolyline as ISegmentCollection; if (segmentCollection != null) { ISegmentCollection segmentCollection2 = new PolygonClass(); segmentCollection2.AddSegmentCollection(segmentCollection); IPolygon polygon = segmentCollection2 as IPolygon; polygon.SpatialReference = pPolyline.SpatialReference; polygon.SimplifyPreserveFromTo(); ITopologicalOperator topologicalOperator2 = polygon as ITopologicalOperator; topologicalOperator2.Simplify(); return polygon; } return null; } public static IPolyline CloseLine(this IPolyline pPolyline) { if (pPolyline == null || pPolyline.IsEmpty) { return null; } if (!pPolyline.IsClosed) { ISegmentCollection segmentCollection = new RingClass(); segmentCollection.AddSegmentCollection(pPolyline as ISegmentCollection); IRing ring = segmentCollection as IRing; ring.Close(); ISegmentCollection segmentCollection2 = new PolylineClass(); segmentCollection2.AddSegmentCollection(ring as ISegmentCollection); return segmentCollection2 as IPolyline; } return pPolyline; } public static bool IsOnBoundary(this IPolyline pPolyline, System.Collections.Generic.List listPolygon) { if (pPolyline != null && listPolygon != null && listPolygon.Count >= 1) { int count = listPolygon.Count; for (int i = 0; i < count; i++) { if (pPolyline.IsOnBoundary(listPolygon[i])) { return true; } } return false; } return false; } public static Tuple GetOffsetPoints(this IPolyline pPolyline, int nCalcType, double dTolerance) { if (pPolyline == null) { return null; } IPoint point = new PointClass(); IPoint point2 = new PointClass(); IPointCollection pointCollection = pPolyline as IPointCollection; int longestLineSegmentStartPoint = pointCollection.GetLongestLineSegmentStartPoint(); if (longestLineSegmentStartPoint < 0) { return null; } IPoint point3 = pointCollection.get_Point(longestLineSegmentStartPoint); IPoint point4 = pointCollection.get_Point(longestLineSegmentStartPoint + 1); IPoint point5 = new PointClass(); point5.PutCoords((point3.X + point4.X) / 2.0, (point3.Y + point4.Y) / 2.0); ILine line = new LineClass(); line.PutCoords(point3, point4); double angle = line.Angle; if (nCalcType == 0) { point.X = point5.X - dTolerance * System.Math.Sin(angle); point.Y = point5.Y + dTolerance * System.Math.Cos(angle); point2.X = point5.X + dTolerance * System.Math.Sin(angle); point2.Y = point5.Y - dTolerance * System.Math.Cos(angle); } else { if (nCalcType == 1) { double num = 0.001; IProximityOperator proximityOperator = point3 as IProximityOperator; double num2 = proximityOperator.ReturnDistance(point4); if (num2 > 1E-06) { num2 /= 2.0; } else { num2 = dTolerance; } point.X = point3.X - num2 * System.Math.Sin(angle + num); point.Y = point3.Y + num2 * System.Math.Cos(angle + num); point2.X = point3.X + num2 * System.Math.Sin(angle - num); point2.Y = point3.Y - num2 * System.Math.Cos(angle - num); } } return new Tuple(point, point2); } public static bool IsOnBoundary(this IPolyline pPolyline, IPolygon iPolygon) { if (iPolygon != null && pPolyline != null) { bool result = false; ITopologicalOperator topologicalOperator = iPolygon as ITopologicalOperator; if (topologicalOperator != null) { IPolyline polyline = topologicalOperator.Boundary as IPolyline; if (polyline != null) { IRelationalOperator relationalOperator = polyline as IRelationalOperator; if (relationalOperator != null) { result = relationalOperator.Contains(pPolyline); } ComReleaser.ReleaseCOMObject(polyline); } } return result; } return false; } public static System.Collections.Generic.List BreakLine(this IPolyline pPolyline, IPolyline pPolylineCutter) { IRelationalOperator relationalOperator = pPolyline as IRelationalOperator; System.Collections.Generic.List selfIntersectPoints = pPolyline.GetSelfIntersectPoints(); if (!relationalOperator.Crosses(pPolylineCutter) && selfIntersectPoints.Count == 0) { return null; } System.Collections.Generic.List intersectPoints = pPolyline.GetIntersectPoints(pPolylineCutter); if (intersectPoints.Count > 0) { selfIntersectPoints.AddRange(intersectPoints); } int count = selfIntersectPoints.Count; System.Collections.Generic.List list = new System.Collections.Generic.List(); IPoint outPoint = new PointClass(); double item = 0.0; double num = 0.0; bool flag = false; for (int i = 0; i < count; i++) { IPoint inPoint = selfIntersectPoints[i]; pPolyline.QueryPointAndDistance(esriSegmentExtension.esriExtendAtFrom, inPoint, false, outPoint, ref item, ref num, ref flag); list.Add(item); } list.Sort(); System.Collections.Generic.List list2 = new System.Collections.Generic.List(); ICurve curve = null; System.Collections.Generic.List list3; for (int j = 0; j < count; j++) { if (j == 0) { pPolyline.GetSubcurve(0.0, list[j], false, out curve); } else { pPolyline.GetSubcurve(list[j - 1], list[j], false, out curve); } (curve as IPolyline).SimplifyNetwork(); list3 = (curve as IPolyline).SplitPolyline(selfIntersectPoints); if (list3 != null && list3.Count != 0) { list2.AddRange(list3); } else { list2.Add(curve as IPolyline); } } pPolyline.GetSubcurve(list[count - 1], pPolyline.Length, false, out curve); list3 = (curve as IPolyline).SplitPolyline(selfIntersectPoints); if (list3 == null || list3.Count == 0) { list2.Add(curve as IPolyline); } else { list2.AddRange(list3); } return list2; } public static System.Collections.Generic.List BreakLine(this IPolyline pPolyline, System.Collections.Generic.List pListPolylineCutter) { IRelationalOperator relationalOperator = pPolyline as IRelationalOperator; System.Collections.Generic.List selfIntersectPoints = pPolyline.GetSelfIntersectPoints(); foreach (IPolyline current in pListPolylineCutter) { if (relationalOperator.Crosses(current)) { System.Collections.Generic.List intersectPoints = pPolyline.GetIntersectPoints(current); if (intersectPoints.Count > 0) { selfIntersectPoints.AddRange(intersectPoints); } } } int count = selfIntersectPoints.Count; if (count == 0) { return null; } System.Collections.Generic.List list = new System.Collections.Generic.List(); IPoint outPoint = new PointClass(); double item = 0.0; double num = 0.0; bool flag = false; for (int i = 0; i < count; i++) { IPoint inPoint = selfIntersectPoints[i]; pPolyline.QueryPointAndDistance(esriSegmentExtension.esriExtendAtFrom, inPoint, false, outPoint, ref item, ref num, ref flag); list.Add(item); } list.Sort(); System.Collections.Generic.List list2 = new System.Collections.Generic.List(); ICurve curve = null; System.Collections.Generic.List list3; for (int j = 0; j < count; j++) { if (j == 0) { pPolyline.GetSubcurve(0.0, list[j], false, out curve); } else { pPolyline.GetSubcurve(list[j - 1], list[j], false, out curve); } (curve as IPolyline).SimplifyNetwork(); list3 = (curve as IPolyline).SplitPolyline(selfIntersectPoints); if (list3 != null && list3.Count != 0) { list2.AddRange(list3); } else { list2.Add(curve as IPolyline); } } pPolyline.GetSubcurve(list[count - 1], pPolyline.Length, false, out curve); (curve as IPolyline).SimplifyNetwork(); list3 = (curve as IPolyline).SplitPolyline(selfIntersectPoints); if (list3 != null && list3.Count != 0) { list2.AddRange(list3); } else { list2.Add(curve as IPolyline); } return list2; } public static System.Collections.Generic.List BreakSelfIntersectLine(this IPolyline pPolyline) { ISegmentCollection segmentCollection = pPolyline as ISegmentCollection; int segmentCount = segmentCollection.SegmentCount; System.Collections.Generic.List list = new System.Collections.Generic.List(); for (int i = 0; i < segmentCount; i++) { ISegment pSegment = segmentCollection.get_Segment(i); for (int j = i + 1; j < segmentCount; j++) { ISegment pSegment2 = segmentCollection.get_Segment(j); System.Collections.Generic.List interserctPoint = pSegment.GetInterserctPoint(pSegment2); if (interserctPoint != null && interserctPoint.Count > 0) { list.AddRange(interserctPoint); } } } System.Collections.Generic.List list2 = new System.Collections.Generic.List(); int count = list.Count; if (count == 0) { list2.Add(pPolyline); return list2; } System.Collections.Generic.List list3 = new System.Collections.Generic.List(); IPoint outPoint = new PointClass(); double item = 0.0; double num = 0.0; bool flag = false; for (int k = 0; k < count; k++) { IPoint inPoint = list[k]; pPolyline.QueryPointAndDistance(esriSegmentExtension.esriExtendAtFrom, inPoint, false, outPoint, ref item, ref num, ref flag); list3.Add(item); } list3.Sort(); ICurve curve = null; System.Collections.Generic.List list4; for (int l = 0; l < count; l++) { if (l == 0) { pPolyline.GetSubcurve(0.0, list3[l], false, out curve); } else { pPolyline.GetSubcurve(list3[l - 1], list3[l], false, out curve); } (curve as IPolyline).SimplifyNetwork(); list4 = (curve as IPolyline).SplitPolyline(list); if (list4 != null && list4.Count != 0) { list2.AddRange(list4); } else { list2.Add(curve as IPolyline); } } pPolyline.GetSubcurve(list3[count - 1], pPolyline.Length, false, out curve); (curve as IPolyline).SimplifyNetwork(); list4 = (curve as IPolyline).SplitPolyline(list); if (list4 != null && list4.Count != 0) { list2.AddRange(list4); } else { list2.Add(curve as IPolyline); } return list2; } public static System.Collections.Generic.List GetSelfIntersectPoints(this IPolyline pPolyline) { ISegmentCollection segmentCollection = pPolyline as ISegmentCollection; int segmentCount = segmentCollection.SegmentCount; System.Collections.Generic.List list = new System.Collections.Generic.List(); for (int i = 0; i < segmentCount; i++) { ISegment pSegment = segmentCollection.get_Segment(i); for (int j = i + 1; j < segmentCount; j++) { ISegment pSegment2 = segmentCollection.get_Segment(j); System.Collections.Generic.List interserctPoint = pSegment.GetInterserctPoint(pSegment2); if (interserctPoint != null && interserctPoint.Count > 0) { list.AddRange(interserctPoint); } } } return list; } public static System.Collections.Generic.List GetIntersectPoints(this IPolyline pPolyline, IPolyline pPolylineOther) { ITopologicalOperator topologicalOperator = pPolyline as ITopologicalOperator; IRelationalOperator relationalOperator = pPolyline as IRelationalOperator; System.Collections.Generic.List list = new System.Collections.Generic.List(); if (relationalOperator.Crosses(pPolylineOther)) { IGeometry geometry = topologicalOperator.Intersect(pPolylineOther, esriGeometryDimension.esriGeometry0Dimension); if (geometry != null && !geometry.IsEmpty) { if (geometry is IPoint) { list.Add(geometry as IPoint); } if (geometry is IMultipoint) { IPointCollection pointCollection = geometry as IPointCollection; int pointCount = pointCollection.PointCount; for (int i = 0; i < pointCount; i++) { IPoint item = pointCollection.get_Point(i); list.Add(item); } } } } return list; } public static System.Collections.Generic.List SplitPolyline(this IPolyline pPolyline, System.Collections.Generic.List plistPoint) { return pPolyline.SplitPolyline(plistPoint, 0.001); } public static System.Collections.Generic.List SplitPolyline(this IPolyline pPolyline, System.Collections.Generic.List plistPoint, double dTolerance) { IRelationalOperator relationalOperator = pPolyline as IRelationalOperator; System.Collections.Generic.List list = new System.Collections.Generic.List(); IPoint point = new PointClass(); double num = 0.0; double num2 = 0.0; bool flag = false; if (dTolerance == 0.0) { dTolerance = 0.001; } foreach (IPoint current in plistPoint) { if (!relationalOperator.Touches(current) && !relationalOperator.Disjoint(current)) { pPolyline.QueryPointAndDistance(esriSegmentExtension.esriExtendAtFrom, current, false, point, ref num, ref num2, ref flag); if (num > dTolerance) { list.Add(num); } } } list.Sort(); ComReleaser.ReleaseCOMObject(point); int count = list.Count; if (count == 0) { return null; } System.Collections.Generic.List list2 = new System.Collections.Generic.List(); ICurve curve = null; for (int i = 0; i < count; i++) { if (i != 0) { pPolyline.GetSubcurve(list[i - 1], list[i], false, out curve); } else { pPolyline.GetSubcurve(0.0, list[i], false, out curve); } (curve as IPolyline).SimplifyNetwork(); list2.Add(curve as IPolyline); } pPolyline.GetSubcurve(list[count - 1], pPolyline.Length, false, out curve); (curve as IPolyline).SimplifyNetwork(); list2.Add(curve as IPolyline); return list2; } public static IPolyline GetFromClosedPolyline(IPolyline pPolyline, int nPointIndex1, int nPointIndex2, bool bAlongPolyline = true) { if (pPolyline != null && !pPolyline.IsEmpty && nPointIndex1 != nPointIndex2) { IPolyline polyline = new PolylineClass(); polyline.SpatialReference = pPolyline.SpatialReference; ISegmentCollection segmentCollection = pPolyline as ISegmentCollection; ISegmentCollection segmentCollection2 = polyline as ISegmentCollection; int segmentCount = segmentCollection.SegmentCount; if (bAlongPolyline) { if (nPointIndex1 >= nPointIndex2) { if (nPointIndex1 > nPointIndex2) { for (int i = nPointIndex1; i < segmentCount; i++) { ISegmentCollection arg_70_0 = segmentCollection2; ISegment arg_70_1 = segmentCollection.get_Segment(i); object value = System.Reflection.Missing.Value; object value2 = System.Reflection.Missing.Value; arg_70_0.AddSegment(arg_70_1, ref value, ref value2); } for (int j = 0; j < nPointIndex2; j++) { ISegmentCollection arg_A0_0 = segmentCollection2; ISegment arg_A0_1 = segmentCollection.get_Segment(j); object value3 = System.Reflection.Missing.Value; object value4 = System.Reflection.Missing.Value; arg_A0_0.AddSegment(arg_A0_1, ref value3, ref value4); } } } else { for (int k = nPointIndex1; k < nPointIndex2; k++) { ISegmentCollection arg_D5_0 = segmentCollection2; ISegment arg_D5_1 = segmentCollection.get_Segment(k); object value5 = System.Reflection.Missing.Value; object value6 = System.Reflection.Missing.Value; arg_D5_0.AddSegment(arg_D5_1, ref value5, ref value6); } } } else { if (nPointIndex1 >= nPointIndex2) { if (nPointIndex1 > nPointIndex2) { for (int l = nPointIndex1 - 1; l >= nPointIndex2; l--) { ISegment segment = segmentCollection.get_Segment(l); segment.ReverseOrientation(); ISegmentCollection arg_125_0 = segmentCollection2; ISegment arg_125_1 = segment; object value7 = System.Reflection.Missing.Value; object value8 = System.Reflection.Missing.Value; arg_125_0.AddSegment(arg_125_1, ref value7, ref value8); } } } else { for (int m = nPointIndex1 - 1; m >= 0; m--) { ISegment segment = segmentCollection.get_Segment(m); segment.ReverseOrientation(); ISegmentCollection arg_164_0 = segmentCollection2; ISegment arg_164_1 = segment; object value9 = System.Reflection.Missing.Value; object value10 = System.Reflection.Missing.Value; arg_164_0.AddSegment(arg_164_1, ref value9, ref value10); } for (int n = segmentCount - 1; n >= nPointIndex2; n--) { ISegment segment = segmentCollection.get_Segment(n); segment.ReverseOrientation(); ISegmentCollection arg_1A1_0 = segmentCollection2; ISegment arg_1A1_1 = segment; object value11 = System.Reflection.Missing.Value; object value12 = System.Reflection.Missing.Value; arg_1A1_0.AddSegment(arg_1A1_1, ref value11, ref value12); } } } polyline.SimplifyNetwork(); return polyline; } return null; } public static IPolyline[] Explode(this IPolyline iPolyline) { IPolyline[] array = null; IGeometryCollection geometryCollection = iPolyline as IGeometryCollection; int geometryCount = geometryCollection.GeometryCount; if (geometryCount != 1) { if (geometryCount > 1) { array = new IPolyline[geometryCount]; for (int i = 0; i < geometryCount; i++) { IPolyline polyline = new PolylineClass(); polyline.SpatialReference = iPolyline.SpatialReference; IPath path = geometryCollection.get_Geometry(i) as IPath; (polyline as ISegmentCollection).AddSegmentCollection(path as ISegmentCollection); polyline.SimplifyNetwork(); (polyline as ITopologicalOperator).Simplify(); array[i] = polyline; } } return array; } return new IPolyline[] { iPolyline }; } public static bool IsSelfIntersection(this IPolyline pPolyline) { ITopologicalOperator3 topologicalOperator = pPolyline as ITopologicalOperator3; topologicalOperator.IsKnownSimple_2 = false; esriNonSimpleReasonEnum esriNonSimpleReasonEnum = esriNonSimpleReasonEnum.esriNonSimpleOK; return !topologicalOperator.get_IsSimpleEx(out esriNonSimpleReasonEnum) && esriNonSimpleReasonEnum == esriNonSimpleReasonEnum.esriNonSimpleSelfIntersections; } public static bool IsSimple(this IPolyline pPolyline) { ITopologicalOperator3 topologicalOperator = pPolyline as ITopologicalOperator3; topologicalOperator.IsKnownSimple_2 = false; esriNonSimpleReasonEnum esriNonSimpleReasonEnum = esriNonSimpleReasonEnum.esriNonSimpleOK; return !topologicalOperator.get_IsSimpleEx(out esriNonSimpleReasonEnum) && esriNonSimpleReasonEnum == esriNonSimpleReasonEnum.esriNonSimpleOK; } public static esriNonSimpleReasonEnum GetNonSimpleReason(this IPolyline pPolyline) { ITopologicalOperator3 topologicalOperator = pPolyline as ITopologicalOperator3; topologicalOperator.IsKnownSimple_2 = false; esriNonSimpleReasonEnum result = esriNonSimpleReasonEnum.esriNonSimpleOK; bool arg_18_0 = topologicalOperator.get_IsSimpleEx(out result); return result; } public static void RepairGeometry(this IPolyline pPolyline) { ITopologicalOperator3 topologicalOperator = pPolyline as ITopologicalOperator3; topologicalOperator.IsKnownSimple_2 = false; topologicalOperator.Simplify(); } } }