【问题标题】:How to draw a route between two locations using MapKit in Swift?如何在 Swift 中使用 MapKit 在两个位置之间绘制路线?
【发布时间】:2015-03-28 16:34:13
【问题描述】:

如何在 Swift 中使用 MapKit 绘制用户当前位置到特定位置之间的路线

我搜索了很多,但没有找到任何有用的 Swift 特定链接或教程。

【问题讨论】:

  • 搜索 MKDirectionsRequest、addOverlay 和 rendererForOverlay。每个都有关于 SO 的 Swift 示例。
  • 感谢您的帮助。但实际上我没有为 Swift 找到任何有价值的结果。你有什么结果或例子我可以从它开始吗?
  • 使用谷歌搜索 SO——答案就在这里。否则,请查看这些类和方法的文档,编写一些代码,尝试一下。
  • 我将链接到一个教程,该教程展示了如何在 Swift 中做到这一点:Ray Wenderlich: Overlays in MapKit 这应该涵盖了您需要的内容。

标签: ios iphone swift 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多