最近项目中遇到了关于地图定位的需求,考虑到用三方库的话项目会变大,还是用了官方自带的地图。
这是结果图:
一、CoreLocation.frame是iPhone SDK中用来检测用户位置的框架。
1.要实现定位功能,首先引入这个框架。然后添加两个类和一个协议(CLLocationManager、CLLocation、CllocationManagerDelegate)。
精确度级别是通过位置管理器的desiredAccuracy属性来设置的,它的取值可以参照下表。精确级别越高,手机消耗的电越多。
desiredAccuracy属性值 | 描述 |
kCLLocationAccuracyBest | 精确度最好 |
kCLLocationAccuracyNearestTenMeters | 精确到10米以内 |
kCLLocationAccuracyHundredMeters | 精确到100米以内 |
kCLLocationAccuracyKilometer | 精确到1000米以内 |
kCLLocationAccuracyThreeKilometers | 精确到3000米以内 |
2.启动位置管理器进行定位。[locManager startUpdatingLocation](也可以停止检测位置更新[locManager stopUpdatingLocation])
3.获取位置信息
coordinate用来存储地理位置的latitude和longitude,分别代表地理位置的纬度和经度。
location是CLLocation类的一个实例对象。
altitude属性表示某个位置的海拔高度,返回值为浮点型,实际定位时极不准确。
horizontalAccuracy属性表示水平准确度,返回值为浮点型。它是以coordinate为圆心的圆的半径,半径越小定位越准确,如果horizontalAccuracy为负值,表示Core Location定位失败。
verticalAccuracy属性表示垂直水平准确度,返回值为浮点型。它的取值和海拔的取值altitude有关系,与实际情况相差很大。
4.CLLocationManagerDelegate协议
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSString * errorMessage;
if ([error code] == kCLErrorDenied) {
errorMessage = @"访问被拒绝!";
}
if ([error code] == kCLErrorLocationUnknown) {
errorMessage = @"无法定位到你的位置!";
}
}
协议
二、使用MapKit显示地图
1.使用MapKit.framework框架可以很轻松地在应用程序中嵌入一幅地图。
region属性用来设置地图的哪一部分被显示,它是一个结构体类型。
center就是coordinate的取值,包括经纬度信息,此处用来表示地图的中心位置。
span表示地图的一个跨度,它包括了该区域的经度和纬度变化度信息,即缩放地图的比例。
MapType属性设置地图的类型,它的取值见下表。
MapType属性值 | 描述 |
MKMapTypeStandard | 表示标准的街道级地图 |
MKMapTypeSatellite | 表示卫星图 |
MKMapTypeHybrid | 表示以上两种类型的混合 |
2.创建一个MKMapView对象视图添加到当前控制器view上,然后在两个位置管理器代理里面设置一下map的region和span,此外还可以设置latitudeDelta和longitudeDelta可实现缩放。
3.添加地图标注,在项目中添加一个MapAnnotations类。该类继承于NSObject,遵循MKAnnotation协议。
详细代码:
1 #import <UIKit/UIKit.h>
2
3 @interface ViewController : UIViewController
4
5
6 @end
ViewController.h
1 #import "ViewController.h"
2 #import <CoreLocation/CoreLocation.h>
3 #import <MapKit/MapKit.h>
4
5 #import <MapKit/MKAnnotation.h>
6 #import "MapAnnotations.h"
7
8 @interface ViewController ()<CLLocationManagerDelegate, MKMapViewDelegate>
9 {
10 CLLocationManager * locManager;
11 CLLocationCoordinate2D loc;
12 UITextView * textView;
13
14 MKMapView * map;
15
16 MapAnnotations * mapAnnotations;
17 }
18 @end
19
20 @implementation ViewController
21
22 - (void)viewDidLoad {
23 [super viewDidLoad];
24 // Do any additional setup after loading the view, typically from a nib.
25 //创建位置管理器
26 locManager = [[CLLocationManager alloc] init];
27 locManager.delegate = self;
28 if ([CLLocationManager locationServicesEnabled]) {
29 locManager.desiredAccuracy = kCLLocationAccuracyBest; //精确度最好
30 locManager.distanceFilter = 300; //距离筛选器 300米
31 [locManager startUpdatingLocation]; //启动位置管理器进行定位
32 [locManager requestAlwaysAuthorization];
33 }
34
35 map = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
36 map.showsUserLocation = YES;
37 [self.view addSubview:map];
38
39 UIButton * addPanBtn = [UIButton buttonWithType:UIButtonTypeContactAdd];
40 addPanBtn.center = CGPointMake(40, 40);
41 [addPanBtn addTarget:self action:@selector(addPin:) forControlEvents:UIControlEventTouchUpInside];
42 [self.view addSubview:addPanBtn];
43 }
44
45 #pragma mark - 代理方法
46 //这是位置更新方法,当我们的移动范围大于距离筛选器的值时,位置管理器会调用此方法进行重新定位
47 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
48 CLLocation * location = [locations firstObject];
49
50 NSLog(@"latitude:%f, longitude:%f",location.coordinate.latitude, location.coordinate.longitude);
51
52 MKCoordinateRegion region;
53 MKCoordinateSpan span;
54 span.latitudeDelta = 1;
55 span.longitudeDelta = 1;
56 region.span = span;
57 region.center = location.coordinate;
58 [map setRegion:region animated:YES];
59 [map regionThatFits:region];
60
61 mapAnnotations = [[MapAnnotations alloc] initWithCoordinate:location.coordinate];
62 mapAnnotations.title = @"TEST";
63 mapAnnotations.subtitle = @"Just For Test";
64 [map addAnnotation:mapAnnotations];
65 }
66
67 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
68 NSString * errorMessage;
69 if ([error code] == kCLErrorDenied) {
70 errorMessage = @"访问被拒绝!";
71 }
72 if ([error code] == kCLErrorLocationUnknown) {
73 errorMessage = @"无法定位到你的位置!";
74 }
75 }
76
77 - (void)dealloc{
78 //停止检测位置更新
79 [locManager stopUpdatingLocation];
80 }
81
82 - (void)addPin:(id)sender{
83 mapAnnotations = [[MapAnnotations alloc] initWithCoordinate:map.region.center];
84 mapAnnotations.title = [NSString stringWithFormat:@"%f",map.region.center.latitude];
85 mapAnnotations.subtitle = [NSString stringWithFormat:@"%f",map.region.center.longitude];
86 [map addAnnotation:mapAnnotations];
87 }
88
89 - (void)didReceiveMemoryWarning {
90 [super didReceiveMemoryWarning];
91 // Dispose of any resources that can be recreated.
92 }
93
94 @end
ViewController.m
1 #import <Foundation/Foundation.h>
2 #import <CoreLocation/CoreLocation.h>
3 #import <MapKit/MapKit.h>
4
5 @interface MapAnnotations : NSObject<MKAnnotation>
6
7 @property (nonatomic, copy) NSString * title;
8 @property (nonatomic, copy) NSString * subtitle;
9 @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
10
11 - (instancetype)initWithCoordinate:(CLLocationCoordinate2D)c;
12
13 @end
MapAnnotations.h
1 #import "MapAnnotations.h"
2
3 @implementation MapAnnotations
4
5 - (instancetype)initWithCoordinate:(CLLocationCoordinate2D)c{
6 _coordinate = c;
7 return self;
8 }
9
10 @end
MapAnnotation.m