天天看點

iOS之原生地圖的使用詳解

一.實作一次定位(實際上就是持續定為,完成定位更新的時候停止定位,就成了一次定位)

@interface ViewController ()<CLLocationManagerDelegate>

@property (nonatomic,strong)CLLocationManager *locationManager;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    //1. 建立一個CLLocationManager對象

    self.locationManager = [CLLocationManagernew];

    //2. 請求授權 --> iOS8以後需要授權并配置plist鍵值,NSLocationWhenInUseUsageDescription:授權需要填加的值,   Localization native development region:en;

    //為了防止iOS7奔潰,需要做判斷: 2種方式: 1.判斷能否響應 2.判斷系統版本

    //if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { }

    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {

//當程式在前台,看見的時候調用        

[self.locationManager requestWhenInUseAuthorization];

    }

    //3. 設定代理-->來擷取使用者定位的資料

    self.locationManager.delegate =self;

    //4. 開始定位

    [self.locationManager startUpdatingLocation];

}

#pragma mark 定位的代理方法

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations

{

    //locations : 包含了經緯度, 速度等資訊

    NSLog(@"locations: %@", locations);

    //5. 停止定位( 如果不 停止定為就是持續定位)

    [self.locationManager stopUpdatingLocation];

}

@end

=============================================================================

持續定位

#import "ViewController.h"

#import <CoreLocation/CoreLocation.h>

@property (nonatomic,strong)CLLocationManager *locationManager;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    //1. 建立一個CLLocationManager對象

    self.locationManager = [CLLocationManagernew];

    //2. 請求授權 --> iOS8以後需要授權并配置plist鍵值

    if ([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {

        [self.locationManagerrequestWhenInUseAuthorization];

    }

    //3. 設定代理-->來擷取使用者定位的資料

    self.locationManager.delegate =self;

    //4. 開始定位

    [self.locationManagerstartUpdatingLocation];

    //5.距離篩選器:機關米  -->主要是通過降低代理方法的調用頻率,達到省電目的

    //Filter:篩選 /過濾

    // 如果設定了10,那麼發生了10米以上的變化時才會調用

    self.locationManager.distanceFilter =10;

    //6. 預期精準度:

    //desired: 期望/預期

    //Accuracy: 精準度

    self.locationManager.desiredAccuracy =kCLLocationAccuracyKilometer;

    //7. 比較2個位置之間的距離比較的是直線距離

    // 北京到西安的距離

    CLLocation *location1 = [[CLLocationalloc]initWithLatitude:40.06longitude:116.39];

    CLLocation *location2 = [[CLLocationalloc]initWithLatitude:34.27longitude:108.93];

    CLLocationDistance distance = [location1 distanceFromLocation:location2];

    NSLog(@"distance: %f",distance /1000);

}

#pragma mark 定位的代理方法

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations

{

    //locations : 包含了經緯度, 速度等資訊

    NSLog(@"locations: %@", locations);

    // CLLocation: 位置對象

    CLLocation *location = locations.lastObject;

    //CLLocationCoordinate2D coordinate : 2D位置坐标: 

    //CLLocationDegrees latitude : 緯度

    //CLLocationDegrees longitude : 經度

    //CLLocationDegrees: double值

    //方法

    //distanceFromLocation

}

@end

=======================================================================

iOS9新特性: 臨時擷取背景定位

#import "ViewController.h"

#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>

@property (nonatomic,strong)CLLocationManager *locationManager;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    //1. 建立一個CLLocationManager對象

    self.locationManager = [CLLocationManagernew];

    //2. 請求授權 --> iOS8以後需要授權并配置plist鍵值;NSLocationAlwaysUsageDescription:随便寫

    // 請求授權這個步驟是在iOS8以後才出現的.如果iOS7之前直接調用會崩潰.

    //為了防止iOS7奔潰,需要做判斷: 2種方式: 1.判斷能否響應 2.判斷系統版本

    //if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) { }

    if ([self.locationManagerrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {

        // 當使用者使用時授權 :當程式能看見的時候,正在運作的時候

        [self.locationManagerrequestWhenInUseAuthorization];

        // 永久授權 :當程式背景運作 /鎖屏界面都可以擷取定位資訊

        //[self.locationManager requestAlwaysAuthorization];

    }

    if ([UIDevicecurrentDevice].systemVersion.floatValue >=9.0) {

        //allowsBackgroundLocationUpdates : 允許背景位置更新

        self.locationManager.allowsBackgroundLocationUpdates = YES;

    }

    //3. 設定代理-->來擷取使用者定位的資料

    self.locationManager.delegate =self;

    //4. 開始定位

    [self.locationManagerstartUpdatingLocation];

}

#pragma mark 定位的代理方法

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations

{

    //locations : 包含了經緯度, 速度等資訊

    NSLog(@"locations: %@", locations);

}

@end

=======================================================================

地理編碼:把地名轉換成經緯度,可能會出現一對多的情況;

#import "GeocoderViewController.h"

#import <CoreLocation/CoreLocation.h>

@interface GeocoderViewController ()

@property (weak, nonatomic) IBOutletUITextField *addressTF;

@property (weak, nonatomic) IBOutletUILabel *latitudeLabel;

@property (weak, nonatomic) IBOutletUILabel *longitudeLabel;

@property (weak, nonatomic) IBOutletUILabel *detailAddressLabel;

@end

@implementation GeocoderViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view.

}

- (IBAction)geocoderClick:(id)sender {

    //1. 建立CLGeocoder對象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2. 調用地理編碼方法

    //placemarks: 地标對象

//CLPlacemark中有CLLocation(可以獲得經緯度),region,街道名稱,城市,州很多資訊。

    [geocoder geocodeAddressString:self.addressTF.textcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {

        //3.1 防錯處理

        if (placemarks.count ==0 || error) {

            NSLog(@"解析出錯");

            return;

        }

        //3.2 解析資料

        // 正地理編碼,一個地名可能對應多個經緯度.是以,實際做的時候應該給使用者一個清單選擇

        // 咱們這裡不做處理了

        for (CLPlacemark *placemarkin placemarks) {

            //3.3 經緯度

            self.latitudeLabel.text = [NSStringstringWithFormat:@"%f",placemark.location.coordinate.latitude];

            self.longitudeLabel.text = [NSStringstringWithFormat:@"%f",placemark.location.coordinate.longitude];

            NSLog(@"la: %f, long: %f", placemark.location.coordinate.latitude

                  , placemark.location.coordinate.longitude);

            //3.4 詳細位址 --name

            self.detailAddressLabel.text = placemark.name;

            //NSLog(@"name: %@", placemark.name);

            NSLog(@"city: %@",placemark.locality);

            // 取城市的時候,locality有可能為空.為了避免取城市的時候程式崩潰,可以使用administrativeArea暫時代替一下

            NSLog(@"administrativeArea%@",placemark.administrativeArea);

        }

    }];

}

@end

============================================================= 反地理編碼:把經緯度轉換成地名

#import "ReverceGeocoderViewController.h"

#import <CoreLocation/CoreLocation.h>

@interface ReverceGeocoderViewController ()

@property (weak, nonatomic) IBOutletUITextField *latitudeTF;

@property (weak, nonatomic) IBOutletUITextField *longitudeTF;

@property (weak, nonatomic) IBOutletUILabel *cityLabel;

@end

@implementation ReverceGeocoderViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view.

}

- (IBAction)reverceGeocoderClick:(id)sender {

    //1. 建立Geocoder對象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2.1 建立位置對象

    CLLocation *location = [[CLLocationalloc]initWithLatitude:[self.latitudeTF.textdoubleValue]longitude:[self.longitudeTF.textdoubleValue]];

    //2.2 調用反地理編碼方法

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks,NSError *_Nullable error) {

        //3.1 防錯處理

        if (placemarks.count ==0 || error) {

            return;

        }

        //3.2 解析資料反地理編碼,隻會對應一個唯一的位址,是以不需要for循環

        CLPlacemark *placemark = placemarks.lastObject;

        //locality: 城市

        if (placemark.locality) {

            self.cityLabel.text = placemark.locality;

        } else {

            //administrativeArea: 行政區域

            self.cityLabel.text = placemark.administrativeArea;

        }

    }];

}

@end

================================================================== mapView的使用

#import "ViewController.h"

#import <MapKit/MapKit.h>

// MapKit包含了CoreLotion架構

// 如果使用了SB或者Xib導入MapView的時候,需要導入架構

// MapView本身就有屬性可以實作跟蹤使用者位置

@interface ViewController ()<MKMapViewDelegate>

@property (nonatomic,strong)CLLocationManager *mgr;

@property (weak, nonatomic) IBOutletMKMapView *mapView;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    //1. 建立位置管理器并授權

    self.mgr = [CLLocationManagernew];

    // 請求授權 --> 配置plist

    if ([self.mgrrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {

        [self.mgrrequestWhenInUseAuthorization];

    }

    //2. 顯示使用者位置

    //Tracking: 跟蹤

    //userTrackingMode: 使用者跟蹤模式

    self.mapView.userTrackingMode = MKUserTrackingModeFollow;

    //3. 設定代理 --> 擷取使用者位置

    self.mapView.delegate =self;

    //1.顯示交通狀況

    self.mapView.showsTraffic =YES;

    //2.顯示比例尺

    self.mapView.showsScale =YES;

    //3.顯示指南針 (預設YES)

    self.mapView.showsCompass =NO;

}

#pragma mark - MapView代理方法

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

{

    //1. 擷取經緯度

    NSLog(@"la: %f, long: %f",userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude );

    //2. 設定标題子标題

//    userLocation.title = @"北京市";

//    userLocation.subtitle = @"asasflsdafsa";

    //2.1 建立Geocoder對象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2.2 調用反地理編碼方法 -->頭檔案第一個方法

    [geocoder reverseGeocodeLocation:userLocation.locationcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {

        //2.3 解析資料

        if (placemarks.count ==0 || error) {

            return;

        }

        CLPlacemark *placemark = placemarks.firstObject;

        //locality: 城市

        if (placemark.locality) {

            userLocation.title = placemark.locality;

        } else {

            //administrativeArea: 行政區域,吧行政區域付給大頭針模型的title

            userLocation.title = placemark.administrativeArea;

        }

        //name: 詳細位址

        userLocation.subtitle = placemark.name;

    }];

}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

{

    //1. 擷取目前顯示大小的跨度

    NSLog(@"latitudeDelta: %f,longitudeDelta: %f", mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta);

    // 放大地圖:将顯示跨度縮小一倍即可

    // 放大地圖:将顯示跨度放大一倍即可

    // 在按鈕點選的時候,先擷取目前顯示跨度大小,然後按照需求放大或縮小跨度,最後再次調用setRegion方法

    // latitudeDelta: 0.046142,longitudeDelta: 0.034943首次運作完畢:

    // latitudeDelta: 0.021251,longitudeDelta: 0.016093

    // latitudeDelta: 0.010625,longitudeDelta: 0.008047

}

#pragma mark - 其他方法

#pragma mark 切換地圖類型

- (IBAction)changeMapTypeClick:(UISegmentedControl *)sender {

    switch (sender.selectedSegmentIndex) {

        case 0:

            self.mapView.mapType =MKMapTypeStandard;

            break;

        case 1:

            self.mapView.mapType =MKMapTypeSatellite;

            break;

        case 2:

            self.mapView.mapType =MKMapTypeHybrid;

            break;

        default:

            break;

    }

}

#pragma mark 傳回使用者的位置

- (IBAction)backUserLocationClick:(id)sender {

    // 設定地圖的中心點經緯度 -->沒有動畫

    //self.mapView.centerCoordinate = self.mapView.userLocation.location.coordinate;

    // 設定地圖的中心點經緯度 -->有動畫

    //[self.mapView setCenterCoordinate:self.mapView.userLocation.location.coordinate animated:YES];

    // 設定地圖的中心點經緯度并且改變地圖的顯示跨度

    //1. 中心點坐标.

    CLLocationCoordinate2D centerCoordinate =self.mapView.userLocation.location.coordinate;

    //2. 顯示跨度大小 1°約等于111KM

    MKCoordinateSpan span =MKCoordinateSpanMake(0.01,0.01);

    //3. 設定Region屬性 -->沒有動畫

    //self.mapView.region = MKCoordinateRegionMake(centerCoordinate, span);

    // 調用set方法來增加動畫

    [self.mapView setRegion:MKCoordinateRegionMake(centerCoordinate, span)animated:YES];

}

#pragma mark 放大地圖

//在按鈕點選的時候,先擷取目前顯示跨度大小,然後按照需求放大或縮小跨度,最後再次調用setRegion方法

- (IBAction)zoomInClick:(id)sender {

    //1. 将目前的顯示跨度縮小一倍

    //region : 是目前地圖顯示的區域

    CGFloat latitude =self.mapView.region.span.latitudeDelta * 0.5;

    CGFloat longitude =self.mapView.region.span.longitudeDelta * 0.5;

    //2. 設定 region

    // 設定範圍, 帶動畫

    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center,MKCoordinateSpanMake(latitude, longitude)) animated:YES];

}

#pragma mark 縮小地圖

- (IBAction)zoomOutClick:(id)sender {

    //1. 将目前的顯示跨度放大一倍

    //region : 是目前地圖顯示的區域

    CGFloat latitude =self.mapView.region.span.latitudeDelta * 2;

    CGFloat longitude =self.mapView.region.span.longitudeDelta * 2;

    // 經緯度: 經360緯180

    // 蘋果地圖能顯示的最大跨度147左右

    if (latitude > 140 || longitude > 140) {

        return;

    }

    //2. 設定    // 設定範圍,帶動畫

    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.region.center,MKCoordinateSpanMake(latitude, longitude)) animated:YES];

}

@end

======================================================================

添加大頭針

#import <Foundation/Foundation.h>

//1. 導入架構

#import <MapKit/MapKit.h>

//2. 遵守協定

@interface MyAnnotation :NSObject<MKAnnotation>

//3. 拷貝協定中的屬性(需要删除readonly屬性)

@property (nonatomic)CLLocationCoordinate2D coordinate;

@property (nonatomic,copy,nullable)NSString *title;

@property (nonatomic,copy,nullable)NSString *subtitle;

@end

#import "ViewController.h"

#import <MapKit/MapKit.h>

#import "MyAnnotation.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutletMKMapView *mapView;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    // 自定義大頭針模型:需要自定義大頭針模型

    MyAnnotation *annotation1 = [MyAnnotationnew];

    annotation1.coordinate =CLLocationCoordinate2DMake(40 ,116);

    annotation1.title = @"北京市";

    annotation1.subtitle = @"北京市是一個迷人的城市";

    //Annotation: 标注/注解 大頭針

    [self.mapViewaddAnnotation:annotation1];

    MyAnnotation *annotation2 = [MyAnnotationnew];

    annotation2.coordinate =CLLocationCoordinate2DMake(23 ,113);

    annotation2.title = @"廣州市";

    annotation2.subtitle = @"廣州市是一個令人向往的城市";

    //Annotation: 标注/注解 大頭針

    [self.mapView addAnnotation:annotation2];

}

#pragma mark 點選地圖上的位置添加大頭針

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    //1. 擷取點選的點

    CGPoint point = [[touches anyObject] locationInView:self.mapView];

    //2. 将點轉換成經緯度

    CLLocationCoordinate2D coordinate = [self.mapView convertPoint:pointtoCoordinateFromView:self.mapView];

    //3. 添加大頭針模型

    MyAnnotation *annotation = [MyAnnotationnew];

    annotation.coordinate = coordinate;

    //可以使用反地理編碼擷取title和subtitle

    annotation.title = @"廣州市";

    annotation.subtitle = @"廣州市是一個令人向往的城市";

    [self.mapViewaddAnnotation:annotation];

}

@end

===============================================================

添加自定義大頭針

#import "ViewController.h"

#import <MapKit/MapKit.h>

#import "MyAnnotation.h"

@interface ViewController ()<MKMapViewDelegate>

@property (weak, nonatomic) IBOutletMKMapView *mapView;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    // 1. 設定地圖的代理方法

    self.mapView.delegate =self;

    // 自定義大頭針模型:需要自定義大頭針模型

    MyAnnotation *annotation1 = [MyAnnotationnew];

    annotation1.coordinate =CLLocationCoordinate2DMake(40 ,116);

    annotation1.title = @"北京市";

    annotation1.subtitle = @"北京市是一個迷人的城市";

    //Annotation: 标注/注解 大頭針

    [self.mapViewaddAnnotation:annotation1];

    MyAnnotation *annotation2 = [MyAnnotationnew];

    annotation2.coordinate =CLLocationCoordinate2DMake(23 ,113);

    annotation2.title = @"廣州市";

    annotation2.subtitle = @"廣州市是一個令人向往的城市";

    //Annotation: 标注/注解 大頭針

    [self.mapViewaddAnnotation:annotation2];

}

#pragma mark 地圖的代理方法

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation

{

    // 如果傳回nil,代表着使用者沒有自定義大頭針的需求.所有的大頭針顯示由系統控制

    //MKUserLocation --> 系統顯示使用者位置的大頭針類

    // 如果不是自己的大頭針模型類,傳回nil

    if (![annotation isKindOfClass:[MyAnnotation class]]) {

        return nil;

    }

     static NSString *ID =@"annoView";

    //MKAnnotationView: 裡面有一個image屬性,預設沒有值,需要設定一張圖

    //MKPinAnnotationView: 預設有圖像

    //如果要更改顔色,設定掉落效果隻能找子類 MKPinAnnotationView

    MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];

    if (annoView == nil) {

        annoView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];

 //如果大頭針自定義了,标題和子标題預設不會實作;

  //設定大頭針可以點選,顯示标題和子标題

        annoView.canShowCallout=YES;

  //設定大頭針左右附屬視圖

        annoView.leftCalloutAccessoryView=[[UISwitchalloc]init];

        annoView.rightCalloutAccessoryView=[[UISwitchalloc]init];

  //設定大頭針頭像

       // annoView.image=[UIImageimageNamed:@"one"];

        //1. 更改顔色

        annoView.pinTintColor = [UIColor colorWithRed:arc4random_uniform(256) /255.0 green:arc4random_uniform(256) /255.0blue:arc4random_uniform(256) /255.0alpha:1];

        //2. 動畫掉落

        annoView.animatesDrop = YES;

    }

    return annoView;

}

//-(void)setAnnotation:(id<MKAnotation>)annotation{

//大頭針自定義view和cell一樣,唯一不同的是,大頭針不用指派模型資料;

//原因是大頭針的view會自動調用setAnnotation方法(模型的set方法);

//系統會自己指派模型資料;一旦重寫,方法就會丢棄,會造成程式崩潰;如果重寫,又不希望程式崩潰,要調用父類的方法;[super setAnnotation:annotation];

}

#pragma mark 點選地圖上的位置添加大頭針

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    //1. 擷取點選的點

    CGPoint point = [[touches anyObject] locationInView:self.mapView];

    //2. 将點轉換成經緯度

    CLLocationCoordinate2D coordinate = [self.mapViewconvertPoint:pointtoCoordinateFromView:self.mapView];

    //3. 添加大頭針模型

    MyAnnotation *annotation = [MyAnnotationnew];

    annotation.coordinate = coordinate;

    //可以使用反地理編碼擷取title和subtitle

    annotation.title = @"廣州市";

    annotation.subtitle = @"廣州市是一個令人向往的城市";

    [self.mapView addAnnotation:annotation];

}

@end

============================================================

地圖導航

#import "ViewController.h"

#import <MapKit/MapKit.h>

@interface ViewController ()

@property (weak, nonatomic) IBOutletUITextField *destinationTF;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

}

- (IBAction)navigateClick:(id)sender {

    //1. 建立CLGeocoder對象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2. 調用地理編碼方法

    [geocoder geocodeAddressString:self.destinationTF.textcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {

        //3. 解析資料

        //3.1 防錯處理

        if (placemarks.count ==0 || error) {

            return;

        }

        //3.2 擷取CLPlacemar對象 -->地理編碼

        // 正向會有多個結果,咱們暫時取出一個

        CLPlacemark *pm = placemarks.lastObject;

        //3.3 建立一個MKPlacemark對象

        MKPlacemark *mkpm = [[MKPlacemarkalloc]initWithPlacemark:pm];

        //3.4 終點位置

        MKMapItem *destinationItem = [[MKMapItemalloc]initWithPlacemark:mkpm];

        //3.5 目前位置

        MKMapItem *sourceItem = [MKMapItemmapItemForCurrentLocation];

        //實作導航關鍵點:在于一個MKMapItem的open方法

        //MKMapItem: 地圖上的點

        //需要起點和終點

        //3.6 調用系統地圖進行導航

        NSArray *maptems = @[sourceItem, destinationItem];

        // 導航模式. 地圖類型.交通狀态

        NSDictionary *options =@{MKLaunchOptionsDirectionsModeKey :MKLaunchOptionsDirectionsModeTransit,MKLaunchOptionsMapTypeKey :@(MKMapTypeHybrid)};

        [MKMapItem openMapsWithItems:maptemslaunchOptions:options];

    }];

}

@end

======================================================================

添加地圖導航劃線

#import "ViewController.h"

#import <MapKit/MapKit.h>

@interface ViewController ()<MKMapViewDelegate>

@property (weak,nonatomic)IBOutlet UITextField *destinationTF;//輸入目的地

@property (weak, nonatomic) IBOutletMKMapView *mapView;

@property (nonatomic,strong)CLLocationManager *mgr;

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    //請求授權 -->想要擷取自己位置必須授權

    self.mgr = [CLLocationManagernew];

    if ([self.mgrrespondsToSelector:@selector(requestWhenInUseAuthorization)]) {

        [self.mgrrequestWhenInUseAuthorization];

    }

    //設定代理

    self.mapView.delegate =self;

}

- (IBAction)navigateClick:(id)sender {

    //1. 建立CLGeocoder對象

    CLGeocoder *geocoder = [CLGeocodernew];

    //2. 調用地理編碼方法

    [geocoder geocodeAddressString:self.destinationTF.textcompletionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError * _Nullable error) {

        //3. 解析資料

        //3.1 防錯處理

        if (placemarks.count ==0 || error) {

            return;

        }

        //3.2 擷取CLPlacemar對象 -->地理編碼

        // 正向會有多個結果,咱們暫時取出一個

        CLPlacemark *pm = placemarks.lastObject;

        //3.3 建立一個MKPlacemark對象

        MKPlacemark *mkpm = [[MKPlacemarkalloc]initWithPlacemark:pm];

        //3.4 終點位置

        MKMapItem *destinationItem = [[MKMapItemalloc]initWithPlacemark:mkpm];

        //3.5 目前位置

        MKMapItem *sourceItem = [MKMapItemmapItemForCurrentLocation];

        //3.6 計算路線

        //1. 建立一個方向請求對象 --> 拼接URL位址的參數

        MKDirectionsRequest *request = [MKDirectionsRequestnew];

        request.source = sourceItem;

        request.destination = destinationItem;

        //2. 建立方向對象

        MKDirections *directions = [[MKDirectionsalloc]initWithRequest:request];

        //3. 調用方法計算路線

        [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *_Nullable response,NSError *_Nullable error) {

            //3.1 防錯處理

            if (response.routes.count ==0 || error) {

                return;

            }

            //3.2 擷取路線資訊polyline

            for (MKRoute *routein response.routes) {

                // 擷取折線 多段線 polyline

                MKPolyline *polyline = route.polyline;

                //3.3 添加地圖遮蓋物

                //Overlay: 遮蓋物

                [self.mapView  addOverlay:polyline];

            }

        }];

    }];

}

#pragma mark 還需要設定渲染物對象 --> MapView代理方法

//Renderer: 渲染

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay

{

    //1. 建立一個渲染物對象 MKPolylineRenderer-->MKOverlayRenderer子類

    MKPolylineRenderer *polyline = [[MKPolylineRendereralloc]initWithOverlay:overlay];

    //2. 設定線條顔色 --> 預設無色

    polyline.strokeColor = [UIColorblueColor];

    return polyline;

}

@end

=================================================================

百度地圖內建

#import "AppDelegate.h"

#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相關所有的頭檔案

//#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地圖功能所有的頭檔案

//

//#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入檢索功能所有的頭檔案

//

//#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入雲檢索功能所有的頭檔案

//

//#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的頭檔案

//

//#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入計算工具所有的頭檔案

//

//#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周邊雷達功能所有的頭檔案

//

//#import <BaiduMapAPI_Map/BMKMapView.h>//隻引入所需的單個頭檔案

@interface AppDelegate ()

{

    BMKMapManager* _mapManager;

}

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 要使用百度地圖,請先啟動BaiduMapManager

    _mapManager = [[BMKMapManageralloc]init];

    // 第三方SDK一般都在這裡進行授權,也都需要填入授權KEY

    // 鑒權未完成

    // 如果要關注網絡及授權驗證事件,請設定     generalDelegate參數

    BOOL ret = [_mapManagerstart:@"yzducGjmv9ydbpB0DBhiNiuU" generalDelegate:nil];

    if (!ret) {

        NSLog(@"manager start failed!");

    }

    return YES;

}

- (void)onGetNetworkState:(int)iError

{

    if (0 == iError) {

        NSLog(@"聯網成功");

    }

    else{

        NSLog(@"onGetNetworkState %d",iError);

    }

}

- (void)onGetPermissionState:(int)iError

{

    if (0 == iError) {

        NSLog(@"授權成功");

    }

    else {

        NSLog(@"onGetPermissionState %d",iError);

    }

}

@end

--------

#import "ViewController.h"

#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相關所有的頭檔案

#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地圖功能所有的頭檔案

#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入檢索功能所有的頭檔案

#import <BaiduMapAPI_Cloud/BMKCloudSearchComponent.h>//引入雲檢索功能所有的頭檔案

#import <BaiduMapAPI_Location/BMKLocationComponent.h>//引入定位功能所有的頭檔案

#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入計算工具所有的頭檔案

#import <BaiduMapAPI_Radar/BMKRadarComponent.h>//引入周邊雷達功能所有的頭檔案

#import <BaiduMapAPI_Map/BMKMapView.h>//隻引入所需的單個頭檔案

@interface ViewController ()<BMKMapViewDelegate,BMKPoiSearchDelegate>

{

    BMKMapView *_mapView;

    BMKPoiSearch *_searcher;

}

@end

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    _mapView = [[BMKMapViewalloc]init];

    self.view =_mapView;

    //addSubview必須設定frame

    //self.view addSubview:<#(nonnull UIView *)#>

    //1. 切換為衛星圖

    [_mapViewsetMapType:BMKMapTypeSatellite];

    //2. 打開實時路況圖層

    [_mapViewsetTrafficEnabled:YES];

    //3. 打開百度城市熱力圖圖層(百度自有資料)

    [_mapViewsetBaiduHeatMapEnabled:YES];

    //4. 添加大頭針

    // 添加一個PointAnnotation

    BMKPointAnnotation* annotation = [[BMKPointAnnotationalloc]init];

    CLLocationCoordinate2D coor;

    coor.latitude = 39.915;

    coor.longitude = 116.404;

    annotation.coordinate = coor;

    annotation.title = @"這裡是北京";

    [_mapView addAnnotation:annotation];

    //5. POI檢索 -->将POI檢索請求延遲發送即可

    [selfperformSelector:@selector(poiSearch)withObject:nilafterDelay:2];

    //6. 顯示跨度 --> 地圖層級

    [_mapViewsetZoomLevel:16];

}

- (void)poiSearch

{

    //初始化檢索對象

    _searcher =[[BMKPoiSearchalloc]init];

    _searcher.delegate =self;

    //發起檢索

    BMKNearbySearchOption *option = [[BMKNearbySearchOptionalloc]init];

    ///分頁索引,可選,預設為0

    option.pageIndex = 0;

    ///分頁數量,可選,預設為10,最多為50

    option.pageCapacity = 10;

    // 經緯度

    option.location =CLLocationCoordinate2DMake(39.915,116.404);

    option.keyword = @"小吃";

    BOOL flag = [_searcherpoiSearchNearBy:option];

    if(flag)

    {

        NSLog(@"周邊檢索發送成功");

    }

    else

    {

        NSLog(@"周邊檢索發送失敗");

    }

}

//實作PoiSearchDeleage處理回調結果

- (void)onGetPoiResult:(BMKPoiSearch*)searcher result:(BMKPoiResult*)poiResultList errorCode:(BMKSearchErrorCode)error

{

    // 一般來說,接受到POI搜尋結果,顯示大頭針 / 提供清單

    if (error ==BMK_SEARCH_NO_ERROR) {

        //在此處理正常結果

        for (BMKPoiInfo *poiInfoin poiResultList.poiInfoList) {

            //添加大頭針

            BMKPointAnnotation* annotation = [[BMKPointAnnotationalloc]init];

            annotation.coordinate = poiInfo.pt;

            annotation.title = poiInfo.address;

            [_mapView addAnnotation:annotation];

        }

    }

    elseif (error ==BMK_SEARCH_AMBIGUOUS_KEYWORD){

        //當在設定城市未找到結果,但在其他城市找到結果時,回調建議檢索城市清單

        // result.cityList;

        NSLog(@"起始點有歧義");

    } else {

        NSLog(@"抱歉,未找到結果");

        NSLog(@"error: %d",error);

    }

}

- (void)viewWillAppear:(BOOL)animated

{

    [_mapViewviewWillAppear];

    _mapView.delegate =self;//此處記得不用的時候需要置nil,否則影響記憶體的釋放

}

- (void)viewWillDisappear:(BOOL)animated

{

    [_mapViewviewWillDisappear];

    _mapView.delegate =nil;//不用時,置nil

    _searcher.delegate =nil;//不使用時将delegate設定為 nil

}

@end