iOS做地图相关需要知道的Tips(二)—— CoreLocation和MapKit框架

栏目: IOS · 发布时间: 6年前

内容简介:CoreLocation框架中使用CLLocationManager对象来做用户定位 创建(初始化)locations参数里面装着CLLocation对象判断定位功能是否可用(为了严谨起见,最好在使用定位功能前进行判断)
  • CoreLocation框架

    • CoreLocation
    • CLLocation
    • ios地图开发的隐私保护(如何添加授权)
    • CLGeocoder
    • CLPlacemark
  • MapKit框架

    • MKMapView
    • MKCoordinateRegion
    • MKMapView的代理
    • MKUserLocation
    • 大头针
    • annotation
    • 自定义大头针
    • MKAnnotationView
    • MKPinAnnotationView
    • MKMapItem调用系统APP进行导航
    • MKMapCamera地图街景
    • MKMapSnapshotter地图截图

二、大框架

CoreLocation:用于地理定位,地理编码区域监听等(着重功能实现)
MapKit:用于地图展示,例如大头针,路线,覆盖层展示等(着重界面展示)
复制代码

CoreLocation框架的使用

CLLocationManager

CoreLocation框架中使用CLLocationManager对象来做用户定位 创建(初始化)

CLLocationManager *lM = [[CLLocationManager alloc] init];
复制代码

常用属性

  • 每隔多少米定位一次

    @property(assign, nonatomic) CLLocationDistance distanceFilter;
    复制代码
  • 定位精确度(越精确就越耗电)

    @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
    复制代码
  • 朝向改变时,每隔多少度调用一次

    @property(assign, nonatomic) CLLocationDegrees headingFilter
    复制代码
  • 每隔多米定位一次

    _lM.distanceFilter = 100;
    /**
        kCLLocationAccuracyBestForNavigation // 最适合导航
        kCLLocationAccuracyBest; // 最好的
        kCLLocationAccuracyNearestTenMeters; // 10m
        kCLLocationAccuracyHundredMeters; // 100m
        kCLLocationAccuracyKilometer; // 1000m
        kCLLocationAccuracyThreeKilometers; // 3000m
    */
    // 精确度越高, 越耗电, 定位时间越长
    _lM.desiredAccuracy = kCLLocationAccuracyBest;
     
    复制代码

常用方法

  • 开始更新用户位置
- (void)startUpdatingLocation;
复制代码
  • 当调用了startUpdatingLocation方法后,就开始不断地请求、刷新用户的位置,一旦请求到用户位置就会调用代理的下面方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
复制代码

locations参数里面装着CLLocation对象

  • 停止更新用户位置
- (void) stopUpdatingLocation;
复制代码

判断定位功能是否可用(为了严谨起见,最好在使用定位功能前进行判断)

+ (BOOL)locationServicesEnabled;
复制代码

监听设备朝向

-(void)startUpdatingHeading(如试例代码中的指南针的实现)
复制代码

区域监听(监听进出某个区域)

-(void)requestStateForRegion:region;
复制代码
//使用位置管理者,开始更新用户位置
    // 默认只能在前台获取用户位置,
    // 勾选后台模式 location updates
    [self.lM startUpdatingLocation];
复制代码
//监听设备朝向
    [self.lM startUpdatingHeading];
复制代码
- 区域监听(监听进出某个区域)
   [self.lM requestStateForRegion:region];
复制代码

代理方法

  • 更新位置后调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
复制代码
  • 授权状态改变时调用
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
复制代码
  • 获取手机朝向时调用
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
复制代码
  • 区域监听的代理方法

    • 进入区域时调用:
      -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
      复制代码
    • 离开区域时调用:
      -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
      复制代码
    • 监听是否在某个区域的状态:
      -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state
      复制代码
/**
*  更新到位置之后调用
*
*  @param manager   位置管理者
*  @param locations 位置数组
*/
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
   NSLog(@"定位到了");
   
   // 拿到位置,做一些业务逻辑操作
   
   
   // 停止更新
//    [manager stopUpdatingLocation];
}
复制代码
/**
 *  授权状态发生改变时调用
 *
 *  @param manager 位置管理者
 *  @param status  状态
 */
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
            // 用户还未决定
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用户还未决定");
            break;
        }
            // 问受限
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"访问受限");
            break;
        }
            // 定位关闭时和对此APP授权为never时调用
        case kCLAuthorizationStatusDenied:
        {
            // 定位是否可用(是否支持定位或者定位是否开启)
            if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"定位开启,但被拒");
            }else
            {
                NSLog(@"定位关闭,不可用");
            }
//            NSLog(@"被拒");
            break;
        }
            // 获取前后台定位授权
        case kCLAuthorizationStatusAuthorizedAlways:
            //        case kCLAuthorizationStatusAuthorized: // 失效,不建议使用
        {
            NSLog(@"获取前后台定位授权");
            break;
        }
            // 获得前台定位授权
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"获得前台定位授权");
            break;
        }
        default:
            break;
    }
}
复制代码
/**
 *  简易指南针的实现
 *  手机朝向改变时调用
 *
 *  @param manager    位置管理者
 *  @param newHeading 朝向对象
 */
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    /**
     *  CLHeading 
     *  magneticHeading : 磁北角度
     *  trueHeading : 真北角度
     */
    
    NSLog(@"%f", newHeading.magneticHeading);
    
    CGFloat angle = newHeading.magneticHeading;
    
    // 把角度转弧度
    CGFloat angleR = angle / 180.0 * M_PI;
    
    // 旋转图片(指南针图片)
    [UIView animateWithDuration:0.25 animations:^{
        self.compassView.transform = CGAffineTransformMakeRotation(-angleR);
    }]; 
}
复制代码
//区域监听的代理方法
// 进入区域
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
   NSLog(@"进入区域--%@", region.identifier);
}

// 离开区域
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
   NSLog(@"离开区域--%@", region.identifier);
}

//监听是否在某个区域的状态
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
   //state的值
   //CLRegionStateUnknown,
   //CLRegionStateInside,
   //CLRegionStateOutside
   NSLog(@"%zd", state);   
}
复制代码

CLLocation

  • CLLocation用来表示某个位置的地理信息,比如经纬度,海拔等等

  • 常用属性

    • 经纬度
    @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
    复制代码
    • 海拔
    @property(readonly, nonatomic) CLLocationDistance altitude;
    复制代码
    • 路线,航向(取值范围是0.0° ~ 359.9°,0.0°代表真北方向)
    @property(readonly, nonatomic) CLLocationDirection course;
    复制代码
    • 移动速度(单位是m/s)
    @property(readonly, nonatomic) CLLocationSpeed speed;
    复制代码
  • 常用方法

    • 计算两个位置之间的距离:
    - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
    复制代码

使用试例:根据移动方向打印出移动的方向和距离

/**
 *  CLLocationManager对象的代理方法,当用户位置改变的时候调用
 *  更新到位置之后调用
 *
 *  @param manager   位置管理者
 *  @param locations 位置数组
 * is kind of
 */
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
//    NSLog(@"定位到了");
    /**
     *  CLLocation 详解
     *  coordinate : 经纬度
     *  altitude : 海拔
     *  course : 航向
     *  speed ; 速度
     */

    CLLocation *location = [locations lastObject];
    
//    NSLog(@"%@", location);
    
    /**
     *  场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
        例如:”北偏东 30度  方向,移动了8米”
     */
    
    // 1. 获取方向偏向
    NSString *angleStr = nil;
    
    switch ((int)location.course / 90) {
        case 0:
            angleStr = @"北偏东";
            break;
        case 1:
            angleStr = @"东偏南";
            break;
        case 2:
            angleStr = @"南偏西";
            break;
        case 3:
            angleStr = @"西偏北";
            break;
            
        default:
            angleStr = @"跑沟里去了!!";
            break;
    }
    // 2. 偏向角度
    NSInteger angle = 0;
    angle = (int)location.course % 90;
    
    // 代表正方向
    if (angle == 0) {
        NSRange range = NSMakeRange(0, 1);
        angleStr = [NSString stringWithFormat:@"正%@", [angleStr substringWithRange:range]];
    }
    // 3.移动多少米
    double distance = 0;
    if(_oldL)
    {
        distance = [location distanceFromLocation:_oldL];
    }
    _oldL = location;
    // 4. 拼串 打印
    // 例如:”北偏东 30度  方向,移动了8米”
    NSString *noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移动了%f米", angleStr, angle, distance];
    NSLog(@"%@", noticeStr);
}
复制代码

ios地图开发用户隐私保护(授权)

ios6+

  • 当使用定位时,系统会自动弹出对话框让用户授权。
    • 一旦用户选择了不允许,意味着应用程序以后都无法使用定位。
  • 开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的(Privacy - Location Usage Description)

ios8.0+

  • 从ios8.0开始,苹果进一步加强了对用户隐私的保护。

  • 当app想访问用户的隐私时,系统不再自动弹出一个对话框让用户授权.

解决方案

  • (1)调用ios8.0的api。主动请求用户授权

    • -(void)requestAlwaysAuthorization // 请求允许在前后台都能获取用户位置的授权
    • -(void)requestWhenInUseAuthorization // 请求允许在前台获取用户位置的授权(注意:当设置为前台授权时,通过设置后台模式:location updates后 也可以后台获取定位信息,但是屏幕上方会出现蓝条)
  • (2)务必在info.plist文件中配置对应的键值, 否则以上请求授权的方法不生效

    • NSLocationAlwaysUsageDescription : 允许在前后台获取GPS的描述
    • NSLocationWhenInUseDescription : 允许在前台获取GPS的描述

ios9.0

  • ios9.0如果当前处于前台授权状态,默认是不可以后台获取用户位置。但可以设置以下属性为YES,就可以继续在后台获取位置,但是在屏幕上方会出现蓝条

    • @property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates
    • 使用注意:必须设置对应的后台模式:location updates
  • ios9.0可以单次请求用户位置

    • -(void)requestLocation
    • -(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations // 成功调用
    • -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失败调用

CLGeocoder

  • 使用CLGeocoder可以完成“地理编码”和“反地理编码”

    • 地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
    • 反地理编码:根据给定的经纬度,获得具体的位置信息
  • 对应方法

    • 地理编码方法
    -(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
    复制代码
    • 反地理编码方法
    -(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
    复制代码
  • CLGeocodeCompletionHandler:反地理编码完成时,就会调用CLGeocodeCompletionHandler

    • typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);

      • error :当编码出错时(比如编码不出具体的信息)有值
      • placemarks :里面装着CLPlacemark对象

地理编码的实现

// 地理编码
- (IBAction)geoCoder {

    //当传入的值为0时直接返回
    if ([self.addressDetailTV.text length] == 0) {
        return;
    }

    // 地理编码方案一:直接根据地址进行地理编码(返回结果可能有多个,因为一个地点有重名)
    [self.geoC geocodeAddressString:self.addressDetailTV.text completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        // 包含区,街道等信息的地标对象
        CLPlacemark *placemark = [placemarks firstObject];
        // 城市名称
//        NSString *city = placemark.locality;
        // 街道名称
//        NSString *street = placemark.thoroughfare;
        // 全称
        NSString *name = placemark.name;
        self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
    }];
    // 地理编码方案二:根据地址和区域两个条件进行地理编码(更加精确)
//    [self.geoC geocodeAddressString:self.addressDetailTV.text inRegion:nil completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
//        // 包含区,街道等信息的地标对象
//        CLPlacemark *placemark = [placemarks firstObject];
//        self.addressDetailTV.text = placemark.description;
//        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
//    }];

    

    // 地理编码方案三:
//    NSDictionary *addressDic = @{
//                                 (__bridge NSString *)kABPersonAddressCityKey : @"北京",
//                                 (__bridge NSString *)kABPersonAddressStreetKey : @"棠下街"
//                                 };
//    [self.geoC geocodeAddressDictionary:addressDic completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
//        CLPlacemark *placemark = [placemarks firstObject];
//        self.addressDetailTV.text = placemark.description;
//        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
//    }];
}
复制代码

反地理编码的实现

// 反地理编码
- (IBAction)decode {
    // 过滤空数据
    if ([self.latitudeTF.text length] == 0 || [self.longtitudeTF.text length] == 0) {
        return;
    }
    // 创建CLLocation对象
    CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text doubleValue] longitude:[self.longtitudeTF.text doubleValue]];
    // 根据CLLocation对象进行反地理编码
    [self.geoC reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
        // 包含区,街道等信息的地标对象
        CLPlacemark *placemark = [placemarks firstObject];
        // 城市名称
//        NSString *city = placemark.locality;
        // 街道名称
//        NSString *street = placemark.thoroughfare;
        // 全称
        NSString *name = placemark.name;
        self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
    }];

}
复制代码

CLPlacemark

  • CLPlacemark的字面意思是地标,封装详细的地址位置信息 常用属性

    • 地理位置
    @property (nonatomic, readonly) CLLocation *location;
    复制代码
    • 区域
    @property (nonatomic, readonly) CLRegion *region;
    复制代码
    • 详细的地址信息
    @property (nonatomic, readonly) NSDictionary *addressDictionary;
    复制代码
    • 地址名称
    @property (nonatomic, readonly) NSString *name;
    复制代码
    • 城市
    @property (nonatomic, readonly) NSString *locality;
    复制代码

MapKit框架的使用

MapKit通过MKMapView来显示地图

  • 常用属性

    • 地图配型:mapType

      • MKMapTypeStandard :普通地图(左图)
      • MKMapTypeSatellite :卫星云图 (中图)
      • MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 )
      • MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0)
      • MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0)
  • 操作项

    • 是否可缩放 zoomEnabled
    • 是否可滚动 scrollEnabled
    • 是否可旋转 rotateEnabled
  • 显示项

    • 是否显示指南针 showsCompass (iOS9.0)
    • 是否显示比例尺 showsScale (iOS9.0)
    • 是否显示交通 showsTraffic (iOS9.0)
    • 是否显示建筑 showsBuildings
  • 跟踪显示用户的位置(ios8-地图不会自动滚到用户所在的位置,ios8+地图会自动放大到合适比例,并显示出用户位置)

    • MKUserTrackingModeNone :不跟踪用户的位置
    • MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
    • MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
  • 设置地图显示的区域和位置

    • 设置地图的中心点位置

      • @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
      • -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
    • 设置地图的显示区域

      • @property (nonatomic) MKCoordinateRegion region;
      • -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

MKCoordinateRegion

  • MKCoordinateRegion是一个用来表示区域的结构体
typedef struct {
         CLLocationCoordinate2D center; // 区域的中心点位置
        MKCoordinateSpan span; // 区域的跨度
} MKCoordinateRegion;
复制代码
  • MKCoordinateSpan
typedef struct {
    CLLocationDegrees latitudeDelta; // 纬度跨度
    CLLocationDegrees longitudeDelta; // 经度跨度
} MKCoordinateSpan;
复制代码

MKMapView的代理

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

    • 一个位置更改默认只会调用一次,不断监测用户的当前位置
    • 每次调用,都会把用户的最新位置(userLocation参数)传进来
  • -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;

    • 地图的显示区域即将发生改变的时候调用
  • -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;

    • 地图的显示区域已经发生改变的时候调用

MKUserLocation

  • @property (nonatomic, copy) NSString *title;
    • 显示在大头针上的标题
  • @property (nonatomic, copy) NSString *subtitle;
    • 显示在大头针上的子标题
  • @property (readonly, nonatomic) CLLocation *location;
    • 地理位置信息(大头针钉在什么地方?)

大头针

  • 添加大头针

    • 添加一个大头针
      • -(void)addAnnotation:(id )annotation;
    • 添加多个大头针
      • -(void)addAnnotations:(NSArray *)annotations;
  • 移除大头针

    • 移除一个大头针
      • -(void)removeAnnotation:(id )annotation;
    • 移除多个大头针
      • -(void)removeAnnotations:(NSArray *)annotations;

annotation

  • 大头针模型对象
#import <MapKit/MapKit.h>

@interface TestAnnotation : NSObject <MKAnnotation>
/** 坐标位置 */
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
/** 标题 */
@property (nonatomic, copy) NSString *title; 
/** 子标题 */
@property (nonatomic, copy) NSString *subtitle; 
@end
复制代码

自定义大头针

  • 设置MKMapView代理

    • -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation;
      • 根据传进来的(id )annotation参数创建并返回对应的大头针控件
      • 注意:如果返回nil,显示出来的大头针就采取系统的默认样式
      • 标识用户位置的蓝色发光圆点,它也是一个大头针,当显示这个大头针时,也会调用代理方法
      • 因此,需要在代理方法中分清楚(id )annotation参数代表自定义的大头针还是蓝色发光圆点
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    // 判断annotation的类型
    if (![annotation isKindOfClass:[TestAnnotation class]]) return nil;
    
    // 创建MKAnnotationView
    static NSString *ID = @"tuangou";
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (annoView == nil) {
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        annoView.canShowCallout = YES;
    }
复制代码

MKAnnotationView

地图上的大头针控件是MKAnnotationView

  • 属性

    • @property (nonatomic, strong) id annotation;
      • 大头针模型
    • @property (nonatomic, strong) UIImage *image;
      • 显示的图片
    • @property (nonatomic) BOOL canShowCallout;
      • 是否显示标注
    • @property (nonatomic) CGPoint calloutOffset;
      • 标注的偏移量
    • @property (strong, nonatomic) UIView *rightCalloutAccessoryView;
      • 标注右边显示什么控件
    • @property (strong, nonatomic) UIView *leftCalloutAccessoryView;
      • 标注左边显示什么控件
    • @property (nonatomic, strong) UIView *detailCalloutAccessoryView
      • 标注下面显示什么控件(iOS9.0)

MKPinAnnotationView

MKPinAnnotationView是MKAnnotationView的子类

  • MKPinAnnotationView比MKAnnotationView多了2个属性

    • @property (nonatomic) MKPinAnnotationColor pinColor;
      • 大头针颜色
    • @property (nonatomic) BOOL animatesDrop;
      • 大头针第一次显示时是否从天而降

MKMapItem调用系统APP进行导航

// 根据两个地标对象进行调用系统导航
- (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark
{
    // 创建起点:根据 CLPlacemark 地标对象创建 MKPlacemark 地标对象
    MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark];
    MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1];

    // 创建终点:根据 CLPlacemark 地标对象创建 MKPlacemark 地标对象
    MKPlacemark *itemP2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark];
    MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:itemP2];

    NSDictionary *launchDic = @{
                                // 设置导航模式参数
                                MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,
                                // 设置地图类型
                                MKLaunchOptionsMapTypeKey : @(MKMapTypeHybridFlyover),
                                // 设置是否显示交通
                                MKLaunchOptionsShowsTrafficKey : @(YES),

                                };
    // 根据 MKMapItem 数组 和 启动参数字典 来调用系统地图进行导航
    [MKMapItem openMapsWithItems:@[item1, item2] launchOptions:launchDic];
}
复制代码

MKMapCamera地图街景

// 创建视角中心坐标
     CLLocationCoordinate2D center = CLLocationCoordinate2DMake(23.132931, 113.375924);
    // 创建3D视角
    MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001) eyeAltitude:1];
    // 设置到地图上显示
    self.mapView.camera = camera;
复制代码

MKMapSnapshotter地图截图

// 截图附加选项
    MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
    // 设置截图区域(在地图上的区域,作用在地图)
    options.region = self.mapView.region;
//    options.mapRect = self.mapView.visibleMapRect;

    // 设置截图后的图片大小(作用在输出图像)
    options.size = self.mapView.frame.size;
    // 设置截图后的图片比例(默认是屏幕比例, 作用在输出图像)
    options.scale = [[UIScreen mainScreen] scale];

    MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
    [snapshotter startWithCompletionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
        if (error) {
            NSLog(@"截图错误:%@",error.localizedDescription);
        }else
        {
            // 设置屏幕上图片显示
            self.snapshootImageView.image = snapshot.image;
            // 将图片保存到指定路径(此处是桌面路径,需要根据个人电脑不同进行修改)
            NSData *data = UIImagePNGRepresentation(snapshot.image);
            [data writeToFile:@"/Users/wangshunzi/Desktop/snap.png" atomically:YES];
        }
    }];
复制代码

原文地址: iOS开发-地图开发(CoreLocation和MapKit))


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Caching

Web Caching

Duane Wessels / O'Reilly Media, Inc. / 2001-6 / 39.95美元

On the World Wide Web, speed and efficiency are vital. Users have little patience for slow web pages, while network administrators want to make the most of their available bandwidth. A properly design......一起来看看 《Web Caching》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码