使用 CLGeocoder 将城市和州信息添加到 MKAnnotation

Posted

技术标签:

【中文标题】使用 CLGeocoder 将城市和州信息添加到 MKAnnotation【英文标题】:Adding City and State Information to MKAnnotation Using CLGeocoder 【发布时间】:2011-12-23 01:49:11 【问题描述】:

我正在尝试将城市和州信息添加到 MKAnnotation,但在将其添加到注释之前,数据已被清除。这是我当前的代码(为简单起见仅显示关注的部分/部分):

实施中:

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
     
    CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) 
    CLPlacemark *placemark = [placemarks objectAtIndex:0];
    [self setCity:[placemark locality] andState:[placemark administrativeArea]];
    ];

    NSLog(@"Location 1: %@, %@", city, state);

    MapPoint *mp = [[MapPoint alloc] initWithCoordinate:[newLocation coordinate]
                                                  title:[locationTitleField text]
                                                   date:[dateFormat stringFromDate:today]];

    [mapView addAnnotation:mp];


- (void)setCity:(NSString *)c andState:(NSString *)s

    [self setCity:c];
    [city retain];
    [self setState:s];
    [state retain];
    NSLog(@"Location 2: %@, %@", city, state);

在界面中:

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate, MKMapViewDelegate>

    CLLocationManager *locationManager;
    IBOutlet MKMapView *mapView;
    NSString *city;
    NSString *state;


@property (strong, nonatomic) IBOutlet UIWindow *window;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, copy) NSString *state;

- (void)setCity:(NSString *)c andState:(NSString *)s;

@end

位置 1 打印 (null), (null) 而位置 2 打印加利福尼亚州旧金山。为什么在我可以在注释中使用它们之前从这些属性中删除数据?

非常感谢...

【问题讨论】:

你在哪里设置 MKAnnotation? 我添加了一些代码来显示我在哪里设置 MKAnnotation。 MapPoint 类符合 MKAnnotation 协议。不要担心日期的东西。如果我在做注释之前能得到城市和州,我会把它添加到副标题中。 这就解释了问题所在。请参阅我的答案中的更新部分。 【参考方案1】:

位置 1 为空的原因是反向地理编码器在运行时尚未完成。 completionHandler 中的所有内容都将在地理编码器完成之后发生。您对位置 1 的日志语句不是 completionHandler 的一部分,而是在调用反向地理编码后立即执行。最终结果是日志调用发生在您调用setCity:andState:之前

更新

您需要在completionHandler 块中设置注解。块中出现的代码在顺序和时间上比locationManager:didUpdateToLocation:fromLocation: 消息实现的其余部分出现得晚。您不妨read about blocks from Apple's documentation或上网搜索。

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
     
    CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
    [geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) 
        CLPlacemark *placemark = [placemarks objectAtIndex:0];
        [self setCity:[placemark locality] andState:[placemark administrativeArea]];
        MapPoint *mp = [[MapPoint alloc] initWithCoordinate:[newLocation coordinate]
                                                      title:[locationTitleField text]
                                                       date:[dateFormat stringFromDate:today]];
        [mapView addAnnotation:mp];
    ];

结束更新

此外,您似乎没有尽可能地使用属性。由于您有 citystate 属性,因此您不需要 citystate 实例变量。

尝试改变它:

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate, MKMapViewDelegate>

    CLLocationManager *locationManager;
    IBOutlet MKMapView *mapView;

实施中:

@synthesize city, state
...
- (void)setCity:(NSString *)c andState:(NSString *)s

    [self setCity:c];
    [self setState:s];
    NSLog(@"Location 2: %@, %@", city, state);

您将不需要额外的保留语句,因为该属性会复制该值。您还必须确保调用 self.cityself.state 来获取值。

【讨论】:

是的,那些额外的保留是希望防止数据被清除。那么如何获取城市和州信息以在我的 MKAnnotation 中使用?无论我如何构造它,completionHandler 块似乎都是在代码中运行的最后一件事。 谢谢,大卫。我最终没有为城市和州的财产而烦恼。我刚刚通过以下方式将信息发送到 MapPoint:[NSString stringWithFormat:@"%@, %@",[placemark locality], [placemark AdministrativeArea]]; @DavidV,与您的答案相关的新手问题。 mapView 的更新不是必须在主线程上执行,因为它会影响 UIView 吗?

以上是关于使用 CLGeocoder 将城市和州信息添加到 MKAnnotation的主要内容,如果未能解决你的问题,请参考以下文章

从 CLGeocoder 获取当前城市和国家?

通过 Zip Google Geocode Api 查找城市和州 [关闭]

如何使用 JavaScript 和 AJAX 根据邮政编码自动填充城市和州?

自动检测位置(城市和州),并将该信息分别放入输入和选择字段

城市和州或国家/地区的 Python 当前时间

当城市名称等于某个国家/地区的名称(不仅如此)时,CLGeocoder 返回错误的结果