0

I would like to retrieve a MKPolyline but my code keeps returning an MKShape. I am trying to use the GEOSwift library as described here: https://github.com/GEOSwift/GEOSwift

My Code:

let linestring = Geometry.create("LINESTRING(51.063164 -0.728986, 51.072347 -0.723721, 51.116898 -0.731893)")!
let shapeLine = linestring.mapShape()
self.mapView.add(shapeLine)

I get the error: Cannot invoke 'add' with an argument list of type '(MKShape)'

(let shapeLine = linestring.mapshape() should convert it to a MKPolyline)

However, if i run:

 let linestring = Geometry.create("LINESTRING(51.063164 -0.728986, 51.072347 -0.723721, 51.116898 -0.731893)")!
 let shapeLine = linestring.mapShape()
 dump(shapeLine)

i get this:

- <MKPolyline: 0x60000069e550> #0
  - super: MKMultiPoint
    - super: MKShape
      - super: NSObject

Is this saying that there is a Polyline there?

My overlay renderer:

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let renderer = MKPolylineRenderer(overlay: overlay)
    renderer.strokeColor = UIColor.blue
    renderer.lineWidth = 5.0

    return renderer
}

Also, i have already got other polylines working on this application. I have set MKMapViewDelegate and also set the delegate to self.

///To try and avoid the xy problem - im trying to search along a route, so am using GEOSwift to create buffer around polyline, then using this to search a database with a geoquery of those points, below is the specific problem as described in the title:///

Im sure the error is simple, but ive looked at the same code for so long i just cant see it.

Any help is much appreciated

vfn
  • 6,026
  • 2
  • 34
  • 45
Alex A
  • 189
  • 12

1 Answers1

0

The method mapShape(), as defined on [GEOSwiftMapKit][1] protocol, returns a MKShape, that is an abstract base class for all shape-based MapKit overlay objects.

The implementation of that method, will return the appropriate subclass, depending on the underlying geometry type, although as I pointed above, the method's signature indicates that it returns MKShape that does not conform to MKOverlay as expected by MapKit.MapView's add method.

All you need to do is to downcast shapeLine to a MKPolyline

guard let shapeLine = linestring.mapShape() as? MKPolyline else {
    preconditionFailure()
}
vfn
  • 6,026
  • 2
  • 34
  • 45
  • Thanks that worked perfectly. However i now need to create a buffer around the polyline, and then retrieve the coordinates of the buffer. is this possible? I also saw you have a LinearRing. Is this what I'm looking for? – Alex A Nov 22 '17 at 11:19
  • i tried a lot of the methods in your library, but didnt post code here to keep it simple. (just wanted to know if what i want to do is even possible or i can spend a very long time trying) – Alex A Nov 22 '17 at 11:50
  • If it interests anyone else, additionally to the answer above, i had a delegate issue. This can be difficult to diagnose as it doesn't throw any errors. The problem was my rendererFor overlay wasn't being called so i recommend putting a print statement in there to check. – Alex A Nov 22 '17 at 11:50
  • @AlexA regarding adding a buffer, you should use the Geometry's `func buffer(width: Double) -> Geometry?`. As you can see it will return a geometry representing the new buffered shape, and then you can access its points – vfn Nov 30 '17 at 10:41
  • Managed to get it working. The key was to cast the shapeLine as an MKPolygon, rather than polyline after the line was buffered. Also, if anyone is following along, buffer works perfectly on a linestring, no need to use LinearRing as long as you cast it as described above. Hope this is helpful to someone. Thanks again for the help vfn! – Alex A Dec 11 '17 at 13:53