转载自:http://blog.sina.com.cn/s/blog_7b9d64af0101cays.html
CLGeocoder是iOS5中新加的一个类,其实跟之前的MKReverseGeocoder很相似,不过CLGeocoder是以一种block的形式来反向地理编码的。
看了官方的文档,MKReverseGeocoder在iOS5中被禁止了,但其实你还是可以使用这个的,只不过在未来的某个时间,会从文档中删除掉,而且苹果这次增加的CLGeocoder类,跟CoreLocation整合在了一起,其实想想也应该是一起的,定位,反向,本应该属于一个系列的。
CLGeocoder类中有几个方法,一个是把经纬度转化成大家能看懂的信息,比如:city,county,街道等等,CLGeocoder类中的其他几个方法也非常的给里,可以把city,county等信息直接转化为坐标,以前大家可能都去githud上下载过把地点名字转回到坐标的demo,现在不用了,apple直接提供了接口给大家使用,我也今天才发现的...哎
下面只抄录最重要的两段吧,需要的话可以具体到原文查看:
#pragma mark - CLLocationManagerDelegate 定位服务
// 当获得了新的位置时,调用该方法
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(@"Latitude = %f", newLocation.coordinate.latitude);
NSLog(@"Longitude = %f", newLocation.coordinate.longitude);
// 创建一个定位对象
CLLocation *thelocation = [[CLLocation alloc]initWithLatitude:newLocation.coordinate.latitude
longitude:newLocation.coordinate.longitude];
// 初始化一个反向地理编码对象
self.myGeocoder = [[CLGeocoder alloc] init];
// 根据给定的经纬度来得到相应的地址信息
[self.myGeocoder reverseGeocodeLocation:thelocation completionHandler:^(NSArray*placemarks, NSError *error) {
if (error == nil && [placemarks count] > 0){
// CLPlacemark 存储着相应的地址数据
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(@"Country = %@", placemark.country);
NSLog(@"Postal Code = %@", placemark.postalCode);
NSLog(@"Locality = %@", placemark.locality);
}
else if (error == nil && [placemarks count] == 0){
NSLog(@"No results were returned.");
}
else if (error != nil){
NSLog(@"An error occurred = %@", error); }
}];
}
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler 方法:
用来转换地理坐标到真实地址的方法。
location:要转换的地址坐标
completionHandler:一个Block,请求返回时调用
typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
placemarks:返回查询的地理信息
error:是否成功
反向地理编码是通过一组经纬度数据的到一个实在的地理位置名称。同样我们可以使用地理编码通过一个地理名称得到一组经纬度数据。
NSString *oreillyAddress =@"1005 Gravenstein Highway North, Sebastopol, CA 95472, USA";
self.myGeocoder = [[CLGeocoder alloc] init];
[self.myGeocoder geocodeAddressString:oreillyAddress completionHandler:^(NSArray*placemarks, NSError *error) {
if ([placemarks count] > 0 && error == nil){
NSLog(@"Found %lu placemark(s).", (unsigned long)[placemarks count]);
CLPlacemark *firstPlacemark = [placemarks objectAtIndex:0];
NSLog(@"Longitude = %f", firstPlacemark.location.coordinate.longitude);
NSLog(@"Latitude = %f", firstPlacemark.location.coordinate.latitude);
}
else if ([placemarks count] == 0 &&
error == nil){
NSLog(@"Found no placemarks.");
}
else if (error != nil){
NSLog(@"An error occurred = %@", error);
}
}];
干脆把其余的也贴上来吧:
地图: #import
#import
#import
#import
@interface MoreViewController :UIViewController<</span>MKMapViewDelegate,CLLocationManagerDelegate>{
}
@property (nonatomic, strong) MKMapView *myMapView;
@end
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// 初始化MKMapView
self.myMapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
self.myMapView.mapType = MKMapTypeHybrid;
[self.myMapView setDelegate:self];
self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.myMapView];
// 返回用户是否开启了设备上的“定位服务”功能
if ([CLLocationManager locationServicesEnabled]){
self.myLocationManager = [[CLLocationManager alloc] init];
[self.myLocationManager setDelegate:self];
[self.myLocationManager setPurpose:@"一些提示信息,告诉用户要开启定位服务功能"];
// 开始更新地理位置,并根据更新结果执行CLLocationManagerDelegate方法
[self.myLocationManager startUpdatingLocation];
} else {
NSLog(@"设备上的“定位服务”功能未开启!");
}
}
@interface MyAnnotation : NSObject <</span>MKAnnotation>
#import
#import
@interface MyAnnotation : NSObject <<span style="color: #743fa4">MKAnnotation>{
}
// 特别要注意这个参数需要标示为只读类型的。因为 MKAnnotation 这个协议中定义的 Coordinate 也是只读类型的。
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy, readonly) NSString *title;
@property (nonatomic, copy, readonly) NSString *subtitle;
@property (nonatomic, unsafe_unretained) MKPinAnnotationColor pinColor;// 气泡的颜色
// 初始化坐标(Coordinate)
- (id) initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString*)paramTitle subTitle:(NSString *)paramSubTitle;
@end
#import "MyAnnotation.h"
@implementation MyAnnotation
@synthesize coordinate;
@synthesize title;
@synthesize subtitle;
@synthesize pinColor;
- (id) initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString*)paramTitle subTitle:(NSString *)paramSubTitle{
self = [super init];
if (self != nil){
coordinate = paramCoordinates;
title = paramTitle;
subtitle = paramSubTitle;
pinColor = MKPinAnnotationColorGreen;// 定义默认颜色
}
return(self);
}
@end
#pragma mark - CLLocationManagerDelegate 定位服务
// 当获得了新的位置时,调用该方法
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(@"Latitude = %f", newLocation.coordinate.latitude);
NSLog(@"Longitude = %f", newLocation.coordinate.longitude);
// 定义一个2D坐标
CLLocationCoordinate2D location =CLLocationCoordinate2DMake(newLocation.coordinate.latitude,newLocation.coordinate.longitude);
// 初始化锚点,根据坐标,标题,副标题
MyAnnotation *annotation =[[MyAnnotation alloc] initWithCoordinates:location
title:@"My Title"
subTitle:@"My Sub Title"];
// 为地图增加锚点
[self.myMapView addAnnotation:annotation];
}
// 当无法获得位置时,调用该方法
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"无法获取经纬度!");
}
#pragma mark - MKMapViewDelegate
// 当地图界面将要加载的时候会调用该方法
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
NSLog(@"mapViewWillStartLoadingMap");
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 返回锚点(大头针)的View,根据坐标信息
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation{
MKAnnotationView *result = nil;
if ([annotation isKindOfClass:[MyAnnotation class]] == NO){
return result;
}
if ([mapView isEqual:self.myMapView] == NO){
return result;
}
MyAnnotation *senderAnnotation = (MyAnnotation *)annotation;
// 获得锚点视图的颜色标识符
// 重用MKPinAnnotationView(跟重用TableView的Cell一个道理)
NSString *pinReusableIdentifier = @"myAnnotation";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapViewdequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];
if (annotationView == nil){
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier];
[annotationView setCanShowCallout:YES];
}
annotationView.pinColor = senderAnnotation.pinColor;
result = annotationView;
return result;
}