【问题标题】:Draw polyline using Swift使用 Swift 绘制折线
【发布时间】:2015-02-17 23:14:19
【问题描述】:

我正在尝试了解如何使用 Swift 绘制折线。我查看了文档,参考了一些教程,并查看了其他一些 SO 帖子,但我仍然无法在我的地图上画一条线。这是我的代码。有人告诉我我在这里做错了什么吗?

import UIKit
import MapKit

class FirstViewController: UIViewController {

    @IBOutlet weak var map: MKMapView!

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        let location = CLLocationCoordinate2D(
            latitude: -73.761105,
            longitude: 41.017791
        )

        let span = MKCoordinateSpanMake(0.07, 0.07)
        let region = MKCoordinateRegion(center: location, span: span)
        map.setRegion(region, animated: true)

        let annotation = MKPointAnnotation()
        annotation.setCoordinate(location)
        annotation.title = "White Plains"
        annotation.subtitle = "Westchester County"
        map.addAnnotation(annotation)

        var locations = [CLLocation(latitude: -73.761105, longitude: 41.017791), CLLocation(latitude: -73.760701,longitude: 41.019348), CLLocation(latitude: -73.757201, longitude: 41.019267), CLLocation(latitude: -73.757482, longitude: 41.016375), CLLocation(latitude: -73.761105, longitude: 41.017791)]
        var coordinates = locations.map({(location: CLLocation!) -> CLLocationCoordinate2D in return location.coordinate})
        var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)

        self.map.addOverlay(polyline)

    }

    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
    }

}

谢谢!

【问题讨论】:

  • 坐标可能向后。怀特普莱恩斯位于 longitude -73.xxx(不是 latitude)。目前,这条线路可能在南极洲。
  • 谢谢安娜!愚蠢的错误。希望我能“接受”这条评论。

标签: ios swift mapkit polyline mkpolyline


【解决方案1】:

这里MKGeodesicPolyline 将解决您的问题。添加MKGeodesicPolyline 的对象而不是MKPolyline

在您的代码中删除以下两行:

    let polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
    map.add(polyline)

并添加这些行:

    let geodesic = MKGeodesicPolyline(coordinates: coordinates, count: 2)
    map.addOverlay(geodesic)

Swift 5.0:

func createPolyline(mapView: MKMapView) {
    let point1 = CLLocationCoordinate2DMake(-73.761105, 41.017791);
    let point2 = CLLocationCoordinate2DMake(-73.760701, 41.019348);
    let point3 = CLLocationCoordinate2DMake(-73.757201, 41.019267);
    let point4 = CLLocationCoordinate2DMake(-73.757482, 41.016375);
    let point5 = CLLocationCoordinate2DMake(-73.761105, 41.017791);
    
    let points: [CLLocationCoordinate2D]
    points = [point1, point2, point3, point4, point5]
    
    let geodesic = MKGeodesicPolyline(coordinates: points, count: 5)
    map.addOverlay(geodesic)
    
    UIView.animate(withDuration: 1.5, animations: { () -> Void in
        let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
        let region1 = MKCoordinateRegion(center: point1, span: span)
        self.map.setRegion(region1, animated: true)
    })
}

目标 C 代码:

- (void) createGeoPolyline {
    
    CLLocationCoordinate2D point1 = { -73.761105, 41.017791 };
    CLLocationCoordinate2D point2 = { -73.760701, 41.019348 };
    CLLocationCoordinate2D point3 = { -73.757201, 41.019267 };
    CLLocationCoordinate2D point4 = { -73.757482, 41.016375 };
    CLLocationCoordinate2D point5 = { -73.761105, 41.017791 };

   CLLocationCoordinate2D points[] = {point1, point2, point3, point4, point5};
    
    MKGeodesicPolyline *geodesic = [MKGeodesicPolyline polylineWithCoordinates:&points[0] count:5];
    [self.mapView addOverlay:geodesic];
    
    [UIView animateWithDuration:1.5 animations:^{
        MKCoordinateRegion region;
        region.center = point1;
        
        MKCoordinateSpan span;
        span.latitudeDelta  = 0.01;
        span.longitudeDelta = 0.01;
        region.span = span;
        [self.mapView setRegion:region animated:YES];
    }];
}

上面的 Objective C 代码完美运行,它会在下面显示覆盖:

但如果你尝试 Swift 代码,它不会。我尽我所能解决它,但它不会改变。可能是 MapKit 框架的错误。

【讨论】:

  • OP的代码没有问题,只是坐标反了。我不明白如果首先坐标错误,使用测地线会解决什么“问题”。
  • OP 的代码和此代码都在南极洲划线。这段代码实际上并没有画出 OP 的意图。
  • 有什么区别?
  • 非常感谢您的回复。这绝对有帮助——至少现在我在地图上有一条线。但现在我有另一个问题。这条线从纽约州的怀特普莱恩斯开始(根据安娜的有用评论我颠倒了我的坐标),并以弧形延伸穿过大西洋,在非洲之外结束。我使用的坐标应该在怀特普莱恩斯绘制了一个非常小的区域。知道这里发生了什么吗?
  • @TJRogers- 是的,我看到覆盖层展开了,我在 Objective C 中尝试过,效果很好。但不是在 Swift 中,我认为这是 MapKit 的错误。
【解决方案2】:

更新: 这似乎已在 Swift 3+ 上修复。查看已接受的答案。

在这一行:

var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)

您将 Swift 数组引用转换为 UnsafePointer<CLLocationCoordinate2D>

这很危险,我不确定为什么 Swift 允许它编译。最好的情况下你得到了划线,最坏的情况(这似乎是你的情况)你什么也得不到。

MKPolyline 构造函数想要一个 UsafePointer<CLLocationCoordinate2D>,这就是你应该传递的。

我通常在 MKPolyline 中添加一个私有类别,以创建一个接受普通 Swift 数组的便捷 init 方法:

private extension MKPolyline {
    convenience init(coordinates coords: Array<CLLocationCoordinate2D>) {
        let unsafeCoordinates = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(coords.count)
        unsafeCoordinates.initializeFrom(coords)
        self.init(coordinates: unsafeCoordinates, count: coords.count)
        unsafeCoordinates.dealloc(coords.count)
    }
}

【讨论】:

  • 我在 Xcode 8.3.1 中收到警告:'initialize(from:)' 已弃用:它将在 Swift 4.0 中删除。请改用'UnsafeMutableBufferPointer.initialize(from:)'
  • @BrandonNott 您实际上不必这样做。使您的数组专门为 [CLLocationCoordinate2D] 类型,并传递数组本身。您不必包含 & 或任何内容。
【解决方案3】:

在苹果地图上创建折线:

import MapKit
import CoreLocation

<CLLocationManagerDelegate,MKMapViewDelegate>

代码

    self.mapView.delegate = self

    var coordinateArray: [CLLocationCoordinate2D] = []
    let destination1 = CLLocationCoordinate2DMake(22.3039, 70.8022)
    let destination2 = CLLocationCoordinate2DMake(23.0225, 72.5714)
    coordinateArray.append(destination1)
    coordinateArray.append(destination2)

    let polygon = MKPolyline(coordinates: coordinateArray, count: coordinateArray.count)
    self.mapView.addOverlay(polygon)

委托方法

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay.isKind(of: MKPolyline.self){
        let polylineRenderer = MKPolylineRenderer(overlay: overlay)
            polylineRenderer.fillColor = UIColor.blue
            polylineRenderer.strokeColor = UIColor.blue
            polylineRenderer.lineWidth = 2
        
        return polylineRenderer
 }
    return MKOverlayRenderer(overlay: overlay)
}

【讨论】:

    猜你喜欢
    • 2017-10-28
    • 2018-11-09
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2016-07-18
    • 2017-05-12
    • 2018-11-15
    • 2016-04-12
    相关资源
    最近更新 更多