阅读量:2
ArcGIS Pro SDK (九)几何 4 折线
文章目录
环境:Visual Studio 2022 + .NET6 + ArcGIS Pro SDK 3.0
1 构造折线 - 从映射点的枚举
// 使用 builderEx 便捷方法或 builderEx 构造函数。 // 都不需要在 MCT 上运行 MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0); MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0); List<MapPoint> list = new List<MapPoint>(); list.Add(startPt); list.Add(endPt); Polyline polyline = PolylineBuilderEx.CreatePolyline(list, SpatialReferences.WGS84); // 使用 AttributeFlags.None 因为列表中只有 2D 点 PolylineBuilderEx pb = new PolylineBuilderEx(list, AttributeFlags.None); pb.SpatialReference = SpatialReferences.WGS84; Polyline polyline2 = pb.ToGeometry(); // 使用 AttributeFlags.NoAttributes 因为列表中只有 2D 点 Polyline polyline4 = PolylineBuilderEx.CreatePolyline(list, AttributeFlags.None);
2 获取折线的点
// 获取点作为只读集合 ReadOnlyPointCollection pts = polyline.Points; int numPts = polyline.PointCount; // 或者 获取点的枚举 IEnumerator<MapPoint> enumPts = polyline.Points.GetEnumerator(); // 或者 获取点坐标作为只读的 Coordinate2D 列表 IReadOnlyList<Coordinate2D> coordinates = polyline.Copy2DCoordinatesToList(); // 或者 获取点坐标作为只读的 Coordinate3D 列表 IReadOnlyList<Coordinate3D> coordinates3D = polyline.Copy3DCoordinatesToList(); // 或者 使用预分配的内存获取集合的子集作为 Coordinate2D IList<Coordinate2D> coordinate2Ds = new List<Coordinate2D>(10); // 分配一些空间 ICollection<Coordinate2D> subsetCoordinates2D = coordinate2Ds; // 分配 pts.Copy2DCoordinatesToList(1, 2, ref subsetCoordinates2D); // 从索引 1 复制 2 个元素到分配的列表 // coordinate2Ds.Count = 2 // 处理 coordinate2Ds // 在不分配更多空间的情况下,获取不同的坐标集 pts.Copy2DCoordinatesToList(5, 9, ref subsetCoordinates2D); // 从索引 5 复制 9 个元素到分配的列表 // coordinate2Ds.Count = 9 // 或者 使用预分配的内存获取集合的子集作为 Coordinate3D IList<Coordinate3D> coordinate3Ds = new List<Coordinate3D>(15); // 分配一些空间 ICollection<Coordinate3D> subsetCoordinates3D = coordinate3Ds; // 分配 pts.Copy3DCoordinatesToList(3, 5, ref subsetCoordinates3D); // 从索引 3 复制 5 个元素到分配的列表 // coordinate3Ds.Count = 5 // 或者 使用预分配的内存获取集合的子集作为 MapPoint IList<MapPoint> mapPoints = new List<MapPoint>(7); // 分配一些空间 ICollection<MapPoint> subsetMapPoint = mapPoints; // 分配 pts.CopyPointsToList(1, 4, ref subsetMapPoint); // 从索引 1 复制 4 个元素到分配的列表 // mapPoints.Count = 4
3 获取折线的各个部分
int numParts = polyline.PartCount; // 获取部分作为只读集合 ReadOnlyPartCollection parts = polyline.Parts;
4 枚举折线的各个部分
ReadOnlyPartCollection polylineParts = polyline.Parts; // 枚举段以获取长度 double len = 0; IEnumerator<ReadOnlySegmentCollection> segments = polylineParts.GetEnumerator(); while (segments.MoveNext()) { ReadOnlySegmentCollection seg = segments.Current; foreach (Segment s in seg) { len += s.Length; // 可能根据段类型执行特定操作 switch (s.SegmentType) { case SegmentType.Line: break; case SegmentType.Bezier: break; case SegmentType.EllipticArc: break; } } } // 或者使用 foreach 模式 foreach (var part in polyline.Parts) { foreach (var segment in part) { len += segment.Length; // 可能根据段类型执行特定操作 switch (segment.SegmentType) { case SegmentType.Line: break; case SegmentType.Bezier: break; case SegmentType.EllipticArc: break; } } }
5 反转折线中点的顺序
var polylineBuilder = new PolylineBuilderEx(polyline); polylineBuilder.ReverseOrientation(); Polyline reversedPolyline = polylineBuilder.ToGeometry();
6 获取折线的段
ICollection<Segment> collection = new List<Segment>(); polyline.GetAllSegments(ref collection); int numSegments = collection.Count; // = 10 IList<Segment> iList = collection as IList<Segment>; for (int i = 0; i < numSegments; i++) { // 处理 iList[i] } // 使用段构建另一条折线 Polyline polylineFromSegments = PolylineBuilderEx.CreatePolyline(collection);
7 构建多部分折线
List<MapPoint> firstPoints = new List<MapPoint>(); firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0)); firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0)); firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0)); firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0)); List<MapPoint> nextPoints = new List<MapPoint>(); nextPoints.Add(MapPointBuilderEx.CreateMapPoint(11.0, 1.0)); nextPoints.Add(MapPointBuilderEx.CreateMapPoint(11.0, 2.0)); nextPoints.Add(MapPointBuilderEx.CreateMapPoint(12.0, 2.0)); nextPoints.Add(MapPointBuilderEx.CreateMapPoint(12.0, 1.0)); // 使用 AttributeFlags.None 因为列表中有 2D 点 PolylineBuilderEx pBuilder = new PolylineBuilderEx(firstPoints, AttributeFlags.None); pBuilder.AddPart(nextPoints); Polyline polyline = pBuilder.ToGeometry(); // polyline 有 2 部分 pBuilder.RemovePart(0); polyline = pBuilder.ToGeometry(); // polyline 有 1 部分
8 折线的起点
// 方法 1: 通过将折线转换为点集合来获取折线的起点,并获取第一个点 // sketchGeometry 是一个 Polyline // 获取草图作为点集合 var pointCol = ((Multipart)sketchGeometry).Points; // 获取线的起点 var firstPoint = pointCol[0]; // 方法 2: 将折线转换为线段集合,并获取第一条线段的 "StartPoint" var polylineGeom = sketchGeometry as ArcGIS.Core.Geometry.Polyline; var polyLineParts = polylineGeom.Parts; ReadOnlySegmentCollection polylineSegments = polyLineParts.First(); // 获取第一个线段作为 LineSegment var firsLineSegment = polylineSegments.First() as LineSegment; // 现在获取起点 var startPoint = firsLineSegment.StartPoint;
9 按角度构造
MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0); double tangentDirection = Math.PI / 6; ArcOrientation orientation = ArcOrientation.ArcCounterClockwise; double startRadius = double.PositiveInfinity; double endRadius = 0.2; ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByAngle; double angle = Math.PI / 2; CurveDensifyMethod densifyMethod = CurveDensifyMethod.ByLength; double densifyParameter = 0.1; Polyline polyline = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, densifyMethod, densifyParameter, SpatialReferences.WGS84); int numPoints = polyline.PointCount; MapPoint queryPoint = polyline.Points[numPoints - 2]; MapPoint pointOnPath; double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated; PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);
10 按长度构造
MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0); MapPoint queryPoint = MapPointBuilderEx.CreateMapPoint(3.8, 1); double tangentDirection = 0; ArcOrientation orientation = ArcOrientation.ArcCounterClockwise; double startRadius = double.PositiveInfinity; double endRadius = 1; ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByLength; double curveLength = 10; MapPoint pointOnPath; double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated; PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84); pointOnPath = MapPointBuilderEx.CreateMapPoint(3.7652656620171379, 1.0332006103128575); radiusCalculated = 2.4876382887687227; tangentDirectionCalculated = 0.80797056423543978; lengthCalculated = 4.0198770235802987; angleCalculated = 0.80797056423544011; queryPoint = MapPointBuilderEx.CreateMapPoint(1.85, 2.6); PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84); pointOnPath = MapPointBuilderEx.CreateMapPoint(1.8409964973501549, 2.6115979967308132); radiusCalculated = 1; tangentDirectionCalculated = -1.2831853071795867; lengthCalculated = 10; angleCalculated = 5; tangentDirection = Math.PI / 4; orientation = ArcOrientation.ArcClockwise; startRadius = double.PositiveInfinity; endRadius = 0.8; createMethod = ClothoidCreateMethod.ByLength; curveLength = 10; Polyline polyline = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, CurveDensifyMethod.ByLength, 0.5, SpatialReferences.WGS84);
11 远距离分割折线
// 创建点列表 MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0); MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0); List<MapPoint> list = new List<MapPoint>(); list.Add(startPt); list.Add(endPt); // BuilderEx 构造函数不需要在 MCT 上运行。 // 使用 PolylineBuilder,因为我们希望操作几何图形 // 使用 AttributeFlags.None 因为我们有 2D 点 PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(list, AttributeFlags.None); // 在 0.75 处分割 polylineBuilder.SplitAtDistance(0.75, false); // 获取折线 Polyline p = polylineBuilder.ToGeometry(); // 折线 p 应该有 3 个点 (1,1), (1.75, 1), (2,1) // 添加另一条路径 MapPoint p1 = MapPointBuilderEx.CreateMapPoint(4.0, 1.0); MapPoint p2 = MapPointBuilderEx.CreateMapPoint(6.0, 1.0); MapPoint p3 = MapPointBuilderEx.CreateMapPoint(7.0, 1.0); List<MapPoint> pts = new List<MapPoint>(); pts.Add(p1); pts.Add(p2); pts.Add(p3); polylineBuilder.AddPart(pts); p = polylineBuilder.ToGeometry(); // 折线 p 有 2 部分。每部分有 3 个点 // 分割第二条路径的一半 - 不创建新路径 polylineBuilder.SplitPartAtDistance(1, 0.5, true, false); p = polylineBuilder.ToGeometry(); // 折线 p 仍然有 2 部分;但现在有 7 个点