xcode8swift4reverse-geocodingclplacemark

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!


Solution

  • 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))
    
    
    }