JTS Technical Specs翻译

JTS拓扑套件

技术规范

1.4版

文件变更控制

修订号

发行日期

作者

变更简述

1.3

2003年3月31日

M.Davis

更新以涵盖JTS 1.3中的更改

1.4

2003年10月17日

J.阿基诺

坐标顺序和用户数据字段

1.4.1

M Davis

  • 包含的确定定义

目录

目录

JTS拓扑套件 1

1.4版 1

文件变更控制 2

4. 术语 7

5. 记数法 7

6. java实现 7

7. 计算几何问题 8

7.1 精密模型 8

7.1.1 固定精度 8

7.1.2 浮动精度 9

7.2 构造点和尺寸折叠 9

7.3 稳健性 10

7.4 数字稳定性 10

7.5 计算性能 11

7.5.1 单调链 11

8. 空间模型 12

8.1 空间模型的设计决策 12

8.2 几何定义 13

8.2.1 几何 14

8.2.2 空几何体 14

8.2.3 几何集合 14

8.2.4 曲线 14

8.2.5 多曲线 14

8.2.6 字符串 15

8.2.7 线环 15

8.2.8 多边形 15

8.2.9 多面 18

8.3 简单要素类 18

8.3.1 Geometry 18

8.3.2 GeometryCollection 18

8.3.3 点 18

8.3.4 多点 18

8.3.5 Curve 18

8.3.6 LineString 18

8.3.7 线 18

8.3.8 LinearRing 18

8.3.9 MultiCurve 18

8.3.10 线集合 18

8.3.11 表面 18

8.3.12 Polygon 18

8.3.13 多面 19

8.3.14 MultiPolygon 19

8.4 几何的标准形式 19

8.5 支持类 19

8.5.1 坐标 19

8.5.2 坐标序列 20

8.5.3 外包矩形 20

8.5.4 交集矩阵 20

8.5.5 GeometryFactory 20

8.5.6 坐标过滤器 20

8.5.7 几何过滤器 20

8.6 空间参考系 20

9. BASIC GEOMETRIC ALGORITHMS ANDSTRUCTURES 21

9.1 点线方向测试 21

9.2 线路交叉试验 21

9.3 线交叉计算 21

9.4 环内点试验 22

9.5 RING ORIENTATIONTEST 22

10. 地形计算 22

10.1 拓扑图 22

10.2 标签 22

10.3 由ALABELING求交矩阵 23

10.4 关联算法 24

10.4.1 标记隔离组件 24

10.5 叠加算法 24

11. 二进制谓词 25

11.1 一般讨论 25

11.2 方法规范 26

11.2.1 相等 26

11.2.2 分离 26

11.2.3 交叉点 26

11.2.4 相接 26

11.2.5 交叉 27

11.2.6 在内部 27

11.2.7 包含 27

11.2.8 重叠 27

12. 空间分析方法 27

12.1 一般讨论 27

1.1.1计算几何图形的表示 27

12.2 CONSTRUCTIVE METHODS 28

12.3 集合理论方法 28

12.4 方法规范 29

12.4.1 缓冲 29

12.4.2 凸包 31

12.4.3 交叉 31

12.4.4 并 31

12.4.5 差别 31

12.4.6 对称差集 31

13. 其他方法 31

13.1.1 边界 31

13.1.2 IsClosed 32

13.1.3 IsSimple 32

13.1.4 IsValid 33

14. 众所周知的文本输入/输出 33

14.1 熟知文本的语法 34

14.2 知名文本阅读器 35

14.3 知名文本编写器 35

15. 参考文献 36

1. OVERVIEW

JTS拓扑套件是一个Java API,它使用明确的精度模型和稳健的几何算法来实现一组核心空间数据操作。JTS旨在用于开发支持空间数据集验证、清理、集成和查询的应用程序。本文档是JTS拓扑套件中实现的类、方法和算法的设计规范。

JTS试图尽可能准确地实现OpenGIS简单功能规范(SFS)。在某些情况下,SFS不清楚或省略了规范;在这种情况下,JTS试图选择一个合理和一致的替代方案。SFS的差异和详细说明记录在本规范中。

类结构和调用方法的详细文档将以JavaDoc形式提供。

2. OTHER RESOURCES

  • SQL 1.1版OpenGIS简单功能规范(在本文档中称为SFS)。本文档提供了空间数据模型的主规范以及JTS实现的空间谓词和函数的定义。

3. DESIGN GOALS

JTS的设计旨在实现以下目标:

  • 空间模型和方法定义将尽可能准确地符合OpenGIS简单特征规范,并与正确的实现保持一致。
  • API设计将尽可能遵循Java惯例。例如:
    • 访问函数将使用Java getX和setX约定
    • 谓词将使用isX约定
    • 方法将以小写字母开头
  • JTS功能将支持用户定义的精度模型。在该精度模型下,JTS算法将是稳健的。
  • 方法将尽可能在定义的精度模型内返回拓扑和几何正确的结果。
  • 正确性是最高优先级;空间和时间效率是重要的,但却是次要的。
  • JTS将足够快,可以在生产环境中使用。
  • JTS中使用的算法和代码将清晰且结构良好,以便于其他开发人员理解。

术语

在这里插入图片描述

记数法

  • 规范中与SFS相关的项目通过参考括号中SFS的相关章节来表示:(SFS1.0)
  • 规范中详细说明SFS或与SFS不同的项目将用括号中的术语“JTS”表示:(JTS)

java实现

Java编码风格在某些情况下与SFS中使用的编码风格不同。两者在一般情况下不同的地方,JTS遵循Java约定。JTS编码风格与SFS编码风格的不同之处在于:

  • SFS有时使用Integer来表示布尔值。在这种情况下,JTS将使用布尔值
  • SFS中的方法名称以大写字母开头。在JTS中,所有方法名称都以小写选择器开头
  • JTS中的方法名称有时会添加前缀“get”或“set”,以符合JavaBeans的约定。

计算几何问题

精密模型

所有的数值计算都是在某种形式的精度模型下进行的。精度模型有几种可能的类型:
在这里插入图片描述

通常,计算的精度模型没有明确说明,而是由用于表示值(如浮点或整数)的模型隐含。这种方法的局限性在于,用户无法在精度较低的精度模型中工作。通常情况下,计算结果的精度高于输入。对于进一步计算或以具有原始(或较低)精度的格式存储,较高精度值可能是不可接受的。

JTS通过允许用户指定精度模型来处理这个问题。精度模型允许客户端说明在输入坐标值中假设有多少精度位,并在任何计算的坐标中保持。

在JTS方法中,输入几何体可能具有不同的精度模型。在返回Geometry的方法的情况下,返回结果的精度模型是两个输入精度模型(即具有最大精度的模型)中的最大值。请注意,这仅在两个精度模型兼容的情况下有效。如果其中一个的比例因子是另一个比例因子的整数倍,则两个精度模型是兼容的。没有试图调和不兼容的精度模型。

JTS支持两种基本类型的精度模型:固定和浮动。

固定精度

在固定精度模型中,假设坐标正好落在离散网格的交点上。栅格的大小由比例因子决定。栅格大小与比例因子相反。比例因子也可以被认为是决定精度保留了多少小数位。比例因子可以大于或小于1,这取决于“精度点”是在小数点的右边还是左边。

坐标根据以下方程式精确计算:

jtsPt.x = round( inputPt.x * scale ) / scale jtsPt.y = round( inputPt.y * scale ) / scale

精确坐标将在内部表示为双精度值。这被称为“精确的内部表示”。由于Java使用IEEE-754浮点标准,因此它提供了53位的精度。(因此,可精确表示的最大值为9007199254740992)。

输入例程负责在创建JTS结构之前将坐标舍入到精度模型。(JTS提供的输入例程将自动执行此舍入。)

浮动精度

支持两种类型的浮动精度模型,双精度和单精度。这两者都基于Java浮点模型,而Java浮点模型又基于IEEE-754浮点标准。这为双精度提供了大约16位精度,为单精度提供了6位精度。

在浮动双精度模型中,坐标可以具有Java双精度浮点数可用的全精度。输入坐标不会被假定为四舍五入,并且计算构造点的内部操作不会对计算的坐标进行四舍五舍五入。请注意,这并不意味着构建的点是精确的;它们仍然局限于双精度数字的精度,因此可能仍然只是精确点的近似值。

在浮动单精度模型中,计算的坐标四舍五入为单精度。这支持计算几何体的最终目的地是单精度格式(例如Java2D)的情况。

构造点和尺寸折叠

通过空间分析方法计算的几何图形可以包含输入几何图形中不存在的构造点。这些新点产生于输入几何体边缘中线段之间的交点。在一般情况下,不可能精确地表示构造点。这是由于交点的坐标可能包含的精度位是输入线段坐标的两倍。为了显式地表示这些构造点,JTS必须将它们四舍五入以适合给定的精度模型。

不幸的是,四舍五入的坐标会稍微移动它们。在精确结果中不重合的线段在截断表示中可能会重合。对于直线-直线组合,这可以生成包含不在输入几何图形内部的点的结果几何图形。更严重的是,对于“线-面积”组合,这可能会导致尺寸塌陷,这种情况下,计算的零部件的尺寸低于其在精确结果中的尺寸。

1 unit

__Figure 1-维度坍缩示例__

JTS通过形成由坍缩产生的较低维度几何体,尽可能优雅地处理维度坍缩。例如,具有标注折叠的“面积-面积”相交将返回一个“线”或“点几何图形”作为结果的组成部分。

稳健性

几何算法包括组合计算和数值计算的结合。与所有使用有限精度数字的数值计算一样,所选择的算法容易受到稳健性问题的影响。当数值计算由于舍入误差而产生不精确的答案时,就会出现稳健性问题。鲁棒性问题在几何计算中尤其严重,因为数值误差会传播到组合计算中,导致算法完全失败。

处理几何计算中的鲁棒性问题有很多方法。毫不奇怪,大多数鲁棒算法比非鲁棒版本复杂得多,性能也较差。JTS试图通过两种方式来处理稳健性问题:

  • 重要的基本几何算法(如线方向、线交点和多边形中的点测试)已经使用鲁棒算法实现。特别是,几种算法的实现依赖于[Ava97]中提出的稳健行列式评估。
  • 已经开发了用于实现SFS谓词和函数的算法,以消除或最小化鲁棒性问题。二进制谓词算法是完全鲁棒的。空间叠加和缓冲算法是不健壮的,但在大多数情况下都会返回正确的答案。

数字稳定性

数值算法的一个可取特征是它们表现出稳定性。数值算法的稳定性取决于其输出中最大误差的界。如果这个界很小,则认为算法是稳定的。

JTS中使用的主要数值算法是计算两段之间的交点。该算法本质上是不精确的,因为表示交点所需的精度比特是输入精度的几倍。这种计算的稳定算法总是会产生接近确切答案的近似答案。特别是,计算的点应该至少位于输入线段的边界框内!理想情况下,计算出的点将位于精确答案的单一精度模型网格单元内。

提高数值算法稳定性的一种方法是对其输入进行调节。调节输入涉及以某种方式对其进行数字操作,从而产生

相同的答案,同时在计算过程中保持更高的精度。JTS使用了一种将输入线段“标准化”到线交点计算的技术。规格化线段已被转换为尽可能靠近原点。这具有从每个纵坐标中去除公共有效数字的效果,从而增加了可用于保持线交点计算精度的精度位。

计算性能

运行时性能是几何算法的生产质量实现的重要考虑因素。JTS中使用的计算量最大的算法是交叉点检测。许多JTS方法需要确定单个几何体中线段之间的所有交点(自交点)和两个不同几何体的线段之间的全部交点。

交叉点检测的算法,即将每个路段相互比较,其性能慢得令人无法接受。有大量关于交叉点检测的有效算法的文献。不幸的是,其中许多都涉及相当复杂的代码。JTS试图在代码简单性和性能提升之间取得平衡。它使用一些特殊的技术来为常见类型的输入数据带来显著的性能提升。这些技术包括各种类型的内存空间索引,以及复杂的数据结构化方法,如单调链技术。

单调链

JTS使用“单调链”技术,以最小的额外代码复杂性获得实质性的性能改进。这种技术包括将边划分为单调的线段链。单调链由一系列线段组成,这些线段的方向向量都位于同一象限。单调链具有两个重要性质:

不相交特性:单调链中的线段不相交。

端点凸包性质:单调链中线段的任何连续子集的凸包都是该子集端点的凸包。

不相交属性意味着不需要测试来自同一单调链中的线段对的相交。端点和最小外包矩形属性允许使用二进制搜索来查找单调链上的交点。此外,相对于单个分段,单调链的较大边界框充当分段的“聚类”形式,这减少了所需的交集测试的总数。

对于具有显著百分比单调链的数据,这些特性消除了大量的分段比较。单调链在通过自然特征流数字化生成的数据中很常见。已经观察到性能比原始算法提高了多达100倍。

(1)

多边形的单调链

(1)

用于寻找两个单调链之间交集的平分过程

图2-单调链

空间模型

空间模型的设计决策

SFS只是现有空间数据库和API中使用的几个空间模型之一。这些模型在很大程度上非常相似。通常,它们都支持表示二维点、线和多边形。然而,几何图形的表示方式之间存在一些细微的差异。这些差异代表了空间API的设计者所做的设计决策。以下列出了一些重要的设计选择(在每种情况下,都指出了SFS和JTS中的选择)。

设计决策

几何图形中允许的重复点

SFS选择

允许重复点

JTS选择

与SFS相同

评论

一般来说,空间算法不能容忍重复点。允许重复点会导致性能和空间损失,因为每个空间方法都必须检查重复点并将其删除。JTS确实支持重复点,因为不这样做是与OGC模型不兼容的主要原因。然而

这样做的内存和性能成本。

Design Decision

允许自相交的字符串(即可以是非简单的)

SFS Choice

允许字符串自相交

JTS的选择

与SFS相同

注释

允许使用非简单的线串会带来很小的性能损失,因为这意味着在空间方法中使用行字符串之前必须对其进行节点化。但是,最好能够表示非简单的行字符串,因此如果线串类本身被定义为

简单,必须引入另一个类来表示非简单线(有时称为“意大利面条”)。

Design Decision

多边形环可以在单个点上自接触。

SFS Choice

多边形环不能在单个点上自接触

JTS选择

与SFS相同

注释

这一决定源于需要支持表示包含在单个点接触外壳的孔的多边形(“倒置”多边形)。它还涵盖了表示单个孔的情况,该孔包含断开连接的外部区域(“外倾”孔)。为了表示倒多边形和外凸孔,必须允许多边形环在一个点上自接触,或者必须允许环在单个点上相互接触。

这种设计决策是一种选择多边形环是否可以在单点相互接触的双重意义

不幸的是,选择多边形环不能自接触会导致算法稍微复杂一些,因为通常的多边形构建算法会导致外壳自接触。是的

需要执行进一步的步骤以将通过自触摸隔离的区域的边界转换成孔。

Design Decision

多边形环可以在单个点上相互接触

SFS选择

多边形环可以在单个点上相互接触

JTS选择

与SFS相同

注释

这个设计决策是关于多边形环是否可以在单点自接触的决策的对偶。

在大多数情况下,这些设计选择对API的用户没有任何影响,因为它们不会更改可以表示的几何图形集。然而,它们确实对API中实现的算法的性能和复杂性有影响。此外,在做出不同设计选择的两个API的表示之间转换通常是不平凡的(特别是,如果两个API对多边形环是否可以自接触做出不同的选择,则需要一些相对复杂的处理来转换多边形表示)。

几何定义

根据SFS中给出的定义,所有JTS方法都假设其自变量是有效的几何对象。

以下定义详细说明或澄清SFS中给出的定义。

几何

精度模型对象将是每个几何体对象的成员。

根据SFS几何体,对象只能表示闭集。这是一个合理的决定,可以实际执行。然而,空间分析方法的语义也有一些含义(见第12节“空间分析方法”)。

JTS有一个向Geometry添加属性的简单方案:应用程序可以将Geometry的用户数据字段设置为任何对象。

空几何体

SFS规定每个Geometry子类的对象可以为空。有时有必要构造类Geometry的通用空对象(例如,如果要返回的几何体的确切类型未知)。SFS未定义特定类别或对象来表示该通用空几何体。JTS使用的约定是,将返回一个空的GeometryCollection。

几何集合

异构几何集合的维度是其元素的最大维度。

曲线

曲线可能不会退化。也就是说,非空曲线必须至少有2个点,并且没有两个连续点可以相等。

多曲线

SFS规定使用“Mod-2”规则来确定多曲线的边界。一个点在多曲线的边界上,当它在多曲线奇数个元素的边界上时。应该注意的是,这导致SFS边界中的点集大于直觉或点集拓扑所指示的情况。也就是说,根据SFS规则,入射到其上的边缘数为奇数>1的点在边界上,但可能不会直观地被视为边界的一部分。这也与边界的拓扑定义不一致,即“不包含在几何中点集的任何开子集中的点集”。

例如,在图3(3)中,根据SFS,点B在边界中,但根据点集拓扑,点B是内部点。

图3-多字符串中Mod-2规则的影响

JTS中需要额外的逻辑来实现Mod-2规则。

字符串

我们正在使用OGC SFS中给出的线串的定义。这在很大程度上不同于其他一些空间模型(例如ESRI ArcSDE使用的模型)。不同之处在于线串可能并不简单。它们可以在点或线段中自相交。

事实上,曲线的边界点(例如端点)可能与曲线内部相交,导致曲线在技术上拓扑闭合,但根据SFS不闭合。在这种情况下,拓扑上的交点不会在曲线的边界上。但是,根据SFS的定义,该点被认为在边界上。JTS遵循SFS的定义。

图4-边界点与内部点相交的字符串

线环

LinearRings是多边形的基本构建块。LinearRings可能不是退化的;也就是说,LinearRing必须至少有3个点。LinearRings是简单的要求隐含了其他的非退化性准则。例如,并非所有的点都可以共线,并且环可能不会自相交。SFS未规定对LinearRing方向的要求。JTS通过允许LinearRings顺时针或逆时针定向来遵循这一点。

多边形

多边形的外壳和孔是线环。SFS对多边形的定义具有以下含义:

  • 壳和孔不能自相交(这是因为它们是LinearRings)
  • 孔只能在一个点接触外边界或另一个孔。这意味着孔不能在多个点或一条线段上相互相交。
  • 多边形内部必须连接(这是前面的语句所暗示的)。
  • 没有要求洞与外壳接触的点是 一个节点

请注意,SFS对多边形的定义与其他一些常用空间模型中的定义不同。例如,ESRI ArcSDE空间模型允许壳在顶点处自相交,但不允许孔接触壳。SFS和ArcSDE模型是等效的,因为它们完全描述了同一组区域。然而,它们可能需要不同的多边形结构来描述相同的区域。

在这里插入图片描述

空多边形可能不包含孔。

由于多边形的壳和孔是线环,因此对它们的方向没有要求。它们可以是顺时针方向或逆时针方向。

多面

MultiPolygon中的元素Polygons可能只在有限数量的点上接触(例如,它们可能不会在线段中接触)。元素的内部必须是不相交的(例如,它们可能不会相交)。没有要求交点是顶点。

简单要素类

所有Geometry类都允许创建空对象,并支持isEmpty方法。空几何体将由其内部数组表示,该数组的长度为零。

所有Geometry类都支持equalsExact()方法,如果两个Geometry子类等价并且具有相同的坐标序列,则该方法返回true。如果两个对象的类相同,则它们是“等价的”。唯一的例外是LinearRing和LineString,JTS认为它们是等价的。

所有Geometry类都支持clone()方法,该方法将返回对象的深度副本。

Geometry

几何是不可实例化的,是作为一个抽象类实现的。

GeometryCollection

GeometryCollection被实现为一组Geometry对象。

点被实现为单个坐标。

多点

MultiPoint继承GeometryCollection的实现,但仅包含点。

Curve

曲线是不可实例化的,并且是作为接口实现的。

LineString

线串被实现为一个坐标数组。

线

JTS不实现Line类,因为LineString提供了等效的功能。

LinearRing

包含n个坐标的LinearRing由包含n+1个点的坐标数组实现,coord[0]=coord[n]。

MultiCurve

MultiCurve是不可实例化的,并且是作为接口实现的。

线集合

MultiLineString继承GeometryCollection的实现,但仅包含LineStrings。

表面

面是不可实例化的,并且是作为接口实现的。

Polygon

多边形被实现为外壳的单个LinearRing和孔的LinearRings阵列。外壳的方向为CW,孔的方向为CCW。

多面

MultiSurface是不可实例化的,并且是作为接口实现的。

MultiPolygon

MultiPolygon继承GeometryCollection的实现,但仅包含多边形。

几何的标准形式

JTS定义了用于表示几何图形的标准(或规范)形式。法线形式是Geometry的唯一表示形式。它可以用来测试两个几何体是否相等,而不依赖于其中坐标的顺序。范式等式是一个比拓扑等式更强的条件,但比逐点等式更弱。

正规形式的定义使用坐标的标准字典排序。“按坐标顺序排序”是指这种排序对坐标序列的明显扩展。

几何图形类

范式的定义

指向

点始终处于正常形式

多点

点元素按其坐标顺序排序

线串

遵守以下条件:

如果有一个i这样的coord[i]!=coord[n–i–1]然后coord[i]<coord[n-i–1]

LinearRing

与LineString相同

MultiLineString

元素线串为正常形式,按其坐标顺序排序

多边形

多边形的线最小的点是第一个,多边形的点按顺时针排列

孔按逆时针方向排列。孔按坐标顺序排列

多多边形

多多边形的组成多边形为正常形式,按坐标顺序排列

几何集合

集合的单个几何图形为正常形式。

元素列表按类排序(使用此列表的顺序)。在类的每个子序列中,元素按坐标的顺序进行排序。

支持类

坐标

坐标是用于存储坐标的轻量级类。它不同于点,点是几何的一个子类。与“点”类型的对象(包含其他信息,如包络、精度模型和空间参照系信息)不同,“坐标”仅包含坐标值和访问器方法。

坐标是二维点,带有一个附加的z坐标。JTS不支持z坐标上的任何操作,除了基本的访问器功能。构造的坐标将具有NaN的z坐标。

Coordinate实现了标准的Java接口Comparable。该实现使用通常的字典比较。也就是说,

c1.compareTo(c2) =

c1.compareTo(c2) = -1 : c1.x < c2.x Ú ((c1.x = c2.x) Ù (c1.y < c2.y)) 0 : (c1.x = c2.x) Ù (c1.y = c2.y)

1 : c1.x > c2.x Ú ((c1.x = c2.x) Ù (c1.y > c2.y))

Coordinate使用逐点比较的明显实现来实现equals()。

坐标序列

坐标序列是几何体中坐标列表的内部表示。因为它是一个接口,所以可以创建默认实现(坐标数组)的替代方案。例如,可以选择将数据存储为某个完全不同的坐标类的数组,或者存储为x和y的数组。请注意,当调用toArray方法时,非Coordinate数组实现将付出性能代价。

外包矩形

包含最大值和最小值x和y的具体类。

交集矩阵

维度扩展的9相交模型(DE-9IM)矩阵的实现。该类可用于表示DE-9IM矩阵的实际实例以及用于匹配它们的模式。方法提供给:

  • 以方便的方式设置和查询矩阵的元素
  • 转换为标准字符串表示或从标准字符串表示转换(SFS第2.1.13.2节中规定)。
  • 测试矩阵是否与给定的模式字符串匹配。

GeometryFactory

GeometryFactory提供了一组实用方法,用于从坐标列表中构建几何体对象。

坐标过滤器

GeometryImpl类支持对Geometry中的每个坐标应用坐标过滤器的概念。坐标过滤器可以记录关于每个坐标的信息,也可以以某种方式更改坐标。坐标过滤器实现接口CoordinateFilter。(CoordinateFilter是“GoF”设计模式的一个示例)。坐标滤波器可以用于实现坐标变换、质心和外包矩形计算以及许多其他功能。

几何过滤器

GeometryImpl类支持将Geometry过滤器应用于Geometry的概念。在GeometryCollection子类的情况下,过滤器应用于每个元素Geometry。几何体过滤器可以记录有关几何体的信息,也可以以某种方式更改几何体。几何过滤器实现GeometryFilter接口。(GeometryFilter是“GoF”访问者模式的一个例子。)

空间参考系

JTS将以SFS中定义的简单方式支持空间参考系统信息。空间参考系统ID(SRID)将出现在每个几何体对象中。Geometry将为该字段提供基本的访问器操作,但不提供其他操作。SRID将表示为一个整数。

如果可能的话,构建对象的SRID将从其中一个输入对象的SRID中复制,或者将为0。

BASIC GEOMETRIC ALGORITHMS ANDSTRUCTURES

点线方向测试

该函数是对节点周围的边进行排序等操作的基础。由于它本质上是一种几何计算,因此除非使用鲁棒算法实现,否则很容易出现鲁棒性问题。JTS使用鲁棒算法来实现该方法,该算法为所有输入值返回正确的结果。所使用的算法基于Avanim等人开发的评估行列式符号的稳健方法([Ava97])。

[点线方向图]

线路交叉试验

该函数用于测试两条线段是否相交。它使用上述鲁棒的点-线方向函数。该函数实际上不计算交点,并因此返回一个精确的答案。该函数计算了关于交点拓扑结构的完整信息,包括以下数据:

HasIntersection()

如果线段相交,则为True

getIntersectionNum()

找到的交点数(0、1或2)

IsProper()

如果交点正确(即不等于其中一个端点),则为True

线交叉计算

此函数用于计算两条线段的交点。两条线段可以在一个点、一条线段中相交,也可以根本不相交。如果交叉点可以用精度模型中的坐标表示,则它将被精确计算。否则,将计算近似值。

作为线段的相交将始终用坐标表示,因为相交线段的每个端点必须等于其中一个输入线段的端点。显然,零交叉点也可以精确计算(尽管交叉点测试必须使用稳健的代码才能正确)。作为点的交点可以表示,也可以不表示,因为通常计算的交点需要比输入点更高的精度,并且不一定精确地落在精度模型网格上。

An important property of the line intersection algorithm is that it is numerically stable. Computed approximate points should be within the Precision Model tolerance of the exact intersection point.

除了“直线交点”测试计算的信息外,“直线交点计算”还计算有关实际交点的信息:

GetIntersection(int i)

第I个交点的坐标

确定边缘图需要关于沿着每个线段的交点的精确顺序的进一步信息。Line Intersection类提供了其他函数,用于确定沿每条线段的交点顺序,并计算给定交点沿线段的(近似)距离。

环内点试验

环中点谓词是通过使用常用的插入线算法和使用稳健的线相交测试以稳健的方式实现的。

在某些情况下,有必要测试给定环中多个点的包含关系(例如,在IsValid谓词中测试孔的正确包含性)。在这种情况下,可以通过使用环的线段的空间索引来提高性能。JTS实现了一维区间树,以加速在刺入线算法中进行的相交测试。

RING ORIENTATIONTEST

如果坐标环的方向是顺时针方向,则此测试返回true。该测试用于确定多边形的内部和外部位于多边形的壳环和孔的哪一侧。

地形计算

拓扑图

交集矩阵的计算依赖于一种称为“拓扑图”的结构的使用。拓扑图包含与几何体的节点和线段相对应的节点和边。图中的每个节点和边都标有其相对于源几何体的拓扑位置。

请注意,不要求自交点是顶点。因此,为了获得正确的拓扑图,几何体在构造其图之前必须进行自节点化。

拓扑图支持两种基本操作:

  • 计算单个图的所有边和节点之间的交点
  • 计算两个差分图的边和节点之间的交点

标签

拓扑图支持在图中标记节点和边的概念。节点或边的标签指定其与一个或多个几何图形的拓扑关系。(事实上,由于JTS操作只有两个参数,因此只需要两个几何图形的标签)。节点或边的标签有一个或两个元素,具体取决于节点或边是出现在一个还是两个输入几何体中。元素包含对节点或边相对于父几何体的拓扑位置进行分类的属性;也就是说,节点或边是在几何体的内部、边界还是外部。

属性具有集合{Interior、Boundary、Exterior}中的值。在一个节点中,每个

元素只有一个属性<On>。对于边,每个元素都有一组属性

<左,开,右>。

由ALABELING求交矩阵

通过对图中节点和边的标记计算覆盖图的相交矩阵(IM)。为了计算IM,我们将包含{i}两个{/i}几何图形元素的节点和边的贡献求和。节点的IM贡献为{i}dim >= 0{/i},对应于节点在父几何图形中的拓扑位置的IM条目。(例如,一个节点位于几何图形A的内部并且位于几何图形B的边界上,将会有{i}label[0][On] = Interior{/i},{i}label[1][On] = Boundary{/i},以及{i}IM(Interior, Boundary) = 0{/i})。边的IM贡献为{i}dim >= 1{/i},对应于边本身在父几何图形中的拓扑位置的IM条目,以及{i}dim >= 2{/i},对应于边的左侧和右侧区域的拓扑位置的条目。

这些规则的算法表达式为:

__function __Node.computeIM(im : IntersectionMatrix)

__if __(label[0] != null and label[1] != null) then

im.setAtLeast(label[0][On], label[1][On], 0)

end if end function

__function __Edge.computeIM(im : IntersectionMatrix)

__if __(label[0] != null and label[1] != null) then

im.setAtLeast(label[0][On], label[1][On], 1)

im.setAtLeast(label[0][Left], label[1][Left], 2)

im.setAtLeast(label[0][Right], label[1][Right], 2)

end if end function

对于几何图形的每个组合,都有一个可能的最大IM值。为了效率,可以在每次IM求和之后测试该最大值,并且如果获得该值则终止计算。

dim(Ext(A)nExt(B))=2总是这样。

完整IM是:

2

1

2

F

F

1

F

F

2

关联算法

关联算法计算描述两个几何关系的交集矩阵。计算关联的算法使用拓扑图支持的交集运算。尽管关联结果取决于由计算的交集形成的结果图,但不需要显式计算整个图。相反,图的结构是在每个交叉节点局部计算的。

关联算法是鲁棒的,因为它基于底层操作的鲁棒性。它不会出现维度折叠问题,因为它避免计算可能不在精确坐标上的交点。

计算关联的算法包括以下步骤:

  1. 构建两个输入几何图形的拓扑图。对于每个几何体,所有的自相交节点都会被计算出来并添加到图形中。
  2. 计算图的边和节点之间的所有交点的节点。
  3. 通过合并输入图中的标签来计算计算节点的标签。
  4. 计算图形中孤立组件的标签(见下文)
  5. 根据节点和边上的标签计算交集矩阵。

标记隔离组件

孤立组件是输入几何体的组件(边或节点),不包含与其他输入几何体任何交点。必须计算这些组件与其他输入几何体的拓扑关系,以确定组件的完整标记。这可以通过测试零部件是位于其他几何体的内部还是外部来完成。如果另一个几何体是一维的,则隔离的零部件必须位于外部(因为否则它将与几何体的边相交)。如果另一个几何体是二维的,则可以使用“多边形中的点”测试来确定隔离零部件是在内部还是外部。

叠加算法

叠加算法用于空间分析方法,用于计算输入几何的集合论运算(布尔组合)。用于计算覆盖的算法使用拓扑图支持的交集运算。计算

为了显式计算叠加,明确计算相交的结果是非常必要的。

计算集合论空间分析方法的算法包括以下步骤:

  1. 构建两个输入几何的拓扑图,每个几何的自相交点加入到图上。
  2. 计算图的边和节点中所有相交的节点。
  3. 通过合并输入图的标签来计算已被计算过的节点。
  4. 计算计算交点节点之间的新边。适当地标记边缘
  5. 从新的节点和边构建结果图。
  6. 计算图形的孤立组件的标签。将隔离的组件添加到结果图中。
  7. 通过选择具有适当标签的节点和边,计算布尔组合的结果。将区域多边形化和线性几何合并在一起。

二进制谓词

一般讨论

二进制谓词可以完全按照交集矩阵模式来指定。事实上,它们的实现只是一个与适当模式相关联的调用。

需要注意的是,二进制谓词是拓扑运算,而不是逐点运算。即使对于像Equals这样明显简单的谓词,也很容易发现逐点比较不会产生与拓扑比较相同的结果的情况。(例如:A和B是同一点重复不同次数的多点;A是具有两条共线线段的LineString,B是具有相同起点和终点的单条线段;A和B为具有相同点集但起点不同的环)。用于关联方法的算法是基于拓扑的算法,该算法产生拓扑正确的结果。

图7.两个几何逐点比较不相同,但是拓扑相同。

与SFS中一样,术语P用于表示0维几何(点和多点),L表示1维几何(线串和多线串),A表示2-

维度几何图形(多边形和多重多边形)。GeometryCollection的尺寸等于其组件的最大尺寸。

在SFS中,对于某些维度组合,一些二进制谓词被声明为未定义(例如,对于P/P,触摸是未定义的)。为了简化API,不在谓词域中的参数几何的组合将返回false(例如,触摸(Point,Point)=>false)。

如果谓词的任何一个参数是空的Geometry,则谓词将返回false。

由于目前尚不清楚涉及GeometryCollection的空间分析方法的语义是有用的,因此不支持GeometryCollection作为二进制谓词或related方法的参数。

方法规范

二元谓词被实现为对 relate 的调用,其中为输入几何体提供了适当的模式。大多数二元谓词的规范在 SFS 中有很好的描述,在这里仅通过它们的 relate 模式进行简单的指定。然而,SFS 中没有描述等于(Equals)操作,因此也以符号方式进行指定。

相等

相等关系适用于几何图形的所有组合。两个几何体在拓扑上是相等的,如果它们的内部相交,并且一个几何体的内部或边界没有任何部分与另一个的外部相交。象征性地

a.equals(b) Ü I(a) » I(b) µ ¸ Ù (I(a) ¼ B(a)) » E(b) = ¸ Ù (I(b) ¼ B(b)) » E(a) = ¸ Ü a.relate(b,“T*F**FFF*”)

Equals()是一种拓扑关系,并不意味着几何图形具有相同的点,甚至不意味着它们属于同一类。(这种限制性更强的等式形式是在equalsExact()方法中实现的。)

参数维度

关联模式

全部的

T*F**FFF*

分离

参数维度

关联模式

所有

FF*FF****

交叉点

A.相交(B)=!A.不相交(B)

相接

关联模式

Relate Pattern

P/L、P/A、L/L、L/A、A/A

FT*******

或F**T*****或F***T****

P/P

未定义的

交叉

Argument Dimensions

Relate Pattern

P/L,P/A,L/A

T*T******

升/升

0********

P/P, A/A

undefined

在内部

Argument Dimensions

Relate Pattern

all

T*F**F***

包含

A.包含(B)=B.在(A)内

重叠

参数维度

关联模式

P/P, A/A

T*T***T**

L/L

1*T***T**

P/L, P/A, L/A

未定义

空间分析方法

一般讨论

SFS列出了许多空间分析方法,包括构造运算(缓冲、凸包)和集合论运算(交集、并集、差分、对称差分)。

1.1.1计算几何图形的表示

SFS指出,集合论方法的结果是操作的通常集合论定义的“点集”结果(SFS 3.2.21.1)。然而,有时有许多方法可以将点集表示为aGeometry。

图8-计算几何图形的表示

SFS没有为从空间分析方法返回的点集指定明确的表示。JTS的一个目标是使该规范精确而明确。JTS对从空间分析方法返回的几何体使用规范形式。规范形式是一个简单且有节点的几何:

  • Simple表示根据中的定义,返回的几何体将是简单的

第13.1.3节

  • Noded仅适用于涉及LineStrings的覆盖。这意味着参数LineStrings之间的所有交点都将作为结果中LineStrings的端点出现。

This definition implies that for non-simple geometries which are arguments to spatial analysis methods, a line-dissolve process is performed on them to ensure that the results are simple.

CONSTRUCTIVE METHODS

由于convexHull()方法没有引入任何新的坐标,因此可以保证返回精确正确的结果。由于不可能在JTS中精确地表示曲线弧,buffer()方法返回正确答案的(接近)近似值。

GeometryCollection被支持作为convexHull()方法的参数,但不被buffer()方法支持。

图9-构造性空间分析方法

集合理论方法

空间分析方法将返回最具体的类来表示结果。如果结果是均质的,且只包含一个元素,则返回 Point、LineString 或 Polygon;如果结果包含多个元素,则返回 MultiPoint、MultiLineString 或 MultiPolygon。如果结果是异质的,则返回 GeometryCollection。

由于目前尚不清楚涉及GeometryCollection的集合论方法的语义是有用的,因此不支持GeometryCollection作为集合论方法参数。

__图10-集合论空间分析方法__

对于某些输入,Difference和SymDifference方法可以计算非闭集。当参数重叠并且具有不同的维度时,可能会发生这种情况。由于JTS几何对象只能表示闭集,因此指定了空间分析方法来返回点集理论结果的闭合。

图11-JTS总是返回闭合的几何图形

方法规范

缓冲

距离d处的几何体的缓冲区是包含几何体距离d内的所有点的多边形或多重多边形。根据几何体的精度模型来解释距离d。支持正距离和负距离。

a.buffer(d)=

d > 0 : { x ³ ¥{sup}2{/sub}| dist(x, a) ã d }

d <0: { x ³ ¥{sup}2{/sub}| x ³ a Ù dist(x, boundary(a)) > d }

在数学术语中,缓冲被定义为取几何图形的Minkowski和或差,圆盘的半径等于缓冲距离的绝对值。

正缓冲和负缓冲也称为扩张或侵蚀。在CAD/CAM术语中,缓冲被称为计算偏移曲线。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图12——正和负缓冲

JTS允许为线的缓冲区指定不同的端盖样式。当直接使用BufferOp类时,端盖样式可用。支持以下端盖样式:

样式名称

描述

圆头端点

普通圆形端点

平头端点

CAP_SQUARE

方头端点

端点在线末端以外的缓冲区距离处成直角

下图说明了指定不同端盖样式的效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

圆头端点

平头端点

方头端点

凸包

凸包是凸多边形的外边界点,如果凸包少于三个点,就会返回低一级维度的几何

凸包中的点数

结果中的几何

0

空几何集合

1

2

线串

3个或更多

多边形

JTS将返回一个具有表示凸包所需最少点数的几何体。特别是,共线的连续点不超过两个。

交叉

两个几何A和B的交点是位于A和B中的所有点的集合。

a.intersection(b) = { x ³ ¥{sup}2{/sub}| x ³ a Ù x ³ b }//a和b相交

两个几何A和B的并集是位于A或B中的所有点的集合。

a.union(b)={x³¥2|x³aÚx³b}

差别

两个几何体A和B之间的差是位于A中但不位于B中的所有点的集合。此方法返回结果几何体的闭包。

a.difference(b) = closure( { x ³ ¥{sup}2{/sub}| x ³ a Ú x ´ b } )

对称差集

两个几何体 A 和 B 的对称差集是指同时位于 A 或 B 中但不在两者中的所有点的集合。该方法返回结果几何体的闭包。

a.symDifference(b) = closure( { x ³ ¥{sup}2{/sub}| (x ³ a Ù x ´ b) Ú (x ´ a Ù x ³ b) })

其他方法

边界

如SFS第2.1.13.1节所述,“几何体的边界是下一个较低维度的一组几何体。”JTS使用几何体集合来表示几何体集合。

对于所有空的几何图形,边界(G)=空的几何集合(JTS)。

对于非空几何体,边界定义如下:

几何类

boundary()的定义

空集合

多点

空集合

线串

如果是封闭的:无多点

如果未封闭:包含两个端点的多点。

线串

无多点

多线

通过将Mod-2规则应用于元素LineStrings的边界而获得的MultiPoint

多边形

按顺序包含壳体和孔的LinearRings的MultiLineString(SFS 2.1.10)

多多边形

MultiLineString包含元素多边形边界的LinearRings,其顺序与MultiPolygon(SFS 2.1.12/JTS)中出现的顺序相同

几何集合

(SFS 第 2.1.13.1 节)“一个任意集合的几何体,其内部是不相交的,其边界由从几何体边界中提取的几何体组成。”

element geometries by application of the Mod-2 rule.”

IsClosed

“封闭”的SFS含义不同于闭的拓扑含义。SFS“isClosed”方法仅适用于曲线。它测试曲线的起点和终点是否为同一点。相反,拓扑闭包取决于几何体是否包含其边界。如前所述,SFS几何类的所有实例根据定义在拓扑上是封闭的。

对于空曲线,isClosed被定义为值为false。

IsSimple

一般情况下,SFS认为的简单性遵循下面的规则:

当且仅当唯一的自相交点在边界点时,几何体是简单的。

对于Point、MultiPolygon和GeometryCollection,SFS没有提供简化规范。JTS基于上述规则为这些几何体类型提供了规范。

对于空的几何,isSimple = true

几何类

isSimple()的定义

真实(JTS)

多点

如果多点中没有两个点相等,则为true(SFS 2.1.4)

线串

如果曲线没有两次通过同一点(端点除外,端点可能相同),则为true(SFS 2.1.5)

线串

true(SFS 2.1.6)

多线

如果线的每个元素是简单的,

只有任意两个元素之间的交点出现在两个LineStrings边界上的点上。

(第2.1.7条)

多边形

true(SFS 2.1.10)

多多边形

true (JTS)

几何集合

如果集合中的所有元素都是简单的,并且任意两个元素之间的唯一交点仅出现在这两个元素的边界上,则返回 true。 (JTS)

intersections between any two elements occur at points that are on the boundaries of both elements. (JTS)

IsValid

由于JTS几何体对象是由用户提供的点序列构建的,因此几何体对象可能实际上没有根据SFS指定拓扑有效的几何体。JTS在构造几何图形时不会验证几何图形,原因是效率问题。提供isValid()方法是为了根据SFS规范测试几何结构是否有效。

检查的验证规则如下:

规则

描述

应用于

有效坐标

坐标必须包含有效的数值

全部的

有效点计数

坐标序列必须为其包含的几何图形包含有效数量的点:

LineString–0或2或更多LinearRing–0或4或更多

全部

没有无效的自相交

任何两个环最多可以在一个点相交。

A

无重复环

区域内的环不能重复。重复的环是指在顺序上具有相同点序列的环

A

无自相交环

环不能自相交。

LR, A

外壳中包含的孔

孔必须包含在其父壳中。

A

未嵌套的孔

孔不得嵌套。

A

未嵌套的壳

壳不能被嵌套

mA

内部连接

多边形的内部必须连接。

A

内部连接

多边形内部必须连接

A

无效坐标

多边形内部必须连接

A

JTS还提供了IsValidOp类,该类执行与isValid相同的检查,但返回验证失败的确切性质和位置。

众所周知的文本输入/输出

SFS特征的众所周知的文本格式在SFS第3.2.5节中定义。众所周知的文本读写器将解析并输出这种格式。

请注意,ESFS中存在不一致性。WKT语法规定多点由“MULTIPOINT((xy),(xy))”表示,但示例将多点显示为“MULTIPONT(xy,xy)”。其他实现遵循后一种语法,因此JTS也将采用它。

SFS未定义线性环的WKT表示。JTS使用关键字LINEARING扩展了WKT语法以支持这些语法。

熟知文本的语法

几何体的众所周知的文本表示的语法定义如下。

The notation {}* denotes 0 or more repetitions of the tokens within the braces. The braces do not appear in the output token list.

:=

|

|

|

|

|

|

|

:= POINT

:= LINESTRING

:= LINEARRING

:= POLYGON

:= MULTIPOINT

:= MULTILINESTRING

:= MULTIPOLYGON

:= GEOMETRYCOLLECTION

:= EMPTY | ( )

:=

:= double precisionliteral

:= double precisionliteral

:= EMPTY

| ( {, }* )

:= EMPTY

| ( {, }*)

:= EMPTY

| ( {, }* )

:= EMPTY

| ( {, }* )

:= EMPTY

| ( {, }* )

:= EMPTY

| (

知名文本阅读器

众所周知的文本阅读器(WKTReader)设计用于从输入流或内部字符串中提取几何体对象。这使它能够充当解析器,从嵌入其他数据格式(如XML)的文本块中读取Geometry对象。

WKTReader由GeometryFactory参数化,以允许其创建适当实现的Geometry对象。特别是,GeometryFactory将确定所使用的PrecisionModel和SRID。

WKTReader将把输入数字转换为精确的内部表示。

知名文本编写器

众所周知的文本编写器将Geometry对象的文本表示输出到Java编写器。

WKTWriter将会输入四舍五入的坐标到精度模型,最多会输出10位。

参考文献

[AS] The OpenGIS Abstract Specification: An Object Model for Interoperable Geoprocessing, Revision 1, OpenGIS Consortium, Inc, OpenGISProject Document Number 96-015R1,1996.

[Ava97] F. Avnaim, J-D. Boissonnat, O. Devillers, F. Preparata and M. Yvinec.{i} “{/i}Evaluating signs of determinants using single-precision arithmetic”[prisme- 2306a. In{i} Algorithmica{/i}, Vol. 17, pp. 111-132, 1997.{lnk:1}{clr:1}{u} http://www-{/u}{/lnk}{u}sop.inria.fr/prisme/publis/abdpy-esdus-97.ps.gz

[Bri98]A.Brinkmann,K.Hinrichs。“在地图覆盖中实现精确的线段相交”。1998年7月11日至15日,《第八届温哥华空间数据处理国际研讨会论文集》,第569-5791998页。

[Sch97] Stefan Schirra. “Precision and robustness in geometric computations”.In

地理信息系统的算法基础,M.van Krevild,

J. Nievergelt, T. Roos, and P. Widmayer Eds., LNCS 1340, Springer, pp. 255- 287, 1997.

[SFS] OpenGIS Simple Features Specification For SQL Revision 1.1. OpenGIS Consortium, Inc. OpenGIS project Document 99-049.{lnk:1}{clr:1}{u} http://www.opengis.org/techno/specs/99-049.pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值