ArcGIS Pro SDK (九)几何 4 折线
文章目录
- ArcGIS Pro SDK (九)几何 4 折线
- 1 构造折线 - 从映射点的枚举
- 2 获取折线的点
- 3 获取折线的各个部分
- 4 枚举折线的各个部分
- 5 反转折线中点的顺序
- 6 获取折线的段
- 7 构建多部分折线
- 8 折线的起点
- 9 按角度构造
- 10 按长度构造
- 11 远距离分割折线
环境: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 个点