作者: ZeroJian
iOS 定位分为 WIFI 定位
基站定位
GPS 定位
三种类型
- WIFI 定位
精确度: 高
通过设备扫描周围的 WIFI(AP) 信号获取到广播出的 MAC 地址, 设备将这些能够标识 AP 的数据发送到位置服务器, 服务器检索出每一个 AP 的地理位置, 并结合每个信号的强弱程度, 计算出设备的地理位置
- 基站定位(蜂窝站点)
精确度: 低
通过设备周围的站点计算出地理位置,在蜂窝站点密集的地方使用这种技术可以达到一个相对准确的值
- GPS定位
精确度: 高
利用设备的 GPS 芯片获取 GPS 卫星,计算出地理位置, 精确度高, 并可准确计算设备的海拔速度等参数
iPhone 会根据用户所处位置以尽量省电的方式获取最精确的定位坐标, 在 CoreLocation 框架中, 并没有提供主动切换定位类型的方法, 也无法获取到当前的定位类型, 但是通过 CLLocation 对象可获取到定位相关的一些参数
- altitude (m)
海拔高度, 正值代表海拔以上高度, 负值代表海拔以下高度
- horizontalAccuracy (m)
通过该属性可以确定定位精度
位置的不确定半径
位置的纬度和经度标识圆的中心,这个值表示圆的半径。负值表示位置的经度和纬度无效
- verticalAccuracy (m)
海拔值的准确性
海拔属性中的值可以加上或减去这个属性所表示的值。负值表示海拔值无效。
确定垂直精度需要一个具有GPS功能的设备
- course: (度)
设备行进的方向 负值代表无效
航向值是从正北方向开始测量,并沿罗盘方向顺时针方向旋转。因此,北是0度,东是90度,南是180度,等等。有些设备可能不可用。负值表示方向无效
- speed (m)
设备的瞬时移动 负值代表无效
这个值反映了设备在其当前航向方向上的瞬时速度。负值表示无效的速度。由于实际速度可以在后续位置事件之间传递很多次,所以您应该仅将此属性用于信息目的
由于用户所处环境的复杂性, 用户的位置有很强的不确定性,虽然苹果的 CoreLocation 框架已经做了很好的优化, 定位的漂移也很难避免,我在某次上班时采集了整个路程的所有定位数据, 接合地图来直观看看定位的漂移问题, 这里我截取了一段通过隧道的定位数据, 其中白色
圆点显示的是设备获取的真实位置, 而黑色
小车显示的是经过简单优化展示给用户的平滑移动效果
我们主要关注一下 horizontalAccuracy
位置不确定半径 和 speed
速度两个参数的变化
这张回放 GIF 图经过了 3 个状态的改变
在设备进入隧道后, GPS 信号逐渐变弱, 位置半径逐渐变大, 最后真实位置漂移到湖上
由于无法获取到 GPS 信号, 使用基站定位获取到一个偏差很大的位置, 设备被定位回隧道入口附近, 速度变为负数
设备出隧道后获取到了精确位置, 位置半径精确到 5m, 此时设备位置从隧道入口漂移到隧道出口, 恢复正确定位
通过收集的定位数据, 我们可以简单的做个定位筛选, 比如 speed 为负数, 此定位可抛弃, horizontalAccuracy(精确度半径)超过 200m, 此定位可抛弃, 返回多个相对精确的定位点, 比如 horizontalAccuracy 小于 20, 在此精确范围内的所有定位坐标只保留一个最精确的点, 当然 altitude verticalAccuracy 两个针对海拔的数值在类似楼房和高架等场景也可以做一些优化工作
在对定位数据精确度要求比较高的应用, 比如地图导航, 打车应用, 设备一般在一个运动状态, 我们提取定位数据的上下文, 通过一组数据的速度和方向等参数可筛选出一些相对可靠的定位数据, 再结合地图服务器商提供的道路数据, 应该可以获取到一组相对平滑和准确的定位数据