CLGeocoder ever returns a single label

I want to revive this and this question because the problem is still persisting for me writing a new question.

This is my code:

- (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; } 

This is my personal version (rather crude) of SVGeocoder using CLGeocoder for direct geocoding with retro-resistance for iOS <5.1

I use this solution because of Google’s conditions that prevent the use of the map APIs without displaying the result on a Google map.

The problem is the same as in the previous questions: CLGeocoder returns only one label, and the journal prints nice

"tags [count] = 1".

My question is, does anyone know if there is another way to get preliminary geocoding or some other magic thing (Apple map application shows several markers for the same request, for example "via roma")?


EDIT FOR ROB SOLUTIONS

 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); }]; } 

This is an interesting solution that gives a different point of view. Unfortunately, even if I set a region around the world, I still get a good magazine

response.mapItems [count] = 1

The request was β€œvia roma”, which is a very common street name in Italy, so much so that I think we can find it in almost any Italian city.

Maybe I'm doing something wrong?


EDIT 2 - new test:

convert World Rect to CLRegion, code from here

  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); }]; 

... and I get the usual "label [count] = 1"

+7
source share
2 answers

Obviously, CLGeocoder will return multiple labels if the address receives multiple hits (i.e. the area is large enough for a simple street address to be ambiguous), but often it will find only one match if the area is small enough or if the specified address is unique enough.

Although this is not a general purpose, efficient iOS 6.1 solution, you have MKLocalSearch that does a more general search (including company names, etc.):

 MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; request.region = self.mapView.region; request.naturalLanguageQuery = textField.text; MKLocalSearch *localsearch = [[MKLocalSearch alloc] initWithRequest:request]; [localsearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) { for (MKMapItem *item in response.mapItems) { Annotation *annotation = [[Annotation alloc] initWithPlacemark:item.placemark]; annotation.title = item.name; annotation.phone = item.phoneNumber; annotation.subtitle = item.placemark.addressDictionary[(NSString *)kABPersonAddressStreetKey]; [self.mapView addAnnotation:annotation]; } }]; 

I assume that it all depends on what kind of few hits you expect to receive.

+5
source

There are several addresses for which CLGeocoder returns multiple labels. One example I found is Herzel 13, Haifa, Israel. I use the geocodeAddressDictionary:completionHandler: method and get the same 2 results for the address (it can be set either as street / city / country or as street - the results are the same).

It’s just hard to find such examples, and they may change in the future, of course. For some reason, the Apple maps application displays the "Did you mean ..." dialog for many other addresses.

0
source

All Articles