跳到主要内容

Geospatial

Databend 提供两种数据类型来存储空间数据:

  • GEOMETRY:基于平面坐标(默认 SRID 为 0,也可指定任意 SRID),适用于局部或投影坐标系的场景。
  • GEOGRAPHY:基于球面坐标(WGS 84,SRID 4326),会对经纬度进行校验,适用于全球范围的场景。

这两种类型都将坐标以 IEEE 754 Float64 格式存储在 EWKB 中,支持从 Point 到 GeometryCollection 的所有常见几何对象,能够输出 WKT/WKB/GeoJSON 格式,并支持通过 ST_TRANSFORM 等函数进行坐标投影转换。

数据类型

GEOMETRY

  • 使用笛卡尔坐标系,非常适合校园、城市或省份等可以使用平面数学计算的场景。
  • 默认 SRID 为 0;在创建列或写入数据时可以指定其他 SRID。
  • 支持大多数空间操作符,并可通过 ST_TRANSFORM 转换为其他投影供下游使用。

GEOGRAPHY

  • 存储 WGS 84 (SRID 4326) 标准的经纬度对;超出 [-180°, 180°] / [-90°, 90°] 范围的值将被拒绝。
  • 推荐用于需要椭球公式计算的跨洲或全球距离/面积计算。
  • 当需要使用平面算法时,可以转换为 GEOMETRY 类型。
特性GEOMETRYGEOGRAPHY
坐标系笛卡尔 (平面)椭球 (球面)
SRID0 (默认) 或自定义仅限 4326 (WGS 84)
X / Y 含义平面上的 X, Y球面上的经度, 纬度
边线含义平面直线大圆弧 (球面最短路径)
主要用途局部 / 投影数据 (如城市、建筑)全球数据 (如 GPS 轨迹、航线)

精度与坐标控制

  • 全程双精度ST_MAKEPOINTST_GEOMETRYFROMEWKT 等函数接收 Float64 值并以 EWKB 格式持久化,从而保留坐标的原始精度。
  • SRID 行为:GEOMETRY 保留你指定的任意 SRID(默认为 0),而 GEOGRAPHY 固定为 SRID 4326 并拒绝其他 SRID。
  • 坐标安全:GEOGRAPHY 的输入会经过 check_point 检查,确保经纬度在 [-180°, 180°] / [-90°, 90°] 范围内。
  • 投影转换ST_TRANSFORM 可以转换 GEOMETRY 的 SRID(例如 4326 → 3857),或者将 GEOGRAPHY 数据转换为平面系统以便进行后续处理。

支持的对象类型

对象类型描述与示例精度说明
Point单个坐标点,例如 POINT(113.98765432109876 23.456789012345678)每个坐标存储为 Float64,保留约 15–16 位有效数字。
LineString连通路径,例如 LINESTRING(10 20, 30 40, 50 60)每个顶点都使用相同的双精度存储,因此计算出的长度依赖于原始值的精度。
Polygon闭合区域,例如 POLYGON((10 20, 30 40, 50 60, 10 20))所有环共享 Float64 顶点,保证多边形边缘在面积/包含测试中的精度。
MultiPoint多点集合,例如 MULTIPOINT((10 20), (30 40))集合中的每个点都继承了独立点的双精度存储特性。
MultiLineString多路径集合,例如 MULTILINESTRING((10 20, 30 40), (50 60, 70 80))每个顶点都保持精度,确保长度或交集计算准确。
MultiPolygon多区域集合,例如 MULTIPOLYGON(((10 20, 30 40, 50 60, 10 20)), ((15 25, 25 35, 35 45, 15 25)))每个多边形的坐标保持 Float64,因此合并区域/重叠部分保留完整精度。
GeometryCollection混合对象集合,例如 GEOMETRYCOLLECTION(POINT(10 20), LINESTRING(10 20, 30 40))无论几何类型如何,成员都保留其原生的双精度坐标。

输出格式

Databend 将空间值持久化为 EWKB,但也提供多种输出格式。你可以设置 geometry_output_format 会话参数(默认:WKT)或调用显式转换函数:

  • WKT / EWKT – 文本表示;EWKT 会添加 SRID 前缀(例如 SRID=4326;POINT(-44.3 60.1))。
  • WKB / EWKB – 紧凑的二进制格式,便于与其他 GIS 运行时互操作。
  • GeoJSON – JSON 表示,适用于 Web 地图和 API。
SET geometry_output_format = 'GeoJSON';
SELECT ST_ASWKB(geo), ST_ASEWKT(geo), ST_ASGEOJSON(geo) FROM ...;

函数

查看完整的空间函数列表:

示例

以下每个示例展示了一种对象类型、它解决的场景、生成它的 SQL 以及示例结果表。CAST('…' AS GEOMETRY) 用于解析内联 WKT 字面量,方便你在不创建表的情况下进行实验。

Point — 定位单个传感器

场景:存储 IoT 设备生成的精确经纬度,并同时展示 GeoJSON 和数值坐标。

SELECT
ST_ASGEOJSON(pt) AS sensor_geojson,
ST_X(pt) AS lon,
ST_Y(pt) AS lat
FROM (SELECT CAST('POINT(113.98765432109876 23.456789012345678)' AS GEOMETRY) AS pt);
┌──────────────────────────────────────────────────────────────────────────────┬──────────────────────┬──────────────────────┐
│ sensor_geojson │ lon │ lat │
├──────────────────────────────────────────────────────────────────────────────┼──────────────────────┼──────────────────────┤
│ {"type":"Point","coordinates":[113.98765432109876,23.456789012345677]} │ 113.98765432109876 │ 23.456789012345677 │
└──────────────────────────────────────────────────────────────────────────────┴──────────────────────┴──────────────────────┘

LineString — 描述路径

场景:记录一条简单的驾驶路线,并以坐标单位测量其长度。

SELECT
ST_ASWKT(route) AS road_segment,
ST_LENGTH(route) AS segment_length
FROM (SELECT CAST('LINESTRING(10 20, 30 40, 50 60)' AS GEOMETRY) AS route);
┌──────────────────────────────────────────────────────────────┬────────────────────┐
│ road_segment │ segment_length │
├──────────────────────────────────────────────────────────────┼────────────────────┤
│ LINESTRING(10 20,30 40,50 60) │ 56.568542495 │
└──────────────────────────────────────────────────────────────┴────────────────────┘

Polygon — 捕获区域或地理围栏

场景:为设施定义一个矩形地理围栏,读取其 SRID 信息,并计算其面积。

SELECT
ST_ASEWKT(area) AS ewkt_polygon,
ST_AREA(area) AS area_units
FROM (SELECT CAST('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))' AS GEOMETRY) AS area);
┌──────────────────────────────────────────────────────────────┬──────────────┐
│ ewkt_polygon │ area_units │
├──────────────────────────────────────────────────────────────┼──────────────┤
│ POLYGON((0 0,0 10,10 10,10 0,0 0)) │ 100 │
└──────────────────────────────────────────────────────────────┴──────────────┘

MultiPoint — 标记多个地点

场景:将三个服务亭的坐标保存在一起,并报告 GeoJSON 数据和总数。

SELECT
ST_ASGEOJSON(places) AS places_geojson,
ST_NUMPOINTS(places) AS total_sites
FROM (SELECT CAST('MULTIPOINT((10 20), (30 40), (50 60))' AS GEOMETRY) AS places);
┌──────────────────────────────────────────────────────────────┬──────────────┐
│ places_geojson │ total_sites │
├──────────────────────────────────────────────────────────────┼──────────────┤
│ {"type":"MultiPoint","coordinates":[[10,20],[30,40],[50,60]]} │ 3 │
└──────────────────────────────────────────────────────────────┴──────────────┘

MultiLineString — 表示平行线

场景:组合两条平行的路段,将其读取为 WKT,并使用 ST_NUMPOINTS 统计总顶点数。

SELECT
ST_ASWKT(lines) AS multiline_wkt,
ST_NUMPOINTS(lines) AS vertex_count
FROM (SELECT CAST('MULTILINESTRING((10 20, 30 40), (50 60, 70 80))' AS GEOMETRY) AS lines);
┌──────────────────────────────────────────────────────────────┬──────────────┐
│ multiline_wkt │ vertex_count │
├──────────────────────────────────────────────────────────────┼──────────────┤
│ MULTILINESTRING((10 20,30 40),(50 60,70 80)) │ 4 │
└──────────────────────────────────────────────────────────────┴──────────────┘

MultiPolygon — 覆盖不相连的区域

场景:表示两个不相连的服务区域,并计算总面积。

SELECT
ST_ASGEOJSON(zones) AS zones_geojson,
ST_AREA(zones) AS total_area
FROM (
SELECT CAST('MULTIPOLYGON(((0 0, 0 10, 10 10, 10 0, 0 0)), ((20 0, 20 10, 30 10, 30 0, 20 0)))' AS GEOMETRY) AS zones
);
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬──────────────┐
│ zones_geojson │ total_area │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────┤
│ {"type":"MultiPolygon","coordinates":[[[[0,0],[0,10],[10,10],[10,0],[0,0]]],[[[20,0],[20,10],[30,10],[30,0],[20,0]]]]} │ 200 │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────┘

GeometryCollection — 混合不同形状

场景:将地标标记及其连接路径保存在一起,展示混合的 GeoJSON 和最大维度。

SELECT
ST_ASGEOJSON(feature) AS feature_geojson,
ST_DIMENSION(feature) AS max_dimension
FROM (
SELECT CAST('GEOMETRYCOLLECTION(POINT(10 20), LINESTRING(10 20, 30 40))' AS GEOMETRY) AS feature
);
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬───────────────┐
│ feature_geojson │ max_dimension │
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼───────────────┤
│ {"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[10,20]},{"type":"LineString","coordinates":[[10,20],[30,40]]}]} │ 1 │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴───────────────┘
欢迎体验 Databend Cloud

基于 Rust + 对象存储构建的新一代多模态数仓,一个平台即可进行 BI、向量、全文检索及地理空间分析。

支持标准 SQL,自动弹性伸缩,助您快速构建现代化数据平台。

注册即领 ¥200 代金券。

注册体验