2014-12-19 2 views
4

Swift를 사용하여 폴리 라인을 그리는 방법을 이해하려고합니다. 나는 문서를보고, 튜토리얼을 참조하고, 다른 게시물을 체크 아웃했지만, 여전히 맵에 선을 그리는 것은 불가능합니다. 여기 내 코드가있다. 아무도 내가 여기서 뭘 잘못하고 있다고 말해?Swift를 사용하여 폴리선 그리기

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 
    } 

} 

고마워요!

+2

좌표는 거꾸로 될 수있다. White Plains는 _longitude_-73.xxx에 있습니다 (_latitude_가 아님). 지금은 남극 대륙에있을 수도 있습니다. – Anna

+0

감사합니다 안나! 멍청한 실수. 이 의견을 "수락"할 수 있기를 바랍니다. –

답변

7

여기 MKGeodesicPolyline은 문제를 해결합니다. MKPolyline 대신 MKGeodesicPolyline의 개체를 추가하십시오. 이 라인

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

그리고 추가 :

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

스위프트 코드 :

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 코드 :

을 코드에서

은 두 줄 아래에 제거 01 목표 C 코드 위 23,516,
- (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]; 
    }]; 
} 

완벽하게 작동하며 아래 오버레이를 표시합니다 :

enter image description here

하지만 스위프트 코드를하려고하면 그것은하지 않습니다. 내가 해결할 수있는만큼 노력했지만 변경되지 않을 것입니다. MapKit 프레임 워크에서 버그 일 수 있습니다.

+2

좌표가 거꾸로 있다는 점을 제외하고 OP 코드에는 아무런 문제가 없습니다. 좌표가 잘못되면 측지학을 사용하여 "문제"가 해결할 것이라고 이해하지 못합니다. – Anna

+0

나는이 좌표를 시도하고 그것은 나를 위해 작동합니다! – Kampai

+0

OP의 코드와이 코드는 모두 남극 대륙에서 선을 그립니다. 이 코드는 실제로 OP가 의도 한 선을 그리지 않습니다. – Anna

3

업데이트 : 이것은 Swift 3+에서 수정 된 것으로 보입니다. 허용 된 답변을 참조하십시오. 이 라인에

: 당신은 UnsafePointer<CLLocationCoordinate2D>로 신속한 배열 참조를 캐스팅하고

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

.

꽤 위험하고 Swift가 왜 컴파일을 허용하는지 잘 모르겠습니다. 당신이 그려진 선을 얻는 가장 좋은 경우, 당신의 경우 인 것처럼 보이는 최악의 경우 당신은 아무것도 얻지 못합니다.

MKPolyline 생성자는 UsafePointer<CLLocationCoordinate2D>을 원하기 때문에 통과해야합니다.

I은 ​​일반적으로 정상 스위프트 배열을 허용하는 편리한 init 메소드를 만들 MKPolyline에 전용 카테고리를 추가

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

Xcode 8.3.1에서 경고 메시지가 나타납니다. '초기화 (from :)'가 사용되지 않음 : Swift 4.0에서 제거됩니다. 'UnsafeMutableBufferPointer.initialize (from :)'대신 –

+0

@BrandonNott을 사용하십시오. 실제로이 작업을 수행 할 필요는 없습니다. 배열을 구체적으로 [CLLocationCoordinate2D] 유형으로 만들고 배열 자체를 전달하십시오. 당신은 &를 포함 할 필요가 없습니다. – Dallas