Looking for business name information from coordinates using CLLocation and/or Mapkit

902 views Asked by At

I'm trying to use coordinates returned using CLLocationManager to see if they are a close match for any local business - if I happened to be standing in a Starbucks for example, I would want my app to suggest that based on my coordinates I was standing in Starbucks. If I was 20 metres outside Starbucks, but it was the closest address to where I was standing, I would want it to suggest 'Starbucks'.

I can return CLPlacemarks no problem, but the information they contain does not contain the business name anywhere. I am in the UK, so, for example, Nando's on the Gloucester Road in London has an address of '170 Gloucester Road, London, SW7 4ST'. I can return 170 Gloucester Road, London, SW7 4ST in the CLPlacemark info no problem, but nowhere does it mention Nando's.

I read in various posts that the info might in the name property, or area of interest or even within the formatted address property, but my extensive testing in Central London suggests that isn't the case, in the UK at any rate. Even in the US, "Apple Inc" is only mentioned within its address's formatted address property before 1 Infinite Loop.

I tried to accomplish this instead by getting the user's coordinates using CLLocation and then using them as a basis for a programmatic MapKit search - this just returns the address again, not a business name.

Having also done a bit of end-user testing of the Apple Maps app, which I am otherwise a huge fan of, it seems to return fairly incomplete results if searching locally generally for e.g. 'bar', 'restaurant'. Some local places are included, others aren't, sometimes the results contain places which are quite far away, even though I know that there are many more restaurants in the immediate vicinity.

I am fast concluding the only way to achieve what I want is to use the Google Places API, which I was hoping to avoid for a number or reasons, not least my considerable lack of experience at iOS programming (in Swift btw...)

If anyone can definitively advise that there is no way to do this natively in Mapkit and that I need to use Google Places API, then at least I know, and can just get on with it - but if there is a way, I would be most grateful to know what it is...

thanks in advance!

2

There are 2 answers

2
Francisco Medina On

I have encounter similar issues with MapKit, and after a while found that Google places API is much better for this kind of task check this link to find sample code on how to use Google Places to get current location

Basically you'll need to

-Install Google places SDK

-Import Google maps to your class

import GoogleMaps

-Add a places client on class

var placesClient: GMSPlacesClient?

-Init your places client probably on your viewDidLoad()

placesClient = GMSPlacesClient()

-And add this code where you need it to search for the current place

placesClient!.currentPlaceWithCallback({ (placeLikelihoods, error) -> Void in
  if error != nil {
    print("Current Place error: \(error.localizedDescription)")
    return
  }

  for likelihood in placeLikelihoods.likelihoods {
    if let likelihood = likelihood as? GMSPlaceLikelihood {
      let place = likelihood.place
      print("Current Place name \(place.name) at likelihood \(likelihood.likelihood)")
      print("Current Place address \(place.formattedAddress)")
      print("Current Place attributions \(place.attributions)")
      print("Current PlaceID \(place.placeID)")
    }
  }
})

Notes about the likelihood values:

The likelihood provides a relative probability of the place being the best match within the list of returned places for a single request. You can't compare likelihoods across different requests. The value of the likelihood will be between 0 and 1.0. The sum of the likelihoods in a returned array of GMSPlaceLikelihood objects is always less than or equal to 1.0. Note that the sum isn't necessarily 1.0. For example, to represent a 55% likelihood that the correct place is Place A, and a 35% likelihood that it's Place B, the likelihood array has two members: Place A with a likelihood of 0.55 and Place B with a likelihood of 0.35.

You also have the chance to use GMSPlacePicker, which can help a lot if you want your users to hace a chance to pick their current place.

1
Adrian Harris in London On

further to Francisco's very helpful answer, this is the tweak I had to make to currentPlaceWithCallback - I removed : GMSPlaceLikelihoodList! which had given the following error: cannot convert value of type GMSPlaceLikelihoodList to expected argument type....

This is the corrected code:

    placesClient!.currentPlaceWithCallback({ (placeLikelihoods, error) -> Void in
        if error != nil {
            print("Current Place error: \(error!.localizedDescription)")
            return
        }

        for likelihood in placeLikelihoods!.likelihoods {
            if let likelihood = likelihood as? GMSPlaceLikelihood {
                let place = likelihood.place
                print("Current Place name \(place.name) at likelihood \(likelihood.likelihood)")
                print("Current Place address \(place.formattedAddress)")
                print("Current Place attributions \(place.attributions)")
                print("Current PlaceID \(place.placeID)")


            }
        }

})