关闭

地图

标签: iOS地图进阶
135人阅读 评论(0) 收藏 举报
分类:


地图

一、地图的简介

在移动互联网时代,移动app能解决用户的很多生活琐事,比如
    导航:去任意陌生的地方
    周边:找餐馆、找酒店、找银行、找电影院
    手机软件:微信摇一摇、QQ附近的人、微博、支付宝等

在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这两大功能,必须基于两个框架进行开发
    Map Kit :用于地图展示
    Core Location :用于地理定位

二、地图定位

CoreLocation框架的使用

导入框架  (iOS5之后不再需要)

导入头文件
        #import <CoreLocation/CoreLocation.h>
CoreLocation框架使用须知
        CoreLocation框架中所有数据类型的前缀都是CL
        CoreLocation中使用CLLocationManager对象来做用户定位

CLLocationManager

CLLocationManager的常用操作
// 开始用户定位
- (void)startUpdatingLocation;
// 停止用户定位
- (void) stopUpdatingLocation;

// 当调用了startUpdatingLocation方法后,就开始不断地定位用户的位置,中途会频繁地调用下面的代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
// 参数locations中的元素对象是CLLocation对象


// 每隔多少米定位一次
@property(assign, nonatomic) CLLocationDistance distanceFilter;

// 定位精确度(越精确就越耗电)
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

CLLocationAccuracy 是一个枚举值
/*
最佳导航
  kCLLocationAccuracyBestForNavigation
最精准
     kCLLocationAccuracyBest;
10米
     kCLLocationAccuracyNearestTenMeters;
百米
   kCLLocationAccuracyHundredMeters;
千米
     kCLLocationAccuracyKilometer;
3千米
     kCLLocationAccuracyThreeKilometers;     
*/

CoreLocation框架的使用

实现定位只需要下面几步:
1.  创建管理者对象
 self.manager = [[CLLocationManager alloc] init];
2.  设置代理
 self.manager.delegate = self;
3.  开启定位
    [self.manager startUpdatingLocation];
注意:从iOS 7之后,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经过用户批准授权:
①要想获得用户的位置和访问用户的通讯录、日历、相机、相册等等都需要用户来手动授权。
②当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权

4 、请求授权 (授权方式根据实际情况进行选择)

// 请求授权

 [self.manager requestAlwaysAuthorization];  // 请求前台和后台定位

 [self.manager requestWhenInUseAuthorization];  // 请求后台定位

开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的(Privacy - Location Usage Description)
一旦用户选择了“Don’t Allow”,意味着你的应用以后就无法使用定位功能
为了严谨起见,最好在使用定位功能之前判断当前应用的定位功能是否可用
CLLocationManager有个类方法可以判断当前应用的定位功能是否可用
+ (BOOL)locationServicesEnabled;


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;

// 此方法可以计算2个位置(CLLocation)之间的距离
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location


CLLocationCoordinate2D

CLLocationCoordinate2D是一个用来表示经纬度的结构体,定义如下
typedef struct {
    CLLocationDegrees latitude; // 纬度
    CLLocationDegrees longitude; // 经度
} CLLocationCoordinate2D;

一般用CLLocationCoordinate2DMake函数来创建CLLocationCoordinate2D

模拟位置

如果是模拟器,需要设置模拟位置(经纬度)
北京的经纬度是:北纬40°,东经116°
大连的经纬度是:北纬39°,东经121°
郑州的经纬度是:北纬34°,东经113°
上海的经纬度是:北纬31°,东经121°
广州的经纬度是:北纬23°,东经113°
西安的经纬度是:北纬34°,东经108°



地理编码与地理反编码

使用CLGeocoder可以完成"地理编码"和"反地理编码"
地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
反地理编码:根据给定的经纬度,获得具体的位置信息

// 地理编码方法
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

// 反地理编码方法
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

CLGeocodeCompletionHandler

当地理编码/反地理编码完成时,就会调用CLGeocodeCompletionHandler
typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);

block包含2个参数
error:当编码出错时(比如编码不出具体的信息),2其错误信息会包含在error中
placemarks:里面装着CLPlacemark对象


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;

总结

CLLocationManager 定位的基础信息
CLLocation  某个位置的地理信息
CLLocationCoordinate2D  存放经纬度的结构体
CLGeocoder 地理位置编码与反编码的类
CLPlacemark 地标.

三、地图显示

MapKit框架的使用

导入主头文件
       #import <MapKit/MapKit.h>
MapKit框架使用须知
  MapKit框架中所有数据类型的前缀都是MK
       MapKit有一个比较重要的UI控件:MKMapView,专门用于地图显示

跟踪显示用户的位置

设置MKMapView的userTrackingMode属性可以跟踪显示用户的当前位置    
    MKUserTrackingModeNone :不跟踪用户的位置
    MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
    MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转

下图是跟踪效果
    蓝色发光圆点就是用户的当前位置
    蓝色发光圆点,专业术语叫做“大头针”


地图的类型

可以通过设置MKMapView的mapType设置地图类型(mapViewType是枚举类型)
MKMapTypeStandard // 普通地图
MKMapTypeSatellite // 卫星云图
MKMapTypeHybrid // 普通地图覆盖于卫星云图之上
MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0) // 地形和建筑物的三维模型
MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0) // 显示道路和附加元素的Flyover

   

MKMapView的代理

MKMapView可以设置一个代理对象,用来监听地图的相关行为,常见的代理方法有:

// 一个位置更改默认只会调用一次,不断监测用户的当前位置时每次都会调用这个方法,把用户的最新位置(userLocation参数)传进来.

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

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

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


MKUserLocation

MKUserLocation其实是个大头针模型,包括以下属性
// 显示在大头针上的标题
@property (nonatomic, copy) NSString *title;

// 显示在大头针上的子标题
@property (nonatomic, copy) NSString *subtitle;

// 地理位置信息(大头针钉在什么地方)
@property (readonly, nonatomic) CLLocation *location;


设置地图的显示

通过MKMapView的下列方法,可以设置地图显示的位置和区域
// 设置地图的中心点位置
@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;


大头针模型

新建一个大头针模型类
#import <MapKit/MapKit.h>
@interface MyAnnonation : NSObject <MKAnnotation>
/** 坐标位置 */
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
/** 标题 */
@property (nonatomic, copy) NSString *title;
/** 子标题 */
@property (nonatomic, copy) NSString *subtitle;
@end

添加大头针

// 初始化大头针对象
MyAnnonation *anno = [[MyAnnonation alloc] init];


// 设置大头针的标题和子标题以及经纬度
anno.title = @"111111111";
anno.subtitle = @"2222222";
anno.coordinate = CLLocationCoordinate2DMake(40, 116);
[self.mapView addAnnotation:anno];


大头针的基本操作

// 添加一个大头针
- (void)addAnnotation:(id <MKAnnotation>)annotation;


// 添加多个大头针
- (void)addAnnotations:(NSArray *)annotations;

// 移除一个大头针
- (void)removeAnnotation:(id <MKAnnotation>)annotation;

// 移除多个大头针
- (void)removeAnnotations:(NSArray *)annotations;


四、自定义大头针

很多情况下,需要自定义大头针的显示样式,比如显示一张图片

设置MKMapView的代理
实现下面的代理方法,返回大头针控件

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
根据传进来的(id <MKAnnotation>)annotation参数创建并返回对应的大头针控件

代理方法的使用注意
如果返回nil,显示出来的大头针就采取系统的默认样式

标识用户位置的蓝色发光圆点,它也是一个大头针,当显示这个大头针时,也会调用代理方法

因此,需要在代理方法中分清楚(id <MKAnnotation>)annotation参数代表自定义的大头针还是蓝色发光圆点

MKAnnotationView

地图上的大头针控件是MKAnnotationView

MKAnnotationView的属性

// 大头针模型
@property (nonatomic, strong) id <MKAnnotation> annotation;

// 显示的图片
@property (nonatomic, strong) UIImage *image;

// 是否显示标注
@property (nonatomic) BOOL canShowCallout;

// 标注的偏移量
@property (nonatomic) CGPoint calloutOffset;

// 标注右边显示什么控件
@property (strong, nonatomic) UIView *rightCalloutAccessoryView;

// 标注左边显示什么控件
@property (strong, nonatomic) UIView *leftCalloutAccessoryView;

MKPinAnnotationView

MKPinAnnotationView是MKAnnotationView的子类

MKPinAnnotationView比MKAnnotationView多了2个属性

// 大头针颜色
@property (nonatomic) MKPinAnnotationColor pinColor;

// 大头针第一次显示时是否从天而降
@property (nonatomic) BOOL animatesDrop;

CLLocationManager 定位的基础信息
CLLocation  位置的地理信息
CLLocationCoordinate2D  存放经纬度的结构体
CLGeocoder地理位置编码与反编码的类
CLPlacemark 地标.
MKMapView 基础地图
MKUserLocation  大头针模型
MKCoordinateRegion  显示区域的结构体
MKAnnotationView 自定义大头针控件









0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:11885次
    • 积分:330
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:4篇
    • 译文:0篇
    • 评论:3条
    文章分类
    最新评论