您的位置:首页 > 移动开发 > IOS开发

iOS项目开发实战——CoreLocation地理编码和反地理编码

2015-09-20 14:32 507 查看
      地理编码是把某个具体的位置计算为经纬度,反地理编码正好相反。这个功能在CoreLocation中如何实现呢?

(1)代码如下:

#import "ViewController.h"
#import <MapKit/MapKit.h>

@interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate>

@property (nonatomic, strong) MKMapView * mapView;
@property (nonatomic, strong) CLLocationManager * locationManager;
@property (nonatomic, strong) UITextField * textField;
@property (nonatomic, strong) NSString * titleString;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

//    116.456011,39.941272
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
[_mapView setDelegate:self];
[_mapView setShowsUserLocation:YES];
[_mapView setMapType:MKMapTypeStandard];
[self.view addSubview:_mapView];

UILongPressGestureRecognizer * longpressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];
[_mapView addGestureRecognizer:longpressGestureRecognizer];

_textField = [[UITextField alloc] init];
[_textField setTranslatesAutoresizingMaskIntoConstraints:NO];
[_textField setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:_textField];

UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundColor:[UIColor orangeColor]];
[btn setTitle:@"查找" forState:UIControlStateNormal];
[btn setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn addTarget:self action:@selector(theBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_textField][btn(100)]-20-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_textField,btn)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[_textField(30)]-(-30)-[btn(30)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(_textField,btn)]];

//检测定位功能是否开启
if([CLLocationManager locationServicesEnabled]){

if(!_locationManager){

_locationManager = [[CLLocationManager alloc] init];

if([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];

}

//设置代理
[_locationManager setDelegate:self];
//设置定位精度
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//设置距离筛选
[_locationManager setDistanceFilter:100];
//开始定位
[_locationManager startUpdatingLocation];
//设置开始识别方向
[_locationManager startUpdatingHeading];

}

}else{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:nil
message:@"您没有开启定位功能"
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alertView show];
}
}

//点击按钮执行此方法
- (void)theBtnPressed:(id)sender {
[_textField resignFirstResponder];
if([_textField.text length] == 0){

return;
}
[self geocoder:_textField.text];
}

#pragma mark LongPress
- (void)longPressed:(UILongPressGestureRecognizer *)recognizer {
if(recognizer.state == UIGestureRecognizerStateBegan){
CGPoint point = [recognizer locationInView:_mapView];
CLLocationCoordinate2D coordinate2D = [_mapView convertPoint:point toCoordinateFromView:_mapView];

[_mapView removeAnnotations:_mapView.annotations];

CLLocation * location = [[CLLocation alloc] initWithLatitude:coordinate2D.latitude longitude:coordinate2D.longitude];

[self reverseGeocoder:location];

//        MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
//        [pointAnnotation setTitle:_titleString];
//        [pointAnnotation setCoordinate:coordinate2D];
//        [_mapView addAnnotation:pointAnnotation];
}
}

//授权状态发生改变的时候执行
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
switch(status){
case kCLAuthorizationStatusDenied:
{
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:nil
message:@"定位功能没有开启" delegate:nil
cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
break;
default:
break;
}
}

#pragma mark mapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString * key = @"key";
MKPinAnnotationView * pinAnnotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:key];

if(pinAnnotationView == nil){
pinAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:key];
[pinAnnotationView setCanShowCallout:YES];
}

if([annotation isKindOfClass:[MKUserLocation class]]){
[pinAnnotationView setPinColor:MKPinAnnotationColorRed];
[((MKUserLocation *)annotation) setTitle:_titleString];
}else{
[pinAnnotationView setPinColor:MKPinAnnotationColorPurple];
}

return pinAnnotationView;
}

#pragma mark - CLLocationManangerDelegate
//定位成功以后调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[_locationManager stopUpdatingLocation];
CLLocation * location = locations.lastObject;

MKCoordinateRegion coordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude), MKCoordinateSpanMake(0.1, 0.1));

[_mapView setRegion:[_mapView regionThatFits:coordinateRegion] animated:YES];

//    [self reverseGeocoder:location];
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"error:%@",error);
}

#pragma mark Geocoder
//反地理编码
- (void)reverseGeocoder:(CLLocation *)currentLocation {

CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {

if(error || placemarks.count == 0){
NSLog(@"error");
}else{

CLPlacemark * placemark = placemarks.firstObject;

self.titleString = placemark.name;
MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
[pointAnnotation setTitle:placemark.name];
[pointAnnotation setCoordinate:CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude)];
[_mapView addAnnotation:pointAnnotation];

NSLog(@"placemark:%@",[[placemark addressDictionary] objectForKey:@"City"]);
}

}];
}

//地理编码
- (void)geocoder:(NSString *)str {
CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:str completionHandler:^(NSArray *placemarks, NSError *error) {

if(error || placemarks.count == 0){
NSLog(@"error");
}else{
CLPlacemark * placemark = placemarks.firstObject;
MKCoordinateRegion coordinateRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude), MKCoordinateSpanMake(0.1, 0.1));

[_mapView setRegion:[_mapView regionThatFits:coordinateRegion] animated:YES];

MKPointAnnotation * pointAnnotation = [[MKPointAnnotation alloc] init];
[pointAnnotation setTitle:placemark.name];
[pointAnnotation setCoordinate:CLLocationCoordinate2DMake(placemark.location.coordinate.latitude, placemark.location.coordinate.longitude)];
[_mapView addAnnotation:pointAnnotation];
}

}];
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end


(2)实现效果如下:




(3)通过输入框的搜索,也能定位到具体的位置。长按地图,就能获得某个位置的详细地址。应该说非常方便。

github主页:https://github.com/chenyufeng1991  。欢迎大家访问!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: