2015-02-25 22 views
5

Sto cercando di tracciare il percorso tra due punti sulla mappa Apple (codice Swift). la seguente struttura viene utilizzata per memorizzare le coordinateVisualizza percorso sulla mappa in Swift

struct GeoLocation { 
    var latitude: Double 
    var longitude: Double 

    func distanceBetween(other: GeoLocation) -> Double { 
     let locationA = CLLocation(latitude: self.latitude, longitude: self.longitude) 
     let locationB = CLLocation(latitude: other.latitude, longitude: other.longitude) 
     return locationA.distanceFromLocation(locationB) 
    } 
} 

self.foundLocations - is an array of these structures 

Nella classe personalizzata ricevo le coordinate dei punti sulla mappa.

var coordinates = self.foundLocations.map{$0.coordinate} 

Poi ho disegnare il percorso sulla mappa

self.polyline = MKPolyline(coordinates: &coordinates, count: coordinates.count) 
     self.mapView.addOverlay(self.polyline, level: MKOverlayLevel.AboveRoads) 

Per disegnare il percorso che uso il seguente metodo da MKMapViewDelegate

func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! { 
    if let polylineOverlay = overlay as? MKPolyline { 
     let render = MKPolylineRenderer(polyline: polylineOverlay) 
     render.strokeColor = UIColor.blueColor() 
     return render 
    } 
    return nil 
} 

Al posto del percorso attuale, che su strade che ricevo solo una linea retta tra due punti. Come posso visualizzare il percorso attuale?

risposta

6

In realtà è necessario recuperare il percorso dal server delle mappe di Apple utilizzando calculateDirectionsWithCompletionHandler.

Innanzitutto creare le pertinenti MKMapItem s sia per l'origine e la destinazione, ad esempio: (. Ripetere per destinazione)

let geocoder = CLGeocoder() 
let location = CLLocation(latitude: sourceLatitude, longitude: sourceLongitude) 

geocoder.reverseGeocodeLocation(location, completionHandler: { 
     (placemarks:[AnyObject]?, error:NSError?) -> Void in 
     if placemarks?.count > 0 { 
      if let placemark: MKPlacemark = placemarks![0] as? MKPlacemark { 
       self.source = MKMapItem(placemark: placemark) 
      } 
     } 
     }) 

Poi prendere il MKRoute, es:

let request:MKDirectionsRequest = MKDirectionsRequest() 

// source and destination are the relevant MKMapItems 
request.setSource(source) 
request.setDestination(destination) 

// Specify the transportation type 
request.transportType = MKDirectionsTransportType.Automobile; 

// If you're open to getting more than one route, 
// requestsAlternateRoutes = true; else requestsAlternateRoutes = false; 
request.requestsAlternateRoutes = true 

let directions = MKDirections(request: request) 

directions.calculateDirectionsWithCompletionHandler ({ 
    (response: MKDirectionsResponse?, error: NSError?) in 

    if error == nil { 
     self.directionsResponse = response 
     // Get whichever currentRoute you'd like, ex. 0 
     self.route = directionsResponse.routes[currentRoute] as MKRoute 
    } 
}) 

Quindi, dopo aver recuperato lo MKRoute, è possibile aggiungere la polilinea alla mappa in questo modo:

mapView.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads) 
+0

si può vedere questo errore si prega di http://stackoverflow.com/questions/30775154/error-400-mentre-aggiunta-percorso-on-mkmapview? noredirect = 1 # comment49605946_30775154 –

0

Swift 3 e la conversione riutilizzabile della risposta di Lyndsey Scott:

final class Route { 

    static func getRouteFor(
     source: CLLocationCoordinate2D, 
     destination: CLLocationCoordinate2D, 
     completion: @escaping (

     _ route: MKRoute?, 
     _ error: String?)->() 

     ) { 

     let sourceLocation = CLLocation(

      latitude: source.latitude, 
      longitude: source.longitude 

     ) 

     let destinationLocation = CLLocation(

      latitude: destination.latitude, 
      longitude: destination.longitude 

     ) 

     let request = MKDirectionsRequest() 

     self.getMapItemFor(location: sourceLocation) { sourceItem, error in 

      if let e = error { 

       completion(nil, e) 

      } 

      if let s = sourceItem { 

       self.getMapItemFor(location: destinationLocation) { destinationItem, error in 

        if let e = error { 

         completion(nil, e) 

        } 

        if let d = destinationItem { 

         request.source = s 

         request.destination = d 

         request.transportType = .walking 

         let directions = MKDirections(request: request) 

         directions.calculate(completionHandler: { response, error in 

          if let r = response { 

           let route = r.routes[0] 

           completion(route, nil) 

          } 

         }) 

        } 

       } 

      } 

     } 

    } 

    static func getMapItemFor(
     location: CLLocation, 
     completion: @escaping (

     _ placemark: MKMapItem?, 
     _ error: String?)->() 

     ) { 

     let geocoder = CLGeocoder() 

     geocoder.reverseGeocodeLocation(location) { placemark, error in 

      if let e = error { 

       completion(nil, e.localizedDescription) 

      } 

      if let p = placemark { 

       if p.count < 1 { 

        completion(nil, "placemark count = 0") 

       } else { 

        if let mark = p[0] as? MKPlacemark { 

         completion(MKMapItem(placemark: mark), nil) 

        } 

       } 

      } 

     } 

    } 

} 

Usage:

Route.getRouteFor(source: CLLocationCoordinate2D, destination: CLLocationCoordinate2D) { (MKRoute?, String?) in 
     <#code#> 
} 
Problemi correlati