几何

空间参考

构造空间参考 - 从已知 ID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Use a builder convenience method or use a builder constructor.

// Builder convenience methods don't need to run on the MCT.
SpatialReference sr3857 = SpatialReferenceBuilder.CreateSpatialReference(3857);

// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857))
{
// do something with the builder

sr3857 = srBuilder.ToSpatialReference();
}
});

构造空间引用 - 从字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Use a builder convenience method or use a builder constructor.

string wkt = "GEOGCS[\"MyGCS84\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Radian\",1.0]]";

// Builder convenience methods don't need to run on the MCT.
SpatialReference sr = SpatialReferenceBuilder.CreateSpatialReference(wkt);

// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (SpatialReferenceBuilder builder = new SpatialReferenceBuilder(wkt))
{
// do something with the builder

SpatialReference anotherSR = builder.ToSpatialReference();
}
});

使用 WGS84 空间参考

1
2
3
SpatialReference wgs84 = SpatialReferences.WGS84;
bool isProjected = wgs84.IsProjected; // false
bool isGeographic = wgs84.IsGeographic; // true

使用垂直坐标系构造空间参考 - 从已知 ID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Use a builder convenience method or use a builder constructor.

// see a list of vertical coordinate systems at http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Vertical_coordinate_systems/02r3000000rn000000/

// Builder convenience methods don't need to run on the MCT.
// 4326 = GCS_WGS_1984
// 115700 = vertical WGS_1984
SpatialReference sr4326_115700 = SpatialReferenceBuilder.CreateSpatialReference(4326, 115700);

// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, 115700))
{
// SpatialReferenceBuilder properties
// sb.wkid == 4326
// sb.Wkt == "GEOGCS["MyGCS84",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT[\"Radian\",1.0]]"
// sb.name == GCS_WGS_1984
// sb.vcsWkid == 115700
// sb.VcsWkt == "VERTCS["WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PARAMETER["Vertical_Shift",0.0],PARAMETER["Direction",1.0],UNIT["Meter",1.0]]

// do something with the builder

sr4326_115700 = sb.ToSpatialReference();
}
});

使用垂直坐标系构造空间参考 - 从字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Use a builder convenience method or use a builder constructor.

// custom VCS - use vertical shift of -1.23 instead of 0
string custom_vWkt = @"VERTCS[""SHD_height"",VDATUM[""Singapore_Height_Datum""],PARAMETER[""Vertical_Shift"",-1.23],PARAMETER[""Direction"",-1.0],UNIT[""Meter"",1.0]]";

// Builder convenience methods don't need to run on the MCT.
SpatialReference sr4326_customVertical = SpatialReferenceBuilder.CreateSpatialReference(4326, custom_vWkt);
// SpatialReferenceBuilder properties
// sr4326_customVertical.wkid == 4326
// sr4326_customVertical.vert_wkid == 0
// sr4326_customVertical.vert_wkt == custom_vWkt
// sr4326_customVertical.hasVcs == true

// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(4326, custom_vWkt))
{
// do something with the builder

sr4326_customVertical = sb.ToSpatialReference();
}
});

使用自定义 PCS 构造空间参考 - 从字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Use a builder convenience method or use a builder constructor.

// Custom PCS, Predefined GCS
string customWkt = "PROJCS[\"WebMercatorMile\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Mile\",1609.344000614692]]";

// Builder convenience methods don't need to run on the MCT.
SpatialReference spatialReference = SpatialReferenceBuilder.CreateSpatialReference(customWkt);
// SpatialReferenceBuilder properties
// spatialReference.Wkt == customWkt
// spatialReference.Wkid == 0
// spatialReference.VcsWkid == 0
// spatialReference.GcsWkid == 4326

SpatialReference gcs = spatialReference.Gcs;
// gcs.Wkid == 4326
// gcs.IsGeographic == true
// spatialReference.GcsWkt == gcs.Wkt

// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
using (SpatialReferenceBuilder sb = new SpatialReferenceBuilder(customWkt))
{
// do something with the builder

spatialReference = sb.ToSpatialReference();
}
});

空间参考属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Builder constructors need to run on the MCT.
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
// use the builder constructor
using (SpatialReferenceBuilder srBuilder = new SpatialReferenceBuilder(3857))
{
// spatial reference builder properties
int builderWkid = srBuilder.Wkid;
string builderWkt = srBuilder.Wkt;
string builderName = srBuilder.Name;

double xyScale = srBuilder.XYScale;
double xyTolerance = srBuilder.XYTolerance;
double xyResolution = srBuilder.XYResolution;
Unit unit = srBuilder.Unit;

double zScale = srBuilder.ZScale;
double zTolerance = srBuilder.ZTolerance;
Unit zUnit = srBuilder.ZUnit;

double mScale = srBuilder.MScale;
double mTolerance = srBuilder.MTolerance;

double falseX = srBuilder.FalseX;
double falseY = srBuilder.FalseY;
double falseZ = srBuilder.FalseZ;
double falseM = srBuilder.FalseM;

// get the spatial reference
SpatialReference sr3857 = srBuilder.ToSpatialReference();

// spatial reference properties
int srWkid = sr3857.Wkid;
string srWkt = sr3857.Wkt;
string srName = sr3857.Name;

xyScale = sr3857.XYScale;
xyTolerance = sr3857.XYTolerance;
xyResolution = sr3857.XYResolution;
unit = sr3857.Unit;

zScale = sr3857.ZScale;
zTolerance = sr3857.ZTolerance;
zUnit = sr3857.ZUnit;

mScale = sr3857.MScale;
mTolerance = sr3857.MTolerance;

falseX = sr3857.FalseX;
falseY = sr3857.FalseY;
falseZ = sr3857.FalseZ;
falseM = sr3857.FalseM;

bool hasVcs = sr3857.HasVcs;
}
});

导入和导出空间参考

1
2
3
4
5
6
7
8
9
10
11
SpatialReference srWithVertical = SpatialReferenceBuilder.CreateSpatialReference(4326, 6916);

string xml = srWithVertical.ToXml();
SpatialReference importedSR = SpatialReferenceBuilder.FromXml(xml);
// importedSR.Wkid = 4326
// importedSR.VcsWkid = 6916

string json = srWithVertical.ToJson();
importedSR = SpatialReferenceBuilder.FromJson(json);
// importedSR.Wkid = 4326
// importedSR.VcsWkid = 6916

确定给定点处空间参考的格网收敛

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Coordinate2D coordinate = new Coordinate2D(10, 30);
double angle = SpatialReferences.WGS84.GetConvergenceAngle(coordinate);
// angle = 0

SpatialReference srUTM30N = SpatialReferenceBuilder.CreateSpatialReference(32630);
coordinate.X = 500000;
coordinate.Y = 550000;
angle = srUTM30N.GetConvergenceAngle(coordinate);
// angle = 0

MapPoint pointWGS84 = MapPointBuilderEx.CreateMapPoint(10, 50, SpatialReferences.WGS84);
MapPoint pointUTM30N = GeometryEngine.Instance.Project(
pointWGS84, srUTM30N) as MapPoint;

coordinate = (Coordinate2D)pointUTM30N;
// get convergence angle and convert to degrees
angle = srUTM30N.GetConvergenceAngle(coordinate) * 180 / Math.PI;
// angle = 10.03

基准

1
2
3
4
5
var cimMapDefinition = MapView.Active.Map.GetDefinition();
// use if map's sr does not have a vertical coordinate system
var datumTransformations = cimMapDefinition.DatumTransforms;
// use if map's sr has a vertical coordinate system
var hvDatumTransformations = cimMapDefinition.HVDatumTransforms;

空间参照基准和基准属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Get datum of a spatial reference
SpatialReference srWgs84 = SpatialReferences.WGS84;
Datum datum = srWgs84.Datum;
// datum.Name = "D_WGS_1984"
// datum.Wkid = 6326
// datum.SpheroidName = "WGS_1984"
// datum.SpheroidWkid = 7030
// datum.SpheroidFlattening = 0.0033528106647474805
// datum.SpheroidSemiMajorAxis = 6378137.0
// datum.SpheroidSemiMinorAxis = 6356752.3142451793

// Custom WKT
string wyomingWkt = "PROJCS[\"Wyoming_State_Pl_NAD_1927\",GEOGCS[\"GCS_North_American_1927\",DATUM[\"D_North_American_1927_Perry\",SPHEROID[\"Clarke_1866_Chase\",6378210.0,250.0]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"false_easting\",500000.0],PARAMETER[\"false_northing\",0.0],PARAMETER[\"central_meridian\",-107.3333333],PARAMETER[\"scale_factor\",0.9999412],PARAMETER[\"latitude_of_origin\",40.66666667],UNIT[\"Foot_US\",0.3048006096012192]]";
SpatialReference srFromWkt = SpatialReferenceBuilder.CreateSpatialReference(wyomingWkt);
datum = srWgs84.Datum;
// datum.Name = "D_North_American_1927_Perry"
// datum.Wkid = 0
// datum.SpheroidName = "Clarke_1866_Chase"
// datum.SpheroidWkid = 0
// datum.SpheroidFlattening = 0.004
// datum.SpheroidSemiMajorAxis = 6378210.0
// datum.SpheroidSemiMinorAxis = 6352697.16

坐标3D

矢量极坐标

1
2
3
4
5
6
7
8
9
10
11
Coordinate3D polarVector = new Coordinate3D(0, 7, 0);
Tuple<double, double, double> polarComponents = polarVector.QueryPolarComponents();
// polarComponents.Item1 = 0 (azimuth)
// polarComponents.Item2 = 0 (inclination)
// polarComponents.Item3 = 7 (magnitude)

polarVector.SetPolarComponents(Math.PI / 4, Math.PI / 2, 8);
polarComponents = polarVector.QueryComponents();
// polarComponents.Item1 = 0 (x)
// polarComponents.Item2 = 0 (y)
// polarComponents.Item3 = 7 (z)

获取矢量倾角

1
2
3
4
5
6
7
8
Coordinate3D v = new Coordinate3D(0, 0, 7);
double inclination = v.Inclination; // inclination = PI/2

v.SetComponents(-2, -3, 0);
inclination = v.Inclination; // inclination = 0

v.SetComponents(0, 0, -2);
inclination = v.Inclination; // inclination = -PI/2

获取矢量方位角

1
2
3
4
5
6
7
8
9
10
Coordinate3D vector = new Coordinate3D(0, 7, 0);
double azimuth = vector.Azimuth; // azimuth = 0

vector.SetComponents(1, 1, 42);
azimuth = vector.Azimuth;
double degrees = AngularUnit.Degrees.ConvertFromRadians(azimuth); // degrees = 45

vector.SetComponents(-8, 8, 2);
azimuth = vector.Azimuth;
degrees = AngularUnit.Degrees.ConvertFromRadians(azimuth); // degrees = 315

向量运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Easy 3D vectors
Coordinate3D v = new Coordinate3D(0, 1, 0);
// v.Magnitude = 1

Coordinate3D other = new Coordinate3D(-1, 0, 0);
// other.Magnitude = -1

double dotProduct = v.DotProduct(other); // dotProduct = 0

Coordinate3D crossProduct = v.CrossProduct(other);
// crossProduct.X = 0
// crossProduct.Y = 0
// crossProduct.Z = 1

Coordinate3D addVector = v.AddCoordinate3D(other);
// addVector.X = -1
// addVector.Y = 1
// addVector.Z = 0

// Rotate around x-axis
Coordinate3D w = v;
w.Rotate(Math.PI, other);
// w.X = 0
// w.Y = -1
// w.Z = 0

w.Scale(0.5);
// w.X = 0
// w.Y = -0.5
// w.Z = 0

w.Scale(-4);
// w.X = 0
// ww.Y = 2
// w.Z = 0
// w.Magnitude = 2

w.Move(3, 2, 0);
// w.X = 3
// w.Y = 4
// w.Z = 0
// w.Magnitude = 5


Coordinate3D emptyVector = new Coordinate3D();
// emptyVector = (0, 0, 0)
emptyVector.SetEmpty();
// emptyVector = (Nan, Nan, Nan)

Coordinate3D c1 = new Coordinate3D(2, 3, 4);
Coordinate3D c2 = new Coordinate3D(9, -1, 3);

var result_add = c1 + c2;
// result_add = (11, 2, 7)
var result_sub = c1 - c2;
// result_sub = (-7, 4, 1)

var b = result_sub != result_add;
// b = true

result_add = emptyVector + c1;
// result_add = (Nan, Nan, Nan)

b = result_add == emptyVector;
// b = true

2D 矢量操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Coordinate2D v = new Coordinate2D(0, 1);
// v.Magnitude = 1

Coordinate2D other = new Coordinate2D(-1, 0);
double dotProduct = v.DotProduct(other);
// dotProduct = 0

Coordinate2D w = v + other;
// w = (-1, 1)

w += other;
// w = (-2, 1)

w -= other;
// w = (-1, 1)

w = v;
w.Rotate(Math.PI, other);
// w = (-2, -1)

w = other;

w.Scale(-4);
// w = (4, 0)
// w.Magnitude = 4

w.Move(-1, 4);
// w = (3, 4)
// w.Magnitude = 5

w.Move(-6, -1);
Tuple<double, double> components = w.QueryComponents();
// components = (-3, 3)
// w.Magnitude = 3 * Math.Sqrt(2)

Coordinate2D unitVector = w.GetUnitVector();
// w = (-Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)
// w.Magnitude = 1


w.SetComponents(3, 4);

生成器属性

生成器属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// list of points
List<MapPoint> points = new List<MapPoint>
{
MapPointBuilderEx.CreateMapPoint(0, 0, 2, 3, 1),
MapPointBuilderEx.CreateMapPoint(1, 1, 5, 6),
MapPointBuilderEx.CreateMapPoint(2, 1, 6),
MapPointBuilderEx.CreateMapPoint(0, 0)
};

// will have attributes because it is created with convenience method
Polyline polylineWithAttrs = PolylineBuilderEx.CreatePolyline(points);
bool hasZ = polylineWithAttrs.HasZ; // hasZ = true
bool hasM = polylineWithAttrs.HasM; // hasM = true
bool hasID = polylineWithAttrs.HasID; // hasID = true

// will not have attributes because it is specified as a parameter
Polyline polylineWithoutAttrs =
PolylineBuilderEx.CreatePolyline(points, AttributeFlags.None);
hasZ = polylineWithoutAttrs.HasZ; // hasZ = false
hasM = polylineWithoutAttrs.HasM; // hasM = false
hasID = polylineWithoutAttrs.HasID; // hasID = false

// will have attributes because it is created with convenience method
Polygon polygonWithAttrs = PolygonBuilderEx.CreatePolygon(points);
hasZ = polygonWithAttrs.HasZ; // hasZ = true
hasM = polygonWithAttrs.HasM; // hasM = true
hasID = polygonWithAttrs.HasID; // hasID = true

// will not have attributes because it is specified as a parameter
Polygon polygonWithoutAttrs =
PolygonBuilderEx.CreatePolygon(points, AttributeFlags.None);
hasZ = polygonWithoutAttrs.HasZ; // hasZ = false
hasM = polygonWithoutAttrs.HasM; // hasM = false
hasID = polygonWithoutAttrs.HasID; // hasID = false

// will not have attributes because it is specified as a parameter
PolylineBuilderEx polylineB =
new PolylineBuilderEx(points, AttributeFlags.None);
hasZ = polylineB.HasZ; // hasZ = false
hasM = polylineB.HasM; // hasM = false
hasID = polylineB.HasID; // hasID = false

// will have attributes because it is passed an attributed polyline
polylineB = new PolylineBuilderEx(polylineWithAttrs);
hasZ = polylineB.HasZ; // hasZ = true
hasM = polylineB.HasM; // hasM = true
hasID = polylineB.HasID; // hasID = true

// will not have attributes because it is passed a non-attributed polyline
polylineB = new PolylineBuilderEx(polylineWithoutAttrs);
hasZ = polylineB.HasZ; // hasZ = false
hasM = polylineB.HasM; // hasM = false
hasID = polylineB.HasID; // hasID = false

// will not have attributes because it is specified as a parameter
PolygonBuilderEx polygonB = new PolygonBuilderEx(points, AttributeFlags.None);
hasZ = polygonB.HasZ; // hasZ = false
hasM = polygonB.HasM; // hasM = false
hasID = polygonB.HasID; // hasID = false

// will have attributes because it is passed an attributed polygon
polygonB = new PolygonBuilderEx(polygonWithAttrs);
hasZ = polygonB.HasZ; // hasZ = true
hasM = polygonB.HasM; // hasM = true
hasID = polygonB.HasID; // hasID = true

// will not have attributes because it is passed a non-attributed polygon
polygonB = new PolygonBuilderEx(polygonWithoutAttrs);
hasZ = polygonB.HasZ; // hasZ = true
hasM = polygonB.HasM; // hasM = true
hasID = polygonB.HasID; // hasID = true

地图点

构造地图点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Use a builder convenience method or use a builder constructor.

// create a 3d point with M
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 2.0, 3.0, 4.0);


// builderEx constructors don't need to run on the MCT.
MapPointBuilderEx mb = new MapPointBuilderEx(1.0, 2.0, 3.0, 4.0);
// do something with the builder

MapPoint ptWithM = mb.ToGeometry();


MapPoint clone = ptWithM.Clone() as MapPoint;
MapPoint anotherM = MapPointBuilderEx.CreateMapPoint(ptWithM);


MapPointBuilderEx builderEx = new MapPointBuilderEx(1.0, 2.0, 3.0);
builderEx.HasM = true;
builderEx.M = 4.0;

pt = builderEx.ToGeometry() as MapPoint;


// or another alternative with builderEx constructor
builderEx = new MapPointBuilderEx(1.0, 2.0, true, 3.0, true, 4.0, false, 0);
pt = builderEx.ToGeometry() as MapPoint;


// or use a builderEx convenience method
pt = MapPointBuilderEx.CreateMapPoint(1.0, 2.0, 3.0, 4.0);

地图点生成器属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Use a builderEx convenience method or a builderEx constructor.
// neither need to run on the MCT.

MapPoint point1 = null;
MapPoint point2 = null;

MapPointBuilderEx mb = new MapPointBuilderEx(1.0, 2.0, 3.0);
bool bhasZ = mb.HasZ; // hasZ = true
bool bhasM = mb.HasM; // hasM = false
bool bhasID = mb.HasID; // hasID = false

// do something with the builder

point1 = mb.ToGeometry();

// change some of the builder properties
mb.X = 11;
mb.Y = 22;
mb.HasZ = false;
mb.HasM = true;
mb.M = 44;
// create another point
point2 = mb.ToGeometry();

double x = point1.X; // x = 1.0
double y = point1.Y; // y = 2.0
double z = point1.Z; // z = 3.0
double m = point1.M; // m = Nan
int ID = point1.ID; // ID = 0
bool hasZ = point1.HasZ; // hasZ = true
bool hasM = point1.HasM; // hasM = false
bool hasID = point1.HasID; // hasID = false
bool isEmpty = point1.IsEmpty; // isEmpty = false

bool isEqual = point1.IsEqual(point2); // isEqual = false


// BuilderEx convenience methods
MapPoint point3 = MapPointBuilderEx.CreateMapPoint(point1);
x = point3.X; // x = 1.0
y = point3.Y; // y = 2.0
z = point3.Z; // z = 3.0
m = point3.M; // m = Nan
ID = point3.ID; // ID = 0
hasZ = point3.HasZ; // hasZ = true
hasM = point3.HasM; // hasM = false
hasID = point3.HasID; // hasID = false


MapPointBuilderEx builderEx = new MapPointBuilderEx(point1);
x = builderEx.X; // x = 1.0
y = builderEx.Y; // y = 2.0
z = builderEx.Z; // z = 3.0
m = builderEx.M; // m = Nan
ID = builderEx.ID; // ID = 0
hasZ = builderEx.HasZ; // hasZ = true
hasM = builderEx.HasM; // hasM = false
hasID = builderEx.HasID; // hasID = false
isEmpty = builderEx.IsEmpty; // isEmpty = false

MapPoint point4 = builderEx.ToGeometry() as MapPoint;


MapPoint point5 = MapPointBuilderEx.CreateMapPoint(point1);
x = point5.X; // x = 1.0
y = point5.Y; // y = 2.0
z = point5.Z; // z = 3.0
m = point5.M; // m = Nan
ID = point5.ID; // ID = 0
hasZ = point5.HasZ; // hasZ = true
hasM = point5.HasM; // hasM = false
hasID = point5.HasID; // hasID = false
isEmpty = point5.IsEmpty; // isEmpty = false

地图点是平等的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, 5);
int ID = pt1.ID; // ID = 5
bool hasID = pt1.HasID; // hasID = true

MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, 0);
ID = pt2.ID; // ID = 0
hasID = pt2.HasID; // hasID = true

MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4);
ID = pt3.ID; // ID = 0
hasID = pt3.HasID; // hasID = false

MapPoint pt4 = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 44);
ID = pt4.ID; // ID = 0
hasID = pt4.HasID; // hasID = false
bool hasM = pt4.HasM; // hasM = true

MapPoint pt5 = MapPointBuilderEx.CreateMapPoint(1, 2, 3);
ID = pt5.ID; // ID = 0
hasID = pt5.HasID; // hasID = false
hasM = pt5.HasM; // hasM = false

bool isEqual = pt1.IsEqual(pt2); // isEqual = false, different IDs
isEqual = pt2.IsEqual(pt3); // isEqual = false, HasId is different
isEqual = pt4.IsEqual(pt3); // isEqual = false, different Ms
isEqual = pt1.IsEqual(pt5); // isEqual = false, pt has M, id but pt5 does not.

缩放至指定点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Create a point
var pt = MapPointBuilderEx.CreateMapPoint(x, y,
SpatialReferenceBuilder.CreateSpatialReference(4326));
//Buffer it - for purpose of zoom
var poly = GeometryEngine.Instance.Buffer(pt, buffer_size);

//do we need to project the buffer polygon?
if (!MapView.Active.Map.SpatialReference.IsEqual(poly.SpatialReference))
{
//project the polygon
poly = GeometryEngine.Instance.Project(poly, MapView.Active.Map.SpatialReference);
}

// Must run on MCT.
QueuedTask.Run(() =>
{
//Zoom - add in a delay for animation effect
MapView.Active.ZoomTo(poly, new TimeSpan(0, 0, 0, 3));
});

折线

构造折线 - 从映射点的枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Use a builderEx convenience method or a builderEx constructor.
// neither need to run on the MCT

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

List<MapPoint> list = new List<MapPoint>();
list.Add(startPt);
list.Add(endPt);

Polyline polyline = PolylineBuilderEx.CreatePolyline(list, SpatialReferences.WGS84);

// use AttributeFlags.None since we only have 2D points in the list
PolylineBuilderEx pb = new PolylineBuilderEx(list, AttributeFlags.None);
pb.SpatialReference = SpatialReferences.WGS84;
Polyline polyline2 = pb.ToGeometry();

// use AttributeFlags.NoAttributes because we only have 2d points in the list
Polyline polyline4 = PolylineBuilderEx.CreatePolyline(list, AttributeFlags.None);

获取折线的点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// get the points as a readonly Collection
ReadOnlyPointCollection pts = polyline.Points;
int numPts = polyline.PointCount;

// OR get an enumeration of the points
IEnumerator<MapPoint> enumPts = polyline.Points.GetEnumerator();

// OR get the point coordinates as a readonly list of Coordinate2D
IReadOnlyList<Coordinate2D> coordinates = polyline.Copy2DCoordinatesToList();

// OR get the point coordinates as a readonly list of Coordinate3D
IReadOnlyList<Coordinate3D> coordinates3D = polyline.Copy3DCoordinatesToList();

// OR get a subset of the collection as Coordinate2D using preallocated memory

IList<Coordinate2D> coordinate2Ds = new List<Coordinate2D>(10); // allocate some space
ICollection<Coordinate2D> subsetCoordinates2D = coordinate2Ds; // assign
pts.Copy2DCoordinatesToList(1, 2, ref subsetCoordinates2D); // copy 2 elements from index 1 into the allocated list
// coordinate2Ds.Count = 2
// do something with the coordinate2Ds

// without allocating more space, obtain a different set of coordinates
pts.Copy2DCoordinatesToList(5, 9, ref subsetCoordinates2D); // copy 9 elements from index 5 into the allocated list
// coordinate2Ds.Count = 9


// OR get a subset of the collection as Coordinate3D using preallocated memory

IList<Coordinate3D> coordinate3Ds = new List<Coordinate3D>(15); // allocate some space
ICollection<Coordinate3D> subsetCoordinates3D = coordinate3Ds; // assign
pts.Copy3DCoordinatesToList(3, 5, ref subsetCoordinates3D); // copy 5 elements from index 3 into the allocated list
// coordinate3Ds.Count = 5


// OR get a subset of the collection as MapPoint using preallocated memory

IList<MapPoint> mapPoints = new List<MapPoint>(7); // allocate some space
ICollection<MapPoint> subsetMapPoint = mapPoints; // assign
pts.CopyPointsToList(1, 4, ref subsetMapPoint); // copy 4 elements from index 1 into the allocated list
// mapPoints.Count = 4

获取折线的各个部分

1
2
3
int numParts = polyline.PartCount;
// get the parts as a readonly collection
ReadOnlyPartCollection parts = polyline.Parts;

枚举折线的各个部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
ReadOnlyPartCollection polylineParts = polyline.Parts;

// enumerate the segments to get the length
double len = 0;
IEnumerator<ReadOnlySegmentCollection> segments = polylineParts.GetEnumerator();
while (segments.MoveNext())
{
ReadOnlySegmentCollection seg = segments.Current;
foreach (Segment s in seg)
{
len += s.Length;

// perhaps do something specific per segment type
switch (s.SegmentType)
{
case SegmentType.Line:
break;
case SegmentType.Bezier:
break;
case SegmentType.EllipticArc:
break;
}
}
}

// or use foreach pattern
foreach (var part in polyline.Parts)
{
foreach (var segment in part)
{
len += segment.Length;

// perhaps do something specific per segment type
switch (segment.SegmentType)
{
case SegmentType.Line:
break;
case SegmentType.Bezier:
break;
case SegmentType.EllipticArc:
break;
}
}
}

反转折线中点的顺序

1
2
3
var polylineBuilder = new PolylineBuilderEx(polyline);
polylineBuilder.ReverseOrientation();
Polyline reversedPolyline = polylineBuilder.ToGeometry();

获取折线的段

1
2
3
4
5
6
7
8
9
10
11
12
ICollection<Segment> collection = new List<Segment>();
polyline.GetAllSegments(ref collection);
int numSegments = collection.Count; // = 10

IList<Segment> iList = collection as IList<Segment>;
for (int i = 0; i < numSegments; i++)
{
// do something with iList[i]
}

// use the segments to build another polyline
Polyline polylineFromSegments = PolylineBuilderEx.CreatePolyline(collection);

构建多部分折线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
List<MapPoint> firstPoints = new List<MapPoint>();
firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 1.0));
firstPoints.Add(MapPointBuilderEx.CreateMapPoint(1.0, 2.0));
firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 2.0));
firstPoints.Add(MapPointBuilderEx.CreateMapPoint(2.0, 1.0));

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

// use AttributeFlags.None since we have 2D points in the list
PolylineBuilderEx pBuilder = new PolylineBuilderEx(firstPoints, AttributeFlags.None);
pBuilder.AddPart(nextPoints);

Polyline polyline = pBuilder.ToGeometry();
// polyline has 2 parts

pBuilder.RemovePart(0);
polyline = pBuilder.ToGeometry();
// polyline has 1 part

折线的起点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Method 1: Get the start point of the polyline by converting the polyline 
// into a collection of points and getting the first point

// sketchGeometry is a Polyline
// get the sketch as a point collection
var pointCol = ((Multipart)sketchGeometry).Points;
// Get the start point of the line
var firstPoint = pointCol[0];

// Method 2: Convert polyline into a collection of line segments
// and get the "StartPoint" of the first line segment.
var polylineGeom = sketchGeometry as ArcGIS.Core.Geometry.Polyline;
var polyLineParts = polylineGeom.Parts;

ReadOnlySegmentCollection polylineSegments = polyLineParts.First();

//get the first segment as a LineSegment
var firsLineSegment = polylineSegments.First() as LineSegment;

//Now get the start Point
var startPoint = firsLineSegment.StartPoint;

按角度构造布料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0);
double tangentDirection = Math.PI / 6;
ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
double startRadius = double.PositiveInfinity;
double endRadius = 0.2;
ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByAngle;
double angle = Math.PI / 2;
CurveDensifyMethod densifyMethod = CurveDensifyMethod.ByLength;
double densifyParameter = 0.1;

Polyline polyline = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, densifyMethod, densifyParameter, SpatialReferences.WGS84);

int numPoints = polyline.PointCount;
MapPoint queryPoint = polyline.Points[numPoints - 2];

MapPoint pointOnPath;
double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated;

PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, angle, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

按长度构造布料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
MapPoint startPoint = MapPointBuilderEx.CreateMapPoint(0, 0);
MapPoint queryPoint = MapPointBuilderEx.CreateMapPoint(3.8, 1);
double tangentDirection = 0;
ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
double startRadius = double.PositiveInfinity;
double endRadius = 1;
ClothoidCreateMethod createMethod = ClothoidCreateMethod.ByLength;
double curveLength = 10;
MapPoint pointOnPath;
double radiusCalculated, tangentDirectionCalculated, lengthCalculated, angleCalculated;


PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

pointOnPath = MapPointBuilderEx.CreateMapPoint(3.7652656620171379, 1.0332006103128575);
radiusCalculated = 2.4876382887687227;
tangentDirectionCalculated = 0.80797056423543978;
lengthCalculated = 4.0198770235802987;
angleCalculated = 0.80797056423544011;

queryPoint = MapPointBuilderEx.CreateMapPoint(1.85, 2.6);

PolylineBuilderEx.QueryClothoidParameters(queryPoint, startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, out pointOnPath, out radiusCalculated, out tangentDirectionCalculated, out lengthCalculated, out angleCalculated, SpatialReferences.WGS84);

pointOnPath = MapPointBuilderEx.CreateMapPoint(1.8409964973501549, 2.6115979967308132);
radiusCalculated = 1;
tangentDirectionCalculated = -1.2831853071795867;
lengthCalculated = 10;
angleCalculated = 5;

tangentDirection = Math.PI / 4;
orientation = ArcOrientation.ArcClockwise;
startRadius = double.PositiveInfinity;
endRadius = 0.8;
createMethod = ClothoidCreateMethod.ByLength;
curveLength = 10;

Polyline polyline = PolylineBuilderEx.CreatePolyline(startPoint, tangentDirection, startRadius, endRadius, orientation, createMethod, curveLength, CurveDensifyMethod.ByLength, 0.5, SpatialReferences.WGS84);

远距离分割折线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// create list of points
MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

List<MapPoint> list = new List<MapPoint>();
list.Add(startPt);
list.Add(endPt);

// BuilderEx constructors don't need to run on the MCT.

// use the PolylineBuilder as we wish to manipulate the geometry
// use AttributeFlags.None as we have 2D points
PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(list, AttributeFlags.None);
// split at a distance 0.75
polylineBuilder.SplitAtDistance(0.75, false);
// get the polyline
Polyline p = polylineBuilder.ToGeometry();
// polyline p should have 3 points (1,1), (1.75, 1), (2,1)

// add another path
MapPoint p1 = MapPointBuilderEx.CreateMapPoint(4.0, 1.0);
MapPoint p2 = MapPointBuilderEx.CreateMapPoint(6.0, 1.0);
MapPoint p3 = MapPointBuilderEx.CreateMapPoint(7.0, 1.0);
List<MapPoint> pts = new List<MapPoint>();
pts.Add(p1);
pts.Add(p2);
pts.Add(p3);

polylineBuilder.AddPart(pts);
p = polylineBuilder.ToGeometry();

// polyline p has 2 parts. Each part has 3 points

// split the 2nd path half way - dont create a new path
polylineBuilder.SplitPartAtDistance(1, 0.5, true, false);

p = polylineBuilder.ToGeometry();

// polyline p still has 2 parts; but now has 7 points

多边形

构造多边形 - 从映射点的枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Use a builderEx convenience method or use a builderEx constructor.

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

List<MapPoint> list = new List<MapPoint>() { pt1, pt2, pt3, pt4 };

Polygon polygon = PolygonBuilderEx.CreatePolygon(list, SpatialReferences.WGS84);
// polygon.HasZ will be false - it is determined by the HasZ flag of the points in the list

// or specifically use AttributeFlags.NoAttributes
polygon = PolygonBuilderEx.CreatePolygon(list, AttributeFlags.None);

// use AttributeFlags.None as we have 2D points
PolygonBuilderEx polygonBuilder = new PolygonBuilderEx(list, AttributeFlags.None);
polygonBuilder.SpatialReference = SpatialReferences.WGS84;
polygon = polygonBuilder.ToGeometry();

构造多边形 - 从信封

1
2
3
4
5
6
7
8
9
10
11
12
13
// Use a builderEx convenience method or use a builderEx constructor.

MapPoint minPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint maxPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);

// Create an envelope
Envelope env = EnvelopeBuilderEx.CreateEnvelope(minPt, maxPt);

Polygon polygonFromEnv = PolygonBuilderEx.CreatePolygon(env);

PolygonBuilderEx polygonBuilderEx = new PolygonBuilderEx(env);
polygonBuilderEx.SpatialReference = SpatialReferences.WGS84;
polygonFromEnv = polygonBuilderEx.ToGeometry() as Polygon;

获取多边形的点

1
2
3
4
5
6
7
8
9
10
11
// get the points as a readonly Collection
ReadOnlyPointCollection pts = polygon.Points;

// get an enumeration of the points
IEnumerator<MapPoint> enumPts = polygon.Points.GetEnumerator();

// get the point coordinates as a readonly list of Coordinate2D
IReadOnlyList<Coordinate2D> coordinates = polygon.Copy2DCoordinatesToList();

// get the point coordinates as a readonly list of Coordinate3D
IReadOnlyList<Coordinate3D> coordinates3D = polygon.Copy3DCoordinatesToList();

获取多边形的各个部分

1
2
// get the parts as a readonly collection
ReadOnlyPartCollection parts = polygon.Parts;

枚举多边形的各个部分

1
2
3
4
5
6
7
8
9
10
11
int numSegments = 0;
IEnumerator<ReadOnlySegmentCollection> segments = polygon.Parts.GetEnumerator();
while (segments.MoveNext())
{
ReadOnlySegmentCollection seg = segments.Current;
numSegments += seg.Count;
foreach (Segment s in seg)
{
// do something with the segment
}
}

获取多边形的线段

1
2
3
4
5
6
7
8
List<Segment> segmentList = new List<Segment>(30);
ICollection<Segment> collection = segmentList;
polygon.GetAllSegments(ref collection);
// segmentList.Count = 4
// segmentList.Capacity = 30

// use the segments to build another polygon
Polygon polygonFromSegments = PolygonBuilderEx.CreatePolygon(collection);

构建圆环多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
List<Coordinate2D> outerCoordinates = new List<Coordinate2D>();
outerCoordinates.Add(new Coordinate2D(10.0, 10.0));
outerCoordinates.Add(new Coordinate2D(10.0, 20.0));
outerCoordinates.Add(new Coordinate2D(20.0, 20.0));
outerCoordinates.Add(new Coordinate2D(20.0, 10.0));

// define the inner polygon as anti-clockwise
List<Coordinate2D> innerCoordinates = new List<Coordinate2D>();
innerCoordinates.Add(new Coordinate2D(13.0, 13.0));
innerCoordinates.Add(new Coordinate2D(17.0, 13.0));
innerCoordinates.Add(new Coordinate2D(17.0, 17.0));
innerCoordinates.Add(new Coordinate2D(13.0, 17.0));

PolygonBuilderEx pbEx = new PolygonBuilderEx(outerCoordinates);
Polygon donutEx = pbEx.ToGeometry() as Polygon;
double areaEx = donutEx.Area; // area = 100

pbEx.AddPart(innerCoordinates);
donutEx = pbEx.ToGeometry() as Polygon;

areaEx = donutEx.Area; // area = 84.0

areaEx = GeometryEngine.Instance.Area(donutEx); // area = 84.0

创建 N 侧正多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// <summary>
// Create an N-sided regular polygon. A regular sided polygon is a polygon that is equiangular (all angles are equal in measure)
// and equilateral (all sides are equal in length). See https://en.wikipedia.org/wiki/Regular_polygon
// </summary>
// <param name="numSides">The number of sides in the polygon.</param>
// <param name="center">The center of the polygon.</param>
// <param name="radius">The distance from the center of the polygon to a vertex.</param>
// <param name="rotation">The rotation angle in radians of the start point of the polygon. The start point will be
// rotated counterclockwise from the positive x-axis.</param>
// <returns>N-sided regular polygon.</returns>
// <exception cref="ArgumentException">Number of sides is less than 3.</exception>
public Polygon CreateRegularPolygon(int numSides, Coordinate2D center, double radius, double rotation)
{
if (numSides < 3)
throw new ArgumentException();

Coordinate2D[] coords = new Coordinate2D[numSides + 1];

double centerX = center.X;
double centerY = center.Y;
double x = radius * Math.Cos(rotation) + centerX;
double y = radius * Math.Sin(rotation) + centerY;
Coordinate2D start = new Coordinate2D(x, y);
coords[0] = start;

double da = 2 * Math.PI / numSides;
for (int i = 1; i < numSides; i++)
{
x = radius * Math.Cos(i * da + rotation) + centerX;
y = radius * Math.Sin(i * da + rotation) + centerY;

coords[i] = new Coordinate2D(x, y);
}

coords[numSides] = start;

return PolygonBuilderEx.CreatePolygon(coords);
}

获取多边形的外环 - 多边形。获取外部环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void GetExteriorRings(Polygon inputPolygon)
{
if (inputPolygon == null || inputPolygon.IsEmpty)
return;

// polygon part count
int partCount = inputPolygon.PartCount;
// polygon exterior ring count
int numExtRings = inputPolygon.ExteriorRingCount;
// get set of exterior rings for the polygon
IList<Polygon> extRings = inputPolygon.GetExteriorRings();

// test each part for "exterior ring"
for (int idx = 0; idx < partCount; idx++)
{
bool isExteriorRing = inputPolygon.IsExteriorRing(idx);
var ring = inputPolygon.GetExteriorRing(idx);
}
}

信封

构造封套

1
2
3
4
5
6
7
8
9
// Use a builderEx convenience method or use a builderEx constructor.

MapPoint minPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint maxPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);

Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(minPt, maxPt);

EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(minPt, maxPt);
envelope = builderEx.ToGeometry() as Envelope;

构造信封 - 从 JSON 字符串

1
2
string jsonString = "{ \"xmin\" : 1, \"ymin\" : 2,\"xmax\":3,\"ymax\":4,\"spatialReference\":{\"wkid\":4326}}";
Envelope envFromJson = EnvelopeBuilderEx.FromJson(jsonString);

合并两个信封

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// use the convenience builders
Envelope env1 = EnvelopeBuilderEx.CreateEnvelope(0, 0, 1, 1, SpatialReferences.WGS84);
Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(0.5, 0.5, 1.5, 1.5, SpatialReferences.WGS84);

Envelope env3 = env1.Union(env2);

double area = env3.Area;
double depth = env3.Depth;
double height = env3.Height;
double width = env3.Width;
double len = env3.Length;

MapPoint centerPt = env3.Center;
Coordinate2D coord = env3.CenterCoordinate;

bool isEmpty = env3.IsEmpty;
int pointCount = env3.PointCount;

// coordinates
//env3.XMin, env3.XMax, env3.YMin, env3.YMax
//env3.ZMin, env3.ZMax, env3.MMin, env3.MMax

bool isEqual = env1.IsEqual(env2); // false


// or use the builderEx constructors = don't need to run on the MCT.
EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(0, 0, 1, 1, SpatialReferences.WGS84);
builderEx.Union(env2); // builder is updated to the result

depth = builderEx.Depth;
height = builderEx.Height;
width = builderEx.Width;

centerPt = builderEx.Center;
coord = builderEx.CenterCoordinate;

isEmpty = builderEx.IsEmpty;

env3 = builderEx.ToGeometry() as Envelope;

与两个信封相交

1
2
3
4
5
6
7
8
9
10
11
12
13
// use the convenience builders
Envelope env1 = EnvelopeBuilderEx.CreateEnvelope(0, 0, 1, 1, SpatialReferences.WGS84);
Envelope env2 = EnvelopeBuilderEx.CreateEnvelope(0.5, 0.5, 1.5, 1.5, SpatialReferences.WGS84);

bool intersects = env1.Intersects(env2); // true
Envelope env3 = env1.Intersection(env2);


// or use the builderEx constructors = don't need to run on the MCT.
EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(0, 0, 1, 1, SpatialReferences.WGS84);
intersects = builderEx.Intersects(env2);
builderEx.Intersection(env2); // note this sets the builder to the intersection
env3 = builderEx.ToGeometry() as Envelope;

展开信封

1
2
3
4
5
6
7
8
9
10
11
12
13
// Use a builderEx convenience method or use a builderEx constructor.

// convenience methods don't need to run on the MCT.
Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(100.0, 100.0, 500.0, 500.0);

// shrink the envelope by 50%
Envelope result = envelope.Expand(0.5, 0.5, true);


// builderEx constructors don't need to run on the MCT.
EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(100.0, 100.0, 500.0, 500.0);
builderEx.Expand(0.5, 0.5, true);
envelope = builderEx.ToGeometry() as Envelope;

更新封套的坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Coordinate2D minCoord = new Coordinate2D(1, 3);
Coordinate2D maxCoord = new Coordinate2D(2, 4);

Coordinate2D c1 = new Coordinate2D(0, 5);
Coordinate2D c2 = new Coordinate2D(1, 3);


// use the EnvelopeBuilderEx. This constructor doesn't need to run on the MCT.

EnvelopeBuilderEx builderEx = new EnvelopeBuilderEx(minCoord, maxCoord);
// builderEx.XMin, YMin, Zmin, MMin = 1, 3, 0, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 2, 4, 0, double.Nan

// set XMin. if XMin > XMax; both XMin and XMax change
builderEx.XMin = 6;
// builderEx.XMin, YMin, ZMin, MMin = 6, 3, 0, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 6, 4, 0, double.Nan

// set XMax
builderEx.XMax = 8;
// builderEx.XMin, YMin, ZMin, MMin = 6, 3, 0, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 8, 4, 0, double.Nan

// set XMax. if XMax < XMin, both XMin and XMax change
builderEx.XMax = 3;
// builderEx.XMin, YMin, ZMin, MMin = 3, 3, 0, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 3, 4, 0, double.Nan

// set YMin
builderEx.YMin = 2;
// builderEx.XMin, YMin, ZMin, MMin = 3, 2, 0, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 3, 4, 0, double.Nan

// set ZMin. if ZMin > ZMax, both ZMin and ZMax change
builderEx.ZMin = 3;
// builderEx.XMin, YMin, ZMin, MMin = 3, 2, 3, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 3, 4, 3, double.Nan

// set ZMax. if ZMax < ZMin. both ZMin and ZMax change
builderEx.ZMax = -1;
// builderEx.XMin, YMin, ZMin, MMin = 3, 2, -1, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 3, 4, -1, double.Nan

builderEx.SetZCoords(8, -5);
// builderEx.XMin, YMin, ZMin, MMin = 3, 2, -5, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 3, 4, 8, double.Nan


builderEx.SetXYCoords(c1, c2);
// builderEx.XMin, YMin, ZMin, MMin = 0, 3, -5, double.Nan
// builderEx.XMax, YMax, ZMax, MMax = 1, 5, 8, double.Nan


builderEx.HasM = true;
builderEx.SetMCoords(2, 5);

var geomEx = builderEx.ToGeometry();

多点

构造多点 - 从映射点的枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Use a builderEx convenience method or use a builderEx constructor.

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));

// use the builderEx constructors - don't need to run on the MCT.
// use AttributeFlags.NoAttributes - we have 2d points in the list
MultipointBuilderEx builderEx = new MultipointBuilderEx(list, AttributeFlags.None);
Multipoint multiPoint = builderEx.ToGeometry() as Multipoint;
int ptCount = builderEx.PointCount;

// builderEx convenience methods dont need to run on the MCT
multiPoint = MultipointBuilderEx.CreateMultipoint(list);
// multiPoint.HasZ, HasM, HasID will be false - the attributes are determined
// based on the attribute state of the points in the list

// or specifically set the state
multiPoint = MultipointBuilderEx.CreateMultipoint(list, AttributeFlags.None);
// multiPoint.HasM = false

multiPoint = MultipointBuilderEx.CreateMultipoint(list, AttributeFlags.HasM);
// multiPoint.HasM = true

ptCount = multiPoint.PointCount;

构造多点 - 使用 MultipointBuilderEx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
Coordinate2D[] coordinate2Ds = new Coordinate2D[] { new Coordinate2D(1, 2), new Coordinate2D(-1, -2) };
SpatialReference sr = SpatialReferences.WGS84;

MultipointBuilderEx builder = new MultipointBuilderEx(coordinate2Ds, sr);

// builder.PointCount = 2

builder.HasZ = true;
// builder.Zs.Count = 2
// builder.Zs[0] = 0
// builder.Zs[1] = 0

builder.HasM = true;
// builder.Ms.Count = 2
// builder.Ms[0] = NaN
// builder.Ms[1] = NaN

builder.HasID = true;
// builder.IDs.Count = 2
// builder.IDs[0] = 0
// builder.IDs[1] = 0

// set it empty
builder.SetEmpty();
// builder.Coords.Count = 0
// builder.Zs.Count = 0
// builder.Ms.Count = 0
// builder.IDs.Count = 0


// reset coordinates
List<Coordinate2D> inCoords = new List<Coordinate2D>() { new Coordinate2D(1, 2), new Coordinate2D(3, 4), new Coordinate2D(5, 6) };
builder.Coordinate2Ds = inCoords;
// builder.Coords.Count = 3
// builder.HasZ = true
// builder.HasM = true
// builder.HasID = true

double[] zs = new double[] { 1, 2, 1, 2, 1, 2 };
builder.Zs = zs;
// builder.Zs.Count = 6

double[] ms = new double[] { 0, 1 };
builder.Ms = ms;
// builder.Ms.Count = 2

// coordinates are now (x, y, z, m, id)
// (1, 2, 1, 0, 0), (3, 4, 2, 1, 0) (5, 6, 1, NaN, 0)

MapPoint mapPoint = builder.GetPoint(2);
// mapPoint.HasZ = true
// mapPoint.HasM = true
// mapPoint.HasID = true
// mapPoint.Z = 1
// mapPoint.M = NaN
// mapPoint.ID = 0

// add an M to the list
builder.Ms.Add(2);
// builder.Ms.count = 3

// coordinates are now (x, y, z, m, id)
// (1, 2, 1, 0, 0), (3, 4, 2, 1, 0) (5, 6, 1, 2, 0)

// now get the 2nd point again; it will now have an M value
mapPoint = builder.GetPoint(2);
// mapPoint.M = 2


int[] ids = new int[] { -1, -2, -3 };
// assign ID values
builder.IDs = ids;

// coordinates are now (x, y, z, m, id)
// (1, 2, 1, 0, -1), (3, 4, 2, 1, -2) (5, 6, 1, 2, -3)


// create a new point
MapPoint point = MapPointBuilderEx.CreateMapPoint(-300, 400, 4);
builder.SetPoint(2, point);

// coordinates are now (x, y, z, m, id)
// (1, 2, 1, 0, -1), (3, 4, 2, 1, -2) (-300, 400, 4, NaN, 0)


builder.RemovePoints(1, 3);
// builder.PointCount = 1

修改多点的点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// assume a multiPoint has been built from 4 points
// the modified multiPoint will have the first point removed and the last point moved

// use the builderEx constructors = don't need to run on the MCT.
MultipointBuilderEx builderEx = new MultipointBuilderEx(multipoint);
// remove the first point
builderEx.RemovePoint(0);
// modify the coordinates of the last point
var ptEx = builderEx.GetPoint(builderEx.PointCount - 1);
builderEx.RemovePoint(builderEx.PointCount - 1);

var newPtEx = MapPointBuilderEx.CreateMapPoint(ptEx.X + 1.0, ptEx.Y + 2.0);
builderEx.AddPoint(newPtEx);
Multipoint modifiedMultiPointEx = builderEx.ToGeometry() as Multipoint;

从多点检索点、2D 坐标、3D 坐标

1
2
3
ReadOnlyPointCollection points = multipoint.Points;
IReadOnlyList<Coordinate2D> coords2d = multipoint.Copy2DCoordinatesToList();
IReadOnlyList<Coordinate3D> coords3d = multipoint.Copy3DCoordinatesToList();

线段

使用两个地图点构造线段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Use a builderEx convenience method or use a builderEx constructor.

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0);

// BuilderEx convenience methods don't need to run on the MCT.
LineSegment lineFromMapPoint = LineBuilderEx.CreateLineSegment(startPt, endPt);

// coordinate2D
Coordinate2D start2d = (Coordinate2D)startPt;
Coordinate2D end2d = (Coordinate2D)endPt;

LineSegment lineFromCoordinate2D = LineBuilderEx.CreateLineSegment(start2d, end2d);

// coordinate3D
Coordinate3D start3d = (Coordinate3D)startPt;
Coordinate3D end3d = (Coordinate3D)endPt;

LineSegment lineFromCoordinate3D = LineBuilderEx.CreateLineSegment(start3d, end3d);

// lineSegment
LineSegment anotherLineFromLineSegment = LineBuilderEx.CreateLineSegment(lineFromCoordinate3D);


// builderEx constructors don't need to run on the MCT
LineBuilderEx lbEx = new LineBuilderEx(startPt, endPt);
lineFromMapPoint = lbEx.ToSegment() as LineSegment;

lbEx = new LineBuilderEx(start2d, end2d);
lineFromCoordinate2D = lbEx.ToSegment() as LineSegment;

lbEx = new LineBuilderEx(start3d, end3d);
lineFromCoordinate3D = lbEx.ToSegment() as LineSegment;

lbEx = new LineBuilderEx(startPt, endPt);
lineFromMapPoint = lbEx.ToSegment() as LineSegment;

lbEx = new LineBuilderEx(lineFromCoordinate3D);
anotherLineFromLineSegment = lbEx.ToSegment() as LineSegment;

更改线段坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// builderEx constructors don't need to run on the MCT
LineBuilderEx lbuilderEx = new LineBuilderEx(lineSegment);
// find the existing coordinates
lbuilderEx.QueryCoords(out startPt, out endPt);

// or use
//startPt = lbuilderEx.StartPoint;
//endPt = lbuilderEx.EndPoint;

// update the coordinates
lbuilderEx.SetCoords(GeometryEngine.Instance.Move(startPt, 10, 10) as MapPoint, GeometryEngine.Instance.Move(endPt, -10, -10) as MapPoint);

// or use
//lbuilderEx.StartPoint = GeometryEngine.Instance.Move(startPt, 10, 10) as MapPoint;
//lbuilderEx.EndPoint = GeometryEngine.Instance.Move(endPt, -10, -10) as MapPoint;

LineSegment segment2 = lbuilderEx.ToSegment() as LineSegment;

立方贝塞尔

构建三次方贝塞尔 - 从坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Use a builderEx convenience method or a builderEx constructor.

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, 3.0);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, 3.0);

Coordinate2D ctrl1Pt = new Coordinate2D(1.0, 2.0);
Coordinate2D ctrl2Pt = new Coordinate2D(2.0, 1.0);

// BuilderEx convenience methods don't need to run on the MCT
CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt, SpatialReferences.WGS84);

// without a SR
bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt);


// builderEx constructors dont need to run on the MCT
CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt, ctrl2Pt, endPt);
bezier = cbbEx.ToSegment() as CubicBezierSegment;

// another alternative
cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt.ToMapPoint(), ctrl2Pt.ToMapPoint(), endPt);
bezier = cbbEx.ToSegment() as CubicBezierSegment;

构建立方贝塞尔 - 从地图点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Use a builderEx convenience method or a builderEx constructor.

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

MapPoint ctrl1Pt = MapPointBuilderEx.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84);
MapPoint ctrl2Pt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84);

// BuilderEx convenience methods don't need to run on the MCT
CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(startPt, ctrl1Pt, ctrl2Pt, endPt);

// builderEx constructors dont need to run on the MCT
CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(startPt, ctrl1Pt, ctrl2Pt, endPt);
bezier = cbbEx.ToSegment() as CubicBezierSegment;

构造三次贝塞尔 - 从映射点的枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Use a buildeExr convenience method or use a builderEx constructor.

MapPoint startPt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
MapPoint endPt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0, SpatialReferences.WGS84);

MapPoint ctrl1Pt = MapPointBuilderEx.CreateMapPoint(1.0, 2.0, SpatialReferences.WGS84);
MapPoint ctrl2Pt = MapPointBuilderEx.CreateMapPoint(2.0, 1.0, SpatialReferences.WGS84);

List<MapPoint> listMapPoints = new List<MapPoint>();
listMapPoints.Add(startPt);
listMapPoints.Add(ctrl1Pt);
listMapPoints.Add(ctrl2Pt);
listMapPoints.Add(endPt);

// BuilderEx convenience methods don't need to run on the MCT
CubicBezierSegment bezier = CubicBezierBuilderEx.CreateCubicBezierSegment(listMapPoints);

// builderEx constructors dont need to run on the MCT
CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(listMapPoints);
bezier = cbbEx.ToSegment() as CubicBezierSegment;

立方贝塞尔生成器属性

1
2
3
4
5
6
7
8
9
10
// retrieve the bezier curve's control points

CubicBezierBuilderEx cbbEx = new CubicBezierBuilderEx(bezierSegment);
MapPoint startPtEx = cbbEx.StartPoint;
Coordinate2D ctrlPt1Ex = cbbEx.ControlPoint1;
Coordinate2D ctrlPt2Ex = cbbEx.ControlPoint2;
MapPoint endPtEx = cbbEx.EndPoint;

// or use the QueryCoords method
cbbEx.QueryCoords(out startPtEx, out ctrlPt1Ex, out ctrlPt2Ex, out endPtEx);

立方贝塞尔属性

1
2
3
4
5
6
7
8
9
// retrieve the bezier curve's control points
CubicBezierSegment cb = CubicBezierBuilderEx.CreateCubicBezierSegment(bezierSegment);
MapPoint startPt = cb.StartPoint;
Coordinate2D ctrlPt1 = cb.ControlPoint1;
Coordinate2D ctrlPt2 = cb.ControlPoint2;
MapPoint endPt = cb.EndPoint;

bool isCurve = cb.IsCurve;
double len = cb.Length;

构造折线 - 从三次贝塞尔

1
Polyline polyline = PolylineBuilderEx.CreatePolyline(bezierSegment);

构造圆弧 - 使用内部点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Construct a circular arc from (2, 1) to (1, 2) with interior pt (1 + sqrt(2)/2, 1 + sqrt(2)/2).
// Use a builderEx convenience method or use a builderEx constructor.

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);

// BuilderEx convenience methods don't need to run on the MCT.
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromPt, toPt, interiorPt);

// BuilderEx constructors dont need to run on the MCT.
EllipticArcBuilderEx eab = new EllipticArcBuilderEx(fromPt, toPt, interiorPt);
// do something with the builder

EllipticArcSegment anotherCircularArc = eab.ToSegment();

构造圆弧 - 使用弦长度和方位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Construct a circular arc counterclockwise from (2, 1) to (1, 2) such that the embedded 
// circle has center point at (1, 1) and radius = 1.
// Use a builderEx convenience method or use a builderEx constructor.

MapPoint fromPt = MapPointBuilderEx.CreateMapPoint(2, 1, SpatialReferences.WGS84);
double chordLength = Math.Sqrt(2);
double chordBearing = 3 * Math.PI / 4;
double radius = 1;
ArcOrientation orientation = ArcOrientation.ArcCounterClockwise;
MinorOrMajor minorOrMajor = MinorOrMajor.Minor;

// BuildeExr convenience methods don't need to run on the MCT.
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromPt, chordLength, chordBearing, radius, orientation, minorOrMajor);

// BuilderEx constructors need to run on the MCT.
EllipticArcBuilderEx cab = new EllipticArcBuilderEx(fromPt, chordLength, chordBearing, radius, orientation, minorOrMajor);
// do something with the builder

EllipticArcSegment anotherCircularArc = cab.ToSegment();

构建圆弧 - 使用中心点、角度和半径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Construct a circular arc with center point at (0, 0), from angle = 0, 
// central angle = pi/2, radius = 1.
// Use a builderEx convenience method or use a builderEx constructor.

SpatialReference sr4326 = SpatialReferences.WGS84;
Coordinate2D centerPt = new Coordinate2D(0, 0);
double fromAngle = 0;
double centralAngle = Math.PI / 2;
double radius = 1;

// BuilderEx convenience methods don't need to run on the MCT.
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromAngle, centralAngle, centerPt, radius, sr4326);

// BuilderEx constructors dont need to run on the MCT.
EllipticArcBuilderEx cab = new EllipticArcBuilderEx(fromAngle, centralAngle, centerPt, radius, sr4326);
EllipticArcSegment otherCircularArc = cab.ToSegment();

构造椭圆弧 - 使用中心点和旋转角度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Construct an elliptic arc centered at (1,1), startAngle = 0, centralAngle = PI/2, 
// rotationAngle = 0, semiMajorAxis = 1, minorMajorRatio = 0.5.
// Use a builderEx convenience method or use a builderEx constructor.

Coordinate2D centerPt = new Coordinate2D(1, 1);

// BuilderEx convenience methods don't need to run on the MCT.
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateEllipticArcSegment(centerPt, 0, Math.PI / 2, 0, 1, 0.5);

double semiMajor;
double semiMinor;
circularArc.GetAxes(out semiMajor, out semiMinor);
// semiMajor = 1, semiMinor = 0.5

// BuilderEx constructors dont need to run on the MCT.
EllipticArcBuilderEx cab = new EllipticArcBuilderEx(centerPt, 0, Math.PI / 2, 0, 1, 0.5);
cab.GetAxes(out semiMajor, out semiMinor);
EllipticArcSegment otherCircularArc = cab.ToSegment();

构造圆弧 - 使用中心点和方向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Construct a circular arc from (2, 1) to (1, 2) 
// with center point at (1, 1) and orientation counterclockwise.
// Use a builderEx convenience method or use a builderEx constructor.

MapPoint toPt = MapPointBuilderEx.CreateMapPoint(1, 2);
MapPoint fromPt = MapPointBuilderEx.CreateMapPoint(2, 1);
Coordinate2D centerPtCoord = new Coordinate2D(1, 1);

// BuilderEx convenience methods don't need to run on the MCT.
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(fromPt, toPt, centerPtCoord, ArcOrientation.ArcCounterClockwise);

// BuilderEx constructors need to run on the MCT.
EllipticArcBuilderEx cab = new EllipticArcBuilderEx(fromPt, toPt, centerPtCoord, ArcOrientation.ArcCounterClockwise);
EllipticArcSegment otherCircularArc = cab.ToSegment();

构造圆弧 - 使用两个线段和半径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Construct a segment from (100, 100) to (50, 50) and another segment from (100, 100) to (150, 50).
// Use a builderEx convenience method or use a builderEx constructor.

LineSegment segment1 = LineBuilderEx.CreateLineSegment(new Coordinate2D(100, 100), new Coordinate2D(50, 50));
LineSegment segment2 = LineBuilderEx.CreateLineSegment(new Coordinate2D(100, 100), new Coordinate2D(150, 50));

// Construct the hint point to determine where the arc will be constructed.
Coordinate2D hintPoint = new Coordinate2D(100, 75);

// Call QueryFilletRadius to get the minimum and maximum radii that can be used with these segments.
var minMaxRadii = EllipticArcBuilderEx.QueryFilletRadiusRange(segment1, segment2, hintPoint);

// Use the maximum radius to create the arc.
double maxRadius = minMaxRadii.Item2;

// BuilderEx convenience methods don't need to run on the MCT.
//At 2.x - EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateEllipticArcSegment(segment1, segment2, maxRadius, hintPoint);
EllipticArcSegment circularArc = EllipticArcBuilderEx.CreateCircularArc(
segment1, segment2, maxRadius, hintPoint);

// BuilderEx constructors need to run on the MCT.
EllipticArcBuilderEx cab = new EllipticArcBuilderEx(segment1, segment2, maxRadius, hintPoint);
EllipticArcSegment otherCircularArc = cab.ToSegment();

构造一个圆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Construct a circle with center at (-1,-1), radius = 2, and oriented clockwise.
// Use a builderEx convenience method or use a builderEx constructor.

Coordinate2D centerPtCoord = new Coordinate2D(-1, -1);

// Builder convenience methods don't need to run on the MCT.
EllipticArcSegment circle = EllipticArcBuilderEx.CreateCircle(centerPtCoord, 2, ArcOrientation.ArcClockwise);
// circle.IsCircular = true
// circle.IsCounterClockwise = false
// circle.IsMinor = false

double startAngle, rotationAngle, centralAngle, semiMajor, semiMinor;
Coordinate2D actualCenterPt;
circle.QueryCoords(out actualCenterPt, out startAngle, out centralAngle, out rotationAngle, out semiMajor, out semiMinor);

// semiMajor = 2.0
// semiMinor = 2.0
// startAngle = PI/2
// centralAngle = -2*PI
// rotationAngle = 0
// endAngle = PI/2

// BuilderEx constructors need to run on the MCT.
EllipticArcBuilderEx builder = new EllipticArcBuilderEx(centerPtCoord, 2, ArcOrientation.ArcClockwise);
EllipticArcSegment otherCircle = builder.ToSegment();

构造椭圆

1
2
3
4
5
6
7
8
9
10
11
12
// Construct an ellipse centered at (1, 2) with rotationAngle = -pi/6,  
// semiMajorAxis = 5, minorMajorRatio = 0.2, oriented clockwise.
// Use a builderEx convenience method or use a builderEx constructor.

Coordinate2D centerPt = new Coordinate2D(1, 2);

// BuilderEx convenience methods don't need to run on the MCT.
EllipticArcSegment ellipse = EllipticArcBuilderEx.CreateEllipse(centerPt, -1 * Math.PI / 6, 5, 0.2, ArcOrientation.ArcClockwise);

// BuilderEx constructors need to run on the MCT.
EllipticArcBuilderEx builder = new EllipticArcBuilderEx(centerPt, -1 * Math.PI / 6, 5, 0.2, ArcOrientation.ArcClockwise);
EllipticArcSegment anotherEllipse = builder.ToSegment();

Elliptic Arc Builder Properties

1
2
3
4
5
6
7
8
9
10
11
12
// retrieve the curve's properties
EllipticArcBuilderEx builder = new EllipticArcBuilderEx(arcSegment);
MapPoint startPt = builder.StartPoint;
MapPoint endPt = builder.EndPoint;
Coordinate2D centerPt = builder.CenterPoint;
bool isCircular = builder.IsCircular;
bool isMinor = builder.IsMinor;
double startAngle = builder.StartAngle;
double endAngle = builder.EndAngle;
double centralAngle = builder.CentralAngle;
double rotationAngle = builder.RotationAngle;
ArcOrientation orientation = builder.Orientation;

椭圆弧属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// retrieve the curve's control points
EllipticArcSegment arc = EllipticArcBuilderEx.CreateEllipticArcSegment(arcSegment);
MapPoint startPt = arc.StartPoint;
MapPoint endPt = arc.EndPoint;
Coordinate2D centerPt = arc.CenterPoint;
bool isCircular = arc.IsCircular;
bool isMinor = arc.IsMinor;
bool isCounterClockwise = arc.IsCounterClockwise;
bool isCurve = arc.IsCurve;
double len = arc.Length;
double ratio = arc.MinorMajorRatio;

double semiMajorAxis, semiMinorAxis;
// get the axes
arc.GetAxes(out semiMajorAxis, out semiMinorAxis);
// or use the properties
// semiMajorAxis = arc.SemiMajorAxis;
// semiMinorAxis = arc.SemiMinorAxis;

double startAngle, centralAngle, rotationAngle;
// or use QueryCoords to get complete information
arc.QueryCoords(out centerPt, out startAngle, out centralAngle, out rotationAngle, out semiMajorAxis, out semiMinorAxis);

// use properties to get angle information
//double endAngle = arc.EndAngle;
//centralAngle = arc.CentralAngle;
//rotationAngle = arc.RotationAngle;
//startAngle = arc.StartAngle;

几何袋

构造几何包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
MapPoint point = MapPointBuilderEx.CreateMapPoint(1, 2, SpatialReferences.WebMercator);

List<Coordinate2D> coords2D = new List<Coordinate2D>()
{
new Coordinate2D(0, 0),
new Coordinate2D(0, 1),
new Coordinate2D(1, 1),
new Coordinate2D(1, 0)
};

Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(coords2D, SpatialReferences.WGS84);
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords2D, SpatialReferences.WebMercator);

GeometryBagBuilderEx builder = new GeometryBagBuilderEx(SpatialReferences.WGS84);

GeometryBag emptyBag = builder.ToGeometry();
// emptyBag.IsEmpty = true

builder.AddGeometry(point);
// builder.GeometryCount = 1

GeometryBag geometryBag = builder.ToGeometry();
// geometryBag.PartCount = 1
// geometryBag.PointCount = 1
// geometryBag.IsEmpty = false

IReadOnlyList<Geometry> geometries = geometryBag.Geometries;
// geometries.Count = 1
// geometries[0] is MapPoint with a sr of WGS84

bool isEqual = geometryBag.IsEqual(emptyBag); // isEqual = false

builder.InsertGeometry(0, multipoint);
geometryBag = builder.ToGeometry();
// geometryBag.PartCount = 2

geometries = geometryBag.Geometries;
// geometries.Count = 2
// geometries[0] is Multipoint
// geometries[1] is MapPoint

builder.AddGeometry(polyline);
builder.RemoveGeometry(1);
geometryBag = builder.ToGeometry();
// geometryBag.PartCount = 2

geometries = geometryBag.Geometries;
// geometries.Count = 2
// geometries[0] is Multipoint
// geometries[1] is Polyline

构造几何包 - 从几何枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Use a builder convenience method or use a builder constructor.

MapPoint point = MapPointBuilderEx.CreateMapPoint(10, 20);
List<Coordinate2D> coords = new List<Coordinate2D>() { new Coordinate2D(50, 60), new Coordinate2D(-120, -70), new Coordinate2D(40, 60) };
Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(coords, SpatialReferences.WebMercator);
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords);

string json = "{\"rings\":[[[0,0],[0,1],[1,1],[1,0],[0,0]],[[3,0],[3,1],[4,1],[4,0],[3,0]]]}";
Polygon polygon = PolygonBuilderEx.FromJson(json);

var geometries = new List<Geometry>() { point, multipoint, polyline, polygon };

// Builder convenience methods don't need to run on the MCT.
//At 2.x - GeometryBag bag = GeometryBagBuilder.CreateGeometryBag(geometries, SpatialReferences.WGS84);
var bag = GeometryBagBuilderEx.CreateGeometryBag(geometries, SpatialReferences.WGS84);

//At 2.x - using (var builder = new GeometryBagBuilder(geometries, SpatialReferences.WGS84))
var builder = new GeometryBagBuilderEx(geometries, SpatialReferences.WGS84);
// do something with the builder
bag = builder.ToGeometry();

ConstructingGeometryBag - 来自 JSON、Xml

1
2
3
4
5
6
7
const string jsonString = "{\"geometries\":[{\"x\":1,\"y\":2},{\"rings\":[[[0,0],[0,4],[3,4],[3,0],[0,0]]]}],\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}";
//At 2.x - GeometryBag geometryBag = GeometryBagBuilder.FromJson(jsonString);
var geometryBag = GeometryBagBuilderEx.FromJson(jsonString);

string xml = geometryBag.ToXml();
//At 2.x - GeometryBag xmlString = GeometryBagBuilder.FromXML(xml);
var xmlString = GeometryBagBuilderEx.FromXml(xml);

构造几何包 - 添加或插入几何枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MapPoint point = MapPointBuilderEx.CreateMapPoint(10, 20);
List<Coordinate2D> coords = new List<Coordinate2D>() { new Coordinate2D(50, 60), new Coordinate2D(-120, -70), new Coordinate2D(40, 60) };
Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(coords, SpatialReferences.WebMercator);
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords);

string json = "{\"rings\":[[[0,0],[0,1],[1,1],[1,0],[0,0]],[[3,0],[3,1],[4,1],[4,0],[3,0]]]}";
Polygon polygon = PolygonBuilderEx.FromJson(json);

var geometries = new List<Geometry>() { point, multipoint, polyline, polygon };

//At 2.x - using (var builder = new GeometryBagBuilder(SpatialReferences.WGS84))
var builder = new GeometryBagBuilderEx(SpatialReferences.WGS84);
builder.AddGeometries(geometries);

GeometryBag geomBag = builder.ToGeometry();
// geomBag.PartCount == 4 (point, multipoint, polyline, polygon)

geometries = new List<Geometry>() { point, polyline };
builder.InsertGeometries(1, geometries);
// builder.GeometryCount == 6
geomBag = builder.ToGeometry();
// geomBag.PartCount == 6 (point, point, polyline, multipoint, polyline, polygon)

多面体

通过拉伸多边形或折线构建多面体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// build a polygon
string json = "{\"hasZ\":true,\"rings\":[[[0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0]]],\"spatialReference\":{\"wkid\":4326}}";
Polygon polygon = PolygonBuilderEx.FromJson(json);

// extrude the polygon by an offset to create a multipatch
Multipatch multipatch = GeometryEngine.Instance.ConstructMultipatchExtrude(polygon, 2);

// a different polygon
json = "{\"hasZ\":true,\"rings\":[[[0,0,1],[0,1,2],[1,1,3],[1,0,4],[0,0,1]]],\"spatialReference\":{\"wkid\":4326}}";
polygon = PolygonBuilderEx.FromJson(json);

// extrude between z values to create a multipatch
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeFromToZ(polygon, -10, 20);

// extrude along the axis defined by the coordinate to create a multipatch
Coordinate3D coord = new Coordinate3D(10, 18, -10);
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongVector3D(polygon, coord);

// build a polyline
json = "{\"hasZ\":true,\"paths\":[[[400,800,1000],[800,1400,1500],[1200,800,2000],[1800,1800,2500],[2200,800,3000]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);

// extrude to a specific z value to create a multipatch
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeToZ(polyline, 500);

Coordinate3D fromCoord = new Coordinate3D(50, 50, -500);
Coordinate3D toCoord = new Coordinate3D(200, 50, 1000);

// extrude between two coordinates to create a multipatch
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongLine(polyline, fromCoord, toCoord);

多面体属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// standard geometry properties
bool hasZ = multipatch.HasZ;
bool hasM = multipatch.HasM;
bool hasID = multipatch.HasID;
bool isEmpty = multipatch.IsEmpty;
var sr = multipatch.SpatialReference;

// number of patches (parts)
int patchCount = multiPatch.PartCount;
// number of points
int pointCount = multiPatch.PointCount;

// retrieve the points as MapPoints
ReadOnlyPointCollection points = multipatch.Points;
// or as 3D Coordinates
IReadOnlyList<Coordinate3D> coordinates = multipatch.Copy3DCoordinatesToList();


// multipatch materials
bool hasMaterials = multiPatch.HasMaterials;
int materialCount = multiPatch.MaterialCount;


// multipatch textures
bool hasTextures = multiPatch.HasTextures;
int textureVertexCount = multiPatch.TextureVertexCount;

// normals
bool hasNormals = multiPatch.HasNormals;


// properties for an individual patch (if multipatch.PartCount > 0)
int patchPriority = multiPatch.GetPatchPriority(patchIndex);
PatchType patchType = multiPatch.GetPatchType(patchIndex);

// patch points
int patchPointCount = multiPatch.GetPatchPointCount(patchIndex);
int pointStartIndex = multiPatch.GetPatchStartPointIndex(patchIndex);
// the patch Points are then the points in multipatch.Points from pointStartIndex to pointStartIndex + patchPointCount

// if the multipatch has materials
if (hasMaterials)
{
// does the patch have a material?
// materialIndex = -1 if the patch does not have a material;
// 0 <= materialIndex < materialCount if the patch does have materials
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);


// properties for an individual material (if multipatch.MaterialCount > 0)
var color = multipatch.GetMaterialColor(materialIndex);
var edgeColor = multipatch.GetMaterialEdgeColor(materialIndex);
var edgeWidth = multipatch.GetMaterialEdgeWidth(materialIndex);
var shiness = multipatch.GetMaterialShininess(materialIndex);
var percent = multipatch.GetMaterialTransparencyPercent(materialIndex);
var cullBackFace = multipatch.IsMaterialCullBackFace(materialIndex);

// texture properties
bool isTextured = multipatch.IsMaterialTextured(materialIndex);
if (isTextured)
{
int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
TextureCompressionType compressionType = multipatch.GetMaterialTextureCompressionType(materialIndex);
var texture = multipatch.GetMaterialTexture(materialIndex);
}
}

// texture coordinates (if multipatch.HasTextures = true)
if (hasTextures)
{
int numPatchTexturePoints = multiPatch.GetPatchTextureVertexCount(patchIndex);
var coordinate2D = multiPatch.GetPatchTextureCoordinate(patchIndex, 0);

ICollection<Coordinate2D> textureCoordinates = new List<Coordinate2D>(numPatchTexturePoints);
multiPatch.GetPatchTextureCoordinates(patchIndex, ref textureCoordinates);
}


// patch normals (if multipatch.HasNormals = true)
if (hasNormals)
{
// number of normal coordinates = multipatch.GetPatchPointCount(patchIndex)
Coordinate3D patchNormal = multipatch.GetPatchNormal(patchIndex, 0);
ICollection<Coordinate3D> normalCoordinates = new List<Coordinate3D>(patchPointCount);
multipatch.GetPatchNormals(patchIndex, ref normalCoordinates);
}

构建多面体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// export to binary xml
string binaryXml = multiPatch.ToBinaryXml();

// import from binaryXML - methods need to run on the MCT
Multipatch binaryMultipatch = MultipatchBuilderEx.FromBinaryXml(binaryXml);

// xml export / import
string xml = multiPatch.ToXml();
Multipatch xmlMultipatch = MultipatchBuilderEx.FromXml(xml);

// esriShape export/import
byte[] buffer = multiPatch.ToEsriShape();
Multipatch esriPatch = MultipatchBuilderEx.FromEsriShape(buffer);

// or use GeometryEngine
Multipatch patchImport = GeometryEngine.Instance.ImportFromEsriShape(EsriShapeImportFlags.EsriShapeImportDefaults, buffer, multiPatch.SpatialReference) as Multipatch;

通过MultipatchBuilderEx构建多面体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
var coords_face1 = new List<Coordinate3D>()
{
new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
new Coordinate3D(12.495461061000071,41.902603910000039,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902576344000067,62.552700000000186),
};

var coords_face2 = new List<Coordinate3D>()
{
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};

var coords_face3 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};

var coords_face4 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
};

var coords_face5 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};

var coords_face6 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};

// materials
var materialRed = new BasicMaterial();
materialRed.Color = System.Windows.Media.Colors.Red;

var materialTransparent = new BasicMaterial();
materialTransparent.Color = System.Windows.Media.Colors.White;
materialTransparent.TransparencyPercent = 80;

var blueTransparent = new BasicMaterial(materialTransparent);
blueTransparent.Color = System.Windows.Media.Colors.SkyBlue;

// create a list of patch objects
var patches = new List<Patch>();

// create the multipatchBuilderEx object
var mpb = new ArcGIS.Core.Geometry.MultipatchBuilderEx();

// make each patch using the appropriate coordinates and add to the patch list
var patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face1;
patches.Add(patch);

patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face2;
patches.Add(patch);

patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face3;
patches.Add(patch);

patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face4;
patches.Add(patch);

patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face5;
patches.Add(patch);

patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face6;
patches.Add(patch);

patches[0].Material = materialRed;
patches[1].Material = materialTransparent;
patches[2].Material = materialRed;
patches[3].Material = materialRed;
patches[4].Material = materialRed;
patches[5].Material = blueTransparent;

// assign the patches to the multipatchBuilder
mpb.Patches = patches;

// check which patches currently contain the material
var red = mpb.QueryPatchIndicesWithMaterial(materialRed);
// red should be [0, 2, 3, 4]


// call ToGeometry to get the multipatch
multipatch = mpb.ToGeometry() as Multipatch;

从另一个多面体构建多面体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// create the multipatchBuilderEx object
var builder = new ArcGIS.Core.Geometry.MultipatchBuilderEx(multipatch);

// check some properties
bool hasM = builder.HasM;
bool hasZ = builder.HasZ;
bool hasID = builder.HasID;
bool isEmpty = builder.IsEmpty;
bool hasNormals = builder.HasNormals;

var patches = builder.Patches;
int patchCount = patches.Count;

// if there's some patches
if (patchCount > 0)
{
int pointCount = builder.GetPatchPointCount(0);

// replace the first point in the first patch
if (pointCount > 0)
{
// get the first point
var pt = builder.GetPoint(0, 0);
builder.SetPoint(0, 0, newPoint);
}

// check which patches currently contain the texture
var texture = builder.QueryPatchIndicesWithTexture(brickTextureResource);

// assign a texture material
patches[0].Material = brickMaterialTexture;
}

// update the builder for M awareness
builder.HasM = true;
// synchronize the patch attributes to match the builder attributes
// in this instance because we just set HasM to true on the builder, each patch will now get a default M value for it's set of coordinates
builder.SynchronizeAttributeAwareness();

// call ToGeometry to get the multipatch
multipatch = builder.ToGeometry() as Multipatch;

// multipatch.HasM will be true

从 3D 模型文件构建多面体

1
2
3
4
5
6
7
8
9
10
11
12
13
try
{
var model = ArcGIS.Core.Geometry.MultipatchBuilderEx.From3DModelFile(@"c:\Temp\My3dModelFile.dae");
bool modelIsEmpty = model.IsEmpty;
}
catch (FileNotFoundException)
{
// file not found
}
catch (ArgumentException)
{
// File extension is unsupported or cannot read the file
}

构建 3D 特殊多面体形状

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var sr = MapView.Active.Map.SpatialReference;

var extent = MapView.Active.Extent;
var center = extent.Center;
var centerZ = MapPointBuilderEx.CreateMapPoint(center.X, center.Y, 500, sr);

// cube
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cube, centerZ, 200, sr);
// tetrahedron
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Tetrahedron, centerZ, 200, sr);
// diamond
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Diamond, centerZ, 200, sr);
// hexagon
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Hexagon, centerZ, 200, sr);

// sphere frame
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.SphereFrame, centerZ, 200, 0.8, sr);
// sphere
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Sphere, centerZ, 200, 0.8, sr);
// cylinder
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cylinder, centerZ, 200, 0.8, sr);
// cone
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);


// use the builder to add materials or textures
// - create a cone with a material
builder = new MultipatchBuilderEx(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);

BasicMaterial faceMaterial = new BasicMaterial();
faceMaterial.Color = System.Windows.Media.Color.FromRgb(255, 0, 0);
faceMaterial.Shininess = 150;
faceMaterial.TransparencyPercent = 50;
faceMaterial.EdgeWidth = 20;

foreach (var patch in builder.Patches)
patch.Material = faceMaterial;

multipatch = builder.ToGeometry() as Multipatch;

创建基本材料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Create BasicMaterial with default values
BasicMaterial material = new BasicMaterial();
System.Windows.Media.Color color = material.Color; // color = Colors.Black
System.Windows.Media.Color edgeColor = material.EdgeColor; // edgeColor = Colors.Black
int edgeWidth = material.EdgeWidth; // edgeWidth = 0
int transparency = material.TransparencyPercent; // transparency = 0
int shininess = material.Shininess; // shininess = 0
bool cullBackFace = material.IsCullBackFace; // cullBackFace = false

// Modify the properties
material.Color = System.Windows.Media.Colors.Red;
material.EdgeColor = System.Windows.Media.Colors.Blue;
material.EdgeWidth = 10;
material.TransparencyPercent = 50;
material.Shininess = 25;
material.IsCullBackFace = true;

使用 JPEG 纹理创建基本材质

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// read the jpeg into a buffer
//At 3.0 you need https://www.nuget.org/packages/Microsoft.Windows.Compatibility
//System.Drawing
System.Drawing.Image image = System.Drawing.Image.FromFile(@"C:\temp\myImageFile.jpg");
MemoryStream memoryStream = new MemoryStream();

System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
image.Save(memoryStream, format);
byte[] imageBuffer = memoryStream.ToArray();

var jpgTexture = new JPEGTexture(imageBuffer);

// texture properties
int bpp = jpgTexture.BytesPerPixel;
int columnCount = jpgTexture.ColumnCount;
int rowCount = jpgTexture.RowCount;

// build the textureResource and the material
BasicMaterial material = new BasicMaterial();
material.TextureResource = new TextureResource(jpgTexture);

使用未压缩纹理创建基本材质

1
2
3
4
5
6
7
8
9
10
11
UncompressedTexture uncompressedTexture1 = new UncompressedTexture(new byte[10 * 12 * 3], 10, 12, 3);

// texture properties
int bpp = uncompressedTexture1.BytesPerPixel;
int columnCount = uncompressedTexture1.ColumnCount;
int rowCount = uncompressedTexture1.RowCount;

// build the textureResource and the material
TextureResource tr = new TextureResource(uncompressedTexture1);
BasicMaterial material = new BasicMaterial();
material.TextureResource = tr;

获取多面体的纹理图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// <summary>
// This method gets the material texture image of a multipatch.
// This method must be called on the MCT. Use QueuedTask.Run.
// </summary>
// <param name="multipatch">The input multipatch.</param>
// <param name="patchIndex">The index of the patch (part) for which to get the material texture.</param>
public void GetMultipatchTextureImage(Multipatch multipatch, int patchIndex)
{
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);
if (!multipatch.IsMaterialTextured(materialIndex))
return;

TextureCompressionType compressionType =
multipatch.GetMaterialTextureCompressionType(materialIndex);

string ext = compressionType == TextureCompressionType.CompressionJPEG ? ".jpg" : ".dat";
byte[] textureBuffer = multipatch.GetMaterialTexture(materialIndex);

Stream imageStream = new MemoryStream(textureBuffer);
System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
image.Save(@"C:\temp\myImage" + ext);
}

获取多面体的法线坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// <summary>
// This method gets the normal coordinate of a multipatch and does something with it.
// This method must be called on the MCT. Use QueuedTask.Run.
// </summary>
// <param name="multipatch">The input multipatch.</param>
// <param name="patchIndex">The index of the patch (part) for which to get the normal.</param>
public void DoSomethingWithNormalCoordinate(Multipatch multipatch, int patchIndex)
{
if (multipatch.HasNormals)
{
// If the multipatch has normals, then the number of normals is equal to the number of points.
int numNormals = multipatch.GetPatchPointCount(patchIndex);

for (int pointIndex = 0; pointIndex < numNormals; pointIndex++)
{
Coordinate3D normal = multipatch.GetPatchNormal(patchIndex, pointIndex);

// Do something with the normal coordinate.
}
}
}

获取多面体的法线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// <summary>
// This method gets the normal coordinate of a multipatch and does something with it.
// This method must be called on the MCT. Use QueuedTask.Run.
// </summary>
// <param name="multipatch">The input multipatch.</param>
public void DoSomethingWithNormalCoordinates(Multipatch multipatch)
{
if (multipatch.HasNormals)
{
// Allocate the list only once
int numPoints = multipatch.PointCount;
ICollection<Coordinate3D> normals = new List<Coordinate3D>(numPoints);

// The parts of a multipatch are also called patches
int numPatches = multipatch.PartCount;

for (int patchIndex = 0; patchIndex < numPatches; patchIndex++)
{
multipatch.GetPatchNormals(patchIndex, ref normals);

// Do something with the normals for this patch.
}
}
}

获取多面体的材质属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void GetMaterialProperties(Multipatch multipatch, int patchIndex)
{
if (multipatch.HasMaterials)
{
// Get the material index for the specified patch.
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);

System.Windows.Media.Color color = multipatch.GetMaterialColor(materialIndex);
int tranparencyPercent = multipatch.GetMaterialTransparencyPercent(materialIndex);
bool isBackCulled = multipatch.IsMaterialCullBackFace(materialIndex);

if (multipatch.IsMaterialTextured(materialIndex))
{
int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
}
}
}

多部件

获取多部分要素的各个部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public IEnumerable<Geometry> MultipartToSinglePart(Geometry inputGeometry)
{
// list holding the part(s) of the input geometry
List<Geometry> singleParts = new List<Geometry>();

// check if the input is a null pointer or if the geometry is empty
if (inputGeometry == null || inputGeometry.IsEmpty)
return singleParts;

// based on the type of geometry, take the parts/points and add them individually into a list
switch (inputGeometry.GeometryType)
{
case GeometryType.Envelope:
singleParts.Add(inputGeometry.Clone() as Envelope);
break;
case GeometryType.Multipatch:
singleParts.Add(inputGeometry.Clone() as Multipatch);
break;
case GeometryType.Multipoint:
var multiPoint = inputGeometry as Multipoint;

foreach (var point in multiPoint.Points)
{
// add each point of collection as a standalone point into the list
singleParts.Add(point);
}
break;
case GeometryType.Point:
singleParts.Add(inputGeometry.Clone() as MapPoint);
break;
case GeometryType.Polygon:
var polygon = inputGeometry as Polygon;

foreach (var polygonPart in polygon.Parts)
{
// use the PolygonBuilderEx turning the segments into a standalone
// polygon instance
singleParts.Add(PolygonBuilderEx.CreatePolygon(polygonPart));
}
break;
case GeometryType.Polyline:
var polyline = inputGeometry as Polyline;

foreach (var polylinePart in polyline.Parts)
{
// use the PolylineBuilderEx turning the segments into a standalone
// polyline instance
singleParts.Add(PolylineBuilderEx.CreatePolyline(polylinePart));
}
break;
case GeometryType.Unknown:
break;
default:
break;
}

return singleParts;
}

获取多边形的最外层环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public Polygon GetOutermostRings(Polygon inputPolygon)
{
if (inputPolygon == null || inputPolygon.IsEmpty)
return null;

List<Polygon> internalRings = new List<Polygon>();

// explode the parts of the polygon into a list of individual geometries
// see the "Get the individual parts of a multipart feature"
// snippet for MultipartToSinglePart
var parts = MultipartToSinglePart(inputPolygon);

// get an enumeration of clockwise geometries (area > 0) ordered by the area
var clockwiseParts = parts.Where(geom => ((Polygon)geom).Area > 0)
.OrderByDescending(geom => ((Polygon)geom).Area);

// for each of the exterior rings
foreach (var part in clockwiseParts)
{
// add the first (the largest) ring into the internal collection
if (internalRings.Count == 0)
internalRings.Add(part as Polygon);

// use flag to indicate if current part is within the already selection polygons
bool isWithin = false;

foreach (var item in internalRings)
{
if (GeometryEngine.Instance.Within(part, item))
isWithin = true;
}

// if the current polygon is not within any polygon of the internal collection
// then it is disjoint and needs to be added to
if (isWithin == false)
internalRings.Add(part as Polygon);
}

PolygonBuilderEx outerRings = new PolygonBuilderEx();
// now assemble a new polygon geometry based on the internal polygon collection
foreach (var ring in internalRings)
{
outerRings.AddParts(ring.Parts);
}

// return the final geometry of the outer rings
return outerRings.ToGeometry();
}

从地理数据库检索几何

从地理数据库检索几何

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
try
{
// open a gdb
using (ArcGIS.Core.Data.Geodatabase gdb =
new ArcGIS.Core.Data.Geodatabase(
new FileGeodatabaseConnectionPath(new Uri(@"c:\Temp\MyDatabase.gdb"))))
{
//Open a featureClass
using (ArcGIS.Core.Data.FeatureClass featureClass =
gdb.OpenDataset<ArcGIS.Core.Data.FeatureClass>("Polygon"))
{

ArcGIS.Core.Data.QueryFilter filter =
new ArcGIS.Core.Data.QueryFilter()
{
WhereClause = "OBJECTID = 6"
};

// get the row
using (ArcGIS.Core.Data.RowCursor rowCursor =
featureClass.Search(filter, false))
{
while (rowCursor.MoveNext())
{
using (var row = rowCursor.Current)
{
long oid = row.GetObjectID();

// get the shape from the row
ArcGIS.Core.Data.Feature feature = row as ArcGIS.Core.Data.Feature;
Polygon polygon = feature.GetShape() as Polygon;

// do something here
}
}
}
}
}
}
catch (Exception ex)
{
// error - handle appropriately
}
});

导入、导出几何图形

将几何图形导入和导出为已知文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// create a point with z, m
MapPoint point = MapPointBuilderEx.CreateMapPoint(
100, 200, 300, 400, SpatialReferences.WebMercator);

// set the flags
WktExportFlags wktExportFlags = WktExportFlags.WktExportDefaults;
WktImportFlags wktImportFlags = WktImportFlags.WktImportDefaults;

// export and import
string wktString = GeometryEngine.Instance.ExportToWKT(wktExportFlags, point);
MapPoint importPoint = GeometryEngine.Instance.ImportFromWKT(
wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

double x = importPoint.X; // x = 100
double y = importPoint.Y; // y = 200
bool hasZ = importPoint.HasZ; // hasZ = true
double z = importPoint.Z; // z = 300
bool hasM = importPoint.HasM; // hasM = true
double m = importPoint.M; // m = 400

// export without z
WktExportFlags exportFlagsNoZ = WktExportFlags.WktExportStripZs;
wktString = GeometryEngine.Instance.ExportToWKT(exportFlagsNoZ, point);
importPoint = GeometryEngine.Instance.ImportFromWKT(
wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

x = importPoint.X; // x = 100
y = importPoint.Y; // y = 200
hasZ = importPoint.HasZ; // hasZ = false
z = importPoint.Z; // z = 0
hasM = importPoint.HasM; // hasM = true
m = importPoint.M; // m = 400

// export without m
WktExportFlags exportFlagsNoM = WktExportFlags.WktExportStripMs;
wktString = GeometryEngine.Instance.ExportToWKT(exportFlagsNoM, point);
importPoint = GeometryEngine.Instance.ImportFromWKT(
wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

x = importPoint.X; // x = 100
y = importPoint.Y; // y = 200
hasZ = importPoint.HasZ; // hasZ = true
z = importPoint.Z; // z = 300
hasM = importPoint.HasM; // hasM = false
m = importPoint.M; // m = Nan

// export without z, m
wktString = GeometryEngine.Instance.ExportToWKT(
exportFlagsNoZ | exportFlagsNoM, point);
importPoint = GeometryEngine.Instance.ImportFromWKT(
wktImportFlags, wktString, SpatialReferences.WebMercator) as MapPoint;

x = importPoint.X; // x = 100
y = importPoint.Y; // y = 200
hasZ = importPoint.HasZ; // hasZ = false
z = importPoint.Z; // z = 0
hasM = importPoint.HasM; // hasM = false
m = importPoint.M; // m = Nan

将几何图形导入和导出到众所周知的二进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// create a polyline
List<Coordinate2D> coords = new List<Coordinate2D>
{
new Coordinate2D(0, 0),
new Coordinate2D(0, 1),
new Coordinate2D(1, 1),
new Coordinate2D(1, 0)
};

Polyline polyline = PolylineBuilderEx.CreatePolyline(
coords, SpatialReferences.WGS84);

WkbExportFlags wkbExportFlags = WkbExportFlags.WkbExportDefaults;
WkbImportFlags wkbImportFlags = WkbImportFlags.WkbImportDefaults;

// export and import
byte[] buffer = GeometryEngine.Instance.ExportToWKB(wkbExportFlags, polyline);
Geometry geometry = GeometryEngine.Instance.ImportFromWKB(
wkbImportFlags, buffer, SpatialReferences.WGS84);
Polyline importPolyline = geometry as Polyline;


// alternatively, determine the size for the buffer
int bufferSize = GeometryEngine.Instance.GetWKBSize(wkbExportFlags, polyline);
buffer = new byte[bufferSize];
// export
bufferSize = GeometryEngine.Instance.ExportToWKB(
wkbExportFlags, polyline, ref buffer);
// import
importPolyline = GeometryEngine.Instance.ImportFromWKB(
wkbImportFlags, buffer, SpatialReferences.WGS84) as Polyline;

将几何导入和导出到 EsriShape

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// create an envelope
List<MapPoint> coordsZM = new List<MapPoint>
{
MapPointBuilderEx.CreateMapPoint(1001, 1002, 1003, 1004),
MapPointBuilderEx.CreateMapPoint(2001, 2002, Double.NaN, 2004),
MapPointBuilderEx.CreateMapPoint(3001, -3002, 3003, 3004),
MapPointBuilderEx.CreateMapPoint(1001, -4002, 4003, 4004)
};

Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(
coordsZM[0], coordsZM[2], SpatialReferences.WGS84);

// export and import
EsriShapeExportFlags exportFlags = EsriShapeExportFlags.EsriShapeExportDefaults;
EsriShapeImportFlags importFlags = EsriShapeImportFlags.EsriShapeImportDefaults;
byte[] buffer = GeometryEngine.Instance.ExportToEsriShape(exportFlags, envelope);
Polygon importedPolygon = GeometryEngine.Instance.ImportFromEsriShape(
importFlags, buffer, envelope.SpatialReference) as Polygon;
Envelope importedEnvelope = importedPolygon.Extent;

// export without z,m
buffer = GeometryEngine.Instance.ExportToEsriShape(
EsriShapeExportFlags.EsriShapeExportStripZs |
EsriShapeExportFlags.EsriShapeExportStripMs, envelope);
importedPolygon = GeometryEngine.Instance.ImportFromEsriShape(
importFlags, buffer, SpatialReferences.WGS84) as Polygon;
importedEnvelope = importedPolygon.Extent;

bool hasZ = importedEnvelope.HasZ; // hasZ = false
bool hasM = importedEnvelope.HasM; // hasM = false

// export with shapeSize
int bufferSize = GeometryEngine.Instance.GetEsriShapeSize(
exportFlags, envelope);
buffer = new byte[bufferSize];

bufferSize = GeometryEngine.Instance.ExportToEsriShape(
exportFlags, envelope, ref buffer);
importedPolygon = GeometryEngine.Instance.ImportFromEsriShape(
importFlags, buffer, envelope.SpatialReference) as Polygon;
importedEnvelope = importedPolygon.Extent;


// or use the envelope and envelopeBuilderEx classes
buffer = envelope.ToEsriShape();
// buffer represents a polygon as there is not an envelope Esri shape buffer
// EnvelopeBuilderEx.FromEsriShape takes a polygon Esri shape buffer and returns the extent of the polygon.
importedEnvelope = EnvelopeBuilderEx.FromEsriShape(buffer);

将几何图形导入和导出为 JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// MapPoint
string inputString =
"{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}";
Geometry geometry = GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, inputString);

MapPoint importPoint = geometry as MapPoint;
// importPoint = 1, 2
// importPoint.SpatialReference.WKid = 4326

// use the MapPointBuilderEx convenience method
MapPoint importPoint2 = MapPointBuilderEx.FromJson(inputString);
// importPoint2 = 1, 2
// impointPoint2.SpatialReference.Wkid = 4326

string outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportDefaults, importPoint);
// outputString =
// "{\"x\":1,\"y\":2,\"spatialReference\":{\"wkid\":4326,\"latestWkid\":4326}}"

string outputString2 = importPoint.ToJson();

inputString =
"{\"spatialReference\":{\"wkid\":4326},\"z\":3,\"m\":4,\"x\":1,\"y\":2}";
importPoint = GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, inputString) as MapPoint;
// importPoint.HasM = true
// importPoint.HasZ = true
// importPoint.X = 1
// importPoint.Y = 2
// importPoint.M = 4
// importPoint.Z = 3

importPoint2 = MapPointBuilderEx.FromJson(inputString);

// export to json - skip spatial reference
outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportSkipCRS, importPoint);
// outputString = "{\"x\":1,\"y\":2,\"z\":3,\"m\":4}"

// export from mappoint, skipping the sr - same as GeometryEngine.Instance.ExportToJson w JsonExportFlags.JsonExportSkipCRS
outputString2 = importPoint.ToJson(true);

//
// Multipoint
//
List<Coordinate2D> coords = new List<Coordinate2D>()
{
new Coordinate2D(100, 200),
new Coordinate2D(201, 300),
new Coordinate2D(301, 400),
new Coordinate2D(401, 500)
};

Multipoint multipoint = MultipointBuilderEx.CreateMultipoint(
coords, SpatialReferences.WebMercator);

inputString =
"{\"points\":[[100,200],[201,300],[301,400],[401,500]],\"spatialReference\":{\"wkid\":3857}}";
Multipoint importMultipoint =
GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, inputString) as Multipoint;
// importMultipoint.IsEqual(multipoint) = true

ReadOnlyPointCollection points = importMultipoint.Points;
// points.Count = 4
// points[0] = 100, 200
// points[1] = 201, 300
// points[2] = 301, 400
// points[3] = 401, 500

// use the MultipointbuilderEx convenience method
Multipoint importMultipoint2 = MultipointBuilderEx.FromJson(inputString);
// importMultipoint2.IsEqual(multipoint) = true

// export to json
outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportDefaults, multipoint);
// outputString = inputString

// or use the multipoint itself
outputString2 = multipoint.ToJson();

//
// Polyline
//
Polyline polyline = PolylineBuilderEx.CreatePolyline(
coords, SpatialReferences.WebMercator);

// export without the spatial reference
outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportSkipCRS, polyline);
// import
geometry = GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, outputString);
Polyline importPolyline = geometry as Polyline;
// importPolyline.SpatialReference = null


points = importPolyline.Points;
// points.Count = 4
// points[0] = 100, 200
// points[1] = 201, 300
// points[2] = 301, 400
// points[3] = 401, 500

// use the polylineBuilderEx convenience method
Polyline importPolyline2 = PolylineBuilderEx.FromJson(outputString);
// importPolyline2 = importPolyline

outputString2 = importPolyline2.ToJson();
// outputString2 = outputString

//
// Polygon
//
Polygon polygon = PolygonBuilderEx.CreatePolygon(
coords, SpatialReferences.WebMercator);

// export without the spatial reference
outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportSkipCRS, polygon);
// import
geometry = GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, outputString);

Polygon importPolygon = geometry as Polygon;
// importPolygon.SpatialReference = null
points = importPolygon.Points;
// points.Count = 5

// polygonBuilderEx convenience method
Polygon importPolyon2 = PolygonBuilderEx.FromJson(outputString);
// importPolygon2 = importPolygon

// export from the polygon
outputString2 = importPolyon2.ToJson(true);

// Empty polygon
polygon = PolygonBuilderEx.CreatePolygon(SpatialReferences.WebMercator);
outputString = GeometryEngine.Instance.ExportToJson(
JsonExportFlags.JsonExportDefaults, polygon);
importPolygon = GeometryEngine.Instance.ImportFromJson(
JsonImportFlags.JsonImportDefaults, outputString) as Polygon;

// importPolygon.IsEmpty = true
// importPolygon.SpatialReference.Wkid = 3857

将几何图形导入和导出为 XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
MapPoint minPoint = MapPointBuilderEx.CreateMapPoint(1, 1, 1, 1, 3);
MapPoint maxPoint = MapPointBuilderEx.CreateMapPoint(5, 5, 5);

//
// MapPoint
//
string xml = minPoint.ToXml();
MapPoint minPointImport = MapPointBuilderEx.FromXml(xml);
// minPointImport = minPoint

//
// Envelope
//
Envelope envelopeWithID = EnvelopeBuilderEx.CreateEnvelope(minPoint, maxPoint);

// Envelopes don't have IDs
// envelopeWithID.HasID = false
// envelopeWithID.HasM = true
// envelopeWithID.HasZ = true

xml = envelopeWithID.ToXml();
Envelope envelopeImport = EnvelopeBuilderEx.FromXml(xml);

//
// Multipoint
//
List<MapPoint> list = new List<MapPoint>();
list.Add(minPoint);
list.Add(maxPoint);

Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);

xml = multiPoint.ToXml();
Multipoint multipointImport = MultipointBuilderEx.FromXml(xml);
// multipointImport.PointCount == 2
// multipointImport.HasID = true
// multipointImport.HasM = true
// multipointImport.HasZ= true

转换

创建地理转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// create from wkid
GeographicTransformation gt1478 =
ArcGIS.Core.Geometry.GeographicTransformation.Create(1478);
string name = gt1478.Name;
string wkt = gt1478.Wkt;
int wkid = gt1478.Wkid;

// create from wkt
GeographicTransformation another_gt1478 =
ArcGIS.Core.Geometry.GeographicTransformation.Create(wkt);

// inverse
GeographicTransformation inverse_gt148 =
another_gt1478.GetInverse() as GeographicTransformation;
bool isForward = inverse_gt148.IsForward;

创建复合地理变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Create singleton from wkid
CompositeGeographicTransformation cgt =
ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(108272);
int count = cgt.Count; // count = 1

IList<GeographicTransformation> gts = cgt.Transformations
as IList<GeographicTransformation>;
gts.Add(ArcGIS.Core.Geometry.GeographicTransformation.Create(1437, false));
count = cgt.Count; // count = 2

// create from an enumeration
CompositeGeographicTransformation another_cgt =
ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(gts);
GeographicTransformation gt0 = another_cgt[0];
GeographicTransformation gt1 = another_cgt[1];

// get the inverse
CompositeGeographicTransformation inversed_cgt = another_cgt.GetInverse() as CompositeGeographicTransformation;
// inversed_cgt[0] is same as gt1
// inversed_cgt[1] is same as gt0

var wkt = gt0.Wkt;
// create from string
CompositeGeographicTransformation third_cgt =
ArcGIS.Core.Geometry.CompositeGeographicTransformation.Create(wkt, gt0.IsForward);
count = third_cgt.Count; // count = 1

// create from josn
string json = cgt.ToJson();
CompositeGeographicTransformation joson_cgt =
DatumTransformation.CreateFromJson(json) as CompositeGeographicTransformation;

创建投影转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// methods need to be on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
SpatialReference sr4267 = SpatialReferenceBuilder.CreateSpatialReference(4267);
SpatialReference sr4326 = SpatialReferences.WGS84;
SpatialReference sr3857 = SpatialReferences.WebMercator;

// Create transformation from 4267 -> 3857
ProjectionTransformation projTransFromSRs =
ArcGIS.Core.Geometry.ProjectionTransformation.Create(sr4267, sr3857);

// create an envelope
Envelope env = EnvelopeBuilderEx.CreateEnvelope(
new Coordinate2D(2, 2), new Coordinate2D(3, 3), sr4267);

// Project with one geo transform 4267 -> 3857
Envelope projectedEnvEx = GeometryEngine.Instance.ProjectEx(
env, projTransFromSRs) as Envelope;

// Create inverse transformation, 3857 -> 4267
ProjectionTransformation projTransFromSRsInverse =
ArcGIS.Core.Geometry.ProjectionTransformation.Create(sr3857, sr4267);
// Project the projected envelope back using the inverse transformation
Envelope projectedEnvBack =
GeometryEngine.Instance.ProjectEx(
projectedEnvEx, projTransFromSRsInverse) as Envelope;

bool isEqual = env.IsEqual(projectedEnvBack);
});

创建高压基准变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Create from wkid
HVDatumTransformation hv110018 = HVDatumTransformation.Create(110018);
int wkid = hv110018.Wkid;
bool isForward = hv110018.IsForward; // isForward = true
string name = hv110018.Name; // Name = WGS_1984_To_WGS_1984_EGM2008_1x1_Height

// Create from wkt
string wkt = hv110018.Wkt;
HVDatumTransformation hv110018FromWkt = HVDatumTransformation.Create(wkt);

// Get the inverse
HVDatumTransformation hv110018Inverse =
hv110018.GetInverse() as HVDatumTransformation;
// hv110018Inverse.IsForward = false

创建复合高压基准变换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
HVDatumTransformation hv1 = HVDatumTransformation.Create(108034);
HVDatumTransformation hv2 = HVDatumTransformation.Create(108033, false);
List<HVDatumTransformation> hvs = new List<HVDatumTransformation>() { hv1, hv2 };

// create from enumeration
CompositeHVDatumTransformation compositehv =
CompositeHVDatumTransformation.Create(hvs);
int count = compositehv.Count; // count = 2

List<HVDatumTransformation> transforms =
compositehv.Transformations as List<HVDatumTransformation>;
HVDatumTransformation tranform = transforms[0];
// transform.Wkid = 108034

// get inverse
CompositeHVDatumTransformation inverse_compositehv =
compositehv.GetInverse() as CompositeHVDatumTransformation;

// create from xml
string xml = compositehv.ToXml();
//At 2.x - CompositeHVDatumTransformation xml_compositehv =
// CompositeHVDatumTransformation.CreateFromXML(xml);

var xml_compositehv = CompositeHVDatumTransformation.CreateFromXml(xml);

// create from json
string json = compositehv.ToJson();
CompositeHVDatumTransformation json_compositehv =
DatumTransformation.CreateFromJson(json) as CompositeHVDatumTransformation;

确定转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
//
// find the first transformation used between spatial references 4267 and 4326
//
SpatialReference sr4267 =
SpatialReferenceBuilder.CreateSpatialReference(4267);
SpatialReference sr4326 = SpatialReferences.WGS84;

List<ProjectionTransformation> transformations =
ProjectionTransformation.FindTransformations(sr4267, sr4326);
// transformations.Count = 1
ProjectionTransformation projTrans = transformations[0];
CompositeGeographicTransformation compositeGT =
projTrans.Transformation as CompositeGeographicTransformation;
GeographicTransformation gt = compositeGT[0];
// gt.Wkid = 15851
// gt.Name = "NAD_1927_To_WGS_1984_79_CONUS"
// gt.IsForward = true


//
// find the first five transformation used between spatial references 4267 and 4326
//
transformations = ProjectionTransformation.FindTransformations(
sr4267, sr4326, numResults: 5);
// transformations.Count = 5
projTrans = transformations[0];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 1
// compositeGT[0].Wkid = 15851
// compositeGT[0].Name = "NAD_1927_To_WGS_1984_79_CONUS"
// compositeGT[0].IsForward = true

projTrans = transformations[1];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 1
// compositeGT[0].Wkid = 1173
// compositeGT[0].Name = "NAD_1927_To_WGS_1984_4"
// compositeGT[0].IsForward = true

projTrans = transformations[2];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 1
// compositeGT[0].Wkid = 1172
// compositeGT[0].Name = "NAD_1927_To_WGS_1984_3"
// compositeGT[0].IsForward = true

projTrans = transformations[3];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 2
// compositeGT[0].Wkid = 1241
// compositeGT[0].Name = "NAD_1927_To_NAD_1983_NADCON"
// compositeGT[0].IsForward = true

// compositeGT[1].Wkid = 108190
// compositeGT[1].Name = "WGS_1984_(ITRF00)_To_NAD_1983"
// compositeGT[1].IsForward = false

projTrans = transformations[4];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 2
// compositeGT[0].Wkid = 1241
// compositeGT[0].Name = "NAD_1927_To_NAD_1983_NADCON"
// compositeGT[0].IsForward = true

// compositeGT[1].Wkid = 1515
// compositeGT[1].Name = "NAD_1983_To_WGS_1984_5"
// compositeGT[1].IsForward = true


//
// find the first transformation used between spatial
// references 4267 and 4326 within Alaska
//

// Alaska
Envelope envelope = EnvelopeBuilderEx.CreateEnvelope(-161, 61, -145, 69);
transformations = ProjectionTransformation.FindTransformations(
sr4267, sr4326, envelope);
// transformations.Count = 1
projTrans = transformations[0];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 2
// compositeGT[0].Wkid = 1243
// compositeGT[0].Name = "NAD_1927_To_NAD_1983_Alaska"
// compositeGT[0].IsForward = true

// compositeGT[1].Wkid = 108190
// compositeGT[1].Name = "WGS_1984_(ITRF00)_To_NAD_1983"
// compositeGT[1].IsForward = false


//
// find the first geographic transformation used between two spatial references with VCS (use vertical = false)
//
SpatialReference inSR =
SpatialReferenceBuilder.CreateSpatialReference(4269, 115702);
SpatialReference outSR =
SpatialReferenceBuilder.CreateSpatialReference(4326, 3855);

// Even though each spatial reference has a VCS,
// vertical = false should return geographic transformations.
transformations = ProjectionTransformation.FindTransformations(inSR, outSR);
// transformations.Count = 1
projTrans = transformations[0];
compositeGT = projTrans.Transformation as CompositeGeographicTransformation;
// compositeGT.Count = 1
// compositeGT[0].Wkid = 108190
// compositeGT[0].Name = ""WGS_1984_(ITRF00)_To_NAD_1983"
// compositeGT[0].IsForward = false

//
// find the first vertical transformation used between two spatial references with VCS (use vertical = true)
//

transformations =
ProjectionTransformation.FindTransformations(
inSR, outSR, vertical: true);
// transformations.Count = 1
projTrans = transformations[0];

CompositeHVDatumTransformation compositeHV =
projTrans.Transformation as CompositeHVDatumTransformation;
// compositeHV.Count = 2
// compositeHV[0].Wkid = 1188
// compositeHV[0].Name = "NAD_1983_To_WGS_1984_1"
// compositeHV[0].IsForward = true

// compositeHV[1].Wkid = 110019
// compositeHV[1].Name = "WGS_1984_To_WGS_1984_EGM2008_2.5x2.5_Height"
// compositeHV[1].IsForward = true
});

地图点地理坐标字符串

地图点 - 地理坐标字符串转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
SpatialReference sr = SpatialReferences.WGS84;
SpatialReference sr2 = SpatialReferences.WebMercator;

// create some points
MapPoint point0 = MapPointBuilderEx.CreateMapPoint(0, 0, sr);
MapPoint point1 = MapPointBuilderEx.CreateMapPoint(10, 20, sr);
MapPoint point2 = GeometryEngine.Instance.Project(point1, sr2) as MapPoint;
MapPoint pointEmpty = MapPointBuilderEx.CreateMapPoint(sr);
MapPoint pointwithNoSR = MapPointBuilderEx.CreateMapPoint(1, 1);
MapPoint pointZM = MapPointBuilderEx.CreateMapPoint(1, 2, 3, 4, sr);

// convert to MGRS
ToGeoCoordinateParameter mgrsParam =
new ToGeoCoordinateParameter(GeoCoordinateType.MGRS);
// 31NAA6602100000
string geoCoordString = point0.ToGeoCoordinateString(mgrsParam);

// use the builder to create a new point from the string.
// Coordinates are the same
// outPoint.x = 0; outPoint.Y = 0
MapPoint outPoint =
MapPointBuilderEx.FromGeoCoordinateString(
geoCoordString, sr, GeoCoordinateType.MGRS);

// 32QPH0460911794
// outPoint.X = 10; outPoint.Y = 20
geoCoordString = point1.ToGeoCoordinateString(mgrsParam);
outPoint = MapPointBuilderEx.FromGeoCoordinateString(
geoCoordString, sr, GeoCoordinateType.MGRS);

// z, m are not transformed
// outPoint.X = 1; outPoint.Y = 2; outPoint.Z = Nan; outPoint.M = Nan;
geoCoordString = pointZM.ToGeoCoordinateString(mgrsParam);
outPoint = MapPointBuilderEx.FromGeoCoordinateString(
geoCoordString, sr, GeoCoordinateType.MGRS);

// set the number of digits to 2 and convert
// 32QPH0512
// outPoint.X = 10; outPoint.Y = 20
mgrsParam.NumDigits = 2;
geoCoordString = point1.ToGeoCoordinateString(mgrsParam);
outPoint = MapPointBuilderEx.FromGeoCoordinateString(
geoCoordString, sr, GeoCoordinateType.MGRS);


// convert to UTM
ToGeoCoordinateParameter utmParam =
new ToGeoCoordinateParameter(GeoCoordinateType.UTM);
// 31N 166021 0000000
geoCoordString = point0.ToGeoCoordinateString(utmParam);
// 32Q 604609 2211793
geoCoordString = point1.ToGeoCoordinateString(utmParam);

// convert to DMS
ToGeoCoordinateParameter dmsParam =
new ToGeoCoordinateParameter(GeoCoordinateType.DMS);
// 00 00 00.00N 000 00 00.00E
geoCoordString = point0.ToGeoCoordinateString(dmsParam);
// 20 00 00.00N 010 00 00.00E
geoCoordString = point1.ToGeoCoordinateString(dmsParam);

// convert to DDM
ToGeoCoordinateParameter ddmParam =
new ToGeoCoordinateParameter(GeoCoordinateType.DDM);
// 00 00.0000N 000 00.0000E
geoCoordString = point0.ToGeoCoordinateString(ddmParam);
// 20 00.0000N 010 00.0000E
geoCoordString = point1.ToGeoCoordinateString(ddmParam);

// convert to DD
ToGeoCoordinateParameter ddParam =
new ToGeoCoordinateParameter(GeoCoordinateType.DD);
// 00.000000N 000.000000E
geoCoordString = point0.ToGeoCoordinateString(ddParam);
// 20.000000N 010.000000E
geoCoordString = point1.ToGeoCoordinateString(ddParam);

角度单元

角度单位 - 在度和弧度之间转换

1
2
3
4
5
// convert 45 degrees to radians
double radians = AngularUnit.Degrees.ConvertToRadians(45);

// convert PI to degrees
double degrees = AngularUnit.Degrees.ConvertFromRadians(Math.PI);

角度单位 - 使用工厂代码创建角度单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
try
{
// create a Grad unit
var grad = AngularUnit.CreateAngularUnit(9105);
string unitName = grad.Name; // Grad
double conversionFactor = grad.ConversionFactor; // 0.015708
double radiansPerUnit = grad.RadiansPerUnit;
int factoryCode = grad.FactoryCode; // 9105

// convert 10 grads to degrees
double val = grad.ConvertTo(10, AngularUnit.Degrees);

// convert 10 radians to grads
val = grad.ConvertFromRadians(10);
}
catch (ArgumentException)
{
// ArgumentException will be thrown by CreateAngularUnit in
// the following scenarios:
// - if the factory code used is a non-angular factory code
// (i.e. it corresponds to square meters which is an area unit code)
// - if the factory code used is invalid
// (i.e. it is negative or doesn't correspond to any factory code)
}

角度单位 - 创建自定义角度单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// custom unit - 3 radians per unit
var myAngularUnit = AngularUnit.CreateAngularUnit("myCustomAngularUnit", 3);
string Name = myAngularUnit.Name; // myCustomAngularUnit
double Factor = myAngularUnit.ConversionFactor; // 3
int Code = myAngularUnit.FactoryCode; // 0 because it is a custom angular unit
double radiansUnit = myAngularUnit.RadiansPerUnit; // 3

// convert 10 degrees to my unit
double converted = AngularUnit.Degrees.ConvertTo(10, myAngularUnit);
// convert it back to degrees
converted = myAngularUnit.ConvertTo(converted, AngularUnit.Degrees);

// convert 1 radian into my angular units
converted = myAngularUnit.ConvertFromRadians(1);

// get the wkt
string wkt = myAngularUnit.Wkt;

// create an angular unit from this wkt
var anotherAngularUnit = AngularUnit.CreateAngularUnit(wkt);
// anotherAngularUnit.ConversionFactor = 3
// anotherAngularUnit.FactoryCode = 0
// anotherAngularUnit.RadiansPerUnit = 3

线性单位

线性单位 - 在英尺和米之间转换

1
2
3
4
5
// convert 10 feet to meters
double metres = LinearUnit.Feet.ConvertToMeters(10);

// convert 20 meters to feet
double feet = LinearUnit.Feet.ConvertFromMeters(20.0);

线性单位 - 在厘米和毫米之间转换

1
2
3
4
5
6
7
8
// convert 11 centimeters to millimeters
double mm = LinearUnit.Centimeters.ConvertTo(11, LinearUnit.Millimeters);

// convert the result back to centimeters
double cm = LinearUnit.Millimeters.ConvertTo(mm, LinearUnit.Centimeters);

// convert the millimeter result back to meters
double meters = LinearUnit.Millimeters.ConvertToMeters(mm);

线性单位 - 使用工厂代码创建线性单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
try
{
// create a british 1936 foot
var britFoot = LinearUnit.CreateLinearUnit(9095);
string unitName = britFoot.Name; // "Foot_British_1936"
double conversionFactor = britFoot.ConversionFactor; // 0.3048007491
double metersPerUnit = britFoot.MetersPerUnit;
int factoryCode = britFoot.FactoryCode; // 9095

// convert 10 british 1936 feet to centimeters
double val = britFoot.ConvertTo(10, LinearUnit.Centimeters);

// convert 10 m to british 1936 feet
val = britFoot.ConvertFromMeters(10);
}
catch (ArgumentException)
{
// ArgumentException will be thrown by CreateLinearUnit
// in the following scenarios:
// - if the factory code used is a non-linear factory code
// (i.e. it corresponds to square meters which is an area unit code)
// - if the factory code used is invalid
// (i.e. it is negative or doesn't correspond to any factory code)
}

线性单位 - 创建自定义线性单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// create a custom linear unit - there are 0.33 meters per myLinearUnit
var myLinearUnit = LinearUnit.CreateLinearUnit("myCustomLinearUnit", 0.33);
string name = myLinearUnit.Name; // myCustomLinearUnit
double convFactor = myLinearUnit.ConversionFactor; // 0.33
int code = myLinearUnit.FactoryCode; // 0 for custom units
double metersUnit = myLinearUnit.MetersPerUnit; // 0.33
string toString = myLinearUnit.ToString(); // same as Name - myCustomLinearUnit

// convert 10 centimeters to myLinearUnit
double convertedVal = LinearUnit.Centimeters.ConvertTo(10, myLinearUnit);


// get the wkt
string lu_wkt = myLinearUnit.Wkt;

// create an angular unit from this wkt
var anotherLinearUnit = LinearUnit.CreateLinearUnit(lu_wkt);
// anotherLinearUnit.ConversionFactor = 0.33
// anotherLinearUnit.FactoryCode = 0
// anotherLinearUnit.MetersPerUnit = 0.33

面积单位

面积单位 - 在平方英尺和平方米之间转换

1
2
3
4
5
// convert 700 square meters to square feet
double sqFeet = AreaUnit.SquareFeet.ConvertFromSquareMeters(700);

// convert 1100 square feet to square meters
double sqMeters = AreaUnit.SquareFeet.ConvertToSquareMeters(1000);

面积单位 - 在公顷和英亩之间转换

1
2
// convert 2 hectares to acres
double acres = AreaUnit.Hectares.ConvertTo(2, AreaUnit.Acres);

面积单位 - 在公顷和平方英里之间转换

1
2
// convert 300 hectares to square miles
double sqMiles = AreaUnit.Hectares.ConvertTo(300, AreaUnit.SquareMiles);

面积单位 - 各种单位的平方米数

1
2
3
4
5
6
double sqMetersPerUnit = AreaUnit.Acres.SquareMetersPerUnit;
sqMetersPerUnit = AreaUnit.Ares.SquareMetersPerUnit;
sqMetersPerUnit = AreaUnit.Hectares.SquareMetersPerUnit;
sqMetersPerUnit = AreaUnit.SquareKilometers.SquareMetersPerUnit;
sqMetersPerUnit = AreaUnit.SquareMiles.SquareMetersPerUnit;
sqMetersPerUnit = AreaUnit.SquareYards.SquareMetersPerUnit;

面积单位 - 创建面积单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try
{
var myFactoryCodeInit = AreaUnit.CreateAreaUnit(109439); // 109439 is the factory code for square miles

var myWktUnit = AreaUnit.CreateAreaUnit("HECTARE_AREAUNIT[\"H\",10000.0]");

var myCustomUnit = AreaUnit.CreateAreaUnit("myAreaUnit", 12);
}
catch (ArgumentException)
{
// ArgumentException will be thrown by CreateAreaUnit in the following scenarios
// - if the factory code used is a non-areal factory code (i.e. it corresponds to degrees which is an angular unit code)
// - if the factory code used is invalid (i.e. it is negative or doesn't correspond to any factory code)
}

几何引擎函数

加速几何图形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Use acceleration to speed up relational operations.  Accelerate your source geometry only if you are going to test many other geometries against it. 
// Acceleration is applicable for polylines and polygons only. Note that accelerated geometries take more memory so if you aren't going to get any
// benefit from accelerating it, don't do it.

// The performance of the following GeometryEngine functions are the only ones which can be improved with an accelerated geometry.
// 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


// methods need to run on the MCT
ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() =>
{
// accelerate the geometry to test
var acceleratedPoly = GeometryEngine.Instance.AccelerateForRelationalOperations(polygon);

// loop through all the geometries to test against
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);
}
});

确定面的面积

1
2
3
4
5
var g1 = PolygonBuilderEx.FromJson("{\"rings\": [ [ [0, 0], [10, 0], [10, 10], [0, 10] ] ] }");
double d = GeometryEngine.Instance.Area(g1);
// d = -100.0 //negative due to wrong ring orientation
d = GeometryEngine.Instance.Area(GeometryEngine.Instance.SimplifyAsFeature(g1));
// d = 100.0 // feature has been simplifed; ring orientation is correct

确定多部分多边形的边界

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// create a donut polygon.  Must use the PolygonBuilderEx object

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;

// add the outer points
PolygonBuilderEx pb = new PolygonBuilderEx(outerPts);
// add the inner points (note they are defined anticlockwise)
pb.AddPart(innerPts);
// get the polygon
donut = pb.ToGeometry();

// get the boundary
Geometry g = GeometryEngine.Instance.Boundary(donut);
Polyline boundary = g as Polyline;

缓冲地图点

1
2
3
4
// buffer a point
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
Geometry ptBuffer = GeometryEngine.Instance.Buffer(pt, 5.0);
Polygon buffer = ptBuffer as Polygon;

缓冲圆弧

1
2
3
4
5
6
7
8
9
10
// create the circular arc
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);

// buffer the arc
Polyline polyline = PolylineBuilderEx.CreatePolyline(circularArc);
Geometry lineBuffer = GeometryEngine.Instance.Buffer(polyline, 10);

缓冲多个地图点

1
2
3
4
5
6
7
8
9
10
// creates a buffer around each 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 will have 4 parts

缓冲多种不同的几何类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);

在折线上插值 Z 值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 (halfway between 0 and 50)
// polylineNoNaNZs.Points[4].HasZ = true
// polylineNoNaNZs.Points[4].Z = 38 (halfway between 76 and 0)

在多边形上插值 M 值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 (halfway between 0 and 50)

将封套在 X,Y 周围居中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

查找几何体的质心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// simple polygon
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);

// verify it is simple
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);
// find the centroid
MapPoint centroid = GeometryEngine.Instance.Centroid(polygon);
// centroid.X = 1
// centroid.Y = 1

// map Point
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

// multipoint
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

剪裁折线

1
2
3
4
5
6
7
// clip a polyline by an envelope

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);

按多边形裁剪折线

1
2
3
4
5
6
7
8
9
10
11
12
13
// clip a polyline by a polygon

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);

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

1
2
3
4
5
var sr = SpatialReferenceBuilder.CreateSpatialReference(4326);
var mapPoint = MapPointBuilderEx.CreateMapPoint(15, 60, sr);

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

构建连接点的大地测量线

1
2
3
4
5
6
7
8
9
10
var sr = SpatialReferenceBuilder.CreateSpatialReference(4326);

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

// densify by length
var gl = GeometryEngine.Instance.ConstructGeodeticLineFromPoints(GeodeticCurveType.Geodesic, pt1, pt2, null, CurveDensifyMethod.ByLength, -3.356);

// densify by deviation
gl = GeometryEngine.Instance.ConstructGeodeticLineFromPoints(GeodeticCurveType.Geodesic, pt1, pt2, null, CurveDensifyMethod.ByDeviation, -0.0026);

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

从一组折线构造多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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));

// build the polylines
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));

// construct polygons from the polylines
var polygons = GeometryEngine.Instance.ConstructPolygonsFromPolylines(polylines);

// polygons.Count = 1
// polygon coordinates are (1.0, 2.0), (1.0, 3.0), (4.0, 3.0), (4.0, 2.0)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// build a polygon      
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);

// test if an inner point is contained
MapPoint innerPt = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);
bool contains = GeometryEngine.Instance.Contains(poly, innerPt); // contains = true

// test a point on a boundary
contains = GeometryEngine.Instance.Contains(poly, poly.Points[0]); // contains = false

// test an interior line
MapPoint innerPt2 = MapPointBuilderEx.CreateMapPoint(1.25, 1.75);
List<MapPoint> innerLinePts = new List<MapPoint>();
innerLinePts.Add(innerPt);
innerLinePts.Add(innerPt2);

// test an inner polyline
Polyline polyline = PolylineBuilderEx.CreatePolyline(innerLinePts);
contains = GeometryEngine.Instance.Contains(poly, polyline); // contains = true

// test a line that crosses the boundary
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

// test a polygon in polygon
Envelope env = EnvelopeBuilderEx.CreateEnvelope(innerPt, innerPt2);
contains = GeometryEngine.Instance.Contains(poly, env); // contains = true

确定凸包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//
// convex hull around a point - returns a point
//

MapPoint pt = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);
Geometry hull = GeometryEngine.Instance.ConvexHull(pt);
MapPoint hullPt = hull as MapPoint;
// nullPt.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));

//
// convex hull around a multipoint - returns a polygon
//

// build a multiPoint
Multipoint multiPoint = MultipointBuilderEx.CreateMultipoint(list);

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

//
// convex hull around a line - returns a polyline or polygon
//

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

// 2 point straight line
Polyline polyline = PolylineBuilderEx.CreatePolyline(polylineList);
hull = GeometryEngine.Instance.ConvexHull(polyline);
Polyline hullPolyline = hull as Polyline;
// hullPolyline.Length = Math.Sqrt(2)
// hullPolyline.PointCount = 2

// 3 point angular line
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

//
// convex hull around a polygon - returns a polygon
//

// simple polygon
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

// polygon with concave angles
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//
// pt on pt
//

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

//
// pt and line
//

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
// end pt of line
crosses = GeometryEngine.Instance.Crosses(line1, pt); // crosses = false

//
// pt and polygon
//
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

//
// line and line
//
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

//
// line and polygon
//
crosses = GeometryEngine.Instance.Crosses(poly1, line1); // crosses = true

//
// polygon and polygon
//
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

使用折线切割几何图形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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 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 polygon = PolygonBuilderEx.CreatePolygon(list);
isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);
cutGeometries = GeometryEngine.Instance.Cut(polygon, cutter) as List<Geometry>;

按长度致密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// densify a line segment
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;


// densify a circular arc
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;

两个多边形之间的差异

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

确定两个几何是否不相交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//
// pt on pt
//

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

bool disjoint = GeometryEngine.Instance.Disjoint(pt, pt2); // result is true

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

disjoint = GeometryEngine.Instance.Disjoint(multiPoint, pt); // result is false

//
// pt and line
//

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); // result is true

disjoint = GeometryEngine.Instance.Disjoint(pt2, line1); // result is true

// end pt of line
disjoint = GeometryEngine.Instance.Disjoint(line1, pt); // result is false

//
// pt and polygon
//
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); // result is true
disjoint = GeometryEngine.Instance.Disjoint(pt, poly1); // result is true

//
// line and line
//

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); // result is false

//
// line and polygon
//
disjoint = GeometryEngine.Instance.Disjoint(poly1, line1); // result is false
disjoint = GeometryEngine.Instance.Disjoint(line1, poly1); // result is false

//
// polygon and polygon
//
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); // result is 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

确定两个几何之间的距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1.0, 1.0);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2.0, 2.0);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(4.0, 2.0);

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

//
// pt and multipoint
//
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)

//
// pt and envelope
//
Envelope env = EnvelopeBuilderEx.CreateEnvelope(pt1, pt2);
d = GeometryEngine.Instance.Distance(pt1, env); // d = 0

//
// pt and polyline
//
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

//
// pt and polygon
//
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)

//
// envelope and polyline
//
d = GeometryEngine.Instance.Distance(env, polyline); // d = 0

//
// polyline and polyline
//
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 and polygon
//
Polygon poly2 = PolygonBuilderEx.CreatePolygon(env);
d = GeometryEngine.Instance.Distance(poly, poly2); // d = Math.Sqrt(2)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// between points 
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 1, 1);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2, 2, 2);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(10, 2, 1);

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

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

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

// intersecting lines

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); // intersects = true
d = GeometryEngine.Instance.Distance3D(line1, line2); // d = 0 (distance is 0 when geomtries intersect)

展开信封

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
{
// expand in 3 dimensions
result = GeometryEngine.Instance.Expand(env, 0.5, 0.5, 0.5, true);
}
catch (InvalidOperationException e)
{
// the geometry is not Z-Aware
}

// expand a 3d envelope
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

扩展折线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// build a polyline
var polyline = PolylineBuilderEx.CreatePolyline(new[]
{
MapPointBuilderEx.CreateMapPoint(1, 1, 10, 20),
MapPointBuilderEx.CreateMapPoint(0, 0, 10, 20),
MapPointBuilderEx.CreateMapPoint(1, -1, 10, 20)
});

// build the extender line
var extender = PolylineBuilderEx.CreatePolyline(new[]
{
MapPointBuilderEx.CreateMapPoint(2, 2),
MapPointBuilderEx.CreateMapPoint(2, -2),
});

// extend
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

// change the flags
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

// extend
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

// extend with no intersection

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

概括

1
2
3
4
5
6
7
8
Polyline generalizedPolyline = GeometryEngine.Instance.Generalize(polylineWithZ, 200) as Polyline;
// generalizedPolyline.HasZ = true

Polygon generalized3DPolyline = GeometryEngine.Instance.Generalize3D(polylineWithZ, 200) as Polygon;
// generalized3DPolyline.HasZ = true

// note that generalized3DPolyline and generalizedPolyline will have different definitions
// ie generalizedPolyline.IsEqual(generalized3DPolyline) = false

计算面的测地线面积

1
2
3
4
5
6
7
8
9
10
11
12
13
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 is close to 255032810857732.31

area = GeometryEngine.Instance.GeodesicArea(polygon, AreaUnit.SquareKilometers);
// area is close to 255032810.85953,

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// buffer a point
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)
}

// specify a unit for the distance
outPolygon = GeometryEngine.Instance.GeodesicBuffer(pt, 5000, LinearUnit.Millimeters) as Polygon;

// buffer of 0 distance produces an empty geometry
Geometry g = GeometryEngine.Instance.GeodesicBuffer(pt, 0);
// g.IsEmpty = true

// buffer many points
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

// buffer different geometry types
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;

// specify unit types
outPolygon = GeometryEngine.Instance.GeodesicBuffer(manyGeometries, 20, LinearUnit.Miles) as Polygon;

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

1
2
3
4
5
6
7
8
var point1 = MapPointBuilderEx.CreateMapPoint(-170, 45, SpatialReferences.WGS84);
var point2 = MapPointBuilderEx.CreateMapPoint(170, 45, SpatialReferences.WGS84);

var distances_meters = GeometryEngine.Instance.GeodesicDistance(point1, point2);
// distance is approximately 1572912.2066940258 in meters

var distance_feet = GeometryEngine.Instance.GeodesicDistance(point1, point2, LinearUnit.Feet);
// distance is approximately 5160473.11904786 in feet

测地线椭圆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

确定线的测地线长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
// length is approx 5243784.5551844323 in meters

length = GeometryEngine.Instance.GeodesicLength(polyline, LinearUnit.Miles);
// length is approx 3258.33666089067 in miles

var polyline2 = GeometryEngine.Instance.Project(polyline, SpatialReferences.WGS84);
length = GeometryEngine.Instance.GeodesicLength(polyline2);
// length is approx 5243784.55518443 in meters after projecting

测地线扇区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;

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

// densify in km
Polyline geodesicPolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Kilometers, GeodeticCurveType.Geodesic) as Polyline;
// densify in m
geodesicPolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, GeodeticCurveType.Geodesic) as Polyline;

// Change curve type to Loxodrome
Polyline loxodromePolyline = GeometryEngine.Instance.GeodeticDensifyByDeviation(polyline, 200, LinearUnit.Meters, GeodeticCurveType.Loxodrome) as Polyline;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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;

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

// get the geodesic lengths of the polygon segments
ReadOnlySegmentCollection segments = polygon.Parts[0];
List<Double> geoLengths = new List<Double>(segments.Count);
foreach (Segment s in segments)
{
Polyline line = PolylineBuilderEx.CreatePolyline(s, sr);
double geoLen = GeometryEngine.Instance.GeodesicLength(line);
geoLengths.Add(geoLen);
}

// find the max length
geoLengths.Sort();
double maxLen = geoLengths[geoLengths.Count - 1];

// densify the polygon (in meters)
Polygon densifiedPoly = GeometryEngine.Instance.GeodeticDensifyByLength(polygon, maxLen, LinearUnit.Meters, GeodeticCurveType.Geodesic) as Polygon;

// densify the polygon (in km)
double maxSegmentLength = maxLen / 10000;
densifiedPoly = GeometryEngine.Instance.GeodeticDensifyByLength(polygon, maxSegmentLength, LinearUnit.Kilometers, GeodeticCurveType.Geodesic) as Polygon;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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);
// distance - 1339728.0303777338
// az12 - 326.235780421405
// az21 - 132.87425637913955

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

distance = GeometryEngine.Instance.GeodeticDistanceAndAzimuth(p1, p2, GeodeticCurveType.GreatElliptic, out az12, out az21);
// distance - 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);
// distance - 111319.49079327342
// az12 - 90
// az21 - 270

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

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

// Change curve type
resultPoints = GeometryEngine.Instance.GeodeticMove(points, sr, distance, LinearUnit.Miles, azimuth, GeodeticCurveType.Loxodrome);
// resultPoints.First().X = 16093.44
// resultPoints.First().Y = 0

检索坐标系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// get all the geographic coordinate systems
IReadOnlyList<CoordinateSystemListEntry> gcs_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem);

// get the projected coordinate systems
IReadOnlyList<CoordinateSystemListEntry> proj_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.ProjectedCoordinateSystem);

// get the vertical coordinate systems
IReadOnlyList<CoordinateSystemListEntry> vert_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.VerticalCoordinateSystem);

// get geographic and projected coordinate systems
IReadOnlyList<CoordinateSystemListEntry> combined_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem | CoordinateSystemFilter.ProjectedCoordinateSystem);

// investigate one of the entries
CoordinateSystemListEntry entry = gcs_list[0];
int wkid = entry.Wkid;
string category = entry.Category;
string name = entry.Name;

检索系统地理变换

1
2
3
4
5
6
7
8
9
10
// a geographic transformation is the definition of how to project from one spatial reference to another
IReadOnlyList<GeographicTransformationListEntry> list = GeometryEngine.Instance.GetPredefinedGeographicTransformationList();

// a GeographicTransformationListEntry consists of Name, Wkid, the From SpatialReference Wkid, the To SpatialReference Wkid
GeographicTransformationListEntry entry = list[0];

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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

图形缓冲区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// mitered join and butt caps
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;

// bevelled join and round caps
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;

图形缓冲器很多

1
2
3
4
5
6
7
// round join and round caps
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);

两条折线之间的交点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// determine intersection between two polylines

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;

// result is a multiPoint that intersects at (2,2) and (4,2)

两个多边形之间的交点

1
2
3
4
5
6
7
8
9
// determine intersection between two polygons

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;

确定多边形的标注点

1
2
3
4
5
6
7
8
9
10
// create a polygon
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);

确定线的长度,长度3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MapPoint c1 = MapPointBuilderEx.CreateMapPoint(1, 2, 3);
MapPoint c2 = MapPointBuilderEx.CreateMapPoint(4, 2, 4);

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

// polyline
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)

获取最小和最大 M 值 - GetMinMaxM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

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

1
2
3
4
5
6
7
8
9
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 has 2 parts

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 has a value because distance 1000 is at the end of the first part, beginning of the second part

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

1
2
3
4
5
6
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 values are { 0, 3000, 7000, 10000, 14000 };

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
string json = "{\"hasM\":true,\"paths\":[[[-3000,-2000,-3],[-2000,-2000,-2],[-1000,-2000,null]]]}";
Polyline polyline = PolylineBuilderEx.FromJson(json);
bool splitHappened;
int partIndex, segmentIndex;

// A point already exists at the given distance
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);

// A point already exists at the given distance, but 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]]]}}
// A new part has been created and the M values for outputPolyline.Points[4] and outputPolyline.Points[5] have been modified

// A point does not exist at the given distance
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 even though createNewPart = false because a new point was created
// 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]]]}
// A new point has been inserted (0, 1500, 1) by interpolating the X and Y coordinates and M value set to the input M value.

使用输入点的 M 值校准 M 值 - CalibrateByMs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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);

// Interpolate using points (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);

// Calibrate all the points in the polyline
double cutOffDistance = polyline.Length;

Polyline updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.Interpolate, cutOffDistance) as Polyline;
// The points in the updated polyline are
// (0, 0, 17 ), ( 1, 0, 42 ), ( 1, 1, 38 ), ( 1, 2, 34 ), ( 3, 1, 30 ), ( 5, 3, 26 ), ( 9, 5, 22 ), ( 7, 6, 18 )

// ExtrapolateBefore using points (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;
// The points in the updated polyline are
// ( 0, 0, 66 ), ( 1, 0, 58 ), ( 1, 1, 50 ), ( 1, 2, 42 ), ( 3, 1, 3 ), ( 5, 3, 4 ), ( 9, 5, 18 ), ( 7, 6, 6 )

// ExtrapolateAfter using points (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;
// The points in the updated polyline are
// ( 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 )

// ExtrapolateAfter and Interpolate using points (0, 0, 17), (1, 2, 42)
updatedPolyline = GeometryEngine.Instance.CalibrateByMs(polyline, updatePoints, UpdateMMethod.ExtrapolateAfter | UpdateMMethod.Interpolate, cutOffDistance) as Polyline;
// The points in the updated polyline are
// (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)

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

1
2
3
4
5
6
7
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);

// Interpolate between points 2 and 6
Polyline outPolyline = GeometryEngine.Instance.InterpolateMsBetween(polyline, 0, 2, 0, 6) as Polyline;
// The points of the output polyline are
// (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)

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

1
2
3
4
5
6
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);

Polyline outPolyline = GeometryEngine.Instance.SetAndInterpolateMsBetween(polyline, 100, 800) as Polyline;
ReadOnlyPointCollection outPoints = outPolyline.Points;
// outPoints M values are { 100, 200, 300, 400, 500, 600, 700, 800 };

移动地图点

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

移动 z 感知地图点

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

移动折线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

移动点沿线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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,


// 'explode' a multipart polygon
result = GeometryEngine.Instance.MultipartToSinglePart(multipartPolygon);


// create a bag of geometries
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] is MultiPoint
// result[1] is Polygon

最近点与最近顶点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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);

// find the nearest point in the polygon geomtry to the 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

// find the nearest vertex in the polgyon geometry to the 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

确定 3D 中的最近点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
MapPoint pt1 = MapPointBuilderEx.CreateMapPoint(1, 1, 1);
MapPoint pt2 = MapPointBuilderEx.CreateMapPoint(2, 2, 2);
MapPoint pt3 = MapPointBuilderEx.CreateMapPoint(10, 2, 1);

//
// test pt1 to 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

//
// multipoint built from pt1, pt2. should be closer to 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

计算与源的几何偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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)


//
// elliptic arc curve
//
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;


//
// offset for a polygon
//
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;

确定几何图形是否重叠

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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);

//
// point and point overlap
//
bool overlaps = GeometryEngine.Instance.Overlaps(pt1, pt2); // overlaps = false
overlaps = GeometryEngine.Instance.Overlaps(pt1, pt1); // overlaps = false
// Two geometries overlap if the region of their intersection is of the same dimension as the geometries involved and
// is not equivalent to either of the geometries.

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);

//
// pt and line overlap
//
Polyline polyline = PolylineBuilderEx.CreatePolyline(pts);
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline); // isSimple = true
overlaps = GeometryEngine.Instance.Overlaps(polyline, pt1); // overlaps = false

//
// line and line
//
Polyline polyline2 = PolylineBuilderEx.CreatePolyline(pts2);
isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline2); // isSimple = true
overlaps = GeometryEngine.Instance.Overlaps(polyline, polyline2); // overlaps = true

从 WGS84 到 Web墨卡托的项目

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

WGS84的项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// create the polygon
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);
// ensure it is simple
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polygon);

// create the spatial reference to project to
SpatialReference northPole = SpatialReferenceBuilder.CreateSpatialReference(102018); // north pole stereographic

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

查询正常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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;

// No extension, distanceAlongCurve = 0.5

// use the polyline
Polyline poly_normal = GeometryEngine.Instance.QueryNormal(polyline, SegmentExtensionType.NoExtension, 0.5, AsRatioOrLength.AsRatio, 1000);
// or a segment
LineSegment seg_normal = GeometryEngine.Instance.QueryNormal(arc, SegmentExtensionType.NoExtension, 0.5, AsRatioOrLength.AsRatio, 1000);

// TangentAtFrom, distanceAlongCurve = -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);

// TangentAtTo (ignored because distanceAlongCurve < 0), distanceAlongCurve = -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);

// TangentAtTo, distanceAlongCurve = 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);

// TangentAtFrom (ignored because distanceAlongCurve > 0), distanceAlongCurve = 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);

// EmbeddedAtTo, distanceAlongCurve = 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);

// EmbeddedAtFrom, distanceAlongCurve = -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);

查询点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SpatialReference sr = SpatialReferences.WGS84;

// Horizontal line segment
Coordinate2D start = new Coordinate2D(1, 1);
Coordinate2D end = new Coordinate2D(11, 1);
LineSegment line = LineBuilderEx.CreateLineSegment(start, end, sr);

Polyline polyline = PolylineBuilderEx.CreatePolyline(line);

// Don't extend the segment

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

// or the segment
MapPoint outPoint_seg = GeometryEngine.Instance.QueryPoint(line, SegmentExtensionType.NoExtension, 1.0, AsRatioOrLength.AsLength);
// outPoint_seg = (2, 1)

// Extend infinitely in both directions
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)

查询点和距离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Horizontal line segment
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);

// Don't extent the segment
SegmentExtensionType extension = SegmentExtensionType.NoExtension;

// A point on the line segment
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


// Extend infinitely in both directions
extension = SegmentExtensionType.ExtendTangents;

// A point on the left side
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

查询切线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
LineSegment line = LineBuilderEx.CreateLineSegment(new Coordinate2D(0, 0), new Coordinate2D(1, 0));

// No extension, distanceAlongCurve = 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)

围绕线反射多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);

// reflect a polygon about the line
Polygon reflectedPolygon = GeometryEngine.Instance.ReflectAboutLine(polygon, line) as Polygon;

// reflectedPolygon points are
// (2, -1), (4, -1), (4, 1), (2, -1)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// set up some geometries

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

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

// polygon
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);

// polylines
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);

// now do the Related tests

// Interior/Interior Intersects
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

// Interior/Boundary Intersects
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

// Boundary/Boundary Interior intersects
scl = "***T*****";
related = GeometryEngine.Instance.Relate(polygon, polyline4, scl); // related = true

// Overlaps Dim1
scl = "1*T***T**";
related = GeometryEngine.Instance.Relate(polygon, polyline5, scl); // related = true

// Crosses Area/Line (LineB crosses PolygonA)
scl = "1020F1102";
related = GeometryEngine.Instance.Relate(polygon, polyline6, scl); // related = false
related = GeometryEngine.Instance.Relate(polygon, polyline9, scl); // related = true

// Boundary/Boundary Touches
scl = "F***T****";
related = GeometryEngine.Instance.Relate(polygon, polyline7, scl); // related = false
related = GeometryEngine.Instance.Relate(polygon, polyline8, scl); // related = true

替换多边形中的 NaN Z

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

改变多边形的形状

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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)
};

// reshaper coordinates intersect the polygon
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]]]}";


// example where the Reshaper polyline doesn't intersect the input

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

反转多边形中点的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

旋转地图点

1
2
3
4
5
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);
// result point is (3, 1)

旋转折线

1
2
3
4
5
6
7
8
9
10
11
12
// rotate a polyline

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; // rotate 45 deg

缩放几何图形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 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 point - scale in 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

设置折线中的所有 Z

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// pt
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 3.0, SpatialReferences.WebMercator);
double area = GeometryEngine.Instance.ShapePreservingArea(pt); // area = 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
Multipoint mPt = MultipointBuilderEx.CreateMultipoint(pts);
area = GeometryEngine.Instance.ShapePreservingArea(mPt); // area = 0

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

// polygon
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// pt
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
Multipoint mPt = MultipointBuilderEx.CreateMultipoint(pts);
len = GeometryEngine.Instance.ShapePreservingLength(mPt); // len = 0

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

// polygon
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

侧缓冲器

1
2
3
4
5
6
7
8
9
10
11
12
13
// right side, round caps
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;

侧缓冲器很多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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);

简化多边形

1
2
3
4
5
var g1 = PolygonBuilderEx.FromJson("{\"rings\": [ [ [0, 0], [10, 0], [10, 10], [0, 10] ] ] }");
var result = GeometryEngine.Instance.Area(g1); // result = -100.0 - negative due to wrong ring orientation
// simplify it
var result2 = GeometryEngine.Instance.Area(GeometryEngine.Instance.SimplifyAsFeature(g1, true));
// result2 = 100.0 - positive due to correct ring orientation (clockwise)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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;

// build a line that has segments that cross over each other
Polyline polyline = PolylineBuilderEx.CreatePolyline(coords, sr);
// polyline.PartCount = 1
ReadOnlyPartCollection parts = polyline.Parts;
ReadOnlySegmentCollection segments = parts[0];
// segments.Count = 5

// note there is a difference between SimpleAsFeature (doesn't detect intersections and overlaps, determines if it's simple enough for gdb storage)
// and SimplifyPolyline (does detect intersections etc)
bool isSimple = GeometryEngine.Instance.IsSimpleAsFeature(polyline, false);
// isSimple = true

// simplify it (with force = false)
// because it has already been deemed 'simple' (previous IsSimpleAsFeature call) no detection of intersections, overlaps occur
Polyline simplePolyline = GeometryEngine.Instance.SimplifyPolyline(polyline, SimplifyType.Planar, false);
// simplePolyline.PartCount = 1
ReadOnlyPartCollection simpleParts = simplePolyline.Parts;
ReadOnlySegmentCollection simpleSegments = simpleParts[0];
// simpleSegments.Count = 5

// simplify it (with force = true)
// detection of intersections, overlaps occur
simplePolyline = GeometryEngine.Instance.SimplifyPolyline(polyline, SimplifyType.Planar, true);
// simplePolyline.PartCount = 3
simpleParts = simplePolyline.Parts;
simpleSegments = simpleParts[0];
// simpleSegments.Count = 1

将多边形切成相等的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var slices = GeometryEngine.Instance.SlicePolygonIntoEqualParts(polygon, 3, 0, SliceType.Blocks);
// slices.Count = 3


// simple polygon
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] coordinates - (1.0, 1.0), (1.0, 1.5), (2.0, 1.5), (2.0, 1.0), (1.0, 1.0)
// slice[1] coordinates - (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] coordinates - (1.0, 1.0), (1.0, 2.0), (2.0, 1.0), (1.0, 1.0)
// slice[1] coordinates - (1.0, 2.0), (2.0, 2.0), (2.0, 1.0), (1.0, 2.0)

在点拆分多部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// define a polyline
MapPoint startPointZ = MapPointBuilderEx.CreateMapPoint(1, 1, 5);
MapPoint endPointZ = MapPointBuilderEx.CreateMapPoint(20, 1, 5);

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

// define a split point
MapPoint splitPointAboveLine = MapPointBuilderEx.CreateMapPoint(10, 10, 10);

bool splitOccurred;
int partIndex;
int segmentIndex;

// split the polyline at the point. dont project the split point onto the line, don't create a new part
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 coordinates are (1, 1, 5), (10, 10, 10), (20, 1, 5)

// split the polyline at the point. dont project the split point onto the line, do create a new part
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 first part coordinates are (1, 1, 5), (10, 10, 10)
// splitPolyline second part coordinates are (10, 10, 10), (20, 1, 5)


// split the polyline at the point. do project the split point onto the line, don't create a new part
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 coordinates are (1, 1, 5), (10, 10, 5), (20, 1, 5)

// split the polyline at the point. do project the split point onto the line, do create a new part
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 first part coordinates are (1, 1, 5), (10, 10, 5)
// splitPolyline second part coordinates are (10, 10, 5), (20, 1, 5)


//
// try to split with a point that won't split the line - pt extends beyond the line
//

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

// splitOccurred = false
// ignore partIndex, sgementIndex
// splitPolyline is the same as polylineZ


///
/// multipart polygon
///
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 is closer to the first part of the multipart - the split occurs in the first part
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 first part coordinates (10, 10, 5), (10, 20, 5), (20, 20, 5), (22, 18, 7), (20, 10, 5), (10, 10, 5)


// pointB is midPoint between the 2 parts - no split will occur
var pointB = MapPointBuilderEx.CreateMapPoint(25, 20, 7);
splitPolygon = GeometryEngine.Instance.SplitAtPoint(multipart, pointB, true, false, out splitOccurred, out partIndex, out segmentIndex);

// splitOccurred = false
// ignore partIndex, sgementIndex
// splitPolyline is the same as polylineZ

多边形接触另一个多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// two disjoint polygons
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

// another polygon that touches the first
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

转换2D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Not all of the input points are transformed as some of them are outside of the GCS horizon.
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];

// transform and choose to remove the clipped coordinates
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}

// transform and don't remove the clipped coordinates
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}

转换3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Not all of the input points are transformed as some of them are outside of the GCS horizon.
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];

// transform and choose to remove the clipped coordinates
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}

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

1
2
3
4
5
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 has point count of 2

并集两个多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// union two polygons

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;

联合许多折线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// union many polylines

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)
};

// create Disjoint lines
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;

联合多个多边形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// union many polygons

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)
};

// create polygons
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;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// build a polygon      
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);

// an inner point
MapPoint innerPt = MapPointBuilderEx.CreateMapPoint(1.5, 1.5);
bool within = GeometryEngine.Instance.Within(innerPt, poly); // within = true

// point on a boundary
within = GeometryEngine.Instance.Within(pts[0], poly); // within = false

// an interior line
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

// a line that crosses the boundary
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


// polygon in polygon
Envelope env = EnvelopeBuilderEx.CreateEnvelope(innerPt, innerPt2);
within = GeometryEngine.Instance.Within(env, poly); // within = true

e