iOS陆哥开发笔记(五) (地图定位之官方API)

定位

要实现地图、导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位操作。Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图开发要配合定位框架使用。在Core Location中主要包含了定位、地理编码(包括反编码)功能。

定位功能

定位是一个很常用的功能,如一些地图软件打开之后如果用户允许软件定位的话,那么打开软件后就会自动锁定到当前位置,如果用户手机移动那么当前位置也会跟随着变化。要实现这个功能需要使用Core Loaction中CLLocationManager类,首先看一下这个类的一些主要方法和属性:

类方法 说明
+ (BOOL)locationServicesEnabled; 是否启用定位服务,通常如果用户没有启用定位服务可以提示用户打开定位服务
+ (CLAuthorizationStatus)authorizationStatus; 定位服务授权状态,返回枚举类型:

kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务

kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权

kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态

kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态

kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务

属性 说明
desiredAccuracy 定位精度,枚举类型:

kCLLocationAccuracyBest:最精确定位

CLLocationAccuracy kCLLocationAccuracyNearestTenMeters:十米误差范围

kCLLocationAccuracyHundredMeters:百米误差范围

kCLLocationAccuracyKilometer:千米误差范围

kCLLocationAccuracyThreeKilometers:三千米误差范围

distanceFilter 位置信息更新最小距离,只有移动大于这个距离才更新位置信息,默认为kCLDistanceFilterNone:不进行距离限制
对象方法 说明
startUpdatingLocation 开始定位追踪,开始定位后将按照用户设置的更新频率执行-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;方法反馈定位信息
stopUpdatingLocation 停止定位追踪
startUpdatingHeading 开始导航方向追踪
stopUpdatingHeading 停止导航方向追踪
startMonitoringForRegion: 开始对某个区域进行定位追踪,开始对某个区域进行定位后。如果用户进入或者走出某个区域会调用- (void)locationManager:(CLLocationManager *)manager

didEnterRegion:(CLRegion *)region和- (void)locationManager:(CLLocationManager *)manager

didExitRegion:(CLRegion *)region代理方法反馈相关信息

stopMonitoringForRegion: 停止对某个区域进行定位追踪
requestWhenInUseAuthorization 请求获得应用使用时的定位服务授权,注意使用此方法前在要在info.plist中配置NSLocationWhenInUseUsageDescription
requestAlwaysAuthorization 请求获得应用一直使用定位服务授权,注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription
代理方法 说明
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; 位置发生改变后执行(第一次定位到某个位置之后也会执行)
- (void)locationManager:(CLLocationManager *)manager

didUpdateHeading:(CLHeading *)newHeading;

导航方向发生变化后执行
  - (void)locationManager:(CLLocationManager *)manager

didEnterRegion:(CLRegion *)region

进入某个区域之后执行
- (void)locationManager:(CLLocationManager *)manager

didExitRegion:(CLRegion *)region

走出某个区域之后执行

iOS 8 还提供了更加人性化的定位服务选项。App 的定位服务不再仅仅是关闭或打开,现在,定位服务的启用提供了三个选项,「永不」「使用应用程序期间」和「始终」。同时,考虑到能耗问题,如果一款 App 要求始终能在后台开启定位服务,iOS 8 不仅会在首次打开 App 时主动向你询问,还会在日常使用中弹窗提醒你该 App 一直在后台使用定位服务,并询问你是否继续允许。在iOS7及以前的版本,如果在应用程序中使用定位服务只要在程序中调用startUpdatingLocation方法应用就会询问用户是否允许此应用是否允许使用定位服务,同时在提示过程中可以通过在info.plist中配置通过配置Privacy
- Location Usage Description告诉用户使用的目的,同时这个配置是可选的。

但是在iOS8中配置配置项发生了变化,可以通过配置NSLocationAlwaysUsageDescription或者NSLocationWhenInUseUsageDescription来告诉用户使用定位服务的目的,并且注意这个配置是必须的,如果不进行配置则默认情况下应用无法使用定位服务,打开应用不会给出打开定位服务的提示,除非安装后自己设置此应用的定位服务。同时,在应用程序中需要根据配置对requestAlwaysAuthorization或locationServicesEnabled方法进行请求。由于本人机器已经更新到最新的iOS8.1下面的内容主要针对iOS8,使用iOS7的朋友需要稍作调整。

注意:

1.定位频率和定位精度并不应当越精确越好,需要视实际情况而定,因为越精确越耗性能,也就越费电。

2.定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法,这个方法返回一组地理位置对象数组,每个元素一个CLLocation代表地理位置信息(包含经度、纬度、海报、行走速度等信息),之所以返回数组是因为有些时候一个位置点可能包含多个位置。

3.使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源。

4.除了提供定位功能,CLLocationManager还可以调用startMonitoringForRegion:方法对指定区域进行监控。

在iOS中进行地图开发主要有两种方式,一种是直接利用MapKit框架进行地图开发,利用这种方式可以对地图进行精准的控制;另一种方式是直接调用苹果官方自带的地图应用,主要用于一些简单的地图应用(例如:进行导航覆盖物填充等),无法进行精确的控制。当然,本节重点内容还是前者,后面的内容也会稍加提示。

用MapKit之前需要简单了解一下MapKit中地图展示控件MKMapView的的一些常用属性和方法,具体如下表:

属性 说明
userTrackingMode 跟踪类型,是一个枚举:

MKUserTrackingModeNone :不进行用户位置跟踪;

MKUserTrackingModeFollow :跟踪用户位置;

MKUserTrackingModeFollowWithHeading :跟踪用户位置并且跟踪用户前进方向;

mapType 地图类型,是一个枚举:

MKMapTypeStandard :标准地图,一般情况下使用此地图即可满足;

MKMapTypeSatellite :卫星地图;

MKMapTypeHybrid :混合地图,加载最慢比较消耗资源;

userLocation 用户位置,只读属性
annotations 当前地图中的所有大头针,只读属性
对象方法 说明
- (void)addAnnotation:(id <MKAnnotation>)annotation; 添加大头针,对应的有添加大头针数组
- (void)removeAnnotation:(id <MKAnnotation>)annotation; 删除大头针,对应的有删除大头针数组

- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

设置地图显示区域,用于控制当前屏幕显示地图范围
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated; 设置地图中心点位置
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view; 将地理坐标(经纬度)转化为数学坐标(UIKit坐标)
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view; 将数学坐标转换为地理坐标
- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier; 从缓存池中取出大头针,类似于UITableView中取出UITableViewCell,为了进行性能优化而设计
- (void)selectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated; 选中指定的大头针
- (void)deselectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated; 取消选中指定的大头针
代理方法 说明
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 用户位置发生改变时触发(第一次定位到用户位置也会触发该方法)
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 显示区域发生改变后触发
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView; 地图加载完成后触发
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation; 显示大头针时触发,返回大头针视图,通常自定义大头针可以通过此方法进行
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 点击选中某个大头针时触发
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view 取消选中大头针时触发
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay 渲染地图覆盖物时触发

设置大头针视图

在一些应用中系统默认的大头针样式可能无法满足实际的需求,此时就需要修改大头针视图默认样式。根据前面MapKit的代理方法不难发现- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;方法可以返回一个大头针视图,只要实现这个方法并在这个方法中定义一个大头针视图MKAnnotationView对象并设置相关属性就可以改变默认大头针的样式。MKAnnotationView常用属性:

属性 说明
annotation 大头针模型信息,包括标题、子标题、地理位置。
image 大头针图片
canShowCallout 点击大头针是否显示标题、子标题内容等,注意如果在- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;方法中重新定义大头针默认情况是无法交互的需要设置为true。
calloutOffset 点击大头针时弹出详情信息视图的偏移量
selected 是否被选中状态
leftCalloutAccessoryView 弹出详情左侧视图
rightCalloutAccessoryView 弹出详情右侧视图

需要注意:

a.这个代理方法的调用时机:每当有大头针显示到系统可视界面中时就会调用此方法返回一个大头针视图放到界面中,同时当前系统位置标注(也就是地图中蓝色的位置点)也是一个大头针,也会调用此方法,因此处理大头针视图时需要区别对待。

b.类似于UITableView的代理方法,此方法调用频繁,开发过程中需要重复利用MapKit的缓存池将大头针视图缓存起来重复利用。

c.自定义大头针默认情况下不允许交互,如果交互需要设置canShowCallout=true

d.如果代理方法返回nil则会使用默认大头针视图,需要根据情况设置。

使用自带的地图应用

除了可以使用MapKit框架进行地图开发,对地图有精确的控制和自定义之外,如果对于应用没有特殊要求的话选用苹果自带的地图应用也是一个不错的选择。使用苹果自带的应用时需要用到MapKit中的MKMapItem类,这个类有一个openInMapsWithLaunchOptions:动态方法和一个openMapsWithItems: launchOptions:静态方法用于打开苹果地图应用。第一个方法用于在地图上标注一个位置,第二个方法除了可以标注多个位置外还可以进行多个位置之间的驾驶导航,使用起来也是相当方便。在熟悉这两个方法使用之前有必要对两个方法中的options参数做一下简单说明:

键(常量) 说明
MKLaunchOptionsDirectionsModeKey 路线模式,常量 MKLaunchOptionsDirectionsModeDriving  驾车模式

MKLaunchOptionsDirectionsModeWalking 步行模式

MKLaunchOptionsMapTypeKey 地图类型,枚举 MKMapTypeStandard :标准模式

MKMapTypeSatellite :卫星模式

MKMapTypeHybrid  :混合模式

MKLaunchOptionsMapCenterKey 中心点坐标,CLLocationCoordinate2D类型  
MKLaunchOptionsMapSpanKey 地图显示跨度,MKCoordinateSpan 类型  
MKLaunchOptionsShowsTrafficKey 是否 显示交通状况,布尔型  
MKLaunchOptionsCameraKey 3D地图效果,MKMapCamera类型

注意:此属性从iOS7及以后可用,前面的属性从iOS6开始可用

 

有些初学者容易混淆,下面简单对比一下。

CLLocation:用于表示位置信息,包含地理坐标、海拔等信息,包含在CoreLoaction框架中。

MKUserLocation:一个特殊的大头针,表示用户当前位置。

CLPlacemark:定位框架中地标类,封装了详细的地理信息。

MKPlacemark:类似于CLPlacemark,只是它在MapKit框架中,可以根据CLPlacemark创建MKPlacemark。

时间: 2024-10-11 14:00:32

iOS陆哥开发笔记(五) (地图定位之官方API)的相关文章

iOS陆哥开发笔记(七) (AVFoundation简单介绍)

在AVFoundation框架中AVAudioRecorder类专门处理录音操作,支持多种音频格式. 以下是经常使用的属性和方法: 属性 说明 @property(readonly, getter=isPlaying) BOOL playing 是否正在播放,仅仅读 @property(readonly) NSUInteger numberOfChannels 音频声道数,仅仅读 @property(readonly) NSTimeInterval duration 音频时长 @property

iOS陆哥开发笔记(七) (AVFoundation简介)

在AVFoundation框架中AVAudioRecorder类专门处理录音操作,支持多种音频格式.下面是常用的属性和方法: 属性 说明 @property(readonly, getter=isPlaying) BOOL playing 是否正在播放,只读 @property(readonly) NSUInteger numberOfChannels 音频声道数,只读 @property(readonly) NSTimeInterval duration 音频时长 @property(read

iOS陆哥开发笔记(八) (GCD死锁及解决方案)

GCD导致死锁的原因和解决方案 所谓死锁,通常指有两个线程A和B都卡住了,并等待对方完成某些操作.A不能完成是因为它在等待B完成.但B也不能完成,因为它在等待A完成.于是大家都完不成,就导致了死锁(DeadLock). 在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue.然而,存在于两种Dispatch Queue,一种是要等待上一个执行完,再执行下一个的Serial Dispatch Queue,这叫做串行队列

斯坦福大学公开课:iOS 7应用开发 笔记

2015-07-06 第一讲   课务.iOS概述 -------------------------------------------------- 开始学习斯坦福大学公开课:iOS 7应用开发留下笔记

Android开发实现高德地图定位

一. 要实现高德地图定位呢,首先需要做好以下几步准备: 1. 在高德开放平台注册帐号 注册地址:http://lbs.amap.com 2. 在开发中下载Android平台下的 地图SDK和定位SDK文件 进入相关下载下载自己想要的功能或文件,图只是截取了地图SDK的页面,定位SDK也是一样,按自己想要的文件下载.下载完成后解压得到: - 3D地图包解压后得到:3D地图显示包"AMap_3DMap_VX.X.X_时间.jar"和库文件夹(包含armeabi.arm64-v8a等库文件)

PHP微信公众开发笔记(五)

PHP微信公众开发笔记系列 日期:2014.9.3 今天做了身份验证的功能,然后完善了下搜索功能.其实主要的是将整个代码结构整理了一番,应该可以说是模块化设计吧. 模块化设计我们的公众号. 因为我们之前提的功能需求中有: 1.菜单--查询功能.我考虑到后期功能的扩展,就想将这些分模块来实现:菜单模块(这样,今后我们需要添加新的菜单功能,可以直接在这个模块里操作,这样修正和维护也简单,在考虑到后期可能会分工协作的时候各开发者之间不会产生冲突): 2.数据库模块(这里就主要是负责数据库相关的工作,如

Android学习个人笔记-百度地图定位sdk的使用

虽然自己已经完成了百度地图的调用,但是在使用过程中产生很多的疑问,在不断的百度各种大神的作品后才慢慢的调试出来,所以觉得作为新手自己应该把这个过程记录下来.尤其是自己在找到大神的文章时,并不能理解有些单纯一个方法和一个解释,主要还是水平有限,在查资料的过程中也深知写好一篇博文对于需要的人来说就是一汪泉水,欣喜的发现这篇博文讲的有头由尾,可以参照一步一步的来进行.记录下来这个过程对于自己也是一种复习,比如当初费尽心思解决的难题再一年后再去看代码却毫无头绪,所以这样的记录还是很有必要的,自己也尽力的

leaflet-webpack 入门开发系列五地图卷帘(附源码下载)

前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 webpack 配置介绍文档详细的 webpack 文档配置介绍,适合新手查看,我也是边看边学 vscode 安装包下载,我这边用 vscode工具编译开发前端项目,个人觉的这款工具还不错 leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 l

android studio开发笔记五

1.activity:一个应用程序组件,提供用户与程序交互的界面2.android四大组件:--activity --service --BroadcastReceiver --Content Provider3.如何创建使用activity(1)继承android的acivity的类(2)重写方法(3)设置显示布局(4)在androidmanifest文件中,注册activity4.activity的生命周期:创建--->销毁onCreate()创建 onStart()运行 onResume(