使用Swift绘制折线

时间:2014-12-19 02:28:39

标签: ios swift mapkit polyline mkpolyline

我试图了解如何使用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
    }

}

谢谢!

3 个答案:

答案 0 :(得分:10)

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

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

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

并添加以下行:

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

Swift代码:

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.add(geodesic)

    UIView.animate(withDuration: 1.5, animations: { () -> Void in
        let span = MKCoordinateSpanMake(0.01, 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];
    }];
}

以上目标C代码工作正常,它将在下面显示叠加:

enter image description here

但是如果你尝试使用Swift代码,它就不会。我尽可能多地尝试解决它,但它不会改变。可能是MapKit框架的bug。

答案 1 :(得分:3)

更新:这似乎是在Swift 3+上修复的。见接受的答案。

在这一行:

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

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

这非常危险,我不确定为什么Swift允许它编译。最好的情况是你得到的线条,更糟糕的情况(这似乎是你的情况)你得不到任何东西。

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

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

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)
    }
}

答案 2 :(得分:0)

在苹果地图上创建折线:

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)
}