mikalooch
mikalooch

Reputation: 91

MapKit Draw poly line from coordinates Swift 5

I have an array of CLLocationCoordinate2D, and need to draw a line connecting from the first index to the last index in the array.

I have seen the answers here and elsewhere, but they are mostly for older versions of swift, or for an array of strings that you first convert to doubles or whatever or for only a single location.

I have tried creating an MKPolyline, viewForOverlay, etc, but I am unable to get the line to show up. What am I missing?

let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 3000
var locations: [CLLocationCoordinate2D] = []
var latitude: [CLLocationDegrees] = []
var longitude: [CLLocationDegrees] = []

override func viewDidLoad() {
        super.viewDidLoad()
        mapView.delegate = self
        mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
        createAnnotations()
        centerMapOnLocation(location: initialLocation)
        var polyline = MKPolyline(coordinates: &locations, count: locations.count)
        mapView.addOverlay(polyline)
    }
    // MARK: - Create Annotaions
    func createAnnotations() {
        locations = zip(latitude, longitude).map(CLLocationCoordinate2D.init)
        AppLogger.logInfo("\(locations)")
        for location in locations {
            let annotation = MKPointAnnotation()
            annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
            mapView.addAnnotation(annotation)
        }
    }
    // MARK: - Region Zoom
    func centerMapOnLocation(location: CLLocation) {
        let coordinateRegion = MKCoordinateRegion(center: location.coordinate,
                                                  latitudinalMeters: regionRadius,
                                                  longitudinalMeters: regionRadius)
      mapView.setRegion(coordinateRegion, animated: true)
    }
    // MARK: - Draw Polylines
    func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        if (overlay is MKPolyline) {
            let pr = MKPolylineRenderer(overlay: overlay)
            pr.strokeColor = UIColor.blue.withAlphaComponent(0.5)
            pr.lineWidth = 5
            return pr
        }
        return nil
    }

Expected output: From the array of locations we essentially draw the route driven. It's not a get directions method as the drive was already taken.

Upvotes: 5

Views: 8594

Answers (2)

Daniel E. Salinas
Daniel E. Salinas

Reputation: 441

Using Swift 5

First you would need to declare a MKPolyline with your array of CLLocationCoordinate2D:

let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline)

Then on your MKMapViewDelegate you would need to add color to your polyline like in this example:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {

    if let routePolyline = overlay as? MKPolyline {
        let renderer = MKPolylineRenderer(polyline: routePolyline)
        renderer.strokeColor = UIColor.mySpecialBlue().withAlphaComponent(0.9)
        renderer.lineWidth = 7
        return renderer
    } 

    return MKOverlayRenderer()
}

With this approach you will be able to recreate something like this: Urbvan App

Upvotes: 11

Rob
Rob

Reputation: 437372

First, confirm whether your locations was empty array or not.

Second, the viewForOverlay is an old method that isn’t used any more (and even then, the method signature is incorrect).

Instead, put your code that creates the renderer in rendererFor:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    ...
}

Upvotes: 0

Related Questions