码迷,mamicode.com
首页 > 移动开发 > 详细

iOS地图定位(Map)

时间:2016-05-31 23:51:59      阅读:358      评论:0      收藏:0      [点我收藏+]

标签:

1.地图的简介

在移动互联网时代,移动app能解决用户的很多生活琐事,比如
    导航:去任意陌生的地方
    周边:找餐馆、找酒店、找银行、找电影院
    手机软件:微信摇一摇、QQ附近的人、微博、支付宝等

在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这两大功能,必须基于两个框架进行开发
    Map Kit :用于地图展示
    Core Location :用于地理定位


地图定位(CoreLocation框架,地理编码与反地理编码)
地图显示(MapKit框架)
自定义大头针

2.地图的定位

1 CLLocationManager的常用操作
2 // 开始用户定位
3 - (void)startUpdatingLocation;
4 // 停止用户定位
5 - (void) stopUpdatingLocation;
6 
7 // 当调用了startUpdatingLocation方法后,就开始不断地定位用户的位置,中途会频繁地调用下面的代理方法
8 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
9 // 参数locations中的元素对象是CLLocation对象
 1 // 每隔多少米定位一次
 2 @property(assign, nonatomic) CLLocationDistance distanceFilter;
 3 
 4 // 定位精确度(越精确就越耗电)
 5 @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
 6 
 7 CLLocationAccuracy 是一个枚举值
 8 /*
 9 最佳导航
10   kCLLocationAccuracyBestForNavigation 
11 最精准
12      kCLLocationAccuracyBest;
13 10米
14      kCLLocationAccuracyNearestTenMeters; 
15 百米
16    kCLLocationAccuracyHundredMeters; 
17 千米
18      kCLLocationAccuracyKilometer; 
19 3千米
20      kCLLocationAccuracyThreeKilometers;     
21 */
22 
23 实现定位只需要下面几步:
24 1.  创建管理者对象
25  self.manager = [[CLLocationManager alloc] init];
26 2.  设置代理
27  self.manager.delegate = self;
28 3.  开启定位
29     [self.manager startUpdatingLocation];
30 注意:从iOS 7之后,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经过用户批准授权:
31 ①要想获得用户的位置和访问用户的通讯录、日历、相机、相册等等都需要用户来手动授权。
32 ②当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权
33 
34 4 、请求授权 (授权方式根据实际情况进行选择)
35 
36 // 请求授权
37 
38  [self.manager requestAlwaysAuthorization];  // 请求前台和后台定位
39 
40  [self.manager requestWhenInUseAuthorization];  // 请求后台定位

定位服务授权状态,返回枚举类型:
kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务
kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态
kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务

用户隐私的保护

NSLocationWhenInUseUsageDescription(当打开APP应用的时候会触发这个方法)

NSLocationAlwaysUsageDescription(总是处于打开的状态)

技术分享

 

模拟位置:(如果是模拟器,需要设置模拟位置(经纬度))======点击模拟器---->Debug---->Location----->CustomLocation更改经纬度

北京的经纬度是:北纬40°,东经116°
大连的经纬度是:北纬39°,东经121°
郑州的经纬度是:北纬34°,东经113°
上海的经纬度是:北纬31°,东经121°
广州的经纬度是:北纬23°,东经113°
西安的经纬度是:北纬34°,东经108°

 

技术分享技术分享

使用CLGeocoder可以完成"地理编码"和"反地理编码"
地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
反地理编码:根据给定的经纬度,获得具体的位置信息

1 // 地理编码方法
2 - (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
3 
4 // 反地理编码方法
5 - (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
 1 当地理编码/反地理编码完成时,就会调用CLGeocodeCompletionHandler
 2 typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
 3 
 4 block包含2个参数
 5 error:当编码出错时(比如编码不出具体的信息),2其错误信息会包含在error中
 6 placemarks:里面装着CLPlacemark对象
 7 
 8 CLPlacemark的字面意思是地标,封装详细的地址位置信息
 9 
10 // 地理位置
11 @property (nonatomic, readonly) CLLocation *location;
12 
13 // 区域
14 @property (nonatomic, readonly) CLRegion *region;
15 
16 // 详细的地址信息
17 @property (nonatomic, readonly) NSDictionary *addressDictionary;
18 
19 // 地址名称
20 @property (nonatomic, readonly) NSString *name;
21 
22 // 地点名称 
23 @property (nonatomic, readonly) NSString *locality;

总结:

CLLocationManager 定位的基础信息
CLLocation  某个位置的地理信息
CLLocationCoordinate2D  存放经纬度的结构体
CLGeocoder 地理位置编码与反编码的类
CLPlacemark 地标.

  1 #import "ViewController.h"
  2 // 第一步: 引入库的头文件
  3 #import <CoreLocation/CoreLocation.h>
  4 
  5 @interface ViewController ()<CLLocationManagerDelegate>
  6 
  7 // 定位管理器
  8 // CoreLocation框架中的CLLocationManager用于管理定位的管理器
  9 // CoreLocation框架中的CLGeocoder能进行编码和反编码
 10 @property (nonatomic, strong) CLLocationManager *manager;
 11 
 12 // 编码反编码的类
 13 @property (nonatomic, strong) CLGeocoder *geocoder;
 14 
 15 
 16 @end
 17 
 18 @implementation ViewController
 19 
 20 - (void)viewDidLoad {
 21     [super viewDidLoad];
 22     // Do any additional setup after loading the view, typically from a nib.
 23     // 定位步骤
 24     // 第一步: 初始化定位管理器
 25     self.manager = [[CLLocationManager alloc] init];
 26     // 第二步: 进行隐私的判断并授权
 27     // 如何跳转隐私界面
 28     // 进行隐私的判断
 29     if (![CLLocationManager locationServicesEnabled]) {
 30         NSLog(@"是否前往隐私进行设置允许定位");
 31     }
 32     
 33     // 根据状态进行授权
 34     // 进行版本的判断
 35     if ([[[UIDevice currentDevice] systemVersion] integerValue] >= 8.0) {
 36         
 37         if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) {
 38             
 39             /*
 40              定位服务授权状态,返回枚举类型:
 41              kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务
 42              kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
 43              kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
 44              kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态
 45              kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务
 46              
 47              */
 48             
 49             
 50             // 在授权请求之前需要在info.plist中设置允许定位的内容:NSLocationWhenInUseUsageDescription   NSLocationAlwaysUsageDescription
 51             // 请求授权
 52             [self.manager requestWhenInUseAuthorization];
 53         }
 54     }
 55     // 第三步: 设置管理器的代理和相关属性
 56     self.manager.delegate = self;
 57     // 设置经度
 58     self.manager.desiredAccuracy = 100;
 59     // 设置最小更新距离
 60     self.manager.distanceFilter = 100;
 61     // 第四步: 开启定位
 62     [self.manager startUpdatingLocation];
 63     
 64     //====================编码和反编码===========================\ 65     
 66     // 初始化编码和反编码对象
 67     self.geocoder = [[CLGeocoder alloc] init];
 68     
 69     // 根据地名获取经纬度
 70     [self getCoordinateByAddress:@"平安村"];
 71     
 72     // 根据经纬度反编码取出地名
 73     [self getAddressByLongitude:113 Latitude:34];
 74     
 75     // 计算两点之间的距离
 76     [self distence];
 77     
 78 }
 79 
 80 #pragma mark - 计算两个地方的距离
 81 
 82 - (void)distence
 83 {
 84     // 创建位置1北京
 85     CLLocation *locationBJ = [[CLLocation alloc] initWithLatitude:40 longitude:116];
 86     // 位置2大连
 87     CLLocation *locationDL = [[CLLocation alloc] initWithLatitude:39 longitude:121];
 88     CLLocationDistance distance = [locationBJ distanceFromLocation:locationDL];
 89     NSLog(@"北京到大连的距离:%f", distance);
 90     
 91 }
 92 
 93 #pragma mark - 根据经纬度获取地名
 94 - (void)getAddressByLongitude:(CLLocationDegrees)longitude Latitude:(CLLocationDegrees)latitude
 95 {
 96     // 反编码
 97     // 创建CLLocation
 98     CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
 99     //反编码
100     [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
101         
102         NSDictionary *dic = placemarks.firstObject.addressDictionary;
103         
104         NSLog(@"反编码地理位置信息:%@", dic);
105     }];
106 }
107 
108 
109 #pragma mark - 根据地名获取相关的信息
110 - (void)getCoordinateByAddress:(NSString *)address
111 {
112     // 编码方法
113     [_geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
114         
115         // 根据返回的地标,取出第一个位置(地标的位置很多)
116         CLPlacemark *mark = placemarks.firstObject;
117         // 根据地标得到location
118         CLLocation *location = mark.location;
119         // 根据location获取区域
120         CLRegion *region =  mark.region;
121         // 获取字典信息
122         NSDictionary *addressDictionary = mark.addressDictionary;
123         
124         NSLog(@"地标位置:%@,区域:%@,地理位置信息:%@",location,region,addressDictionary);
125         
126         
127         //        NSString *name=placemark.name;//地名
128         //        NSString *thoroughfare=placemark.thoroughfare;//街道
129         //        NSString *subThoroughfare=placemark.subThoroughfare; //街道相关信息,例如门牌等
130         //        NSString *locality=placemark.locality; // 城市
131         //        NSString *subLocality=placemark.subLocality; // 城市相关信息,例如标志性建筑
132         //        NSString *administrativeArea=placemark.administrativeArea; //133         //        NSString *subAdministrativeArea=placemark.subAdministrativeArea; //其他行政区域信息
134         //        NSString *postalCode=placemark.postalCode; //邮编
135         //        NSString *ISOcountryCode=placemark.ISOcountryCode; //国家编码
136         //        NSString *country=placemark.country; //国家
137         //        NSString *inlandWater=placemark.inlandWater; //水源、湖泊
138         //        NSString *ocean=placemark.ocean; // 海洋
139         //        NSArray *areasOfInterest=placemark.areasOfInterest; //关联的或利益相关的地标
140         
141     }];
142 }
143 
144 #pragma mark - CLLocationManagerDelegate的代理方法
145 // 这个代理方法是定位成功之后开始更新位置信息,只要移动设置的最小距离之后也开始走这个方法
146 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
147 {
148     // 获取最后一次的位置
149     CLLocation *location = locations.lastObject;
150     // 获取位置坐标
151     CLLocationCoordinate2D coordinate = location.coordinate;
152     // latitude(纬度) longitude(经度) altitude(海拔) course(航线) speed(速度)
153     NSLog(@"%f,%f, %f, %f,%f",coordinate.latitude,coordinate.longitude,location.altitude,location.course,location.speed);
154     /*
155      注意:
156      
157      1.定位频率和定位精度并不应当越精确越好,需要视实际情况而定,因为越精确越耗性能,也就越费电。
158      
159      2.定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法,这个方法返回一组地理位置对象数组,每个元素一个CLLocation代表地理位置信息(包含经度、纬度、海报、行走速度等信息),之所以返回数组是因为有些时候一个位置点可能包含多个位置。
160      
161      3.使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源。
162      
163      4.除了提供定位功能,CLLocationManager还可以调用startMonitoringForRegion:方法对指定区域进行监控。
164      */
165     
166     // 为了节省电源,如果不适用定位,需要把定位关掉
167     [self.manager stopUpdatingLocation];
168     
169 }
170 
171 // 定位失败
172 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
173 {
174     NSLog(@"定位失败");
175 }

 

iOS地图定位(Map)

标签:

原文地址:http://www.cnblogs.com/leikun1113/p/5547885.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!