web-dev-qa-db-ja.com

Swift)を使用してポリラインを描画します

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
    }

}

ありがとう!

11
TJ Rogers

ここでMKGeodesicPolylineが問題を解決します。 MKGeodesicPolylineの代わりにMKPolylineのオブジェクトを追加します。

コードで、以下の2行を削除します。

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

Objective 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];
    }];
}

上記のObjectiveCコードは完璧に機能し、以下にオーバーレイが表示されます。

enter image description here

しかし、Swiftコードを試してみても、うまくいきません。できる限り解決しようとしましたが、変更されません。MapKitフレームワークのバグである可能性があります。

12
Kampai

PDATE:これは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)
    }
}
3
duhanebel