一.實作一次定位(實際上就是持續定為,完成定位更新的時候停止定位,就成了一次定位)
@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