API Reference 系列 之Mapkit解析

作者: AFWater | 来源:发表于2016-07-24 16:43 被阅读489次

    前言

    最近要开发一个地图相关的工具,于是去苹果开发者官网查阅了资料。发现网站更新了API Reference 的文档结构,聚合了Framework的Guide和所有类,变得很清晰阅读。

    虽然官网的Guide解释的已经比较清楚,但是不够直观。于是结合官网资料,对Mapkit做了一些思维导图,并做了一些注解。

    本文章适合有OC基础,但对Mapkit不了解的同学。另外,本文章只大概说明Mapkit的作用和相关类,不做具体API说明。

    概要

    马斯克在一次访谈中,谈到他眼中的第一原理,简单来说就是从本质一层层往上走。

    所以我们认识和学习一个事物,我觉得要从四个角度去考虑:

    • 这个事务是什么
    • 这个事务解决了什么问题
    • 具体是怎么解决的
    • 解决的详细步骤是什么

    本文章中主要针对Mapkit讨论了前三个问题,第四个问题则需要使用Mapkit的同学结合官网和其他网站上的Demo,去自己实践。即本文将要讨论的三个问题:

    • Mapkit是什么
    • Mapkit解决了什么问题
    • Mapkit是怎么解决这些问题的

    详解

    Mapkit是什么

    我们先看下官网的简要解释:

    Location-based information consists of two pieces: location services and maps. Location services are provided by the Core Location framework, which defines Objective-C interfaces for obtaining information about the user’s location and heading (the direction in which a device is pointing). Maps are provided by the Map Kit framework, which supports both the display and annotation of maps similar to those found in the Maps app. (To use the features of the Map Kit framework, you must turn on the Maps capability in your Xcode project.) Location services and maps are available on both iOS and OS X.

    简单来说就是 Location framework 提供了定位和设备方向服务,MapKit提供了地图的标注和地图展示服务。

    Mapkit解决了什么问题

    通过Mapkit,我们可以获取当前定位、地图展示、标注、覆盖物、地理编码和反地理编码、位置检测、设备方向判断、获取路线信息、地理位置查询等地图相关的操作。

    Mapkit是怎么解决这些问题的

    Mapkit有很多类,针对以上的功能,画了一个思维导图,方便梳理。


    地图相关概念

    定位

    iOS中获取用户当前坐标的方式有两种:

    • 通过Core Loation FrameworkCLLocationManager
    • 通过Mapkit的MKMapViewuserLocation获取(需要设置showsUserLocation)

    从iOS8 开始,以上两种方式获取当前坐标时,都需要手动调用请求授权API:

    • 配置plist中的授权提示文案,key为 NSLocationWhenInUseUsageDescription (前台) 或 NSLocationAlwaysUsageDescription(前台,后台)
    • 手动调用CLLocationManagerrequestWhenInUseAuthorizationrequestAlwaysAuthorization,进行定位授权

    通过CLLocationManager进行定位的基本步骤:

    • 配置 CLLocationManager
    • 调用 requestWhenInUseAuthorizationrequestAlwaysAuthorization
    • 实现CLLocationManagerDelegate

    通过Mapkit中获取展示当前定位点的基本步骤:

    • 创建MKMapView
    • 设定showsUserLocation=YES
    • 实现 MKMapViewDelegatemapView:didUpdateUserLocation:

    注:

    1. CLLocationManager获得的坐标类型是WGS84坐标(即真实的地理坐标),MKMapView获得的坐标类型为GCJ02(即国测局经纬度坐标,高德用该坐标系)
    2. 从iOS8以后,MKMapView只有展示后上才会启动定位,单独alloc一个MKMapView,并不会启动定位。
    3. 相关的类:CLLocationManagerMKMapView

    地图展示

    展示地图是通过MKMapView类,初始化MKMapView,即可展示普通地图或卫星地图。这里不细说MKMapView类,相关的资料很多,主要提几个点。

    这里有三种坐标系

    • 地球的经纬度坐标。通过结构CLLocationCoordinate2D表示
    • 墨卡托坐标。即地图上的点,通过MKMapPoint表示
    • view上的坐标。即iOS的view坐标系,通过CGPoint表示

    三种坐标系的相关类见下面的思维导图:


    三种坐标系

    有些情况,不需要展示一个完整的MKMapView,只需要展示a map image即可。则可以通过MKMapSnapshotter异步生成一个 static map image

    • 配置MKMapSnapshotOptions
    • 初始化MKMapSnapshotter
    • 调用startWithCompletionHandler:异步获得地图图片

    标注 Annotation

    Annotation,就是地图上的常见的大头针等标注。Annotation的设计遵循数据与View分离的原则,数据为符合MKAnnotation协议的类,View为MKAnnotationView的子类,添加的基本步骤如下:

    • 定义一个 MKPointAnnotation 对象,添加数据
    • 使用 MKMapViewaddAnnotation: 方法添加到地图
    • 实现 mapView:viewForAnnotation: 代理方法
    • 在代理内定义 MKPinAnnotationView 对象

    通过上面几个步骤,即可显示标准的大头针。如果要显示自定义标注,把MKPointAnnotation对象替换为自定义MKAnnotation,把MKPinAnnotationView替换为自定义的MKAnnotationView即可。

    另外,在这块还有一个点是Callout,即自定义气泡,如下图是一个标准的Callout展示。通过MKAnnotationViewcanShowCalloutrightCalloutAccessoryViewleftCalloutAccessoryView三个属性控制。

    Callout

    覆盖物 Overlay

    简单来说,覆盖物就是在地图上画的线,圆,矩形等等。覆盖物的设计也遵循数据与View分离的原则。一个Overlay对象对应一个OverlayRenderer对象。

    • Overlay 对象,通过实现 MKOverlay 协议,定义数据。现有的Overlay对象有:MKPolylineMKPolygonMKCircle以及 MATileOverlay
    • Overlay 渲染器,通过继承 MKOverlayRenderer,用于在地图显示 Overlay。以上Overlay对应的渲染器对象有:MKPolylineRendererMKPolygonRendererMKCircleRenderer以及 MKTileOverlayRenderer

    更加复杂的自定义可以详见Location and Maps Programming Guide中的解释。

    Geocoding and reverse-geocoding

    geocoding,地理编码,即通过地理位置信息转化为坐标点。reverse-geocoding,反地理编码,即通过坐标点转化为地理位置信息。主要通过CLGeocoder实现。

    Region Monitoring And iBeacon

    区域检测用于监测固定区域内的定位变化,在iOS上有两种方式,第一种是通过CLLocationManager监控指定区域(circular Region),另一种是通过蓝牙区域检测(Beacon Region)。其中蓝牙参见Core Bluetooth framework

    Heading

    通过CLLocationManager可以获取当前设备的方向。

    Direction

    Mapkit可以通过MKDirections获取指定的路线信息

    地理信息查询

    Mapkit支持用户查询地理位置信息,主要步骤为:

    • 初始化MKLocalSearchRequest,配置查询参数
    • 初始化MKLocalSearch
    • 调用startWithCompletionHandler:获取查询结果

    后记

    本篇文章主要梳理了地图功能,并未详细分析API的使用,只作为地图框架参考,具体使用请查询相关API资料,并结合Demo进行练习。

    附录

    第一原理

    马斯克在访谈中表述他眼中的第一原理:

    我们运用「第一原理思维」而不是「比较思维」去思考问题是非常重要的。我们在生活中总是倾向于比较——别人已经做过了或者正在做这件事情,我们就也去做。这样的结果是只能产生细小的迭代发展。「第一原理」的思考方式是用物理学的角度看待世界的方法,也就是说一层层剥开事物的表象,看到里面的本质,然后再从本质一层层往上走。这要消耗大量的脑力。

    更多解释参见马斯克的「第一原理」到底是什么?

    火星坐标

    简单来说就是对GPS坐标进行偏移后得到的坐标,就是所谓的火星坐标。国测局要求国内地图上的坐标都要经过偏移,即国内地图上的坐标都是火星坐标。下面是几种国内的经纬度。

    • wgs84,GPS经纬度
    • gcj02,国测局经纬度偏移坐标,高德用该坐标系
    • bd09,百度经纬度坐标,百度在gcj02的基础上再次进行了偏移

    这里需要注意的是CLLocationManager进行定位获得坐标是GPS坐标。

    参考资料

    MapKit API Reference
    Location and Maps Programming Guide
    高度地图
    百度地图
    Core Location Manager Changes in iOS 8
    Core Location 最佳实践 (WWDC 2016 - session716)

    相关文章

      网友评论

      本文标题:API Reference 系列 之Mapkit解析

      本文链接:https://www.haomeiwen.com/subject/eowwjttx.html