2015-02-25 18 views
5

Harita üzerinde iki nokta arasındaki yolu çizmeye çalışıyorum (Swift code). aşağıdaki yapı koordinatları harita üzerinde noktalarının koordinatları alma özel bir sınıf olarak Ekrandaki yol haritasını görüntüle: 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 

saklamak için kullanılır.

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

O zaman olsun yollarda ben döşeme yerine gerçek rotanın

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 
} 

MKMapViewDelegate

aşağıdaki yöntemi kullanın rotayı çizmek için harita

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

rotayı çizmek iki nokta arasında sadece düz bir çizgi. Gerçek rotayı nasıl görüntüleyebilirim?

cevap

6

Aslında yolu, Apple'ın haritalarının sunucusundan calculateDirectionsWithCompletionHandler kullanarak getirmeniz gerekir.

Birinci kaynak ve hedef, eski hem de ilgili MKMapItem ler oluşturmak: (. Hedef için tekrarlayın)

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) 
      } 
     } 
     }) 

Sonra MKRoute getirme, örn:

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 
    } 
}) 

Daha sonra MKRoute'u aldıktan sonra, polyline'ı haritayı şu şekilde ekleyebilirsiniz:

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

bu hatayı görebilirsiniz lütfen http://stackoverflow.com/questions/30775154/hata-400-while-ekleme-rota-on-mkmapview? noredirect = 1 # comment49605946_30775154 –

0

Swift 3 ve Lyndsey Scott'un cevabın yeniden dönüşüm:

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) 

        } 

       } 

      } 

     } 

    } 

} 

Kullanımı:

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