Search code examples
iosmkmapviewmkoverlaymkpolyline

Check if MKPolyline overlay already exists


How can I check if a polyline has already been added to the map?

I've tried the following code, but it doesnt seem to work

for (MKPolyline *feature1 in self.mapView.overlays) {

       NSLog(@"feature1.title: %@", feature1.title);
       NSLog(@"Polu.title: %@", polu.title);

       if (![feature1.title isEqualToString:polu.title]) {
             NSLog(@"NOT");
             [self.mapView addOverlay:polu];
       }
       else {
             NSLog(@"Already added");
       }
      }
     }

I've also tried this:

if (![self.mapView.overlays containsObject:polu]) {
    NSLog(@"NOT");
   [self.mapView addOverlay:polu];
}

Solution

  • The current for loop assumes the overlay exists or doesn't exist as soon as it finds one other overlay whose title doesn't match.

    But at that point, the for loop might not have checked the remaining overlays (one of which might be the overlay you're looking for).

    For example:

    • Assume there are already 4 overlays on the map with the titles A, B, C, and D.
    • Assume the overlay you want to check for (polu) has the title C.
    • The first overlay checked is A. Since A does not match C, the existing code immediately adds another overlay named C.
    • Then the for loop continues and looks at B. Again, since B does not match C, the existing code adds another overlay named C.
    • Then the loop continues, looks at C, and logs "already added".
    • Then the loop continues, looks at D, sees it doesn't match C, and adds another overlay.


    Instead, you want to stop the loop when a matching title is found and if the loop ends with no match found, then add the overlay.

    Example:

    BOOL poluExists = NO;
    
    for (MKPolyline *feature1 in self.mapView.overlays) {
    
        NSLog(@"feature1.title: %@", feature1.title);
        NSLog(@"Polu.title: %@", polu.title);
    
        //STOP looping if titles MATCH...
        if ([feature1.title isEqualToString:polu.title]) {
            poluExists = YES;
            break;
        }
    }
    
    //AFTER the loop, we know whether polu.title exists or not.
    //If it existed, loop would have been stopped and we come here.
    //If it didn't exist, loop would have checked all overlays and we come here.
    if (poluExists) {
        NSLog(@"Already added");
    }
    else {
        NSLog(@"NOT");
        [self.mapView addOverlay:polu];
    }
    


    In the second example in the question, containsObject: will only work if polu was the original object that was given the first time addOverlay was called because in this case, containsObject: will compare pointer addresses and not the title property of the overlays.