H3六边形索引有什么用?Python库怎么调?
《H3六边形索引有什么用?Python库怎么调?》这篇文章面向 GIS 学生、空间数据分析师和 Python GIS 入门用户,解决一个很具体的问题:当点数据很多、行政区边界不规则、网格统计又需要稳定尺度时,如何用 H3 六边形索引把经纬度点快速归入统一网格,并在 Python 中完成统计、可视化和导出。
引言:H3六边形索引适合解决什么 GIS 问题
H3六边形索引是 Uber 开源的一套全球离散网格系统。它把地球表面划分为不同分辨率的六边形格网,并给每个格子分配一个唯一索引。对 GIS 用户来说,它最常见的用途不是“画好看的六边形”,而是把点、轨迹、订单、POI、传感器位置等经纬度数据快速聚合到统一空间单元里。
如果你遇到下面这些场景,H3 往往比直接按行政区统计更灵活:
- 外卖订单、打车上下车点、用户签到点需要做空间热度统计。
- 不同城市之间需要用统一尺度比较空间分布。
- 点数据量很大,直接做点在面内分析速度慢。
- 需要把统计结果发布到 WebGIS 中,并按缩放级别加载不同精度。
- 想用 Python 快速完成网格化、聚合、导出 GeoJSON。

背景:为什么不用普通方格或行政区统计
在 GIS 分析中,常见的空间聚合单元有行政区、规则方格、鱼网、栅格像元和六边形网格。H3六边形索引的优势,主要体现在跨区域、跨尺度和程序化处理上。
行政区统计的问题
行政区边界适合做管理口径分析,但不适合所有空间问题。例如同样是一个街道,面积可能差异很大;同样的订单数量,放在大面积区域和小面积区域里,空间含义并不一样。行政区边界还会带来可变面元问题,也就是统计结果会受到分区方式影响。
普通方格的问题
方格容易生成,也容易计算,但方格的邻接关系不如六边形均衡。方格有 4 邻接和 8 邻接两种理解方式,斜向邻居距离与正向邻居距离不同。六边形每个格子通常有 6 个邻居,中心到邻居中心的距离更一致,适合做邻域扩散、热点平滑、覆盖分析等任务。
H3 的实际价值
H3 的核心价值是:把地球上的任意经纬度位置映射为一个字符串索引。这个索引既能代表空间位置,又能通过分辨率控制格网大小。你可以在数据库、Python、WebGIS 前端之间传递这个索引,而不必每次都重新做复杂的几何叠加。
原理:H3六边形索引到底是什么
H3六边形索引可以理解为一种全球网格编码。给定一个纬度、经度和分辨率,H3 会返回一个 cell id,例如一个十六进制风格的字符串。这个 cell id 对应地球表面的一个六边形单元。
H3 有多个分辨率级别。分辨率越低,六边形越大;分辨率越高,六边形越小。实际项目中,不要盲目选择最高分辨率,而要根据业务尺度决定。
| 分析场景 | 建议思路 | 注意点 |
|---|---|---|
| 全国或省域趋势 | 使用较低分辨率,先看总体格局 | 避免生成过多格子导致结果难以阅读 |
| 城市热点分析 | 使用中等分辨率,兼顾空间细节和统计稳定性 | 检查每个格子的样本量是否足够 |
| 街区级精细分析 | 使用较高分辨率 | 数据量不足时容易出现碎片化噪声 |
| WebGIS 分级显示 | 不同缩放级别使用不同 H3 分辨率 | 前端加载前最好先做后端聚合 |
需要特别注意:H3 的 Python 库通常使用 WGS84 经纬度坐标。也就是说,输入点应当是经纬度,而不是 Web Mercator 米制坐标、CGCS2000 投影坐标或地方投影坐标。如果坐标系不对,得到的 H3六边形索引也会完全错误。
步骤:Python库怎么调 H3 六边形索引
步骤 1:安装 Python H3 库
在 Python 环境中可以直接安装 H3 官方 Python 绑定库。建议先在虚拟环境中操作,避免和已有 GIS 环境冲突。
pip install h3 geopandas shapely pandas
如果你使用 Anaconda,也可以在新环境中安装。GeoPandas 依赖较多,Windows 用户如果安装失败,可以优先使用 conda-forge。
conda create -n h3gis python=3.11
conda activate h3gis
conda install -c conda-forge geopandas shapely pandas
pip install h3
步骤 2:把经纬度点转换为 H3 索引
下面示例用一组点数据演示如何生成 H3六边形索引。注意新版 h3-py 常用函数名是 latlng_to_cell,参数顺序是纬度、经度、分辨率。
import pandas as pd
import h3
df = pd.DataFrame({
"id": [1, 2, 3, 4],
"lon": [116.397, 116.398, 116.410, 116.420],
"lat": [39.908, 39.909, 39.915, 39.920]
})
resolution = 9
df["h3_cell"] = df.apply(
lambda row: h3.latlng_to_cell(row["lat"], row["lon"], resolution),
axis=1
)
print(df)
这里最容易写错的是经纬度顺序。很多 GIS 文件和 GeoJSON 使用经度、纬度顺序,但 H3 的 latlng_to_cell 使用纬度、经度顺序。只要顺序反了,点就会落到完全错误的位置。
步骤 3:按 H3 单元统计点数量
有了 H3 索引之后,普通表格统计就可以完成空间聚合。对于订单数、POI 数、事故点数量、访问量等点事件数据,这是最常见的用法。
grid_count = (
df.groupby("h3_cell")
.size()
.reset_index(name="point_count")
)
print(grid_count)
这一步的本质是把空间问题转换成分组统计问题。相比每次都做点面叠加,H3 索引可以更方便地进入数据库、缓存和前端渲染流程。
步骤 4:把 H3 单元转换为六边形边界
如果要在 QGIS、ArcGIS Pro 或 WebGIS 中显示结果,需要把 H3 cell id 转换为多边形几何。下面示例使用 cell_to_boundary 获取六边形边界,再构造 GeoDataFrame。
import geopandas as gpd
from shapely.geometry import Polygon
def h3_cell_to_polygon(cell):
boundary = h3.cell_to_boundary(cell)
coords = [(lng, lat) for lat, lng in boundary]
return Polygon(coords)
grid_count["geometry"] = grid_count["h3_cell"].apply(h3_cell_to_polygon)
gdf = gpd.GeoDataFrame(
grid_count,
geometry="geometry",
crs="EPSG:4326"
)
print(gdf)
这里也要注意坐标顺序。cell_to_boundary 返回的通常是纬度、经度坐标对,而 Shapely 的 Polygon 坐标需要经度、纬度顺序,所以示例中做了 (lng, lat) 的转换。
步骤 5:导出 GeoJSON 给 QGIS 或 WebGIS 使用
生成 GeoDataFrame 后,可以导出为 GeoJSON。这个结果可以直接拖入 QGIS,也可以作为 Leaflet、OpenLayers、MapLibre GL JS 的矢量数据源。
gdf.to_file("h3_point_count.geojson", driver="GeoJSON")
如果数据量较大,不建议把所有 H3 多边形一次性塞进前端。更稳妥的方式是先按地图视窗、城市范围或分辨率切片查询,再返回当前需要显示的 H3 结果。
步骤 6:把已有面范围填充为 H3 六边形
除了点转 H3,另一个常见需求是把一个行政区、研究区或服务区填充为 H3 格网。新版 h3-py 中可以使用多边形填充相关接口,但不同版本函数名可能有所变化。实际使用前建议查看当前安装版本的文档或用 dir(h3) 检查可用函数。
import h3
print(h3.__version__)
print([name for name in dir(h3) if "polygon" in name or "cells" in name])
如果你的版本支持 polygon_to_cells,可以把区域多边形转换为 H3 cells。处理真实项目时,务必确认输入多边形是 WGS84 经纬度坐标,并且外环、内洞方向符合库函数要求。
常见坑:H3六边形索引用错通常错在哪里
坑 1:坐标系不是 EPSG:4326
H3六边形索引通常基于经纬度坐标。如果你的点数据来自高德、百度、Web Mercator、地方投影或 CGCS2000 投影坐标,必须先确认坐标系并转换。尤其是米制坐标直接传给 H3,会得到没有意义的索引。
- 检查字段范围:经度通常在 -180 到 180,纬度通常在 -90 到 90。
- 检查中国区域数据:经度大致在 73 到 135,纬度大致在 18 到 54。
- 如果坐标值是几百万,通常不是经纬度。
坑 2:经纬度顺序写反
GeoJSON、Shapely 和多数 GIS 几何对象习惯使用经度、纬度顺序,而 H3 的点转索引函数通常使用纬度、经度。写代码时建议明确使用字段名,不要直接写位置参数。
cell = h3.latlng_to_cell(lat=39.908, lng=116.397, res=9)
如果你的 h3-py 版本不支持关键字参数,就保持清晰的变量名,避免把 lon 和 lat 放反。
坑 3:分辨率选得过高
H3 分辨率越高,格子越小,结果越细,但格子数量也会快速增加。对于样本量不大的点数据,高分辨率会让很多格子只有 1 个点,看起来像噪声,而不是可解释的空间格局。
建议先用较低或中等分辨率做探索,再逐步提高分辨率。每次调整后都检查每个 H3 单元的样本量分布,而不是只看地图是否“更细”。
坑 4:把 H3 当作精确面积统计工具
H3 的格网单元面积随纬度和分辨率会有差异,不能简单认为每个六边形面积完全相等。如果要做严谨面积统计,应当把结果投影到合适的等面积坐标系中,再进行面积计算。
坑 5:Python 库版本导致函数名不一致
h3-py 不同版本中函数名有过变化。例如旧资料中常见 geo_to_h3,新版中常见 latlng_to_cell。如果复制网上代码报错,先检查版本和函数列表。
import h3
print(h3.__version__)
print("latlng_to_cell" in dir(h3))
print("geo_to_h3" in dir(h3))
方法比较:H3、普通鱼网、Geohash 和行政区统计怎么选
| 方法 | 适合场景 | 优点 | 限制 |
|---|---|---|---|
| H3六边形索引 | 点数据聚合、热点分析、WebGIS 分级展示 | 全球统一编码,邻接关系清晰,适合程序化处理 | 需要注意经纬度顺序、分辨率和面积差异 |
| 普通方格鱼网 | 本地投影坐标下的规则网格分析 | 容易理解,QGIS 和 ArcGIS Pro 都容易生成 | 跨区域和多尺度管理不如 H3 方便 |
| Geohash | 位置编码、粗略空间检索、文本索引 | 字符串前缀具有空间层级特征 | 格子形状和邻接关系不如 H3 均衡 |
| 行政区统计 | 报表、管理单元、政策分析 | 业务解释性强,容易和人口经济数据关联 | 边界尺度不统一,容易受到分区方式影响 |
如果你的目标是业务报表,行政区统计通常更合适。如果你的目标是空间模式识别、热点分析、前端地图聚合或跨城市对比,H3六边形索引更值得优先考虑。
检查清单:做 H3 Python 分析前后要确认什么
- 坐标系:输入点是否为 WGS84 经纬度,是否需要从投影坐标转换。
- 字段顺序:调用 H3 函数时是否使用纬度、经度,而不是经度、纬度。
- 分辨率:所选分辨率是否匹配研究尺度,是否导致格子过密或过稀。
- 样本量:每个 H3 单元的点数量是否足够支撑分析结论。
- 边界转换:H3 边界转 Polygon 时是否把坐标顺序转换为经度、纬度。
- 导出格式:GeoJSON 是否声明 EPSG:4326,QGIS 中位置是否正确。
- 版本兼容:当前 h3-py 版本的函数名是否和示例代码一致。
- 前端性能:WebGIS 是否需要按视窗、缩放级别或瓦片方式加载。
FAQ:H3六边形索引常见问题
H3六边形索引有什么用?
H3六边形索引主要用于把地球表面的点、线、面数据映射到统一六边形网格中。最常见用途包括点数据聚合、热点分析、空间索引、邻域分析、轨迹统计和 WebGIS 分级渲染。
Python 调 H3 库时为什么结果位置不对?
最常见原因是坐标系或经纬度顺序错误。H3 通常要求输入 WGS84 经纬度,点转索引函数使用纬度、经度顺序;而 GeoJSON 和 Shapely 常用经度、纬度顺序。建议先打印坐标范围,再在 QGIS 中抽样核对结果。
H3 分辨率应该选多少?
没有固定答案。分辨率要根据研究尺度、点密度和地图展示比例决定。城市级热点分析通常先从中等分辨率试起,再根据每个格子的样本量和地图可读性调整。不要只追求更高分辨率。
H3 可以替代 PostGIS 空间索引吗?
不能简单替代。PostGIS 空间索引用于加速几何查询,H3 更像一种离散空间编码和聚合单元。在实际项目中,两者可以配合使用:PostGIS 存储和查询空间数据,H3 用于预聚合、分级统计和前端展示。
QGIS 能不能直接显示 H3 结果?
可以。用 Python 把 H3 cell 转换成 Polygon 后导出 GeoJSON、GeoPackage 或 Shapefile,就能在 QGIS 中加载显示。推荐使用 GeoJSON 或 GeoPackage,字段和坐标系处理更方便。
H3 六边形面积完全一样吗?
不完全一样。H3 的格网面积会随位置和分辨率变化。如果只是做点数量聚合,通常影响不大;如果要做严谨密度或面积统计,应使用合适的等面积投影,并明确计算口径。
结论:把 H3 当作“空间分组键”来用
理解 H3六边形索引的关键,不是记住某个函数名,而是把它看作空间数据的分组键。经纬度点先转换为 H3 cell id,再用普通表格分组统计,最后把 cell id 转回六边形几何用于 GIS 展示。
在 Python 工作流中,最小可用流程就是:安装 h3,用 latlng_to_cell 生成索引,用 groupby 统计,用 cell_to_boundary 转几何,再用 GeoPandas 导出 GeoJSON。只要坐标系、经纬度顺序和分辨率选型不出错,H3 就能成为点数据聚合和 WebGIS 可视化中非常实用的工具。