Draw a polyline using Swift

I am trying to figure out how to draw polylines using Swift. I looked at the documentation, referenced some tutorials and checked out some other SO posts, but I still can't figure out how to draw a line on my map. Here is my code. Will someone tell me what I'm doing wrong here?

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

Thanks!

+9
source share
2 answers

Here MKGeodesicPolyline will solve your problem. Add an MKGeodesicPolyline object instead of MKPolyline .

In your code, remove the two lines below:

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

And add these lines:

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

Target Code 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]; }]; } 

The code above Objective-C works fine, and it will display below:

enter image description here

But if you try Swift code, this will not happen. I tried my best to solve this, but that will not change. Maybe this is a bug in the MapKit framework.

+12
source

UPDATE: This is similar to Swift 3+. See Accepted Answer.

In this line:

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

You specify the Swift array reference as UnsafePointer<CLLocationCoordinate2D> .

This is pretty dangerous, and I'm not sure why Swift allows you to compile it. The best random scenario that you get a drawn line, the worst case (which seems to be your case), you get nothing.

MKPolyline constructors want UsafePointer<CLLocationCoordinate2D> and what you have to go through.

Usually I add a private category to MKPolyline to create a convenient initialization method that accepts a regular Swift array:

 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
source

Source: https://habr.com/ru/post/1209506/


All Articles