如何在类Yelp、Uber的位置服务场景中使用S2地理库?
S2 周边检索场景落地与底层逻辑答疑
周边餐厅检索场景S2接入流程
你可以直接按照以下步骤替换原有自行维护四叉树的方案:
- 预处理全量餐厅数据:为每个餐厅的经纬度生成对应检索精度层级的S2 Cell ID,和餐厅基础信息一并存入数据库,同时为S2 Cell ID字段建立普通索引即可。
参考生成逻辑示例:S2CellId.FromLatLng(S2LatLng.FromDegrees(餐厅纬度, 餐厅经度)).parent(目标层级)
建议本地生活场景选择1517级S2层级,对应精度10米100米,完全覆盖周边检索的精度需求 - 处理用户查询请求:拿到用户经纬度和查询半径后,先将该圆形查询区域转换为S2 Cell覆盖集合,该集合会包含所有可能落在查询范围内的S2 Cell
- 召回候选数据:用覆盖集合中的所有S2 Cell ID作为检索条件,从数据库中批量命中对应Cell下的餐厅,得到初步候选集
- 精确过滤结果:对候选集做精确的球面距离计算,过滤掉超出查询半径的无效数据,返回最终结果即可
是否可以替代自行维护四叉树
完全可以,不需要再自行维护四叉树。
你自行维护四叉树需要额外处理节点分裂、邻接节点查询、多节点数据同步、精度适配等大量工程问题,S2已经把所有空间索引的底层逻辑封装完成,官方提供了多语言的实现库,直接调用即可,鲁棒性和查询效率都远高于自定义实现的四叉树。
底层逻辑认知验证
你的理解基本正确,补充两点细节即可:
- S2的四叉树是构建在单位球面上的,没有平面四叉树的投影变形问题,全球任意位置的Cell精度都是统一的,更适配跨地域的LBS服务
- 64位S2 Cell ID本身已经编码了四叉树的层级、节点路径等全部信息,且相邻位置的Cell ID因为希尔伯特曲线的特性,数值上大概率是连续的,天然适配数据库的范围查询特性,不需要额外做邻接节点的遍历逻辑
内容的提问来源于stack exchange,提问作者Dipen
相关产品推荐
相关产品推荐

