zoukankan      html  css  js  c++  java
  • 地图、定位 CLLocationManager CLGeocoder CLPlacemark

    地图、定位
    一、基本知识点
    定位:
    1、info.plist文件设置
    ios8以后,使用定位需要在info.plist文件中添加两个字段NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription
    2、导入CoreLocation.framework框架并导入头文件
    #import <CoreLocation/CoreLocation.h>
    3、判断定位服务是否打开
    if (![CLLocationManager locationServicesEnabled]) {
           NSLog(@"定位不可用");
        }
    4、创建定位管理器
    CLLocationManager *_manager = [[CLLocationManager alloc]init];
    5、判断是否授权,如果未授权则发送授权请求
    if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
                [_manager requestWhenInUseAuthorization];
     }
    6、设置代理(CLLocationManagerDelegate)
    _manager.delegate=self;
    7、设置精度
    _manager.desiredAccuracy=kCLLocationAccuracyBest;
    8、设置定位频率,多少米定位一次
    _manager.distanceFilter=10.0;
    9、开始定位
    [_manager startUpdatingLocation];
    10、停止定位
    [_manager stopUpdatingLocation];
    11、代理方法
    -(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);
        }];
    地图:
    12、导入MapKit.framework,并导入#import <MapKit/MapKit.h>头文件,实现MKMapViewDelegate协议
    13、创建
    _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
    14、设置代理
    _mapView.delegate  = self;
    15、是否显示用户位置
    _mapView.showsUserLocation = YES;
    16、用户位置跟踪
    _mapView.userTrackingMode = MKUserTrackingModeFollow;//可以省略,但是需要自己设置地图的缩放级别
    17、代理方法:获取用户当前位置
    -(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];//设置地图缩放级别
    }
    18、地图显示范围发生改变
    -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
        NSLog(@"地图显示范围发生改变");
    }
    19、添加大头针
    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(@"大头针被点击");
    }
    21、自定义大头针视图
    -(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;
        }
    }
    22、大头针左侧或者右侧视图被点击
    -(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
        if ([control isKindOfClass:[UIButton class]]) {
            NSLog(@"121212");
        }
    }
    23、调用系统自带地图进行导航
    -(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];
            }]; 
        }];}
     
    二、具体代码
     
    #import "ViewController.h”
    1、首先导入头文件 #import <CoreLocation/CoreLocation.h>
    //导入头文件
    2、info.plist文件设置,ios8以后,使用定位需要在info.plist文件中添加两个字段NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription。
    @interface ViewController ()<CLLocationManagerDelegate>{
        CLLocationManager *manager;//位置管理
    }
    @end
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
     
    3、判断是否允许访问定位           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];
        }
    }
     
    4、错误信息
    -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
        NSLog(@"%@",error);
    }
    5、打印具体内容
    -(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);
    }
    6、地理编码
    -(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);
        }];
    }
     
    7、反地理编码:根据经纬度得到位置信息
    -(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);
        }]; 
    }
     
    地图具体代码
    1、导入头文件
    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    #import <MapKit/MapKit.h>
    @interface ViewController ()
    2、添加代理
    <CLLocationManagerDelegate,MKMapViewDelegate>{   
    3、创建对象
        CLLocationManager *_manager;
        MKMapView *_mapView;
    }
    @end
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
    4、判断是否允许访问,如果不允许则重新设置
        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];
       }  
    }
    5、点击大头针
    -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
        NSLog(@"大头针被点击:%@",view.annotation.title);
    }
    6、定位失败信息反馈
    -(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error{
        //定位失败
    }
     
    7、更新坐标位置
    -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
        //在该方法中获取用户当前位置的经纬度
        NSLog(@"经度:%f  纬度:%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude);
      8、设置经纬度精度范围
        MKCoordinateSpan span = {0.1,0.1};//在中心经纬度的基础上+/- 的值
       9、设置中心经纬度以及可视范围 
        MKCoordinateRegion region = {userLocation.coordinate,span};
       10、设置地图缩放级别
        [mapView setRegion:region animated:YES];
    }
    11、拖动地图走该方法
    -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
         NSLog(@"----改变");
    }
    12、添加大头针
    -(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]; 
    }
    13、自定义大头针
    -(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;
        }
    }
    14、自定义导航
    -(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];
    }
  • 相关阅读:
    LibreOJ2095
    Codeforces
    LibreOJ2241
    LibreOJ2044
    LibreOJ2043
    LibreOJ2045
    LibreOJ2042
    LibreOJ2097
    洛谷P4175
    POJ2888
  • 原文地址:https://www.cnblogs.com/wxzboke/p/5062951.html
Copyright © 2011-2022 走看看