iOS-----使用CoreLocation定位
使用CoreLocation定位
CoreLocation框架 (CoreLocation.framework)可用于定位设备当前经纬度, 通过该框架, 应用程序可通过附近的蜂窝基站\WIFI信号
或者GPS等信息计算用户位置.
iOS SDK提供了CLLocationManager、CLLocationManagerDelegate来处理设备的定位信息,包括获取设备的方向以及进行方向检测等。
其中CLLocationManager是整个CoreLocation框架的核心,定位、方向检测、区域检测等都由该API完成;而CLLocationManagerDelegate是
一个协议,实现该协议的对象可作为CLLocationManager的delegate对象,负责处理CLLocationManager的定位、方向检测、区域检测等相关事
件。iOS还提供了CLLocation (代表位置信息)、CLHeading(代表设备方向)、CIRegion(代表区域)等API,这些API与CLLocationManager、CLLocationManagerDelegate共同组成了iOS的CoreLocation框架.
iOS的定位支持
GPS卫星定位
GPS是英文Global Positing System (全球定位系统) 的简称,由GPS卫星组成的空间部分、若干地面站组成的控制部分和普通用
户手中的接收机这3个部分。
iOS的GPS定位于单纯的GPS定位不同,它是A-GPS(所谓辅助GPS),首先通过基站定位或WiFi定位获得该设备的大概位置,然
后通过将设备的大致位置发发哦远程服务器,由服务器负责进行查询和计算,从而获取当前位置的卫星信息,并通过网络将这些卫星
信息反馈给iOS设备,避免了iOS设备直接通过GPS扫面、分析天上的卫星信息。
基站定位
每个手机基站都是一个标识符,iOS设备可以搜集周围所有收到信号的基站和它们的标识符,通过联网发送到苹果云端服务器,再由
服务器根据这些基站的位置信息查询并计算出当前位置,然后把该定位信息返回给手机。
WiFi定位
iOS设备通过无线网卡搜集周围所有的WiFi热点,获得它们的MAC地址,然后通过Apple的云端服务器查询该WiFi热点是否已经登记,
如果已经登记,即可获取该WiFi热点的位置,最后通过对多个WiFi热点折中计算得到当前位置并返回给iOS设备。精确度大概在几十米范围内。
获取定位信息
CoreLocation.framework的常用API主要有如下几个。 |
|
CLLocationManager |
定位管理类 |
CLLocationManagerDelegate |
该协议代表定位管理器的delegate协议.实现协议的对象可负责处理CLLocationManager的定位事件 |
CLLocation |
该对象代表位置。该对象包含了当前设备的经度、纬度、高度、速度、路线等信息,还包含了该定位信息的水平精确度、垂直精确度以及时间戳信息。 |
CLHeading |
该对象代表设备的移动方向。 |
CLRegion |
该对象代表一个区域。一般程序不会直接使用该类,而是使用它的两个子类,即CLCircularRegion (圆形区域)和CLBeaconRegion (蓝牙信号区)。 |
CLLocationCoordinate2D |
该结构体变量包含经度、纬度两个值。其中CLLocation对象的coordinate属性就是一个CLLocationCoordinate2D结构体变量。 |
获取位置信息
使用CoreLocation..framework进行定位只要如下3步即可 |
|
CLLocationManager负责获取定位信息,delegate则负责处理定位事件--------通过这些事件即可获取设备所在位置。 |
CLLocationManager还提供了如下类方法来判断当前设备的定位相关服务状态。 |
+ locationServicesEnabled:返回当前定位服务是否可用 |
+ deferredLocationUpdatesAvailable:返回延迟定位更新是否可用 |
+ significantLocationChangeMonitoringAvailable:返回重大位置改变监听是否可用。 |
+ headingAvailable:返回该设备是否支持磁力计计算方向。 |
+ isRangingAvailable:返回蓝牙信号范围服务是否可用。 |
CLLocationManager该对象设置如下属性 |
pausesLocationUpdatesAutomatically:设置iOS设备是否可暂停定位来节省电池的电量。如果该属性设为“ YES ”,则当iOS设备不再需要定位数据时,iOS设备可以自动暂停定位 |
distanceFilter: 设置CLLocationManager的自动过滤距离。也就是说,只有当设备在水平方向的位置改变超过该数值(以米为单位)指定的距离时才会生成一次位置改变的信号。 |
desiredAccuracy:设置定位服务的精度。该属性值支持kCLLocationAccuracyBestForNavigation (导航级的最佳精确度)、kCLLocationAccuracyBest(最佳精确度)、kCLLocationAccuracyNearestTenMeters(10米误差)、kCLLocationAccuracyHundredMeters(百米误差)、kCLLocationAccuracyKilometer(千米误差)、kCLLocationAccuracyThreeKilometers(三千米误差)等常量值。当然,也可直接指定一个浮点数作为定位服务允许的误差。 |
activityType:设置定位数据的用途。该属性支持CLActivityTypeOther(定位数据作为普通用途)、CLActivityTypeAutomotiveNavigation(定位数据作为车辆导航使用)、CLActivityTypeFitness(定位数据作为步行导航使用)和CLActivityTypeOtherNavigation(定位数据作为其他导航使用)这几个枚举值之一。 |
代 码 片 段 |
ViewController.m @interface ViewController () <CLLocationManagerDelegate> @property (strong, nonatomic)CLLocationManager* locationManager; @end @implementation ViewController - (void) viewDidLoad { [super viewDidLoad]; // 创建CLLocationManager对象 self.locationManager = [[CLLocationManager alloc] init]; } - (IBAction)bnTapped: (id)sender { // 如果定位服务可用 if([CLLocationManager locationServiceEnabled]) { NSLog(@” 开始执行定位服务 ”); // 设置定位精度: 最佳精度 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置距离过滤器为50米,表示每移动50米更新一次位置 self.locationManager.distanceFilter = ; // 将视图控制器自身设置为CLLocationManager的delegate // 因此该视图控制器需要实现CLLocationManagerDelegate协议 self.locationManager.delegate = self; // 开始监听定位信息 [self.locationManager startUpdatingLocation]; } else { NSLog(@” 无法使用定位服务! ”); } } // 成功获取定位数据后将会激发该方法 - (void)locationManager: (CLLocationManager*)manager didUpdateLocations: (NSArray*)locations { // 获取最后一个定位数据 CLLocation* location = [location lastObject]; // 依次获取CLLocation中封装的经度、纬度、高度、速度、方向等信息 self.longitudeTxt.text = [NSString stringWithFormat: @”%g”, location.Coordinate.longitude]; // 经度 self.latitudeTxt.text = [NSString stringWithFormat: @”%g”, location.Coordinate.latitude]; // 纬度 self.altitudeTxt.text = [NSString stringWithFormat: @”%g”, location.altitude]; // 高度 self.speedTxt.text = [NSString stringWithFormat: @”%g”, location.speed]; // 速度 self.courseTxt.text = [NSString stringWithFormat: @”%g”, location.course]; // 速度 } // 定位失败时激发的方法 - (void)locationManager: (CLLocationManager*)manager didFailWithError: (NSError*)error { NSLog(@”定位失败: %@”, error); } @end |
上面程序中的第1段红色字代码为CLLocationManager对象设置了属性之后,关键是将该视 控制器设置为CLLocationManager的delegate,程序调用CLLocationManager的 startUpdatingLocation方法开始获取定位数据. 由于程序指定该视图控制器作为CLLocationManager的delegate, 因此该视图控制器需要实现CLLocationManagerDelegate协议, 并实现该协议中定位相关的两个事件处理方法。当程序成功获取定位数据时,将会激发delegate的locationManager:didUpdateLocation: 方法,因此上面视图控制器类实现了该方法,并在该方法中获取最后一个定位数据:CLLocation对象。 |
CLLocation对象中包含如下属性,这些属性包含了定位相关信息 |
altitude:该属性表示当前设备的海拔高度,单位是米。 |
coordinate:该属性返回一个CLLocationCoordinate2D结构体变量,该结构体变量中包含经度、纬度信息。 course:该属性表示当钱设备前进的方向。该值为0°表示向北,90°表示向东,180°表示向南,270°表示向西。 horizontalAccuracy:该属性表明定位信息的水平精确度。将返回的坐标作为圆心,并将水平精确度视为半径。真正的设备位置落在此圆内的某处。此圆越小,位置就越精确:此圆越大,则位置越不精确。如果精确度为负值,则表明测量精确度失败。 verticalAccuracy:该属性表明定位信息的垂直精确度。也就是说,iOS设备的实际高度在该定位信息的高度加或减该属性值的范围内. |
timestamp:该属性返回定位信息的返回时间. |
speed:该属性返回设备的移动速度,单位是米/秒.实际上,该属性适用于行车速度,而不太适用于步行速度。 |
使用iOS模拟器模拟位置
iOS模拟器本身并不能作为GPS接收机,因此无法得到定位信息,但为了方便程序员测试定位应用,iOS模拟器可以模拟定位信息。
启动iOS模拟器之后,即可通过iOS模拟器主菜单中的“调试”→”位置”来模拟iOS设备的位置
自定位置:可以自行输入位置的经度值、纬度值 |
City Bicycle Ride:模拟设备携带者在城市中骑车移动 |
City Run:模拟设备携带者在城市中跑动。 |
Freeway Drive:模拟设备携带者在高速公路中驾车 |
监控行车速度和行车距离
通过一个示例来计算设备的平均移动速度 下面是实现部分代码 |
ViewController.m #import “ViewController.h” #import <CoreLocation/CoreLocation.h> @interface ViewController()<CLLocationManagerDelegate> @property (nonatomic, retain) CLLocationManager* locationManager; @property (nonatomic, retain) CLLocation* prevLocation; @property (nonatomic, assign) CGFloat sumDistance; @property (nonatomic, assign) CGFloat sumTime; @end @implementation ViewController - (void) viewDidLoad { [super viewDidLoad]; // 创建CLLocationManager对象 self.locationManager = [[CLLocationManager alloc] init]; } - (void)viewWillAppear: (BOOL)animated { [super viewWillAppear: animated]; // 设置定位精度:最佳精度 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置距离过滤器为50米,表示每移动50米更新一次位置 self.locationManager.distanceFilter = ; // 将视图控制器自身设置为CLLocationManager的delegate // 因此该视图控制器需要实现CLLocationManagerDelegate协议 self.locationManager.delegate = self; // 开始监听定位信息 [self.locationManager startUpdatingLocation]; NSLog(@” 开始执行定位服务 ”); } // 定位失败时激发的方法 - (void)locationManager: (CLLocationManager*)manager didFailWithError: (NSError*) error { NSLog(@”定位失败: %@”, error); } // 成功获取定位数据后将会激发该方法 - (void)locationManager: (CLLocationManager*) manager didUpdateLocations: (NSArray*)locations { // 获取最后一个定位数据 CLLocation* newLocation = [location lastObject]; if(newLocation,horizontalAccuracy < kCLLocationAccuracyHundredMeters) |
上面程序中的两行红色字代码分贝用于计算本次定位数据与上次定位数据之间的时间差、距离,用此距离除以时间,即可得到该设备的当前速度。该程序还定义了一个sumDistance 属性来保存设备移动的总距离,并定义一个sumTime来保存设备移动的总时间,用设备移动的总距离除以设备移动的总时间,即可获取该设备移动的平均速度。 |
方向监测
iOS系统通过heading属性来获取设备的真实方向。需要指出的是,并不是所有的iOS设备都支持heading属性,因此程序获取
方向之前需要先测试该设备是否支持heading。如果定位管理器支持heading属性,那么CLLocationManager的headingAvailable属性
将会返回“YES”。
使用CLLocationManager获取设备方向与获取移动距离的步骤基本相似,只是此时不是检测位置移动,而是检测方向改变。
使用CLLocationManager获取设备方向的步骤如下: |
1.创建CLLocationManager对象,该对象负责获取定位相关信息。并为该对象设置一些必要的属性。 |
2.为CLLocationManager指定delegate属性,该属性值必须是一个实现CLLocationManagerDelegate协议的对象。实现CLLocationManagerDelegate协议时可根据需要实现协议中特定的方法。 |
3.调用CLLocationManager的startUpdatingHeading方法获取方向信息。获取方向结束时,可调用stopUpdatingHeading方法结束获取方向信息。 |
当设备的方向改变时,iOS系统将会自动激发CLLocationManager的delegate对象的locationManager:didUpdateHeading:方法,而程序可通过重写该方法来获取设备方向。 |
iOS允许为检测方向改变设置如下属性。 |
CLLocationDegrees headingFilter:设置只有当设备方向的改变值超过该属性值时才激发delegate的方法。 |
CLDeviceOrientation headingOrientation:设置设备当前方向。 |
监听方向时返回的是一个CLHeading对象,该对象包含如下属性。 |
magneticHeading:该属性返回设备与磁北的相对方向。 |
trueHeading:该属性返回值设备与真北的相对方向。 真北始终指向地理北极点;磁北则对应于随时间变化的地球磁场北极。iOS系统使用一个计算后的偏移量(称为偏差)来确定这两者之间的差异。 |
headingAccuracy:该属性返回方向值的误差范围。 |
timestamp:该属性返回方向值的生成时间。 |
x:获取该设备在x方向上监听得到的原始磁力值,该磁力值的强度单位是微特斯拉 |
y: 获取该设备在Y方向上监听得到的原始磁力值,该磁力值的强度单位是微特斯拉。 |
z:获取该设备在Z方向上监听得到的原始磁力值,该磁力值的强度单位是微特斯拉。 |
代码片段:指南针 |
ViewController.m @interface ViewController () <CLLocationManagerDelegate> |
上面程序中的前两行红色字代码用于为CLLocationManager设置delegate属性,接下来程序调用该对象的startUpdatingHeading方法开始监听设备的方向改变-------当设备的方向改变时,系统会自动激发CLLocationManager设置delegate的locationManager:didUpdateHeading:方法,程序的视图控制器重写了该方法,并在该方法中获取设备方向,然后将图片“反转”相应的角度,从而让图片的北极总是指向真实的北极。 |
区域监测
如果希望iOS设备进入某个区域发出通知,那么这种区域检测的工能被称为临近警告。
用户设备不断地临近指定固定点,当与该固定点的距离小于指定范围时,系统可以触发相应的处理。用户设备离开指定固定点,
当与该固定点的距离大于指定范围时,系统也可以触发相应的处理。
iOS的区域监测同样可以使用CLLocationManager来实现,监听设备是否进入、离开某个区域的步骤如下。 |
|
当设备进入指定区域时,iOS系统将会自动激发CLLocationManager的delegate对象的locationManager:didEnterRegion:方法;当设备离开指定区域时,iOS系统将会自动激发CLLocationManager的delegate对象的locationManager:didExitRegion:方法,重写这两个方法对用户进行提醒。 |
iOS提供了CLRegion来定义被 监测的区域,但实际编程中推荐使用CLCircularRegion(CLRegion的子类)创建圆形区域,创建CLCircularRegion对象时无非就是指定圆心、半径等信息,非常简单。 |
代 码 片 段 |
ViewController.m |
正如上面程序中的红色字代码所看到的,第1行红色字代码创建了一个CLRegion对象作为被监测区域,接下来调用CLLocationManager的startMonitoringForRegion:方法监听该设备是否进入/离开指定区域。 当设备进入或离开中区域时,iOS系统都会自动激发CLLocationManager的delegate对象的相应方法,上面程序重写了这两个方法对用户进行提醒。 |
iOS-----使用CoreLocation定位的更多相关文章
- iOS开发拓展篇—CoreLocation定位服务
iOS开发拓展篇—CoreLocation定位服务 一.简单说明 1.CLLocationManager CLLocationManager的常用操作和属性 开始用户定位- (void)startUp ...
- iOS - CoreLocation 定位
前言 NS_CLASS_AVAILABLE(10_6, 2_0) @interface CLLocationManager : NSObject 1.CoreLocation 定位 配置 1.在 iO ...
- Ios开发之定位CLLocationManager
Ios中的定位功能是通过 Core Location框架实现的.它和地图开发框架是相互独立的.在Core Location中主要实现了定位和地理编码的功能! 下面我们就来介绍一下它的属性,方法和代理方 ...
- iOS8中使用CoreLocation定位[转]
本文转自:http://blog.devzeng.com/blog/ios8-corelocation-framework.html iOS8以前使用CoreLocation定位 1.首先定义一个全局 ...
- iOS 后台持续定位详解(支持ISO9.0以上)
iOS 后台持续定位详解(支持ISO9.0以上) #import <CoreLocation/CoreLocation.h>并实现CLLocationManagerDelegate 代理, ...
- iOS 开发 申请定位
在iOS8以后,苹果已经强制开发者在请求定位服务时获得用户的授权,此外iOS状态栏中还有指示图标,提示用户当前应用是否正在使用定位服务.另外在iOS8以后,苹果进一步改善了定位服务,让开发者请求定位服 ...
- XamarinSQLite教程在Xamarin.iOS项目中定位数据库文件
XamarinSQLite教程在Xamarin.iOS项目中定位数据库文件 开发者可以在指定的路径中找到复制的数据库文件,具体的操作步骤如下: (1)单击Mac电脑中Finder菜单中的“前往”|“前 ...
- ios 底部用定位 fixed。在软件盘出来后,页面元素被顶上去一部分,fixed定位的footer也跑到了上面去。解决方法
ios 底部用定位 fixed.在软件盘出来后,页面元素被顶上去一部分,fixed定位的footer也跑到了上面去.解决方法 $("input").focus(function() ...
- iOS iOS9.0 的CoreLocation定位
一.简介 iOS9.0如果当前处于前台授权状态,默认是不可以后台获取用户位置. 如果在前台授权下,让其能获取到后台定位,该怎么办 可以设置以下属性为YES,就可以继续获取后台位置,但是会出现蓝条 使用 ...
随机推荐
- python 多线程队列
##Using Queue with multiprocessing – Chapter : Process Based Parallelism import multiprocessing impo ...
- jenkins定时构建示例
项目:使用git+jenkins实现持续集成 开始构建 General 源码管理 我们安装的是git插件,还可以安装svn插件 我们将git路径存在这里还需要权限认证,否则会出现error 我们添加一 ...
- python 获取本地语言和编码的代码
#! /usr/bin/env python # encoding=utf8 import locale language, encoding = locale.getdefaultlocale() ...
- pyHook监听用户鼠标、键盘事件
一.代码部分:获取用户输入信息,并与截图一起保存到XX目录下 # -*- coding: utf-8 -*- # import pythoncom import pyHook impor ...
- 《剑指offer》第七题(重要!重建二叉树)
文件一:main.cpp // 面试题:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历 ...
- JSON和JS对象之间的互转【转】
1. jQuery插件支持的转换方式 $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 2. 浏览器支持的 ...
- Mac下使用源码编译安装TensorFlow CPU版本
1.安装必要的软件 1.1.安装JDK 8 (1)JDK 8 can be downloaded from Oracle's JDK Page: http://www.oracle.com/techn ...
- 20170609批量生成WORD合同
Sub NextSeven_CodeFrame() Application.ScreenUpdating = False Application.DisplayAlerts = False Appli ...
- h5 plus/h5+规范使用,模块索引,教你如何去看h5+的手册
最近看了下h5+规范的官网,开始觉得晦涩难懂,确实很乱,不过这也是基于我不理解的情况,终于艰难读完了,现在来分享下心得吧,基本看完文章,按我的方法,应该可以直接上手项目. 我准备的工具 hbuilde ...
- bind出现Address already in use解决方法
在socket函数和bind函数之间加入一段代码: // 建立服务器端socket if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0))<0) ...