GIS

WKT是什么

了解GIS中WKT(Well-Known Text)的基本概念、Geometry类型、坐标结构、WKT语法以及WKT与WKB、GeoJSON、Shapefile和GeoPackage之间的关系。

阅读约 98 分钟

WKT是什么

WKT(Well-Known Text)是一种用于以文本形式表示GIS Geometry的标准格式。

它可以使用简单的文本描述:

  • Point
  • LineString
  • Polygon
  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • GeometryCollection

例如一个点:

POINT (116.397 39.908)

其中:

POINT
    ↓
Geometry类型

116.397
    ↓
X坐标

39.908
    ↓
Y坐标

简单来说:

WKT就是用文本描述Geometry的一种方式。

WKT有什么用

WKT主要用于:

  • GIS数据交换
  • Geometry调试
  • 空间数据库查询
  • GIS程序开发
  • 空间数据测试
  • Geometry序列化
  • 坐标和空间形状表达

例如在开发GIS工具时,可以输入:

POINT (116.397 39.908)

然后解析为:

Geometry
├── type = Point
├── x = 116.397
└── y = 39.908

WKT的基本结构

WKT通常由:

Geometry Type
+
Coordinates

组成。

例如:

POINT (116.397 39.908)

结构:

POINT
  ↓
Geometry Type

116.397 39.908
  ↓
Coordinates

对于复杂Geometry,则会出现更多坐标以及嵌套括号。

例如:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10,
  0 0
))

Point

Point表示一个点。

基本语法:

POINT (X Y)

例如:

POINT (116.397 39.908)

通常可以理解为:

X = 116.397
Y = 39.908

在经纬度坐标系中,如果使用EPSG:4326:

X = 经度
Y = 纬度

例如:

POINT (116.397 39.908)

可以理解为:

经度 = 116.397
纬度 = 39.908

空Point

WKT还可以表示空Geometry。

例如:

POINT EMPTY

表示:

Point
    ↓
没有坐标

这在数据处理和数据库中比较有用。

MultiPoint

MultiPoint表示多个点。

例如:

MULTIPOINT (
  (116.397 39.908),
  (116.405 39.915),
  (116.412 39.920)
)

结构:

MULTIPOINT
├── Point
├── Point
└── Point

MultiPoint常用于:

  • 多个采样点
  • 多个监测点
  • 一组设施
  • 空间事件

LineString

LineString表示一条线。

语法:

LINESTRING (
  X1 Y1,
  X2 Y2,
  X3 Y3
)

例如:

LINESTRING (
  116.397 39.908,
  116.405 39.915,
  116.412 39.920
)

结构:

Point
  ↓
Point
  ↓
Point

多个坐标按照顺序连接,就形成一条LineString。

LineString常用于:

  • 道路
  • 河流
  • 铁路
  • 管线
  • GPS轨迹

LineString的特点

LineString中的坐标具有顺序。

例如:

A → B → C → D

与:

D → C → B → A

方向不同。

因此LineString不仅表示一组坐标,还表示这些坐标之间的连接关系和顺序。

空LineString

可以使用:

LINESTRING EMPTY

表示一个空的LineString。

Polygon

Polygon用于表示一个区域。

基本语法:

POLYGON ((
  X1 Y1,
  X2 Y2,
  X3 Y3,
  X1 Y1
))

例如:

POLYGON ((
  116.390 39.900,
  116.400 39.900,
  116.400 39.910,
  116.390 39.910,
  116.390 39.900
))

结构:

Polygon
    ↓
Exterior Ring
    ↓
多个坐标
    ↓
回到起点

Polygon通常用于:

  • 行政区
  • 地块
  • 建筑物
  • 湖泊
  • 公园
  • 土地利用区域

Polygon为什么有两层括号

这是WKT初学者经常遇到的问题。

例如:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10,
  0 0
))

第一层表示Polygon的Ring集合。

第二层表示其中一个Ring。

可以理解为:

POLYGON
└── Ring
    ├── Point
    ├── Point
    ├── Point
    ├── Point
    └── Point

因此Polygon通常至少存在两层括号。

Polygon的闭合

Polygon的Ring需要形成闭合边界。

例如:

0 0
10 0
10 10
0 10
0 0

最后一个坐标:

0 0

与第一个坐标相同。

因此:

起点
 ↓
多个坐标
 ↓
终点
 ↓
回到起点

形成闭合区域。

Polygon内部空洞

Polygon可以包含内部Ring。

例如:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10,
  0 0
),(
  2 2,
  8 2,
  8 8,
  2 8,
  2 2
))

结构:

Polygon
├── Exterior Ring
└── Interior Ring

其中:

Exterior Ring
    ↓
外部边界

Interior Ring
    ↓
内部空洞

MultiLineString

MultiLineString表示多个LineString。

例如:

MULTILINESTRING (
  (
    0 0,
    10 10
  ),
  (
    20 20,
    30 30
  )
)

结构:

MultiLineString
├── LineString
│   ├── Point
│   └── Point
│
└── LineString
    ├── Point
    └── Point

常用于:

  • 多段道路
  • 河流网络
  • 铁路
  • 管线

MultiPolygon

MultiPolygon表示多个Polygon。

例如:

MULTIPOLYGON (
  ((
    0 0,
    10 0,
    10 10,
    0 10,
    0 0
  )),
  ((
    20 20,
    30 20,
    30 30,
    20 30,
    20 20
  ))
)

结构:

MultiPolygon
├── Polygon
│   └── Ring
│
└── Polygon
    └── Ring

常用于:

  • 群岛
  • 多个不连续区域
  • 多个地块
  • 多个行政区域

GeometryCollection

GeometryCollection可以包含不同类型的Geometry。

例如:

GEOMETRYCOLLECTION (
  POINT (10 10),
  LINESTRING (20 20, 30 30),
  POLYGON ((
    40 40,
    50 40,
    50 50,
    40 50,
    40 40
  ))
)

结构:

GeometryCollection
├── Point
├── LineString
└── Polygon

与Multi类型不同:

MultiPoint
    ↓
多个Point

MultiLineString
    ↓
多个LineString

MultiPolygon
    ↓
多个Polygon

GeometryCollection
    ↓
可以混合不同Geometry类型

WKT坐标顺序

WKT通常使用:

X Y

例如:

POINT (116.397 39.908)

而不是:

POINT (39.908 116.397)

如果使用经纬度坐标系:

X = Longitude
Y = Latitude

也就是:

X = 经度
Y = 纬度

因此需要特别注意:

经度在前,纬度在后。

WKT与EPSG:4326

WKT Geometry本身主要描述Geometry和坐标。

例如:

POINT (116.397 39.908)

如果这些坐标使用:

EPSG:4326

通常可以理解为:

经度 = 116.397
纬度 = 39.908

但是单独的传统WKT字符串通常不能完整表达CRS信息。

因此实际系统中需要额外保存:

Geometry
+
CRS

WKT与EPSG:3857

如果Geometry使用:

EPSG:3857

坐标通常是投影坐标:

POINT (12958000 4858000)

此时:

X
Y

并不是直接的:

经度
纬度

而是Web Mercator投影平面上的坐标。

因此:

WKT
+
CRS

才能正确解释Geometry。

WKT中的Z

WKT可以表示三维坐标。

例如:

POINT Z (116.397 39.908 45)

其中:

X = 116.397
Y = 39.908
Z = 45

Z通常可以表示:

  • 高程
  • 建筑高度
  • 三维空间高度

结构:

POINT Z
    ↓
X Y Z

WKT中的M

WKT还可以表示M(Measure)值。

例如:

POINT M (116.397 39.908 100)

这里:

X = 116.397
Y = 39.908
M = 100

M通常用于:

  • 里程
  • 测量值
  • 时间
  • 轨迹距离

WKT中的ZM

Geometry也可以同时包含Z和M。

例如:

POINT ZM (116.397 39.908 45 100)

对应:

X = 116.397
Y = 39.908
Z = 45
M = 100

因此:

2D
X Y

3D
X Y Z

M
X Y M

4D
X Y Z M

WKT的EMPTY

WKT可以表示空Geometry。

例如:

POINT EMPTY
LINESTRING EMPTY
POLYGON EMPTY
MULTIPOINT EMPTY

表示Geometry类型存在,但当前没有实际坐标。

这对于数据库中的空空间数据非常有用。

WKT的大小写

WKT关键字通常不要求严格区分大小写。

例如:

POINT (10 20)

和:

point (10 20)

在支持WKT的解析器中通常可以被识别。

但为了保持规范、统一和可读性,实际开发中通常使用大写:

POINT
LINESTRING
POLYGON
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON

WKT括号结构

WKT最容易出错的地方之一就是括号。

可以通过Geometry类型理解:

Point

POINT (X Y)

LineString

LINESTRING (
  X Y,
  X Y
)

Polygon

POLYGON ((
  X Y,
  X Y,
  X Y,
  X Y
))

MultiPoint

MULTIPOINT (
  (X Y),
  (X Y)
)

MultiLineString

MULTILINESTRING (
  (
    X Y,
    X Y
  ),
  (
    X Y,
    X Y
  )
)

MultiPolygon

MULTIPOLYGON (
  ((
    X Y,
    X Y,
    X Y,
    X Y
  )),
  ((
    X Y,
    X Y,
    X Y,
    X Y
  ))
)

可以看到:

Geometry越复杂,WKT的括号嵌套通常越深。

WKT常见错误

经纬度顺序错误

错误:

POINT (39.908 116.397)

如果数据约定是:

X = 经度
Y = 纬度

那么应该是:

POINT (116.397 39.908)

Polygon没有闭合

例如:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10
))

首尾没有闭合。

通常应写成:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10,
  0 0
))

括号数量错误

例如:

POLYGON (
  0 0,
  10 0,
  10 10
)

这不是标准的Polygon结构。

Polygon通常需要Ring:

POLYGON ((
  0 0,
  10 0,
  10 10,
  0 10,
  0 0
))

坐标数量错误

例如:

POINT (116.397)

二维Point通常需要:

POINT (116.397 39.908)

WKT有效性

WKT格式正确,不代表Geometry一定有效。

例如:

POLYGON ((
  0 0,
  10 10,
  0 10,
  10 0,
  0 0
))

这个Polygon可能存在自相交问题。

可以理解为:

WKT语法正确
    ↓
Geometry可以被解析

但:

Geometry有效性
    ↓
仍然需要进一步检查

因此需要区分:

Syntax
    ↓
语法是否正确

Validity
    ↓
Geometry是否有效

WKT与Geometry

WKT本身不是Geometry对象。

它是:

Geometry
    ↓
WKT
    ↓
Text

例如:

POINT (116.397 39.908)

经过解析:

WKT
 ↓
Parser
 ↓
Geometry Object

因此GIS程序通常需要WKT解析器。

WKT解析流程

一个典型的WKT解析过程:

WKT
 ↓
Tokenizer
 ↓
Geometry Type
 ↓
Coordinates
 ↓
Geometry Object

例如:

POINT (116.397 39.908)

解析:

POINT
 ↓
Point

116.397
 ↓
X

39.908
 ↓
Y

最终得到:

{
  type: "Point",
  coordinates: [116.397, 39.908]
}

Geometry转WKT

也可以反向操作:

Geometry Object
 ↓
WKT Serializer
 ↓
WKT

例如:

{
  type: "Point",
  coordinates: [116.397, 39.908]
}

转换成:

POINT (116.397 39.908)

因此WKT在GIS程序中经常用于:

Geometry
    ↕
WKT

WKT与WKB

WKT和WKB描述的是相同的Geometry概念。

区别是:

WKT
 ↓
Text

而:

WKB
 ↓
Binary

例如:

Geometry
   │
   ├──→ WKT
   │      └── Text
   │
   └──→ WKB
          └── Binary
对比WKTWKB
格式文本二进制
可读性
调试方便较困难
数据库常用常用
程序处理适合非常适合
数据大小通常较大通常更紧凑

WKT与GeoJSON

GeoJSON同样可以表示Geometry。

例如WKT:

POINT (116.397 39.908)

GeoJSON:

{
  "type": "Point",
  "coordinates": [116.397, 39.908]
}

两者都表示:

Point
X = 116.397
Y = 39.908

区别主要是表达结构:

WKT
 ↓
专门描述Geometry的文本格式
GeoJSON
 ↓
JSON格式的GIS数据
 ↓
可以包含Geometry + Properties

WKT与Feature

WKT主要表示Geometry。

例如:

POINT (116.397 39.908)

而Feature通常包含:

Feature
├── Geometry
└── Attributes

因此:

WKT
 ↓
Geometry

而:

GeoJSON Feature
 ↓
Geometry + Properties

例如:

{
  "type": "Feature",
  "properties": {
    "name": "北京"
  },
  "geometry": {
    "type": "Point",
    "coordinates": [116.397, 39.908]
  }
}

WKT与Shapefile

Shapefile是一种完整的GIS数据格式。

WKT主要表示单个Geometry。

可以理解为:

WKT
 ↓
Geometry

而:

Shapefile
├── Geometry
├── Attributes
├── Index
└── CRS

因此:

WKT不是Shapefile的替代品,而是Geometry的一种文本表达方式。

WKT与GeoPackage

GeoPackage是一种基于SQLite的空间数据格式。

它可以保存:

多个Layer
+
Geometry
+
Attributes
+
空间索引
+
CRS

而WKT主要用于:

Geometry

所以:

GeoPackage
    ↓
Geometry
    ↓
可以转换为WKT

例如数据库查询时,可以将Geometry转换成WKT进行查看。

WKT与GeoParquet

GeoParquet主要用于现代空间数据分析。

Geometry可以使用二进制方式存储,而WKT更适合:

查看
调试
转换
测试

例如:

GeoParquet
    ↓
Geometry
    ↓
WKT
    ↓
人工检查

WKT的常见应用

GIS数据库

空间数据库中可以使用WKT表示Geometry:

POINT (116.397 39.908)

然后通过空间函数转换成数据库中的Geometry类型。

API数据交换

后端API可以返回:

{
  "geometry": "POINT (116.397 39.908)"
}

前端再进行解析。

GIS开发

开发过程中可以使用WKT快速创建测试Geometry:

POINT (116.397 39.908)

或者:

LINESTRING (0 0, 10 10, 20 0)

Geometry调试

当地图显示异常时,可以先输出WKT:

Geometry
    ↓
WKT
    ↓
检查坐标

非常方便判断:

  • 坐标是否正确
  • Geometry类型是否正确
  • Polygon是否闭合
  • 坐标顺序是否正确

WKT数据处理流程

一个典型流程:

WKT
 ↓
解析
 ↓
Geometry
 ↓
空间分析
 ↓
输出
 ├── GeoJSON
 ├── WKB
 ├── Shapefile
 ├── GeoPackage
 └── GeoParquet

例如:

POINT (116.397 39.908)

可以转换成:

GeoJSON
{
  "type": "Point",
  "coordinates": [116.397, 39.908]
}

也可以转换成:

WKB

最终形成二进制Geometry。

WKT知识结构

可以把WKT总结为:

WKT
│
├── Point
│
├── MultiPoint
│
├── LineString
│
├── MultiLineString
│
├── Polygon
│   ├── Exterior Ring
│   └── Interior Ring
│
├── MultiPolygon
│
└── GeometryCollection

坐标维度:

2D
X Y

3D
X Y Z

Measure
X Y M

4D
X Y Z M

GIS格式之间的关系

可以建立这样的关系:

Geometry
    │
    ├──→ WKT
    │      ↓
    │    Text
    │
    └──→ WKB
           ↓
         Binary

完整GIS数据格式:

Geometry
+
Attributes
+
CRS
+
Metadata
    ↓
GIS Data

常见格式:

Shapefile
GeoJSON
GeoPackage
GeoParquet

GIS格式选择

可以简单理解:

Geometry文本表示
    ↓
WKT

Geometry二进制表示
    ↓
WKB

Web GIS数据交换
    ↓
GeoJSON

传统GIS数据
    ↓
Shapefile

本地空间数据库
    ↓
GeoPackage

大规模空间分析
    ↓
GeoParquet

总结

WKT(Well-Known Text)是一种使用文本表示GIS Geometry的格式。

最常见的Geometry包括:

Point
MultiPoint
LineString
MultiLineString
Polygon
MultiPolygon
GeometryCollection

核心结构可以理解为:

Geometry Type
    ↓
Coordinates
    ↓
WKT

例如:

POINT (116.397 39.908)

表示:

Point
X = 116.397
Y = 39.908

可以记住:

WKT是Geometry的文本表示方式,非常适合GIS开发、空间数据库、数据交换、Geometry调试和空间数据测试。

在GIS数据体系中:

Geometry
    │
    ├── WKT
    │   └── 文本表示
    │
    └── WKB
        └── 二进制表示

完整GIS数据
    │
    ├── GeoJSON
    ├── Shapefile
    ├── GeoPackage
    └── GeoParquet

理解WKT之后,可以继续学习WKT解析、WKT转GeoJSON、WKT转WKB、WKT坐标转换以及WKT在空间数据库中的应用。

🧰

相关工具

使用 IYATools 在线工具快速处理 GIS 数据