Spartakus
Spartakus

Reputation: 69

Swift ReverseGeocode CLPlacemark areasOfInterest almost always nil. Should I be using something else?

I am using CLGeocoder and reverseGeocodeLocation to get my CLPlacemark. How come the name mostly comes back as an address and areasOfInterest come back as nil? For example... the areasOfInterest appear for really major things like apple HQ and airports, things of that sort but stores such as Walmart, Publix blah blah are nil. Should I be searching another way? Am I expecting more information than is available with this method? I mean, Apple has these points of interest on their maps, is there another way I should be trying to get this information?

Here are a few location lat longs that I've tried in my area that aren't bringing back the store names. These came from google and when put into apple maps, it beings you right on top of the correct location but it doesn't associate either... This makes me think I should be doing something different to being back the name of the store. Other info like a description or category would be nice as well.

Note: I am only wanting the information, I am not trying to place it on a map or anything.

Walmart: 35.0944° N, 85.3319° W

Aquarium: 35.0558° N, 85.3111° W

Publix: 35.0651° N, 85.3083° W

Small bit of my code. All works just wanted to give you an adea of what im bringing back and how.

CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
                if placemarks != nil
                {
                    if error == nil && placemarks!.count >= 1 {
                        let thePlacemarks = placemarks![0] as CLPlacemark
                        print(placemarks)
                        print(thePlacemarks.areasOfInterest?.description)
                        print(thePlacemarks.administrativeArea?.description)
                        print(thePlacemarks.areasOfInterest?.description)
                        print(thePlacemarks.country?.description)
                        print(thePlacemarks.inlandWater?.description)
                        print(thePlacemarks.isoCountryCode?.description)
                        print(thePlacemarks.locality?.description)
                        print(thePlacemarks.location?.description)
                        print(thePlacemarks.name?.description)
                        print(thePlacemarks.ocean?.description)
                        print(thePlacemarks.subAdministrativeArea?.description)
                        print()
                    }
                }
            })

Any help would be great!

Thanks!

Upvotes: 0

Views: 504

Answers (1)

Spartakus
Spartakus

Reputation: 69

So... Not necessarily ideal but by using mapkit I was able to do a MKLocalSearch to get what I wanted. This only works because I have an array in my code of the specific locations I am interested in. See me code below.

Import Mapkit
let listArr = ["Walmart", "Publix","Game Stop"]

Then somewhere in your ViewController

func searchArr() //This function will iterate through the array and see if any of the locations are within 30 meters
{
    for element in listsArr
    {
          let request = MKLocalSearchRequest()
          request.naturalLanguageQuery = "\(element)"
          request.region = MKCoordinateRegionMakeWithDistance(currentCoordinates, 3200, 3200)
          MKLocalSearch(request: request).start { (response, error) in

              guard error == nil else {print()return}
              guard let response = response else {return}
              guard response.mapItems.count > 0 else {return}
              print(response.mapItems[0])
              let coord1 = currentCoordinates
              let coord2 = response.mapItems[0].placemark.coordinate
              let distance = self.calculateDistance(fromlat: currentCoordinates.latitude, fromlon: currentCoordinates.longitude, tolat: response.mapItems[0].placemark.coordinate.latitude, tolon: response.mapItems[0].placemark.coordinate.longitude)

          if distance > 30
          {
               print("the distance between the two points is: \(distance) meters")

          }            
      }
}

Here is a little function I found to get the distance between two coordinates.

func calculateDistance(fromlat : Double, fromlon : Double, tolat : Double, tolon : Double) -> Double {

    let  DEG_TO_RAD = 0.017453292519943295769236907684886
    let  EARTH_RADIUS_IN_METERS = 6372797.560856

    let latitudeArc : Double   = (fromlat - tolat) * DEG_TO_RAD
    let longitudeArc : Double  = (fromlon - tolon) * DEG_TO_RAD
    var latitudeH : Double   = sin(latitudeArc * 0.5)
    latitudeH  *= latitudeH
    var lontitudeH : Double  = sin(longitudeArc * 0.5)
    lontitudeH *= lontitudeH
    let tmp : Double  = cos(fromlat*DEG_TO_RAD) * cos(tolat*DEG_TO_RAD)
    return EARTH_RADIUS_IN_METERS * 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH))


}

Upvotes: 1

Related Questions