2

我需要使用 CLGeocoder而非Google API 对大量地址进行地理编码。

我的问题是我的代码只是为下面数组中的第一个地址添加注释。但是,该函数被调用了适当的次数 -在为所有地址调用该函数之后,该块仅针对第一个地址运行:

- (void)mapPoints {
    NSString *foo = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"names%d", self.indexOfSchool] ofType:@"plist"];
    NSArray *description = [NSArray arrayWithContentsOfFile:foo];
    NSString *bar = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%d1", self.indexOfSchool] ofType:@"plist"];
    NSArray *details = [NSArray arrayWithContentsOfFile:bar];

    NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%d0", self.indexOfSchool] ofType:@"plist"];
    NSArray *addresses = [NSArray arrayWithContentsOfFile:path];
    self.saved = [NSMutableArray alloc] init];
    for (int q = 0; q < addresses.count; q+= 20) {
        [self annotate:[addresses objectAtIndex:q] detail:[details objectAtIndex:q] andDesc:[description objectAtIndex:q]];
    }
}

see updated annotate: method below...

以下是我的日志的显示方式:

here
here
here
here
.
..
...
....
<MKPointAnnotation: 0x16fc12e0>

因此,尽管该函数是通过循环调用的,但该块并未针对除第一个结果之外的任何结果运行。

我知道我的地址很好。这不适用于任何数量 (>1) 的函数调用。+= 20in 循环与仅绘制一个点无关:这对任何一个都不起作用(++也有大约 200 个结果)。

我对块相当陌生,所以希望这是一个简单的修复。任何帮助是极大的赞赏!

编辑 这样做:

- (void)annotate:(NSString *)address detail:(NSString *)detail andDesc:(NSString *)description {
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder geocodeAddressString:address
             completionHandler:^(NSArray* placemarks, NSError* error) {
                 if (placemarks && placemarks.count > 0) {
                     CLPlacemark *topResult = [placemarks objectAtIndex:0];
                     MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
                     MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
                     point.coordinate = placemark.coordinate;
                     point.title = description;
                     point.subtitle = [NSString stringWithFormat:@"%@ miles from origin", detail];
                     MKCoordinateRegion region = self.directionsView.region;
                     region.center = [(CLCircularRegion *)placemark.region center];
                     region.span.longitudeDelta /= 8.0;
                     region.span.latitudeDelta /= 8.0;
                     [self.directionsView addAnnotation:point];
                     NSLog(@"%@", point);
                     [self.directionsView setRegion:region animated:YES];
                 }
             }
 ];
    [self.saved addObject:geocoder];
    NSLog(@"%@", geocoder);
}

...仍然拉出没有注释的空白地图 - 甚至不是第一个。每次调用该函数时,地理编码器数组具有不同的内存地址,因此该部分似乎正在工作。

4

4 回答 4

5

您连续几次调用 geocodeAddressString,但苹果的文档说

发起正向地理编码请求后,不要尝试发起另一个正向或反向地理编码请求。

所以我认为正在发生的事情是当你提出一个新请求时当前请求被取消,或者如果一个新请求已经在进行中,则所有新请求都被忽略。

作为一种解决方法,您可以对一个点进行地理编码,然后对完成块中的下一个点进行地理编码或创建地理编码器的多个实例

于 2013-11-07T14:40:04.013 回答
3

每个CLGeocoder对象一次只能处理一个请求。尝试在您的方法中创建一个新CLGeocoder对象,annotate而不是重用存储在属性中的单个对象。只要您启用了 ARC,就应该没问题。

请注意,Apple 可能会限制您发送到其服务器的同时请求的数量,因此如果您执行大量请求,您可能需要限制未完成请求的数量。

于 2013-11-07T14:39:50.597 回答
1

无论您有多少实例,您一次只能运行一个地理编码请求CLGeocoder。您将不得不从前一个请求的完成块开始另一个请求。

另外,请注意,在短时间内对太多地址进行地理编码将达到其内部限制。在我的实验中,大约 50 个请求(一个接一个)之后,框架拒绝在接下来的大约 60 秒内处理新请求。

于 2013-11-07T14:51:49.567 回答
-2

这是一个 Xamarin 伪代码,但它应该在本机中工作,因为我必须首先转换为 C#:

forloop()
{
    var geocoder = new CLGeocoder();
    var placemarks = await geocoder.GeocodeAddressAsync(address);
}
于 2017-09-20T09:40:33.393 回答