原生几何类型

表示空间中的单个位置,是所有其他几何类型的构建块。一个点至少有一个 x 坐标和一个 y 坐标。点的坐标可以是直线单位,如英尺或米,也可以是角度单位,如度或弧度。相关联的空间引用指定坐标的单位。对于经纬度,x 坐标表示经度,y 坐标表示纬度。

以米为单位

边界、内部和外部

点的边界是空集合,内部是点本身,外部是不在内部的点的集合。在使用各种操作符时,了解几何体的边界、内部和外部是很重要的。例如,关系运算符非常依赖这些概念。

有效点

每一点都是有效的。

有效的几何被认为是简单的。有关简单几何的详细规范,请参阅 Simplify规范。

JSON 格式

点可以表示为 JSON 字符串。JSON 格式的一个点包含 xy 字段以及一个可选的 spatialReference。一个点也可以有 mz 字段。

当一个点的 x 字段存在并且值为 null 或字符串Nan时,该点为空。空点在空间中没有位置。

语法

{"x": <x>, "y": <y>, "z": <z>, "m": <m>, "spatialReference": {"wkid" : <wkid>}
}

2D 点

{"x": 32462, "y": -57839, "spatialReference": {"wkid" : 54004}
}

3D 点

{"x": 32462, "y": -57839, "z": 20, "m": 1, "spatialReference" : {"wkid" : 54004}
}

空点

{ "x": null }
{ "x": "NaN" }

创建一个点

To create a point, we can use the Point class methods or one of the import operators.

要创建一个点,我们可以使用 Point 类方法或者一个导入操作符。

下面的每个代码示例创建了一个点,代表 Mount Elbert 的顶峰,落基山脉的最高峰。这一点在地图上看起来是这样的:

Create this point

Point类方法创建

我们创建一个新的 Point,并在构造函数中同时设置 x,y 坐标。

    @Testpublic void createPoint1() {Point point = new Point(-106.4453583, 39.11775);System.out.println(point.toString());}

导入 JSON

我们首先创建表示点的 JSON 字符串,然后调用 OperatorImportFromJsonexecute 方法。

    @Testpublic void createPointFromJson() {String jsonString = "{\"x\":-106.4453583,\"y\":39.11775,\"spatialReference\":{\"wkid\":4326}}";Point point = (Point) OperatorImportFromJson.local().execute(Geometry.Type.Point, jsonString).getGeometry();System.out.println(point.toString());}

导入 GeoJSON

我们首先创建代表点的 GeoJSON 字符串,然后调用 OperatorImportFromGeoJsonexecute 方法。

    @Testpublic void createPointFromGeoJson() {String geoJsonString = "{\"type\":\"Point\",\"coordinates\": [-106.4453583,39.11775],\"crs\":\"EPSG:4326\"}";Point point = (Point) OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Point, geoJsonString, null).getGeometry();System.out.println(point.toString());}

导入 WKT

我们首先创建表示点的 WKT 字符串,然后调用 OperatorImportFromWktexecute 方法。

    @Testpublic void createPointFromWKT() {String wktString = "Point(-106.4453583 39.11775)";Point point = (Point) OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Point, wktString, null);System.out.println(point.toString());}

多点

多点是点的有序集合。

边界、内部和外部

多点的边界是空集合,内部是集合中点的集合,外部是不在内部的点的集合。在使用各种操作符时,了解几何体的边界、内部和外部是很重要的。例如,关系运算符非常依赖这些概念。

有效的多点

有效的多点是指集合中的每个点都是不同的。公差是用来确定两点是否不同的。换句话说,如果两个点的每个坐标之间的距离小于空间参考指定的公差,则认为两点相等。

例如,考虑下面所示的多点:

Valid multipoint? 有效的多点?

它是一个有效的多点吗? 它取决于空间引用。

假设这个多点的空间引用使用 WGS_1984_UTM_Zone_31N 坐标系,默认公差为0.001米。矩形勾勒出的区域中的两个点看起来非常接近。让我们放大这两点。

比公差更接近的坐标?

如果 x 坐标和 y 坐标之间的距离小于0.001米,那么多点就不是有效的多点。

多点无效

例子

让我们来看一些多点的例子。

The example below shows six multipoints each of which represents major cities grouped by continent.

下面的例子显示了六个多点,每个点代表按大陆分组的主要城市。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87bxaZGs-1628133433280)(http://esri.github.io/geometry-api-java/doc/Images/Multipoint/WorldCities.jpg)]

按大陆分列的世界城市

下一个例子显示了四个多点,每个点代表按人口分组的主要城市。

按人口分列的世界城市

这里我们有13个多点,每个点代表在美国公路旅行的可能路线上的兴趣点。

按路线划分的兴趣点

JSON format

JSON 格式

A multipoint can be represented as a JSON string. A multipoint in JSON format contains an array of points and an optional spatialReference. A multipoint can also have boolean-valued hasM and hasZ fields. The default value is false for both the hasM and hasZ fields.

多点可以表示为 JSON 字符串。JSON 格式的多点包含一个点数组和一个可选的 spatialReference。多点还可以具有布尔值 hasMhasZ 字段。对于 hasMhasZ 字段,默认值都为 false。

数组的每个元素本身是一个由2、3或4个数字组成的数组。它有两个元素表示2D 点,三个元素表示3D 点,2或3个元素表示2D 点,3个元素表示3D 点。对于具有 Ms 的2D 点,如果存在 m 坐标,则为索引2。对于3D 点,z 坐标是必需的,并且位于索引2。对于有 Ms 的3D 点,z 坐标位于索引2,如果有 m 坐标,则位于索引3。

空多点用点字段的空数组表示。

语法
{"hasZ" : true | false,"hasM" : true | false,"points": [[<x1>,<y1>,<z1>,<m1>], ... ,[<xn>,<yn>,<zn>,<mn>]],"spatialReference" : {"wkid" : <wkid>}
}

2D 多点

{"points": [[32462,-57839],[43892,-49160],[35637,-65035],[46009,-60379]],"spatialReference" : {"wkid" : 54004}
}

3D 多点

注意,第三个点没有 z 值,第四个点没有 m 值。

{"hasZ" : true,"hasM" : true,"points": [[32462,-57839,20,1],[43892,-49160,25,2],[35637,-65035,null,3],[46009,-60379,22]],"spatialReference" : {"wkid" : 54004}
}

空多点

{"points": []
}

创建一个多点

要创建多点,我们可以使用 MultiPoint 类方法或导入操作符之一。

下面的每个代码示例都创建了一个带有六个点的多点:

创建这个多点

MultiPoint类方法

我们创建一个新的 MultiPoint,并通过调用 add 方法来添加点。

    @Testpublic void createMultipoint1() {MultiPoint multiPoint = new MultiPoint();// 添加 点multiPoint.add(1, 1);multiPoint.add(0.5, -0.5);multiPoint.add(1, -1.5);multiPoint.add(-1, -1);multiPoint.add(-2, -0.5);multiPoint.add(-1.5, 1.5);System.out.println(multiPoint);}

Import from JSON

导入JSON

我们首先创建 JSON 字符串,它表示多点,然后调用 OperatorImportFromJsonexecute 方法。

    @Testpublic void createMultipointFromJson() {String jsonString = "{\"points\":[[1,1],[0.5,-0.5],[1,-1.5],[-1,-1],[-2,-0.5],[-1.5,1.5]],\"spatialReference\":{\"wkid\":4326}}";MultiPoint multiPoint = (MultiPoint) OperatorImportFromJson.local().execute(Geometry.Type.MultiPoint, jsonString).getGeometry();System.out.println(multiPoint);}

导入GeoJSON

我们首先创建代表多点的 GeoJSON 字符串,然后调用 OperatorImportFromGeoJsonexecute 方法。

    @Testpublic void createMultipointFromGeoJson() {String geoJsonString = "{\"type\":\"MultiPoint\",\"coordinates\":[[1,1],[0.5,-0.5],[1,-1.5],[-1,-1],[-2,-0.5],[-1.5,1.5]],\"crs\":\"EPSG:4326\"}";MultiPoint multiPoint = (MultiPoint) OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.MultiPoint, geoJsonString, null).getGeometry();System.out.println(multiPoint);}

导入 WKT

我们首先创建表示多点的 WKT 字符串,然后调用 OperatorImportFromWktexecute 方法。

    @Testpublic void createMultipointFromWKT() {String wktString = "MULTIPOINT ((1 1),(0.5 -0.5),(1 -1.5),(-1 -1),(-2 -0.5),(-1.5 1.5))";MultiPoint multiPoint = (MultiPoint)OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.MultiPoint, wktString, null);System.out.println(multiPoint);}

线

线是路径的有序集合。每个路径是一组相邻线段的集合。线段由一对连续的点定义。

具有3条路径的线

边界、内部和外部

折线的边界是每条路径的起点和终点的集合。多线的内部是多线中不在边界上的点的集合。折线的外部是一组不在边界或内部的点。在使用各种操作符时,了解几何体的边界、内部和外部是很重要的。例如,关系运算符非常依赖这些概念。

对于下面显示的折线,组成边界的点集用红色显示。折线的内部用黑色显示。

红色是边界,黑色是内部

如果一个顶点包含在几条路径中,我们如何确定它是否在折线的边界上?若要确定一个顶点是否位于多段线的边界上,请计算其所包含的段数。如果这个数字是偶数,那么顶点就不在边界上。如果这个数字是奇数,那么顶点就在边界上。

例如,考虑下面所示的折线。

红色是界限,绿色是界限?

很明显,红色的顶点在折线的边界上。但是那个绿色的呢?答案是绿色顶点不在边界上,因为它包含在四个部分中。

这是另一个例子。

红色是界限,绿色是界限?

在这种情况下,由于绿色顶点包含在五个段中,所以它位于折线的边界上。

记住这个规则的一种方法是考虑一个有三个顶点的单一路径。

红色是界限

显而易见,红色顶点在边界上,而黑色顶点不在。请注意,包含每个红色顶点的段数是一个奇数。现在计算包含黑色顶点的段数。二,一个偶数。

有效的折线

一条有效的折线是这样的: 每条路径至少有两个不同的点。公差是用来确定两点是否不同的。换句话说,如果两点之间的距离小于空间参考指定的公差,则认为两点相等。

封闭路径是一条有两个以上不同点的路径,起点等于终点。封闭路径是有效的折线。

封闭路径有效

A valid polyline is said to be simple. See the Simplify operator for a more detailed specification of simple polylines. Note that a simple polyline may not be OGC compliant. See the Simplify operator with OGC restrictions.

有效的线被认为是简单的。有关简单折线的更详细规范,请参阅 Simplify 规范。注意,一个简单的多元线可能不符合 OGC。请参阅带有 OGC 限制的 Simplify规范。

例子

让我们来看一些 polylines 的例子。在第一组例子中,绿色圆圈是线的顶点。




这个例子展示了代表美国一些主要公路的多段线路。

JSON format

JSON 格式

可以将多段线表示为 JSON 字符串。JSON 格式的多段线包含路径数组和可选的 spatialReference。多段线还可以具有布尔值 hasMhasZ 字段。对于 hasMhasZ 字段,默认值都为 false。

Each path is represented by an array of points. Each point in a path is represented as an array of numbers. See the description of JSON multipoints for details on the interpretation of the point arrays.

每条路径由一组点表示。路径中的每个点都表示为一组数字。有关点数组解释的详细信息,请参阅 JSON多点。

空折线用路径字段的空数组表示。

语法

{"hasZ" : true | false,"hasM" : true | false,"paths": [[[<x11>,<y11>,<z11>,<m11>],[<x12>,<y12>,<z12>,<m12>], ... ,[<x1j>,<y1j>,<z1j>,<m1j>]],... ,[[<xn1>,<yn1>,<zn1>,<mn1>],[<xn2>,<yn2>,<zn2>,<mn2>], ... ,[<xnk>,<ynk>,<znk>,<mnk>]]],"spatialReference" : {"wkid" : <wkid>}
}

2D 线

{"paths": [[[32462,-57839],[43892,-49160],[35637,-65035],[46009,-60379\]],[[52570,-77736],[39870,-83027],[46644,-99114]]],"spatialReference" : {"wkid" : 54004}
}

3D 线

注意,第三个点没有 z 值,第二个环没有任何 m 值。

{"hasZ" : true,"hasM" : true,"paths": [[[32462,-57839,20,1],[43892,-49160,25,2],[35637,-65035,null,3],[46009,-60379,22,4]],[[52570,-77736,30],[39870,-83027,32],[46644,-99114,35]]],"spatialReference" : {"wkid" : 54004}
}

空线

{"paths": []
}

创建一个多边形

要创建一个 Polyline,我们可以使用 Polyline 类方法或者一个导入操作符。

下面的每个代码示例创建一条带有三条路径的折线:

创建这个折线

Polyline类方法

要开始每个路径,我们调用 startPath 方法,然后成功调用 lineTo 方法。

static Polyline createPolyline1() {Polyline line = new Polyline();// Path 1line.startPath(6.9, 9.1);line.lineTo(7, 8.8);// Path 2line.startPath(6.8, 8.8);line.lineTo(7, 9);line.lineTo(7.2, 8.9);line.lineTo(7.4, 9);// Path 3line.startPath(7.4, 8.9);line.lineTo(7.25, 8.6);line.lineTo(7.15, 8.8);return poly;
}

导入 JSON

我们首先创建表示折线的 JSON 字符串。注意,路径的顺序并不重要。只有每条路径中点的顺序才是重要的。然后我们调用 OperatorImportFromJsonexecute 方法。

    @Testpublic void createPolygonFromJson() {String jsonString = "{\"paths\":[" +"[[6.8,8.8],[7,9],[7.2,8.9],[7.4,9]]," +"[[7.4,8.9],[7.25,8.6],[7.15,8.8]]," +"[[6.9, 9.1],[7, 8.8]]" +"],\"spatialReference\":{\"wkid\":4326}}";Polyline polyline = (Polyline) OperatorImportFromJson.local().execute(Geometry.Type.Polyline, jsonString).getGeometry();System.out.println(polyline);}

导入 GeoJSON

我们首先创建代表 polyline 的 GeoJSON 字符串,然后调用 OperatorImportFromGeoJsonexecute 方法。

下面显示的代码创建与前面示例中相同的多边形。

    @Testpublic void createPolylineFromGeoJson() {String geoJsonString = "{\"type\":\"MultiLineString\",\"coordinates\":[" +"[[6.8,8.8],[7,9],[7.2,8.9],[7.4,9]]," +"[[7.4,8.9],[7.25,8.6],[7.15,8.8]]," +"[[6.9, 9.1],[7, 8.8]]" +"],\"crs\":\"EPSG:4326\"}";Polyline polyline = (Polyline) OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Polyline, geoJsonString, null).getGeometry();System.out.println(polyline);}

导入 WKT

我们首先创建表示折线的 WKT 字符串,然后调用 OperatorImportFromWktexecute 方法。

下面显示的代码创建与前面示例中相同的多边形。

    @Testpublic void createPolylineFromWKT() {String wktString = "MULTILINESTRING ((6.9 9.1,7 8.8),(6.8 8.8,7 9,7.2 8.9,7.4 9),(7.4 8.9,7.25 8.6,7.15 8.8))";Polyline polyline = (Polyline) OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Polyline, wktString, null);System.out.println(polyline);}

多边形

多边形是由一组环定义的。每个环是一个连续线段的集合,这样起点和终点是相同的。

边界和环

The boundary of a polygon is the collection of rings by which the polygon is defined. The boundary contains one or more outer rings and zero or more inner rings. An outer ring is oriented clockwise while an inner ring is oriented counterclockwise. Imagine walking clockwise along an outer ring. The area to your immediate right is the interior of the polygon and to your left is the exterior.

多边形的边界是定义多边形的环的集合。边界包含一个或多个外环和零个或多个内环。外环为顺时针方向,而内环为逆时针方向方向。想象沿着外环顺时针方向行走。你的右边是多边形的内部,左边是外部。

类似地,如果你沿着内环逆时针方向走,你的右边是多边形的内部,左边是外部。

在使用各种操作符时,了解几何体的边界、内部和外部是很重要的。例如,关系运算符非常依赖这些概念。

如果一个多边形有一个内环,内环看起来像一个洞。如果这个洞还包含另一个外环,那个外环看起来就像一个岛。

1个外圈,没有内圈 四个外环,没有内环 1个外圈,1个内圈 两个外圈,一个内圈

有效的多边形

有效的多边形具有以下主要属性:

  • 对于每个多边形段,外部的多边形无歧义地位于段的左侧,内部的多边形无歧义地位于段的右侧
    由于上述特性,以下情况也是正确的:
  • 片段只能在端点接触其他片段,
  • 段的长度非零,
  • 外圈为顺时针方向孔为逆时针方向,
  • 每个多边形环具有非零面积
  • 环的顺序并不重要,
  • 环可以是自切的,
  • 星环不能重叠

例子

让我们来看一些非简单多边形和简单多边形的例子。绿色的圆是多边形的顶点,淡紫色的区域代表多边形的内部。

非简单多边形
自相交 自相交 悬挂段 悬挂段 重叠环
简单的多边形
无自交点 顶点自交 没有悬挂段 没有悬挂段 没有重叠的环

绘制多边形时,使用奇偶填充规则。偶奇填充规则将保证多边形将正确绘制,即使环的方向不是上面所描述的简单多边形。

JSON 格式

多边形可以表示为 JSON 字符串。JSON 格式的多边形包含一个数组和一个可选的 spatialReference。多边形还可以具有布尔值 hasMhasZ 字段。对于 hasMhasZ 字段,默认值都为 false。

空多边形用空数组表示,该数组用于指环字段。

语法

{"hasZ" : true | false,"hasM" : true | false,"rings": [[[<x11>,<y11>,<z11>,<m11>],[<x12>,<y12>,<z12>,<m12>], ... ,[<x1j>,<y1j>,<z1j>,<m1j>]],... ,[[<xn1>,<yn1>,<zn1>,<mn1>],[<xn2>,<yn2>,<zn2>,<mn2>], ... ,[<xnk>,<ynk>,<znk>,<mnk>]]],"spatialReference" : {"wkid" : <wkid>}
}

2D 多边形

{"rings": [[[6453,16815],[10653,16423],[14549,5204],[-7003,6939],[6453,16815]],[[914,7992],[3140,11429],[1510,10525],[914,7992]]],"spatialReference" : {"wkid" : 54004}
}

3D 多边形

注意,第三个点没有 z 值,第二个环没有任何 m 值。

{"hasZ" : true,"hasM" : true,"rings": [[[6453,16815,35,1],[10653,16423,36,2],[14549,5204,null,3],[-7003,6939,37,4],[6453,16815,35,1]],[[914,7992,30],[3140,11429,29],[1510,10525,28],[914,7992,30]]],"spatialReference" : {"wkid" : 54004}
}

空多边形

{"rings": []
}

创建一个多边形

要创建一个多边形,我们可以使用 Polygon 类方法或导入操作符之一。

下面的每个代码示例都创建了一个包含两个外环和一个内环的多边形。多边形看起来是这样的:

创建这个多边形

Polygon类方法

当使用 Polygon 类方法创建多边形时,创建环的顺序并不重要。重要的是环的方向。记住,顺时针意味着外环,而逆时针意味着内环。

要开始每个环,我们调用 startPath 方法,然后连续调用 lineTo 方法。我们不需要重复起点作为终点。

    @Testpublic void createPolygon1() {Polygon polygon = new Polygon();// clockwise => outer ringpolygon.startPath(0, 0);polygon.lineTo(-0.5, 0.5);polygon.lineTo(0, 1);polygon.lineTo(0.5, 1);polygon.lineTo(1, 0.5);polygon.lineTo(0.5, 0);// holepolygon.startPath(0.5, 0.2);polygon.lineTo(0.6, 0.5);polygon.lineTo(0.2, 0.9);polygon.lineTo(-0.2, 0.5);polygon.lineTo(0.1, 0.2);polygon.lineTo(0.2, 0.3);// islandpolygon.startPath(0.1, 0.7);polygon.lineTo(0.3, 0.7);polygon.lineTo(0.3, 0.4);polygon.lineTo(0.1, 0.4);System.out.println(polygon);}

导入 JSON

使用 OperatorImportFromJson 创建一个多边形时,创建环的顺序并不重要。重要的是环的方向。与 Polygon 类方法不同,必须重复每个环的起点以指定终点。

下面显示的代码和前面一样创建了相同的多边形,但是注意形成孔的内环是在外环之前给出的。这样做只是为了说明,当多边形采用 JSON 格式时,环的顺序并不重要。

    @Testpublic void createPolygonFromJson() {String jsonString = "{\"rings\":[" +"[[0.5,0.2],[0.6,0.5],[0.2,0.9],[-0.2,0.5],[0.1,0.2],[0.2,0.3],[0.5,0.2]]," +"[[0.0,0.0],[-0.5,0.5],[0.0,1.0],[0.5,1.0],[1.0,0.5],[0.5,0.0],[0.0,0.0]]" +"], \"spatialReference\":{\"wkid\":4326}}";Polygon polygon = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, jsonString).getGeometry();System.out.println(polygon);}

导入 GeoJSON

使用 OperatorImportFromGeoJson 创建一个多边形时,给定环的顺序很重要。在一个环阵列中,外环总是紧跟着零个或更多个内环。然而,环数组的顺序并不重要。必须重复每个环的起始点以指定终止点。

下面显示的代码创建与前面示例中相同的多边形。

    @Testpublic void createPolygonFromGeoJson() {String geoJsonString = "{\"type\":\"MultiPolygon\",\"coordinates\":[" +"[[[0.0,0.0],[-0.5,0.5],[0.0,1.0],[0.5,1.0],[1.0,0.5],[0.5,0.0],[0.0,0.0]]," +"[[0.5,0.2],[0.6,0.5],[0.2,0.9],[-0.2,0.5],[0.1,0.2],[0.2,0.3],[0.5,0.2]]]," +"[[[0.1,0.7],[0.3,0.7],[0.3,0.4],[0.1,0.4],[0.1,0.7]]]" +"],\"crs\":\"EPSG:4326\"}";Polygon polygon = (Polygon) OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Polygon, geoJsonString, null).getGeometry();System.out.println(polygon);}

导入 WKT

使用 OperatorImportFromWkt 创建一个多边形时,给出环的顺序是很重要的。在一个环阵列中,外环总是紧跟着零个或更多个内环。然而,环数组的顺序并不重要。必须重复每个环的起始点以指定终止点。

下面显示的代码创建了与前面示例相同的多边形,但请注意,首先给出了形成岛的外环。这样做是为了说明问题。它可以放在最后,这样读者可能更容易理解。

    @Testpublic void createPolygonFromWKT() {String wktString = "MULTIPOLYGON (((0.1 0.7, 0.1 0.4, 0.3 0.4, 0.3 0.7, 0.1 0.7)),((0 0, 0.5 0, 1 0.5, 0.5 1, 0 1, -0.5 0.5, 0 0),(0.5 0.2, 0.2 0.3, 0.1 0.2, -0.2 0.5, 0.2 0.9, 0.6 0.5, 0.5 0.2)))";Polygon polygon = (Polygon) OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Polygon, wktString, null);System.out.println(polygon);}

提取外环

许多工作流只需要获得多边形的外环。

方法 getAllOuteRings 提取一个多边形的所有外环。对 operatorsimplfyogc 的调用确保了没有自交点,所有的外环都是顺时针的,孔是逆时针方向的。如果信任输入多边形,则可以跳过对 operatorsimplfyogc 的调用。

    /*** 提取一个多边形的所有外环* @param polygon* @return*/public List<Polygon> getAllOuterRings(Polygon polygon) {List<Polygon> rings = new ArrayList<Polygon>();Polygon simplePolygon = (Polygon)OperatorSimplifyOGC.local().execute(polygon, null, true, null);Polygon ring = null;for (int i = 0; i < simplePolygon.getPathCount(); i++) {// 计算四至面积if (simplePolygon.calculateRingArea2D(i) <= 0) {continue;}ring = new Polygon();ring.addPath(simplePolygon, i, true);rings.add(ring);}return rings;}

方法 getOutermostRings 提取最外层的环,也就是说,只提取不包含在任何环中的环。

    /*** 提取最外层的外环* @param polygon* @return*/public List<Polygon> getOutermostRings(Polygon polygon) {// 联合SimpleGeometryCursor outerRingsCursor = new SimpleGeometryCursor((Geometry) getAllOuterRings(polygon));GeometryCursor unionCursor = OperatorUnion.local().execute(outerRingsCursor, null, null);// 在联合期间可能会产生环,因此请重新运行以防万一。return getAllOuterRings((Polygon)unionCursor.next());}

四至

四至是另一个几何体或一组几何体的轴对齐的矩形盒子。在某些操作中,它不等同于矩形多边形。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFrgFgky-1628133433295)(http://esri.github.io/geometry-api-java/doc/Images/Envelope/Envelope1.jpg)]

埃斯里总部周围的四至

有效四至

所有四至都是有效的,因为四至是包含其他几何图形或一组几何图形的边界盒。一个电子表面的定义因素是它与轴线对齐。一维包络是平行于一个轴的包络,而二维包络是平行于两个轴的包络。

例子

包围某一邻域的多边形 包围着所有的几何图形

Envelope类方法

为了创建四至,在 Envelope 类中定义了几个方法,这些方法需要一组不同的参数。

    @Testpublic void createEnvelope() {// 创建四至的一种方法是指定四至的中心点,高度和宽度,即应该覆盖的区域Envelope env0 = new Envelope(new Point(0, 0), 20, 20);System.out.println(env0);/* 创建包络的另一种方法是指定X和Y范围:*  xmin: 最小X坐标*  ymin:最小Y坐标*  xmax: 最大X坐标*  ymax:最大Y坐标*/Envelope env1 = new Envelope(0, 0, 30.5, 30.5);System.out.println(env1);// 为了创建围绕点的包络,我们指定点,并使用其坐标来设置包络的范围Envelope env2 = new Envelope(new Point(3.5, 4.4));System.out.println(env2);// 使用JSON字符串加载四至MapGeometry mg = OperatorFactoryLocal.loadGeometryFromJSONStringDbg("{\"hasZ\":true,\"hasM\":true,\"xmin\":0,\"ymin\":0,\"zmin\":0,\"mmin\":null,\"xmax\":1,\"ymax\":1,\"zmax\":1,\"mmax\":null}");Envelope env3 = (Envelope) mg.getGeometry();System.out.println(env3);}

获取给定几何体的四至

我们可以使用几何图形类的 queryEnvelope(Envelope e)方法查询由给定几何图形绑定的四至。

public void getGeometry(){Polygon poly = new Polygon();poly.startPath(-117.192322, 34.057129);poly.lineTo(-117.191406, 34.057129);poly.lineTo(-117.192871, 34.055298);poly.lineTo(-117.193298, 34.055725);Envelope env = new Envelope();poly.queryEnvelope(env);// 现在,env包含指定多边形的周围四至
}

OGC 几何类型

开放地理空间联盟 (OGC) 几何类型

OGC Point

com.esri.core.geometry.ogc.OGCPoint

OGC MultiPoint

com.esri.core.geometry.ogc.OGCMultiPoint

OGC LineString

com.esri.core.geometry.ogc.OGCLineString

OGC MultiLineString

com.esri.core.geometry.ogc.OGCMultiLineString

OGC Polygon

com.esri.core.geometry.ogc.OGCPolygon

OGC MultiPolygon

com.esri.core.geometry.ogc.OGCMultiPolygon

OGC GeometryCollection

com.esri.core.geometry.ogc.OGCConcreteGeometryCollection

Operations

拓扑结构(布尔运算)

Cut 切割

OperatorCut用线段(Polyline)切割几何体,获取0~n个切割后的对象

使用OperatorCut(在ArcMap中也被称为切割工具),我们可以使用切割器多段线切割多边形/多段线。

这里有一个例子,我们能够把美国地图分为西部、中部和东部三大类,以便进一步分析人口变化。

Here is how we use OperatorCut in a simple Java Program:

下面是我们如何在一个简单的Java程序中使用OperatorCut

// 创建 OperatorCut 实例
OperatorCut opCut = OperatorCut.local();/*
* considerTouch: 表示我们是否认为一个触摸事件是一个切割,这只适用于多条线,但建议将这个变量设置为True。
* cuttee: 要切割的输入几何体
* cutter: 用来将被切割者分成几块的多段线,在它与切割者交叉的地方。
* 返回: 切割几何体的GeometryCursor。
*/
GeometryCursor cursor = opCut.execute(considerTouch, cuttee, cutter, spatialReference, null);/*
* 从GeometryCurson中获取结果的多边形
*/
Polygon cut = (Polygon) cursor.next();

The cut operation returns a Geometry Cursor of cut geometries.

OperatorCut返回切割后的几何图形 Geometry Cursor。

所有左面的切割都会在第一个几何体中被归为一组。右边的切割和重合的切割会被归入第二个几何体。每个未定义的切割以及任何未切割的部分都会作为单独的几何体输出。如果没有切割,光标将不返回任何几何体。如果左切或右切不存在,返回的几何体将是空的。

只有当产生了左或右的切割,并且切割后还有剩余的部分,或者切割的边界是在切割机的左边和右边,才会产生未定义的切割。

    @Testpublic void cut() {String polygonString = "{\"rings\":[[[0.5,0.2],[0.6,0.5],[0.2,0.9],[-0.2,0.5],[0.1,0.2],[0.2,0.3],[0.5,0.2]]], \"spatialReference\":{\"wkid\":4326}}";String lineString = "{\"paths\":[[[0.5,0.2],[-0.2,0.5]]],\"spatialReference\":{\"wkid\":4326}}";Polygon polygon = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();Polyline polyline = (Polyline) OperatorImportFromJson.local().execute(Geometry.Type.Polyline, lineString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(polygon));System.out.println(OperatorExportToGeoJson.local().execute(polyline));System.out.println("--------------");GeometryCursor geometryCursor = OperatorCut.local().execute(false, polygon, polyline, null, null);while (geometryCursor.tock()) {Geometry geometry = geometryCursor.next();if (geometry == null) {break;}System.out.println(OperatorExportToGeoJson.local().execute(geometry));}}

Cut 切割

获得两个图形的拓扑差,及即获取不包含与其他图形的部分

    /*** 对两个几何体进行拓扑差操作** @param inputGeometry 原图形* @param subtractor 用于比较差异的图形* @return 获得原图形上与新图形的差异部分*/OperatorDifference.local().execute(Geometry inputGeometry,Geometry subtractor, SpatialReference sr,ProgressTracker progressTracker);
    /*** 在两个几何体上执行拓扑差异操作*/@Testpublic void difference() {String polygonString1 = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";String polygonString2 = "{\"rings\":[[[94.21875,26.115985925333536],[89.6484375,20.3034175184893],[87.1875,0.3515602939922709],[107.9296875,16.97274101999902],[106.5234375,27.059125784374068],[94.21875,26.115985925333536]]], \"spatialReference\":{\"wkid\":4326}}";Polygon inputGeometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString1).getGeometry();Polygon subtractor = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString2).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(inputGeometry));System.out.println(OperatorExportToGeoJson.local().execute(subtractor));System.out.println("---------------------------------------------");Geometry geometry = OperatorDifference.local().execute(inputGeometry, subtractor, null, null);System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

Intersection 相交

交集运算符在一个几何体、交点和一个或多个其他输入几何体之间创建集理论交点。这个运算符返回每个对、交点和每个输入几何体的交点。

输出图形的尺寸

输出几何体的所需尺寸可以通过mask参数指定。维度mask只与输出有关。

基础:

  • 1(binary: 001): points/multipoints 点/多点
  • 2(binary: 010): polylines 线段
  • 4(binary: 100): polygons 图形

组合:

  • 3(binary: 011): points/multipoints & polylines
  • 5(binary: 101): points/multipoints & polygons
  • 6(binary: 110): polylines & polygons
  • 7(binary: 111): points/multipoints & polylines & polygons

其他:

  • -1:返回的几何体将是相交对的最低维度

    • (polygons,polygons)==> polygons
    • (polygons,polylines)==> polylines

如果其他维度并不重要,当多边形与多边形或多角线相交时,值为-1的维度mask是最快的选择。

如果某个维度的交点是空的,我们将得到一个空的几何体。

例如,如果mask是 7(二进制中的 111),但没有多边形交点,我们将得到点交点、多线交点和一个空多边形。

为了获得最佳性能,请使用适当的mask。如果我们真的只想要多段线,请将尺寸mask设为2(二进制的010),而不是7(二进制的111)。

例子

我们来看几个简单的例子。在下面的图片中,蓝色的几何体是交集,绿色的几何体是输入的几何体。交集与每个输入几何体配对,输出红色几何体。

跨区间输入 尺寸 mask =-1 尺寸 mask = 3 尺寸 mask = 6

调用交集运算符

有两种方法可以调用OperatorIntersection,因为有两个execute方法。其中一个execute方法没有mask参数。通过调用这个方法,我们本质上是将维度mask设置为-1。回想一下,这意味着返回的几何体将是相交对的最低维度。

有两种方法调用 Intersection 运算符,因为有两种执行方法。其中一个 execute 方法没有遮罩参数。通过调用此方法,我们实际上将维度掩码设置为 -1。回想一下,这意味着返回的几何图形将是相交对的最低维度。

如果我们没有使用维度mask,调用的结果是这样的:

GeometryCursor outputGeoms = OperatorIntersection.local().execute(inputGeoms, intersector, spatialRef, null);

如果我们使用维度mask,调用的结果是这样的:

GeometryCursor outputGeoms = OperatorIntersection.local().execute(inputGeoms, intersector, spatialRef, null, mask);

其中 inputGeomsintersector 的类型为 GeometryCursor

然后从光标中获取相交的几何图形,我们的代码是这样的:

Geometry geometry = null;
while ((geometry = outputGeoms.next()) != null) {... do something
}

输出

每个输入对的输出几何体的数量取决于维度mask,如果维度mask等于-1,那么每个输入对将有一个输出几何体。

  • mask == -1,则每个输入都有一个输出几何体

  • mask >= 0,则每个输入都有与尺寸mask中指定的相同数量的输出几何体。

  • mask大于0,则每个输入的输出几何图形的数量将与尺寸mask中指定的数量相同。

有些输出几何体可能是空的。

为了更好地理解输出,我们将查看下图所示的应用程序生成的输出。该应用程序创建了我们之前看的几何体,并使用各种维度掩码调用交集。它打印出输出几何体的JSON格式。

    // 创建一个空间参考对象(GCS_WGS_1984)// 根据所提供的水平坐标系ID,创建空间参考的实例public static final SpatialReference SPATIAL_REFERENCE = SpatialReference.create(4326);// 原图形public static Polygon oldPolygon = null;// 输入 线1public static Polyline inputPolyline1 = null;// 输入 线2public static Polyline inputPolyline2 = null;// 输入 图形1public static Polygon inputPolygon1 = null;// 输入 图形2public static Polygon inputPolygon2 = null;@Beforepublic void init() {// 交点double coords[][] = {{0,4},{2,10},{8,12},{12,6},{10,2},{4,0}};oldPolygon = createPolygon(coords);System.out.println("原图形:");printJSONGeometry(SPATIAL_REFERENCE, oldPolygon);// Polyline 1double coords1[][] = {{1,15},{3.5,10.5},{6.5,11.5},{18,11.5}};inputPolyline1 = createPolyline(coords1);// Polyline 2double coords2[][] = {{-2,10},{1,7}};inputPolyline2 = createPolyline(coords2);// Polygon 3double coords3[][] = {{8,8},{10,10},{14,10},{16,8},{16,4},{14,2},{10,2},{8,4}};inputPolygon1 = createPolygon(coords3);// Polygon 4double coords4[][] = {{1,3},{3,1},{0,0}};inputPolygon2 = createPolygon(coords4);}/*** 创建线段* @param pts* @return*/public static Polyline createPolyline(double[][] pts) {Polyline line = new Polyline();line.startPath(pts[0][0], pts[0][1]);for (int i = 1; i < pts.length; i++) {line.lineTo(pts[i][0], pts[i][1]);}return line;}/*** 创建图形* @param pts* @return*/public static Polygon createPolygon(double[][] pts) {Polygon poly = new Polygon();poly.startPath(pts[0][0], pts[0][1]);for (int i = 1; i < pts.length; i++) {poly.lineTo(pts[i][0], pts[i][1]);}return poly;}/*** 打印 JSON图形* @param spatialRef* @param geometry*/public static void printJSONGeometry(SpatialReference spatialRef, Geometry geometry) {System.out.println("类型: " + geometry.getType());// Export the geometry to JSON format to print it out.String jsonString = OperatorExportToGeoJson.local().execute(spatialRef, geometry);System.out.println(jsonString);System.out.println();}/*** 计算相交(获取与输入图形相交部分)* @param polyline*/private void getIntersection(Polyline polyline) {Geometry geometry = null;GeometryCursor outputGeometryList = null;// 尝试不同的维度 maskint masks[] = {-1, 3, 6};for (int mask : masks) {SimpleGeometryCursor intersector = new SimpleGeometryCursor(oldPolygon);SimpleGeometryCursor inGeoms = new SimpleGeometryCursor(polyline);System.out.println("========== 当前 mask: " + mask + " ========");outputGeometryList = OperatorIntersection.local().execute(inGeoms, intersector, SPATIAL_REFERENCE, null, mask);// 从光标中获取几何图形,并以JSON格式打印.while((geometry = outputGeometryList.next()) != null) {printJSONGeometry(SPATIAL_REFERENCE, geometry);}System.out.println();}}/*** 计算相交(获取与输入图形相交部分)* @param polygon*/private void getIntersection(Polygon polygon) {Geometry geometry = null;GeometryCursor outputGeometryList = null;// 尝试不同的维度 maskint masks[] = {-1, 3, 6};for (int mask : masks) {SimpleGeometryCursor intersector = new SimpleGeometryCursor(oldPolygon);SimpleGeometryCursor inGeoms = new SimpleGeometryCursor(polygon);System.out.println("========== 当前 mask: " + mask + " ========");outputGeometryList = OperatorIntersection.local().execute(inGeoms, intersector, SPATIAL_REFERENCE, null, mask);// 从光标中获取几何图形,并以JSON格式打印.while((geometry = outputGeometryList.next()) != null) {printJSONGeometry(SPATIAL_REFERENCE, geometry);}System.out.println();}}

现在我们来看看每次的输出情况。

-1 => lowest dimension of input pair
3 => output multipoints (1) and polylines (2) (1 + 2 = 3)
6 => polylines (2) and polygons (4) (2 + 4 = 6)

首先,我们只需要打印出交点和输入的几何图形,这样就可以看到坐标了。

    @Testpublic void test01() {System.out.println("输入图形:");printJSONGeometry(SPATIAL_REFERENCE, inputPolyline1);getIntersection(inputPolyline1);}
========== 当前 mask: -1 ========
类型: Polyline
{"type":"LineString","coordinates":[[3.5,10.5],[6.5,11.5],[8.333333333333334,11.5]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 3 ========
类型: MultiPoint
{"type":"MultiPoint","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polyline
{"type":"LineString","coordinates":[[3.5,10.5],[6.5,11.5],[8.333333333333334,11.5]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 6 ========
类型: Polyline
{"type":"LineString","coordinates":[[3.5,10.5],[6.5,11.5],[8.333333333333334,11.5]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polygon
{"type":"Polygon","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}

第一个mask等于-1。因为交点是一个多边形,如果输入是一个多边形,那么输出将是一个多边形。如果输入是一条多边形,那么输出将是一条多边形。每个输入的几何体都会有一个输出。

请注意,第二个输出的多棱线是空的。这是因为交点多边形和多边形2的交点是一个点,而不是一条多边形。同样,第二个输出多边形是空的,因为交点多边形和多边形2的交点是一条多棱线,而不是多边形。

    @Testpublic void test02() {System.out.println("输入图形:");printJSONGeometry(SPATIAL_REFERENCE, inputPolyline2);getIntersection(inputPolyline2);}
========== 当前 mask: -1 ========
类型: Polyline
{"type":"LineString","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 3 ========
类型: MultiPoint
{"type":"MultiPoint","coordinates":[[1,7]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polyline
{"type":"LineString","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 6 ========
类型: Polyline
{"type":"LineString","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polygon
{"type":"Polygon","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}

接下来,我们使用一个等于3的维度mask,这表示我们要找到点/多点和多线的交点。因此,我们将对每个输入几何体有两个输出几何体。

注意,唯一不为空的多点是作为交点和多棱线2的交点输出的。

    @Testpublic void test03() {System.out.println("输入图形:");printJSONGeometry(SPATIAL_REFERENCE, inputPolygon1);getIntersection(inputPolygon1);}
*******Dim mask: 3*******
========== 当前 mask: -1 ========
类型: Polygon
{"type":"Polygon","coordinates":[[[10,2],[12,6],[9.6,9.6],[8,8],[8,4],[10,2]]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 3 ========
类型: MultiPoint
{"type":"MultiPoint","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polyline
{"type":"LineString","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 6 ========
类型: Polyline
{"type":"LineString","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polygon
{"type":"Polygon","coordinates":[[[10,2],[12,6],[9.6,9.6],[8,8],[8,4],[10,2]]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}

最后,我们检查维度mask等于6时的结果。这次我们要的是多线和多边形的交点。

    @Testpublic void test04() {System.out.println("输入图形:");printJSONGeometry(SPATIAL_REFERENCE, inputPolygon2);getIntersection(inputPolygon2);}
*******Dim mask: 6*******
========== 当前 mask: -1 ========
类型: Polygon
{"type":"Polygon","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 3 ========
类型: MultiPoint
{"type":"MultiPoint","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polyline@Testpublic void test04() {System.out.println("输入图形:");printJSONGeometry(SPATIAL_REFERENCE, inputPolygon2);getIntersection(inputPolygon2);}
{"type":"LineString","coordinates":[[3,1],[0.9999999999999999,3]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}========== 当前 mask: 6 ========
类型: Polyline
{"type":"LineString","coordinates":[[3,1],[0.9999999999999999,3]],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}类型: Polygon
{"type":"Polygon","coordinates":[],"crs":{"type":"name","properties":{"name":"EPSG:4326"}}}

OperatorSymmetricDifference 异或

几何图形之间的异或运算,即获取非公共部分

    /*** 在几何集上执行异或运算* @param inputGeometries 要被rightGeometry XOR的几何体实例的集合* @param rightGeometry 与输入几何体XOR的几何体* @return 返回异或运算结果** operator XOR将inputGeometries中的每一个几何体与rightGeometry进行对比。*/public abstract GeometryCursor execute(GeometryCursor inputGeometries,GeometryCursor rightGeometry, SpatialReference sr,ProgressTracker progressTracker);/*** 对两个几何体进行异或运算* @param leftGeometry 要被rightGeometry XOR的几何体实例的集合* @param 与输入几何体XOR的几何体* @return 返回异或运算结果*/public abstract Geometry execute(Geometry leftGeometry,Geometry rightGeometry, SpatialReference sr,ProgressTracker progressTracker);
    @Testpublic void symmetricDifferenceTest() {String polygonString1 = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";String polygonString2 = "{\"rings\":[[[94.21875,26.115985925333536],[89.6484375,20.3034175184893],[87.1875,0.3515602939922709],[107.9296875,16.97274101999902],[106.5234375,27.059125784374068],[94.21875,26.115985925333536]]], \"spatialReference\":{\"wkid\":4326}}";Polygon inputGeometries = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString1).getGeometry();Polygon rightGeometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString2).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(inputGeometries));System.out.println(OperatorExportToGeoJson.local().execute(rightGeometry));System.out.println("---------------------------------------------");Geometry geometry = OperatorSymmetricDifference.local().execute(inputGeometries, rightGeometry, null, null);System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

OperatorUnion 合并

在两个几何体上执行拓扑合并操作,及获取并集

    /*** 在几何体集上执行拓扑联合操作* @param inputGeometries 要结合的几何体实例的集合.**/public abstract GeometryCursor execute(GeometryCursor inputGeometries,SpatialReference sr, ProgressTracker progressTracker);/*** 在两个几何体上执行拓扑联合操作* @param geom1和geom2是要联合的几何体实例.**/public abstract Geometry execute(Geometry geom1, Geometry geom2,SpatialReference sr, ProgressTracker progressTracker);
    @Testpublic void union() {String polygonString1 = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";String polygonString2 = "{\"rings\":[[[94.21875,26.115985925333536],[89.6484375,20.3034175184893],[87.1875,0.3515602939922709],[107.9296875,16.97274101999902],[106.5234375,27.059125784374068],[94.21875,26.115985925333536]]], \"spatialReference\":{\"wkid\":4326}}";Polygon inputGeometries = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString1).getGeometry();Polygon rightGeometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString2).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(inputGeometries));System.out.println(OperatorExportToGeoJson.local().execute(rightGeometry));System.out.println("---------------------------------------------");Geometry geometry = OperatorUnion.local().execute(inputGeometries, rightGeometry, null, null);System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

校验

Simplify

验证并修复几何体,使其正确存储在地理数据库中

简化几何体或确定几何体是否简单。

OperatorSimplify 的目标是生成一个有效的几何体,以便Geodatabase存储,而不需要额外的处理。地质处理工具CheckGeometries应该接受这个操作者的execute方法产生的几何体。对于多边形来说,execute的效果与IPolyline6.NonPlanarSimplify相同,而对于多边形和多点来说,则与ITopologicalOperator.Simplify相同。对于点类,这个运算符没有任何作用,点总是简单的。在执行方法之后,isSimpleAsFeature应该返回true。

    /*** 对几何体光标进行验证* @param geoms 要验证的集合体* @param sr 获取公差的空间参考。当为空时,公差将根据每个几何体的边界单独得出。* @param bForceSimplify 当为真时,无论内部是否有IsKnownSimple标志,几何体都将被验证。* @param progressTracker 允许取消一个长操作。可以为空。* @return 返回一个验证几何体的 GeometryCursor。** The isSimpleAsFeature returns true after this method.*/public abstract GeometryCursor execute(GeometryCursor geoms,SpatialReference sr, boolean bForceSimplify,ProgressTracker progressTracker);/*** 执行几何体的验证* @param geom 要验证的集合体* @param sr 获取公差的空间参考。当为空时,公差将根据每个几何体的边界单独得出。* @param bForceSimplify 当为真时,无论内部是否有IsKnownSimple标志,几何体都将被简化。* @param progressTracker 允许取消一个长操作。可以为空。* @return 返回一个验证几何体的 geometry.**The isSimpleAsFeature returns true after this method.*/public abstract Geometry execute(Geometry geom, SpatialReference sr,boolean bForceSimplify, ProgressTracker progressTracker);
    @Testpublic void simplify() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));Geometry execute = OperatorSimplify.local().execute(geometry, null, true, null);System.out.println(OperatorExportToGeoJson.local().execute(execute));}

IsSimple

验证几何形状是否正确,以便存储在geodatabase中

简化几何体或确定几何体是否简单。

OperatorSimplify 的目标是生成一个有效的几何体,以便Geodatabase存储,而不需要额外的处理。

地质处理工具CheckGeometries应该接受这个操作者的execute方法产生的几何体。

对于多边形来说,execute的效果与IPolyline6.NonPlanarSimplify相同,而对于多边形和多点来说,则与ITopologicalOperator.Simplify相同。对于点类,这个运算符没有任何作用,点总是简单的。在执行方法之后,isSimpleAsFeature应该返回true。

    /*** 测试几何体是否简单* @param geom 需要测试的几何图形* @param spatialRef 获取公差的空间参考。可以为空,然后从几何边界中得出一个非常小的公差值。* @param bForceTest 当True时,无论内部的IsKnownSimple标志如何,都会对几何体进行测试。* @param result 如果不为空,将包含检查的结果。* @param progressTracker 允许取消长时间的操作。可以为空。**/public abstract boolean isSimpleAsFeature(Geometry geom,SpatialReference spatialRef, boolean bForceTest,NonSimpleResult result, ProgressTracker progressTracker);/*** 测试几何体是否简单(第二次调用将使用缓存的IsKnownSimple标志并立即返回)。* @param geom 需要测试的几何图形* @param spatialRef 获取公差的空间参考。可以为空,然后从几何边界中得出一个非常小的公差值。* @param progressTracker 允许取消长时间的操作。可以为空。**/public boolean isSimpleAsFeature(Geometry geom,SpatialReference spatialRef, ProgressTracker progressTracker) {return isSimpleAsFeature(geom, spatialRef, false, null, progressTracker);}
    @Testpublic void simplify() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));Geometry execute = OperatorSimplify.local().execute(geometry, null, true, null);System.out.println(OperatorExportToGeoJson.local().execute(execute));boolean simpleAsFeature1 = OperatorSimplify.local().isSimpleAsFeature(geometry, null, null);System.out.println(simpleAsFeature1);boolean simpleAsFeature2 = OperatorSimplify.local().isSimpleAsFeature(execute, null, null);System.out.println(simpleAsFeature2);}

Simplify with OGC restrictions

根据OGC规则,验证并修正几何体的正确性

简化几何体或确定几何体是否简单。遵照OGC的简单特征访问规范1.2.1 (06-103r4)。使用公差来确定相等的顶点或交点。

    /*** 处理几何体光标,确保其几何体简单,符合OGC规范* @param geoms 要简化的几何体* @param sr 获取公差的空间参考。当为空时,公差将从几何边界中单独得出。* @param bForceSimplify 当为真时,无论内部是否有IsKnownSimple标志,几何体都将被简化。* @param progressTracker 允许取消长时间的操作。可以为空。* @return 返回一个简化几何体的GeometryCursor。* * isSimpleOGC在此调用后返回true。*/public abstract GeometryCursor execute(GeometryCursor geoms,SpatialReference sr, boolean bForceSimplify,ProgressTracker progressTracker);/*** 对几何体进行处理,以确保其对OGC规范的简单* @param geom 要简化的几何体* @param sr 获取公差的空间参考。当为空时,公差将从几何边界中单独得出。* @param bForceSimplify 当为真时,无论内部是否有IsKnownSimple标志,几何体都将被简化。* @param progressTracker 允许取消长时间的操作。可以为空。* @return 返回一个简单的几何体,这个几何体应该与输入的几何体在视觉上相等。* * The isSimpleOGC returns true after this call.isSimpleOGC在此调用后返回true。*/public abstract Geometry execute(Geometry geom, SpatialReference sr,boolean bForceSimplify, ProgressTracker progressTracker);
    @Testpublic void simplifyOGC() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));Geometry execute = OperatorSimplifyOGC.local().execute(geometry, null, true, null);System.out.println(OperatorExportToGeoJson.local().execute(execute));}

IsSimple with OGC restrictions

根据OGC规则,检查几何形状是否正确

简化几何体或确定几何体是否简单。遵照OGC的简单特征访问规范1.2.1 (06-103r4)。使用公差来确定相等的顶点或交点。

    /*** 测试OGC规格的几何体是否简单* @param geom 待测几何图形* @param spatialRef 获取公差的空间参考。当为空时,公差将从几何边界中单独得出。* @param bForceTest 当True时,无论IsKnownSimple标志是什么,都会对几何体进行测试。* @param progressTracker 允许取消长时间的操作。可以为空。** 注意:与 OperatorSimplifyOGC 中的其他方法一样,本方法使用了来自空间参考的容差。* 在容许范围内的点视为相等** 当这个方法返回true时,OperatorSimplify.isSimpleAsFeature也会返回true(这并不一定要反过来)。*/public abstract boolean isSimpleOGC(Geometry geom,SpatialReference spatialRef, boolean bForceTest,NonSimpleResult result, ProgressTracker progressTracker);
    @Testpublic void simplifyOGC() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));Geometry execute = OperatorSimplifyOGC.local().execute(geometry, null, true, null);System.out.println(OperatorExportToGeoJson.local().execute(execute));boolean simpleAsFeature1 = OperatorSimplifyOGC.local().isSimpleOGC(geometry, null, true, null, null);System.out.println(simpleAsFeature1);boolean simpleAsFeature2 = OperatorSimplifyOGC.local().isSimpleOGC(execute, null, true, null, null);System.out.println(simpleAsFeature2);}

空间关系

前置知识点

为了了解关系操作是如何工作的,首先回顾一下基本几何类型的维度、内部、边界和外部的定义。

维度

  • 零维: 所有的点和多点形状
  • 一维: 折线形状
  • 二维: 多边形形状

请注意,z 坐标或 m 坐标的存在并不影响几何体的维数。

内部、边界和外部

每种几何类型都有一个已定义的内部、边界和外部,这对于理解关系运算符很重要。

Point 点

一个点表示空间中的单一位置。

点的内部是点本身,边界是空集,外部是所有其他点

MultiPoint 多点

多点是点的有序集合。

多点的内部是集合中的点的集合,边界是空集合,外部是集合中不存在的点的集合

Polyline 线段

线段是一个有序的路径集合,其中每个路径是一个相邻段的集合。一个段有一个起点和一个终点。

线段的边界是每条路径的起点和终点的集合,内部是折线中不在边界上的点的集合,外部是不在边界或内部的点的集合

对于下面显示的折线,组成边界的点集用红色显示。折线的内部用黑色显示

Polygon 多边形

一个多边形是由一组环定义的。每个环是一个连续段的集合,这样起点和终点是相同的。

多边形的边界是定义多边形的环的集合。边界包含一个或多个外环和零个或多个内环。外环为顺时针方向,内环为逆时针方向。想象沿着外环顺时针方向行走。你的右边是多边形的内部,左边是外部

类似地,如果你沿着内环逆时针方向走,你的右边是多边形的内部,左边是外部。

Contains 包含 && Within 包含

Contains 包含

一个几何体包含另一个几何体,如果另一个几何体是它的子集,并且它们的内部至少有一个共同点。

在下面的图片中几何 a 是蓝色的,几何 b 是红色的。

private boolean geometryContains(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean contains = OperatorContains.local().execute(geometryA, geometryB, sr, null);return contains;
}

Within 包含

如果一个几何体是另一个几何体的子集,并且它们的内部至少有一个共同点,那么这个几何体就在另一个几何体中。

在下面的图片中几何 a 是蓝色的,几何 b 是红色的。

static boolean geometryIsWithin(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean isWithin = OperatorWithin.local().execute(geometryA, geometryB, sr, null);return isWithin;
}

Crosses 相交 && Intersects 互相交叉 && Disjoint 不相交

Crosses 相交

如果两条折线仅在(a)点处相交,则两条折线相交,且至少其中一个共享点位于两条折线的内部。

如果多边形的连通部分部分在多边形内部和部分在多边形外部,则为多边形和多边形的交叉。

static boolean geometryCrosses(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean crosses = OperatorCrosses.local().execute(geometryA, geometryB, sr, null);return crosses;
}

Intersects 互相交叉

两个几何图形如果共享至少一个点则相交。

static boolean geometryIntersects(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean intersects = OperatorIntersects.local().execute(geometryA, geometryB, sr, null);return intersects;
}

Disjoint 不相交

如果两种几何体没有任何共同点,它们就是不相交的。不相交算子是最有效的算子,即使在非简单的几何上也能工作。

static boolean geometryIsDisjoint(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean isDisjoint = OperatorDisjoint.local().execute(geometryA, geometryB, sr, null);return isDisjoint;
}

Equals 相等

如果两个几何体占据同一空间,它们是相等的。

注意,下面显示的两个几何图形有不同数量的顶点,但它们仍然相等。

static boolean geometryEquals(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean equals = OperatorEquals.local().execute(geometryA, geometryB, sr, null);return equals;
}

Overlaps 重叠

Overlaps 重叠

Two geometries overlap if they have the same dimension, and their intersection also has the same dimension but is different from both of them.

如果两个几何体具有相同的维度,那么它们就会重叠,而且它们的交集也具有相同的维度,但是它们与两者不同。

static boolean geometryOverlaps(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean overlaps = OperatorOverlaps.local().execute(geometryA, geometryB, sr, null);return overlaps;
}

Touches 接触

Touches 接触

如果两个几何图形的内部交集是空的,但两个几何图形的交集不是空的,则两个几何图形相接触。

boolean geometryTouches(Geometry geometryA, Geometry geometryB, SpatialReference sr) {boolean touches = OperatorTouches.local().execute(geometryA, geometryB, sr, null);return touches;
}

示例代码

    private static final String POLYGON_STRING_1 = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";private static final String POLYGON_STRING_2 = "{\"rings\":[[[94.21875,26.115985925333536],[89.6484375,20.3034175184893],[87.1875,0.3515602939922709],[107.9296875,16.97274101999902],[106.5234375,27.059125784374068],[94.21875,26.115985925333536]]], \"spatialReference\":{\"wkid\":4326}}";private static final String POLYGON_STRING_3 = "{\"rings\":[[[102.63427734374999,25.562265014427492],[102.81005859375,24.10664717920179],[104.26025390625,24.50714328310284],[103.7548828125,25.661333498952683],[102.63427734374999,25.562265014427492]]], \"spatialReference\":{\"wkid\":4326}}";private static Polygon polygon1 = null;private static Polygon polygon2 = null;private static Polygon polygon3 = null;@Beforepublic void init() {polygon1 = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, POLYGON_STRING_1).getGeometry();polygon2 = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, POLYGON_STRING_2).getGeometry();polygon3 = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, POLYGON_STRING_3).getGeometry();System.out.println("polygon1:");System.out.println(OperatorExportToGeoJson.local().execute(polygon1));System.out.println("polygon2:");System.out.println(OperatorExportToGeoJson.local().execute(polygon2));System.out.println("polygon3:");System.out.println(OperatorExportToGeoJson.local().execute(polygon3));System.out.println("===============================================");}@Testpublic void containsAndWithin() {System.out.println(OperatorContains.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorWithin.local().execute(polygon1, polygon2, null, null));System.out.println("-----------------------");System.out.println(OperatorContains.local().execute(polygon1, polygon3, null, null));System.out.println(OperatorWithin.local().execute(polygon1, polygon3, null, null));}@Testpublic void crossesAndIntersectsAndDisjoint() {System.out.println(OperatorCrosses.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorIntersects.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorDisjoint.local().execute(polygon1, polygon2, null, null));System.out.println("-----------------------");System.out.println(OperatorCrosses.local().execute(polygon1, polygon3, null, null));System.out.println(OperatorIntersects.local().execute(polygon1, polygon3, null, null));System.out.println(OperatorDisjoint.local().execute(polygon1, polygon3, null, null));}@Testpublic void equals() {System.out.println(OperatorEquals.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorEquals.local().execute(polygon1, polygon3, null, null));System.out.println(OperatorEquals.local().execute(polygon1, polygon1, null, null));}@Testpublic void overlaps() {System.out.println(OperatorOverlaps.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorOverlaps.local().execute(polygon1, polygon3, null, null));System.out.println("---------------------");System.out.println(OperatorOverlaps.local().execute(polygon1, polygon1, null, null));}@Testpublic void touches() {System.out.println(OperatorTouches.local().execute(polygon1, polygon2, null, null));System.out.println(OperatorTouches.local().execute(polygon1, polygon3, null, null));System.out.println("---------------------");System.out.println(OperatorTouches.local().execute(polygon1, polygon1, null, null));}

导入/导出

ESRI Shape

导出

    /*** 执行ExportToESRIShape操作* * @return ByteBufferCursor.*/abstract ByteBufferCursor execute(int exportFlags,GeometryCursor geometryCursor);/*** 执行ExportToESRIShape操作* @param exportFlags 使用{@link ShapeExportFlags}接口* @param geometry 要输出的几何体* @return 返回一个包含ESRIShape格式的几何体的ByteBuffer对象*/public abstract ByteBuffer execute(int exportFlags, Geometry geometry);/*** 执行ExportToESRIShape操作* @param exportFlags 使用{@link ShapeExportFlags}接口。* @param geometry 要输出的几何体* @param shapeBuffer 包含以ESRIShape格式导出的几何体的ByteBuffer* @return 如果输入缓冲区是空的,那么返回缓冲区所需的大小,否则返回写入缓冲区的字节数。否则返回写入缓冲区的字节数。*/public abstract int execute(int exportFlags, Geometry geometry,ByteBuffer shapeBuffer);
    @Testpublic void exportTest() throws IOException {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();ByteBuffer byteBuffer = OperatorExportToESRIShape.local().execute(ShapeExportFlags.ShapeExportDefaults, geometry);FileUtils.writeByteArrayToFile(new File("E:/test01.shape"), byteBuffer.array());}

导入

    /*** 在形状缓冲流上执行ImportFromESRIShape操作* @param importFlags 使用{@link ShapeImportFlags}接口。默认值是0,表示几何体来自可信的来源,并且拓扑结构简单。* 如果几何体来自非信任源(即它可以是非简单的),传递ShapeImportNonTrusted。* @param type 您要导入的几何体类型。使用{@link Geometry.Type}枚举,如果需要从形状缓冲区中找出几何体的类型,它可以是Geometry.Type.Unknown。* @param shapeBuffers 形状缓冲区上的光标,以ESRIShape格式保存几何体。* @return GeometryCursor.*/abstract GeometryCursor execute(int importFlags, Geometry.Type type,ByteBufferCursor shapeBuffers);/*** 执行从ESRIShape导入操作* @param importFlags 使用{@link ShapeImportFlags}接口。默认值是0,表示几何体来自可信的来源,并且拓扑结构简单。* 如果几何体来自非信任源(即它可以是非简单的),传递ShapeImportNonTrusted。* @param type 您要导入的几何体类型。使用{@link Geometry.Type}枚举,如果需要从形状缓冲区中找出几何体的类型,它可以是Geometry.Type.Unknown。* @param shapeBuffer 形状缓冲区上的光标,以ESRIShape格式保存几何体。* @return Geometry.*/public abstract Geometry execute(int importFlags, Geometry.Type type,ByteBuffer shapeBuffer);
    @Testpublic void importTest() throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(FileUtils.readFileToByteArray(new File("E:/test01.shape")));Geometry geometry = OperatorImportFromESRIShape.local().execute(ShapeImportFlags.ShapeImportDefaults, Geometry.Type.Unknown, byteBuffer);System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

Json

导出

    /*** 执行ExportToJson操作** @return 返回一个JsonCursor*/public abstract JsonCursor execute(SpatialReference spatialReference,GeometryCursor geometryCursor);/*** 执行ExportToJson操作** @return 返回一个字符串*/public abstract String execute(SpatialReference spatialReference,Geometry geometry);/*** 执行ExportToJson操作** @return 返回一个字符串*/public abstract String execute(SpatialReference spatialReference,Geometry geometry, Map<String, Object> exportProperties);
    @Testpublic void exportJson() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();String result = OperatorExportToJson.local().execute(null, geometry);System.out.println(result);}

导入

    /*** 对多个Json字符串执行ImportFromJson操作* * @return 返回一个MapGeometryCursor*/abstract MapGeometryCursor execute(Geometry.Type type,JsonReaderCursor jsonReaderCursor);/*** 对多个Json字符串执行ImportFromJson操作* @return 返回一个MapGeometry.*/public abstract MapGeometry execute(Geometry.Type type,JsonReader jsonReader);/*** 对多个Json字符串执行ImportFromJson操作* @return 返回一个MapGeometry.*/public abstract MapGeometry execute(Geometry.Type type, String string);
    @Testpublic void importJson() {String json = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]]}";Geometry geometry = OperatorImportFromJson.local().execute(Geometry.Type.Unknown, json).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

GeoJson

导出

    /*** 执行ExportToGeoJson操作* @param spatialReference 几何体的空间参照物,如果空间参照物为空,则写成 "crs":null。如果spatialReference为空,则写为 "crs":null。* @param geometryCursor 要导出GeoJson的几何体光标* @return 返回一个JsonCursor.*/public abstract JsonCursor execute(SpatialReference spatialReference, GeometryCursor geometryCursor);/*** 执行ExportToGeoJson操作* @param spatialReference 几何体的空间参照物,如果空间参照物为空,则写成 "crs":null。如果spatialReference为空,则写为 "crs":null。* @param geometry 要导出GeoJson的几何体光标* @return 返回一个 GeoJson 格式的字符串.*/public abstract String execute(SpatialReference spatialReference, Geometry geometry);/*** 执行ExportToGeoJson操作* @param exportFlags 使用{@link GeoJsonExportFlags}接口* @param spatialReference 几何体的空间参照物,如果空间参照物为空,则写成 "crs":null。如果spatialReference为空,则写为 "crs":null。* @param geometry 要导出GeoJson的几何体光标* @return 返回一个 GeoJson 格式的字符串.*/public abstract String execute(int exportFlags, SpatialReference spatialReference, Geometry geometry);/*** 执行ExportToGeoJson操作。不会写出空间参考或crs标签。假设几何体是在wgs84中。* @param geometry 要导出GeoJson的几何体光标* @return 返回一个 GeoJson 格式的字符串.*/public abstract String execute(Geometry geometry);
    @Testpublic void exportGeoJson() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

导入

    /*** 执行ImportFromGeoJson操作** @param type 使用{@link Geometry.Type}枚举* @param jsonReader * @return 返回输入的MapGeometry* @throws JsonGeometryException*/public abstract MapGeometry execute(int importFlags, Geometry.Type type, JsonReader jsonReader, ProgressTracker progressTracker);/*** 已废弃,使用不带import_flags的版本* * 执行ImportFromGeoJson操作** @param import_flags Use the {@link GeoJsonImportFlags} interface.* @param type 使用{@link Geometry.Type}枚举* @param geoJsonString 以geoJson格式保存几何体的字符串* @return 返回输入的MapGeometry* */public abstract MapGeometry execute(int import_flags, Geometry.Type type, String geoJsonString, ProgressTracker progress_tracker);/*** * 执行ImportFromGeoJson操作** @param import_flags Use the {@link GeoJsonImportFlags} interface.* @param geoJsonString 以geoJson格式保存几何体的字符串* @return 返回输入的MapOGCStructure.*/public abstract MapOGCStructure executeOGC(int import_flags, String geoJsonString, ProgressTracker progress_tracker);
    @Testpublic void importGeoJson() {String geoJson = "{\"type\":\"Polygon\",\"coordinates\":[[[58.71093750000001,51.39920565355378],[137.4609375,55.3791104480105],[136.7578125,17.308687886770034],[78.046875,28.92163128242129],[58.71093750000001,51.39920565355378]]]}";MapGeometry mapGeometry = OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Unknown, geoJson, null);Geometry geometry = mapGeometry.getGeometry();System.out.println(geometry);}

WKT

导出

    /*** 执行exportToWkt* @param exportFlags 使用{@link WktExportFlags}接口* @param geometry 待导出的几何对象* @param progress_tracker 回调,为长时间的操作提供进度和取消跟踪机制*/public abstract String execute(int exportFlags, Geometry geometry,ProgressTracker progress_tracker);
    @Testpublic void exportWKT() {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();String result = OperatorExportToWkt.local().execute(WktExportFlags.wktExportDefaults, geometry, null);System.out.println(result);}

导入

    /*** 执行ImportFromWkt操作* @param import_flags 使用{@link WktImportFlags}接口* @param type 使用{@link Geometry.Type}枚举* @param wkt_string 以wkt格式保存几何体的字符串* @return 返回导入的几何体*/public abstract Geometry execute(int import_flags, Geometry.Type type,String wkt_string, ProgressTracker progress_tracker);/*** 执行ImportFromWkt操作* @param import_flags 使用{@link WktImportFlags}接口* @param wkt_string 以wkt格式保存几何体的字符串* @return 返回导入的OGCStructure*/public abstract OGCStructure executeOGC(int import_flags,String wkt_string, ProgressTracker progress_tracker);
    @Testpublic void importWKT() {String wkt = "MULTIPOLYGON (((58.71093750000001 51.39920565355378, 137.4609375 55.3791104480105, 136.7578125 17.308687886770034, 78.046875 28.92163128242129, 58.71093750000001 51.39920565355378)))";Geometry geometry = OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Unknown, wkt, null);System.out.println(geometry);}

WKB

导出

    /*** 执行ExportToWKB操作* @param exportFlags 使用{@link WkbExportFlags}接口* @param geometry 待导出的几何体* @return Returns 一个包含WKB格式几何体的ByteBuffer对象*/public abstract ByteBuffer execute(int exportFlags, Geometry geometry,ProgressTracker progressTracker);/*** 执行ExportToWKB操作* @param exportFlags 使用{@link WkbExportFlags}接口* @param geometry 待导出的几何体* @param wkbBuffer 包含WKB格式导出的几何体的ByteBuffer* @return 如果输入缓冲区是空的,那么返回缓冲区所需的大小,否则返回写入缓冲区的字节数。否则返回写入缓冲区的字节数。*/public abstract int execute(int exportFlags, Geometry geometry,ByteBuffer wkbBuffer, ProgressTracker progressTracker);
    @Testpublic void exportWKB() throws IOException {String polygonString = "{\"rings\":[[[58.71093750000001,51.39920565355378],[78.046875,28.92163128242129],[136.7578125,17.308687886770034],[137.4609375,55.3791104480105],[58.71093750000001,51.39920565355378]]], \"spatialReference\":{\"wkid\":4326}}";Polygon geometry = (Polygon) OperatorImportFromJson.local().execute(Geometry.Type.Polygon, polygonString).getGeometry();ByteBuffer byteBuffer = OperatorExportToWkb.local().execute(WkbExportFlags.wkbExportDefaults, geometry, null);FileUtils.writeByteArrayToFile(new File("E:/test02.wkb"), byteBuffer.array());}

导入

    /*** 执行ImportFromWKB操作* @param importFlags 使用{@link WkbImportFlags}接口* @param type 使用{@link Geometry.Type}枚举* @param wkbBuffer wkb格式的几何体缓冲区* @return 返回导入Geometry*/public abstract Geometry execute(int importFlags, Geometry.Type type,ByteBuffer wkbBuffer, ProgressTracker progress_tracker);/*** 执行ImportFromWKB操作* @param importFlags 使用{@link WkbImportFlags}接口* @param wkbBuffer wkb格式的几何体缓冲区* @return 返回导入的OGCStructure*/public abstract OGCStructure executeOGC(int importFlags,ByteBuffer wkbBuffer, ProgressTracker progress_tracker);
    @Testpublic void importWKB() throws IOException {ByteBuffer byteBuffer = ByteBuffer.wrap(FileUtils.readFileToByteArray(new File("E:/test02.wkb")));Geometry geometry = OperatorImportFromWkb.local().execute(WkbImportFlags.wkbImportDefaults, Geometry.Type.Unknown, byteBuffer, null);System.out.println(geometry);}

其他

Boundary 边界

创建一个给定几何体的边界几何体

  /*** 计算边界* @param geoms 输入的几何体.* @param progress_tracker 进度跟踪器,可以取消冗长的操作* @return 返回每个几何体的边界上的游标*/abstract public GeometryCursor execute(GeometryCursor geoms, ProgressTracker progress_tracker);/*** 计算边界* @param geom 输入的几何体.* @param progress_tracker 进度跟踪器,可以取消冗长的操作* @return 返回边界** 点 - 空点* 多点 - 空点* 边界 - 返回一个多段线,它是包络线的边界* 线 - 返回一个多点,使用OGC规范(包括路径端点,使用mod 2规则)。* 图形 - 返回多角形的边界线(将多角形的所有环加到一条多角线上)。*/abstract public Geometry execute(Geometry geom, ProgressTracker progress_tracker);
    @Testpublic void boundary() {String geoJsonString = "{\"type\":\"Polygon\",\"coordinates\":[[[58.71093750000001,51.39920565355378],[137.4609375,55.3791104480105],[136.7578125,17.308687886770034],[78.046875,28.92163128242129],[58.71093750000001,51.39920565355378]]]}";Polygon polygon = (Polygon) OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Polygon, geoJsonString, null).getGeometry();Geometry geometry = OperatorBoundary.local().execute(polygon, null);// 面System.out.println(geoJsonString);// 线段System.out.println(OperatorExportToGeoJson.local().execute(geometry));}

Buffer 缓冲

Buffer 操作符在指定距离上围绕输入几何形状创建一个缓冲多边形。如果输入几何图形是一个多边形,并且指定了负距离,那么缓冲多边形可以位于输入几何图形内部。指定的距离以相关空间引用的单位为单位。

让我们看一些不同几何类型的简单例子。在下面的图像中,蓝色几何体是输入几何体,绿色几何体是一个可能的缓冲多边形。

输入几何 缓冲多边形 两者都有

线

输入几何 缓冲多边形 两者都有

多边形

输入几何 缓冲多边形 两者都有

我们也可以从更复杂的几何图形中创建缓冲区。例如,考虑下面显示的代表印度尼西亚的输入几何图形。这个多部分多边形有137个部分和9,164个顶点。

输入几何 缓冲多边形 两者都有

我们还可以使用游标缓冲多个几何图形,并在一次执行中输入多个距离参数。我们稍后再谈这个问题。

现在,我们将研究从单个输入几何图形生成缓冲区的一些代码。

缓冲单个几何体

为了缓冲一个几何图形,我们使用 OperatorBuffer 类的一个执行方法。

public abstract Geometry execute(Geometry inputGeometry, SpatialReference sr, double distance, ProgressTracker progressTracker);

若要调用 execute 方法,请创建 Buffer 运算符的本地实例。

Geometry outputGeometry = OperatorBuffer.local().execute(inputGeometry, sr, distance, null);

例子

下面给出的程序创建一个多边形,然后将其用作 Buffer 操作符的输入。空间参考是 GCS _ wgs _ 1984,所以距离单位为度。

package com.huitian.esri.geometry.demo.operations.other;import com.esri.core.geometry.*;
import org.junit.jupiter.api.Test;/*** Copyright (C), 2017-2020, 云南慧天** @Description:* @Author: YangZhi* @Date: 2020/10/28 20:15* @History: <author>          <time>          <version>          <desc>* 作者姓名           修改时间           版本号              描述*/
public class OperatorBufferDemo {private static final SpatialReference SPATIAL_REFERENCE = SpatialReference.create(4326);public static Polygon createPolygon1() {Polygon poly = new Polygon();// Outer ringpoly.startPath(0, 0);poly.lineTo(0, 1);poly.lineTo(1, 1);poly.lineTo(1, 0);// Holepoly.startPath(0.25, 0.25);poly.lineTo(0.75, 0.25);poly.lineTo(0.75, 0.75);poly.lineTo(0.25, 0.75);return poly;}public static void printResult(Geometry geometry) {// 将几何体导出为JSON格式打印出来String jsonString = OperatorExportToGeoJson.local().execute(SPATIAL_REFERENCE, geometry);System.out.println(jsonString);System.out.println();}public static void main(String[] args) {Polygon poly1 = createPolygon1();printResult(poly1);Geometry outputGeom = OperatorBuffer.local().execute(poly1, SPATIAL_REFERENCE, 0.5, null);printResult(outputGeom);outputGeom = OperatorBuffer.local().execute(poly1, SPATIAL_REFERENCE, 0.1, null);printResult(outputGeom);// 缓冲区的多边形应该在输入的几何体内outputGeom = OperatorBuffer.local().execute(poly1, SPATIAL_REFERENCE, -0.09, null);printResult(outputGeom);}}

The input geometry and the buffer polygons generated by BufferApp_1 are shown below.

下面显示了 OperatorBufferDemo 生成的输入几何图形和缓冲多边形。

输入几何 缓冲多边形 (距离 = 0.5) 两者都有
输入几何 缓冲多边形 (距离 = 0.1) 两者都有
输入几何 缓冲多边形 (距离 =-0.09) 两者都有

缓冲多个几何图形

假设我们有很多几何体,我们想为其生成缓冲多边形。事实上,也许我们想要结果缓冲区多边形的结合。也许我们需要进行链式操作,也就是说,将缓冲区操作的输出作为另一个操作的输入。如果输入的几何体是相同的类型,就没有必要一次处理一个。在这些和类似的情况下,我们考虑使用几何体游标。

为了同时缓冲多个几何图形,我们使用 OperatorBuffer 类中的另一个执行方法。

public abstract GeometryCursor execute(GeometryCursor inputGeometries, SpatialReference sr, double[] distances, boolean bUnion, ProgressTracker progressTracker);

若要调用 execute 方法,请创建 Buffer 运算符的本地实例。

GeometryCursor outputGeometries = OperatorBuffer.local().execute(inputGeometries, sr, distances, bUnion, null);

请注意,我们现在有一个距离数组。第一个输入几何体将使用数组中的第一个距离进行缓冲,第二个输入几何体将使用数组中的第二个距离进行缓冲,以此类推。如果距离数组的大小小于输入几何体的数量,数组中最后一个距离值将被用来缓冲剩余的输入几何体。

bUnion参数是一个布尔值,表示缓冲区的多边形是否应该合并,如果bUnion设置为true,那么输出光标只包含一个多边形,即所有缓冲区多边形的合并。如果bUnion被设置为true,那么输出光标只包含一个多边形,即所有缓冲多边形的结合。如果bUnion设置为false,则输出光标包含每一个缓冲区多边形作为一个单独的几何体。

例子

考虑下面显示的代表丹佛市中心街道的一部分的多线。

我们希望有一个120米的缓冲周围封闭的息肉线

还有一个50米的缓冲区,围绕着剩下的水线。

我们可以通过下面给出的程序来完成我们的任务。它创建了五条多线和一个几何体光标,作为缓冲运算符的输入。第一条多线的缓冲距离为120米,其余多线的缓冲距离为50米。空间参考是NAD_1983_2011_UTM_Zone_13N,所以距离单位是米。

package com.huitian.esri.geometry.demo.operations.other;import com.esri.core.geometry.*;import java.util.ArrayList;
import java.util.List;/*** Copyright (C), 2017-2020, 云南慧天** @Description:* @Author: YangZhi* @Date: 2020/10/29 8:57* @History: <author>          <time>          <version>          <desc>* 作者姓名           修改时间           版本号              描述*/
public class OperatorBufferDemo2 {// NAD_1983_2011_UTM_Zone_13Nprivate static final SpatialReference SPATIAL_REFERENCE = SpatialReference.create(102382);public static List<Geometry> createAllPolylines() {List<Geometry> geomList = new ArrayList<>(5);double coords[][] = {{-11686713,4828005},{-11687175,4828005},{-11687337,4827898},{-11687461,4828009},{-11687461,4828250},{-11687421,4828250},{-11687305,4828331},{-11687143,4828237},{-11686716,4828237},{-11686713,4828237},{-11686713,4828005}};geomList.add(createPolyline(coords));double coords2[][] = {{-11686998,4828712},{-11686998,4828240}};geomList.add(createPolyline(coords2));coords2[0][0] = -11686998;coords2[0][1] = 4828001;coords2[1][0] = -11686998;coords2[1][1] = 4827533;geomList.add(createPolyline(coords2));coords2[0][0] = -11687848;coords2[0][1] = 4828618;coords2[1][0] = -11687480;coords2[1][1] = 4828251;geomList.add(createPolyline(coords2));coords2[0][0] = -11688017;coords2[0][1] = 4828250;coords2[1][0] = -11687461;coords2[1][1] = 4828250;geomList.add(createPolyline(coords2));return geomList;}public static Polyline createPolyline(double[][] pts) {Polyline polyline = new Polyline();polyline.startPath(pts[0][0], pts[0][1]);for (int i = 1; i < pts.length; i++) {polyline.lineTo(pts[i][0], pts[i][1]);}return polyline;}public static void printResult(Geometry geometry) {String jsonString = OperatorExportToGeoJson.local().execute(SPATIAL_REFERENCE, geometry);System.out.println(jsonString);System.out.println();}public static void main(String[] args) {// 创建要缓冲的输入多线List<Geometry> geomList = createAllPolylines();// 从多条线的列表中创建几何体游标SimpleGeometryCursor inputGeoms = new SimpleGeometryCursor(geomList);// 缓冲第一条极线的距离=120,其余的距离=50double distances[] = {120, 50};// 缓冲几何图形。不要联合结果。GeometryCursor outputGeoms = OperatorBuffer.local().execute(inputGeoms, SPATIAL_REFERENCE, distances, false, null);// 从游标中获取几何图形并以JSON格式打印。Geometry geom = null;while((geom = outputGeoms.next()) != null) {printResult(geom);}}
}

下面显示了生成的输入几何图形和缓冲多边形。

Esri-Geometry-Api-Java 笔记相关推荐

  1. Java笔记07-List、Set、数据结构、Collections

    Java笔记07-List.Set.数据结构.Collections 主要内容 数据结构 List集合 Set集合 Collections 第一章 数据结构 2.1 数据结构有什么用? 当你用着jav ...

  2. Java笔记05-Collection、泛型、迭代器

    Java笔记05-Collection.泛型.迭代器 [Collection.泛型] 主要内容 Collection集合 迭代器 增强for 泛型 第一章 Collection集合 1.1 集合概述 ...

  3. Java笔记04-核心类库

    Java笔记04-核心类库 Object类 1.1 常用的包 java.lang包 -该包是Java语言中的核心包,该包中的内容由Java虚拟机自动导入 如:String类,System类等java. ...

  4. 【Java笔记+踩坑】SpringBoot基础3——开发。热部署+配置高级+整合NoSQL/缓存/任务/邮件/监控

      导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...

  5. 【Java笔记+踩坑】SpringBoot基础2——运维实用

      导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...

  6. 常用API类方法笔记整理1

    常用API类方法笔记整理1 1.文档注释 文档注释是功能级注释,用来说明一个类,一个方法或一个常量的,因此只在上述三个地方使用. 文档注释可以使用java自带的命令javadoc来对这个类生成手册. ...

  7. Java 笔记 # 一

    *本系列文章为<Java语言程序设计>必修课笔记. 教材 教材 王素琴,<Java语言程序设计实用教程>,中国电力出版社 参考书 肖波,<Java语言程序设计>,清 ...

  8. java 笔记 pdf_JAVA笔记完整版.pdf

    JAVA笔记完整版 1.Basic Linux 操作 1)Linux 是模仿UNIX 的操作系统, 是山寨版的Unix 2)Linux 命令 pwd 打印当前工作目录 cd 改变工作目录 ls 显示目 ...

  9. 【Java笔记+踩坑】SpringBoot——基础

      导航: [黑马Java笔记+踩坑汇总]JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud/SpringCloudAlibaba+黑马旅游+谷粒商城 目录 ...

  10. java笔记1/3 (B站hsp学java)

    JAVA基础 文章目录 JAVA基础 变量 整形(INT) 浮点型(float/double) 字符型(char) 布尔类型(boolean) 基础数据类型的转换 自动类型转换 强制类型转换 重载 可 ...

最新文章

  1. MySQL 8.0 新特性之统计直方图
  2. yolo_model to output理解
  3. VBScript教程-第一章. 脚本的定义和术语
  4. 如何处理高并发写入mysql_如何处理高并发情况下的DB插入
  5. 库洛游戏首次公开分享:《战双帕弥什》的动作打击感是怎么做出来的
  6. CCF NOI1029 信息加密
  7. 【转】Go Micro(2)——微服务工具箱
  8. 【分治】LeetCode 69. Sqrt(x)
  9. Bing API 将新增 Bing 空间数据服务
  10. 基于springBoot的薪资管理系统
  11. [蓝桥杯Python]:跑步训练----小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一-或月初,小蓝也是跑2千米。小蓝
  12. Go语言——cap函数详解
  13. python手机端如何下载_过去,哔哩哔哩上面的视频只能在手机上面下载;现在,我用Python爬虫实现了能在PC端上面下载...
  14. error:jump to case label [-fpermissive]
  15. 把苦难的时光删去:从小县城售货员到深圳IT白领的蜕变之路
  16. Multisim基础 利用示波器观察二极管的正向电压
  17. Liunx本地Yum源配置
  18. GO 发送邮件,官方连包都帮我们写好了
  19. ios6应用运行在ios7系统上
  20. 泰勒展开式求sin(x)

热门文章

  1. 网络营销不是收费删帖:为网络营销正本清源
  2. 字节、字、位、比特的关系
  3. Python爬取微信好友的信息
  4. GitHub最有毒的仓库
  5. K8S与Vault集成,进行Secret管理
  6. 挑战GPT-3以色列推出参数多30亿、词条多5倍的新语言模型
  7. PUMA 560 机器人构型总结
  8. Flash/Flex/AIR:Flex简介
  9. 无人机数据处理工作站完美配置方案
  10. spring boot接入微信小程序支付流程