使用MapKit在Swift 5中绘制由坐标点组成的折线。

5

我有一个CLLocationCoordinate2D数组,需要从数组的第一个索引连接到最后一个索引并绘制一条线。

我已经看过这里和其他地方的答案,但它们大多是针对旧版本的Swift,或者针对首先将字符串数组转换为双精度或其他类型,或仅针对单个位置。

我尝试创建MKPolyline、viewForOverlay等,但无法使线显示出来。我错过了什么?

let locationManager = CLLocationManager()
let regionRadius: CLLocationDistance = 3000
var locations: [CLLocationCoordinate2D] = []
var latitude: [CLLocationDegrees] = []
var longitude: [CLLocationDegrees] = []

override func viewDidLoad() {
        super.viewDidLoad()
        mapView.delegate = self
        mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
        createAnnotations()
        centerMapOnLocation(location: initialLocation)
        var polyline = MKPolyline(coordinates: &locations, count: locations.count)
        mapView.addOverlay(polyline)
    }
    // MARK: - Create Annotaions
    func createAnnotations() {
        locations = zip(latitude, longitude).map(CLLocationCoordinate2D.init)
        AppLogger.logInfo("\(locations)")
        for location in locations {
            let annotation = MKPointAnnotation()
            annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)
            mapView.addAnnotation(annotation)
        }
    }
    // MARK: - Region Zoom
    func centerMapOnLocation(location: CLLocation) {
        let coordinateRegion = MKCoordinateRegion(center: location.coordinate,
                                                  latitudinalMeters: regionRadius,
                                                  longitudinalMeters: regionRadius)
      mapView.setRegion(coordinateRegion, animated: true)
    }
    // MARK: - Draw Polylines
    func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        if (overlay is MKPolyline) {
            let pr = MKPolylineRenderer(overlay: overlay)
            pr.strokeColor = UIColor.blue.withAlphaComponent(0.5)
            pr.lineWidth = 5
            return pr
        }
        return nil
    }

预期输出:从位置数组中我们实际上绘制了所行驶的路线。这不是一个获取方向的方法,因为行驶已经完成。

2个回答

11

使用Swift 5

首先,您需要声明一个MKPolyline,其中包含您的CLLocationCoordinate2D数组:

let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline)

然后在您的MKMapViewDelegate上,您需要像以下示例中那样为您的折线添加颜色:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {

    if let routePolyline = overlay as? MKPolyline {
        let renderer = MKPolylineRenderer(polyline: routePolyline)
        renderer.strokeColor = UIColor.mySpecialBlue().withAlphaComponent(0.9)
        renderer.lineWidth = 7
        return renderer
    } 

    return MKOverlayRenderer()
}

通过这种方法,您将能够重新创建类似于以下内容的东西: Urbvan App


0

首先,确认你的locations是否为空数组。

其次,viewForOverlay是一个已经不再使用的旧方法(即使当时,该方法签名也是不正确的)。

相反,将创建渲染器的代码放在rendererFor中:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    ...
}

嘿,Rob!我可以通过调试器确认数组不为空。它最初是双精度浮点数,但我将它们转换为CLLocationCoordinate2D数组。在返回nil时出现错误。如果我返回MKOverlayRenderer,也会出现错误,类型为MKOverlayRenderer.Type的表达式。 - mikalooch
奇怪!!...我得到了覆盖层,但它绘制的路线是错误的。它似乎是从位置而不是位置索引开始绘制。这意味着它似乎是绘制到最接近的点...可能不是数组中下一个实际点。该数组是一次驾车从起点到终点的所有位置。我将进行一些调查。 - mikalooch
关于您的调试信息,非常感谢。实际上,鉴于您的上一个问题,我已经做出了这样的假设,但是为了那些没有看到过的未来读者,我还是必须提及一下。当您提供“期望输出”时,如果您能够分享“实际输出”也是非常好的。 ;) - Rob
知道了!嘿,你有什么想法它为什么会把“路径”画错?我知道叠加层并不是实际路径的表示,但它似乎连接最接近的标注而不是按索引标注。想象一下在一个单向街区行驶,而折线告诉你你开错了方向...哈哈! - mikalooch
重新排序不是您预期的,我敢打赌数组中的顺序是在折线中呈现的顺序。它是非常强大的机制,不会对您进行重新排序。我想知道您是否有一些临时无序结构(例如使用字典或集合,添加数据的顺序并不重要,生成的集合是无序的,即可能以任何顺序出现)。如果您找不到它,请分享一个最小但可重现的示例 - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接