zoukankan      html  css  js  c++  java
  • iOS | 地图定位

    在IOS开发中,最常见的功能之一就是地图定位功能,不单单是百度地图,高德地图等专业的地图导航软件,还有美团,咕咚等一些美食购物类和运动类也需要这样的功能,所以学会这项技能是一名IOS开发工程师必须的.
    百度地图
    咕咚
    美团

    分享一些比较基础的关于定位方面的小知识.

    关于定位有两个框架
    1.CoreLocation ---->用于地理定位
    2.Map Kit ---->用于地图展示

    两个热词:

    LBS: location based service
    SLM: social local mobile

    使用CoreLocation定位

    首先在之前需要导入corelocation框架,然后在头文件导入corelocation.h头文件.
    注意:coordinate是坐标,latitude是纬度,longitude是经度.

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 1.创建位置管理者
        CLLocationManager *locationManager = [[CLLocationManager alloc] init];
        self.locationManager = locationManager;
        // 在iO8之前,只要导入CoreLocation 会自动申请权限
        // 在iOS8之后需要程序员手写
        
        // 2.请求用户授权    必须要配置info.plist文件
        //在info里面配置NSLocationAlwaysUsageDescription或者
        //NSLocationWhenInUseUsageDescription
        // 请求app始终授权  无论程序在前台还是在后台运行  都可以使用定位
    //    [locationManager requestAlwaysAuthorization];
        // 请求app在使用期间授权   在前台使用时才可以使用定位
        [locationManager requestWhenInUseAuthorization];
        
        if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
            // 临时开启后台定位  配置info.plist文件  不配置直接崩溃
            locationManager.allowsBackgroundLocationUpdates = YES;
        }
        // 3.设置属性(两个属性是为了让程序可以持续的进行定位)
    //    // 距离筛选  单位:米  当用户移动100.5米后调用定位方法
    //    locationManager.distanceFilter = 100.5;
    //    // 期望精度  单位:米  系统默认将100米范围内作为一个位置
    //    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        // 4.设置代理
        locationManager.delegate = self;
        // 5.开启定位
        [locationManager startUpdatingLocation];
        // 开始更新移动方向
    //    [locationManager startUpdatingHeading];
    
    
    //代理方法,一旦开启定位,会自动调用这个代理方法
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    {
        // 获取数据
    //    NSLog(@"%@",locations);
        // 停止定位  省电
    //    [manager stopUpdatingLocation];
    }
    
    
    
    // 比较位置的距离  比较的是两点之间的直线距离
    - (void)compareDistance
    {
        // 北京的位置
        CLLocation *location = [[CLLocation alloc] initWithLatitude:39 longitude:115];
        // 上海的位置
        CLLocation *location1 = [[CLLocation alloc] initWithLatitude:30 longitude:120];
        // 比较北京到上海的位置(直线距离)
        double distance = [location distanceFromLocation:location1];
        // 单位:米
        NSLog(@"%f",distance / 1000);
    }
        
    
    使用MapKit定位

    修改地图类型   mapView.mapType
    地图实时交通状态 mapView.showsTraffic
    设置用户跟踪模式  mapView.userTrackingMode
    代理方法,
    //显示在地图中用户定位的位置

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

    //获取实时地图变化的区域变化(中心点,区域跨度)

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

    注意:这里需要导入的是MapKit框架和MapKit.h头文件.

    - (void)viewDidLoad {
        [super viewDidLoad];
         
        // 修改地图类型
        /*
         MKMapTypeStandard    标准(默认)
         MKMapTypeSatellite   卫星
         MKMapTypeHybrid      混合
         MKMapTypeSatelliteFlyover  在中国暂时不能使用
         MKMapTypeHybridFlyover  在中国暂时不能使用
         */
        self.mapView.mapType = MKMapTypeStandard;
        
        // 实时交通状况 iOS9新增
        self.mapView.showsTraffic = YES;
        
        // 创建位置管理者
        self.locationManager = [[CLLocationManager alloc] init];
        // 请求用户授权  配置info.plist
        [self.locationManager requestWhenInUseAuthorization];
        // 设置用户的跟踪模式
        /*
         MKUserTrackingModeFollow  跟踪用户的位置   MKUserTrackingModeFollowWithHeading  跟踪用户的位置和方向
         */
        self.mapView.userTrackingMode = MKUserTrackingModeFollow;
        
        // 设置代理
        self.mapView.delegate = self;
    }
    
    // 跟踪到用户位置时调用
    // mapView:地图
    // userLocation:用户位置的大头针模型
    - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
    {
        // 1.反地理编码
        // 1.1创建地理编码对象
        CLGeocoder *geocoder = [[CLGeocoder alloc] init];
        // 1.2反地理编码
        [geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            // 1.3防错处理
            if (error) {
                NSLog(@"%@",error);
                return ;
            }
            // 1.4获取地标
            CLPlacemark *placemark = [placemarks firstObject];
            // 2.给标题和子标题赋值
            userLocation.title = placemark.locality;
            userLocation.subtitle = placemark.name;
        }];
    }
    
    
    // 回到当前用户的位置
    - (IBAction)backToCurrentLocation
    {
        
        // 获取当前的跨度
        MKCoordinateSpan span = MKCoordinateSpanMake(0.024967, 0.015407);
        // 设置回到用户刚开始的区域 region(结构体) --1.中心点经纬度(结构体)--> 经度和纬度  2.经纬度跨度(结构体)-->经度跨度和纬度跨度
        // 设置区域并使用动画
        [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.userLocation.location.coordinate, span) animated:YES];
    }
    
    
    - (IBAction)biggerMap
    {
        // 修改经纬度跨度
        CGFloat latitudeDelta = self.mapView.region.span.latitudeDelta * 0.5;
        CGFloat longitudeDelta = self.mapView.region.span.longitudeDelta * 0.5;
        MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
        // 确定放大地图后的区域
        [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.centerCoordinate, span) animated:YES];
    }
    - (IBAction)smallerMap
    {
        // 修改经纬度跨度
        CGFloat latitudeDelta = self.mapView.region.span.latitudeDelta * 2;
        CGFloat longitudeDelta = self.mapView.region.span.longitudeDelta * 2;
        MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
        [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.centerCoordinate, span) animated:YES];
    }
    

    演示

    效果演示

    说到底,其实苹果官方的框架已经做得不错了,该有的功能基本都具备,而且使用起来不是怎么困难,掌握起来也非常快.我这里只是分享一些比较基础的功能,欢迎工程师们赐教.
    另外附上地理编码的小演示.

    地理编码.gif

  • 相关阅读:
    redis 内存管理与数据淘汰机制(转载)
    Memcached特性及优缺点
    二叉树深度优先遍历和广度优先遍历
    电商 秒杀系统 设计思路和实现方法(转载)
    6种负载均衡算法
    解决like '%字符串%'时索引不被使用的方法
    哪些情况下索引会失效?
    PreferenceActivity详解
    sun.misc.BASE64Encoder在Eclipse中不能直接使用的原因和解决方案
    单点登录原理与简单实现
  • 原文地址:https://www.cnblogs.com/JanChuJun/p/10102264.html
Copyright © 2011-2022 走看看