地圖、定位 CLLocationManager CLGeocoder CLPlacemark

地圖、定位
1、基本知識點
定位:
一、info.plist文件設置
ios8之後,使用定位須要在info.plist文件中添加兩個字段NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription
二、導入CoreLocation.framework框架並導入頭文件
#import <CoreLocation/CoreLocation.h>
三、判判定位服務是否打開
if (![CLLocationManager locationServicesEnabled]) {
       NSLog(@"定位不可用");
    }
四、建立定位管理器
CLLocationManager *_manager = [[CLLocationManager alloc]init];
五、判斷是否受權,若是未受權則發送受權請求
if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
            [_manager requestWhenInUseAuthorization];
 }
六、設置代理(CLLocationManagerDelegate)
_manager.delegate=self;
七、設置精度
_manager.desiredAccuracy=kCLLocationAccuracyBest;
八、設置定位頻率,多少米定位一次
_manager.distanceFilter=10.0;
九、開始定位
[_manager startUpdatingLocation];
十、中止定位
[_manager stopUpdatingLocation];
十一、代理方法
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    //定位失敗
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    CLLocation *location = [locations firstObject];
CLLocationCoordinate2D coordinate=location.coordinate;
    NSLog(@"經度:%f,緯度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);
    }
地理編碼,根據地址得出經緯度、詳細信息等
    CLGeocoder *geocode = [[CLGeocoder alloc]init];
    [geocode geocodeAddressString:@"泰山" completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *place = [placemarks firstObject];
        CLLocation *location = place.location;//位置
        CLRegion *region = place.region;//區域
        NSDictionary *dic = place.addressDictionary;//詳細地址信息字典,包含如下字段
        NSString *name=place.name;//地名
        NSString *thoroughfare=place.thoroughfare;//街道
        NSString *subThoroughfare=place.subThoroughfare; //街道相關信息,例如門牌等
        NSString *locality=place.locality; // 城市
        NSString *subLocality=place.subLocality; // 城市相關信息,例如標誌性建築
        NSString *administrativeArea=place.administrativeArea; // 州
        NSString*subAdministrativeArea=place.subAdministrativeArea; //其餘行政區域信息
        NSString *postalCode=place.postalCode; //郵編
        NSString *ISOcountryCode=place.ISOcountryCode; //國家編碼
        NSString *country=place.country; //國家
        NSString *inlandWater=place.inlandWater; //水源、湖泊
        NSString *ocean=place.ocean; // 海洋
        NSArray *areasOfInterest=place.areasOfInterest; //關聯的或利益相關的地標
    }];
}
反向地理編碼,根據經緯度得出具體的地址信息
    CLLocation*location=[[CLLocation alloc]initWithLatitude:36.228 longitude:117.042];
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark*placemark=[placemarks firstObject];
        NSLog(@"詳細信息:%@",placemark.addressDictionary);
    }];
地圖:
十二、導入MapKit.framework,並導入#import <MapKit/MapKit.h>頭文件,實現MKMapViewDelegate協議
1三、建立
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
1四、設置代理
_mapView.delegate  = self;
1五、是否顯示用戶位置
_mapView.showsUserLocation = YES;
1六、用戶位置跟蹤
_mapView.userTrackingMode = MKUserTrackingModeFollow;//能夠省略,可是須要本身設置地圖的縮放級別
1七、代理方法:獲取用戶當前位置
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation*)userLocation{
        MKCoordinateSpan span=MKCoordinateSpanMake(0.01, 0.01);
        MKCoordinateRegion region=MKCoordinateRegionMake(userLocation.location.coordinate, span);
        [_mapView setRegion:region animated:true];//設置地圖縮放級別
}
1八、地圖顯示範圍發生改變
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    NSLog(@"地圖顯示範圍發生改變");
}
1九、添加大頭針
MKPointAnnotation *point = [[MKPointAnnotation alloc]init];//初始化
point.title = @"大頭針";//標題
point.subtitle = @"我是大頭針";//子標題
point.coordinate = CLLocationCoordinate2DMake(36.236867, 117.054895);//經緯度
[_mapView addAnnotation:point];
20、大頭針被點擊
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    NSLog(@"大頭針被點擊");
}
2一、自定義大頭針視圖
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {//判斷是否是本身添加的大頭針
        static NSString *key1=@"AnnotationKey1";
        MKAnnotationView*annotationView=[_mapView dequeueReusableAnnotationViewWithIdentifier:key1];//獲取大頭針視圖
        //若是緩存池中不存在則新建
        if (!annotationView) {
            annotationView=[[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1];
           annotationView.canShowCallout=true;//容許交互點擊                     annotationView.calloutOffset=CGPointMake(0, 1);//定義詳情視圖偏移量
           UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
          button.frame = CGRectMake(0, 0, 40, 40);           [button setBackgroundImage:[UIImage imageNamed:@"icon_classify_cafe.png"] forState:UIControlStateNormal];            annotationView.leftCalloutAccessoryView=button;//定義詳情左側視圖
        }       
        //修改大頭針視圖
        //從新設置此類大頭針視圖的大頭針模型(由於有多是從緩存池中取出來的,位置是放到緩存池時的位置)
        annotationView.annotation=annotation;
        annotationView.image=[UIImage imageNamed:@"icon_paopao_waterdrop_streetscape"];//設置大頭針視圖的圖片       
       return annotationView;
    }else {
        return nil;
    }
}
2二、大頭針左側或者右側視圖被點擊
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
    if ([control isKindOfClass:[UIButton class]]) {
        NSLog(@"121212");
    }
}
2三、調用系統自帶地圖進行導航
-(void)turnByTurn{
    //根據「泰山學院」地理編碼
    CLGeocoder *_geocoder = [[CLGeocoder alloc] init];
    [_geocoder geocodeAddressString:@"泰山學院" completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *clPlacemark1=[placemarks firstObject];//獲取第一個地標
        MKPlacemark *mkPlacemark1=[[MKPlacemark alloc]initWithPlacemark:clPlacemark1];
        //注意地理編碼一次只能定位到一個位置,不能同時定位,所在放到第一個位置定位完成回調函數中再次定位
        [_geocoder geocodeAddressString:@"山東省泰安市泰山站" completionHandler:^(NSArray *placemarks, NSError *error) {
            CLPlacemark *clPlacemark2=[placemarks firstObject];//獲取第一個地標
            MKPlacemark *mkPlacemark2=[[MKPlacemark alloc]initWithPlacemark:clPlacemark2];
            NSDictionary *options=@{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard),MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving};//設置導航類型
            MKMapItem *mapItem1=[[MKMapItem alloc]initWithPlacemark:mkPlacemark1];
            MKMapItem *mapItem2=[[MKMapItem alloc]initWithPlacemark:mkPlacemark2];
            [MKMapItem openMapsWithItems:@[mapItem1,mapItem2] launchOptions:options];
        }]; 
    }];}
 
2、具體代碼
 
#import "ViewController.h」
一、首先導入頭文件 #import <CoreLocation/CoreLocation.h>
//導入頭文件
二、info.plist文件設置,ios8之後,使用定位須要在info.plist文件中添加兩個字段NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription。
@interface ViewController ()<CLLocationManagerDelegate>{
    CLLocationManager *manager;//位置管理
}
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
 
三、判斷是否容許訪問定位           if([CLLocationManagerlocationServicesEnabled]) {
        manager = [[CLLocationManager alloc]init];//初始化
        NSLog(@"容許定位");
        //判斷用戶是否選擇了位置訪問權限
        if ([CLLocationManager authorizationStatus] == 0) {
            //若是還沒有選擇,則從新彈出請求
            [manager requestAlwaysAuthorization];
        }
        //設置代理
        manager.delegate = self;
        manager.distanceFilter = 10;//多少米訪問一次位置
        manager.desiredAccuracy = kCLLocationAccuracyBest;//定位的精確度
        [manager startUpdatingLocation];//開始定位 
        [self getInfoBUyAddress];
    }
}
 
四、錯誤信息
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"%@",error);
}
五、打印具體內容
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    NSLog(@"--%zi---%@",locations.count,locations);
    CLLocation *location = [locations firstObject];
    NSLog(@"weidu:%f--jingdu:%f",location.coordinate.latitude,location.coordinate.longitude);
}
六、地理編碼
-(void)getInfoBUyAddress{
    CLGeocoder *geo = [[CLGeocoder alloc]init];//初始化編碼管理
    //地理編碼,傳入地址,獲得具體信息
    [ geo geocodeAddressString:@"周口火車站" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        NSLog(@"--數量:%zi  信息:%@",placemarks.count,placemarks);
        CLPlacemark *place = [placemarks firstObject];
        NSLog(@"經緯度:%f---%f",place.location.coordinate.latitude,place.location.coordinate.longitude);
        NSLog(@"街道:%@",place.ocean);
    }];
}
 
七、反地理編碼:根據經緯度獲得位置信息
-(void)getInfoBuyCoordinate{
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    CLLocation *location = [[CLLocation alloc]initWithLatitude:34.709895 longitude:113.509167];//經過經緯度定義位置對象
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        NSLog(@"數量:%zi   反向: %@",placemarks.count,placemarks);
       
        CLPlacemark *place = [placemarks firstObject];
        NSLog(@"經緯度:%f,%f",place.location.coordinate.longitude,place.location.coordinate.latitude);
        NSLog(@"街道:%@",place.ocean);
    }]; 
}
 
地圖具體代碼
一、導入頭文件
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
@interface ViewController ()
二、添加代理
<CLLocationManagerDelegate,MKMapViewDelegate>{   
三、建立對象
    CLLocationManager *_manager;
    MKMapView *_mapView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
四、判斷是否容許訪問,若是不容許則從新設置
    if ([CLLocationManager locationServicesEnabled]) {
        _manager = [[CLLocationManager alloc] init];
        if ([CLLocationManager authorizationStatus] == 0) {
            [_manager requestWhenInUseAuthorization];
        }
        _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
        _mapView.delegate = self;//設置代理
        _mapView.showsUserLocation = YES;//顯示用戶位置
       // mapView.userTrackingMode = MKUserTrackingModeFollow;//跟隨模式
        [self.view addSubview:_mapView];
        [self addAnnotation];
        [self daohang];
   }  
}
五、點擊大頭針
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    NSLog(@"大頭針被點擊:%@",view.annotation.title);
}
六、定位失敗信息反饋
-(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error{
    //定位失敗
}
 
七、更新座標位置
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
    //在該方法中獲取用戶當前位置的經緯度
    NSLog(@"經度:%f  緯度:%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude);
  八、設置經緯度精度範圍
    MKCoordinateSpan span = {0.1,0.1};//在中心經緯度的基礎上+/- 的值
   九、設置中心經緯度以及可視範圍 
    MKCoordinateRegion region = {userLocation.coordinate,span};
   十、設置地圖縮放級別
    [mapView setRegion:region animated:YES];
}
十一、拖動地圖走該方法
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
     NSLog(@"----改變");
}
十二、添加大頭針
-(void)addAnnotation{
1)初始化大頭針
    MKPointAnnotation *an = [[MKPointAnnotation alloc] init];
2)設置大頭針標題
    an.title = @"個人大頭針";
3)設置大頭針副標題
    an.subtitle = @"副標題";
4)設置大頭針的經緯度
    an.coordinate = CLLocationCoordinate2DMake(34.709895, 113.509167);
    [_mapView addAnnotation:an]; 
}
1三、自定義大頭針
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
 1)判斷是不是程序員本身添加的大頭針
    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
 2)定義重用標識
    static NSString *identifier = @"an";
       MKAnnotationView *view = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];//從重用池中取可用的大頭針
3)若是!view 則從新定義
        if (!view) {
            view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
4)是否容許彈出氣泡
       view.canShowCallout = YES;
    }
5)設置彈出信息
        view.annotation = annotation;
6)自定義大頭針圖形
        view.image = [UIImage imageNamed:@"an"];
        return view;
    }else{
        //用戶當前位置
        return nil;
    }
}
1四、自定義導航
-(void)daohang{
    MKPlacemark *placeMark = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(34.695135, 113.682188) addressDictionary:nil];
     MKPlacemark *placeMark1 = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(34.709895, 113.499167) addressDictionary:nil];
    NSDictionary *options=@{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard),MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving};//設置導航類型
    MKMapItem *item = [[MKMapItem alloc] initWithPlacemark:placeMark];
    MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:placeMark1];
    [MKMapItem openMapsWithItems:@[item,item1] launchOptions:options];
}
相關文章
相關標籤/搜索