跳到主要内容

空间格式转换函数

空间格式转换函数用于在不同空间数据表示格式之间转换,如将几何对象转换为文本或二进制格式。

seekdb 当前所支持的空间格式转换函数包括 ST_AsGeoJSON_ST_AsMVTST_AsMVTGeom

ST_AsGeoJSON

ST_AsGeoJSON 函数用于将一个几何对象(geometry)转换成 GeoJSON 格式的字符串。GeoJSON 是一种基于 JSON(JavaScript Object Notation)的地理空间数据交换格式。GeoJSON 标准主要支持的几何类型包括点(Point)、多点(MultiPoint)、线串(LineString)、多线串(MultiLineString)、多边形(Polygon)和多多边形(MultiPolygon)。

语法如下:

ST_AsGeoJSON(g [, max_dec_digits [, options]])

参数释义:

  • g:这是函数的主要参数,表示要转换为 GeoJSON 的几何对象,几何对象 g 必须是有效的。

  • max_dec_digits (可选):用于控制输出的 GeoJSON 字符串的精度,即坐标点小数点后的最大显示位数。

    • 若不指定,默认为最大值(232 - 1)。
    • 最小指定值为 0。
  • options (可选):为 3 个比特位开关,用于控制在 Json 中是否输出边界框(bounding box),CRS 等信息。

    • 0:默认值,全部关闭。
    • 1:打开 Bbox 输出。
    • 2:打开 CRS 短格式输出(EPSG:srid)。
    • 4:打开 CRS 长格式输出(urn:ogc:def:crs:EPSG::srid),若同时打开长格式和短格式输出,输出为长格式。

以下示例中,ST_AsGeoJSON 函数将几何对象转换为 GeoJSON 格式的字符串。不同的查询展示了如何使用 ST_AsGeoJSON 函数的 flag 参数来控制输出的 GeoJSON 字符串。

示例 1 如下:

-- 使用 flag 参数来控制 GeoJSON 输出的选项,flag 的值从 0(二进制 000)到 7(二进制 111)。
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,0);

使用 ST_AsGeoJSON 函数,将一个点几何对象转换为 GeoJSON,且不带任何额外的属性(例如,边界框或坐标系)。

返回结果如下:

+---------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,0) |
+---------------------------------------------------------------------+
| {"type": "Point", "coordinates": [12.2, 11.1]} |
+---------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 2 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,1);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 1,以包含边界框信息。

返回结果如下:

+----------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,1) |
+----------------------------------------------------------------------------------+
| {"bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+----------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 3 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,2);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 2,以包含简单坐标参考系统(CRS)信息。

返回结果如下:

+--------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,2) |
+--------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+--------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 4 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,3);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 3,以包含边界框信息和简单坐标参考系统(CRS)信息。

返回结果如下:

+------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,3) |
+------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 5 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,4);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 4,以包含详细坐标参考系统(CRS)信息。

返回结果如下:

+-------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,4) |
+-------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 6 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,5);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 5,以包含详细坐标参考系统(CRS)信息和边界框。

返回结果如下:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,5) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 7 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,6);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 6,该值与 4 的输出相同,包含详细坐标参考系统(CRS)信息。

返回结果如下:

+-------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,6) |
+-------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "type": "Point", "coordinates": [12.2, 11.1]} |
+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 8 如下:

SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,7);

使用 ST_AsGeoJSON 函数,并设置 flag 参数为 7,该值与 5 的输出相同,包含详细坐标参考系统(CRS)信息和边界框。

返回结果如下:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)', 4326),1,7) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4326"}}, "bbox": [12.2, 11.1, 12.2, 11.1], "type": "Point", "coordinates": [12.2, 11.1]} |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

_ST_AsMVT

_ST_AsMVT 函数用于将表中含有地理信息系统(GIS)的所有行数据聚合,返回一个使用 Google Protocol Buffers(Protobuf)进行二进制编码格式的 mapbox 矢量瓦片。

语法如下:

_ST_AsMVT(table_name.*, text name, integer extent, text geom_name, text feature_id_name);

参数释义:

  • table_name.*:这代表查询返回的所有列,用于构建矢量瓦片。通常使用星号(*)来选择表中的所有列。这个参数必须指向一个真实存在的表,并且该表应当包含空间数据列。
  • text name (可选):这是矢量图层的名称。在生成的 MVT 中,这个名称将用于标识对应的图层。
  • integer extent (可选):这是矢量瓦片的像素范围。这个整数定义了切片的空间范围,通常是 4096 或 256 等常用值。
  • text geom_name (可选):这是表中用于表示几何数据的列名。
  • text feature_id_name (可选):这是表中用于表示特征唯一标识符(Feature ID)的列名。

示例如下:

SELECT 'TG1', hex(_ST_AsMVT(q.*, 'test', 4096, 'geom')) FROM (SELECT 1 AS c1, ST_GeomFromText('POINT(25 17)')AS geom) AS q;

在这个示例中,_ST_AsMVT 函数将查询结果集中的空间数据转换为 Mapbox Vector Tile (MVT) 格式的矢量瓦片。我们构造了一个内联查询(子查询)q,它只包含一个具有常量值 1 的列 c1 和一个通过 ST_GeomFromText 函数创建的 POINT 几何对象 geom。

然后,将子查询的结果集 q.* 作为 _ST_AsMVT 函数的输入,其中包括:

  • 'TG1':一个简单的字符串,用作查询结果集中的第一个字段。
  • hex(_ST_AsMVT(q.*, 'test', 4096, 'geom')):调用 _ST_AsMVT 函数,并将结果转换为十六进制字符串。函数参数中 'test' 为图层名,4096 为瓦片范围,'geom' 指定了 geom 列用于生成 MVT 数据。

最终结果显示了编码后的十六进制字符串,包含了字段 c1 的值 1 和 POINT(25 17) 几何对象。

返回结果如下:

+-----+----------------------------------------------------------------------+
| TG1 | hex(_ST_AsMVT(q.*, 'test', 4096, 'geom')) |
+-----+----------------------------------------------------------------------+
| TG1 | 1A200A0474657374120B12020000180122030932221A026331220228012880207802 |
+-----+----------------------------------------------------------------------+
1 row in set (0.001 sec)

ST_AsMVTGeom

ST_AsMVTGeom 函数用于将空间对象按 Mapbox Vector Tile (MVT) 标准转换至相应坐标系。该函数确保转换后的几何对象与 MVT 规范相符,并适用于瓦片渲染。如果几何对象超出了 bounds 定义的矩形边界,但仍在 buffer 设置的缓冲区内,其裁剪行为将由 clip_geom 参数决定。MVT 坐标系的原点在左上角,符合屏幕坐标系统的习惯。最终,函数输出兼容 MVT 规范的有效几何对象,通常用作 ST_AsMVT 函数的输入参数。

语法如下:

ST_AsMVTGeom(geometry geom, box2d bounds, integer extent=4096, integer buffer=256, boolean clip_geom=true);

参数释义:

  • geom:要转换的输入几何对象,geom 必须是一个有效的几何对象。
  • bounds:定义瓦片边界的二维盒子。通常这个盒子是由四个值(xmin, ymin, xmax, ymax)定义的矩形区域,表示瓦片的空间范围。
  • integer extent=4096 (可选):矢量瓦片的像素范围,默认值是 4096,且必须为非负整数。
  • integer buffer=256 (可选):在瓦片边界外添加的缓冲区大小,默认值是 256 像素,且必须为非负整数。
  • boolean clip_geom=true (可选):一个布尔值,指示是否应该裁剪在瓦片边界外但在缓冲区内的几何数据,以减小输出瓦片的大小。默认值为 true,表示对超出边界的部分进行裁剪。

示例 1 如下:

SELECT ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, false));

在这个示例中,使用 ST_AsMVTGeom 函数将一个给定的 POLYGON 几何对象转换为 MVT 格式:

首先,我们定义一个 POLYGON 几何对象作为输入 然后,我们定义瓦片的 bounds 为一个 4096*4096 像素的区域;将 extent 设置为 4096,表示瓦片的尺寸;将 buffer 设置为 0,表示在瓦片边界外没有额外的缓冲区;将 clip_geom 设置为 false,表示不裁剪超出 bounds 的几何部分。 最终,通过 ST_AsText 函数将转换后的几何对象转换为文本格式

返回结果如下:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, false)) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 4101,0 4096,10 4091,10 4096,0 4101)) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

示例 2 如下:

SELECT ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, true));

在这个示例中,使用相同的输入几何对象和 bounds,但这次将 clip_geom 设置为 true,ST_AsMVTGeom 函数会裁剪超出 bounds 的几何部分。

返回结果如下:

+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_AsText(_ST_AsMVTGeom(ST_GeomFromText('POLYGON ((0 0, 0 -5, 10 0, 10 5, 0 0))'),ST_GeomFromText('POLYGON((0 0,0 4096,4096 4096,4096 0,0 0))'),4096, 0, true)) |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| POLYGON((10 4096,0 4096,10 4091,10 4096)) |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)