How to draw line between two annotations in map view swift ios? - ios

let latitude = NSUserDefaults.standardUserDefaults().doubleForKey(klat)
let longitude = NSUserDefaults.standardUserDefaults().doubleForKey(klong)
let location = CLLocationCoordinate2DMake(latitude, longitude)
// Second Location lat and long
let latitudeSec: CLLocationDegrees = 10.0100
let longitudeSec: CLLocationDegrees = 76.3620
let locationSec = CLLocationCoordinate2DMake(latitudeSec, longitudeSec)
let span = MKCoordinateSpanMake(1, 1)
let region = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
I have two locations(lat and long) with two annotations. I need to know how to draw the line between these two annonations on MKMap?

Create an array of [CLLocationCoordinate2D], convert to MKPolyline and add to map.
If you have a CLLocation could get CLLocationCoordinate2D from CLLocation.coordinate
In your case...
let pointArry = [location, locationSec]
let myPolyline = MKPolyline(coordinates: pointArray, count: pointArray.count)
mapView.addOverlay(myPolyline)
//MARK: MKMapViewDelegate Method (make sure class has been set as delegate)
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay.isKind(of: MKPolyline.self) {
// draw the track
let polyLine = overlay
let polyLineRenderer = MKPolylineRenderer(overlay: polyLine)
polyLineRenderer.strokeColor = UIColor.blue
polyLineRenderer.lineWidth = 2.0
return polyLineRenderer
}
return MKPolylineRenderer()
}

Related

MapKit: Route not being displayed between two annotations

Im trying to display a route between two annotations.
The annotations and the region work fine but the route won't show up and I have no idea why
It looks like the route is not being rendered at all.
I'm sure that the route exists because I tried to print it and it is in the directionResponse.routes
Any suggestions?
I'm using SwiftUI
Then this is included in a parent view.
import SwiftUI
import MapKit
import FirebaseFirestore
struct MapView: UIViewRepresentable {
var packageLocation: GeoPoint
var destination: GeoPoint
var driverLocation = CLLocationCoordinate2D()
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
MKMapView()
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolygonRenderer(overlay: overlay)
renderer.strokeColor = .blue
renderer.lineWidth = 2.0
return renderer
}
func updateUIView(_ uiView: MKMapView, context: UIViewRepresentableContext<MapView>) {
let requestLocation: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: packageLocation.latitude, longitude: packageLocation.longitude)
let destinationLocation: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: destination.latitude, longitude: destination.longitude)
//let span = MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)
//let region = MKCoordinateRegion(center: requestLocation, span: span)
//uiView.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = requestLocation
annotation.title = "Package Title"
uiView.addAnnotation(annotation)
let annotation2 = MKPointAnnotation()
annotation2.coordinate = destinationLocation
annotation2.title = "Destiantion"
uiView.addAnnotation(annotation2)
let sourcePlacemark = MKPlacemark(coordinate: requestLocation)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlacemark)
directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate { (response, error) in
guard let directionResponse = response else {
if let error = error {
print(error.localizedDescription)
}
return
}
print(directionResponse)
let route = directionResponse.routes[0]
uiView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
uiView.setRegion(MKCoordinateRegion(rect), animated: true)
}
}
}
You've almost got it.
The one issue that you need to resolve is the use of the MKMapView delegate functions.
The easiest way to do that is to subclass MKMapView and make your own map view that has conforms to MKMapViewDelegate.
Firstly, create your own map view, subclassing MKMapView and conforming to MKMapViewDelegate. At the moment you're only really using the rendererFor overlay delegate method so I'll just implement that, but you can add other methods if you require them.
class WrappableMapView: MKMapView, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .red
renderer.lineWidth = 4.0
return renderer
}
}
Then you need to update your UIViewRepresentable to use the new WrappableMapView that you just created. I have gone for making a functional example, so here I am passing in the request and destination locations. You can handle this how you want but at least this will give you something that works.
struct MyMapView: UIViewRepresentable {
#Binding var requestLocation: CLLocationCoordinate2D
#Binding var destinationLocation: CLLocationCoordinate2D
private let mapView = WrappableMapView()
func makeUIView(context: UIViewRepresentableContext<MyMapView>) -> WrappableMapView {
mapView.delegate = mapView // make sure we set our delegate to be the mapView we just created
return mapView
}
func updateUIView(_ uiView: WrappableMapView, context: UIViewRepresentableContext<MyMapView>) {
let requestAnnotation = MKPointAnnotation()
requestAnnotation.coordinate = requestLocation
requestAnnotation.title = "Package Title"
uiView.addAnnotation(requestAnnotation)
let destinationAnnotation = MKPointAnnotation()
destinationAnnotation.coordinate = destinationLocation
destinationAnnotation.title = "Destination"
uiView.addAnnotation(destinationAnnotation)
let requestPlacemark = MKPlacemark(coordinate: requestLocation)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: requestPlacemark)
directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate { response, error in
guard let response = response else { return }
let route = response.routes[0]
uiView.addOverlay(route.polyline, level: .aboveRoads)
let rect = route.polyline.boundingMapRect
uiView.setRegion(MKCoordinateRegion(rect), animated: true)
// if you want insets use this instead of setRegion
// uiView.setVisibleMapRect(rect, edgePadding: .init(top: 50.0, left: 50.0, bottom: 50.0, right: 50.0), animated: true)
}
}
}
Finally we can put it all together with a ContentView that shows it works:
struct ContentView: View {
#State var requestLocation = CLLocationCoordinate2D(latitude: 51.509865, longitude: -0.118092)
#State var destinationLocation = CLLocationCoordinate2D(latitude: 51.501266, longitude: -0.093210)
var body: some View {
MyMapView(requestLocation: $requestLocation, destinationLocation: $destinationLocation)
}
}
This is what it should look like:
One thing to note, using the rendererFor overlay delegate function in the simulator causes an error. This only happens in the simulator and not on device, so don't be surprised if you see an error message like this in the console.
2019-11-08 18:50:30.034066+0000 StackOverflow[80354:9526181] Compiler error: Invalid library file

MKMapView - Show Customizable Gridlines

I want these lines to be visible on a regular map in such a way where each square represents 1x1m.
I looked into MKTileOverlay but didn't find too much about it. Is it possible to show the gridline on the map as well as change the color?
I've done something very similar for an app I've been playing around with. Mine is for putting a coloured grid over a map so that there are 15 columns and rows in a square mile around a home location, so you'll need to adjust the calculations for your distances but the same general approach should work. The app is only a prototype at the moment, and hasnt been optimised (could refactor code out of viewDidLoad for a start!), but the code should be good enough to get you started.
var homeLocation: CLLocationCoordinate2D!
let metresPerMile = 1609.344
var degPerHorizEdge: Double!
var degPerVertEdge: Double!
override func viewDidLoad() {
homeLocation = CLLocationCoordinate2D(latitude: 53.7011, longitude: -2.1071)
let hd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude + 1, longitude: homeLocation.longitude))
let vd = CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude).distance(from: CLLocation(latitude: homeLocation.latitude, longitude: homeLocation.longitude + 1))
let degPerHMile = 1 / (hd / metresPerMile)
let degPerVMile = 1 / (vd / metresPerMile)
degPerHorizEdge = degPerHMile / 15
degPerVertEdge = degPerVMile / 15
super.viewDidLoad()
let gridController = GridController(for: gameID!)
gridController.delegate = self
let mapSize = CLLocationDistance(1.2 * metresPerMile)
let region = MKCoordinateRegion(center: homeLocation, latitudinalMeters: mapSize, longitudinalMeters: mapSize)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.showsBuildings = true
mapView.mapType = .standard
mapView.setRegion(region, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let overlays = prepareOverlays() {
mapView.addOverlays(overlays)
}
}
func prepareOverlays() -> [MKPolygon]? {
let topLeft = CLLocationCoordinate2D(latitude: homeLocation.latitude - 7.5 * degPerHorizEdge, longitude: homeLocation.longitude - degPerVertEdge * 7.5)
var overlays = [MKPolygon]()
var locations = [CLLocationCoordinate2D]()
for y in 0...14 {
for x in 0...14 {
locations.append(CLLocationCoordinate2D(latitude: topLeft.latitude + Double(x) * degPerHorizEdge, longitude: topLeft.longitude + Double(y) * degPerVertEdge))
}
}
for coord in locations.enumerated() {
let location = coord.element
var corners = [location, //has to be a var due to using pointer in next line
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude),
CLLocationCoordinate2D(latitude: location.latitude + degPerHorizEdge, longitude: location.longitude + degPerVertEdge),
CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude + degPerVertEdge)]
let overlay = MKPolygon(coordinates: &corners, count: 4)
overlay.title = "\(coord.offset)"
overlays.append(overlay)
}
return overlays.count > 0 ? overlays : ni
}
//MARK:- MKMapViewDelegate
extension MapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// overlay is a WSW zone
if let polygon = overlay as? MKPolygon {
let renderer = MKPolygonRenderer(polygon: polygon)
renderer.strokeColor = UIColor.gray.withAlphaComponent(0.4)
renderer.fillColor = UIColor.orange.withAlphaComponent(0.5)
renderer.lineWidth = 2
return renderer
}
// overlay is a line segment from the run (only remaining overlay type)
else {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue.withAlphaComponent(0.8)
renderer.lineWidth = 3
return renderer
}
}
}

Swift 3 Firebase to MapKit

I am looking to get data from a Firebase Database into a map. I have a good amount working but am stuck. This is all 100% code, no storyboards.
What I have below works. It will show all pins on a map but I am stuck at that point. I want to be able to tap each pin and get the data for that particular pin. When I do, using the code below I will print out "tap" and the array for MTA.
The data could be shown in a pin annotation/info window or in labels below the map in the View Controller. I am unsure of where to put the code/get it to work. I assume not in the for snap in snapshot but I cannot get the data out for each individual record/pin.
View did load for reference:
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
self.navigationItem.title = stop
mapContainerView.delegate = self
view.addSubview(mapContainerView)
setUpContorller()
fetchTrip()
}
Function to get coordinates for map:
func fetchTrip(){
let ref = FIRDatabase.database().reference()
let tripsRef = ref.child("Trips").child(stop!)
tripsRef.observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
let tripSnap = snap as! FIRDataSnapshot
if let dict = tripSnap.value as? [String:AnyObject] {
let lat = dict["lat"] as! CLLocationDegrees
let lng = dict["lng"] as! CLLocationDegrees
let MTA = dict["MTAStop"] as! String
let center = CLLocationCoordinate2D(latitude: lat, longitude: lng)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.08, longitudeDelta: 0.08))
self.stopMTA.append(MTA)
self.mapContainerView.setRegion(region, animated: true)
let pinCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat, lng)
let annotation = MKPointAnnotation()
annotation.coordinate = pinCoordinate
self.mapContainerView.addAnnotation(annotation)
}
}
})
}
Function to tap pin: (I know I need more.. not sure what, possibly a class to hold the data.)
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
// do something
print("tap")
print(stopMTA)
}
Here is an example of the database from simulator testing.
Thanks in advance!
Using MKPointAnnotation() will only place a pin on the map. You need to use a custom class to hold the annotation information and call it with initializers.
Original:
let annotation = MKPointAnnotation()
annotation.coordinate = pinCoordinate
self.mapContainerView.addAnnotation(annotation)
Working version:
let annotation = PinAnnotation(title: MTA, coordinate: pinCoordinate, info: MTA)
annotation.coordinate = pinCoordinate
self.mapContainerView.addAnnotation(annotation)
Also Need:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
}
and
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
}

Draw polyline using Swift

I'm trying to get an understanding of how to draw polylines using Swift. I've looked at the documentation, referenced some tutorials, and checked out some other SO posts, but I still can't get the thing to draw a line on my map. Here's my code. Anyone tell me what I'm doing wrong here?
import UIKit
import MapKit
class FirstViewController: UIViewController {
#IBOutlet weak var map: MKMapView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let location = CLLocationCoordinate2D(
latitude: -73.761105,
longitude: 41.017791
)
let span = MKCoordinateSpanMake(0.07, 0.07)
let region = MKCoordinateRegion(center: location, span: span)
map.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.setCoordinate(location)
annotation.title = "White Plains"
annotation.subtitle = "Westchester County"
map.addAnnotation(annotation)
var locations = [CLLocation(latitude: -73.761105, longitude: 41.017791), CLLocation(latitude: -73.760701,longitude: 41.019348), CLLocation(latitude: -73.757201, longitude: 41.019267), CLLocation(latitude: -73.757482, longitude: 41.016375), CLLocation(latitude: -73.761105, longitude: 41.017791)]
var coordinates = locations.map({(location: CLLocation!) -> CLLocationCoordinate2D in return location.coordinate})
var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
self.map.addOverlay(polyline)
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 5
return polylineRenderer
}
return nil
}
}
Thanks!
Here MKGeodesicPolyline will solve your problem. Add object of MKGeodesicPolyline instead of MKPolyline.
In your code remove below two lines:
let polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
map.add(polyline)
And add these lines:
let geodesic = MKGeodesicPolyline(coordinates: coordinates, count: 2)
map.addOverlay(geodesic)
Swift 5.0:
func createPolyline(mapView: MKMapView) {
let point1 = CLLocationCoordinate2DMake(-73.761105, 41.017791);
let point2 = CLLocationCoordinate2DMake(-73.760701, 41.019348);
let point3 = CLLocationCoordinate2DMake(-73.757201, 41.019267);
let point4 = CLLocationCoordinate2DMake(-73.757482, 41.016375);
let point5 = CLLocationCoordinate2DMake(-73.761105, 41.017791);
let points: [CLLocationCoordinate2D]
points = [point1, point2, point3, point4, point5]
let geodesic = MKGeodesicPolyline(coordinates: points, count: 5)
map.addOverlay(geodesic)
UIView.animate(withDuration: 1.5, animations: { () -> Void in
let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
let region1 = MKCoordinateRegion(center: point1, span: span)
self.map.setRegion(region1, animated: true)
})
}
Objective C code:
- (void) createGeoPolyline {
CLLocationCoordinate2D point1 = { -73.761105, 41.017791 };
CLLocationCoordinate2D point2 = { -73.760701, 41.019348 };
CLLocationCoordinate2D point3 = { -73.757201, 41.019267 };
CLLocationCoordinate2D point4 = { -73.757482, 41.016375 };
CLLocationCoordinate2D point5 = { -73.761105, 41.017791 };
CLLocationCoordinate2D points[] = {point1, point2, point3, point4, point5};
MKGeodesicPolyline *geodesic = [MKGeodesicPolyline polylineWithCoordinates:&points[0] count:5];
[self.mapView addOverlay:geodesic];
[UIView animateWithDuration:1.5 animations:^{
MKCoordinateRegion region;
region.center = point1;
MKCoordinateSpan span;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
region.span = span;
[self.mapView setRegion:region animated:YES];
}];
}
Above Objective C code works perfect and it will show overlay below:
But if you try Swift code it will not. I tried as much as I can to solve it out but It won't change. May be it is bug from MapKit framework.
UPDATE: This seems to be fixed on Swift 3+. See accepted answer.
On this line:
var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
You're casting a Swift array reference as an UnsafePointer<CLLocationCoordinate2D>.
That's pretty dangerous and I'm not sure why Swift allows it to compile. Best case scenario you get the line drawn, worse case (which seems to be your case) you get nothing.
The MKPolyline constructors wants an UsafePointer<CLLocationCoordinate2D> and that's what you should pass.
I usually add a private category to MKPolyline to create a convenience init method that accepts a normal Swift array:
private extension MKPolyline {
convenience init(coordinates coords: Array<CLLocationCoordinate2D>) {
let unsafeCoordinates = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(coords.count)
unsafeCoordinates.initializeFrom(coords)
self.init(coordinates: unsafeCoordinates, count: coords.count)
unsafeCoordinates.dealloc(coords.count)
}
}
Create polyline on apple map :
import MapKit
import CoreLocation
<CLLocationManagerDelegate,MKMapViewDelegate>
Code
self.mapView.delegate = self
var coordinateArray: [CLLocationCoordinate2D] = []
let destination1 = CLLocationCoordinate2DMake(22.3039, 70.8022)
let destination2 = CLLocationCoordinate2DMake(23.0225, 72.5714)
coordinateArray.append(destination1)
coordinateArray.append(destination2)
let polygon = MKPolyline(coordinates: coordinateArray, count: coordinateArray.count)
self.mapView.addOverlay(polygon)
Delegate Method
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay.isKind(of: MKPolyline.self){
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.fillColor = UIColor.blue
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return MKOverlayRenderer(overlay: overlay)
}

Polyline Overlay in Swift

I have my MKMapViewDelegate in place. Also, MapView.delegate = self
let c1 = myCLLocationCoodinate
let c2 = myCLLocationCoodinate2
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
self.MapView.addOverlay(polyline)
With this Delegate Method:
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.whiteColor()
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return nil
}
I get this: EXC BAD ACCESS Thread 8 on
self.MapView.addOverlay(polyline)
I think issue here is with the line:
var a = [c1, c2]
Here you directly created array without specifying its type.
See below reference code to create Polyline overlay and related delegate method:
let c1 = myCLLocationCoodinate
let c2 = myCLLocationCoodinate2
var points: [CLLocationCoordinate2D]
points = [c1, c2]
var geodesic = MKGeodesicPolyline(coordinates: &points[0], count: 2)
mapView.add(geodesic)
UIView.animate(withDuration: 1.5, animations: { () -> Void in
let span = MKCoordinateSpanMake(20, 20)
let region1 = MKCoordinateRegion(center: c1, span: span)
mapView.setRegion(region1, animated: true)
})
A delegate method to render overlay:
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.whiteColor()
polylineRenderer.lineWidth = 2
return polylineRenderer
}
return nil
}
It seems that your map view has been deallocated. The polyline construction is OK.
Normally, variables start with lowercase. Have you subclassed the map view and are trying to access the class?
I spent WAAAAAAAAYYYY too much time on this so I thought I would add the solution to a similar issue. I was getting a EXC BAD ACCESS on addOverlay w/ a MKPolygon. Turns out I was just on the wrong thread the whole time. Fixed it with:
var points = [MKMapPoint]()
for var i = 0; i < area.coordinates.count; i+=2 {
let c = CLLocationCoordinate2DMake(area.coordinates[i], area.coordinates[i+1])
points.append(MKMapPointForCoordinate(c))
}
let polygon = MKPolygon(points: &points, count: points.count)
dispatch_async(dispatch_get_main_queue(), {
self.mapView.addOverlay(polygon)
})
let firstlat : string = "12.9166"
let firstlon : string = "77.6101"
let secondlat : string = "12.9610"
let secondLon : string = "77.6387"
let point1 = CLLocationCoordinate2DMake(Double(firstlat)!, Double(firstlon)!)
let point2 = CLLocationCoordinate2DMake(Double(secondlat as String)!, Double(secondLon)!)
let pickAnnotation : MKPointAnnotation = MKPointAnnotation()
pickAnnotation.coordinate = point1
pickAnnotation.title = "pick"
displayMapView.addAnnotation(pickAnnotation)
let dropAnnotation : MKPointAnnotation = MKPointAnnotation()
dropAnnotation.coordinate = point2
dropAnnotation.title = "drop"
displayMapView.addAnnotation(dropAnnotation)
displayMapView.showAnnotations(displayMapView.annotations, animated: true)
var points: [CLLocationCoordinate2D]
points = [point1, point2]
routeLine = MKPolyline(coordinates: &points[0] , count: 2)
displayMapView.add(routeLine)
func showRouteOnMap(_ pickCoordinate: CLLocationCoordinate2D, _ destinationCoordinate: CLLocationCoordinate2D) {
let request = MKDirections.Request()
let sourcePlacemark = MKPlacemark(coordinate: pickCoordinate)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
request.source = sourceMapItem
let myPlacemark = MKPlacemark(coordinate: destinationCoordinate)
let destinationMapItem = MKMapItem(placemark: myPlacemark)
request.destination = destinationMapItem
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
directions.calculate(completionHandler: {(response, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let response = response {
self.showRoute(response)
}
}
})
}
func showRoute(_ response: MKDirections.Response) {
for route in response.routes {
routeMap.addOverlay(route.polyline,
level: MKOverlayLevel.aboveRoads)
self.routeMap.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor(red: 17.0/255.0, green: 147.0/255.0, blue: 255.0/255.0, alpha: 1)
renderer.lineWidth = 5.0
return renderer
}

Resources