Giuseppe Puglisi
Giuseppe Puglisi

Reputation: 503

Draw route in mapView for an array of CLLocation (Swift)

how can i make a route in mapview for an array of CLLocation? i create a polyline and i want create a route by walking. this is my code:

@IBAction func addPolyline(sender: AnyObject) {
    let locations = [CLLocation(latitude: annotazioni.objectAtIndex(0).coordinate.latitude, longitude:annotazioni.objectAtIndex(0).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(1).coordinate.latitude, longitude:annotazioni.objectAtIndex(1).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(2).coordinate.latitude, longitude:annotazioni.objectAtIndex(2).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(3).coordinate.latitude, longitude:annotazioni.objectAtIndex(3).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(4).coordinate.latitude, longitude:annotazioni.objectAtIndex(4).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(5).coordinate.latitude, longitude:annotazioni.objectAtIndex(5).coordinate.longitude ),
                     CLLocation(latitude: annotazioni.objectAtIndex(6).coordinate.latitude, longitude:annotazioni.objectAtIndex(6).coordinate.longitude )]
    addPolyLineToMap(locations)
}
func addPolyLineToMap(locations: [CLLocation!]){
    var coordinates = locations.map({ (location: CLLocation!) -> CLLocationCoordinate2D in
        return location.coordinate
    })
    let geodesic = MKGeodesicPolyline(coordinates: &coordinates, count: locations.count)
    mapView.addOverlay(geodesic)

}
func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {

    if (overlay is MKPolyline) {
        let pr = MKPolylineRenderer(overlay: overlay);
        pr.strokeColor = UIColor.blueColor().colorWithAlphaComponent(0.5);
        pr.lineWidth = 5;
        return pr;
    }

    return nil
}

Sorry for my bad english :D

Upvotes: 2

Views: 4347

Answers (2)

Taras
Taras

Reputation: 1909

it works for me.

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

Upvotes: 0

Code Different
Code Different

Reputation: 93191

You can ask for direction between each successive pair of locations using MKDirectRequest and MKDirections, get the route as a polyline and then draw it on your map.

MKDirection.routes is available in iOS 8 and later. Below is an example for walking around downtown New York City. You walk from the blue pin through all the green pins and stop at the red pin.

class MyPointAnnotation : MKPointAnnotation {
    var isStartingPoint = false
    var isEndingPoint = false
}

@IBAction func addPolyline(sender : AnyObject) {
    let locations = [
        CLLocation(latitude: 40.759011, longitude: -73.984472), // Times Square, Manhattan, NY 10036, United States
        CLLocation(latitude: 40.760920, longitude: -73.988665), // Palace Theater, 1564 7th Avenue & W 47th Street, New York, NY 10036, United States
        CLLocation(latitude: 40.761417, longitude: -73.977120), // The Museum of Modern Art, 11 West 53rd Street, New York, NY 10019, United States
        CLLocation(latitude: 40.756520, longitude: -73.973406), // Waldorf Astoria New York, 301 Park Avenue, New York, NY 10022, United States
        CLLocation(latitude: 40.748441, longitude: -73.985664), // Empire State Building, 350 5th Avenue, New York, NY 10118, USA
        CLLocation(latitude: 40.756359, longitude: -73.988873) // Madame Tussauds New York, 234 West 42nd Street, New York, NY 10036, United States
    ]

    self.mapView.region = MKCoordinateRegion(center: locations[0].coordinate, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))

    // Pins for the locations you want to visit
    for loc in locations.enumerate() {
        let point = MyPointAnnotation()
        point.coordinate = loc.element.coordinate
        point.title = "Point \(loc.index)"

        if loc.index == 0 {
            point.subtitle = "Starting point"
            point.isStartingPoint = true
        } else if loc.index == locations.count - 1 {
            point.subtitle = "Ending point"
            point.isEndingPoint = true
        }

        self.mapView.addAnnotation(point)
    }

    // Request directions from one point to the next
    dispatch_apply(locations.count - 1, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) { i in
        let sourcePlacemark      = MKPlacemark(coordinate: locations[i].coordinate, addressDictionary: nil)
        let destinationPlacemark = MKPlacemark(coordinate: locations[i+1].coordinate, addressDictionary: nil)

        let request = MKDirectionsRequest()
        request.source = MKMapItem(placemark: sourcePlacemark)
        request.destination = MKMapItem(placemark: destinationPlacemark)
        request.transportType = .Walking

        let directions = MKDirections(request: request)
        directions.calculateDirectionsWithCompletionHandler { response, error in
            guard error == nil else {
                print(error!)
                return
            }

            // Get the walking route as a polyline
            let polyline = response!.routes.first!.polyline
            self.mapView.addOverlay(polyline)
        }
    }
}

// MARK: -
// MARK: Map View Delegate
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if let point = annotation as? MyPointAnnotation {
        let view = MKPinAnnotationView(annotation: point, reuseIdentifier: "pointAnnotationView")
        view.canShowCallout = true

        // You walk from the blue pin through all the green pins and stop at the red pin
        if point.isStartingPoint {
            view.pinTintColor = UIColor.blueColor()
        } else if point.isEndingPoint {
            view.pinTintColor = UIColor.redColor()
        } else {
            view.pinTintColor = UIColor.greenColor()
        }

        return view
    }

    return nil
}

func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
    if (overlay is MKPolyline) {
        let pr = MKPolylineRenderer(overlay: overlay)
        pr.strokeColor = UIColor.blueColor().colorWithAlphaComponent(0.5)
        pr.lineWidth = 5
        return pr
    }

    return nil
}

Upvotes: 7

Related Questions