地图和定位的基本使用

作者: 蓝心儿的蓝色之旅 | 来源:发表于2015-12-08 22:56 被阅读5349次

    近些天用到了有关定位的功能,所以顺便把自己用到的一些相关知识整理如下.

    一.定位要使用" CoreLocation "框架

    想要定位,大概需要使用以下5个步骤:

    1.首先创建一个"强引用"的位置管理器CLLocationManager

    2.设置位置管理器的代理

    3.请求用户授权(iOS8后方法)

    >设置方法requestWhenInUseAuthorization    或requestAlwaysAuthorization

    >配置plist文件 NSLocationWhenInUseUsageDescription  或  NSLocationAlwaysUsageDescription

    >注意1对1对应

    4.开启定位

    startUpdatingLocation  对应的有停止定位stopUpdatingLocation

    5.实现didUpdateLocations代理方法

    >代理方法一直调用,会非常耗电。除非特殊需求(如导航),可以使用stopUpdatingLocation停止定位,实现一次定位

    >除了停止定位,还可以设置管理器的distanceFilter,当用户改变位置一定值后才会调用。(如后面跟50,即改变50米后调用一次代理方法)-->持续定位

    >desiredAccuracy-->定位精度-->将周围一定值的范围看作一个地点

    比较两点之间的距离使用CLLocation的distanceFromLocation方法--  注意计算出来的是直线距离

    iOS9新特性-->后台定位-->allowsBackgroundLocationUpdates

    >当用户授权为使用期间时,可以设置这个属性为YES,在plist中添加"Required background modes"  在字典中添加值"App registers for location updates".

    二.地理编码和反地理编码都使用CLGeocoder类来实现.

    地理编码使用 geocodeAddressString: completionHandler: 方法.将一个地名字符串转换为经纬度。

    在此方法中得到一个装着CLPlacemark的数组。一个CLPlacemark表示一个地理坐标,有位置信息(经纬度),以及地理位置的详情,如下:

    name                    地名

    thoroughfare            街道

    subThoroughfare        街道相关信息,例如门牌等

    locality                城市

    subLocality            城市相关信息,例如标志性建筑

    administrativeArea      直辖市

    subAdministrativeArea  其他行政区域信息(自治区等)

    postalCode              邮编

    ISOcountryCode          国家编码

    country                国家

    inlandWater            水源,湖泊

    ocean                  海洋

    areasOfInterest        关联的或利益相关的地标

    将CLPlacemark中的经纬度取出,就完成了地理编码

    反地理编码使用reverseGeocodeLocation: completionHandler: 方法.将一个包含经纬度的CLLocation传进去,得到位置信息,就是反地理编码。

    在得到的CLPlacemark中取出name信息即可。

    三.mapView的基本使用需要用到  "MapKit 框架

    注意:在storyBoard中使用到非UIKit的框架,要在项目的TARGETS-->General-->Linked Frameworks and Libraries中点击+号添加框架

    1.定位到用户位置

    1.1 创建位置管理器并请求用户授权

    1.2 设置mapView的跟踪模式userTrackingMode

    MKUserTrackingModeNone  //不跟踪

    MKUserTrackingModeFollow //跟踪位置

    MKUserTrackingModeFollowWithHeading //跟踪位置和移动方向

    2.设置用户位置大头针的属性

    2.1 设置mapView的代理,实现协议,在didUpdateUserLocation方法中拿到MKUserLocation类型的大头针

    2.2 userLocation有location、title、subtitle属性,根据location反地理编码拿到CLPlacemark并赋值给title和subtitle即可

    3.回到用户当前位置

    3.1 确定当前位置(region-->MKCoordinateRegion)

    确定一个区域和确定一个圆类似,需要且只需要确定两个元素:1.中心点经纬度CLLocationCoordinate2D-->self.mapView.userLocation.coordinate  2.经纬度跨度span-->MKCoordinateSpan  两个都是结构体,直接make。

    3.2 如何确定系统默认经纬度跨度 --> 在mapView的代理方法regionDidChangeAnimated中,当地图区域改变时回自动调用,在此方法中打印经纬度跨度。

    如果需要动画回到当前位置,调用mapView的 setRegion: animated:

    4.放大(缩小)地图

    放大和缩小地图其实就是:"当前"地图显示的中心点经纬度不变,经纬度跨度(span)缩小或增大2倍;

    注意:在回到当前位置设置region时的中心点经纬度是定位到用户的经纬度(userLocation),而放大缩小地图的中心点经纬度是当前地图界面的中心点经纬度。

    四.添加大头针模型设计

    1.导入框架

    -->在模型类中导入mapKit框架

    2.遵守协议

    -->遵守MKAnnotation协议

    3.实现属性

    -->实现title\subtitle\coordinate(可直接跳进头文件复制,注意删除readonly修饰)

    添加大头针 -->mapView的addAnnotation: 方法

    #pragma mark 修改大头针颜色,动画掉落

    mapView的viewForAnnotation代理方法中实现,这块和cell的创建基本一样

    1.首先创建一个唯一的标识符ID

    static NSString *ID = @"annotation"

    2.根据ID去缓存池取:

    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];

    3.如果取不到(为空),再创建

    annotationView = [[MKAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];

    MKAnnotationView默认是没有界面的,MKPinAnnotationView继承自MKAnnotationView,可以设置大头针颜色,动画掉落效果。而父类MKAnnotationView中的属性方法其子类都有,如:

    canShowCallout --> 能否显示大头针详情

    leftCalloutAccessoryView \ rightCalloutAccessoryView \ detailCalloutAccessoryView-->分别对应左\右\详情的视图.

    注意如果大头针没有设置title属性,就不能显示左右和详情视图。如果同时设置了大头针的subtitle和detailCalloutAccessoryView,会显示detailCalloutAccessoryView。

    在代理方法中如果直接return nil  系统会默认创建一个系统样式的大头针--> 当需要系统蓝光圈的大头针时,可以判断代理方法中参数的类型,匹配就return nil

    #pragma mark  自定义实现动画掉落效果

    自定义动画效果在mapView的代理方法didAddAnnotationViews 中实现,此方法在加载完大头针的view时系统自动调用

    自定义动画掉落思路: 1.保存大头针位置    2.修改大头针位置的Y值    3.动画返回到大头针默认位置

    注意:如果要取消系统默认蓝光圈(MKModernUserLocationView类型)的动画掉落效果,在didAddAnnotationViews 代理方法中判断传进来的MKAnnotationView类型(MKModernUserLocationView是私有方法,用NSClassFromString方法替代 [MKModernUserLocationView class])

    #pragma mark  封装代码

    这里的封装代码和tableViewCell类似,不再赘述.

    只是要注意如果不给大头针添加模型,系统会自动调用set方法,所以在工作中处理数据的代码可以放在set方法中。注意调用父类方法[super setAnnotation:annotation];

    五.实现导航

    地图导航所需的数据拿不到,交由苹果处理,在中国苹果交友高德地图处理。由于封装的比较好,我们本质上只需要一行代码:

    MKMapItem openMapsWithItems: launchOptions:

    根据所需传入的参数倒推即可。

    所需正序步骤:

    1.地理编码目的地位置

    >>使用CLGeocoder进行地理编码,得到CLPlacemark

    2.转换CLPlacemark --> MKPlacemark

    MKPlacemark *mkPlacemark = [[MKPlacemark alloc] initWithPlacemark:placemark];

    3.获取当前位置和目的地mapItem

    //目的地的item

    MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:mkPlacemark];

    //当前位置的item

    MKMapItem *currentmapItem = [MKMapItem mapItemForCurrentLocation];

    4.开始导航

    MKMapItem openMapsWithItems: launchOptions:

    第一个参数传入目的地和当前位置的数组,第二个是选项的字典。如下:

    //keys

    MKLaunchOptionsMapCenterKey:地图中心的坐标(NSValue)

    MKLaunchOptionsMapSpanKey:地图显示的范围(NSValue)

    MKLaunchOptionsShowsTrafficKey:是否显示交通信息(boolean NSNumber)

    //MKLaunchOptionsDirectionsModeKey: 导航类型(NSString)

    {

    MKLaunchOptionsDirectionsModeDriving:驾车

    MKLaunchOptionsDirectionsModeWalking:步行

    }

    //MKLaunchOptionsMapTypeKey:地图类型(NSNumber)

    enum {

    MKMapTypeStandard = 0,

    MKMapTypeSatellite,

    MKMapTypeHybrid

    };//MKLaunchOptionsCameraKey  3D地图效果

    相关文章

      网友评论

      • Ths:写的不错啊

      本文标题:地图和定位的基本使用

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