iOS地圖

各種地圖


在這篇文章裏, 你可以學習到:

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(方法:計算兩個位置之間的距離)
    
    
    所以, 我們一旦得到某個座標, 即可通過其方法和屬性獲得其相應的值.
  • CLGeocoder: 此類提供兩個方法:
    * geocodeAddressString(座標變地名)
    * reverseGeocodeLocation(地名換座標)
    
    

我們通過下面一段代碼來解釋其中的過程:
新建工程, 在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
發佈了20 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章