空间数据格式
seekdb 支持两种标准的空间数据格式用于表示查询中的几何对象:
-
Well-Know Text Format(WKT)
-
Well-Know Binary Format(WKB)
WKT
WKT 是基于EBNF(Extended Backus Naur Form)定义的。WKT 既可以作为数据格式(本文中称作 WKT-Data),也可以在 GIS 用于 SRS 的定义(在本文中简称 WKT-SRS)。
Point
Point 不使用逗号分隔。格式示例如下:
POINT(15 20)
如下示例使用 ST_X() 从 Point 对象中提取 X 坐标。 第一个直接使用 Point() 函数生成对象。第二个使用通过 ST_GeomFromText() 转换为 Point 的 WKT 表示。
obclient> SELECT ST_X(Point(15, 20));
+---------------------+
| ST_X(Point(15, 20)) |
+---------------------+
| 15 |
+---------------------+
1 row in set
obclient> SELECT ST_X(ST_GeomFromText('POINT(15 20)'));
+---------------------------------------+
| ST_X(ST_GeomFromText('POINT(15 20)')) |
+---------------------------------------+
| 15 |
+---------------------------------------+
1 row in set
Line
Line 是由多个点组成,点之间使用逗号隔开。格式示例如下:
LINESTRING(0 0, 10 10, 20 25, 50 60)
Polygon
Polygon 是由至 少一条外环(闭合的线)以及若干条(可以是 0 条)内环(闭合的线)组成。格式示例如下:
POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
MultiPoint
MultiPoint 由多个点组成,和线比较类似,但是语义不同。多点连接组成线,多点离散是 MultiPoint。格式示例如下:
MULTIPOINT(0 0, 20 20, 60 60)
在函数 ST_MPointFromText() 以及 ST_GeoFromText() 中,MultiPoint 中的点采用括号括起来也是合法的。格式示例如下:
ST_MPointFromText('MULTIPOINT (1 1, 2 2, 3 3)')
ST_MPointFromText('MULTIPOINT ((1 1), (2 2), (3 3))')
MultiLineString
MultiLineString 是多条线的集合。格式示例如下:
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
MultiPolygon
MultiPolygon 是多个多边形的集合。格式示例如下:
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
GeometryCollection
GeometryCollection 可以是多种基础类型以及集合类型的集合。
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
WKB
WKB 是基于 OpenGIS 规范开发的,支持 7 种类型(Point、Linestring、Polygon、Multipoint、Multilinestring、Multipolygon 和 Geometrycollection)以及对应格式定义。
Point
以 POINT(1 -1) 为例,格式定义如下表所示。
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 01000000 |
| X coordinate | 8 bytes | double-precision | 000000000000F03F |
| Y coordinate | 8 bytes | double-precision | 000000000000F0BF |
Linestring
基于 LINESTRING(1 -1, -1 1) 举例,格式定义如下表所示。Num points 要求大于等于 2。
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 02000000 |
| Num points | 4 bytes | unsigned int | 02000000 |
| X coordinate | 8 bytes | double-precision | 000000000000F03F |
| Y coordinate | 8 bytes | double-precision | 000000000000F0BF |
| X coordinate | 8 bytes | double-precision | 000000000000F0BF |
| Y coordinate | 8 bytes | double-precision | 000000000000F03F |
Polygon
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 03000000 |
| Num rings | 4 bytes | unsigned int | 大于等于 1 |
| repeat ring | - | - | - |
MultiPoint
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 04000000 |
| Num points | 4 bytes | unsigned int | 要求 Num points >= 1 |
| repeat POINT | - | - | - |
MultilineString
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 05000000 |
| Num linestrings | 4 bytes | unsigned int | 大于等于 1 |
| repeat LINESTRING | - | - | - |
MultiPolygon
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 06000000 |
| Num polygons | 4 bytes | unsigned int | 大于等于 1 |
| repeat POLYGON | - | - | - |
GeometryCollection
| 组件名称 | 规格 | 类型 | 取值 |
|---|---|---|---|
| Byte order | 1 byte | unsigned int | 01 |
| WKB type | 4 bytes | unsigned int | 07000000 |
| Num wkbs | 4 bytes | unsigned int | - |
| repeat WKB | - | - | - |
说明:
- 只有 GeometryCollection 可以为空,表示存储了 0 个元素,其它类型都不能为空。
LENGTH()作用在 GIS 对象上的时候,返回的是存储的二进制的长度。
obclient [test]> SET @g = ST_GeomFromText('POINT(1 -1)');
Query OK, 0 rows affected
obclient [test]> SELECT LENGTH(@g);
+------------+
| LENGTH(@g) |
+------------+
| 25 |
+------------+
1 row in set
obclient [test]> SELECT HEX(@g);
+----------------------------------------------------+
| HEX(@g) |
+----------------------------------------------------+
| 000000000101000000000000000000F03F000000000000F0BF |
+----------------------------------------------------+
1 row in set
句法和几何合法性
句法合法性
句法合法需要满足如下条件:
- Linestring 需要至少 2 个点
- Polygon 需要至少一个环
- Polygon 是需要闭环的(首位的 2 个点相同)
- Polygon 的环至少需要 4 个点(最小的多边形是三角形,第一个点和最后一个点相同)
- 除了 GeometryCollection,其它的集合类型都不能为空
几何合法性
几何合法需要满足如下条件:
- Polygon 不能自己和自己相交
- Polygon 的外环要在内环外面
- Multipolygons 中不能存在重叠的多边形
通过 ST_IsValid() 函数可以显式检查几何对象的几何合法性。
GIS 示例
插入示例
//转换函数和 WKT 都放在 SQL 语句内
INSERT INTO geom VALUES (ST_GeomFromText('POINT(1 1)'));
//WKT 放在参数中
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
//转换表达式直接放在参数中
SET @g = ST_GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);
//使用统一的转换函数
SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
SET @g ='GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
//使用基于类型的转换函数
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_PointFromText(@g));
SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_LineStringFromText(@g));
SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (ST_PolygonFromText(@g));
SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomCollFromText(@g));
//也可以直接基于 WKB 进行插入
INSERT INTO geom VALUES(ST_GeomFromWKB(X'0101000000000000000000F03F000000000000F03F'));
查询示例
//查询并转换成 WKT 输出
SELECT ST_AsText(g) FROM geom;
//查询并转换为 WKB 输出
SELECT ST_AsBinary(g) FROM geom;