《我是程序媛》之地图网格系统Grids,主要用来实现通勤找房的产品需求。
背景
- 给用户提供更好的找房产品,产品需求叫“通勤找房”:
- 直线距离找房误差较大,效果差,app上原来有此方案但是已经下线;
- 网站的写字楼找房只提供了固定的“x分钟路程”,没有结合交通方式;
- 通过滑动条更改通勤时间,而不是固定时间;
- 列表页的查询数据和地图找房数据差距较大;
- 之后还有更复杂的场景化找房需求,例如:情侣找房需求等;
- 基于以上问题,有一些技术难点:
- 实时计算x分钟之内到达某点的查询量大,计算多,性能较低;
- 地球是椭圆的;
- 结合调研了链家网、京东到家等实现方式;
目标
- 实现通勤找房的产品需求;
- 建设一个通用的栅格化路径搜索系统,满足全球化业务;
- 数据指标
-
Grids测距离的数据平均偏差±10%以内
- 指标算法:出发地->目的地的百度测距:Grids的测距,抽查10%的数据;
- 实现方式:可以通过缩小每个格子的精确度达到;
-
业务数据平均偏差200米内
- 楼盘上只有小区的坐标,没有楼栋坐标,较大的小区误差会大;
- 调用地图拿到楼栋的坐标;
- 产品驱动运营方去完善房源的楼栋精确坐标;
-
价值
- 实现通勤找房的用户需求,完成产品设定的目标和运营目标;
- 建设一个通用的栅格化路径搜索系统,全球化业务开展的开发周期降低80%(只需要跑业务数据,不需要开发);
- 更多场景化的业务场景;比如:情侣找房、找附近的管家、找附近的师傅、就近派单等;
- 提供了社交场景的想象空间;
- bricks房源展示系统也借此开展;
核心方案
- 时间转换距离
- 直接调用百度api拿到交通方式和距离的数据,不需要自己拿速度去算,给大众的感受较一致;
(暂时不提供早晚高峰和实时的距离)
- 直接调用百度api拿到交通方式和距离的数据,不需要自己拿速度去算,给大众的感受较一致;
- 地图栅格化
- 基于WEB墨卡托投影的原理,将地球平面化
- 优点:最多可以精确到米;数据更直观友好;正方形;城市边界可以无限扩展,全球化的坐标;
- 缺点:越接近两极放大越严重,所以我们只用它画格子,做简单的逻辑,不做实际距离测算;
(市面上还有geohash,公式等)
- 格子编号直接采用魔卡托坐标,格子编号为:魔卡托经度+魔卡托维度+格子米数
- 基于WEB墨卡托投影的原理,将地球平面化
A格子编号 | B格子编号 | 时间 | 时间 |
---|---|---|---|
XY00500 | AB00500 | 5min | 500 |
AB00500 | XY00500 | 10min | 1000 |
XY00500 | PQ00500 | 6min | 567 |
-
格子和格子的距离索引(绿色部分)
- 调用地图api计算距离
计算的是每个格子的实际路径距离,而不是直线距离; - 提供三种精确度索引
分别是 e1=200米,e2=500米,e3=1000米(先做500米的); - 离线数据,定期更新
每新开一个城市,需要提前建立索引;
需要新城市的起始左下角L,K的坐标;
- 调用地图api计算距离
北京的数据大约需要跑7天,约千万级数据量;
-
房源和格子索引(红色部分)
- 在基础研发部新的搜索平台上建立房源和格子的索引数据;
-
查询(紫色部分)
- app获取到WGS84坐标,然后根据公示转换为web Mercator坐标
- 所在格子的中心点精度坐标 = L+ int((web Mercator经度坐标 - L坐标)/e2)*e2+e2/2,纬度同理,从而得到所在的格子编号(no);
- 查询网格间距离的索引得到所有的格子编号(格子s),查询条件:where B格子编号=no and 距离< 规定距离;
- 查询房源网格索引,查询在这些格子(格子s)里的所有房源数据,给客户端返回;
数据流程图
- 应用架构图
- 存在的问题