2

I'm trying to add overlays to an MKMapView, avoiding duplicates by first looking for the overlay in the maps overlays (mapView.overlays: [MKoverlay]) store.

This is what I'm trying currently

func addBoundary(points: [CLLocationCoordinate2D]) -> MKPolygon! {
    var x = points
    let polygon: MKPolygon = MKPolygon(coordinates: &x, count: points.count)

    if overlays.indexOf(polygon as MKOverlay) == nil {
        addOverlay(polygon)
        return polygon
    }
    return nil
}

Yet, I'm getting the following error

Cannot convert value of type 'MKOverlay' to expected argument type '@noescape (MKOverlay) throws -> Bool'

I'm guessing it's something simple. I've managed to do checks like this in the past with my own structs, but it doesn't seem to work on pre-defined arrays of common objects.

Can someone please shed some light on my mistakes. I'm guessing it's something to do with MKOverlay not being comparable - if that's the case, I've not certain how best to go about appending that functionality to a pre-defined object...

Many thanks

p.s. This is Swift 2.0

I primarily tried simpler and more logical approach of using

if !overlays.contains(polygon) {
    addOverlay(polygon)
} 

...yielding an identical error - It seems likely that I'm missing something.

NickSaintJohn
  • 65
  • 1
  • 7
  • Maybe just go the easy option and just remove all and add the ones that you want to view. i.e. mapView.removeOverlays(mapView.overlays) – DogCoffee Oct 14 '15 at 09:49
  • That was how it has been operating until now. It would be nice to progressively add these overlays (so they are retained off screen) as they are pulled from the DB. The current method is fairly primitive and I was hoping to improve upon it, in this manner – NickSaintJohn Oct 14 '15 at 14:27
  • Can you convert to maybe an NSValue then compare it? Thats how i compare locations... – DogCoffee Oct 14 '15 at 22:01
  • My main problem is mapping / enumerating the array using the newly built-in functions. I could no doubt iterate / walk the array, and compare in the old-school way, I was just hoping to use some of the fancy new Swift 2.0 functions... Sadly, it seems I'm either doing it all wrong, or it's not quite there yet :( – NickSaintJohn Oct 16 '15 at 01:03
  • maybe try, let polys = mapview.overlays.map { $0 as! MKOverlay } then loop through that rather than loop through mapview.overlays. I know i had to do this when using MKAnnotations as the the cast would fail but via the map method it worked – DogCoffee Oct 16 '15 at 01:56

1 Answers1

1

As you surmised, it has to do with MKOverlay not being comparable (specifically Equatable), and since MKOverlay is a protocol, you can't extend it as you would a class. There's good explanation of this in this answer: How do I do indexOfObject or a proper containsObject

If you're sure that overlays actually contains only MKPolygon objects, try casting [MKOverlay] to [MKPolygon]:

    let polygons = mapView.overlays as? [MKPolygon]
    if polygons?.indexOf(polygon) == nil { ... }

MKPolygon is an NSObject, so as of Swift 2, it automatically conforms to Equatable.

Without trying it, it's unclear how MKPolygon implements equality comparison. If it's the default NSObject pointer comparison, it won't work for your example, since you're instantiating new MKPolygon objects. You could subclass MKPolygon and implement -isEqual: and -hash based on your own logic to compare the coordinate points.

Community
  • 1
  • 1
jrc
  • 20,354
  • 10
  • 69
  • 64