Search code examples
iosswiftios9cllocationreversegeocodelocation

Sort a list by distance using reversed Geolocation


I'm using Xcode 7 with iOS9. I want to sort a list ascending, based on distance from users current location to all other locations in the list.

I don't want to calculate the distance to a location by coordinates, but by address because the distance depends on the choosen method (drive / walk). All I want to do is save the address in each location object to calculate the distance to that object later on.

When initializing the list with objects I'm doing this request in each object's initializer:

let location = CLLocation(latitude: latitude, longitude: longitude) //changed!!!

CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in 
    //the code to obtain an address and save it in a location object is here and works
}

The problem I have now is that I have to send 172 such reverseGeocodeLocation requests as my list contains 172 objects and I need to calculate the distance from my users location to each object's location.

Sending so many requests so fast results in this error: The operation couldn’t be completed. (kCLErrorDomain error 2.)

Is there a way to solve this? If things aren't clear tell me please so I can clarify


Solution

  • I finally found the answer myself with help of some comments here.

    At the moment, the only distance that can be retrieved using Apple Maps API is the straight line distance between coordinates. However if you want to calculate real distances between two addresses or coordinates you can do it with the Google Maps Distance Matrix API by sending a simple request.

    Example:

    Calculate the distance from: 51.226531,4.190688
    to 51.114476,4.139618 and 51.148123,4.182590.

    You can simply do this with this API call: https://maps.googleapis.com/maps/api/distancematrix/json?origins=51.226531,4.190688&destinations=51.114476,4.139618|51.148123,4.182590

    Notice i'm using 3 parameters:
    json: the format in which I want the result to be returned
    origins: the coordinates/address where you start
    destinations: multiple coordinates/addresses seperated by " | "

    This is the result from the call:

    {
      "destination_addresses" : [
      "Dorpstraat 70, 9140 Temse, België",
      "Eigenlostraat 38, 9100 Sint-Niklaas, België"
    ],
    "origin_addresses" : [ "Provinciale Baan 37, 9120 Beveren, België" ],
    "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16,3 km",
                  "value" : 16346
               },
               "duration" : {
                  "text" : "22 min.",
                  "value" : 1321
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "10,5 km",
                  "value" : 10521
               },
               "duration" : {
                  "text" : "17 min.",
                  "value" : 1003
               },
               "status" : "OK"
            }
         ]
      }
    ],
    "status" : "OK" 
    }
    

    If things aren't clear, ask me!