JTS拓扑套件
开发人员指南
1.4版
文件变更控制
修订号
发行日期
作者
变更简述
1.4 2003年10月17日 乔纳森·阿基诺 为JTS 1.4创建的初稿
目录
目录
JTS拓扑套件 1
开发人员指南 1
1.概述
1.1 其他资源
2. 开始
3. 计算空间关系
4. 计算重叠操作
5. 计算缓冲区
5.1 基本缓冲
5.2 端点样式
5.3 指定近似量化
6. 多边形化
7. 合并一组线串 10
8. 使用自定义坐标序列
9. 技巧和技巧
7.1 线的节点化
10.高效合并多边形
1.概述
JTS拓扑套件是一个Java API,它使用明确的高精度模型和稳健的几何算法实现了一组核心空间数据操作。它为二维平面几何提供了一个完整的模型。计算几何和空间数据处理中的许多常见操作都清晰、一致的集成到公开的API中。JTS旨在为空间数据提供验证、清洗、集成和查询处理。
本文档适用于希望使用JTS来满足其空间数据处理需求的开发人员。它描述了JTS API的常见用法,并给出了代码示例。
1.1其他资源
SQLRevision1.1的OpenGIS简化功能说明(请参阅本文档中的sSFS)。JTS实现的空间数据模型、空间谓词和函数的参考规范。
JTS技术规范。JTS拓扑套件中实现的类、方法和算法的设计规范。
JTS JavaDoc。JTS中所有包、类和方法的文档。
2.开始
最常见的JTS任务涉及创建和使用几何体对象。手工创建几何体的最简单方法是使用WKTReader从已知文本(WKT)字符串生成几何体。例如:
Geometry g1 = new WKTReader().read("LINESTRING (0 0, 10 10, 20 20)");
JTS技术规范中给出了WKT的精确规范。在测试目录中的文件中可以找到许多WKT的示例。
在实际程序中,使用GeometryFactory更容易,因为您不需要构建WKT字符串;相反,您可以直接使用对象:
```csharp
Coordinate[] coordinates = new Coordinate[] {
new Coordinate(0, 0), new Coordinate(10, 10), new Coordinate(20, 20) };
Geometry g1 = new GeometryFactory().createLineString(coordinates);
一旦你制作了几何图形,你可以用它做很多事情。你可以很容易地找到两个几何图形的交集:
```csharp
Geometry g3 = g1.intersection(g2);
几何中内置的其他计算包括:面积、外包矩形、质心和缓冲区。有关Geometry可以做什么的更多信息,请参阅com.vividsolutions.jts.geom包中的JavaDoc For Geometry,以及本文档中的后续部分。
3.计算空间关系
JTS的一个重要应用是计算几何体之间的空间关系。提供了计算关系的各种方法。JTS遵循OGC指定的维度扩展9交集矩阵模型。要计算两个几何图形的DE-9IM,请使用相关方法:
Geometry a = . . . Geometry b = . . .
IntersectionMatrix m = a.relate(b);
大多数几何关系可以指定为一组相交矩阵的操作模式。JTS还提供了一组布尔谓词,这些谓词直接计算公共空间关系。这些是:
方法 含义
相等 几何图形在拓扑上是相等的
分离 几何图形没有共同点
交叉点 几何图形至少有一个共同点
相接 几何图形至少有一个共同的边界点,但没有内部点
交叉 几何图形共享一些但不是所有内部点,并且相交的尺寸小于至少一个几何图形的尺寸。
在内部 几何体A位于几何体B的内部
包含 几何体B位于几何体A的内部
重叠 几何图形共享一些但不是所有的公共点,交叉点与几何图形本身具有相同的尺寸
在某些情况下,谓词的精确定义是微妙的。您应该参考JTS技术规范,以确定在任何给定情况下将返回的确切内容。
4.计算重叠操作
上一节讨论了返回true或false的函数,如相交和包含。我们现在将介绍JTS覆盖操作,其中一些操作如下图4-1所示。
图4-1–叠加操作
覆盖操作的说明如下表所示。
方法 意思
缓冲 包含几何体指定距离内的所有点的多边形或多重多边形。有关更多信息,请参阅第7页的5个计算缓冲区。
凸包 包含几何体中所有点的最小凸多边形。
交叉 两个几何A和B的交点是位于A和B中的所有点的集合。
并 两个几何A和B的并集是位于A中的所有点的集合
或B。
差别 两个几何A和B之间的差是位于A中但不位于B中的所有点的集合。
SymDifference 两个几何体A和B的对称差是位于A或B中的所有点的集合,而不是位于两者中。
与上一节中描述的空间关系一样,这些叠加操作在JTS技术规范中给出了精确的定义。
5.计算缓冲区
在GIS中,缓冲是一种操作,在GIS中用于计算包含几何图形给定距离内所有点的区域。用数学术语来说,这被称为计算半径等于缓冲距离的圆盘的几何体的闵可夫斯基和。寻找正缓冲区和负缓冲区有时被称为侵蚀和扩张操作。在CAD/CAM中,缓冲曲线被称为偏移曲线。
您可以使用JTS使用Geometry缓冲区方法或BufferOp类来计算Geometry的缓冲区。缓冲区操作的输入Geometry可以是任何类型(包括任意GeometryCollection)。缓冲区操作的结果始终是区域类型(多边形或多重多边形)。结果可能为空(例如,LineString的负缓冲区)。
可以同时计算具有正缓冲区距离和逆缓冲区距离的缓冲区。缓冲区距离为正的缓冲区始终包含输入几何体。缓冲区距离为负的缓冲区始终包含在输入几何体中。LineStringor点的负缓冲区会成为一个空的几何。
图5-1——正和逆缓冲
还支持缓冲区距离为0。可以使用此操作来执行多个多边形的有效并集。
5.1基本缓冲
要计算给定距离的缓冲区,请在Geometry上调用buffer()方法:
Geometry g = . . .
Geometry buffer = g.buffer(100.0);
5.2端点样式
缓冲区多边形可以使用不同的端点样式进行计算。端点样式确定缓冲多边形的线条在字符串末端的构造方式。支持以下不同类型的端点样式:
下图说明了指定不同端盖样式的效果:
图5-2-不同端盖样式
要指定缓冲区端盖样式,请使用包中的BufferOp类
com.vividsolutions.jts.operation.bufferis直接使用:
Geometry g = . . .
BufferOp bufOp = new BufferOp(g); bufOp.setEndCapStyle(BufferOp.CAP_BUTT);
Geometry buffer = bufOp.getResultGeometry(distance);
5.3指定近似量化
由于几何体的精确缓冲区轮廓通常包含圆形截面,因此缓冲区必须由JTS支持的线性几何体近似。近似程度可以由用户控制。在JTS中,这是通过指定用于近似四分之一圆的象限段的数量来实现的。指定更多的线段可以更好地近似实际面积,但也会在计算的多边形中产生更多的线段。
要指定象限线段的值,请将“几何体”缓冲方法与第二个参数一起使用:
Geometry g = . . .
Geometry buffer = g.buffer(100.0, 16);
分段的默认数量为8。这在计算的曲线近似到实际缓冲曲线的距离上给出了小于2%的最大误差。通过使用值12,该误差可以减少到小于1%。下图显示了增加近似曲线分段数量的效果。
Quadrant Segments = 3 Quadrant Segments =8 Quadrant Segments = 20
图5-3-使用不同的曲线近似水平
6.POLYGONIZATION
多边形化是由包围区域的线形成多边形的过程。要形成多边形的线必须完全有节点——也就是说,线串不能交叉,只能在端点处相接。
JTS提供了Polygonizer类来执行多边形化。多边形化器采用一组完全节点化的LineStrings,并形成由线包围的所有多边形。
可以识别和报告多边形化错误,如悬挂线或切割线。
Collection lines = new ArrayList();
lines.add(read("LINESTRING (0 0 ,1010)")); // 隔离边线
lines.add(read("LINESTRING (185 221,100100)")); //悬挂边线
lines.add(read(“LINESTRING(185 221、88 275、180 316)”);
lines.add(read(“LINESTRING(185 221、292 281、180 316)”);
lines.add(read(“LINESTRING(189 98、83 187、185 221)”);
lines.add(read(“LINESTRING(189 98325 168185 221)”);
polygonizer.add(lines);
Collectionpolys = polygonizer.getPolygons(); Collection dangles = polygonizer.getDangles(); Collectioncuts =polygonizer.getCutEdges();
如果未正确地对线集合进行节点化,多边形化工具仍将对其进行操作,但生成的多边形几何体将无效。多线并集技术可用于对一组多线进行节点连接(请参见第11页9.1“对一组多线进行节点连接”)。
Input–一组完全节点的LineStrings 输出–多边形、悬挂线和剪切线
图6-1-多边形化操作
7.合并一组线串
有时,诸如#union之类的空间操作会产生小的LineStrings链。JTS LineMerger is是一个简单的实用程序,可以将这些小的LineStrings缝合在一起,如下所示。
Input–一组完全节点的LineStrings 输出-合并的字符串
图7-1-线路合并操作
LineMerger假设输入的线串是有节点的(即它们不交叉;只有它们的端点可以接触。请参阅第11页的9.1 Noding A Set Of LineStrings)。请注意,输出LineStrings也是节点化的。
如果要合并的多线的方向不相同,则合并后的结果线的方向按照多数线的方向。
LineMergeris使用如下:
LineMerger lineMerger = new LineMerger(); Collection lineStrings = . . . lineMerger.add(lineStrings);
Collection mergedLineStrings = lineMerger.getMergedLineStrings();
8.使用自定义坐标序列
默认情况下,JTS使用坐标数组来表示几何图形的点和线。在某些情况下,您可能希望几何体使用其他实现来存储它们的点。例如,为了节省内存,您可能需要使用更紧凑的数组实现,例如x的数组和y的数组。另一种可能性是使用自定义坐标类来存储每个坐标的额外信息,例如线性引用的度量。
您可以通过实现CoordinateSequence和CoordinateSequenceFactory接口来实现这一点。然后,您将创建一个由CoordinateSequenceFactory参数化的GeometryFactory,并使用此GeometryFactory来创建新的Geometry。所有这些新的几何图形都将使用您的CoordinateSequence实现。
有关示例,请参阅
com.vividsolutions.jtsexample.geom包:
扩展坐标示例 使用向基本坐标表示添加信息的示例
两个坐标数组示例 使用更高效内存的示例
序列实现
关于性能的注意事项:如果您的CoordinateSequence不是基于标准JTS坐标的数组(或Coordinate的子类),则可能会导致较小的性能损失。这是由于JTS将用户坐标转换为JTS坐标数组所需的编组和解编组。
9.技巧和技巧
线的节点化
许多空间操作都假设它们的输入数据是节点形式的,这意味着LineStrings永远不会交叉。例如,前面描述的JTS Polygonizer和JTS LineMerger假设它们的输入是节点形式的线。
noding过程将相交的LineStrings拆分为在某个点或节点相交的较小LineStrings,如下所示。
未节点(3个字符串) Noded(9个字符串)
图9-1——节点前后
对一组LineStrings进行节点化的一个简单技巧是将它们联合在一起。事实证明,统一过程将为我们对LineStrings进行节点化。例如,以下代码将对一个LineStrings集合进行节点化:
Collection lineStrings = . . .
Geometry nodedLineStrings=(LineString)lineStrings.get(0);for(int i=1;i<lineStrings.size();i++){
nodedLineStrings=nodedLineStrings.union((LineString)lineStrings.get(i));
}
10.高效合并多边形
重复调用Polygon 并集是将多个多边形并集在一起的一种方法。但这里有一个技巧可以更快(秒而不是分钟)——将多边形添加到GeometryCollection,然后应用零距离的缓冲区:
Polygon[] polygons = . . . GeometryCollection polygonCollection =
geometryFactory.createGeometryCollection(polygons); Geometry union = polygonCollection.buffer(0);