【问题标题】:"Name" of a CLPlacemarkCLPlacemark 的“名称”
【发布时间】:2012-09-13 04:01:02
【问题描述】:

我正在尝试了解 CLPlacemark 以及何时/如何为添加到地图的图钉标注创建信息。在几年前我在更多 iOS 3 开发中读到的内容之前,他们对地址进行了反向地理编码并构建了地址(街道、邮编、州等)。首先,我需要自己构建这个字符串吗?我试图找出如何获取某些已知事物的位置名称,例如在下面的代码中搜索苹果商店:

NSString *address = @"1 stockton, san francisco, ca";    
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
        [geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {

    [placemarks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSLog(@"obj description: %@", [obj description]);

        CLPlacemark *aPlacemark = (CLPlacemark *)obj;
        NSLog(@"%@", [aPlacemark.addressDictionary description]);
        NSLog(@"name: %@", ((CLPlacemark *)obj).name);
    }];
];

当我打印出描述时,我看到控制台说:

Apple Store, San Francisco, 1 Stockton St, San Francisco, CA  94108-5805, United States @ <+37.78584545,-122.40651752> +/- 100.00m, region (identifier <+37.78584545,-122.40652161> radius 18.96) <+37.78584545,-122.40652161> radius 18.96m

旧金山 Apple Store 商店的名称从何而来?我认为这将是 CLPlacemark.name 属性,但那是空的。所以在试图弄清楚 name 属性是如何创建的时,我发现:

        NSLog(@"%@", [aPlacemark.addressDictionary description]);

我得到输出:

City = "San Francisco";
Country = "United States";
CountryCode = US;
FormattedAddressLines =     (
    "Apple Store, San Francisco",
    "1 Stockton St",
    "San Francisco, CA  94108-5805",
    "United States"
);
PostCodeExtension = 5805;
State = California;
Street = "1 Stockton St";
SubAdministrativeArea = "San Francisco";
SubLocality = "Union Square";
SubThoroughfare = 1;
Thoroughfare = "Stockton St";
ZIP = 94108;

从这里,我只能看到,在 addressDictionary 的 FormattedAddressLines 键中,标题也在那里。

所以我想我的 2 个问题是:

1) 如果有位置(例如 Apple Store),我如何获取位置的名称?

2) 我是否需要再构建我的字符串,因为地址字典似乎已经为我做了这个?

谢谢!

【问题讨论】:

    标签: iphone clgeocoder


    【解决方案1】:

    您可以使用 AddressBookUI 框架中的 ABCreateStringWithAddressDictionary 函数从 CLPlacemark 的“addressDictionary”属性中获取地址字符串。

    【讨论】:

      【解决方案2】:

      要回答您的第一个问题,请使用 CLPlacemark 的 areasOfInterest 属性。

      至于第二个问题,这完全取决于您,以及您希望如何格式化字符串。如果您想使用来自addressDictionary 属性的字符串来构建它,那么一定要这样做。您可以挑选零件,并在完成处理程序中创建一个字符串。

      另外,您提到要创建注释以在地图上显示。我个人将 MKAnnotation 子类化,并使用它来快速创建要在地图上显示的注释。

      MyAnnotation.h

      #import <Foundation/Foundation.h>
      #import <MapKit/MapKit.h>
      
      @interface MyAnnotation : NSObject <MKAnnotation> {
          NSString *_name;
          NSString *_address;
          CLLocationCoordinate2D _coordinate;
      }
      
      @property (copy) NSString *name;
      @property (copy) NSString *address;
      @property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
      
      - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate;
      
      @end
      

      MyAnnotation.m

      #import "MyAnnotation.h"
      
      @implementation MyAnnotation
      @synthesize name = _name;
      @synthesize address = _address;
      @synthesize coordinate = _coordinate;
      
      - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate
      {
          if ((self = [super init])) {
              _name = [name copy];
              _address = [address copy];
              _coordinate = coordinate;
          }
          return self;
      }
      
      - (NSString *)title
      {
          return _name;
      }
      
      - (NSString *)subtitle
      {
          return _address;
      }
      
      @end
      

      声明一个 NSMutableArray 来保存所有注解,并在完成处理程序中抛出 initWithName:address:coordinate:,您可以快速获取可以添加到地图的注解数组。

      NSString *address = @"1 stockton, san francisco, ca";    
      CLGeocoder *geocoder = [[CLGeocoder alloc] init];
      [geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) 
      {
         NSMutableArray *annotationArray = [NSMutableArray array];
         for (CLPlacemark *aPlacemark in placemarks)
         {
            NSString *nameString = // Get your name from an array created by aPlacemark.areasOfInterest;
            NSString *addressString = // Put your address string info you get from the placemark here.
            CLLocationCoordinate2D coordinate = aPlacemark.location.coordinate;
            MyAnnotation *annotation = [[MyAnnotation alloc] initWithName:nameString address:addressString coordinate:coordinate];
            [annotationArray addObject:annotation];
         }
         // Now save annotationArray if you want to use it later
         // Add it to your MapView with [myMapView addAnnotations:annotationArray];
      }];
      

      希望对您有所帮助!

      【讨论】:

      • 你知道从那时起填充的 name 属性是什么吗?文档只是说它是地标的名称,它是只读的。该字段如何填充?
      • 该信息来自 Apple 的地理定位 API,所以我不确定他们从哪里得到的。从 iOS 6 开始,他们与几家不同的公司签订了协议,我无法进入,因为它仍处于保密协议之下。我敢肯定,在网上快速搜索会找到一个列表。话虽如此,我不确定您如何确定究竟是哪一个 Apple 用于获取信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多