2

I am trying to learn MapKit and add some MKPolyLine as an overlay. Couple of questions:

  1. What is the difference between MKPolyLine and MKPolyLineView. Which one should be used when?

  2. For the MKPolyLine init method one of the parameter is a generic type(MKMapPoint) of UnsafePointer? Not really sure what is that supposed to mean. Looking up the various SO questions, it seems we are supposed to pass the memory address of the CLLocationCoordinate2D struct as a parameter, but it doesn't work for me.

    let testline = MKPolyline()
    let coords1 = CLLocationCoordinate2D(latitude: 52.167894, longitude: 17.077399)
    let coords2 = CLLocationCoordinate2D(latitude: 52.168776, longitude: 17.081326)
    let coords3 = CLLocationCoordinate2D(latitude: 52.167921, longitude: 17.083730)
    let testcoords:[CLLocationCoordinate2D] = [coords1,coords2,coords3]
    
    
    let line = MKPolyline.init(points: &testcoords, count: testcoords.count)
    
    mapView.add(testline)
    

I keep getting a "& is not allowed passing array value as 'UnsafePointer<MKMapPoint>" argument".

What is wrong here?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user2511882
  • 9,022
  • 10
  • 51
  • 59

2 Answers2

12

1.

MKPolyLine is a class which holds multiple map-coordinates to define the shape of a polyline, very near to just an array of coordinates. MKPolyLineView is a view class which manages the visual representation of the MKPolyLine. As mentioned in the Kane Cheshire's answer, it's outdated and you should use MKPolyLineRenderer.

Which one should be used when?

You need to use both MKPolyLine and MKPolyLineRenderer as in the code below.


2.

MKPolyLine has two initializers:

When you want to pass [CLLocationCoordinate2D] to MKPolyLine.init, you need to use init(coordinates:count:).

(Or you can create an Array of MKMapPoint and pass it to init(points:count:).)

And when you want to pass an immutable Array (declared with let) to UnsafePointer (non-Mutable), you have no need to prefix &.


The code below is actually built and tested with Xcode 9 beta 3:

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let coords1 = CLLocationCoordinate2D(latitude: 52.167894, longitude: 17.077399)
        let coords2 = CLLocationCoordinate2D(latitude: 52.168776, longitude: 17.081326)
        let coords3 = CLLocationCoordinate2D(latitude: 52.167921, longitude: 17.083730)
        let testcoords:[CLLocationCoordinate2D] = [coords1,coords2,coords3]

        let testline = MKPolyline(coordinates: testcoords, count: testcoords.count)
        //Add `MKPolyLine` as an overlay.
        mapView.add(testline)

        mapView.delegate = self

        mapView.centerCoordinate = coords2
        mapView.region = MKCoordinateRegion(center: coords2, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        //Return an `MKPolylineRenderer` for the `MKPolyline` in the `MKMapViewDelegate`s method
        if let polyline = overlay as? MKPolyline {
            let testlineRenderer = MKPolylineRenderer(polyline: polyline)
            testlineRenderer.strokeColor = .blue
            testlineRenderer.lineWidth = 2.0
            return testlineRenderer
        }
        fatalError("Something wrong...")
        //return MKOverlayRenderer()
    }

}
OOPer
  • 47,149
  • 6
  • 107
  • 142
0

Change testCoords to be var instead of let. It needs to be mutable (variable) to be passed in as a pointer.

You're also trying to pass an array of CLLocationCoordinate2Ds into an argument that expects an array of MKMapPoints. Either convert your coordinates into points or use the function that takes an array of coordinates instead.

MKPolyLineView is an old way of rendering lines onto maps, Apple's docs say to use MKPolylineRenderer from iOS 7 and onwards: https://developer.apple.com/documentation/mapkit/mkpolylineview

Kane Cheshire
  • 1,654
  • 17
  • 20
  • why cant i just use "&" just like in objC – user2511882 Jul 12 '17 at 22:36
  • Because this is Swift and not Objective-C. Everything is mutable in Objective-C, in Swift `let` means it can't be changed. Arrays are also structs in Swift and classes in Objective-C. All you have to do is change `let` to `var` in your code, leave the `&` where it is. – Kane Cheshire Jul 12 '17 at 22:37
  • changed let to var..still fails with cannot convert value to 'unsafepointer – user2511882 Jul 12 '17 at 22:39
  • You're passing coordinates into an argument that is expecting points. Either change to use MKMapPoint like the error says or use `MKPolyline(coordinates: &testCoords, count: testCoords.count)` – Kane Cheshire Jul 12 '17 at 22:40
  • You have no need to change `let` to `var` when passing Swift Array to `UnsafePointer` (non-mutable). Use `let` and remove `&`. – OOPer Jul 12 '17 at 22:54
  • Hmm, so I just tried with `let` and it doesn't compile. When I change to `var` it does. – Kane Cheshire Jul 12 '17 at 22:56
  • Have you included _remove `&`_? As far as I tested on Xcode 9 beta 3, it compiles without any problems – OOPer Jul 12 '17 at 23:37