Google S2的希尔伯特曲线应用如何解决Geohash近邻单元格前缀不一致问题
Google S2 解决 Geohash 相邻点哈希跳变问题的核心原理
Geohash的相邻点哈希值完全不同的问题根源是采用了Z阶空间填充曲线,跨空间划分块时曲线数值会出现大幅跳变,同时依赖前缀匹配做空间查询的逻辑也无法覆盖跳变场景。S2针对该问题的优化思路如下:
- 采用希尔伯特曲线作为空间填充曲线
不同于Geohash使用的Z阶曲线,希尔伯特曲线的空间连续性更强,地理空间上相邻的点,映射到希尔伯特曲线上的位置绝大多数都是连续的,从根源上大幅降低了相邻点的Cell ID出现大幅跳变的概率。 - 球面到平面的映射更合理
S2先将地球球面投影到立方体的6个面上,每个立方体面内部是连续的平面空间,避免了Geohash直接拆分经纬度导致的极点、国际日期变更线附近的严重划分畸变,进一步减少了边界跳变场景。 - 不依赖前缀匹配做空间查询
S2做空间范围查询时,不会用前缀匹配逻辑,而是先把目标查询范围(比如周边5公里、指定矩形区域)映射为一组S2单元格的覆盖集合,直接检索这组单元格内的所有数据即可。如果是相邻点查询,S2原生支持获取任意单元格的8个相邻单元格ID,只要将目标单元格和相邻单元格都纳入检索范围,就能完全覆盖极少数可能出现的边界跳变场景,不会出现漏查。 - Cell ID本身支持范围检索
S2的Cell ID是64位整型,同一父级单元格下的所有子级单元格ID都落在连续的数值区间内,就算出现小范围跳变,也可以通过数值范围查询完成同一父级区域的全量检索,检索效率比Geohash的前缀匹配更高。
内容的提问来源于stack exchange,提问作者Aung Khant
相关产品推荐
相关产品推荐

