最近的一个业务涉及地图相关的服务,由于时间比较紧,所以借鉴了网上一些大神的代码,总算是交了差。现在回想起来,当初的自己是多么的窘迫,上网查看,铺天盖地的博文,每篇都是华丽丽的几大页,功能也都能满足要求,就是代码太多,全部复制粘贴吧,不合适,删减吧,又不能马上找到关键代码,不知道各自的依赖关系,只能根据自己的想象和经验修改后加入工程。
如今空闲之余,本着打破沙锅的精神重新研究了地图与定位服务,现总结如下,希望给初始接触地图开发的人员以及将来的自己作为参考。
我始终觉得,“最小系统”对于一个初学者非常重要。当初,我把百度地图嵌入的自己的APP中,在显示出地图的一刹那,我感到非常的兴奋,因为那是我花了几乎一整天时间的成果,现在想想,除了集成百度地图框架之外,也就几行代码就可以搞定的事情。所以,在这里我要从最基础的“最小系统”讲起,逐步在其上增加功能,尽量一个模块完成一个功能。
啰嗦完了,开始正题:
当今的生活中,手机已成为每个人的必备随身品,手机上越来越多的应用都使用了地图服务,而使用地图通常都离不开定位服务,所以在我的印象中,定位服务是地图的一个子功能,而实际上,在iOS中,定位与地图是两个完全不同的东东,它们有着相互独立的两套API(定位使用的类通常以CL开头,而地图服务的类以MK开头),可以只定位而不使用地图,也可以只用地图而不定位,只是他们结合很紧密,经常一起使用而已。
在iOS中,定位服务基于CoreLocation框架,定位时主要使用CLLocationManager、CLLocationManagerDelegate和CLLocation,其中CLLocationManager类是定位服务管理类,他能够使我们获得设备的位置、高度、速度、运行方向等信息,也可以监控设备进出某个区域。而CLLocationManagerDelegate是CLLocationManager类的委托协议,CLLocation类封装了位置和高度信息。
//
// ViewController.h
// LocationTest011
//
// Created by LZH on 15-4-2.
// Copyright (c) 2015年 LZH. All rights reserved.
//
#import
#import //添加定位服务头文件(不可缺少)
@interface ViewController : UIViewController //添加代理协议 CLLocationManagerDelegate
@end
//
// ViewController.m
// LocationTest011
//
// Created by LZH on 15-4-2.
// Copyright (c) 2015年 LZH. All rights reserved.
//
#import "ViewController.h"
@interface ViewController (){
CLLocationManager *_locationManager; //定位服务管理类
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_locationManager = [[CLLocationManager alloc] init]; //创建CLLocationManager对象
_locationManager.delegate = self; //设置代理,这样函数didUpdateLocations才会被回调
[_locationManager startUpdatingLocation]; //启动定位服务
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //定位服务回调函数
CLLocation *location = [locations lastObject]; //当前位置信息
NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f", location.coordinate.longitude, location.coordinate.latitude,location.altitude,location.course,location.speed);
}
@end
这便是关于定位服务的“最小系统”,关键代码只有7行,运行如下图:
- (void)requestAlwaysAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);
- (void)requestWhenInUseAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);
NSLocationAlwaysUsageDescription //对应方法 requestAlwaysAuthorization
NSLocationWhenInUseUsageDescription //对应方法 requestWhenInUseAuthorization
//
// ViewController.m
// LocationTest011
//
// Created by LZH on 15-4-2.
// Copyright (c) 2015年 LZH. All rights reserved.
//
#import "ViewController.h"
@interface ViewController (){
CLLocationManager *_locationManager; //定位服务管理类
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_locationManager = [[CLLocationManager alloc] init]; //创建CLLocationManager对象
_locationManager.delegate = self; //设置代理,这样函数didUpdateLocations才会被回调
[_locationManager requestAlwaysAuthorization]; /////// 新增的请求定位服务的语句
[_locationManager startUpdatingLocation]; //启动定位服务
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ //定位服务回调函数
CLLocation *location = [locations lastObject]; //当前位置信息
NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f", location.coordinate.longitude, location.coordinate.latitude,location.altitude,location.course,location.speed);
}
@end
经纬度、海拔、航向,速度等信息都取到正确的值。
如果刚刚点击了“不允许”,则以后都将无法获取到位置信息,直到重新安装应用。当然,也可以手动取消本应用定位服务的限制:点击 设置->隐私->定位服务,在下面的应用列表中找到自己的APP,更改“永不”设置即可。
好了,主题介绍完毕,现在补充些定位服务相关的知识:
使用iOS系统的iPhone、iPod touch及iPad都可以提供定位服务,而在iOS设备中能够提供以下3种不同的定位途径:
比较以上3种位置信息获取途径,GPS定位优点是:定位准确,覆盖面广,缺点是不能被遮挡且相当的费电;而蜂窝基站定位不仅误差比较大,且要耗费用户的流量;WiFi定位最经济实惠,缺点是定位信息是根据路由器来定,即使你出差去了外地,你的位置信息依然显示的时当初首次使用路由器定位时的位置信息。
那么我们在编程时究竟该采用哪种定位方式呢?
这个其实完全不用担心,iOS不像Android系统那样,开发者在定位服务编程时可以指定采用哪种途径定位,iOS的API把底层这些细节屏蔽掉了,开发人员和用户并不知道当前设备是采用哪种方式进行定位的,iOS系统会根据设备的情况和周围的环境,采用一套最佳的解决方案。其核心思想是:如果能够接收GPS信号,则优先采用GPS定位,否则将采用WiFi定位,然后才会去考虑蜂窝基站定位。
GPS(Global Positioning System,全球定位系统)
GPS是20世纪70年代由美国陆海空三军联合研制的新一代卫星定位系统,其前身是美国军方在1958年研制的子午仪卫星定位系统(Transit),主要目的是为陆海空三大领域提供实时、全天候和全球性的导航服务,并用于情报收集、核爆监测和应急通讯等一些军事目的,经过20余年的研究实验,耗资300亿美元,到1994年,全球覆盖率高达98%的24颗GPS卫星星座己布设完成。
BDS(BeiDou Navigation Satellite System,中国北斗卫星导航系统)
BDS是中国自行研制的全球卫星导航系统,是继美国全球定位系统(GPS)、俄罗斯格洛纳斯卫星导航系统(GLONASS)之后第三个成熟的卫星导航系统。北斗卫星导航系统(BDS)和美国GPS、俄罗斯GLONASS、欧盟GALILEO,是联合国卫星导航委员会已认定的供应商。
到2012年10月26日,中国已成功发射了16颗北斗导航卫星,这些导航卫星都分为军用频道和民用频道,军用频道是加密的且定位精度极高,民用频道定位精度要低一些。
2014年11月23日,国际海事组织海上安全委员会审议通过了对北斗卫星导航系统认可的航行安全通函,这标志着北斗卫星导航系统正式成为全球无线电导航系统的组成部分,取得面向海事应用的国际合法地位。