定位

要实现地图、导航功能,往往需要先熟悉定位功能,在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

NSLocationWhenInUseUsageDescription

requestAlwaysAuthorization

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

走出某个区域之后执行

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

注意:

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

-(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

渲染地图覆盖物时触发



设置大头针视图

- (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则会使用默认大头针视图,需要根据情况设置。


使用自带的地图应用

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。