如何在 Swift 中使用 MapKit 在两个位置之间绘制路线?
Posted
技术标签:
【中文标题】如何在 Swift 中使用 MapKit 在两个位置之间绘制路线?【英文标题】:How to draw a route between two locations using MapKit in Swift? 【发布时间】:2015-03-28 16:34:13 【问题描述】:如何在 Swift 中使用 MapKit 绘制用户当前位置到特定位置之间的路线?
我搜索了很多,但没有找到任何有用的 Swift 特定链接或教程。
【问题讨论】:
搜索 MKDirectionsRequest、addOverlay 和 rendererForOverlay。每个都有关于 SO 的 Swift 示例。 感谢您的帮助。但实际上我没有为 Swift 找到任何有价值的结果。你有什么结果或例子我可以从它开始吗? 使用谷歌搜索 SO——答案就在这里。否则,请查看这些类和方法的文档,编写一些代码,尝试一下。 签出这个***.com/questions/26563854/… 我将链接到一个教程,该教程展示了如何在 Swift 中做到这一点:Ray Wenderlich: Overlays in MapKit 这应该涵盖了您需要的内容。 【参考方案1】:斯威夫特 4
class MapController: UIViewController, MKMapViewDelegate
// MARK: - showRouteOnMap
func showRouteOnMap(pickupCoordinate: CLLocationCoordinate2D, destinationCoordinate: CLLocationCoordinate2D)
let sourcePlacemark = MKPlacemark(coordinate: pickupCoordinate, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationCoordinate, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let sourceAnnotation = MKPointAnnotation()
if let location = sourcePlacemark.location
sourceAnnotation.coordinate = location.coordinate
let destinationAnnotation = MKPointAnnotation()
if let location = destinationPlacemark.location
destinationAnnotation.coordinate = location.coordinate
self.mapView.showAnnotations([sourceAnnotation,destinationAnnotation], animated: true )
let directionRequest = MKDirectionsRequest()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .automobile
// Calculate the direction
let directions = MKDirections(request: directionRequest)
directions.calculate
(response, error) -> Void in
guard let response = response else
if let error = error
print("Error: \(error)")
return
let route = response.routes[0]
self.mapView.add((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor(red: 17.0/255.0, green: 147.0/255.0, blue: 255.0/255.0, alpha: 1)
renderer.lineWidth = 5.0
return renderer
【讨论】:
嘿,我使用的是相同的代码,但它不会用蓝线为我绘制路径 请不要忘记使用这个函数 // MARK: - MKMapViewDelegate func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer let renderer = MKPolylineRenderer(overlay: overlay) 渲染器.strokeColor = UIColor(red: 17.0/255.0, green: 147.0/255.0, blue: 255.0/255.0, alpha: 1) renderer.lineWidth = 5.0 return renderer 你必须使用 MKMapViewDelegate 和 func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer 你会发现 renderer.strokeColor = UIColor(red: 17.0/255.0, green: 147.0/255.0 , blue: 255.0/255.0, alpha: 1) 并使 renderer.lineWidth = 5.0 可见 如果有人按照@AbdelrahmanMohamed的步骤没有出现路线,可能需要添加mapView.delegate = self。顺便说一句,为什么这个答案还没有被标记为解决方案? @PoojaGupta 我相信你可以缩小缩放范围【参考方案2】:class MapController: UIViewController, MKMapViewDelegate
func showRouteOnMap()
let request = MKDirectionsRequest()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: annotation1.coordinate, addressDictionary: nil))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: annotation2.coordinate, addressDictionary: nil))
request.requestsAlternateRoutes = true
request.transportType = .Automobile
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler [unowned self] response, error in
guard let unwrappedResponse = response else return
if (unwrappedResponse.routes.count > 0)
self.mapView.addOverlay(unwrappedResponse.routes[0].polyline)
self.mapView.setVisibleMapRect(unwrappedResponse.routes[0].polyline.boundingMapRect, animated: true)
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer!
if overlay is MKPolyline
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 5
return polylineRenderer
return nil
返回的是一个可能的路由数组,通常我们只想显示第一个。注解为地图注解。
【讨论】:
从 Swift 2 开始,你不能在 rendererForOverlay 中返回 nil。而是返回 MKPolylineRenderer()。【参考方案3】:Swift 5 + 扩展基于 bdelrahman Mohamed 的回答
extension MKMapView
func showRouteOnMap(pickupCoordinate: CLLocationCoordinate2D, destinationCoordinate: CLLocationCoordinate2D)
let sourcePlacemark = MKPlacemark(coordinate: pickupCoordinate, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationCoordinate, addressDictionary: nil)
let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
let sourceAnnotation = MKPointAnnotation()
if let location = sourcePlacemark.location
sourceAnnotation.coordinate = location.coordinate
let destinationAnnotation = MKPointAnnotation()
if let location = destinationPlacemark.location
destinationAnnotation.coordinate = location.coordinate
self.showAnnotations([sourceAnnotation,destinationAnnotation], animated: true )
let directionRequest = MKDirections.Request()
directionRequest.source = sourceMapItem
directionRequest.destination = destinationMapItem
directionRequest.transportType = .automobile
// Calculate the direction
let directions = MKDirections(request: directionRequest)
directions.calculate
(response, error) -> Void in
guard let response = response else
if let error = error
print("Error: \(error)")
return
let route = response.routes[0]
self.addOverlay((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.setRegion(MKCoordinateRegion(rect), animated: true)
【讨论】:
【参考方案4】:覆盖 func viewDidLoad() super.viewDidLoad()
mapView.delegate = self
let sourceLocation = CLLocationCoordinate2D(latitude: 22.4649, longitude: 69.0702)
let destinationLocation = CLLocationCoordinate2D(latitude: 23.0225, longitude: 72.5714)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let sourceRegion = MKCoordinateRegion(center: sourceLocation, span: span)
mapView.setRegion(sourceRegion, animated: true)
let destinationRegion = MKCoordinateRegion(center: destinationLocation, span: span)
mapView.setRegion(destinationRegion, animated: true)
let sourcePin = MKPointAnnotation()
sourcePin.coordinate = sourceLocation
mapView.addAnnotation(sourcePin)
let destinationPin = MKPointAnnotation()
destinationPin.coordinate = destinationLocation
mapView.addAnnotation(destinationPin)
let sourcePlacemark = MKPlacemark(coordinate: sourceLocation, addressDictionary: nil)
let destinationPlacemark = MKPlacemark(coordinate: destinationLocation, addressDictionary: nil)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlacemark)
directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate (response, error) in
guard let response = response else
if let error = error
print("Error: \(error)")
return
let route = response.routes[0]
self.mapView.addOverlay((route.polyline), level: MKOverlayLevel.aboveRoads)
let rect = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegion(rect), animated: true)
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.red
renderer.lineWidth = 4.0
return renderer
【讨论】:
以上是关于如何在 Swift 中使用 MapKit 在两个位置之间绘制路线?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 2 MapKit Annotations - 如何对注释进行分组?
如何使用 mapkit 和 swift 在设定的位置覆盖一个圆圈