地图上的多个位置(使用MKMapItem和CLGeocoder)

时间:2013-01-07 12:12:26

标签: ios cocoa-touch clgeocoder mkmapitem

我正在尝试在MKMapItem中显示多个位置。我从CLGeocoder获取这些位置,不幸的是它只接受一个位置。即使我传入NSArray,它也会返回一个位置。

以下适用于单个位置,但不适用于多个位置。我如何对多个位置进行地理编码?

Class mapItemClass = [MKMapItem class];
if (mapItemClass && [mapItemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
    NSArray *addresses = @[@"Mumbai",@"Delhi","Banglore"];

    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:@[addresses] completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0];
        MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:geocodedPlacemark.location.coordinate addressDictionary:geocodedPlacemark.addressDictionary];
        MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
        [mapItem setName:geocodedPlacemark.name];

        [MKMapItem openMapsWithItems:@[mapItem] launchOptions:nil];
    }];
}

2 个答案:

答案 0 :(得分:13)

在回答您的问题时,您是正确的,您一次只能发送一个地理编码请求。事实上,CLGeocoder Class Reference表示我们的应用程序应该为任何一个用户操作发送最多一个地理编码请求。"

因此,要执行此操作,您必须发送单独的请求。但是这些请求(异步运行)不应该同时运行。因此,问题是如何使一系列异步地理编码请求一个接一个地顺序运行。

有很多不同的解决方法,但一种特别优雅的方法是使用并发的NSOperation子类,它不能完成操作(即不执行{{ 1}} KVN)直到调用地理编码请求的异步完成块。 (有关并发操作的信息,请参阅并发编程指南Operation Queue章节中的配置并发执行操作部分)。然后只需将这些操作添加到串行操作队列中。

另一种方法是使此异步地理编码请求以同步方式运行,然后您可以将请求添加到串行队列,并且请求将按顺序执行而不是并行执行。您可以通过使用信号量来实现此目的,有效地指示调度任务在地理编码请求完成之前不返回。你可以这样做:

isFinished

或者,您也可以使用更传统的模式。例如,您可以编写一个执行单个地理编码请求的方法,并在完成块中启动下一个请求,并重复该过程,直到完成所有请求。

答案 1 :(得分:0)

对于寻找Swift解决方案的人:

func getCoordinate( addressString : String, completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void ){
            let geocoder = CLGeocoder()
            geocoder.geocodeAddressString(addressString) { (placemarks, error) in
                if error == nil {
                    if let placemark = placemarks?[0] {
                        let location = placemark.location!
                        completionHandler(location.coordinate, nil)
                        return
                    }
                }

                completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
            }
        }

感谢Apple。官方文件link

您可以通过以下方式将代码段用于多个地址:

let address = ["India","Nepal"]

for i in 0..<address.count {
 getCoordinate(addressString: address[i], completionHandler: { (location, error) in
                //Do your stuff here. For e.g. Adding annotation or storing location
      })

}