智能路径技术设计(一期)

一,解决问题

目前动态派工算法获取师傅到目标点的距离及时间,是通过百度API获取的。目前调用百度API所需的时间相对较长,且有调用次数及并发数限制。并且这部分数据没有积累。因此打算开发智能路径系统,一期将调用百度API的数据采集起来,在测算距离及时间的起始点重复时,复用数据。二期将通过获取多能工轨迹,通过机器学习,对保存的距离时间做自优化。

二,设计思路

1.地图数据网格化

在保存从百度地图API获取的两点间距离及时间数据时,如果保存点到点的信息,则需要保存无数个点到点的信息,这样的数据量太大,大大增加了数据存储难度及系统的复杂度。所以采用化繁为简的方式,将地图划分为若干个方形的经纬网格,存储数据时,存储起始网格中心点到目的网格中心点的距离及时间数据。当计算地图上某两点的距离时,则看这两点的经纬度落到哪两个网格内,返回已存储的这两个网格中心点的时间及距离数据即可。网格越小,则精确度越高。

经纬度距离换算

Icon

对于两个点,在纬度相等的情况下:
经度每隔0.00001度,距离相差约1米;每隔0.0001度,距离相差约10米;每隔0.001度,距离相差约100米;每隔0.01度,距离相差约1000米;每隔0.1度,距离相差约10000米。

对于两个点,在经度相等的情况下:
纬度每隔0.00001度,距离相差约1.1米;每隔0.0001度,距离相差约11米;每隔0.001度,距离相差约111米;每隔0.01度,距离相差约1113米;每隔0.1度,距离相差约11132米。

按照上述经纬度距离换算公式,将地图划分为若干个200米*222米的经纬网格,则构筑这个网格的四个顶点坐标为(m代表纬度,n代表经度)[m,n],[m+0.002,n],[m,n+0.002],[m+0.002,n+0.002],该网格中心点的坐标为[m+0.001,n+0.001]。当某一点的坐标[M,N]满足条件m<M≤m+0.002,n<N≤n+0.002时,则将坐标[M,N]≈[m+0.001,n+0.001]进行距离及时间计算。

经纬网格中心点计算方法

Icon

如果经纬度第三位小数为奇数,则舍去三位小数后的数字即为该经纬度所在经纬网格的中心点的经纬度。
如果经纬度第三位小数为偶数,则第三位小数+1后,舍去三位小数后的数字即为该经纬度所在经纬网格的中心点的经纬度。

如图所示(比例尺为100米/厘米),为廊坊e城e家营业厅(尚都金茂营业厅)到星盛园小区的实际距离,图中黑色网格为200米*222米的经纬网格,实际存储及使用的为图中橙色两点的距离。

2.网格化数据存储

按照上述经纬网格的划分方式,以廊坊市为例,廊坊市两个市区安次区及广阳区的面积为908平方公里。黑色网格的面积为200米*222米≈0.04平方公里。则908平方公里会划分为22700个经纬网格。

经纬网格数据存储计算公式

Icon

因为从经纬网格A到经纬网格B之间的距离时间与从经纬网格B到经纬网格A之间的距离时间接近相等。则在保存数据时【A,B】,【B,A】的数据保存一条即可。

 所以M个经纬网格之间的距离时间的数据条数计算公式为M*(M-1)/2

按照上述的计算公式,廊坊市区所有经纬网格的数据条数为22700*(22700-1)/2=257633650(两亿五千万)条数据。

在线服务名称 未认证用户 认证用户
个人 企业
配额(次/日) 并发(次/分钟) 配额(次/日) 并发(次/分钟) 配额(次/日) 并发(次/分钟)
批量算路(Route Matrix v2.0) 2000 1200 30000 3000 300000 12000

由于实际数据来源为百度地图API批量算路(Route Matrix v2.0),上表为批量算路(Route Matrix v2.0)API的配额,企业认证用户每天只可以查询30万次。如果查询整个廊坊市区的经纬网格的距离时间数据需要833天才可以。所以不能按照廊坊市区范围去选取经纬网格调用百度API,而是按照服务区域去进行数据获取。※由于全城模式数据量巨大,全城模式中师傅与目标点距离的数据不进行预存储。

3.服务区网格数据预存储

如图所示,假设蓝色虚线为划分的服务区,该服务区的顶点坐标为[m1,n1],[m2,n2],[m3,n3],[m4,n4]......从这些顶点坐标中找到最大及最小纬度M,m,最大及最小经度N,n,则将服务区转化为长方形的区域,四个顶点坐标为[m,n],[M,n],[m,N],[M,N]。从而算出该服务区的经纬网格范围为淡蓝色长方形所示。按照章节2的逻辑,将服务区经纬网格数据进行预存储。

4.地图海量数据的存储与查询

按照上述存储逻辑,每个城市的经纬网格间距离及时间数据的数量级是千万级的,全国若干个城市数据的集合应该是十亿级以上。对如此大的数据进行存储查询,需要采用大数据存储。采用的方案为Hbase+Solr的解决方案。

采用Hbase+Solr做地图数据存储的原因

Icon

HBase 是一个列存数据库,每行数据只有一个主键RowKey,无法依据指定列的数据进行检索。查询时需要通过RowKey进行检索,然后查看指定列的数据是什么,效率低下。在实际应用中,我们经常需要根据指定列进行检索,或者几个列进行组合检索,这就提出了建立 HBase 二级索引的需求。

基于Solr的HBase多条件查询原理很简单,将HBase表中涉及条件过滤的字段和rowkey在Solr中建立索引,通过Solr的多条件查询快速获得符合过滤条件的rowkey值,拿到这些rowkey之后在HBASE中通过指定rowkey进行查询。


初期数据查询的需求是通过指定起始点经纬网格中心的经纬度,目标点网格中心的经纬度,如果这个数据已经实现存储,则返回存储的数据,否则调用百度地图API并将获取到的数据存储。所以合理的设计Hbase的Rowkey,暂时不需要使用Solr做二级索引。

因为从经纬网格A到经纬网格B之间的距离时间与从经纬网格B到经纬网格A之间的距离时间接近相等。则在存储数据时【A,B】,【B,A】的数据保存一条即可。在查询数据时,为了保证查询【A,B】,【B,A】返回唯一的结果,在存储数据时需要遵循以下原则将标量化的数据转化为矢量化的数据。

两点数据存储原则

Icon

将A[m1,n1],B[m2,n2]的两点坐标按照以下规则排序后查询:

  • 如果A点的纬度m1<B点的纬度m2,则先将AB两点的坐标排序成【A,B】再进行查询。
  • 如果A点的纬度m1>B点的纬度m2,则先将AB两点的坐标排序成【B,A】再进行查询。
  • 如果A点的纬度m1=B点的纬度m2,且A点的经度n1<B点的经度n2,则先将AB两点的坐标排序成【A,B】再进行查询。
  • 如果A点的纬度m1=B点的纬度m2,且A点的经度n1>B点的经度n2,则先将AB两点的坐标排序成【B,A】再进行查询。
  • 如果A点的纬度m1=B点的纬度m2,且A点的经度n1=B点的经度n2,则距离时间均返回0。

为了保证每次查询的数据范围不至于太大,在进行Hbase数据存储时,每个城市的数据存储到以城市命名的Hbase表中,在进行查询时,首先根据传入参数中的城市找到指定的Hbase的表,在将坐标按照上述的逻辑排序后生成Hbase Rowkey,进行查询。

5.地图海量数据HBase的RowKey设计

Hbase Rowkey设计原则

Icon

rowkey长度原则

rowkey是一个二进制码流,可以是任意字符串,最大长度64kb,实际应用中一般为10-100bytes,以byte[]形式保存,一般设计成定长。
建议越短越好,不要超过16个字节,原因如下:

  1. 数据的持久化文件HFile中是按照KeyValue存储的,如果rowkey过长,比如超过100字节,1000w行数据,光rowkey就要占用100*1000w=10亿个字节,将近1G数据,这样会极大影响HFile的存储效率;

  2. MemStore将缓存部分数据到内存,如果rowkey字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率。

  3. 目前操作系统都是64位系统,内存8字节对齐,控制在16个字节,8字节的整数倍利用了操作系统的最佳特性。

rowkey散列原则

如果rowkey按照时间戳的方式递增,不要将时间放在二进制码的前面,建议将rowkey的高位作为散列字段,由程序随机生成,低位放时间字段,这样将提高数据均衡分布在每个RegionServer,以实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息,所有的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中在个别的RegionServer上,造成热点问题,会降低查询效率。

rowkey唯一原则

必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。


按照章节4设计的数据存储逻辑,Rowkey只要存储排序后的AB两点的经纬网格中心点的坐标即可。可以按照如下几种方式生成Rowkey:

A.精确到三位小数直接存储:

廊坊e城e家营业厅(尚都金茂营业厅) 经纬度坐标 [39.5334240000,116.7145800000] ,所在网格中心点的坐标为[39.5330000000,116.7140000000]

廊坊康乐花园小区门口经纬度坐标 [39.5351570000,116.7298310000],所在网格中心点的坐标为[39.5350000000,116.7290000000]

精确到第三位小数,并且方便区分,RowKey的格式为:【39.533,116.714/39.535,116.729】,字节数为29。

B.采用Geohash算法计算后存储:

Geohash

Icon

GeoHash将二维的经纬度转换成字符串,字符串越长,表示的范围越精确。具体算法请参照97 GeoHash核心原理解析

经过Geohash算法处理后,廊坊e城e家营业厅(尚都金茂营业厅) 所在网格中心点的坐标转化为wx4bzuu8,廊坊康乐花园小区门口所在网格中心点的坐标转化为wx50bjpk。

则RowKey的格式为【wx4bzuu8/wx50bjpk】,字节数为17。

 

采用Geohash算法计算后存储的优点除了Rowkey的字节数之外,还有如下优点:

  1. Geohash的数据是可以重用的,Geohash base32编码长度为8时,精度在19米左右,实际上取得是19米范围的正方形的中心点。目前经纬网格的大小为200米,后续数据做精确化存储时,可以将经纬网格缩小到19米,这样之前收集的数据是可以重用的。
  2. Geohash base32编码前缀可以代表更大的范围, 这个特性可以用于附近地点搜索。首先根据用户当前坐标计算geohash然后取其前缀进行查询 。
  3. Geohash base32编码是可排序,可以比较的,一次比较就可以比较出经纬度两个值的差异,减少运算次数。

所以推荐使用Geohash base32对经纬度计算后的值做为Hbase的Rowkey。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值