ArcGIS Pro SDK (九)几何 17 几何引擎函数

ArcGIS Pro SDK (九)几何 17 几何引擎函数

文章目录

环境:Visual Studio 2022 + .NET6 + ArcGIS Pro SDK 3.0

1 加速几何图形

// 使用加速来加速关系操作。仅当您要测试许多其他几何图形时才加速源几何图形。
// 加速仅适用于折线和多边形。请注意,加速的几何图形会占用更多内存,因此如果您不会从中受益,请不要加速。

// 以下GeometryEngine函数的性能是唯一可以通过加速几何图形来提高的。
//    GeometryEngine.Instance.Contains
//    GeometryEngine.Instance.Crosses
//    GeometryEngine.Instance.Disjoint
//    GeometryEngine.Instance.Disjoint3D
//    GeometryEngine.Instance.Equals
//    GeometryEngine.Instance.Intersects
//    GeometryEngine.Instance.Relate
//    GeometryEngine.Instance.Touches
//    GeometryEngine.Instance.Within

// 方法需要在MCT上运行
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(
    () =>
    {
        // 加速要测试的几何图形
        var acceleratedPoly = GeometryEngine.Instance.AccelerateForRelationalOperations(polygon);

        // 循环遍历所有要测试的几何图形
        foreach (var testPolygon in testPolygons)
        {
            bool contains = GeometryEngine.Instance.Contains(acceleratedPoly, testPolygon);
            bool within = GeometryEngine.Instance.Within(acceleratedPoly, testPolygon);
            bool crosses = GeometryEngine.Instance.Crosses(acceleratedPoly, testPolygon);
        }
    });

2 确定面的面积

var g1 = PolygonBuilderEx.FromJson("{\"rings\": [ [ [0, 0], [10, 0], [10, 10], [0, 10] ] ] }");
double d = GeometryEngine.Instance.Area(g1);
// d = -100.0 // 由于环的方向错误导致为负值
d = GeometryEngine.Instance.Area(GeometryEngine.Instance.SimplifyAsFeature(g1));
// d = 100.0 // 特征已简化;环的方向正确

3 确定多部分多边形的边界

// 创建一个甜甜圈多边形。必须使用PolygonBuilderEx对象

List<Coordinate2D> outerPts = new List<Coordinate2D>();
outerPts.Add(new Coordinate2D(10.0, 10.0));
outerPts.Add(new Coordinate2D(10.0, 20.0));
outerPts.Add(new Coordinate2D(20.0, 20.0));
outerPts.Add(new Coordinate2D(20.0, 10.0));

List<Coordinate2D> innerPts = new List<Coordinate2D>();
innerPts.Add(new Coordinate2D(13.0, 13.0));
innerPts.Add(new Coordinate2D(17.0, 13.0));
innerPts.Add(new Coordinate2D(17.0, 17.0));
innerPts.Add(new Coordinate2D(13.0, 17.0));

Polygon donut = null;

// 添加外部点
PolygonBuilderEx pb = new PolygonBuilderEx(outerPts);
// 添加内部点(注意它们是逆时针定义的)
pb.AddPart(innerPts);
// 获取多边形
donut = pb.ToGeometry();

// 获取边界
Geometry g = GeometryEngine.Instance.Boundary(donut);
Polyline boundary = g as Polyline;

4 缓冲地图点

// 缓冲一个点
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
Geometry ptBuffer = GeometryEngine.Instance.Buffer(pt, 5.0);
Polygon buffer = ptBuffer as Polygon;

5 缓冲圆弧

// 创建圆弧
MapPoint fromPt = MapPointBuilderEx.CreateMapPoint(2, 1);
MapPoint toPt = MapPointBuilderEx.CreateMapPoint(1, 2);
Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromPt, toPt, interiorPt);

// 缓冲圆弧
Polyline polyline = PolylineBuilderEx.CreatePolyline(circularArc);
Geometry lineBuffer = GeometryEngine.Instance.Buffer(polyline, 10);

6 缓冲多个地图点

// 在每个MapPoint周围创建缓冲区

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

Geometry ptsBuffer = GeometryEngine.Instance.Buffer(pts, 0.25);
Polygon bufferResult = ptsBuffer as Polygon; // bufferResult 将有4部分

7 缓冲多种不同的几何类型

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(4, 2),
    new Coordinate2D(5, 6), new Coordinate2D(7, 8), new Coordinate2D(8, 4),
    new Coordinate2D(9, 10), new Coordinate2D(11, 12), new Coordinate2D(12, 8),
    new Coordinate2D(10, 8), new Coordinate2D(12, 12), new Coordinate2D(14, 10)
};

List<Geometry> manyGeometries = new List<Geometry>
{
    MapPointBuilderEx.CreateMapPoint(coords[9]),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolygonBuilderEx.CreatePolygon(new List<Coordinate2D>(){coords[6], coords[7], coords[8]})
};

Geometry manyGeomBuffer = GeometryEngine.Instance.Buffer(manyGeometries, 0.25);

8 在折线上插值 Z 值

List<Coordinate3D> coords2 = new List<Coordinate3D>()
{
    new Coordinate3D(0, 0, 0),
    new Coordinate3D(0, 1000, double.NaN),
    new Coordinate3D(1000, 1000, 50),
    new Coordinate3D(1000, 1000, 76),
    new Coordinate3D(0, 1000, double.NaN),
    new Coordinate3D(0, 0, 0)
};

SpatialReference sr = SpatialReferences.WebMercator;

Polyline polyline = PolylineBuilderEx.CreatePolyline(coords2, sr);

// polyline.HasZ = true
// polyline.Points[1].HasZ = true
// polyline.Points[1].Z = NaN
// polyline.Points[4].HasZ = true
// polyline.Points[4].Z = NaN

Polyline polylineNoNaNZs = GeometryEngine.Instance.CalculateNonSimpleZs(polyline, 0) as Polyline;

// polylineNoNaNZs.Points[1].HasZ = true
// polylineNoNaNZs.Points[1].Z = 25 (介于0和50之间的一半)
// polylineNoNaNZs.Points[4].HasZ = true
// polylineNoNaNZs.Points[4].Z = 38 (介于76和0之间的一半)

9 在多边形上插值 M 值

List<MapPoint> coords = new List<MapPoint>()
{
    MapPointBuilderEx.CreateMapPoint(0, 0, 0, 0),
    MapPointBuilderEx.CreateMapPoint(0, 1000),
    MapPointBuilderEx.CreateMapPoint(1000, 1000, 10, 50)
};

SpatialReference sr = SpatialReferences.WebMercator;

Polygon polygon = PolygonBuilderEx.CreatePolygon(coords, sr);

// polygon.HasM = true
// polygon.Points[1].HasM = true
// polygon.Points[1].M = NaN

Polygon polygonNoNaNMs = GeometryEngine.Instance.CalculateNonSimpleMs(polygon, 0) as Polygon;

// polygonNoNaNMs.Points[1].HasM = true
// polygonNoNaNMs.Points[1].M = 25 (介于0和50之间的一半)

10 将封套在 X,Y 周围居中

Envelope env = EnvelopeBuilderEx.CreateEnvelope(1.0, 1.0, 5.0, 5.0);
Envelope centered = GeometryEngine.Instance.CenterAt(env, 2.0, 2.0);

// centered.Center.X = 2.0
// centered.Center.Y = 2.0
// centered.XMin = 0
// centered.YMin = 0
// centered.XMax = 4
// centered.YMax = 4

centered = env.CenterAt(4.0, 3.0);
// centered.Center.X == 4.0
// centered.Center.Y == 3.0
// centered.XMin == 2.0
// centered.YMin == 1.0
// centered.XMax == 6.0
// centered.YMax == 5.0

11 查找几何体的质心

// 简单的多边形
List<Coordinate2D> list2D = new List<Coordinate2D>();
list2D.Add(new Coordinate2D(0, 0));
list2D.Add(new Coordinate2D(0, 2));
list2D.Add(new Coordinate2D(2, 2));
list2D.Add(new Coordinate2D(2, 0));

Polygon polygon = PolygonBuilderEx.CreatePolygon(list2D, SpatialReferences.WGS84);

// 验证它是否简单
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);
// 查找质心
MapPoint centroid = GeometryEngine.Instance.Centroid(polygon);
// centroid.X = 1
// centroid.Y = 1

// 地图点
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, SpatialReferences.WGS84);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(5, 2, double.NaN, 7);

// pt1.HasZ = true
// pt1.HasM = true
centroid = GeometryEngine.Instance.Centroid(pt1);
// centroid.HasZ = true
// centroid.HasM = true
// pt1.IsEqual(centroid) = true

// 多点
List<MapPoint> list = new List<MapPoint>() { pt1, pt2 };
Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(list);
// multipoint.HasZ = true
// multipoint.HasM = true

centroid = GeometryEngine.Instance.Centroid(multipoint);
// centroid.X = 3
// centroid.Y = 2
// centroid.HasZ = false
// centroid.HasM = false

12 剪裁折线

// 按封套剪裁折线

Envelope env = EnvelopeBuilderEx.CreateEnvelope(2.0, 2.0, 4.0, 4.0);
LineSegment line = LineBuilderEx.CreateLineSegment(new Coordinate2D(0, 3), new Coordinate2D(5.0, 3.0));
Polyline polyline = PolylineBuilderEx.CreatePolyline(line);

Geometry clipGeom = GeometryEngine.Instance.Clip(polyline, env);

13 按多边形裁剪折线

// 按多边形剪裁折线

List<Coordinate2D> list = new List<Coordinate2D>();
list.Add(new Coordinate2D(1.0, 1.0));
list.Add(new Coordinate2D(1.0, 4.0));
list.Add(new Coordinate2D(4.0, 4.0));
list.Add(new Coordinate2D(4.0, 1.0));

Polygon polygon = PolygonBuilderEx.CreatePolygon(list, SpatialReferences.WGS84);

LineSegment crossingLine = LineBuilderEx.CreateLineSegment(MapPointBuilderEx.CreateMapPoint(0, 3), MapPointBuilderEx.CreateMapPoint(5.0, 3.0));
Polyline p = PolylineBuilderEx.CreatePolyline(crossingLine);
Geometry geometry = GeometryEngine.Instance.Clip(p, polygon.Extent);

14 构建具有指定距离和方位角的大地测量线

var sr = SpatialReferenceBuilder.CreateSpatialReference(4326);
var mapPoint = MapPointBuilderEx.CreateMapPoint(15, 60, sr);

// 计算
var polylineGeodetic = GeometryEngine.Instance.ConstructGeodeticLineFromDistance(GeodeticCurveType.Loxodrome, mapPoint, 5000000, 45, null, CurveDensifyMethod.ByLength, 300000);

15 构建连接点的大地测量线

var sr = SpatialReferenceBuilder.CreateSpatialReference(4326);

var pt1 = MapPointBuilderEx.CreateMapPoint(60, 180, sr);
var pt2 = MapPointBuilderEx.CreateMapPoint(60, 0, sr);

// 按长度加密
var gl = GeometryEngine.Instance.ConstructGeodeticLineFromPoints(GeodeticCurveType.Geodesic, pt1, pt2, null, CurveDensifyMethod.ByLength, -3.356);

// 按偏差加密
gl = GeometryEngine.Instance.ConstructGeodeticLineFromPoints(GeodeticCurveType.Geodesic, pt1, pt2, null, CurveDensifyMethod.ByDeviation, -0.0026);

16 在距现有点一定距离和一定角度处构造点

MapPoint inPoint = MapPointBuilderEx.CreateMapPoint(3, 4);
double angle = 0;
double distance = 10;

MapPoint outPoint = GeometryEngine.Instance.ConstructPointFromAngleDistance(inPoint, angle, distance);
// outPoint.X = 13
// outPoint.Y = 4

SpatialReference sr = SpatialReferences.WGS84;
inPoint = MapPointBuilderEx.CreateMapPoint(0, 0, sr);
angle = Math.PI;
distance = 1;

outPoint = GeometryEngine.Instance.ConstructPointFromAngleDistance(inPoint, angle, distance, sr);
// outPoint.X = -1
// outPoint.Y = 0

17 从一组折线构造多边形

List<Coordinate2D> firstLinePts = new List<Coordinate2D>();
firstLinePts.Add(new Coordinate2D(1.0, 1.0));
firstLinePts.Add(new Coordinate2D(1.0, 4.0));

List<Coordinate2D> secondLinePts = new List<Coordinate2D>();
secondLinePts.Add(new Coordinate2D(4.0, 4.0));
secondLinePts.Add(new Coordinate2D(4.0, 1.0));

List<Coordinate2D> thirdLinePts = new List<Coordinate2D>();
thirdLinePts.Add(new Coordinate2D(0.0, 2.0));
thirdLinePts.Add(new Coordinate2D(5.0, 2.0));

List<Coordinate2D> fourthLinePts = new List<Coordinate2D>();
fourthLinePts.Add(new Coordinate2D(0.0, 3.0));
fourthLinePts.Add(new Coordinate2D(5.0, 3.0));

// 构建折线
List<Polyline> polylines = new List<Polyline>();
polylines.Add(PolylineBuilderEx.CreatePolyline(firstLinePts));
polylines.Add(PolylineBuilderEx.CreatePolyline(secondLinePts));
polylines.Add(PolylineBuilderEx.CreatePolyline(thirdLinePts));
polylines.Add(PolylineBuilderEx.CreatePolyline(fourthLinePts));

// 从折线构建多边形
var polygons = GeometryEngine.Instance.ConstructPolygonsFromPolylines(polylines);

// polygons.Count = 1
// 多边形坐标为 (1.0, 2.0), (1.0, 3.0), (4.0, 3.0), (4.0, 2.0)

18 多边形包含地图点、折线、多边形

// 构建一个多边形
List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

Polygon poly = PolygonBuilderEx.CreatePolygon(pts);

// 测试内部点是否被包含
MapPoint innerPt = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);
bool contains = GeometryEngine.Instance.Contains(poly, innerPt);   // contains = true

// 测试边界上的点
contains = GeometryEngine.Instance.Contains(poly, poly.Points[0]);     // contains = false

// 测试内部线
MapPoint innerPt2 = MapPointBuilderEx.CreateMapPoint(1.25, 1.75);
List<MapPoint> innerLinePts = new List<MapPoint>();
innerLinePts.Add(innerPt);
innerLinePts.Add(innerPt2);

// 测试内部折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(innerLinePts);
contains = GeometryEngine.Instance.Contains(poly, polyline);   // contains = true

// 测试穿过边界的线
MapPoint outerPt = MapPointBuilderEx.CreateMapPoint(3, 1.5);
List<MapPoint> crossingLinePts = new List<MapPoint>();
crossingLinePts.Add(innerPt);
crossingLinePts.Add(outerPt);

polyline = PolylineBuilderEx.CreatePolyline(crossingLinePts);
contains = GeometryEngine.Instance.Contains(poly, polyline);     // contains = false

// 测试多边形中的多边形
Envelope env = EnvelopeBuilderEx.CreateEnvelope(innerPt, innerPt2);
contains = GeometryEngine.Instance.Contains(poly, env);      // contains = true

19 确定凸包

//
// 点的凸包 - 返回一个点
//

MapPoint pt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);
Geometry hull = GeometryEngine.Instance.ConvexHull(pt);
MapPoint hullPt = hull as MapPoint;
// hullPt.X = 2
// hullPt.Y = 2


List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
list.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

//
// 多点的凸包 - 返回一个多边形
//

// 创建一个多点
Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);

hull = GeometryEngine.Instance.ConvexHull(multiPoint);
Polygon hullPoly = hull as Polygon;
// hullPoly.Area = 1
// hullPoly.PointCount = 5

// 
// 折线的凸包 - 返回一个折线或多边形
// 

List<MapPoint> polylineList = new List<MapPoint>();
polylineList.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
polylineList.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));

// 两点直线
Polyline polyline = PolylineBuilderEx.CreatePolyline(polylineList);
hull = GeometryEngine.Instance.ConvexHull(polyline);
Polyline hullPolyline = hull as Polyline;
// hullPolyline.Length = Math.Sqrt(2)
// hullPolyline.PointCount = 2

// 三点折线
polylineList.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));
polyline = PolylineBuilderEx.CreatePolyline(polylineList);
hull = GeometryEngine.Instance.ConvexHull(polyline);
hullPoly = hull as Polygon;
// hullPoly.Length = 2 + Math.Sqrt(2)
// hullPoly.Area = 0.5
// hullPoly.PointCount = 4

//
// 多边形的凸包 - 返回一个多边形
//

// 简单多边形
Polygon poly = PolygonBuilderEx.CreatePolygon(list);
hull = GeometryEngine.Instance.ConvexHull(poly);
hullPoly = hull as Polygon;

// hullPoly.Length = 4.0
// hullPoly.Area = 1.0
// hullPoly.PointCount = 5

// 含有凹角的多边形
List<MapPoint> funkyList = new List<MapPoint>();
funkyList.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(1.5, 1.5));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(1.5, 1.5));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));
funkyList.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));

Polygon funkyPoly = PolygonBuilderEx.CreatePolygon(funkyList);
hull = GeometryEngine.Instance.ConvexHull(funkyPoly);
hullPoly = hull as Polygon;
// hullPoly.Length = 4.0
// hullPoly.Area = 1.0
// hullPoly.PointCount = 5
// hullPoly.Points[0] = 1.0, 1.0
// hullPoly.Points[1] = 1.0, 2.0
// hullPoly.Points[2] = 2.0, 2.0
// hullPoly.Points[3] = 2.0, 1.0
// hullPoly.Points[4] = 1.0, 1.0

20 确定两个几何图形是否相交

//
// 点与点相交
//

MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);

bool crosses = GeometryEngine.Instance.Crosses(pt, pt2);         // crosses = false
crosses = GeometryEngine.Instance.Crosses(pt, pt);               // crosses = false

// 
// 点与折线相交
// 

List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
list.Add(MapPointBuilderEx.CreateMapPoint(3.0, 3.0));
list.Add(MapPointBuilderEx.CreateMapPoint(5.0, 1.0));

Polyline line1 = PolylineBuilderEx.CreatePolyline(list);
crosses = GeometryEngine.Instance.Crosses(line1, pt2);           // crosses = false
crosses = GeometryEngine.Instance.Crosses(pt2, line1);           // crosses = false
// 折线的端点
crosses = GeometryEngine.Instance.Crosses(line1, pt);            // crosses = false

//
// 点与多边形相交
//
List<MapPoint> polyPts = new List<MapPoint>();
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 2.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 2.0));

Polygon poly1 = PolygonBuilderEx.CreatePolygon(polyPts);
crosses = GeometryEngine.Instance.Crosses(poly1, pt);              // crosses = false
crosses = GeometryEngine.Instance.Crosses(pt, poly1);              // crosses = false

// 
// 折线与折线相交
//
List<MapPoint> list2 = new List<MapPoint>();
list2.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(5.0, 3.0));

Polyline line2 = PolylineBuilderEx.CreatePolyline(list2);
crosses = GeometryEngine.Instance.Crosses(line1, line2);           // crosses = true

//
// 折线与多边形相交
//
crosses = GeometryEngine.Instance.Crosses(poly1, line1);           // crosses = true

//
// 多边形与多边形相交
//
Envelope env = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(1.0, 1.0), MapPointBuilderEx.CreateMapPoint(4, 4));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);
crosses = GeometryEngine.Instance.Crosses(poly1, poly2);           // crosses = false

21 使用折线切割几何图形

SpatialReference sr = SpatialReferences.WGS84;

List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, sr));
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 4.0, sr));
list.Add(MapPointBuilderEx.CreateMapPoint(4.0, 4.0, sr));
list.Add(MapPointBuilderEx.CreateMapPoint(4.0, 1.0, sr));

List<Geometry> cutGeometries;

LineSegment line = LineBuilderEx.CreateLineSegment(MapPointBuilderEx.CreateMapPoint(0, 0, sr), MapPointBuilderEx.CreateMapPoint(3, 6, sr));
Polyline cutter = PolylineBuilderEx.CreatePolyline(line);

// 折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(list);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline);
cutGeometries = GeometryEngine.Instance.Cut(polyline, cutter) as List<Geometry>;

Polyline leftPolyline = cutGeometries[0] as Polyline;
Polyline rightPolyline = cutGeometries[1] as Polyline;

// leftPolyline.Points[0] = 1, 2
// leftPolyline.Points[1] = 1, 4
// leftPolyline.Points[2] = 2, 4

// rightPolyline.Points.Count = 5
// rightPolyline.Parts.Count = 2

ReadOnlySegmentCollection segments0 = rightPolyline.Parts[0];
// segments0[0].StartCoordinate = 1, 1
// segments0[0].EndCoordinate = 1, 2

ReadOnlySegmentCollection segments1 = rightPolyline.Parts[1];
// segments1.Count = 2
// segments1[0].StartCoordinate = 2, 4
// segments1[0].EndCoordinate = 4, 4
// segments1[1].StartCoordinate = 4, 4
// segments1[1].EndCoordinate = 4, 1

// 多边形 
Polygon polygon = PolygonBuilderEx.CreatePolygon(list);
isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);
cutGeometries = GeometryEngine.Instance.Cut(polygon, cutter) as List<Geometry>;

22 按长度致密

// 致密化线段
MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(1, 21);
LineSegment line = LineBuilderEx.CreateLineSegment(startPt, endPt);
Polyline polyline = PolylineBuilderEx.CreatePolyline(line);

Geometry geom = GeometryEngine.Instance.DensifyByLength(polyline, 2);
Polyline result = geom as Polyline;


// 致密化圆弧
MapPoint fromPt = MapPointBuilderEx.CreateMapPoint(2, 1);
MapPoint toPt = MapPointBuilderEx.CreateMapPoint(1, 2);
Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

EllipticArcBuilderEx cab = new EllipticArcBuilderEx(fromPt, toPt, interiorPt);
EllipticArcSegment circularArc = cab.ToSegment();
polyline = PolylineBuilderEx.CreatePolyline(circularArc);
geom = GeometryEngine.Instance.DensifyByLength(polyline, 2);
result = geom as Polyline;

23 两个多边形之间的差异

List<MapPoint> polyPts = new List<MapPoint>();
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 2.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 2.0));

Polygon poly1 = PolygonBuilderEx.CreatePolygon(polyPts);

Envelope env = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(1.0, 1.0), MapPointBuilderEx.CreateMapPoint(4, 4));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);

Geometry result = GeometryEngine.Instance.Difference(poly1, poly2);
Polygon polyResult = result as Polygon;
// polyResult.Area = 10.0

result = GeometryEngine.Instance.Difference(poly2, poly1);
polyResult = result as Polygon;
// polyResult.Area = 7.0

24 确定两个几何是否不相交

//
// 点与点
//

MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2.0, 2.5);

bool disjoint = GeometryEngine.Instance.Disjoint(pt, pt2);       // 结果为 true

MultipointBuilderEx mpb = new MultipointBuilderEx();
mpb.AddPoint(pt);
mpb.AddPoint(pt2);
Multipoint multiPoint = mpb.ToGeometry();

disjoint = GeometryEngine.Instance.Disjoint(multiPoint, pt);     // 结果为 false

// 
// 点与折线
// 

List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
list.Add(MapPointBuilderEx.CreateMapPoint(3.0, 3.0));
list.Add(MapPointBuilderEx.CreateMapPoint(5.0, 1.0));

Polyline line1 = PolylineBuilderEx.CreatePolyline(list);
disjoint = GeometryEngine.Instance.Disjoint(line1, pt2);       // 结果为 true

disjoint = GeometryEngine.Instance.Disjoint(pt2, line1);       // 结果为 true

// 折线的端点
disjoint = GeometryEngine.Instance.Disjoint(line1, pt);        // 结果为 false

//
// 点与多边形
//
List<MapPoint> polyPts = new List<MapPoint>();
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 2.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 2.0));

Polygon poly1 = PolygonBuilderEx.CreatePolygon(polyPts);
disjoint = GeometryEngine.Instance.Disjoint(poly1, pt);          // 结果为 true
disjoint = GeometryEngine.Instance.Disjoint(pt, poly1);          // 结果为 true

// 
// 折线与折线
//

List<MapPoint> list2 = new List<MapPoint>();
list2.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(5.0, 3.0));

Polyline line2 = PolylineBuilderEx.CreatePolyline(list2);
disjoint = GeometryEngine.Instance.Disjoint(line1, line2);         // 结果为 false

//
// 折线与多边形
//
disjoint = GeometryEngine.Instance.Disjoint(poly1, line1);         // 结果为 false
disjoint = GeometryEngine.Instance.Disjoint(line1, poly1);         // 结果为 false

//
// 多边形与多边形
//
Envelope env = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(1.0, 1.0), MapPointBuilderEx.CreateMapPoint(4, 4));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);

disjoint = GeometryEngine.Instance.Disjoint(poly1, poly2);         // 结果为 false


// disjoint3D

SpatialReference sr = SpatialReferences.WGS84;

MapPoint pt3D_1 = MapPointBuilderEx.CreateMapPoint(1, 1, 1, sr);
MapPoint pt3D_2 = MapPointBuilderEx.CreateMapPoint(2, 2, 2, sr);
MapPoint pt3D_3 = MapPointBuilderEx.CreateMapPoint(1, 1, 2, sr);

MultipointBuilderEx mpbEx = new MultipointBuilderEx();
mpbEx.AddPoint(pt3D_1);
mpbEx.AddPoint(pt3D_2);
mpbEx.HasZ = true;

multiPoint = mpbEx.ToGeometry();
disjoint = GeometryEngine.Instance.Disjoint3D(multiPoint, pt3D_2);     // disjoint = false
disjoint = GeometryEngine.Instance.Disjoint3D(multiPoint, pt3D_3);     // disjoint = true

25 确定两个几何之间的距离

MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(4.0, 2.0);

//
// 点与点 
//
double d = GeometryEngine.Instance.Distance(pt1, pt2);         // d = Math.Sqrt(2)

//
// 点与多点
//
List<MapPoint> multiPts = new List<MapPoint>();
multiPts.Add(pt2);
multiPts.Add(pt3);
Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(multiPts);
d = GeometryEngine.Instance.Distance(pt1, multiPoint);         // d = Math.Sqrt(2)

//
// 点与包络
//
Envelope env = EnvelopeBuilderEx.CreateEnvelope(pt1, pt2);
d = GeometryEngine.Instance.Distance(pt1, env);                // d = 0

//
// 点与折线
//
List<MapPoint> polylinePts = new List<MapPoint>();
polylinePts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));
polylinePts.Add(pt2);
Polyline polyline = PolylineBuilderEx.CreatePolyline(polylinePts);

d = GeometryEngine.Instance.Distance(pt1, polyline);             // d = 1.0

//
// 点与多边形
//
Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(3.0, 3.0), MapPointBuilderEx.CreateMapPoint(5.0, 5.0));
Polygon poly = PolygonBuilderEx.CreatePolygon(env2);
d = GeometryEngine.Instance.Distance(pt1, poly);                 // d = Math.Sqrt(8)

//
// 包络与折线
//
d = GeometryEngine.Instance.Distance(env, polyline);             // d = 0

//
// 折线与折线
//
List<MapPoint> polylineList = new List<MapPoint>();
polylineList.Add(MapPointBuilderEx.CreateMapPoint(4, 3));
polylineList.Add(MapPointBuilderEx.CreateMapPoint(4, 4));
Polyline polyline2 = PolylineBuilderEx.CreatePolyline(polylineList);

d = GeometryEngine.Instance.Distance(polyline, polyline2);           // d = Math.Sqrt(5)


//
// 多边形与多边形
//
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);
d = GeometryEngine.Instance.Distance(poly, poly2);                 // d = Math.Sqrt(2)

26 确定两个几何体之间的 3D 距离

// 点与点之间
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 1, 1);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2, 2, 2);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(10, 2, 1);

// pt1 到 pt2
double d = GeometryEngine.Instance.Distance3D(pt1, pt2);        // d = Math.Sqrt(3)

// pt1 到 pt3
d = GeometryEngine.Instance.Distance3D(pt1, pt3);        // d = Math.Sqrt(82)

// pt2 到 pt3
d = GeometryEngine.Instance.Distance3D(pt2, pt3);        // d = Math.Sqrt(65)

// 相交的折线

List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 1.0));
list.Add(MapPointBuilderEx.CreateMapPoint(3.0, 3.0, 1.0));
list.Add(MapPointBuilderEx.CreateMapPoint(5.0, 1.0, 1.0));

Polyline line1 = PolylineBuilderEx.CreatePolyline(list);

List<MapPoint> list2 = new List<MapPoint>();
list2.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0, 1.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0, 1.0));
list2.Add(MapPointBuilderEx.CreateMapPoint(5.0, 3.0, 1.0));

Polyline line2 = PolylineBuilderEx.CreatePolyline(list2);

bool intersects = GeometryEngine.Instance.Intersects(line1, line2);    // 相交 = true
d = GeometryEngine.Instance.Distance3D(line1, line2);                  // d = 0   (当几何体相交时距离为 0)

27 展开包络

Envelope env = EnvelopeBuilderEx.CreateEnvelope(100.0, 100.0, 500.0, 500.0);
// env.HasZ = false

Envelope result = GeometryEngine.Instance.Expand(env, 0.5, 0.5, true);
// result.Center = 300, 300
// result.XMin = 200
// result.YMin = 200
// result.XMax = 400
// result.YMax = 400

result = GeometryEngine.Instance.Expand(env, 100, 200, false);
// result.Center = 300, 300
// result.XMin = 0
// result.YMin = -100
// result.XMax = 600
// result.YMax = 700

try
{
  // 在 3 维度上展开
  result = GeometryEngine.Instance.Expand(env, 0.5, 0.5, 0.5, true);
}
catch (InvalidOperationException e)
{
  // 几何体不支持 Z 维度
}

// 展开一个 3D 包络
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(100, 100, 100);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(200, 200, 200);

env = EnvelopeBuilderEx.CreateEnvelope(pt1, pt2);
// env.HasZ = true

result = GeometryEngine.Instance.Expand(env, 0.5, 0.5, 0.5, true);

// result.Center = 150, 150, 150
// result.XMin = 125
// result.YMin = 125
// result.ZMin = 125
// result.XMax = 175
// result.YMax = 175
// result.ZMax = 175

28 扩展折线

// 构建一条折线
var polyline = PolylineBuilderEx.CreatePolyline(new[]
                                                {
                                                    MapPointBuilderEx.CreateMapPoint(1, 1, 10, 20),
                                                    MapPointBuilderEx.CreateMapPoint(0, 0, 10, 20),
                                                    MapPointBuilderEx.CreateMapPoint(1, -1, 10, 20)
                                                });

// 构建扩展线
var extender = PolylineBuilderEx.CreatePolyline(new[]
                                                {
                                                    MapPointBuilderEx.CreateMapPoint(2, 2),
                                                    MapPointBuilderEx.CreateMapPoint(2, -2),
                                                });

// 扩展
var result = GeometryEngine.Instance.Extend(polyline, extender, ExtendFlags.KeepEndAttributes);
Polyline extendedLine = result as Polyline;
// result.Parts[0].Points[0] = 2, 2, 10, 20
// result.Parts[0].Points[1] = 1, 1, 10, 20
// result.Parts[0].Points[2] = 0, 0, 10, 20
// result.Parts[0].Points[3] = 1, -1, 10, 20
// result.Parts[0].Points[4] = 2, -2, 10, 20

// 更改标志
result = GeometryEngine.Instance.Extend(polyline, extender, ExtendFlags.NoEndAttributes);
extendedLine = result as Polyline;
// result.Parts[0].Points[0] = 2, 2, 0
// result.Parts[0].Points[1] = 1, 1, 10, 20
// result.Parts[0].Points[2] = 0, 0, 10, 20
// result.Parts[0].Points[3] = 1, -1, 10, 20
// result.Parts[0].Points[4] = 2, -2, 0

// 扩展
result = GeometryEngine.Instance.Extend(polyline, extender, ExtendFlags.KeepEndAttributes | ExtendFlags.NoExtendAtTo);
extendedLine = result as Polyline;
// result.Parts[0].Points[0] = 2, 2, 10, 20
// result.Parts[0].Points[1] = 1, 1, 10, 20
// result.Parts[0].Points[2] = 0, 0, 10, 20
// result.Parts[0].Points[3] = 1, -1, 10, 20

// 扩展无交集

polyline = PolylineBuilderEx.CreatePolyline(new[]
                                            {
                                                MapPointBuilderEx.CreateMapPoint(1, 1),
                                                MapPointBuilderEx.CreateMapPoint(3, 1)
                                            });

extender = PolylineBuilderEx.CreatePolyline(new[]
                                            {
                                                MapPointBuilderEx.CreateMapPoint(1, 4),
                                                MapPointBuilderEx.CreateMapPoint(3, 4)
                                            });

result = GeometryEngine.Instance.Extend(polyline, extender, ExtendFlags.Default);
// result = null

29 概括

Polyline generalizedPolyline = GeometryEngine.Instance.Generalize(polylineWithZ, 200) as Polyline;
// generalizedPolyline.HasZ = true   // 处理后的折线包含 Z 坐标

Polygon generalized3DPolyline = GeometryEngine.Instance.Generalize3D(polylineWithZ, 200) as Polygon;
// generalized3DPolyline.HasZ = true   // 处理后的三维折线包含 Z 坐标

// 注意:generalized3DPolyline 和 generalizedPolyline 的定义不同
// 即 generalizedPolyline.IsEqual(generalized3DPolyline) = false

30 计算面的测地线面积

var polygon = PolygonBuilderEx.CreatePolygon(new[]
                                             {
                                                 MapPointBuilderEx.CreateMapPoint(-10018754.1713946, 10018754.1713946),
                                                 MapPointBuilderEx.CreateMapPoint(10018754.1713946, 10018754.1713946),
                                                 MapPointBuilderEx.CreateMapPoint(10018754.1713946, -10018754.1713946),
                                                 MapPointBuilderEx.CreateMapPoint(-10018754.1713946, -10018754.1713946)
                                             }, SpatialReferences.WebMercator);
var area = GeometryEngine.Instance.GeodesicArea(polygon);

// area 约等于 255032810857732.31

area = GeometryEngine.Instance.GeodesicArea(polygon, AreaUnit.SquareKilometers);
// area 约等于 255032810.85953, 

31 在指定的测地线距离处创建缓冲区面

// 缓冲一个点
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
Polygon outPolygon = GeometryEngine.Instance.GeodesicBuffer(pt, 5) as Polygon;

double delta = SpatialReferences.WGS84.XYTolerance * 2 * Math.Sqrt(2);
ReadOnlyPointCollection points = outPolygon.Points;
foreach (MapPoint p in points)
{
    double d = GeometryEngine.Instance.GeodesicDistance(pt, p);
    // d = 5 (+- delta)
}

// 指定距离单位
outPolygon = GeometryEngine.Instance.GeodesicBuffer(pt, 5000, LinearUnit.Millimeters) as Polygon;

// 0 距离的缓冲区产生一个空几何体
Geometry g = GeometryEngine.Instance.GeodesicBuffer(pt, 0);
// g.IsEmpty = true

// 缓冲多个点
List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
list.Add(MapPointBuilderEx.CreateMapPoint(10.0, 20.0));
list.Add(MapPointBuilderEx.CreateMapPoint(40.0, 40.0));
list.Add(MapPointBuilderEx.CreateMapPoint(60.0, 60.0));

outPolygon = GeometryEngine.Instance.GeodesicBuffer(list, 10000) as Polygon;
// outPolygon.PartCount = 4

// 缓冲不同的几何类型
List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(1, 2), new Coordinate2D(10, 20), new Coordinate2D(20, 30),
    new Coordinate2D(50, 60), new Coordinate2D(70, 80), new Coordinate2D(80, 40),
    new Coordinate2D(90, 10), new Coordinate2D(110, 15), new Coordinate2D(120, 30),
    new Coordinate2D(10, 40), new Coordinate2D(-10, 40), new Coordinate2D(-10, 50)
};

List<Geometry> manyGeometries = new List<Geometry>
{
    MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolygonBuilderEx.CreatePolygon(new List<Coordinate2D>(){coords[9], coords[10], coords[11]})
};

outPolygon = GeometryEngine.Instance.GeodesicBuffer(manyGeometries, 20000) as Polygon;

// 指定单位类型
outPolygon = GeometryEngine.Instance.GeodesicBuffer(manyGeometries, 20, LinearUnit.Miles) as Polygon;

32 确定两个几何之间的测地线距离

var point1 = MapPointBuilderEx.CreateMapPoint(-170, 45, SpatialReferences.WGS84);
var point2 = MapPointBuilderEx.CreateMapPoint(170, 45, SpatialReferences.WGS84);

var distances_meters = GeometryEngine.Instance.GeodesicDistance(point1, point2);
// 距离约为 1572912.2066940258 米

var distance_feet = GeometryEngine.Instance.GeodesicDistance(point1, point2, LinearUnit.Feet);
// 距离约为  5160473.11904786 英尺

33 测地线椭圆

GeodesicEllipseParameter param = new GeodesicEllipseParameter();
param.AxisDirection = 4 * Math.PI / 3;
param.Center = new Coordinate2D(-120, 60);
param.LinearUnit = LinearUnit.Meters;
param.OutGeometryType = GeometryType.Polyline;
param.SemiAxis1Length = 6500000;
param.SemiAxis2Length = 1500000;
param.VertexCount = 800;

Geometry geometry = GeometryEngine.Instance.GeodesicEllipse(param, SpatialReferences.WGS84);
// geometry.IsEmpty = false

Polyline polyline = geometry as Polyline;
// polyline.PointCount = 801
// polyline.PartCount = 1

34 确定线的测地线长度

var polyline = PolylineBuilderEx.CreatePolyline(new[]
                                                {
                                                    MapPointBuilderEx.CreateMapPoint(-10018754.1713946, 10018754.1713946),
                                                    MapPointBuilderEx.CreateMapPoint(10018754.1713946, 10018754.1713946)
                                                }, SpatialReferences.WebMercator);

var length = GeometryEngine.Instance.GeodesicLength(polyline);
// 长度约为 5243784.5551844323 米

length = GeometryEngine.Instance.GeodesicLength(polyline, LinearUnit.Miles);
// 长度约为 3258.33666089067 英里

var polyline2 = GeometryEngine.Instance.Project(polyline, SpatialReferences.WGS84);
length = GeometryEngine.Instance.GeodesicLength(polyline2);
// 投影后的长度约为 5243784.55518443 米

35 测地线扇区

GeodesicSectorParameter param = new GeodesicSectorParameter();
param.ArcVertexCount = 50;
param.AxisDirection = Math.PI / 4;
param.Center = new Coordinate2D(0, 0);
param.LinearUnit = LinearUnit.Meters;
param.OutGeometryType = GeometryType.Polygon;
param.RadiusVertexCount = 10;
param.SectorAngle = 5 * Math.PI / 3;
param.SemiAxis1Length = 100000;
param.SemiAxis2Length = 20000;
param.StartDirection = 11 * Math.PI / 6;

Geometry geometry = GeometryEngine.Instance.GeodesicSector(param, SpatialReferences.WGS84);
// geometry.IsEmpty = false

Polygon polygon = geometry as Polygon;
// polygon.PointCount = 68
// polygon.PartCount = 1

36 大地测量致密化偏差 - 折线

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(-80, 0),
    new Coordinate2D(-20, 60),
    new Coordinate2D(40, 20),
    new Coordinate2D(0, -20),
    new Coordinate2D(-80, 0)
};

SpatialReference sr = SpatialReferences.WGS84;

// 创建一条折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);

// 按偏差致密化(以千米为单位)
Polyline geodesicPolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Kilometers, GeodeticCurveType.Geodesic) as Polyline;
// 按偏差致密化(以米为单位)
geodesicPolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, GeodeticCurveType.Geodesic) as Polyline;

// 更改曲线类型为横断线
Polyline loxodromePolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, GeodeticCurveType.Loxodrome) as Polyline;

37 大地测量致密按长度 - 多边形

SpatialReference sr = SpatialReferences.WGS84;

MapPoint p1 = MapPointBuilderEx.CreateMapPoint(111, 55, sr);
MapPoint p2 = MapPointBuilderEx.CreateMapPoint(95.5845, 64.2285, sr);

double distance, az12, az21;

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.Geodesic, out az12, out az21);
// 距离 - 1339728.0303777338
// az12 - 326.235780421405
// az21 - 132.87425637913955

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.Loxodrome, out az12, out az21);
// 距离 - 1342745.9687172563
// az12 - 319.966400332104
// az21 - 139.96640033210397

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.GreatElliptic, out az12, out az21);
// 距离 - 1339728.038837946
// az12 - 326.22479262335418
// az21 - 132.88558894347742



MapPoint p3 = MapPointBuilderEx.CreateMapPoint(0, 0, sr);
MapPoint p4 = MapPointBuilderEx.CreateMapPoint(1, 0, sr);

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p3, p4, GeodeticCurveType.Geodesic, out az12, out az21);
// 距离 - 111319.49079327342
// az12 - 90
// az21 - 270

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p3, p4, GeodeticCurveType.Geodesic, LinearUnit.Miles, out az12, out az21);
// 距离 - 69.1707247134693
// az12 - 90
// az21 - 270

38 计算大地测量距离,两点之间的方位角

SpatialReference sr = SpatialReferences.WGS84;

MapPoint p1 = MapPointBuilderEx.CreateMapPoint(111, 55, sr);
MapPoint p2 = MapPointBuilderEx.CreateMapPoint(95.5845, 64.2285, sr);

double distance, az12, az21;

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.Geodesic, out az12, out az21);
// 距离 - 1339728.0303777338
// az12 - 326.235780421405
// az21 - 132.87425637913955

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.Loxodrome, out az12, out az21);
// 距离 - 1342745.9687172563
// az12 - 319.966400332104
// az21 - 139.96640033210397

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.GreatElliptic, out az12, out az21);
// 距离 - 1339728.038837946
// az12 - 326.22479262335418
// az21 - 132.88558894347742



MapPoint p3 = MapPointBuilderEx.CreateMapPoint(0, 0, sr);
MapPoint p4 = MapPointBuilderEx.CreateMapPoint(1, 0, sr);

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p3, p4, GeodeticCurveType.Geodesic, out az12, out az21);
// 距离 - 111319.49079327342
// az12 - 90
// az21 - 270

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p3, p4, GeodeticCurveType.Geodesic, LinearUnit.Miles, out az12, out az21);
// 距离 - 69.1707247134693
// az12 - 90
// az21 - 270

39 对一组地图点执行大地测量移动

SpatialReference sr = SpatialReferences.WebMercator;
var points = new[] { MapPointBuilderEx.CreateMapPoint(0, 0, sr) };
double distance = 10;
double azimuth = Math.PI / 2;
var resultPoints = GeometryEngine.Instance.GeodeticMove(points, sr, distance, LinearUnit.Meters, azimuth, GeodeticCurveType.Geodesic);

// resultPoints.First().X = 10
// resultPoints.First().Y = 0
// resultPoints.First().SpatialReference.Wkid = sr.Wkid

// 更改 LinearUnit 为 Miles
resultPoints = GeometryEngine.Instance.GeodeticMove(points, sr, distance, LinearUnit.Miles, azimuth, GeodeticCurveType.Geodesic);
// resultPoints.First().X = 16093.44
// resultPoints.First().Y = 0

// 更改曲线类型
resultPoints = GeometryEngine.Instance.GeodeticMove(points, sr, distance, LinearUnit.Miles, azimuth, GeodeticCurveType.Loxodrome);
// resultPoints.First().X = 16093.44
// resultPoints.First().Y = 0

40 检索坐标系

// 获取所有地理坐标系
IReadOnlyList<CoordinateSystemListEntry> gcs_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem);

// 获取投影坐标系
IReadOnlyList<CoordinateSystemListEntry> proj_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.ProjectedCoordinateSystem);

// 获取垂直坐标系
IReadOnlyList<CoordinateSystemListEntry> vert_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.VerticalCoordinateSystem);

// 获取地理和投影坐标系
IReadOnlyList<CoordinateSystemListEntry> combined_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem | CoordinateSystemFilter.ProjectedCoordinateSystem);

// 调查其中一个条目
CoordinateSystemListEntry entry = gcs_list[0];
int wkid = entry.Wkid;
string category = entry.Category;
string name = entry.Name;

41 检索系统地理变换

// 地理变换是如何从一个空间参考系投影到另一个空间参考系的定义
IReadOnlyList<GeographicTransformationListEntry> list = GeometryEngine.Instance.GetPredefinedGeographicTransformationList();

// GeographicTransformationListEntry 包含名称、Wkid、从空间参考系 Wkid、到空间参考系 Wkid
GeographicTransformationListEntry entry = list[0];

int fromWkid = entry.FromSRWkid;
int toWkid = entry.ToSRWkid;
int wkid = entry.Wkid;
string name = entry.Name;

42 获取折线或多边形的子曲线

SpatialReference sr = SpatialReferences.WGS84;

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(-111, 72),
    new Coordinate2D(-108, 68),
    new Coordinate2D(-114, 68)
};

Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);

Polyline subCurve = GeometryEngine.Instance.GetSubCurve(polyline, 0, 5, AsRatioOrLength.AsLength);
// subCurve.PartCount = 1
// subCurve.PointCount = 2

ReadOnlyPointCollection points = subCurve.Points;
// points[0] = -111, 72
// points[1] = -108, 68

subCurve = GeometryEngine.Instance.GetSubCurve(polyline, 0, 0.5, AsRatioOrLength.AsRatio);
// subCurve.PointCount = 3

points = subCurve.Points;
// points[0] = -111, 72
// points[1] = -108, 68
// points[2] = -108.5, 68


List<Coordinate3D> coords3D = new List<Coordinate3D>()
{
    new Coordinate3D(0, 0, 0),
    new Coordinate3D(0, 1, 1),
    new Coordinate3D(1, 1, 2),
    new Coordinate3D(1, 0, 3)
};

Polygon polygon = PolygonBuilderEx.CreatePolygon(coords3D, sr);

subCurve = GeometryEngine.Instance.GetSubCurve3D(polygon, 0, 1, AsRatioOrLength.AsLength);
// subCurve.HasZ = true

points = subCurve.Points;
// points.Count = 2
// points[0] = 0, 0, 0
// points[1] = 0, 0.70710678118654746, 0.70710678118654746

43 图形缓冲区

// 锥形接缝和端头帽
SpatialReference sr = SpatialReferenceBuilder.CreateSpatialReference(102010);
List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(1400,6200),
    new Coordinate2D(1600,6300),
    new Coordinate2D(1800,6200)
};

Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);

Polygon polygon = GeometryEngine.Instance.GraphicBuffer(polyline, 50, LineJoinType.Miter, LineCapType.Butt, 10, 0, -1) as Polygon;

// 倒角接缝和圆形帽
Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(0, 0, 10000, 10000, SpatialReferences.WebMercator);

Polygon outPolygon = GeometryEngine.Instance.GraphicBuffer(envelope, 1000, LineJoinType.Bevel, LineCapType.Round, 4, 0, 96) as Polygon;

44 图形缓冲器很多

// 圆形接缝和圆形帽
MapPoint point1 = MapPointBuilderEx.CreateMapPoint(0, 0);
MapPoint point2 = MapPointBuilderEx.CreateMapPoint(1, 1, SpatialReferences.WGS84);
MapPoint point3 = MapPointBuilderEx.CreateMapPoint(1000000, 1200000, SpatialReferences.WebMercator);
List<MapPoint> points = new List<MapPoint>() { point1, point2, point3 };

IReadOnlyList<Geometry> geometries = GeometryEngine.Instance.GraphicBuffer(points, 5, LineJoinType.Round, LineCapType.Round, 0, 0, 3000);

45 两条折线之间的交点

// 确定两条折线之间的交点

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(5.0, 1.0));

Polyline line1 = PolylineBuilderEx.CreatePolyline(pts);

List<MapPoint> pts2 = new List<MapPoint>();
pts2.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0));
pts2.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0));
pts2.Add(MapPointBuilderEx.CreateMapPoint(5.0, 3.0));

Polyline line2 = PolylineBuilderEx.CreatePolyline(pts2);

bool intersects = GeometryEngine.Instance.Intersects(line1, line2);    // intersects = true
Geometry g = GeometryEngine.Instance.Intersection(line1, line2, GeometryDimensionType.EsriGeometry0Dimension);
Multipoint resultMultipoint = g as Multipoint;

// 结果是一个多点,在 (2,2) 和 (4,2) 处交点

46 两个多边形之间的交点

// 确定两个多边形之间的交点

Envelope env1 = EnvelopeBuilderEx.CreateEnvelope(new Coordinate2D(3.0, 2.0), new Coordinate2D(6.0, 6.0));
Polygon poly1 = PolygonBuilderEx.CreatePolygon(env1);

Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(new Coordinate2D(1.0, 1.0), new Coordinate2D(4.0, 4.0));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env2);

Polygon polyResult = GeometryEngine.Instance.Intersection(poly1, poly2) as Polygon;

47 确定多边形的标注点

// 创建一个多边形
List<Coordinate2D> list2D = new List<Coordinate2D>();
list2D.Add(new Coordinate2D(1.0, 1.0));
list2D.Add(new Coordinate2D(1.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 1.0));

Polygon polygon = PolygonBuilderEx.CreatePolygon(list2D);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);
MapPoint pt = GeometryEngine.Instance.LabelPoint(polygon);

48 确定线的长度,长度3D

MapPoint c1 = MapPointBuilderEx.CreateMapPoint(1, 2, 3);
MapPoint c2 = MapPointBuilderEx.CreateMapPoint(4, 2, 4);

// 线段
LineSegment line = LineBuilderEx.CreateLineSegment(c1, c2);
double len = line.Length;     // = 3
double len3D = line.Length3D;   // = Math.Sqrt(10)

// 折线
Polyline p = PolylineBuilderEx.CreatePolyline(line);
double p_len = p.Length;        // = len = 3
double p_len3D = p.Length3D;    // = len3D = Math.Sqrt(10)

double ge_len = GeometryEngine.Instance.Length(p);      // = p_len = len = 3
double ge_len3d = GeometryEngine.Instance.Length3D(p);    // = p_len3D = len3D = Math.Sqrt(10)

49 获取最小和最大 M 值

string json = "{\"hasM\":true,\"rings\":[[[-3000,-2000,10],[-2000,-2000,15],[-1000,-2000,20],[0,-2000,0],[1000,-2000,-20],[2000,-2000,-30],[3000,-2000,10],[4000,-2000,5]]],\"spatialReference\":{\"wkid\":3857}}";
Polygon polygon = PolygonBuilderEx.FromJson(json);

double minM, maxM;
GeometryEngine.Instance.GetMinMaxM(polygon, out minM, out maxM);
// minM = -30 
// maxM = 20

json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,10],[-2000,-2000,null],[-1000,-2000,null]]]}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

GeometryEngine.Instance.GetMinMaxM(polyline, out minM, out maxM);
// minM = 10
// maxM = 10

json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,null],[-2000,-2000,null],[-1000,-2000,null]]]}";
polyline = PolylineBuilderEx.FromJson(json);

GeometryEngine.Instance.GetMinMaxM(polyline, out minM, out maxM);
// minM = double.Nan
// maxM = double.Nan

50 确定 M 是单调的,是升序还是降序

string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,10],[-2000,-2000,15],[-1000,-2000,20]]]}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

MonotonicType monotonic = GeometryEngine.Instance.GetMMonotonic(polyline);
// monotonic = Monotonic.Ascending

json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,10],[-2000,-2000,5],[-1000,-2000,0]]]}";
polyline = PolylineBuilderEx.FromJson(json);

monotonic = GeometryEngine.Instance.GetMMonotonic(polyline);
// monotonic = Monotonic.Descending

json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,10],[-2000,-2000,15],[-1000,-2000,0]]]}";
polyline = PolylineBuilderEx.FromJson(json);

monotonic = GeometryEngine.Instance.GetMMonotonic(polyline);
// monotonic = Monotonic.NotMonotonic

51 获取与几何图形中指定 M 值出现的位置相对应的多点

string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,10],[-2000,-2000,15],[-1000,-2000,20],[0,-2000,0],[1000,-2000,20],[2000,-2000,30],[3000,-2000,10],[4000,-2000,5]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

Multipoint multipoint = GeometryEngine.Instance.GetPointsAtM(polyline, 10, 500);
// multiPoint.PointCount = 4
// multipoint.Points[0]  X= -3000, Y= -2500  M= 10
// multipoint.Points[1]  X= -500, Y= -2500  M= 10
// multipoint.Points[2]  X= 500, Y= -2500  M= 10
// multipoint.Points[3]  X= 3000, Y= -2500  M= 10

52 获取与指定 M 值之间的子曲线对应的折线

string json = "{\"hasM\":true,\"paths\":[[[-2000,0,1],[-1000,1000,2],[-1000,0,3],[1000,1000,4],[2000,1000,5],[2000,2000,6],[3000,2000,7],[4000,0,8]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

Polyline subCurve = GeometryEngine.Instance.GetSubCurveBetweenMs(polyline, 2, 6);
// subCurve.PointCount = 5
// subCurve.Points[0]  X= --1000, Y= 1000 M= 2
// subCurve.Points[1]  X= --1000, Y= 0  M= 3
// subCurve.Points[2]  X= 1000, Y= 1000  M= 4
// subCurve.Points[3]  X= 2000, Y= -1000  M= 5
// subCurve.Points[4]  X= 2000, Y= -2000  M= 6

subCurve = GeometryEngine.Instance.GetSubCurveBetweenMs(polyline, double.NaN, 5);
// subCurve.PointCount = 0
// subCurve.IsEmpty = true

53 获取与沿几何图形中出现指定 M 值的位置处的法线对应的线段

IList<MapPoint> inPoints = new List<MapPoint>()
{
  MapPointBuilderEx.CreateMapPoint(-3000, -2000, 0, 100),
  MapPointBuilderEx.CreateMapPoint(-3000, 0, 0, 200),
  MapPointBuilderEx.CreateMapPoint(-1000, 0, 0, 300),
  MapPointBuilderEx.CreateMapPoint(-1000, 2000, 0, 100),
  MapPointBuilderEx.CreateMapPoint(3000, 2000, 0, 200),
  MapPointBuilderEx.CreateMapPoint(3000, 0, 0, 300),
  MapPointBuilderEx.CreateMapPoint(1000, 0, 0, 100),
  MapPointBuilderEx.CreateMapPoint(1000, -2000, 0, 200),
  MapPointBuilderEx.CreateMapPoint(-3000, -2000, 0, 300)
};

Polygon polygon = PolygonBuilderEx.CreatePolygon(inPoints);
// polygon.HasM = true

Polyline polyline = GeometryEngine.Instance.GetNormalsAtM(polygon, 150, 100);
// polyline.PartCount = 5
// polyline.PointCount = 10
// polyline.HasM = false

ReadOnlyPartCollection parts = polyline.Parts;
ReadOnlySegmentCollection segments = parts[0];
LineSegment line = segments[0] as LineSegment;
// line.StartCoordinate = (-3000, -1000)
// line.EndCoordinate = (-2900, -1000)

segments = parts[1];
line = segments[0] as LineSegment;
// line.StartCoordinate = (-1000, 1500)
// line.EndCoordinate = (-900, 1500)

segments = parts[2];
line = segments[0] as LineSegment;
// line.StartCoordinate = (1000, 2000)
// line.EndCoordinate = (1000, 1900)

segments = parts[3];
line = segments[0] as LineSegment;
// line.StartCoordinate = (1500, 0)
// line.EndCoordinate = (1500, 100)

segments = parts[4];
line = segments[0] as LineSegment;
// line.StartCoordinate = (1000, -1000)
// line.EndCoordinate = (900, -1000)

54 获取沿多部分的指定距离处的 M 值

string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,-3],[-2000,-2000,-2]],[[-2000,-2000,1],[-2000,1000,2]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

// polyline 具有 2 个部分

double m1, m2;
GeometryEngine.Instance.GetMsAtDistance(polyline, 0, AsRatioOrLength.AsLength, out m1, out m2);
// m1 = -3
// m2 = NaN

GeometryEngine.Instance.GetMsAtDistance(polyline, 500, AsRatioOrLength.AsLength, out m1, out m2);
// m1 = -2.5
// m2 = NaN

GeometryEngine.Instance.GetMsAtDistance(polyline, 1000, AsRatioOrLength.AsLength, out m1, out m2);
// m1 = -2
// m2 = 1     // m2 有值,因为距离 1000 是第一个部分的结束,第二个部分的开始

55 将 M 值设置为从多部分开始的累积长度

string json = "{\"hasM\":true,\"rings\":[[[0,0],[0,3000],[4000,3000],[4000,0],[0,0]]],\"spatialReference\":{\"wkid\":3857}}";
Polygon polygon = PolygonBuilderEx.FromJson(json);

Polygon outPolygon = GeometryEngine.Instance.SetMsAsDistance(polygon, AsRatioOrLength.AsLength) as Polygon;
ReadOnlyPointCollection outPoints = outPolygon.Points;
// outPoints M 值为 { 0, 3000, 7000, 10000, 14000 };

56 在给定距离处插入 M 值 - 插入距离

string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,-3],[-2000,-2000,-2],[-1000,-2000,null]]]}";
Polyline polyline = PolylineBuilderEx.FromJson(json);
bool splitHappened;
int partIndex, segmentIndex;

// 一个点已经存在于给定的距离处
double m = -1;
double distance = 2000;
bool createNewPart = false;
Polyline outputPolyline = GeometryEngine.Instance.InsertMAtDistance(polyline, m, distance, AsRatioOrLength.AsLength, createNewPart, out splitHappened, out partIndex, out segmentIndex) as Polyline;

// splitHappened = false, partIndex = 0, segmentIndex = 2
// outputPolyline.Points[2].M = -1

json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,-3],[-2000,-2000,-2],[-1000,-2000,-1]],[[0,0,0],[0,1000,0],[0,2000,2]]],\"spatialReference\":{\"wkid\":3857}}";
polyline = PolylineBuilderEx.FromJson(json);

// 在给定的距离处已经有一个点,但是 createNewPart = true
m = 1;
distance = 3000;
createNewPart = true;
outputPolyline = GeometryEngine.Instance.InsertMAtDistance(polyline, m, distance, AsRatioOrLength.AsLength, createNewPart, out splitHappened, out partIndex, out segmentIndex) as Polyline;
string outputJson = outputPolyline.ToJson();

// splitHappened = true, partIndex = 2, segmentIndex = 0
// outputJson = {"hasM":true,"paths":[[[-3000,-2000,-3],[-2000,-2000,-2],[-1000,-2000,-1]],[[0,0,0],[0,1000,1]],[[0,1000,1],[0,2000,2]]]}}
// 创建了一个新部分,并且 outputPolyline.Points[4] 和 outputPolyline.Points[5] 的 M 值已被修改

// 在给定的距离处没有点
m = 1;
distance = 3500;
createNewPart = false;
outputPolyline = GeometryEngine.Instance.InsertMAtDistance(polyline, m, distance, AsRatioOrLength.AsLength, createNewPart, out splitHappened, out partIndex, out segmentIndex) as Polyline;
outputJson = outputPolyline.ToJson();

// splitHappened = true,即使 createNewPart = false,因为创建了一个新点
// partIndex = 1, segmentIndex = 2
// outputJson = {"hasM":true,"paths":[[[-3000,-2000,-3],[-2000,-2000,-2],[-1000,-2000,-1]],[[0,0,0],[0,1000,0],[0,1500,1],[0,2000,2]]]}
// 通过插值 X 和 Y 坐标,新点 (0, 1500, 1) 被插入,M 值设置为输入的 M 值。

57 使用输入点的 M 值校准 M 值

string json = "{\"hasM\":true,\"paths\":[[[0,0,-1],[1,0,0],[1,1,1],[1,2,2],[3,1,3],[5,3,4],[9,5,5],[7,6,6]]],\"spatialReference\":{\"wkid\":4326}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

// 使用点 (0, 0, 17), (1, 0, 42), (7, 6, 18) 进行插值
List<MapPoint> updatePoints = new List<MapPoint>(3);
MapPointBuilderEx builder = new MapPointBuilderEx(0, 0);
builder.M = 17;
updatePoints.Add(builder.ToGeometry() as MapPoint);

builder.X = 1;
builder.M = 42;
updatePoints.Add(builder.ToGeometry() as MapPoint);

builder.X = 7;
builder.Y = 6;
builder.M = 18;
updatePoints.Add(builder.ToGeometry() as MapPoint);

// 校准多段线中的所有点
double cutOffDistance = polyline.Length;

Polyline updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.Interpolate, cutOffDistance) as Polyline;
// 更新后的多段线中的点为
// (0, 0, 17 ), ( 1, 0, 42 ), ( 1, 1, 38 ), ( 1, 2, 34 ), ( 3, 1, 30 ), ( 5, 3, 26 ), ( 9, 5, 22 ), ( 7, 6, 18 )

// 使用点 (1, 2, 42), (9, 5, 18) 进行外推
builder.X = 1;
builder.Y = 2;
builder.M = 42;
updatePoints[0] = builder.ToGeometry() as MapPoint;

builder.X = 9;
builder.Y = 5;
builder.M = 18;
updatePoints[1] = builder.ToGeometry() as MapPoint;

updatePoints.RemoveAt(2);

updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.ExtrapolateBefore, cutOffDistance) as Polyline;
// 更新后的多段线中的点为
// ( 0, 0, 66 ), ( 1, 0, 58 ), ( 1, 1, 50 ), ( 1, 2, 42 ), ( 3, 1, 3 ), ( 5, 3, 4 ), ( 9, 5, 18 ), ( 7, 6, 6 )

// 使用点 (0, 0, 17), (1, 2, 42) 进行外推
builder.X = 0;
builder.Y = 0;
builder.M = 17;
updatePoints.Insert(0, builder.ToGeometry() as MapPoint);

updatePoints.RemoveAt(2);

updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.ExtrapolateAfter, cutOffDistance) as Polyline;
// 更新后的多段线中的点为
// ( 0, 0, 17 ), ( 1, 0, 0 ), ( 1, 1, 1 ), ( 1, 2, 42 ), ( 3, 1, 50.333333333333333 ), ( 5, 3, 58.666666666666671 ), ( 9, 5, 67 ), ( 7, 6, 75.333333333333343 )

// 外推和插值使用点 (0, 0, 17), (1, 2, 42)
updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.ExtrapolateAfter | UpdateMMethod.Interpolate, cutOffDistance) as Polyline;
// 更新后的多段线中的点为
// (0,0,17),(1,0,25.333333333333336),(1,1,33.666666666666671),(1,2,42),(3,1,50.333333333333336),(5,3,58.666666666666671),(9,5,67),(7,6,75.333333333333343)

58 通过对一系列点进行线性插值生成 M 值

string json = "{\"hasM\":true,\"paths\":[[[0,0,-1],[1,0,0],[1,1,1],[1,2,2],[3,1,3],[5,3,4],[9,5,5],[7,6,6]]],\"spatialReference\":{\"wkid\":4326}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

// 在点 2 和 6 之间插值
Polyline outPolyline = GeometryEngine.Instance.InterpolateMsBetween(polyline, 0, 2, 0, 6) as Polyline;
// 输出多段线的点为
// (0, 0, -1), (1, 0, 0), (1, 1, 1), (1, 2, 1.3796279833912741), (3, 1, 2.2285019604153242), (5, 3, 3.3022520459518998), (9, 5, 5), (7, 6, 6)

59 在几何图形的开头和结尾设置 Ms,并在两个值之间插值 M 值

string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000],[-2000,-2000],[-1000,-2000],[0,-2000],[1000,-2000],[2000,-2000],[3000,-2000],[4000,-2000]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

// 设置 M 值并插值
Polyline updatedPolyline = GeometryEngine.Instance.SetAndInterpolateMsBetween(polyline, -10, 10) as Polyline;
// 输出多段线的点为
// (-3000,-2000,-10), (-2000,-2000,-5), (-1000,-2000,0), (0,-2000,1.6666666666666667), (1000,-2000,3.333333333333333), (2000,-2000,5), (3000,-2000,6.666666666666667), (4000,-2000,8.333333333333334)

60 移动地图点

MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0);
MapPoint ptResult = GeometryEngine.Instance.Move(pt, -3.5, 2.5) as MapPoint;
// ptResult 是 (-2.5, 5.5)

61 移动 z 感知地图点

MapPoint zPt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0, 2.0);
MapPoint zPtResult = GeometryEngine.Instance.Move(zPt, 4, 0.25, 0.5) as MapPoint;
// zPtResult 是 (5.0, 3.25, 2.5);

62 移动折线

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 3.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3, 2, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(4.0, 2.0, 3.0));

Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);

Geometry geometry = GeometryEngine.Instance.Move(polyline, 3, 2);
Polyline polylineResult = geometry as Polyline;
// polylineResult.Points[0] = 4.0, 3.0, 3.0
// polylineResult.Points[1] = 6.0, 5.0, 3.0
// polylineResult.Points[2] = 6.0, 4.0, 3.0
// polylineResult.Points[3] = 7.0, 4.0, 3.0

63 移动点沿线

LineSegment line = LineBuilderEx.CreateLineSegment(MapPointBuilderEx.CreateMapPoint(0, 3), MapPointBuilderEx.CreateMapPoint(5.0, 3.0));
Polyline polyline = PolylineBuilderEx.CreatePolyline(line);
bool simple = GeometryEngine.Instance.IsSimpleAsFeature(polyline);

// ratio = false
MapPoint pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 1.0, false, 0.0, SegmentExtensionType.NoExtension);
// pt = 1.0, 3.0

pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 1.0, false, -1.0, SegmentExtensionType.NoExtension);
// pt = 1.0, 4.0

pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 1.0, false, 2.0, SegmentExtensionType.NoExtension);
// pt = 1.0, 1.0

// ratio = true
pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 0.5, true, 0, SegmentExtensionType.NoExtension);
// pt = 2.5, 3.0

// move past the line
pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 7, false, 0, SegmentExtensionType.NoExtension);
// pt = 5.0, 3.0

// move past the line with extension at "to" point
pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 7, false, 0, SegmentExtensionType.ExtendEmbeddedAtTo);
// pt = 7.0, 3.0

// negative distance with extension at "from" point
pt = GeometryEngine.Instance.MovePointAlongLine(polyline, -2, false, 0, SegmentExtensionType.ExtendEmbeddedAtFrom);
// pt = -2.0, 3.0

// ratio = true
pt = GeometryEngine.Instance.MovePointAlongLine(polyline, 0.5, true, 0, SegmentExtensionType.NoExtension);
// pt = 2.5, 3.0

// line with Z
List<Coordinate3D> coords3D = new List<Coordinate3D> { new Coordinate3D(0, 0, 0), new Coordinate3D(1113195, 1118890, 5000) };
Polyline polylineZ = PolylineBuilderEx.CreatePolyline(coords3D, SpatialReferences.WebMercator);
// polylineZ.HasZ = true

// ratio = true, no offset
pt = GeometryEngine.Instance.MovePointAlongLine(polylineZ, 0.5, true, 0, SegmentExtensionType.NoExtension);
// pt.X = 556597.5
// pt.Y = 559445
// pt.Z = 2500

// ratio = true, past the line with "to" extension, no offset
pt = GeometryEngine.Instance.MovePointAlongLine(polylineZ, 1.5, true, 0, SegmentExtensionType.ExtendEmbeddedAtTo);
// pt.X = 1669792.5
// pt.Y = 1678335
// pt.Z = 7500

// ratio = true, negative distance past the line with no extension, no offset
pt = GeometryEngine.Instance.MovePointAlongLine(polylineZ, -1.5, true, 0, SegmentExtensionType.NoExtension);
// pt.X = 0
// pt.Y = 0
// pt.Z = -7500

// polyline with Z but 2d distance = 0
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(5, 5, 0);
MapPoint pt4 = MapPointBuilderEx.CreateMapPoint(5, 5, 10);
List<MapPoint> pts = new List<MapPoint>() { pt3, pt4 };

polyline = PolylineBuilderEx.CreatePolyline(pts);
// polyline.HasZ = true
// polyline.Length3D = 10
// polyline.Length = 0

MapPoint result = GeometryEngine.Instance.MovePointAlongLine(polyline, 2, false, 0, SegmentExtensionType.NoExtension);
// result = 5, 5, 2

// polyline with length2d = 0 and length3d = 0
MapPoint pt5 = MapPointBuilderEx.CreateMapPoint(5, 5, 10);
MapPoint pt6 = MapPointBuilderEx.CreateMapPoint(5, 5, 10);
pts.Clear();
pts.Add(pt5);
pts.Add(pt6);

polyline = PolylineBuilderEx.CreatePolyline(pts);
// polyline.HasZ = true
// polyline.Length3D = 0
// polyline.Length = 0

result = GeometryEngine.Instance.MovePointAlongLine(polyline, 3, true, 0, SegmentExtensionType.NoExtension);
// result = 5, 5, 10

result = GeometryEngine.Instance.MovePointAlongLine(polyline, 3, true, 0, SegmentExtensionType.ExtendEmbeddedAtFrom);
// result = 5, 5, 10

// polyline with Z and M
List<MapPoint> inputPoints = new List<MapPoint>()
{
    MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4),
    MapPointBuilderEx.CreateMapPoint(1, 2, 33, 44),
};

Polyline polylineZM = PolylineBuilderEx.CreatePolyline(inputPoints, SpatialReferences.WGS84);
// polylineZM.HasZ = true
// polylineZM.HasM = true

// ratio = true, no offset
MapPoint pointAlong = GeometryEngine.Instance.MovePointAlongLine(polylineZM, 0.5, true, 0, SegmentExtensionType.NoExtension);
// pointAlong = 1, 2, 18, 24

// ratio = true with offset
pointAlong = GeometryEngine.Instance.MovePointAlongLine(polylineZM, 0.2, true, 2.23606797749979, SegmentExtensionType.NoExtension);
// pointAlong = 1, 2, 9, 12

64 将几何体的组件分离为单个组件几何图形

List<Coordinate2D> coords2D = new List<Coordinate2D>()
{
    new Coordinate2D(0, 0),
    new Coordinate2D(1, 4),
    new Coordinate2D(2, 7),
    new Coordinate2D(-10, 3)
};

Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(coords2D, SpatialReferences.WGS84);

IReadOnlyList<Geometry> result = GeometryEngine.Instance.MultipartToSinglePart(multipoint);
// result.Count = 4, 

// '爆炸' 多部分多边形
result = GeometryEngine.Instance.MultipartToSinglePart(multipartPolygon);

// 创建几何体袋
Polygon polygon = PolygonBuilderEx.CreatePolygon(coords2D, SpatialReferences.WGS84);
//At 2.x - GeometryBag bag = GeometryBagBuilder.CreateGeometryBag(new List<Geometry>() { multipoint, polygon });
var bag = GeometryBagBuilderEx.CreateGeometryBag(new List<Geometry>() { multipoint, polygon });
// bag.PartCount = =2

result = GeometryEngine.Instance.MultipartToSinglePart(bag);
// result.Count == 2
// result[0] 是 MultiPoint
// result[1] 是 Polygon

65 最近点与最近顶点

SpatialReference sr = SpatialReferences.WGS84;
MapPoint pt = MapPointBuilderEx.CreateMapPoint(5, 5, sr);

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(10, 1),
    new Coordinate2D(10, -4),
    new Coordinate2D(0, -4),
    new Coordinate2D(0, 1),
    new Coordinate2D(10, 1)
};

Polygon polygon = PolygonBuilderEx.CreatePolygon(coords);

// 查找多边形几何中离 pt 最近的点
ProximityResult result = GeometryEngine.Instance.NearestPoint(polygon, pt);
// result.Point = 5, 1
// result.SegmentIndex = 3
// result.PartIndex = 0
// result.PointIndex = null
//result.Distance = 4
//result.RightSide = false

// 查找多边形几何中离 pt 最近的顶点
result = GeometryEngine.Instance.NearestVertex(polygon, pt);
// result.Point = 10, 1
// result.PointIndex = 0
// result.SegmentIndex = null
// result.PartIndex = 0
// result.Distance = Math.Sqrt(41)
// result.RightSide = false

66 确定 3D 中的最近点

MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 1, 1);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2, 2, 2);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(10, 2, 1);

//
// 测试 pt1 到 pt2
//
ProximityResult result = GeometryEngine.Instance.NearestPoint3D(pt1, pt2);
// result.Point = 1,1,1
// result.Distance = Math.Sqrt(3)
// result.SegmentIndex = null
// result.PartIndex = 0
// result.PointIndex = 0
// result.RightSide = false

// 
// 从 pt1 和 pt2 构建的 multipoint。应更接近 pt2
// 
Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(new List<MapPoint>() { pt1, pt2 });
result = GeometryEngine.Instance.NearestPoint3D(multipoint, pt3);
// result.Point = 2, 2, 2
// result.Distance = Math.Sqrt(65)
// result.SegmentIndex = null
// result.PartIndex = 1
// result.PointIndex = 1
// result.RightSide = false

67 计算与源的几何偏移

List<MapPoint> linePts = new List<MapPoint>();
linePts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
linePts.Add(MapPointBuilderEx.CreateMapPoint(10.0, 1.0, SpatialReferences.WGS84));

Polyline polyline = PolylineBuilderEx.CreatePolyline(linePts);

Geometry g = GeometryEngine.Instance.Offset(polyline, 10, OffsetType.Square, 0);
Polyline gResult = g as Polyline;
// gResult.PointCount = 2
// gResult.Points[0] = (1, -9)
// gResult.Points[1] = (10, -9)

g = GeometryEngine.Instance.Offset(polyline, -10, OffsetType.Round, 0.5);
gResult = g as Polyline;
// gResult.PointCount = 2
// gResult.Points[0] = (1, -11
// gResult.Points[1] = (10, 11)

//
// 椭圆弧曲线
//
Coordinate2D fromPt = new Coordinate2D(2, 1);
Coordinate2D toPt = new Coordinate2D(1, 2);
Coordinate2D interiorPt = new Coordinate2D(1 + Math.Sqrt(2) / 2, 1 + Math.Sqrt(2) / 2);

EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromPt.ToMapPoint(), toPt.ToMapPoint(), interiorPt);

polyline = PolylineBuilderEx.CreatePolyline(circularArc);
g = GeometryEngine.Instance.Offset(polyline, -0.25, OffsetType.Miter, 0.5);
gResult = g as Polyline;

g = GeometryEngine.Instance.Offset(polyline, 0.25, OffsetType.Bevel, 0.5);
gResult = g as Polyline;

//
// 多边形的偏移
//
List<MapPoint> list = new List<MapPoint>();
list.Add(MapPointBuilderEx.CreateMapPoint(10.0, 10.0, SpatialReferences.WGS84));
list.Add(MapPointBuilderEx.CreateMapPoint(10.0, 20.0, SpatialReferences.WGS84));
list.Add(MapPointBuilderEx.CreateMapPoint(20.0, 20.0, SpatialReferences.WGS84));
list.Add(MapPointBuilderEx.CreateMapPoint(20.0, 10.0, SpatialReferences.WGS84));

Polygon polygon = PolygonBuilderEx.CreatePolygon(list);

g = GeometryEngine.Instance.Offset(polygon, 2, OffsetType.Square, 0);
Polygon gPolygon = g as Polygon;

g = GeometryEngine.Instance.Offset(polygon, -2, OffsetType.Round, 0.3);
gPolygon = g as Polygon;

g = GeometryEngine.Instance.Offset(polygon, -0.5, OffsetType.Miter, 0.6);
gPolygon = g as Polygon;

68 确定几何图形是否重叠

MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(1.25, 1.75);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(3, 1.5);
MapPoint pt4 = MapPointBuilderEx.CreateMapPoint(1.5, 2);

//
// 点与点的重叠
//
bool overlaps = GeometryEngine.Instance.Overlaps(pt1, pt2);        // 重叠 = false
overlaps = GeometryEngine.Instance.Overlaps(pt1, pt1);             // 重叠 = false
// 如果几何体的交集区域与参与的几何体的维度相同且不等于任一几何体,则它们重叠。

List<MapPoint> pts = new List<MapPoint>();
pts.Add(pt1);
pts.Add(pt2);
pts.Add(pt3);

List<MapPoint> pts2 = new List<MapPoint>();
pts2.Add(pt2);
pts2.Add(pt3);
pts2.Add(pt4);

//
// 点与线的重叠
//
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline);         // isSimple = true
overlaps = GeometryEngine.Instance.Overlaps(polyline, pt1);                  // 重叠 = false

//
// 线与线的重叠
//
Polyline polyline2 = PolylineBuilderEx.CreatePolyline(pts2);
isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline2);             // isSimple = true
overlaps = GeometryEngine.Instance.Overlaps(polyline, polyline2);            // 重叠 = true

69 从 WGS84 到 Web墨卡托的投影

MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0, SpatialReferences.WGS84);
Geometry result = GeometryEngine.Instance.Project(pt, SpatialReferences.WebMercator);
MapPoint projectedPt = result as MapPoint;

70 WGS84的投影

// 创建多边形
List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84));

Polygon polygon = PolygonBuilderEx.CreatePolygon(pts);
// 确保它是简单的
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);

// 创建要投影到的空间参考
SpatialReference northPole = SpatialReferenceBuilder.CreateSpatialReference(102018);   // 北极立体投影 

// 投影
Geometry geometry = GeometryEngine.Instance.Project(polygon, northPole);

71 查询法线

string json = "{\"curvePaths\":[[[-13046586.8335,4036570.6796000004]," +
    "{\"c\":[[-13046645.107099999,4037152.5873000026]," +
    "[-13046132.776277589,4036932.1325614937]]}]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

EllipticArcSegment arc = polyline.Parts[0][0] as EllipticArcSegment;

// 不扩展,沿曲线的距离 = 0.5

// 使用多边形
Polyline poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.NoExtension, 0.5, AsRatioOrLength.AsRatio, 1000);
// 或者使用段
LineSegment seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.NoExtension, 0.5, AsRatioOrLength.AsRatio, 1000);

// 从端点切线,沿曲线的距离 = -1.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendTangentAtFrom, -1.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendTangentAtFrom, -1.2, AsRatioOrLength.AsRatio, 1000);

// 端点切线(忽略,因为沿曲线的距离 < 0),沿曲线的距离 = -1.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendTangentAtTo, -1.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendTangentAtTo, -1.2, AsRatioOrLength.AsRatio, 1000);

// 端点切线,沿曲线的距离 = 1.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendTangentAtTo, 1.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendTangentAtTo, 1.2, AsRatioOrLength.AsRatio, 1000);

// 端点切线(忽略,因为沿曲线的距离 > 0),沿曲线的距离 = 1.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendTangentAtFrom, 1.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendTangentAtFrom, 1.2, AsRatioOrLength.AsRatio, 1000);

// 端点扩展到,沿曲线的距离 = 1.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendEmbeddedAtTo, 1.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendEmbeddedAtTo, 1.2, AsRatioOrLength.AsRatio, 1000);

// 端点扩展到,沿曲线的距离 = -0.2
poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.ExtendEmbeddedAtFrom, -0.2, AsRatioOrLength.AsRatio, 1000);
seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.ExtendEmbeddedAtFrom, -0.2, AsRatioOrLength.AsRatio, 1000);

72 查询点

SpatialReference sr = SpatialReferences.WGS84;

// 水平线段
Coordinate2D start = new Coordinate2D(1, 1);
Coordinate2D end = new Coordinate2D(11, 1);
LineSegment line = LineBuilderEx.CreateLineSegment(start, end, sr);

Polyline polyline = PolylineBuilderEx.CreatePolyline(line);

// 不扩展段

MapPoint outPoint = GeometryEngine.Instance.QueryPoint(polyline, SegmentExtensionType.NoExtension, 1.0, AsRatioOrLength.AsLength);
// outPoint = (2, 1)

// 或者段
MapPoint outPoint_seg = GeometryEngine.Instance.QueryPoint(line, SegmentExtensionType.NoExtension, 1.0, AsRatioOrLength.AsLength);
// outPoint_seg = (2, 1)

// 无限扩展
outPoint = GeometryEngine.Instance.QueryPoint(polyline, SegmentExtensionType.ExtendTangents, 1.5, AsRatioOrLength.AsRatio);
// outPoint = (16, 1)
outPoint_seg = GeometryEngine.Instance.QueryPoint(line, SegmentExtensionType.ExtendTangents, 1.5, AsRatioOrLength.AsRatio);
// outPoint_seg = (16, 1)

73 查询点和距离

// 水平线段
List<MapPoint> linePts = new List<MapPoint>();
linePts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84));
linePts.Add(MapPointBuilderEx.CreateMapPoint(11.0, 1.0, SpatialReferences.WGS84));
Polyline polyline = PolylineBuilderEx.CreatePolyline(linePts);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline);

// 不扩展段
SegmentExtensionType extension = SegmentExtensionType.NoExtension;

// 在线段上的点
MapPoint inPoint = MapPointBuilderEx.CreateMapPoint(2, 1, SpatialReferences.WGS84);

double distanceAlongCurve, distanceFromCurve;
LeftOrRightSide whichSide;
AsRatioOrLength asRatioOrLength = AsRatioOrLength.AsLength;

MapPoint outPoint = GeometryEngine.Instance.QueryPointAndDistance(polyline, extension, inPoint, asRatioOrLength, out distanceAlongCurve, out distanceFromCurve, out whichSide);
// outPoint = 2, 1
// distanceAlongCurve = 1
// distanceFromCurve = 0
// whichSide = GeometryEngine.Instance.LeftOrRightSide.LeftSide


// 无限扩展
extension = SegmentExtensionType.ExtendTangents;

// 左侧的点
inPoint = MapPointBuilderEx.CreateMapPoint(16, 6, SpatialReferences.WGS84);
asRatioOrLength = AsRatioOrLength.AsRatio;

outPoint = GeometryEngine.Instance.QueryPointAndDistance(polyline, extension, inPoint, asRatioOrLength, out distanceAlongCurve, out distanceFromCurve, out whichSide);
// outPoint = 16, 1
// distanceAlongCurve = 1.5
// distanceFromCurve = 5
// whichSide = GeometryEngine.Instance.LeftOrRightSide.LeftSide

74 查询切线

LineSegment line = LineBuilderEx.CreateLineSegment(new Coordinate2D(0, 0), new Coordinate2D(1, 0));

// 不扩展,沿曲线的距离 = 0.5
LineSegment tangent = GeometryEngine.Instance.QueryTangent(line, SegmentExtensionType.NoExtension, 0.5, AsRatioOrLength.AsRatio, 1);
// tangent.StartCoordinate = (0.5, 0.0)
// tangent.EndCoordinate = (1.5, 0.0)

tangent = GeometryEngine.Instance.QueryTangent(line, SegmentExtensionType.NoExtension, 1.5, AsRatioOrLength.AsLength, 1);
// tangent.StartCoordinate = (1.0, 0.0)
// tangent.EndCoordinate = (2.0, 0.0)

tangent = GeometryEngine.Instance.QueryTangent(line, SegmentExtensionType.ExtendTangentAtTo, 1.5, AsRatioOrLength.AsLength, 1);
// tangent.StartCoordinate = (1.5, 0.0)
// tangent.EndCoordinate = (2.5, 0.0)

tangent = GeometryEngine.Instance.QueryTangent(line, SegmentExtensionType.ExtendTangentAtFrom, -1.5, AsRatioOrLength.AsLength, 1);
// tangent.StartCoordinate = (-1.5, 0.0)
// tangent.EndCoordinate = (-0.5, 0.0)

tangent = GeometryEngine.Instance.QueryTangent(line, SegmentExtensionType.ExtendTangentAtFrom, -0.5, AsRatioOrLength.AsRatio, 1);
// tangent.StartCoordinate = (-0.5, 0.0)
// tangent.EndCoordinate = (0.5, 0.0)

75 围绕线反射多边形

SpatialReference sr = SpatialReferences.WGS84;

Coordinate2D start = new Coordinate2D(0, 0);
Coordinate2D end = new Coordinate2D(4, 4);
LineSegment line = LineBuilderEx.CreateLineSegment(start, end, sr);

Coordinate2D[] coords = new Coordinate2D[]
{
    new Coordinate2D(-1, 2),
    new Coordinate2D(-1, 4),
    new Coordinate2D(1, 4),
    new Coordinate2D(-1, 2)
};

Polygon polygon = PolygonBuilderEx.CreatePolygon(coords, sr);

// 将多边形围绕线反射
Polygon reflectedPolygon = GeometryEngine.Instance.ReflectAboutLine(polygon, line) as Polygon;

// reflectedPolygon 的点是
//    (2, -1), (4, -1), (4, 1), (2, -1)

76 确定两个几何图形之间的关系

// 设置一些几何体

// 点
MapPoint point0 = MapPointBuilderEx.CreateMapPoint(0, 0, SpatialReferences.WGS84);
MapPoint point1 = MapPointBuilderEx.CreateMapPoint(1, 1, SpatialReferences.WGS84);
MapPoint point2 = MapPointBuilderEx.CreateMapPoint(-5, 5, SpatialReferences.WGS84);

// 多点
List<MapPoint> points = new List<MapPoint>() { point0, point1, point2 };
Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(points, SpatialReferences.WGS84);

// 多边形 
List<Coordinate2D> polygonCoords = new List<Coordinate2D>()
{
    new Coordinate2D(-10, 0),
    new Coordinate2D(0, 10),
    new Coordinate2D(10, 0),
    new Coordinate2D(-10, 0)
};
Polygon polygon = PolygonBuilderEx.CreatePolygon(polygonCoords, SpatialReferences.WGS84);

// 多条线
Polyline polyline1 = PolylineBuilderEx.CreatePolyline(LineBuilderEx.CreateLineSegment(new Coordinate2D(-9.1, 0.1), new Coordinate2D(0, 9)), SpatialReferences.WGS84);
Polyline polyline2 = PolylineBuilderEx.CreatePolyline(LineBuilderEx.CreateLineSegment(new Coordinate2D(-5, 5), new Coordinate2D(0, 5)), SpatialReferences.WGS84);
Polyline polyline3 = PolylineBuilderEx.CreatePolyline(LineBuilderEx.CreateLineSegment(new Coordinate2D(2.09, -2.04), new Coordinate2D(5, 10)), SpatialReferences.WGS84);
Polyline polyline4 = PolylineBuilderEx.CreatePolyline(LineBuilderEx.CreateLineSegment(new Coordinate2D(10, -5), new Coordinate2D(10, 5)), SpatialReferences.WGS84);

List<Segment> segments = new List<Segment>()
{
    LineBuilderEx.CreateLineSegment(new Coordinate2D(5.05, -2.87), new Coordinate2D(6.35, 1.57)),
    LineBuilderEx.CreateLineSegment(new Coordinate2D(6.35, 1.57), new Coordinate2D(4.13, 2.59)),
    LineBuilderEx.CreateLineSegment(new Coordinate2D(4.13, 2.59), new Coordinate2D(5, 5))
};
Polyline polyline5 = PolylineBuilderEx.CreatePolyline(segments, SpatialReferences.WGS84);

segments.Add(LineBuilderEx.CreateLineSegment(new Coordinate2D(5, 5), new Coordinate2D(10, 10)));

Polyline polyline6 = PolylineBuilderEx.CreatePolyline(segments, SpatialReferences.WGS84);
Polyline polyline7 = PolylineBuilderEx.CreatePolyline(polyline5);
Polyline polyline8 = PolylineBuilderEx.CreatePolyline(LineBuilderEx.CreateLineSegment(new Coordinate2D(5, 5), new Coordinate2D(10, 10)), SpatialReferences.WGS84);

segments.Clear();
segments.Add(LineBuilderEx.CreateLineSegment(new Coordinate2D(0.6, 3.5), new Coordinate2D(0.7, 7)));
segments.Add(LineBuilderEx.CreateLineSegment(new Coordinate2D(0.7, 7), new Coordinate2D(3, 9)));

Polyline polyline9 = PolylineBuilderEx.CreatePolyline(segments, SpatialReferences.WGS84);

// 进行关系测试

// 内部/内部 相交
string scl = "T********";
bool related = GeometryEngine.Instance.Relate(polygon, polyline1, scl);     // related = true
related = GeometryEngine.Instance.Relate(point0, point1, scl);              // related = false
related = GeometryEngine.Instance.Relate(point0, multipoint, scl);          // related = true
related = GeometryEngine.Instance.Relate(multipoint, polygon, scl);         // related = true
related = GeometryEngine.Instance.Relate(multipoint, polyline1, scl);       // related = false
related = GeometryEngine.Instance.Relate(polyline2, point2, scl);           // related = false
related = GeometryEngine.Instance.Relate(point1, polygon, scl);             // related = true

// 内部/边界 相交
scl = "*T*******";
related = GeometryEngine.Instance.Relate(polygon, polyline2, scl);          // related = true
related = GeometryEngine.Instance.Relate(polygon, polyline3, scl);          // related = false
related = GeometryEngine.Instance.Relate(point1, polygon, scl);             // related = false

// 边界/边界 内部相交
scl = "***T*****";
related = GeometryEngine.Instance.Relate(polygon, polyline4, scl);          // related = true

// 重叠维度1
scl = "1*T***T**";
related = GeometryEngine.Instance.Relate(polygon, polyline5, scl);          // related = true

// 交叉 区域/线(线B穿过多边形A)
scl = "1020F1102";
related = GeometryEngine.Instance.Relate(polygon, polyline6, scl);          // related = false
related = GeometryEngine.Instance.Relate(polygon, polyline9, scl);          // related = true

// 边界/边界 接触
scl = "F***T****";
related = GeometryEngine.Instance.Relate(polygon, polyline7, scl);          // related = false
related = GeometryEngine.Instance.Relate(polygon, polyline8, scl);          // related = true

77 替换多边形中的 NaN Z

List<Coordinate3D> coordsZ = new List<Coordinate3D>()
{
    new Coordinate3D(1, 2, double.NaN),
    new Coordinate3D(4, 5, 3),
    new Coordinate3D(7, 8, double.NaN)
};

Polygon polygon = PolygonBuilderEx.CreatePolygon(coordsZ);
// polygon.HasZ = true

Polygon polygonZReplaced = GeometryEngine.Instance.ReplaceNaNZs(polygon, -1) as Polygon;

// polygonZReplaced.Points[0].Z = -1
// polygonZReplaced.Points[1].Z = 3
// polygonZReplaced.Points[2].Z = -1

78 改变多边形的形状

List<Coordinate2D> polygon1Coords = new List<Coordinate2D>()
{
    new Coordinate2D(0, -11000),
    new Coordinate2D(1000, -11000),
    new Coordinate2D(1000, -12000),
    new Coordinate2D(0, -12000),
    new Coordinate2D(0, -11000)
};

// 重新塑形坐标与多边形相交
List<Coordinate2D> reshaperCoords = new List<Coordinate2D>()
{
    new Coordinate2D(1500, -11800),
    new Coordinate2D(-2600, -11800)
};

SpatialReference sr = SpatialReferenceBuilder.CreateSpatialReference(102010);
Polygon polygon1 = PolygonBuilderEx.CreatePolygon(polygon1Coords, sr);
Polyline reshaper = PolylineBuilderEx.CreatePolyline(reshaperCoords, sr);

Polygon outPolygon = GeometryEngine.Instance.Reshape(polygon1, reshaper) as Polygon;
// outPolygon.PartCount = 1

ReadOnlySegmentCollection segments = outPolygon.Parts[0];
// segments.Count = 4
// outPolygon.PointCount = 5

string json = GeometryEngine.Instance.ExportToJson(JsonExportFlags.JsonExportSkipCRS, outPolygon);
// json = "{\"rings\":[[[0,-11800],[0,-11000],[1000,-11000],[1000,-11800],[0,-11800]]]}";


// 重新塑形多边形的情况下,重塑线段不相交

reshaperCoords.Clear();
reshaperCoords.Add(new Coordinate2D(1000, 1000));
reshaperCoords.Add(new Coordinate2D(2000, 1000));

reshaper = PolylineBuilderEx.CreatePolyline(reshaperCoords, sr);

outPolygon = GeometryEngine.Instance.Reshape(polygon1, reshaper) as Polygon;
// outPolygon = null

79 反转多边形中点的顺序

List<Coordinate2D> list2D = new List<Coordinate2D>();
list2D.Add(new Coordinate2D(1.0, 1.0));
list2D.Add(new Coordinate2D(1.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 1.0));

Polygon polygon = PolygonBuilderEx.CreatePolygon(list2D);

Geometry g = GeometryEngine.Instance.ReverseOrientation(polygon);
Polygon gPolygon = g as Polygon;

// gPolygon.Points[0] = 1.0, 1.0
// gPolygon.Points[1] = 2.0, 1.0
// gPolygon.Points[2] = 2.0, 2.0
// gPolygon.Points[3] = 1.0, 2.0
// gPolygon.Points[4] = 1.0, 1.0
// gPolygon.Area = -1 * polygon.Area

80 旋转地图点

MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0);
MapPoint rotatePt = MapPointBuilderEx.CreateMapPoint(3.0, 3.0);

Geometry result = GeometryEngine.Instance.Rotate(pt, rotatePt, Math.PI / 2);
// 结果点是 (3, 1)

81 旋转折线

// 旋转折线
MapPoint fixedPt = MapPointBuilderEx.CreateMapPoint(3.0, 3.0);

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 5.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(5, 5));
pts.Add(MapPointBuilderEx.CreateMapPoint(5.0, 1.0));
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);

Polyline rotated = GeometryEngine.Instance.Rotate(polyline, fixedPt, Math.PI / 4) as Polyline;  // 旋转45度

82 缩放几何图形

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3, 3, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0, 3.0));

MapPoint midPt = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);

// 折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);
// polyline.Length = 6
// polyline.Length3D = 0
Geometry g = GeometryEngine.Instance.Scale(polyline, midPt, 0.5, 0.5);
Polyline resultPolyline = g as Polyline;
// resultPolyline.length  = 3
// resultPolyline.Points[0] = 1.25, 1.25, 3
// resultPolyline.Points[1] = 1.25, 2.25, 3
// resultPolyline.Points[2] = 2.25, 2.25, 3
// resultPolyline.Points[3] = 2.25, 1.25, 3

// 3D 点 - 在 3D 空间中缩放
MapPoint midPtZ = MapPointBuilderEx.CreateMapPoint(1.5, 1.5, 1);
g = GeometryEngine.Instance.Scale(polyline, midPtZ, 0.5, 0.5, 0.25);
resultPolyline = g as Polyline;
// resultPolyline.Points[0] = 1.25, 1.25, 1.5
// resultPolyline.Points[1] = 1.25, 2.25, 1.5
// resultPolyline.Points[2] = 2.25, 2.25, 1.5
// resultPolyline.Points[3] = 2.25, 1.25, 1.5

83 设置折线中的所有 Z

List<Coordinate3D> coordsZ = new List<Coordinate3D>()
{
    new Coordinate3D(1, 2, 3),
    new Coordinate3D(4, 5, 6),
    new Coordinate3D(7, 8, double.NaN)
};

Polyline polyline = PolylineBuilderEx.CreatePolyline(coordsZ);
// polyline.HasZ = true

Polyline polylineSetZ = GeometryEngine.Instance.SetConstantZ(polyline, -1) as Polyline;
// polylineSetZ.Points[0].Z = -1
// polylineSetZ.Points[1].Z = -1
// polylineSetZ.Points[2].Z = -1

polylineSetZ = GeometryEngine.Instance.SetConstantZ(polyline, double.NaN) as Polyline;
// polyline.HasZ = true
// polylineSetZ.Points[0].HasZ = true
// polylineSetZ.Points[0].Z = NaN
// polylineSetZ.Points[1].HasZ = true
// polylineSetZ.Points[1].Z = NaN
// polylineSetZ.Points[2].HasZ = true
// polylineSetZ.Points[2].Z = NaN

polylineSetZ = GeometryEngine.Instance.SetConstantZ(polyline, double.PositiveInfinity) as Polyline;
// polyline.HasZ = true
// polylineSetZ.Points[0].HasZ = true
// polylineSetZ.Points[0].Z = double.PositiveInfinity
// polylineSetZ.Points[1].HasZ = true
// polylineSetZ.Points[1].Z = double.PositiveInfinity
// polylineSetZ.Points[2].HasZ = true
// polylineSetZ.Points[2].Z = double.PositiveInfinity

84 计算地球椭球体表面上的几何面积 - 形状保存面积

// 点
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0, SpatialReferences.WebMercator);
double area = GeometryEngine.Instance.ShapePreservingArea(pt);         // 面积 = 0

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3, 3, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0, 3.0));

// 多点
Multipoint mPt = MultipointBuilderEx.CreateMultipoint(pts);
area = GeometryEngine.Instance.ShapePreservingArea(mPt);               // 面积 = 0

// 折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);
area = GeometryEngine.Instance.ShapePreservingArea(polyline);          // 面积 = 0

// 多边形
Polygon polygon = PolygonBuilderEx.CreatePolygon(pts, SpatialReferences.WGS84);
area = GeometryEngine.Instance.ShapePreservingArea(polygon);

polygon = PolygonBuilderEx.CreatePolygon(pts, SpatialReferences.WebMercator);
area = GeometryEngine.Instance.ShapePreservingArea(polygon);

polygon = PolygonBuilderEx.CreatePolygon(new[]
{
    MapPointBuilderEx.CreateMapPoint( -170, 45),
    MapPointBuilderEx.CreateMapPoint( 170, 45),
    MapPointBuilderEx.CreateMapPoint( 170, -45),
    MapPointBuilderEx.CreateMapPoint( -170, -54)
}, SpatialReferences.WGS84);

var area_meters = GeometryEngine.Instance.ShapePreservingArea(polygon);// , AreaUnits.SquareMeters);
var area_miles = GeometryEngine.Instance.ShapePreservingArea(polygon, AreaUnit.SquareMiles);

// area_meters - 352556425383104.37
// area_miles - 136122796.848425

85 计算地球椭球体表面几何形状的长度 - 形状保存长度

// 点
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0, SpatialReferences.WebMercator);
double len = GeometryEngine.Instance.ShapePreservingLength(pt);          // len = 0

List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 3.0, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3, 3, 3.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 1.0, 3.0));

// 多点
Multipoint mPt = MultipointBuilderEx.CreateMultipoint(pts);
len = GeometryEngine.Instance.ShapePreservingLength(mPt);                // len = 0

// 折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts, SpatialReferences.WGS84);
len = GeometryEngine.Instance.ShapePreservingLength(polyline);

// 多边形
Polygon polygon = PolygonBuilderEx.CreatePolygon(pts, SpatialReferences.WGS84);
len = GeometryEngine.Instance.ShapePreservingLength(polygon);



polyline = PolylineBuilderEx.CreatePolyline(new[]
                                            {
                                                MapPointBuilderEx.CreateMapPoint( -170, 0),
                                                MapPointBuilderEx.CreateMapPoint( 170, 0)
                                            }, SpatialReferences.WGS84);


var length_meters = GeometryEngine.Instance.ShapePreservingLength(polyline); // , LinearUnits.Meters);
var length_miles = GeometryEngine.Instance.ShapePreservingLength(polyline, LinearUnit.Miles);

// length_meters - 37848626.869713023
// length_miles - 23518.046402579574

86 侧缓冲器

// 右侧,圆形端点
SpatialReference sr = SpatialReferenceBuilder.CreateSpatialReference(102010);
List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(1200, 5800),
    new Coordinate2D(1400, 5800),
    new Coordinate2D(1400, 6000),
    new Coordinate2D(1300, 6000),
    new Coordinate2D(1300, 5700)
};

Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);
Polygon output = GeometryEngine.Instance.SideBuffer(polyline, 20, LeftOrRightSide.RightSide, LineCapType.Round) as Polygon;

87 更多侧缓冲器

SpatialReference spatialReference = SpatialReferenceBuilder.CreateSpatialReference(102010);
List<Coordinate2D> coordinates = new List<Coordinate2D>()
{
    new Coordinate2D(1200, 5800),
    new Coordinate2D(1400, 5800),
    new Coordinate2D(1400, 6000),
    new Coordinate2D(1300, 6000),
    new Coordinate2D(1300, 5700)
};

Polyline polyline1 = PolylineBuilderEx.CreatePolyline(coordinates, spatialReference);

coordinates.Clear();
coordinates.Add(new Coordinate2D(1400, 6050));
coordinates.Add(new Coordinate2D(1600, 6150));
coordinates.Add(new Coordinate2D(1800, 6050));

Polyline polyline2 = PolylineBuilderEx.CreatePolyline(coordinates, spatialReference);
List<Polyline> polylines = new List<Polyline>() { polyline1, polyline2 };
IReadOnlyList<Geometry> outGeometries = GeometryEngine.Instance.SideBuffer(polylines, 10, LeftOrRightSide.RightSide, LineCapType.Round);

88 简化多边形

var g1 = PolygonBuilderEx.FromJson("{\"rings\": [ [ [0, 0], [10, 0], [10, 10], [0, 10] ] ] }");
var result = GeometryEngine.Instance.Area(g1);      // result = -100.0   - 由于环的方向错误,结果为负数
// 简化它
var result2 = GeometryEngine.Instance.Area(GeometryEngine.Instance.SimplifyAsFeature(g1, true));
// result2 = 100.0  - 由于环方向正确(顺时针),结果为正数

89 简化具有相交、重叠的折线

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(8, 0),
    new Coordinate2D(8, 4),
    new Coordinate2D(6, 4),
    new Coordinate2D(8, 4),
    new Coordinate2D(10, 4),
    new Coordinate2D(8, 4)
};

SpatialReference sr = SpatialReferences.WGS84;

// 构建一个具有交叉段的折线
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);
// polyline.PartCount = 1
ReadOnlyPartCollection parts = polyline.Parts;
ReadOnlySegmentCollection segments = parts[0];
// segments.Count = 5

// 注意 SimpleAsFeature(不检测交叉和重叠,仅确定是否足够简单以存储到 gdb)
// 和 SimplifyPolyline(会检测交叉等)
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline, false);
// isSimple = true

// 简化折线(force = false)
// 因为它已经被认为是 '简单'(先前 IsSimpleAsFeature 调用),不检测交叉、重叠
Polyline simplePolyline = GeometryEngine.Instance.SimplifyPolyline(polyline, SimplifyType.Planar, false);
// simplePolyline.PartCount = 1
ReadOnlyPartCollection simpleParts = simplePolyline.Parts;
ReadOnlySegmentCollection simpleSegments = simpleParts[0];
// simpleSegments.Count = 5

// 简化折线(force = true)
// 检测交叉、重叠
simplePolyline = GeometryEngine.Instance.SimplifyPolyline(polyline, SimplifyType.Planar, true);
// simplePolyline.PartCount = 3
simpleParts = simplePolyline.Parts;
simpleSegments = simpleParts[0];
// simpleSegments.Count = 1

90 将多边形切成相等的部分

var slices = GeometryEngine.Instance.SlicePolygonIntoEqualParts(polygon, 3, 0, SliceType.Blocks);
// slices.Count = 3

// 简单多边形
List<Coordinate2D> list2D = new List<Coordinate2D>();
list2D.Add(new Coordinate2D(1.0, 1.0));
list2D.Add(new Coordinate2D(1.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 2.0));
list2D.Add(new Coordinate2D(2.0, 1.0));

Polygon p = PolygonBuilderEx.CreatePolygon(list2D);
slices = GeometryEngine.Instance.SlicePolygonIntoEqualParts(p, 2, 0, SliceType.Strips);

// slice[0] 坐标 - (1.0, 1.0), (1.0, 1.5), (2.0, 1.5), (2.0, 1.0), (1.0, 1.0) 
// slice[1] 坐标 - (1.0, 1.5), (1.0, 2.0), (2.0, 2.0), (2.0, 1.5), (1.0, 1.5)

slices = GeometryEngine.Instance.SlicePolygonIntoEqualParts(p, 2, Math.PI / 4, SliceType.Strips);

// slice[0] 坐标 - (1.0, 1.0), (1.0, 2.0), (2.0, 1.0), (1.0, 1.0)
// slice[1] 坐标 - (1.0, 2.0), (2.0, 2.0), (2.0, 1.0), (1.0, 2.0)

91 在点拆分多部分

// 定义一个折线
MapPoint startPointZ = MapPointBuilderEx.CreateMapPoint(1, 1, 5);
MapPoint endPointZ = MapPointBuilderEx.CreateMapPoint(20, 1, 5);

Polyline polylineZ = PolylineBuilderEx.CreatePolyline(new List<MapPoint>() { startPointZ, endPointZ });

// 定义一个拆分点
MapPoint splitPointAboveLine = MapPointBuilderEx.CreateMapPoint(10, 10, 10);

bool splitOccurred;
int partIndex;
int segmentIndex;

// 在点拆分折线。 不将拆分点投影到折线上,不创建新部分
var splitPolyline = GeometryEngine.Instance.SplitAtPoint(polylineZ, splitPointAboveLine, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = true
// partIndex = 0
// segmentIndex = 1
// splitPolyline.PointCount = 3
// splitPolyline.PartCount = 1
// splitPolyline 坐标为 (1, 1, 5), (10, 10, 10), (20, 1, 5)

// 在点拆分折线。 不将拆分点投影到折线上,创建新部分
splitPolyline = GeometryEngine.Instance.SplitAtPoint(polylineZ, splitPointAboveLine, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = true
// partIndex = 1
// segmentIndex = 0
// splitPolyline.PointCount = 4
// splitPolyline.PartCount = 2
// splitPolyline 第一个部分坐标为 (1, 1, 5), (10, 10, 10)
// splitPolyline 第二个部分坐标为 (10, 10, 10), (20, 1, 5)

// 在点拆分折线。 将拆分点投影到折线上,不创建新部分
splitPolyline = GeometryEngine.Instance.SplitAtPoint(polylineZ, splitPointAboveLine, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = true
// partIndex = 0
// segmentIndex = 1
// splitPolyline.PointCount = 3
// splitPolyline.PartCount = 1
// splitPolyline 坐标为 (1, 1, 5), (10, 10, 5), (20, 1, 5)

// 在点拆分折线。 将拆分点投影到折线上,创建新部分
splitPolyline = GeometryEngine.Instance.SplitAtPoint(polylineZ, splitPointAboveLine, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = true
// partIndex = 1
// segmentIndex = 0
// splitPolyline.PointCount = 4
// splitPolyline.PartCount = 2
// splitPolyline 第一个部分坐标为 (1, 1, 5), (10, 10, 5)
// splitPolyline 第二个部分坐标为 (10, 10, 5), (20, 1, 5)

//
// 尝试用一个不会拆分折线的点 - 点超出折线范围
//

var pointAfterLine = MapPointBuilderEx.CreateMapPoint(50, 1, 10);
splitPolyline = GeometryEngine.Instance.SplitAtPoint(polylineZ, pointAfterLine, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = false
// 忽略 partIndex, segmentIndex
// splitPolyline 与 polylineZ 相同

///
/// 多部分多边形
///
List<Coordinate3D> coordsZ = new List<Coordinate3D>()
{
    new Coordinate3D(10,10,5),
    new Coordinate3D(10,20,5),
    new Coordinate3D(20,20,5),
    new Coordinate3D(20,10,5)
};

List<Coordinate3D> coordsZ_2ndPart = new List<Coordinate3D>()
{
    new Coordinate3D(30,20,10),
    new Coordinate3D(30,30,10),
    new Coordinate3D(35,28,10),
    new Coordinate3D(40,30,10),
    new Coordinate3D(40,20,10),
};

var builder = new PolygonBuilderEx();
builder.HasZ = true;
builder.AddPart(coordsZ);
builder.AddPart(coordsZ_2ndPart);

Polygon multipart = builder.ToGeometry();

// pointA 更接近第一个多部分 - 拆分发生在第一个部分
var pointA = MapPointBuilderEx.CreateMapPoint(22, 18, 7);
var splitPolygon = GeometryEngine.Instance.SplitAtPoint(multipart, pointA, false, false, out splitOccurred, out partIndex, out segmentIndex);

// splitPolygon.PointCount = 12
// splitPolygon.PartCount = 2
// splitPolygon 第一个部分坐标为 (10, 10, 5), (10, 20, 5), (20, 20, 5), (22, 18, 7), (20, 10, 5), (10, 10, 5)

// pointB 是两个部分之间的中点 - 不会发生拆分
var pointB = MapPointBuilderEx.CreateMapPoint(25, 20, 7);
splitPolygon = GeometryEngine.Instance.SplitAtPoint(multipart, pointB, true, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = false
// 忽略 partIndex, segmentIndex
// splitPolygon 与 multipart 相同

92 多边形接触另一个多边形

// 两个不相交的多边形
Envelope env = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(4.0, 4.0), MapPointBuilderEx.CreateMapPoint(8, 8));
Polygon poly1 = PolygonBuilderEx.CreatePolygon(env);

Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(1.0, 1.0), MapPointBuilderEx.CreateMapPoint(5, 5));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env2);

bool touches = GeometryEngine.Instance.Touches(poly1, poly2);    // touches = false

// 另一个与第一个多边形接触的多边形
Envelope env3 = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(1.0, 1.0), MapPointBuilderEx.CreateMapPoint(4, 4));
Polygon poly3 = PolygonBuilderEx.CreatePolygon(env3);

touches = GeometryEngine.Instance.Touches(poly1, poly3);         // touches = true

93 转换2D

// 并非所有输入点都被转换,因为其中一些点超出了 GCS 范围。
Coordinate2D[] inCoords2D = new Coordinate2D[]
{
    new Coordinate2D(-1, -1),
    new Coordinate2D(-2, -5),
    new Coordinate2D(-5, -11),
    new Coordinate2D(-10, -19),
    new Coordinate2D(-17, -29),
    new Coordinate2D(-26, -41),
    new Coordinate2D(-37, -5),
    new Coordinate2D(-50, -21),
    new Coordinate2D(-65, -39),
    new Coordinate2D(-82, -9)
};

int arraySize = inCoords2D.Length;

ProjectionTransformation projTrans = ProjectionTransformation.Create(SpatialReferences.WGS84, SpatialReferenceBuilder.CreateSpatialReference(24891));

Coordinate2D[] outCoords2D = new Coordinate2D[arraySize];

// 转换并选择删除裁剪的坐标
int numPointsTransformed = GeometryEngine.Instance.Transform2D(inCoords2D, projTrans, ref outCoords2D, true);

// numPointsTransformed = 4
// outCoords2D.Length = 4

// outCoords2D[0] = {5580417.6876455201, 1328841.2376554986}
// outCoords2D[1] = {3508774.290814558, -568027.23444226268}
// outCoords2D[2] = {1568096.0886155984, -2343435.4394415971}
// outCoords2D[3] = {57325.827391741652, 1095146.8917508761}

// 转换并且不删除裁剪的坐标
numPointsTransformed = GeometryEngine.Instance.Transform2D(inCoords2D, projTrans, ref outCoords2D, false);

// numPointsTransformed = 4
// outCoords2D.Length = 10

// outCoords2D[0] = {double.Nan, double.Nan}
// outCoords2D[1] = {double.Nan, double.Nan}
// outCoords2D[2] = {double.Nan, double.Nan}
// outCoords2D[3] = {double.Nan, double.Nan}
// outCoords2D[4] = {double.Nan, double.Nan}
// outCoords2D[5] = {double.Nan, double.Nan}
// outCoords2D[6] = {5580417.6876455201, 1328841.2376554986}
// outCoords2D[7] = {3508774.290814558, -568027.23444226268}
// outCoords2D[8] = {1568096.0886155984, -2343435.4394415971}
// outCoords2D[9] = {57325.827391741652, 1095146.8917508761}

94 转换3D

// 并非所有输入点都被转换,因为其中一些点超出了 GCS 范围。
Coordinate3D[] inCoords3D = new Coordinate3D[]
{
    new Coordinate3D(-1, -1, 0),
    new Coordinate3D(-2, -5, 1),
    new Coordinate3D(-5, -11, 2),
    new Coordinate3D(-10, -19, 3),
    new Coordinate3D(-17, -29, 4),
    new Coordinate3D(-26, -41, 5),
    new Coordinate3D(-37, -5, 6),
    new Coordinate3D(-50, -21, 7),
    new Coordinate3D(-65, -39, 8),
    new Coordinate3D(-82, -9, 9)
};

int arraySize = inCoords3D.Length;

ProjectionTransformation projTrans = ProjectionTransformation.Create(SpatialReferences.WGS84, SpatialReferenceBuilder.CreateSpatialReference(24891));

Coordinate3D[] outCoords3D = new Coordinate3D[arraySize];

// 转换并选择删除裁剪的坐标
int numPointsTransformed = GeometryEngine.Instance.Transform3D(inCoords3D, projTrans, ref outCoords3D);

// numPointsTransformed = 4
// outCoords2D.Length = 4

// outCoords2D[0] = {5580417.6876455201, 1328841.2376554986, 7}
// outCoords2D[1] = {3508774.290814558, -568027.23444226268, 8}
// outCoords2D[2] = {1568096.0886155984, -2343435.4394415971, 9}
// outCoords2D[3] = {57325.827391741652, 1095146.8917508761, 10}

95 合并两个地图点 - 创建一个多点

MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2.0, 2.5);

Geometry geometry = GeometryEngine.Instance.Union(pt1, pt2);
Multipoint multipoint = geometry as Multipoint;   // multipoint 点数为 2

96 并集两个多边形

// 合并两个多边形

List<MapPoint> polyPts = new List<MapPoint>();
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 2.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(3.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 6.0));
polyPts.Add(MapPointBuilderEx.CreateMapPoint(6.0, 2.0));

Polygon poly1 = PolygonBuilderEx.CreatePolygon(polyPts);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(poly1);

Envelope env = EnvelopeBuilderEx.CreateEnvelope(MapPointBuilderEx.CreateMapPoint(4.0, 4.0), MapPointBuilderEx.CreateMapPoint(8, 8));
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);
isSimple = GeometryEngine.Instance.IsSimpleAsFeature(poly2);

Geometry g = GeometryEngine.Instance.Union(poly1, poly2);
Polygon polyResult = g as Polygon;

97 联合许多折线

// 合并许多折线

List<Coordinate2D> coords = new List<Coordinate2D>()
{
    new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(4, 2),
    new Coordinate2D(5, 6), new Coordinate2D(7, 8), new Coordinate2D(8, 4),
    new Coordinate2D(9, 10), new Coordinate2D(11, 12), new Coordinate2D(12, 8),
    new Coordinate2D(10, 8), new Coordinate2D(12, 12), new Coordinate2D(14, 10)
};

// 创建不相交的折线
List<Polyline> manyLines = new List<Polyline>
{
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[3], coords[4], coords[5]}),
    PolylineBuilderEx.CreatePolyline(new List<Coordinate2D>(){coords[6], coords[7], coords[8]})
};

Polyline polyline = GeometryEngine.Instance.Union(manyLines) as Polyline;

98 联合多个多边形

// 合并多个多边形

List<Coordinate3D> coordsZ = new List<Coordinate3D>()
{
    new Coordinate3D(1, 2, 0), new Coordinate3D(3, 4, 1), new Coordinate3D(4, 2, 2),
    new Coordinate3D(5, 6, 3), new Coordinate3D(7, 8, 4), new Coordinate3D(8, 4, 5),
    new Coordinate3D(9, 10, 6), new Coordinate3D(11, 12, 7), new Coordinate3D(12, 8, 8),
    new Coordinate3D(10, 8, 9), new Coordinate3D(12, 12, 10), new Coordinate3D(14, 10, 11)
};

// 创建多边形
List<Polygon> manyPolygonsZ = new List<Polygon>
{
    PolygonBuilderEx.CreatePolygon(new List<Coordinate3D>(){coordsZ[0], coordsZ[1], coordsZ[2]}, SpatialReferences.WGS84),
    PolygonBuilderEx.CreatePolygon(new List<Coordinate3D>(){coordsZ[3], coordsZ[4], coordsZ[5]}),
    PolygonBuilderEx.CreatePolygon(new List<Coordinate3D>(){coordsZ[6], coordsZ[7], coordsZ[8]})
};

Polygon polygon = GeometryEngine.Instance.Union(manyPolygonsZ) as Polygon;

99 地图点、折线、多边形内的多边形

// 创建一个多边形      
List<MapPoint> pts = new List<MapPoint>();
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
pts.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

Polygon poly = PolygonBuilderEx.CreatePolygon(pts);

// 内部点
MapPoint innerPt = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);
bool within = GeometryEngine.Instance.Within(innerPt, poly);   // within = true

// 边界上的点
within = GeometryEngine.Instance.Within(pts[0], poly);     // within = false

// 内部折线
MapPoint innerPt2 = MapPointBuilderEx.CreateMapPoint(1.25, 1.75);
List<MapPoint> innerLinePts = new List<MapPoint>();
innerLinePts.Add(innerPt);
innerLinePts.Add(innerPt2);

Polyline polyline = PolylineBuilderEx.CreatePolyline(innerLinePts);
within = GeometryEngine.Instance.Within(polyline, poly);   // within = true

// 穿越边界的折线
MapPoint outerPt = MapPointBuilderEx.CreateMapPoint(3, 1.5);
List<MapPoint> crossingLinePts = new List<MapPoint>();
crossingLinePts.Add(innerPt);
crossingLinePts.Add(outerPt);

polyline = PolylineBuilderEx.CreatePolyline(crossingLinePts);
within = GeometryEngine.Instance.Within(polyline, poly);     // within = false

// 多边形在多边形内
Envelope env = EnvelopeBuilderEx.CreateEnvelope(innerPt, innerPt2);
within = GeometryEngine.Instance.Within(env, poly);      // within = true
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ArcGIS Pro SDK是用于创建ArcGIS Pro加载项的开发工具包。您可以使用ArcGIS Pro SDK来扩展ArcGIS Pro的功能,添加自定义工具、面板、任务和其他功能。\[1\] 要安装ArcGIS Pro SDK 3.0,您需要使用Visual Studio 2022,并从Visual Studio Marketplace搜索并安装以下三个扩展:ArcGIS Pro SDK for .NET,ArcGIS Pro SDK for .NET(Utilities),ArcGIS Pro SDK for .NET(Migration)\[1\]。请注意,ArcGIS Pro SDK for .NET扩展只能集成到Visual Studio 2022中,建议使用版本17.2或更高版本\[2\]。 ArcGIS Pro SDK for .NET提供了三个不同的扩展名(.vsix文件):ArcGIS Pro SDK for .NET用于创建ArcGIS Pro加载项的工程和项模板的集合,ArcGIS Pro SDK for .NET(Utilities)用于帮助创建ArcGIS Pro加载项的实用程序的集合,ArcGIS Pro SDK for .NET(Migration)用于将ArcGIS Pro SDK 2.x扩展模块迁移到ArcGIS Pro SDK 3.0 for .NET\[3\]。 总结来说,ArcGIS Pro SDK是用于创建ArcGIS Pro加载项的开发工具包,您可以使用它来扩展ArcGIS Pro的功能。要安装ArcGIS Pro SDK 3.0,您需要使用Visual Studio 2022,并从Visual Studio Marketplace安装相应的扩展。 #### 引用[.reference_title] - *1* *2* *3* [VS2022中ArcGIS Pro SDK for .NET安装和卸载指南](https://blog.csdn.net/u012685544/article/details/126317090)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WineMonk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值