Sort list by distance using reverse geolocation

I am using Xcode 7 with iOS9. I want to sort the list in ascending order based on the distance from the current location of users to all other places in the list.

I do not want to calculate the distance to the place by coordinates, but by address, because the distance depends on the chosen method (drive / walk). All I want to do is save the address in each location object, so that I can calculate the distance to this object later.

When initializing a list with objects, I make this request in each object 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 } 

Now the problem is that I have to send 172 such reverseGeocodeLocation requests, since my list contains 172 objects, and I need to calculate the distance from my users location to each location of the object.

Sending so many requests so quickly leads to this error: The operation could not be completed. (error kCLErrorDomain 2.)

Is there any way to solve this? If something is not clear, please tell me so that I can clarify

+5
source share
2 answers

I finally found the answer with some comments here.

Currently, the only distance that can be obtained using the Apple Maps API is the distance between the lines between the coordinates. However, if you want to calculate the real distances between two addresses or coordinates, you can do this using the Google Distance Matrix APIs by sending a simple request.

Example:

Calculate 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

Please note that I use 3 parameters:
json: format in which I want the result to be returned
origins: coordinates / address where you start: destinations: multiple coordinates / addresses separated by "|"

This is the result of 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 everything is not clear, ask me!

+1
source

Apple geocoding is not intended for bulk geocoding. See the CLGeocoder class CLGeocoder in Xcode for more information. Brief excerpt:

Applications need to understand how they use geocoding. Geocoding requests are limited in speed for each application, so making too many requests in a short period of time may cause some requests to fail . (When the maximum speed is exceeded, the geocoder returns an error object with a value of kCLErrorNetwork to the appropriate completion handler.) Here are some rules of thumb for using this class effectively:

Send no more than one geocoding request for any user action.

If the user performs several actions related to geocoding, location, reuse of the results from the initial geocoding request, starting individual requests for each action.

If you want to automatically update the current location of users (for example, when the user is moving), issue new geocoding requests when the user has moved a considerable distance and after a reasonable amount of time has passed. For example, in a typical situation, you should not send more than one geocoding request per minute .

(Emphasis added by me.)

The summary is that you cannot do what you are trying to do with the Apple CLGeocoder class.

You should only submit one geocoding request for user action, and then, as a rule, no more than one geocoding request per minute.

You will need to license a third-party geocoding service (and possibly pay for it) in order to perform bulk geocoding or reverse geocoding.

+3
source

Source: https://habr.com/ru/post/1238962/


All Articles