我希望重新激活此问题和此问题,因为这个问题对我来说仍然存在,所以我要写一个新的问题。
这是我的代码:
- (SVGeocoder*)initWithParameters:(NSMutableDictionary*)parameters completion:(SVGeocoderCompletionHandler)block {
self = [super init];
self.operationCompletionBlock = block;
Class cl = NSClassFromString(@"CLGeocoder");
if (cl != nil)
{
if (self.geocoder_5_1 == nil) {
self.geocoder_5_1 = [[cl alloc] init];
}
NSString *address = [parameters objectForKey:kGeocoderAddress];
[self.geocoder_5_1 geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
SVPlacemark *placemark;
NSLog(@"placemarks[count] = %i", [placemarks count]);
for (CLPlacemark *mark in placemarks) {
placemark = [[SVPlacemark alloc] initWithPlacemark:mark];
[svplacemarks addObject:placemark];
}
self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
}];
}
else
{
self.operationRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://maps.googleapis.com/maps/api/geocode/json"]];
[self.operationRequest setTimeoutInterval:kSVGeocoderTimeoutInterval];
[parameters setValue:@"true" forKey:kGeocoderSensor];
[parameters setValue:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode] forKey:kGeocoderLanguage];
[self addParametersToRequest:parameters];
self.state = SVGeocoderStateReady;
}
return self;
}
这是我个人版本(相当粗糙)的SVGeocoder,它使用CLGeocoder进行正向地理编码,并对iOS<5.1进行了向后兼容处理。
我使用这种解决方案是因为谷歌条款禁止在不显示谷歌地图结果的情况下使用地图API。
问题与先前提到的问题相同:CLGeocoder仅返回一个地标,日志打印出漂亮的“placemarks [count] = 1”。
我的问题是,是否有其他检索正向地理编码的方法,或者其他神奇的事情(例如,苹果地图应用程序显示相同查询“通过罗马”的多个标记)?
编辑Rob的解决方案
Class mkLocalSearch = NSClassFromString(@"MKLocalSearch");
if (mkLocalSearch != nil)
{
NSString *address = [parameters objectForKey:kGeocoderAddress];
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.region = MKCoordinateRegionForMapRect(MKMapRectWorld);
request.naturalLanguageQuery = address;
MKLocalSearch *localsearch = [[MKLocalSearch alloc] initWithRequest:request];
[localsearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
SVPlacemark *placemark;
NSLog(@"response.mapItems[count] = %i", [response.mapItems count]);
for (MKMapItem *item in response.mapItems)
{
placemark = [[SVPlacemark alloc] initWithPlacemark:item.placemark];
[svplacemarks addObject:placemark];
}
self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
}];
}
这是一个有趣的解决方案,提供了另一个视角。不幸的是,即使我将区域设置为全球,我仍然得到了一个漂亮的日志。
查询是“via roma”,这是意大利非常常见的街道名称,以至于我认为我们在任何意大利城市都可以找到它。response.mapItems[count] = 1
也许我做错了什么?
编辑2 - 新测试:
将World Rect转换为CLRegion,代码来自这里。
NSString *address = [parameters objectForKey:kGeocoderAddress];
// make a conversion from MKMapRectWorld to a regular CLRegion
MKMapRect mRect = MKMapRectWorld;
MKMapPoint neMapPoint = MKMapPointMake(MKMapRectGetMaxX(mRect), mRect.origin.y);
MKMapPoint swMapPoint = MKMapPointMake(mRect.origin.x, MKMapRectGetMaxY(mRect));
float ewDelta= neMapPoint.x - swMapPoint.x;
float nsDelta= swMapPoint.y - neMapPoint.y;
MKMapPoint cMapPoint = MKMapPointMake(ewDelta / 2 + swMapPoint.x, nsDelta / 2 + neMapPoint.y);
CLLocationCoordinate2D neCoord = MKCoordinateForMapPoint(neMapPoint);
CLLocationCoordinate2D swCoord = MKCoordinateForMapPoint(swMapPoint);
CLLocationCoordinate2D centerCoord = MKCoordinateForMapPoint(cMapPoint);
CLLocationDistance diameter = [self getDistanceFrom:neCoord to:swCoord];
// i don't have the map like showed in the example so i'm trying to center the search area to the hypothetical center of the world
CLRegion *clRegion = [[CLRegion alloc] initCircularRegionWithCenter:centerCoord radius:(diameter/2) identifier:@"worldwide"];
[self.geocoder_5_1 geocodeAddressString:address inRegion: clRegion completionHandler:^(NSArray *placemarks, NSError *error) {
NSMutableArray *svplacemarks = [NSMutableArray arrayWithCapacity:1];
SVPlacemark *placemark;
NSLog(@"placemarks[count] = %i", [placemarks count]);
for (CLPlacemark *mark in placemarks) {
placemark = [[SVPlacemark alloc] initWithPlacemark:mark];
[svplacemarks addObject:placemark];
}
self.operationCompletionBlock([NSArray arrayWithArray:svplacemarks],nil,error);
}];
...然后我得到了通常的“placemark [count] = 1”
(这句话是关于it技术的)。
CLGeoCoder
还是MKLocalSearch
),我都只得到一个结果。我在德国的柏林,当搜索“San”时,我得到的是“圣地亚哥,加利福尼亚州”而不是“旧金山,加利福尼亚州”。我希望两者都能出现(地球上有很多“San…”)。 - Julian F. WeinertCLGeocoder
,我最多只能看到1或2个条目。它感觉像是一种“最佳猜测”方法,返回两三个条目。使用MKLocalSearch
,你会得到更多的结果(例如,在任何特定城市搜索“餐厅”,你会得到一个餐厅列表),但这并不是详尽的列表(稍微改变区域,你就可以得到非常不同的结果列表)。 - Rob