GeometryEngine是ArcGIS Pro SDK中的一个关键组件,它提供了一系列用于处理几何图形(Point、Polyline、Polygon……)的方法和算法。例如计算距离、缓冲区分析、叠加分析和几何关系检查等。
这里汇总一下在开发中可能会用到的功能,方便查询。
面要素的面积分为投影面积和椭球面积2种。
投影面积计算方法:
double area = GeometryEngine.Instance.Area(polygon1);
椭球面积计算方法:
double area = GeometryEngine.Instance.GeodesicArea(polygon1);
例如某些面要素存在几何错误,如环方向错误,可以尝试简化要素特征,效果类似于几何修复:
Polygon polygon2 = GeometryEngine.Instance.SimplifyAsFeature(polygon1);
创建一个简单的面要素,这里采用【PolygonBuilderEx】方法创建:
// 创建点集合
List pts = new List();
pts.Add(new Coordinate2D(10.0, 10.0));
pts.Add(new Coordinate2D(10.0, 20.0));
pts.Add(new Coordinate2D(20.0, 20.0));
pts.Add(new Coordinate2D(20.0, 10.0));
// 转为要素
Polygon poly = PolygonBuilderEx.CreatePolygon(pts);
创建一个带空洞的面要素,这类面要素有一个外边界和一个以上的内边界:
// 创建外环的点集合
List outerPts = new List();
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 innerPts = new List();
innerPts.Add(new Coordinate2D(13.0, 13.0));
innerPts.Add(new Coordinate2D(17.0, 13.0));
innerPts.Add(new Coordinate2D(17.0, 17.0));
innerPts.Add(new Coordinate2D(13.0, 17.0));
// 设置一个空的面要素
Polygon donut = null;
// 创建一个PolygonBuilderEx,并将外环加入PolygonBuilderEx
PolygonBuilderEx pb = new PolygonBuilderEx(outerPts);
// 将内环加入PolygonBuilderEx
pb.AddPart(innerPts);
// 转为要素
donut = pb.ToGeometry();
先获取边界要素,再按需求转化:
Geometry g = GeometryEngine.Instance.Boundary(donut);
Polyline boundary = g as Polyline;
以点要素为例,按距离生成缓冲区:
MapPoint pt = MapPointBuilderEx.CreateMapPoint(1.0, 1.0, SpatialReferences.WGS84);
Geometry ptBuffer = GeometryEngine.Instance.Buffer(pt, 5.0);
Polygon buffer = ptBuffer as Polygon;
同样适用于点要素的集合:
List pts = new List();
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;
甚至可以是不同类型的要素集合:
List coords = new List()
{
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 manyGeometries = new List
{
MapPointBuilderEx.CreateMapPoint(coords[9]),
PolylineBuilderEx.CreatePolyline(new List(){coords[0], coords[1], coords[2]}, SpatialReferences.WGS84),
PolylineBuilderEx.CreatePolyline(new List(){coords[3], coords[4], coords[5]}),
PolygonBuilderEx.CreatePolygon(new List(){coords[6], coords[7], coords[8]})
};
Geometry manyGeomBuffer = GeometryEngine.Instance.Buffer(manyGeometries, 0.25);
判断点、线、面是否在面的内部,需要注意二者前后关系(前包含后):
bool contains = GeometryEngine.Instance.Contains(polygon, pt);
bool contains = GeometryEngine.Instance.Contains(polygon, polyline);
bool contains = GeometryEngine.Instance.Contains(polygon, polygon2);
判断面边界上的点是否在面内部(false):
bool contains = GeometryEngine.Instance.Contains(poly, poly.Points[0]);
和包含关系一样,同样适用于点、线、面两两判断:
bool crosses = GeometryEngine.Instance.Crosses(line1, line2);
bool crosses = GeometryEngine.Instance.Crosses(pt1, line2);
bool crosses = GeometryEngine.Instance.Crosses(pt1, polyngo1);
例如用线裁剪线:
var cutGeometries = GeometryEngine.Instance.Cut(polyline, cutline) as List;
裁剪生成的结果根据实际结果为要素列表,可以分别读取:
Polyline leftPolyline = cutGeometries[0] as Polyline;
Polyline rightPolyline = cutGeometries[1] as Polyline;
用线裁剪面也是同样的:
var cutGeometries = GeometryEngine.Instance.Cut(polygon, cutline) as List;
Geometry geom = GeometryEngine.Instance.DensifyByLength(polyline, 2);
Polyline result = geom as Polyline;
类似工具箱的擦除(用poly2去擦poly1):
Geometry result = GeometryEngine.Instance.Difference(poly1, poly2);
Polygon polyResult = result as Polygon;
适用于点、线、面、边界框两两之间的距离:
var d = GeometryEngine.Instance.Distance(pt1, multiPoint);
var d = GeometryEngine.Instance.Distance(pt1, polyline);
var d = GeometryEngine.Instance.Distance(polyline, polyline2);
var d = GeometryEngine.Instance.Distance(poly, poly2);
var d = GeometryEngine.Instance.Distance(env, polyline);
按相对位置移动:
Geometry geometry = GeometryEngine.Instance.Move(polyline, 3, 2);
Polyline polylineResult = geometry as Polyline;
可以按种类检索坐标系,包括地理、投影、垂直坐标系:
// 获取所有地理坐标系
IReadOnlyList gcs_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem);
// 获取投影坐标系
IReadOnlyList proj_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.ProjectedCoordinateSystem);
// 获取垂直坐标系
IReadOnlyList vert_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.VerticalCoordinateSystem);
// 获取地理坐标系和投影坐标系
IReadOnlyList combined_list = GeometryEngine.Instance.GetPredefinedCoordinateSystemList(CoordinateSystemFilter.GeographicCoordinateSystem | CoordinateSystemFilter.ProjectedCoordinateSystem);
// 获取其中一个条目的详细信息
CoordinateSystemListEntry entry = gcs_list[0];
int wkid = entry.Wkid; // WKID(Well-Known ID)值,用于唯一标识坐标系
string category = entry.Category; // 坐标系的类别,例如"地理坐标系"、"投影坐标系"等
string name = entry.Name; // 坐标系的名称
SpatialReference northPole = SpatialReferenceBuilder.CreateSpatialReference(102018);
Geometry geometry = GeometryEngine.Instance.Project(polygon, northPole);
Polyline polylineSetZ = GeometryEngine.Instance.SetConstantZ(polyline, -1) as Polyline;
Polyline polylineSetZ = GeometryEngine.Instance.SetConstantZ(polyline, double.NaN) as Polyline;
多个点、线、面要素合并:
// 合并2个点
Geometry geometry = GeometryEngine.Instance.Union(pt1, pt2);
Multipoint multipoint = geometry as Multipoint;
// 合并2个面
Geometry g = GeometryEngine.Instance.Union(poly1, poly2);
Polygon polyResult = g as Polygon;
// 合并多个线
List manyLines = new List{………………};
Polyline polyline = GeometryEngine.Instance.Union(manyLines) as Polyline;
// 合并多个面
List manyPolygons = new List{………………};
Polygon polygon = GeometryEngine.Instance.Union(manyPolygons) as Polygon;