地图 | 定位技术

LBS技术(Location Based Service): 基于位置的定位服务.

相关框架

  • CoreLoacation.framework
  • MapKit.framework
目标: 使用定位服务,获取用户的位置
//没有决定权限状态
 kCLAuthorizationStatusNotDetermined = 0,

//权限状态限制
 kCLAuthorizationStatusRestricted,

//拒绝状态,必须需要用户手动修改.
 kCLAuthorizationStatusDenied,

//任意时刻都需要定位
 kCLAuthorizationStatusAuthorizedAlways :

 // launch APIs has not been granted.
//当使用的时候定位
 kCLAuthorizationStatusAuthorizedWhenInUs
  1. 授权:iOS8后,需要App自己手动的调用授权相关的代码.

      1. CLLocationManager类:官方文档:定位授权的相关操作.
        1. 判断当前的授权状态
        2. 请求用户授权(前提是配置info.plsit:NSLocationWhenInUseUsageDescription(注意不带带空格,错都不知道为什么,为什么需要使用定位)
        3. 授权请求的结果,需要代理去获取.(哪个代理方法:)
    1. 代理方法,授权didChange方法
      根据status来处理,注意当用户拒绝时,需要提醒用户打开定位权限.
  2. 使用定位服务,来获取位置.

    1. 开始更新位置.
    2. 实现代理方法(两个),CLLocation类对象?
    3. 这是个数组?why,拿到设备的经纬度.
    4. 模拟器的位置是假的,可以是自己设置,有bug.
    5. 有一个updata(多次更新位置需要stop)方法,一个request方法(获取一次位置)
    6. 处理错误信息.location..fail方法是成对实现的
请求位置
[self.manager requestLocation];

// 位置更新和发生错误成对出现
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    //   locations至少包含有一个位置 (最新的当前位置)
    // 如果是延迟模式或者是多个位置值还没有处理, 可能会包含多个位置
    CLLocation *location = locations.lastObject;
    // 获取经度和纬度coordinate坐标的意思
    CLLocationCoordinate2D coordinate = location.coordinate;
    NSLog(@"%f",coordinate.longitude);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"位置更新错误%@",error);
}
  • 程序后台允许更新位置:注意需要配置
Snip20161025_1.png

假的跑步应用

  1. 请求位置更新
  2. 代理方法获得参数locations
  3. 根据对象location获取两个的距离和时间累加,算出速度
[self.manager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
             // 获取距离
              [currentLocation distanceFromLocation:self.previousLocation];
           // 获取时间间隔
              NSTimeInterval time = [currentLocation.timestamp timeIntervalSinceDate:self.previousLocation.timestamp];
}

做指南针的应用(真机才能用,模拟器不支持)

  • 跟方向有关(heading)
  • 1, 先判断硬件是否支持
  • 2, 开启更新方向,实现代理方法
  • 3, CLHeading类,磁北偏移量属性
//开启方向更新
[self.manager startUpdatingHeading];
//代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
                // 磁北偏移量, (地磁场的北极)
    // 0度表示的磁场北极, 顺时针旋转递增, 0 ~ 359.9 的角度值
    CLLocationDirection direction = newHeading.magneticHeading;
}

区域监听:判断用户是否跨入边界

CLRegion:查文档,发现需要使用子类,圆形区域.

//    In iOS, you do not create instances of this class directly; instead, you instantiate 
subclasses that define specific types of regions
因此这个region对象参数需要子类获取,打开方法说明知道需要调用哪几个代理方法.
[self.manager startMonitoringForRegion:region];

地理编码和反地理编码

地理描述:经纬度,海拔(机器识别)
文字描述:位置(用户友好)

地理编码:文字->地理
反地理编码:地理->文字
本质上是网络请求,发送数据apple帮你查询.
类:CLGeoCoder:地理编码类,进行地理和反地理编码
类:CLPlacemark:既包含地理描也包含文字描述

MapKit

地图视图的使用

Xcode6.0之后,直接引用头文件会"自动"导入官方库,但是还是崩溃,是因为你没有使用它[MKMapView class]一使用就不会崩溃了.自己是直接导入了框架了.

  1. 直接使用MKMapView,会崩溃.要先导入MapKit框架(导入加引用)
  2. 部分显示地图(去哪等)必须关闭手势.(三个手势,拖拽,捏合,旋转)
  • 显示用户所在位置(需要申请授权)
    1. 申请定位授权
    2. 设置mapView显示用户所在区域.
      ** overlay **覆盖.
    _mapView.zoomEnabled = YES;
    _mapView.scrollEnabled = YES;
    _mapView.rotateEnabled = YES;
    
    _mapView.delegate = self;
#pragma mark - 代理方法
//地图区域将要改变
//- mapView:regionWillChangeAnimated:
//Tells the delegate that the region displayed by the map view is about to change.
//地图区域已经改变动画
//- mapView:regionDidChangeAnimated:
//Tells the delegate that the region displayed by the map view just changed.
//地图被加载
//- mapViewDidFinishLoadingMap:
//Tells the delegate that the specified map view successfully loaded the needed map data.

---------------------------------------------------------------------

//地图显示用户所在位置前(涉及隐私三步)
// ========== 显示用户所在的位置 ==========
    // 显示用户所在位置 (本质上是需要定位用户所在位置)
    // 一旦地图定位到用户所在位置, 会触发相关的代理方法
    [self.mapView setShowsUserLocation:YES];
显示用户大头针
/**
 地图视图已经更新了用户位置 (定位到新数据)
 @param userLocation 用户位置的"大头针"(Annotation, 注解)数据模型
 */
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    // MKUserLocation : 专门用来表示用户位置的数据 (大头针视图的数据模型)
    // M - V (视图 - 模型)
    NSLog(@"%@", userLocation.title);
}
// 地图追踪模式
self.mapView.userTrackingMode = MKUserTrackingModeFollow;

自定义大头针.

MKAnnotation注释协议,自定义类类,遵守协议.

  1. 写三个协议内的属性.

MKAnnotationView地图注释View,就是大头针.

创建MKAnnotationView的子类
目标:希望继承这个类的MKAnnotation属性内的三个属性,并且还能新增功能属性.
1. 写一个同名属性
将@property (nonatomic, strong, nullable) id <MKAnnotation> annotation;换成下面的属性
@property (nonatomic, strong, nullable) ZLAnnotation * annotation;
这样会产生警告
2. 跟父类的相同属性,变为自己的解决办法:先写个同名属性,但是不要生成setter和getter方法,加关键字,就不会报警告了.
@dynamic annotation;
3. 重写setter方法
#pragma mark - 重写setter方法
- (void)setAnnotation:(ZLAnnotation *)annotation {
    //Annotation是从父类继承过来的属性
    // 父类的setAnnotation会处理coordinate, title, 和subtitle这三个属性.就有了标题等内容
#pragma mark - 关键,先把父类的属性赋值过来,在实现自己需要实现的功能.
    super.annotation = annotation;
    
    //再来处理自己有关的操作
    NSString *imageName = [NSString stringWithFormat:@"category_%zd",annotation.type + 1];
    self.image = [UIImage imageNamed:imageName];
}

路线规划

路线规划的本质是向地图上添加遮盖.
V-M的视图设计模式(先获取系统的原型model),在通过代理 获取视图对象.
大头针和路线遮盖都是这样的原理.

集成百度地图SDK的应用

配置:根据百度官方API介绍配置,不要遗漏就可以了.

目标:导入百度地图进行使用.

  1. 注册
  2. 简介和配置秘钥
  3. 重点看注意事项:
    1. 注意地图视图的生命周期
    2. 配置info.plist文件
      下载SDK,以前是一个库.a文件,现在是多个.framework.方便了,只要导入相关的framework.(查阅百度官方解释)
      注意:先不导,然后根据错误来导入.
  4. 添加相关framework
  5. 导入相关boundle(其实就是文件),内有资源
  6. 导入百度地图引用的系统框架.
  7. 解决object-C+=的问题.
    1. 修改某个文件的后缀为.mm (why?系统编译是根据文件类型来支持语言.mm就可以也支持ocject-C++了)
    2. 设置buildSetting.搜索compile source as,设置为object-C
  8. 解决boundle display name问题.表示项目名称.
  9. 加载BMKmapView,得到地图视图.注意额外注意生命周期问题.

注意真实项目中,所有的第三方SDK需要用单独的.h文件管理.永发哦了导入,不用pch文件.

  • 代码:
    1. 初始化BMKMapManager,启动百度地图
    2. 使用百度地图.

https:在iOS9之后,苹果需要采用的安全传输协议https,需要配置的.
.framework是什么:库,框架.Xcode6以后推出的framework

  1. 百度地图的生命周期和代理设置的问题

Overlay遮盖.
ParkMark商圈标记点

目标:百度地图的定位功能

  1. 开始定位
    1. 百度地图的定位和地图功能是分开的.所以需要重新导入新的BMKLocation.framework.
    2. 核心类:BMKLocationService定位服务
    3. 类比原生:创建对象,设置代理返回数据.
    4. 开始定位(方法介绍,需要配置info.plist)
  2. 用户的位置数据模型
    1. 代理方法中BMKUserLocation参数:用户当前位置的大头针数据模型
    2. 错误处理:查找相关错误code,在BMKTypes.h文件中,查找
    3. 相关属性:desiredAccuary精确度.看官方解释
  3. 地图显示用户位置(搜mapView库location)
    1. 显示用户所在位置.
    2. 将用户数据传给地图,更新位置数据
      结果:能显示位置,但是不会跳转到用户位置
  4. 设置地图显示区域
  5. 手动设置用户所在区域.
  6. setRegion方法,根据参数写位置.
  7. 导入工具模块.BMKUtils
  8. 获取用户的位置(便利操作:LocationService有更新位置的属性,定位后才是正确的)
  9. 追踪用户位置.
  10. 开启用户追踪模式
  11. 周期兴趣点查询(POI - ponit of interset)
    POI:ATM,KTV,电影院等等
    1. 导入searchAPI,有关的查找功能
    2. BMKPoiSearch类.
    3. 设置代理,需要在viewWillAppear配置和代理置空问题,否则影响释放.
    4. poiSearchNearBy方法参数option配置(很多需要配置,注意看一下,关键字等).
    5. 代理方法回调结果:查一下
    6. poiResult获取poiInfo类
  12. 大头针添加(mapView)
    1. 1.添加一个大头针数据,使用系统提供的表示一个点的大头针(找一下),不用自定义
      2.根据你遍历模型数据,指定大头针.
  13. 自定义大头针视图
    1. mapView的代理方法,返回某个模型对应的视图
    2. 判断类型BMKPointAnnotation返回对应的视图(类比原生)
    3. 创建BWKPinAnnotationView注意复用问题.
    4. 配置模型
  14. 需要改默认我的位置图片,但是不知道类型,代码改不了.
    可以进入百度素材,改百度素材里面的图片名,并且注意同名.

新的东西:实现点击大头针触发弹出自定义窗口

  1. 百度的paopaoView.相似原生的自定义BMKAnnotationView.
  2. 有一个在这里上车的绿标大头针,他一直显示在屏幕的正中央.怎么做的?
    1. 把绿标不加载mapView上,而是加在view上.
    2. 获取绿标所在位置的经纬度描述.地图mapView提供了很多frame和坐标进行转化的方法.
      // 转换坐标点
      convertPoint方法返回一个坐标点.
      
    3. 利用反地理编码,获取详细信息.在search框架内.
  3. 周边标志性地表查找
    1. 通过反地理编码可以获取到周边的标志性地标.
    2. 反地理编码的poiList属性,就可以获取到周边信息了.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,600评论 18 139
  • 各位小伙伴们大家好,今天我向大家介绍一下苹果百度地图的使用方法,因为做过一些想关的APP,感觉百度地图还是挺方便的...
    Lee0528阅读 14,659评论 18 46
  • 作者:柳骏原文地址:http://www.ios520junge.com/ 初学地图时,觉得地图是个很高深的玩意儿...
    行走的苹果哥阅读 1,314评论 0 4
  • *初学地图时,觉得地图是个很高深的玩意儿,导航、定位、检索这得运用多少算法和核心动画的知识点啊,于是一直排斥 * ...
    柳骏阅读 3,702评论 11 22
  • 前几天,跟一个中学时期的学弟在一起吃饭,酒过三巡,这位学弟也就敞开了话题聊了起来;他在中学曾苦苦地追过一个女孩,无...
    摇橹的渡人阅读 409评论 0 0