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 个点 

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部