h3
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
pg_h3 | 4.2.3 | GIS | Apache-2.0 | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 1530 | h3 | 否 | 是 | 否 | 是 | 否 | 是 | - |
| 1531 | h3_postgis | 否 | 是 | 否 | 是 | 否 | 是 | - |
| 相关扩展 | postgis q3c pg_geohash postgis_topology postgis_raster postgis_sfcgal postgis_tiger_geocoder address_standardizer |
|---|---|
| 下游依赖 | h3_postgis |
pgdg missing el8.x86.pg17 and el8.x86.pg18
版本
| 类型 | 仓库 | 版本 | PG 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | PGDG | 4.2.3 | 1817161514 | pg_h3 | - |
| RPM | PGDG | 4.2.3 | 1817161514 | h3-pg_$v | - |
| DEB | PGDG | 4.2.3 | 1817161514 | postgresql-$v-h3 | - |
安装
您可以直接安装 pg_h3 扩展包的预置二进制包,首先确保 PGDG 仓库已经添加并启用:
pig repo add pgdg -u # 添加 PGDG 仓库并更新缓存
使用 pig 或者是 apt/yum/dnf 安装扩展:
pig install pg_h3; # 当前活跃 PG 版本安装
pig ext install -y pg_h3 -v 18 # PG 18
pig ext install -y pg_h3 -v 17 # PG 17
pig ext install -y pg_h3 -v 16 # PG 16
pig ext install -y pg_h3 -v 15 # PG 15
pig ext install -y pg_h3 -v 14 # PG 14
dnf install -y h3-pg_18 # PG 18
dnf install -y h3-pg_17 # PG 17
dnf install -y h3-pg_16 # PG 16
dnf install -y h3-pg_15 # PG 15
dnf install -y h3-pg_14 # PG 14
apt install -y postgresql-18-h3 # PG 18
apt install -y postgresql-17-h3 # PG 17
apt install -y postgresql-16-h3 # PG 16
apt install -y postgresql-15-h3 # PG 15
apt install -y postgresql-14-h3 # PG 14
创建扩展:
CREATE EXTENSION h3;
用法
该扩展为 H3 核心库(Uber 的六边形层次地理空间索引系统)提供 PostgreSQL 绑定。完整 API 参考请参见 H3 文档。
通常,所有函数都从 H3 的 camelCase 重命名为 SQL 的 snake_case,并加上 h3_ 前缀。
CREATE EXTENSION h3;
SELECT h3_latlng_to_cell(POINT('37.3615593,-122.0553238'), 5);
h3_latlng_to_cell
-------------------
85e35e73fffffff
基础类型
h3index 类型是一个无符号 64 位整数,表示任何 H3 对象(六边形、五边形、有向边等),以 16 字符的十六进制字符串显示,如 '8928308280fffff'。
索引函数
这些函数用于查找包含指定坐标的 H3 索引,以及获取 H3 索引的中心和边界。
-- 在指定分辨率(0-15)索引一个位置
SELECT h3_latlng_to_cell(POINT('37.3615593,-122.0553238'), 5);
-- 查找索引的质心
SELECT h3_cell_to_latlng('85283473fffffff'::h3index);
-- 查找索引的边界多边形
SELECT h3_cell_to_boundary('85283473fffffff'::h3index);
使用 SET h3.extend_antimeridian TO true 可在跨越 180 度经线时扩展坐标。
索引检查函数
-- 获取索引的分辨率(0-15)
SELECT h3_get_resolution('85283473fffffff'::h3index);
-- 获取基础单元格编号
SELECT h3_get_base_cell_number('85283473fffffff'::h3index);
-- 验证 H3 索引
SELECT h3_is_valid_cell('85283473fffffff'::h3index);
-- 检查索引是否为五边形
SELECT h3_is_pentagon('85283473fffffff'::h3index);
-- 检查分辨率是否为 Class III 方向
SELECT h3_is_res_class_iii('85283473fffffff'::h3index);
-- 查找索引相交的所有二十面体面
SELECT h3_get_icosahedron_faces('85283473fffffff'::h3index);
网格遍历函数
网格遍历可以查找起始单元格附近的单元格,以及确定从一个单元格到另一个单元格的遍历路径。
-- 获取距起点 k 步以内的所有索引
SELECT h3_grid_disk('85283473fffffff'::h3index, 2);
-- 带距离的索引
SELECT * FROM h3_grid_disk_distances('85283473fffffff'::h3index, 2);
-- 距离为 k 的空心六边形环
SELECT h3_grid_ring_unsafe('85283473fffffff'::h3index, 1);
-- 两个单元格之间的索引路径(含端点)
SELECT h3_grid_path_cells('85283473fffffff'::h3index, '8528342bfffffff'::h3index);
-- 两个索引之间的网格距离
SELECT h3_grid_distance('85283473fffffff'::h3index, '8528342bfffffff'::h3index);
-- 局部 IJ 坐标
SELECT h3_cell_to_local_ij('85283473fffffff'::h3index, '8528342bfffffff'::h3index);
SELECT h3_local_ij_to_cell('85283473fffffff'::h3index, POINT(0,0));
层次网格函数
在 H3 网格系统中的不同分辨率之间移动,生成父级(更粗)或子级(更细)单元格。
-- 获取更粗分辨率的父单元格
SELECT h3_cell_to_parent('85283473fffffff'::h3index, 3);
-- 获取更细分辨率的所有子单元格
SELECT h3_cell_to_children('85283473fffffff'::h3index, 7);
-- 获取更细分辨率的中心子单元格
SELECT h3_cell_to_center_child('85283473fffffff'::h3index, 7);
-- 压缩单元格数组
SELECT h3_compact_cells(ARRAY['85283473fffffff'::h3index, '85283477fffffff'::h3index]);
-- 解压到目标分辨率
SELECT h3_uncompact_cells(ARRAY['85283473fffffff'::h3index], 7);
-- 获取子单元格在父单元格子列表中的位置
SELECT h3_cell_to_child_pos('872834700ffffff'::h3index, 5);
-- 获取指定位置的子单元格
SELECT h3_child_pos_to_cell(0, '85283473fffffff'::h3index, 7);
区域函数
在 H3 索引和多边形区域之间互转。
-- 用指定分辨率的六边形填充多边形
SELECT h3_polygon_to_cells(
'((37.7,-122.5),(37.8,-122.5),(37.8,-122.4),(37.7,-122.4))'::polygon,
NULL::polygon[],
5
);
-- 获取一组六边形的轮廓多边形
SELECT * FROM h3_cells_to_multi_polygon(
ARRAY['85283473fffffff'::h3index, '85283477fffffff'::h3index]
);
单向边函数
编码从一个单元格到相邻单元格的有向边。
-- 检查两个单元格是否相邻
SELECT h3_are_neighbor_cells('85283473fffffff'::h3index, '85283477fffffff'::h3index);
-- 获取相邻单元格之间的有向边
SELECT h3_cells_to_directed_edge('85283473fffffff'::h3index, '85283477fffffff'::h3index);
-- 验证边
SELECT h3_is_valid_directed_edge(edge) FROM ...;
-- 从边获取起点和终点
SELECT h3_get_directed_edge_origin(edge);
SELECT h3_get_directed_edge_destination(edge);
-- 以记录形式获取两端
SELECT * FROM h3_directed_edge_to_cells(edge);
-- 从一个单元格出发的所有边
SELECT h3_origin_to_directed_edges('85283473fffffff'::h3index);
-- 边界坐标
SELECT h3_directed_edge_to_boundary(edge);
顶点函数
-- 获取单元格的单个顶点
SELECT h3_cell_to_vertex('85283473fffffff'::h3index, 0);
-- 获取单元格的所有顶点
SELECT h3_cell_to_vertexes('85283473fffffff'::h3index);
-- 获取顶点的地理坐标
SELECT h3_vertex_to_latlng(vertex);
-- 验证顶点
SELECT h3_is_valid_vertex(vertex);
杂项函数
-- 两点之间的大圆距离(km、m 或 rads)
SELECT h3_great_circle_distance(POINT(37.7,-122.5), POINT(40.7,-74.0), 'km');
-- 指定分辨率的六边形平均面积
SELECT h3_get_hexagon_area_avg(5, 'km^2');
-- 特定单元格的精确面积
SELECT h3_cell_area('85283473fffffff'::h3index, 'km^2');
-- 指定分辨率的平均边长
SELECT h3_get_hexagon_edge_length_avg(5, 'km');
-- 精确边长
SELECT h3_edge_length(edge, 'km');
-- 指定分辨率的唯一单元格数
SELECT h3_get_num_cells(5);
-- 全部 122 个分辨率 0 的单元格
SELECT h3_get_res_0_cells();
-- 指定分辨率的所有五边形
SELECT h3_get_pentagons(5);
运算符
-- 网格距离运算符
SELECT '85283473fffffff'::h3index <-> '8528342bfffffff'::h3index;
-- B-tree 等于/不等于
SELECT a = b, a <> b FROM ...;
-- R-tree 空间运算符
SELECT a && b -- 相交
SELECT a @> b -- 包含
SELECT a <@ b -- 被包含
SP-GiST 索引(实验性)
CREATE INDEX spgist_idx ON h3_data USING spgist(hex h3index_ops_experimental);
类型转换
-- H3 索引与 bigint 互转
SELECT '85283473fffffff'::h3index::bigint;
SELECT 599686042433355775::bigint::h3index;
-- H3 索引转 point
SELECT '85283473fffffff'::h3index::point;
PostGIS 集成
传递给 h3-pg PostGIS 函数的 GEOMETRY 数据应使用 SRID 4326。使用其他 SRID(如 3857)可能导致错误或无效数据。
PostGIS 集成需要伴随扩展 h3_postgis:
CREATE EXTENSION h3_postgis CASCADE;
-- 对 PostGIS 几何体建立指定分辨率的索引
SELECT h3_latlng_to_cell(geom, 9) FROM points;
-- 将 H3 单元格转换为 PostGIS geometry/geography
SELECT h3_cell_to_geometry('85283473fffffff'::h3index);
SELECT h3_cell_to_geography('85283473fffffff'::h3index);
-- 单元格边界转 PostGIS 几何体(在反子午线处分割)
SELECT h3_cell_to_boundary_geometry('85283473fffffff'::h3index);
-- 用 H3 单元格填充 PostGIS 多边形
SELECT h3_polygon_to_cells(geom, 7) FROM polygons;
-- 将 H3 单元格转回 PostGIS 多多边形
SELECT h3_cells_to_multi_polygon_geometry(ARRAY['85283473fffffff'::h3index]);
-- PostGIS 索引运算符
SELECT geom @ 9 FROM points; -- geometry @ resolution
栅格处理
对于连续栅格数据(温度、高程等),汇总 H3 单元格内的像素值:
SELECT
(summary).h3 AS h3,
(h3_raster_summary_stats_agg((summary).stats)).*
FROM (
SELECT h3_raster_summary(rast, 8) AS summary
FROM rasters
) t
GROUP BY 1;
对于离散/分类栅格数据(土地覆盖、土地利用),按 H3 单元格聚合分类统计:
SELECT
h3,
jsonb_object_agg(
concat('class_', val::text),
h3_raster_class_summary_item_to_jsonb(item)
ORDER BY val
) AS summary
FROM (
SELECT h3, val, h3_raster_class_summary_item_agg(summary) AS item
FROM rasters, h3_raster_class_summary(rast, 8)
GROUP BY 1, 2
) t
GROUP BY 1;
栅格汇总方法:h3_raster_summary(自动选择)、h3_raster_summary_clip(按单元格几何体裁剪)、h3_raster_summary_centroids(按像素质心分组)、h3_raster_summary_subpixel(适用于亚像素 H3 单元格)。分类汇总也有相同的变体。