Получить адрес текущего местоположения пользователя

#iphone #objective-c #xcode #android-mapview #userlocation

#iPhone #objective-c #xcode #android-просмотр карты #местоположение пользователя

Вопрос:

Я следую некоторому руководству и смешиваю свой ужасный код. Теперь я могу получить свое текущее местоположение. И когда я нажимаю на кнопку, она запускает PIN-код, который находится в моем текущем местоположении. Если я нажму на PIN-код, в сообщении будет показан адрес моего текущего.

У меня есть два вопроса:

  1. Почему я не могу получить более точный адрес? Теперь я получаю адрес со страной, городом и районом, но без названия дороги.
  2. Как я могу получить «текст» адреса текущего местоположения? Я хочу отобразить адрес в UILabel в другом месте, но не знаю, как это сделать.

Большое вам спасибо!

вот .h

 #import <UIKit/UIKit.h>
#import "MapKit/MapKit.h"
#import "CoreLocation/CoreLocation.h"

@interface UserLocationAddressViewController : UIViewController     <MKMapViewDelegate,MKReverseGeocoderDelegate>
{
    MKMapView *userLocationAddMapView;
    CLLocationManager *locationManager;
}

@property (nonatomic, retain) MKMapView *userLocationAddMapView;

-(IBAction)getUserLocationAddress:(id)sender;

@end
 

И вот .m

 #import "UserLocationAddressViewController.h"

@implementation UserLocationAddressViewController

@synthesize userLocationAddMapView;

-(IBAction)getUserLocationAddress:(id)sender
{
    MKReverseGeocoder *geoCoder = [[MKReverseGeocoder alloc] initWithCoordinate:locationManager.location.coordinate];
    geoCoder.delegate = self;
    [geoCoder start]; 
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(void)dealloc
{
    [userLocationAddMapView release];
    [super dealloc];
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

self.userLocationAddMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    userLocationAddMapView.showsUserLocation = YES;
    userLocationAddMapView.delegate = self;
    self.userLocationAddMapView.mapType = MKMapTypeStandard;

    locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
    CLLocationCoordinate2D coordinate = locationManager.location.coordinate;

    MKCoordinateRegion mapRegion;
    mapRegion.center = coordinate;
    MKCoordinateSpan mapSpan;
    mapSpan.latitudeDelta = 0.006;
    mapSpan.longitudeDelta = 0.006;
    mapRegion.span = mapSpan;
    [userLocationAddMapView setRegion:mapRegion animated:YES];
    self.userLocationAddMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.userLocationAddMapView];

    self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Get Add" style:UIBarButtonItemStylePlain target:self action:@selector(getUserLocationAddress:)] autorelease];  
}

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
    NSLog(@"placemark %f %f", placemark.coordinate.latitude, placemark.coordinate.longitude);
    NSLog(@"addressDictionary %@", placemark.addressDictionary);
    [userLocationAddMapView addAnnotations:[NSArray arrayWithObjects:placemark, nil]];
    [geocoder release];
}

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
    NSLog(@"reverseGeocoder fail");
    [geocoder release];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end
 

Ответ №1:

На самом деле вы не должны использовать MKReverseGeocoder, поскольку Apple обесценила его в iOS5, вам действительно следует использовать CLGeocoder. Следующий пример вернет целую тонну информации, которая основана на метках NSArray *, затем вы можете перебирать их и вызывать ключи в массиве assoc.

 #import "MapPoint.h"

@implementation MapPoint
@synthesize coordinate, title, dateAdded, subtitle, city, reverseGeo;

-(id)initWithCoordinates:(CLLocationCoordinate2D)c 
                   title:(NSString *)t {

    self = [super init];
    if (self) {

        coordinate = c;
        [self setTitle: t];
        [self setCurrentCity: [[CLLocation alloc] initWithLatitude:c.latitude longitude:c.longitude]];

        [self setDateAdded: [[NSDate alloc] init]];

    }
    return self;

}

-(void)setCurrentCity: (CLLocation *)loc {

    if (!self.reverseGeo) {
        self.reverseGeo = [[CLGeocoder alloc] init];
    }

    [self.reverseGeo reverseGeocodeLocation: loc completionHandler: 
     ^(NSArray *placemarks, NSError *error) {

         for (CLPlacemark *placemark in placemarks) {

             NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
             [formatter setTimeStyle:NSDateFormatterNoStyle];
             [formatter setDateStyle:NSDateFormatterLongStyle];

             NSString *dateString = [formatter stringFromDate: [self dateAdded]];
             [self setSubtitle: [dateString stringByAppendingString: [placemark locality] ] ];             

         }
     }];
}

@end
 

Ответ №2:

Просто поместите эти методы делегирования, я надеюсь, что это может вам помочь.

 -- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
    NSLog(@"MKReverseGeocoder has failed.");

}

-- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
    currentLocation = [placemark.locality stringByAppendingFormat:@", "];
    currentLocation = [currentLocation stringByAppendingString:placemark.country];
    [indicator stopAnimating];
    txtLocation.text = currentLocation;

}
 

Комментарии:

1. Это устарело в iOS 5

2. MK_CLASS_DEPRECATED(NA, NA, 3_0, 5_0)

Ответ №3:

У меня такая же проблема, MKReverseGeocoder не всегда возвращает полный адрес, потому что иногда координаты недостаточно точны, и служба не может сгенерировать приблизительный адрес. Для получения наилучших результатов я внедрил другое обратное геокодирование для yahoo. Итак, в основном, если MKReverseGeocoder (Google) не возвращает полный адрес, я запрашиваю yahoo, который может сгенерировать приблизительный.

С другой стороны, будьте осторожны с MKReverseGeocoder, он устарел в IOS 5, вместо этого они рекомендуют использовать CLGeocoder