地图和定位的基本使用

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

一.定位要使用" 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地图效果

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容