O2O应用层出不穷的这几年,极大的推进了LBS技术架构的发展。O2O应用除了无状态请求但又是一直在线这个特点,还有一个重要的特点:终端用户有一个位置信息。就是这个位置信息才有了O2O应显示附近餐馆、定位上车、还有微信的摇一摇获取附的人,不少游戏中也是有和附近的朋友完。这些都需要使用LBS(Location Based Services)
本系列文章会介绍LBS App后台架构中的相关技术知识。
LBS类应用特点-定位
不管是什么LBS应用,一个共同的特点就是:他们的数据都或多或少包含了地理位置信息。那核心的问题就是如何获取用户的位置信息了,要解决这个问题我们还要先了解一下定位方案。
而如何对这些信息进行查询、处理、分析,也就成为了支撑LBS应用的最基础也是最关键的技术问题。
而由于地理位置信息的特殊性,在开发中经常会有比较难以处理的问题出现,比如:由于用户所在位置的不固定性,用户可能会在很小范围内移动,而此时经纬度值也会随之变化;甚至在同一个位置,通过GPS设备获取到的位置信息也可能不一样。所以如果通过经纬度去获取周边信息时,就很难像传统数据库那样做查询并进行缓存。
获取用户定位信息
下面4中方法可以获取用户的地理坐标
- 基站定位
每个手机基站都有一个ID标识符,一个手机能够接打电话、收发短信,说明该手机能与附近基站发起交互,收发信号。特别地,对于智能手机,还可以通过系统的接口得到基站ID。基站定位则是利用基站对手机的距离的测算距离来确定手机位置的,但是现实并没有理论那么完美,实际上手机很难同时获取到周围的多个基站ID,运营商也不会浪费钱,一个地方已经有基站覆盖了,为什么还要建立其他基站对吧。基站定位的精度很大程度依赖于基站的分布及覆盖范围的大小,有时误差会超过一公里。这个只能在粗略定位中使用,比如app刚刚启动时获取用户所在省份。
- Wi-Fi定位
现在的智能手机都支持wifi上网了,而我们连接的每个wifi路由器(包括手机做移动热点的那种),都有全球唯一的MAC地址。更重要的是,wifi路由器的部署成本低,因而非常普遍,在一个楼层里就会有很多个wifi热点。因而不难想到,一旦我们有了这个全球每个路由器的实际位置,那么我们就可以确定用户当前的位置。
说到这里,有的朋友会问,如果一个人带着手机,开着移动热点到处行走,那么这种移动热点的mac地址,岂不是就会引起定位的错误?答对了,确实是这样,而且根据统计,这种情形还在愈演愈烈,因此,如何想办法来迅速过滤这种移动热点,是个值得研究的问题。
- 3.GPS定位
如果手机在室外或者窗边,那么就可以接收到天上的定位卫星发射出来的信号,基于这种信号,可以推算手机到每颗卫星的距离、卫星位置,进而推算出手机的位置来。需要注意的是,这个解算是在GPS芯片中完成的,在手机操作系统层面上,可以直接通过API接口得到解算的结果和误差半径。
对于GPS,要注意两点。第一就是GPS的初始定位是很耗时间的,对于老一些的芯片,可能要耗费几分钟才能冷启动定位成功;第二是GPS精度并非是完全可依赖的,在一些地方达到几百米甚至上千米都很正常
- AGPS定位(Assisted GPS)-GPS+基站的结合
以上4种是最常用的定位方式,此外还有蓝牙/IP/地磁场等手段,对于他们的优缺点,我们汇总如下:
AGPS利用网络,首先将基站定位或者WIFI定位获得的大概位置发到远程服务器,由服务器进行查询和计算,得出这个位置下当前卫星信息,反馈给设备,设备就可以直接用这些信息来接受卫星信号,不用等待漫长的卫星轨道信息广播完毕后,才能知道卫星的位置,大大缩短搜星时间。GPS解决方案的优势主要体现在其定位精度上,在室外等空旷地区,其精度在正常的GPS工作环境下,可以达到10米左右,堪称目前定位精度最高的一种定位技术。该技术的另一优点为:首次捕获GPS信号的时间一般仅需几秒,不像GPS的首次捕获时间可能要2~3分钟。
定位方法 | 场景 | 精度 | 开发者实现方式 |
---|---|---|---|
GPS | 室外或窗边,初次定位需要若干秒锁定等待时间 | 一般情况下10M内,高楼边和高架下面100M内 | 芯片实现,系统API提供,开发者直接调用。 |
基站定位 | 可以打电话的地方 | 几百米 | 系统API提供基站ID获取接口,开发者自行维护基站数据库,自行查询推算位置。 |
WIFI定位 | 有WIFI覆盖的地方 | 几米到几十米均可能,取决于部署密度。 | 系统API提供周围WIFI的mac地址获取接口,开发者自行维护mac数据库,自行查询推算位置。 |
IP定位 | 所有能上网的手机 | 如果连宽带上网,且宽带IP稳定,则几十米到几百米,否则只能到城市级,在漫游时IP会发生错误。 | 开发者需要部署一个服务端,在服务端得到手机设备联网的公网ip,并且自行维护一个ip数据库,查询推算位置。 |
蓝牙定位 | 有iBeacon部署的区域 | 5-10M左右,取决于部署密度 | 系统API提供周围蓝牙信标的设备ID获取接口,开发者自行维护ibeacon数据库,自行查询推算位置。 |
磁场定位 | 任意区域。 | 室内磁场分布多样的区域可达到3M,否则就会变差。 | 系统API提供磁场强度获取接口,开发者自行维护磁场数据库,自行查询推算位置。注意磁场强度的绝对定位能力弱,须配合WIFI和Ibeacon等绝对定位方式 |
生产实际中,还是建议使用第三方的定位SDK,比如国内的百度、高德等地图厂商自行实现了定位SDK,该定位SDK的作用就是通过系统接口读取到原始定位信息,然后借助于各家自行部署维护的数据库,查询到当前扫描到的基站、WIFI的位置,最终计算出更准确的定位结果,通过SDK的接口,返回给开发者。这么做的好处,在于能够让app的定位能力脱离对手机系统的依赖。
定位偏移问题
做过LBS App应用的移动端人员应该都遇见过定位不准或者说坐标便宜的问题,App通过系统级的函数获取的坐标,放到百度地图或者高德地图上,会发现他们显示的位置信息是不一致的。
通过系统底层获取的坐标系是国际坐标系WGS-84(World GEodetic System 1984),是为GPS全球定位系统的使用而建立的坐标系统。
GCJ-02是由中国国家测绘局制定的地理信息系统的坐标系统,其是对经纬度数据(WGS-84)的加密算法,即加入随机的偏差。不同的电子地图服务提供商有不同的坐标系,例如,Google、高德地图使用的是同一套坐标系,而百度、腾讯又是使用的另一套坐标系,解决这个问题最简单的办法就是尽量使用相同的坐标系,当然有时候迫不得已的话,也可以进行坐标系的转化。腾讯就提供这样的服务。
确定功能需求
了解了定位相关的知识,那些都是移动端的同事需要关心的,现在我们要去考虑服务端的东西了。
假设我们先要开发一个打车APP,APP有司机端和用户端,用户提供自己的定位,需要获取到附近的司机信息,司机需要由近到远排序,并显示距离,没错这个就是嘀嘀打车等APP的其中一个小功能。
可能的技术方案
排除一些不通用和难以实现的技术,我们罗列出以下几种方案:
- 基于MySQL数据库
- 采用GeoHash索引,基于MySQL
- MySQL空间存储(MySQL Spatial Extensions)
- 使用Redis存储地理位置信息
- 使用MongoDB存储地理位置信息
文章同步发布在博客,LBS-查找附近的人-地理坐标定位详解
请看下篇