从时空数据到空间计算工具-JTS

随着智慧城市的发展,GIS行业迎来了新机遇,时空数据也成为了这个行业的基石。作为一名有追求的程序员,终于在时空数据的道路上越走越远。

  • JTS是什么?
  • 怎么使用JTS?
  • 来个入门案例

免责声明:

JTS是什么?

https://github.com/locationtech/jts

JTS Topology Suite的缩写,递归命名 or Java Topology Suite。

JTS是一个java api,它使用显式精度模型和健壮的几何算法实现一组空间数据变换的核心操作。

JTS试图尽可能精确地实现OpenGIS简单特性规范(SFS)。在某些SFS不清楚或省略的地方,JTS尝试选择合理且一致的替代方案。

术语解释

术语 解释
Geometry 几何体的统称,代码表示为所有几何体的父类
Coordinate 空间中的一个点
Point R^3中一个任意点
Node 交点(节点),2条线段相交的点
Noding(Noded) 一种计算过程:geometry相交时Node的计算过程
SFS OGC Simple Features Specification
Vertex 几何体的顶点

几何对象定义

术语 解释
Geometry 所有几何对象的统称,可以认为是父类
Empty Geometry 标准定义几何体可能是空的
GeometryCollection
Curve 非空曲线必须至少有2个点,并且两个连续的点不能相等。注意,这里的曲线不一定是曲线,也可能是直线。
MultiCurve 规范里有个“Mod 2”规则。
LineString 线性点集,0个或至少2个点,可交叉,连续的点可相同。
LinearRing 线性环,是LineString的子类,至少4个点,或0个点为空。
Polygon 壳和孔都是LinearRing。有以下规则:* 壳和孔不能自相交 * 孔可以挨着壳(touch),但只能有一个点重合,不能是一条边重合 * 上面重合的点不需要是顶点(vertex)
MultiPolygon

合法的polygon

从时空数据到空间计算工具-JTS

不合法的polygon

从时空数据到空间计算工具-JTS

几何关系(二元谓词的方法规约)

从时空数据到空间计算工具-JTS

JTS中基础类分析

了解一些基础实现类帮助开发。

Coordinate

一个轻量级的坐标点实现。

FAQ:Coordinate与Point的区别?

QA:Point是Geometry的子类,带有精度模型,空间引用信息等,Coordinate属于轻量级的点,主攻二维,3维作为附加属性。

CoordinateSequence

一个接口,代表一系列Geometry中的点。

Envelope

一个包含最大最小x、y值的类。

IntersectionMatrix

实现 Dimensionally Extended Nine-Intersection Model (DE-9IM) 模型计算的矩阵。

GeometryFactory

很多几何对象都由此工厂方法创建。

CoordinateFilter

使用访问者模式实现的 点过滤器。

GeometryFilter

几何对象过滤器。

JAVA实现与SFS的差别

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

helloworld实践

了解下模块分布,用于按需引包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e79kFLPK-1610545503599)(./imgs/000.png)]

<properties>
    <jts.version>1.16.1</jts.version>
</properties>
<dependency>
    <groupId>org.locationtech.jts</groupId>
    <artifactId>jts-core</artifactId>
    <version>${jts.version}</version>
</dependency>
<dependency>
	<groupId>org.locationtech.jts.io</groupId>
	<artifactId>jts-io-common</artifactId>
	<version>${jts.version}</version>
</dependency>

构建可视化程序

https://github.com/locationtech/jts/blob/master/doc/JTSTestBuilder.md

  1. 先把源码pull下来
  2. package modules/app 模块
  3. 通过 >java -jar JTSTestBuilder.jar 运行

演示demo

输入俩几何体 A和B (可绘制,也可手动输入polygon)

从时空数据到空间计算工具-JTS

执行一些函数查看结果,比如 symDifference

从时空数据到空间计算工具-JTS

这里没显示出效果,可以把结果copy到输入:

从时空数据到空间计算工具-JTS

还可以转换成其他格式,比较方便, 比如转成geojson格式

从时空数据到空间计算工具-JTS

使用程序实现

	// 从WKT里创建几何体
	WKTReader wktReader = new WKTReader();
	Geometry a = wktReader.read("POLYGON ((50 150, 150 150, 150 50, 50 50, 50 150))");
	// Geometry b = wktReader.read("POLYGON ((100 100, 200 100, 200 0, 100 0, 100 100))");

	// 用工厂方法创建
	GeometryFactory factory = new GeometryFactory();
	Polygon b = factory.createPolygon(new Coordinate[]{
			new Coordinate(100, 100),
			new Coordinate(200, 100),
			new Coordinate(200, 0),
			new Coordinate(100, 0),
			new Coordinate(100, 100),
	});

	// 关系运算
	Geometry res = a.symDifference(b);
	System.out.println(res.toText());

	// 输出不同的格式
	// WKTWriter wktWriter = new WKTWriter();
	GeoJsonWriter geoJsonWriter = new GeoJsonWriter();
	String json = geoJsonWriter.write(res);
	System.out.println(json);

结果:

MULTIPOLYGON (((50 150, 150 150, 150 100, 100 100, 100 50, 50 50, 50 150)), ((100 50, 150 50, 150 100, 200 100, 200 0, 100 0, 100 50)))
{"type":"MultiPolygon","coordinates":[[[[50,150],[150,150],[150,100],[100,100],[100,50],[50,50],[50,150]]],[[[100,50],[150,50],[150,100],[200,100],[200,0.0],[100,0.0],[100,50]]]],"crs":{"type":"name","properties":{"name":"EPSG:0"}}}

附录

WKT

Well-Known Text:SFS定义的一种格式

<Geometry Tagged Text> :=
<Point Tagged Text>
	| <LineString Tagged Text>
	| <LinearRing Tagged Text>
	| <Polygon Tagged Text>
	| <MultiPoint Tagged Text>
	| <MultiLineString Tagged Text>
	| <MultiPolygon Tagged Text>
	| <GeometryCollection Tagged Text>

<Point Tagged Text> :=
	POINT <Point Text>

<LineString Tagged Text> :=
	LINESTRING <LineString Text>

<LinearRing Tagged Text> :=
	LINEARRING <LineString Text>

<Polygon Tagged Text> :=
	POLYGON <Polygon Text>

<MultiPoint Tagged Text> :=
	MULTIPOINT <Multipoint Text>

<MultiLineString Tagged Text> :=
	MULTILINESTRING <MultiLineString Text>

<MultiPolygon Tagged Text> :=
	MULTIPOLYGON <MultiPolygon Text>

<GeometryCollection Tagged Text> :=
	GEOMETRYCOLLECTION <GeometryCollection Text>

<Point Text> := EMPTY | ( <Point> )
<Point> := <x> <y>

<x> := double precision literal
<y> := double precision literal

<LineString Text> := EMPTY
| ( <Point> {, <Point> }* )

<Polygon Text> := EMPTY
| ( <LineString Text> {, <LineString Text> }*)

<Multipoint Text> := EMPTY
| ( <Point > {, <Point > }* )

<MultiLineString Text> := EMPTY
| ( <LineString Text> {, <LineString Text> }* )

<MultiPolygon Text> := EMPTY
| ( <Polygon Text> {, <Polygon Text> }* )

<GeometryCollection Text> := EMPTY
| ( <Geometry Tagged Text>

DE-9IM

这个模型的定义参考SFS规范6.1.15.2小节。

从时空数据到空间计算工具-JTS

来个比较直观的理解:

从时空数据到空间计算工具-JTS

为什么要这样表示?可以从下面的计算过程发现:

从时空数据到空间计算工具-JTS

从时空数据到空间计算工具-JTS

要理解这里的T、F、* 达标什么意思,看下面

从时空数据到空间计算工具-JTS

参考

  1. https://github.com/locationtech/jts
  2. https://www.ogc.org/standards
  3. SFS规范:https://www.ogc.org/standards/sfa
上一篇:机器学习笔记(二十三)——Tensorflow 2(可视化)


下一篇:浙大版《C语言程序设计(第3版)》题目集 练习2-4 温度转换 (5 分)