关于iPhone:CLGeocoder地理编码无可救药

CLGeocoder geocoding is hopelessly inaccurate

我有一个应用程序,该应用程序进行地理编码(获取给定地址的坐标)以在MKMapView上显示一堆引脚。在iOS支持使用CLGeocoder进行正向地理编码之前(iOS 5中首次提供),该应用程序开发良好。因此,我的应用使用的是Google Maps Geocoding API,通常非常准确。给定完整的地址和街道编号,通常会在两米之内为您提供该地址的确切位置。

我正在对我的应用程序进行一些更新以支持iOS 6,并决定从使用Google API切换为使用CLGeocoder,前提是该应用程序在iOS 5或更高版本上运行。但是,在我的测试中(所有地址都是我居住的葡萄牙的地址),它是如此不准确,以致完全无法使用。

我使用的是– geocodeAddressString:completionHandler:,例如,给定地址"葡萄牙里斯本,自由大道195号",它给我的是辛特拉市的"自由大道",而不是里斯本(里斯本)。距真实地址约15公里。自由大道(Avenida da Liberdade)是里斯本最大和最知名的大街之一。相当于纽约第五大道。这不是一些晦涩的小街。

我有什么不对的地方可以得到如此糟糕的准确性?其他人是否存在类似的准确性问题,尤其是在美国境外的地址?

目前看来,我将不得不坚持使用Google Maps API。顺便说一句,我一直在使用iOS 6模拟器,结果没有更好的结果。将相同的搜索字符串放入iOS 6 Maps应用程序的搜索框中会得到完全相同的结果。

编辑:添加CLGeocoder代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    CLGeocoder *fgeo = [[[CLGeocoder alloc] init] autorelease];
    NSLog(@"Geocoding for Address: %@\
", address);
    [fgeo geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
        if (!error) {
            // do stuff with the placemarks

            for (CLPlacemark *placemark in placemarks) {
                NSLog(@"%@\
 %.2f,%.2f",[placemark description], placemark.location.horizontalAccuracy, placemark.location.verticalAccuracy);
            }
        } else {
            NSLog(@"Geocoding error: %@", [error localizedDescription]);
        }
    }];

编辑2:我发现,如果我使用– geocodeAddressDictionary:completionHandler:并通过地址字典传递街道地址,邮政编码(邮政编码)和我能提供的尽可能多的详细信息,它会给我相当准确的坐标,但仍然精度半径超过400m,这是不可接受的。


好吧,看来,是的,Apple的CLGeocoder不能像Google Maps Geocoding API一样对正向地理编码(地址->坐标)准确,尤其是在美国境外。 使用地址字典并尽可能完整地填充所有字段的效果比简单的地址字符串要好得多,但是仍然远远不够。 如果您幸运的话,Google通常会在街道编号5-10m内给您坐标,而苹果会在正确的街道上给您坐标。

编辑:
找到了Apple开发人员技术说明TN2289,其中详细说明了CLGeocoder的受支持国家/地区。 葡萄牙似乎在其部分支持的地区的列表中,其描述为:

The following are territories are not fully supported, either because coverage is more limited or for other reasons. For example a location may only be able to be geocoded to road level as opposed to a specific address point on that road.

这使我的结果与葡萄牙的CLGeocoder匹配。 我想我只需要等待改善的覆盖范围即可。