iPhone实战:定位与地图
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
但从iOS5之后MKReverseGeocoder成为了不推荐使用的类。因此有一个新的类取代了他的作用,那就是CLGeocoder类,使用该类进行反向解析也非常容易,请看下面代码:
CLGeocoder *geocoder=[[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation
{
[super viewDidLoad];
MKMapView *mapView=[[MKMapView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 460.0)];
{
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
geocoder.delegate =
placemark.subAdministrativeArea,
placemark.locality,
placemark.subLocality,
3、地图显示
想更加形象地表现出位置信息靠文字的描述是远远不够的,因为使用地图来显示地理位置将会给用户带来全新的体验。在iOS里面已经将Google地图封装到SDK里面了,我们可以用很少的代码来实现很多在地图上的操作(如标记位置、绘画线路等)。下面的代码是生成一张地图并显示到界面上:
- (void)viewDidLoad
completionHandler:^(NSArray *placemarks,
NSError *error)
{
CLPlacemark *placemark=[placemarks objectAtIndex:0];
placemark.subAdministrativeArea,
placemark.locality,
placemark.subLocality,
placemark.thoroughfare,
placemark.subThoroughfare);
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder
didFailWithError:(NSError *)error
{
manager.delegate = self;
[manager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
那么CLLocationManager是通过什么方法来开启定位的呢?他是通过调用startUpdatingLocation开启定位功能,然后使用stopUpdatingLocation停止定位,其中定位信息是通过loctionManager:didUpdateToLocation:fromLocation;委托方法来通知委托对象的,因此委托对象必须实现CLLocationManagerDelegate委托。在返回定位信息委托方法中主要的两个参数是newLocation和oldLocation,newLocation表示最新定位,oldLocation表示上一次的定位信息。这两个都是CLLocation对象。以下是CLLocation的属性说明:
,
placemark.country,
placemark.postalCode,
placemark.ISOcountryCode,
1、获取当前定位
iOS提供了一个叫作CoreLocation.framework的框架。使用他可以取到自己的定位信息(经纬度)。请参考下面代码片段:
if([CLLocationManager locationServicesEnabled]){
//定位功能开启的情况下进行定位
个人觉得地理位置这部分的知识其实是相当有趣的。说到定位其实在大多数的社交软件中都有这样的一个功能,用户可以共享自己的位置并且查看其他用户的位置,从而更容易地结交一些附近或者在同一地区的朋友,又或者在地图上显示自己的当前位置,并且显示附近的餐厅或者咖啡厅。这些功能看起来是挺复杂,但在实际的开发过程中,iOS为我们封装了大部分的功能,让我们不需要学习太底层的知识,通过他提供的两个库就能轻松实现。接下来我会一步一步地讲述相关知识。
{
[manager stopUpdatingLocation];
}如上面代码所示CLLocationManager就是用于获取定位信息对象类,在实际应用中可以根据自己的需要来设置定位的更新频率以及定位准确度。其中代码中的distanceFilter表示更新位置的距离,假如超过设定值则进行定位更新,否则不更新。代码中的kCLDistanceFilterNone表示不设置距离过滤,即随时更新地理位置。desiredAccuracy属性表示取得定位的精度,kCLLocationAccuracyBest表示最精确,但也预示着需要消耗更多的时间和电量,所以应该根据需要设定。
属性 描述
altitude 海拔高度
coordinate 经纬度
course 行驶方向
horizontalAccuracy 水平方向的精确度
Speed 行驶速度
timestamp 时间戳
verticalAccuracy 垂直方向的精确度
2、获取地理位置信息
当你取到了一个经纬度信息时,也许还有这样的一个需求,那就是当前的经纬度所对应的地理位置信息是什么。那么这时候我们需要用到框架来为我们实现这一功能,那就是MapKit.framework。在这个框架中有一个叫MKReverseGeocoder的类可以帮助我们实现反向解析地理位置。请看一下代码:
fromLocation:(CLLocation *)oldLocation
{
[manager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
placemark.thoroughfare,
placemark.subThoroughfare);
}]; 从代码来看,CLGeocoder类没有使用委托的形式通知返回状态,而是通过block的方式进行回调,而且MKReverseGeocoder委托只返回了一个地标位置,但是CLGeocoder则返回了一个包含多个地标位置的数组,但这个数组在通常状态下是只有一个元素,如果存在多个元素那证明了给定解析的经纬度被解析到多个不同的地标信息。如果解析错误或者调用cancel方法则此参数为nil。
CLLocationManager *manager = [[CLLocationManager alloc] init];
manager.distanceFilter = kCLDistanceFilterNone;
manager.desiredAccuracy = kCLLocationAccuracyBest;
NSLog(@"name:%@\n country:%@\n postalCode:%@\n ISOcountryCode:%@\n ocean:%@\n inlandWater:%@\n locality:%@\n subLocality:%@
\n administrativeArea:%@\n subAdministrativeArea:%@\n thoroughfare:%@\n subThoroughfare:%@\n",
placemark.country,
placemark.postalCode,
placemark.ISOcountryCode,
placemark.administrativeArea,
NSLog(@"reverse geocoder fail!!");
}上面的代码是在获取到经纬度后,立刻进行反向地理位置解析的。其实MKReverseGeocoder用法也比较简单,通过经纬度初始化后直接调用start方法就可以实现反向解析了,然后等待返回,其返回是通过委托形式通知的。所以委托对象必须实现MKReverseGeocoderDelegate委托。解析成功后会返回一个MKPlacemark的对象里面包含了相关的地理位置信息(包括国家、地区、街道等)。
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder
didFindPlacemark:(MKPlacemark *)placemark
{
NSLog(@"\n country:%@\n postalCode:%@\n ISOcountryCode:%@\n locality:%@\n subLocality:%@\n administrativeArea:%@\n subAdministrativeArea:%@\n thoroughfare:%@\n subThoroughfare:%@\n",
placemark.ocean,
placemark.inlandWater,
placemark.administrativeArea,