随着智慧城市的發展,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
不合法的polygon
幾何關系(二進制謂詞的方法規約)
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
- 先把源碼pull下來
- package
子產品modules/app
- 通過
運作>java -jar JTSTestBuilder.jar
示範demo
輸入倆幾何體 A和B (可繪制,也可手動輸入polygon)
執行一些函數檢視結果,比如
symDifference
這裡沒顯示出效果,可以把結果copy到輸入:
還可以轉換成其他格式,比較友善, 比如轉成geojson格式
使用程式實作
// 從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小節。
來個比較直覺的了解:
為什麼要這樣表示?可以從下面的計算過程發現:
要了解這裡的
T、F、*
達标什麼意思,看下面
參考
- https://github.com/locationtech/jts
- https://www.ogc.org/standards
- SFS規範:https://www.ogc.org/standards/sfa