您的位置:首页 > 移动开发 > IOS开发

iOS地图

2016-03-29 17:53 676 查看


各种地图

在这篇文章里, 你可以学习到:

1.iOS系统地图

2.百度地图的简单了解

3.高德地图的简单了解

4.谷歌地图的简单了解

一.系统自带地图

首先需要明白, 地图和定位是两个功能.

定位: 通过GPS或者Wifi或者蜂窝数据定位到手机的具体物理位置, 返回值通常是一个地理坐标.
地图: 和我们实际生活中的地图类似, 基本作用是展示, 至于其中的插大头针, 导航, 查询公交等功能, 并不是其基本功能.

在iOS系统中, 二者分别依赖下面两个库:

1
2
3
4

# 定位
#import <CoreLocation/CoreLocation.h>
# 地图
#import <MapKit/MapKit.h>

定位功能:

地图功能:

定位CoreLocation

通过导图我们介绍框架下的三个常用的类, 定位管理类(CLLocationManager), 坐标类(CLLocation) 和 编码/反编码类(CLGeocoder).

CLLocationManager: 就像文件管理类一样, 它负责你的app在有关定位功能配置方面的设置. 比如定位开关, 定位精度, 权限申请等功能设置.
CLLocation: 此类对象下有如下属性和方法:
- CLLocationCoordinate2D(类型:坐标)
- CLLocationDistance(类型:位置距离)
- coordinate(属性:经纬度)
* altitude(海拔)
* course(航向)
* speed(行走速度)
* distanceFromLocation(方法:计算两个位置之间的距离)

[/code]
所以, 我们一旦得到某个坐标, 即可通过其方法和属性获得其相应的值.
CLGeocoder: 此类提供两个方法:
* geocodeAddressString(坐标变地名)
* reverseGeocodeLocation(地名换坐标)

[/code]

我们通过下面一段代码来解释其中的过程:

新建工程, 在info.plist中插入一条:

NSLocationWhenInUseUsageDescription 类型为String, 值为随意, 这个是在请求权限时给用户看的.

在ViewController.m填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>
// 定位类
@property(nonatomic,strong)CLLocationManager * manager;

// 属性,2d坐标
@property(nonatomic,assign)CLLocationCoordinate2D coor2d;

// 编码与反编码
@property(nonatomic,strong)CLGeocoder *geo;

// 编码:传入一个城市名称,返回一个地理坐标(这个方法是我们自己写的)
-(void)getCoordinateWithCityName:(NSString *)cityName;

// 反编码:根据传入的经纬度,算出是哪个城市的坐标.
-(void)getCityNameWithCoordinate:(CLLocationCoordinate2D)cood;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 判断定位服务是否可用
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"定位服务不可用");
}else
{
NSLog(@"定位服务可用");
}

// 新建管理对象.
self.manager = [[CLLocationManager alloc] init];

// 设置代理
self.manager.delegate = self;

// 请求授权
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) { // 授权状态不是当使用时获取
[self.manager requestWhenInUseAuthorization];
}

// 多少米定位一次(多少米走一次代理方法),kCLDistanceFilterNone 呆着不动也定位.
self.manager.distanceFilter = 10;

// 定位精度.这是个枚举值
/*kCLLocationAccuracyBestForNavigation 最佳导航
kCLLocationAccuracyBest;  最精准
kCLLocationAccuracyNearestTenMeters;  10米
kCLLocationAccuracyHundredMeters;  百米
kCLLocationAccuracyKilometer;  千米
kCLLocationAccuracyThreeKilometers;  3千米
*/
self.manager.desiredAccuracy = kCLLocationAccuracyBest;

// 通过定位管理类, 开启当前程序的定位功能.
[self.manager startUpdatingLocation];

// 调用计算两个坐标之间距离的方法.
[self countDistance];

// 编码与反编码初始化
self.geo = [[CLGeocoder alloc] init];

// 编码
// [self getCoordinateWithCityName:@"北京"];

// 反编码
[self getCityNameWithCoordinate:CLLocationCoordinate2DMake(40, 116)];
}

#pragma mark 定位模块
-(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);

// 定位之后,关闭定位. 有时需要节能..
[self.manager stopUpdatingLocation];
}

// 定位失败走的方法.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"=== 定位失败");
NSLog(@"%@",error);
}

// 计算两个经纬度之间的距离.
-(void)countDistance
{
CLLocation * locat1 = [[CLLocation alloc] initWithLatitude:40 longitude:116];
CLLocation * locat2 = [[CLLocation alloc] initWithLatitude:41 longitude:116];

// 使用CLLocation中的distanceFromLocation方法求两个位置之间的距离(米)
NSLog(@"1一个纬度相差%f米",[locat1 distanceFromLocation:locat2]);
}

// 编码与反编码
-(void)getCoordinateWithCityName:(NSString *)cityName
{
[self.geo geocodeAddressString:cityName completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(@"编码失败");
return;
}
CLPlacemark * placemark = [placemarks lastObject];
NSLog(@"%@的 纬度 = %f 经度 = %f",cityName, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude);
}];
}

-(void)getCityNameWithCoordinate:(CLLocationCoordinate2D)cood
{
CLLocation * locat = [[CLLocation alloc] initWithLatitude:cood.latitude longitude:cood.longitude];

[self.geo reverseGeocodeLocation:locat completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(@"反编码失败");
return;
}

CLPlacemark * placemark = [placemarks lastObject];

// enumerateKeysAndObjectsUsingBlock
[placemark.addressDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ( [key isEqualToString:@"FormattedAddressLines"]) {
for (NSString *str in obj) {
NSLog(@"===%@",str);
}
}else
{
NSLog(@"%@ : %@",key, obj);
}
/*
if (stop) {
if ([obj isKindOfClass:[NSArray class]]) {
NSArray *arr = obj;
NSLog(@"key = %@, obj = %@",key,arr.firstObject);
} else {
NSLog(@"key = %@ , obj = %@",key,obj);
}
}
*/

}];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

地图UIKit

直接上代码了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>
// 地图
@property(nonatomic,strong)MKMapView * mapView;
// 属性,2d坐标
@property(nonatomic,assign)CLLocationCoordinate2D coor2d;
// 定位类
@property(nonatomic,strong)CLLocationManager * manager;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 判断定位服务是否可用
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"定位服务不可用");
}else
{
NSLog(@"定位服务可用");
}

// 请求授权
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) { // 授权状态不是当使用时获取
[self.manager requestWhenInUseAuthorization];
}

/////////////////地图////////////
// 初始化地图界面.
self.mapView = [[MKMapView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:self.mapView];

// 设置地图的类型
self.mapView.mapType = MKMapTypeStandard;

// 设置地图的中心
CLLocationCoordinate2D locat = CLLocationCoordinate2DMake(40, 116);
[self.mapView setCenterCoordinate:locat];

// 设置地图的显示范围(中心与经纬度跨度)
[self.mapView setRegion:MKCoordinateRegionMake(locat, MKCoordinateSpanMake(2, 2))];

// 跟踪用户,打开用户的位置
// 设置模式.
self.mapView.showsUserLocation = YES;
self.mapView.userTrackingMode = MKUserTrackingModeNone;

// 设置地图代理.
self.mapView.delegate = self;

// 设置地图不能转圈
self.mapView.rotateEnabled = NO;

// 添加一个大头针
// 写在touchBegin中
}
#pragma mark 地图的代理方法
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error {
NSLog(@"地图加载失败");
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"获取用户位置完成");
self.coor2d = userLocation.coordinate;
// 不显示用户位置之后就不在走这个代理
self.mapView.showsUserLocation = YES;
// 经纬度转为地图坐标
userLocation.title = nil;
}

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"屏幕区域已经变化");
}
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
NSLog(@"屏幕区域将要发生变化");
}

-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"您点击了大头针!");
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  iOS地图