在Swift上显示地图上的路线
我试图绘制苹果地图(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
在自定义类中,我收到地图上点的坐标。
var coordinates = self.foundLocations.map{$0.coordinate}
然后我在地图上绘制路线
self.polyline = MKPolyline(coordinates: &coordinates, count: coordinates.count) self.mapView.addOverlay(self.polyline, level: MKOverlayLevel.AboveRoads)
为了绘制路线,我从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 }
而不是路上铺设的实际路线,我只能得到两点之间的直线。 我怎样才能显示实际的路线?
您实际上必须使用calculateDirectionsWithCompletionHandler
从Apple的地图服务器获取路线。
首先为源和目标创build相关的MKMapItem
,例如:
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) } } })
(重复目的地。)
然后取MKRoute
,例如:
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 } })
然后在检索MKRoute
,可以像下面这样将折线添加到地图中:
mapView.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
Swift 3和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) } } } } } }
用法:
Route.getRouteFor(source: CLLocationCoordinate2D, destination: CLLocationCoordinate2D) { (MKRoute?, String?) in <#code#> }