To put it in perspective, you need to first specify what "distance" are you looking for. If you are looking for simple Euclidean Distance then any of the other answers or using distanceFromLocation
would work. According to Apple's documentaion on distanceFromLocation
This method measures the distance between the two locations by tracing
a line between them that follows the curvature of the Earth. The
resulting arc is a smooth curve and does not take into account
specific altitude changes between the two locations.
This means, that the distance derived using this method will not be the actual route/transportation distance between two points.
If that is what you are looking for then head over to the answer I linked above, if not then keep reading (but either way, I encourage you to read the whole post :).
If you are looking for "route" distance (drivable, walkable etc.) between your location and the other annotations in the map, it's going to take little more work using MKRoute
object. To be more specific you need to first have access to the MKMapItem
objects of each of your annotations and then a custom method like below would be able to get the route info between two MapItem
objects.
Note - if you don't have MapItems
then you can create them just using the coordinates of each of your annotations, like so
ley myCoordinates CLLocationCoordinate2D(latitude: 25.647399800, longitude: -100.334304500)
let myPlacemark = MKPlacemark(coordinate: myCoordinates)
let myMapItem = MKMapItem(placemark: myPlacemark)
Define an MKRoute variable globally in your class (or ViewController class). This var
will hold the calculated Route information between two points.
var route: MKRoute!
and then
func getDistanceToDestination(srcMapItem srcmapItem: MKMapItem, destMapItem destmapItem: MKMapItem){
let request = MKDirectionsRequest() //create a direction request object
request.source = srcmapItem //this is the source location mapItem object
request.destination = destmapItem //this is the destination location mapItem object
request.transportType = MKDirectionsTransportType.automobile //define the transportation method
let directions = MKDirections(request: request) //request directions
directions.calculate { (response, error) in
guard let response = response else {
print(error.debugDescription)
return
}
self.route = response.routes[0] //get the routes, could be multiple routes in the routes[] array but usually [0] is the best route
}
}
Usage would be
self.getDistanceToDestination(srcMapItem: yourSourceMapItemObj, destMapItem: yourDestinationMapitemObj)
where yourSourceMapItemObj
and yourDestinationMapitemObj
are two MapItem
objects aka source and destination points.
And then you can access the distance using self.route.distance
to get the distance of the first best route returned by MKRoute
. There are a whole bunch of other properties for the MKRoute
object route
which you can use as well to display/calculate other things, and I encourage you to take a look at those too. You can use the function above to also draw a ployLine
i.e. a line showing the route between the two locations in the MapView
just by adding self.mapView.add(self.route.polyline)
in the end of the custom method above and then use the below MKMapViewDelegate
function below to render the polyline.
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let linerenderer = MKPolylineRenderer(overlay: self.route.polyline)
linerenderer.strokeColor = .blue
linerenderer.lineWidth = 3.5
return linerenderer
}
And finally, make sure your class (or your class extension) complies to CLLocationManagerDelegate
and MKMapViewDelegate
protocols and mapview delegate pointed to self
(which I assume you already do) in order for everything above to work.