swiftgeolocationcore-location

Can geocodeAddressString function be made more accurate for landmarks and points of interest


Working with the geocodeAddressString function, it's possible to specify an address. But I have found it to be unreliable with landmarks, including well known ones like the Eiffel Tower in Paris, France. I have tried expanding the address to include more than just the landmarks name with both the city and country but it gives the same output when it matches.

geocoder.geocodeAddressString(addressString) { (placemarks, error) in
    if error == nil {
        if let placemark = placemarks?[0] {
            let location = placemark.location!
            completionHandler(CGFloat(250), CGFloat(250), location.coordinate, nil)
        }
    } else {
        print(addressString, error)
    }
}

A location is passed as a a string and the location should then be passed to the completionHandler, however not all landmarks will return the correct location.

For example, Wembley Stadium does work. The string passed is "Wembley Stadium, London" and the output of the location is:

+51.55695420,-0.27957620

For "Eiffel Tower, Paris" I actually get an error, but for "Eiffel Tower, Paris, France", the location is:

+48.85678790,+2.35107680

The Eiffel Tower's actual coordinates are 48.858200,2.294610 but it appears to be giving me the location of the city rather than for the landmark specified. I have seen there is the option to specify a region but I have not seen this to make any difference. Is there a way to make this lookup more accurate or to specify a landmark or point of interest is being searched for? There are also cases where a landmark's name matches that of a city (Anfield is an area of Liverpool and also the name of a stadium for example, same for Old Trafford in Manchester).


Solution

  • LocalSearch is much more accurate.

        let request : MKLocalSearch.Request = .init()
        request.region = region //The closer the region the more accurate the search is.
        request.naturalLanguageQuery = "Eiffel Tower, Paris"
    
        let search = MKLocalSearch(request: request)
        let results = try await search.start()
        let result = results.mapItems.first
    

    Results =

       "Eiffel Tower, Paris, France" (latitude: 48.8582583, longitude: 2.2944877)
    
       "Eiffel Tower, Paris" (latitude: 48.8582583, longitude: 2.2944877)
    
       "Wembley Stadium, London"  (latitude: 51.5560557, longitude: -0.2795251)