Check if mapView already contains an annotation
Asked Answered
H

5

7

I have a method of adding secondary nearby annotations (ann2) when I tap on another annotation (ann1). But when I deselect and re-select the exact same annotation (ann1) the ann2 re-creates it self and is getting added again. Is there a way to check if the annotation already exists on the map and if yes then do nothing otherwise add the new annotation. I have already checked this: Restrict Duplicate Annotation on MapView but it did not help me.. Any advice is appreciated. This is what I have so far:

    fixedLocationsPin *pin = [[fixedLocationsPin alloc] init];
        pin.title = [NSString stringWithFormat:@"%@",nearestPlace];
        pin.subtitle = pinSubtitle;
        pin.coordinate = CLLocationCoordinate2DMake(newObject.lat, newObject.lon);

        for (fixedLocationsPin *pins in mapView.annotations) {
            if (MKMapRectContainsPoint(mapView.visibleMapRect, MKMapPointForCoordinate (pins.coordinate))) {
                NSLog(@"already in map");
            }else{
                [mapView addAnnotation:pin];
            }

In this case I get the log already on map but I also get the drop animation of the annotation adding to the map. Any ideas?

Thank you in advance..

Herold answered 28/2, 2013 at 11:56 Comment(19)
are you removing the annotation from the mapview any whereTippler
no.. why remove it? Thanks..Herold
You are telling that it is adding again na so i got a doubt ....Tippler
I get the annotation animatesDrop so I'll guess that it is re-adding/ duplicating itself.. Is there a way to see if it is actually adding another one or if it is mimic-ing the animation only?Herold
You are using this if (MKMapRectContainsPoint(mapView.visibleMapRect, MKMapPointForCoordinate (pins.coordinate))) it will check the pins with in the visible region of map rect is the other point with in the visible map rect or notTippler
You can observe it by the pin color gets more darker if the pin is duplicating check itTippler
Yes it is.. they are both near the center of the map with ann2 almost 50pixels above ann1 (on a full screen map).Herold
@Tippler they are re-adding.. I just checked.. the shadow of the pins is getting darker and darker every time..Herold
ok... once debug it by printing the mapView.annotations and check wether how many annotation are coming .,.,Tippler
@Tippler yes.. it is being re-added.. NSLog(@"mapview annotations%@", mapView.annotations); I get +1 of annotation Class everytime..Herold
Means Your if condition is not satisfying it is readding againTippler
try modifying the if condition as followed if (MKMapRectContainsPoint(mapview.region , MKMapPointForCoordinate (pins.coordinate))) may work i hopeTippler
Passing 'MKCoordinateRegion' to parameter of incompatible type 'MKMapRect'Herold
I am not getting one thing first time You are adding all ponta on mapview again why do u want to add ???? if i am wrong to understand excuse...Tippler
the ann2 is not added until you press/ select ann1..Herold
every time u will get only two annotations or more..?Tippler
every time I press/select ann1, ann2 is added. And every time you deselect and select ann1, ann2 is re-added/duplicated (+1), instead of doing nothing because it has already been added.Herold
if ([mapView.annotations count] == 2) return; else [mapView addAnnotation:pin];Tippler
that will not work in my case because users can add their own annotations. So the ann1 will not always be of a fixed number.. I need to check for the exact coordinates because the map may contain 30+ annotations.. Thank you..Herold
H
5

Your for loop isn't checking if the annotation is on the screen, it is checking if the coordinates of the pin are currently within the visible area. Even if it was checking if the pin object was already in the mapView.annotations it would never be true, because you've only just created pin a few lines earlier, it can't possibly be the same object as on in the mapView.annotations. It might though have the same coordinates and title, and that's what you need to check:

bool found = false;
for (fixedLocationsPin *existingPin in mapView.annotations)
{
  if (([existingPin.title isEqualToString:pin.title] && 
       (existingPin.coordinate.latitude == pin.coordinate.latitude)
       (existingPin.coordinate.longitude == pin.coordinate.longitude))
  { 
    NSLog(@"already in map");
    found = true;
    break;
  }
}    
if (!found)
{
    [mapView addAnnotation:pin];
} 
Hackney answered 28/2, 2013 at 20:3 Comment(4)
I don't see how that would work. Good idea to check for equality in title and coordinates, but the logic seems wrong here. You need to add the annotation once you are sure that ALL existing points have been parsed.Afraid
You're right Fred, it needs to get to the end of the loop and be sure none of the items are the one about to be added, then add it. I'll update the code.Hackney
Yep, now that would work. Look at my answer too. Although it is written in Swift, the advantage is that if an entry is found, it exists right away, rather than continuing parsing the annotations unnecessarily.Afraid
As I was going through this answer, I think one good thing to check for is that the current pin in the for loop is NOT equal to the current MKUserLocation (since that is considered an annotation on an MKMapView).Roguish
O
1

Annotations array exist in map object so you just have to check

if ( yourmap.annotations.count==0)
{
NSLog(@"no annotations");
}
Oleoresin answered 1/2, 2016 at 11:1 Comment(1)
This code checks whether there are any annotations in the mapView, not if a given annotation is contained in the mapView.Afraid
F
1
NSNumber *latCord = [row valueForKey:@"latitude"];
NSNumber *longCord = [row valueForKey:@"longitude"];
NSString *title = [row valueForKey:@"name"];

CLLocationCoordinate2D coord;
coord.latitude = latCord.doubleValue;
coord.longitude = longCord.doubleValue;
MapAnnotation *annotation = [[MapAnnotation alloc]initWithCoordinate:coord withTitle:title];
if([mkMapView.annotations containsObject:annotation]==YES){
    //add codes here if the map contains the annotation.
}else {
    //add codes here if the annotation does not exist in the map.
}
Flap answered 11/2, 2016 at 8:33 Comment(0)
M
0
        if (sampleMapView.annotations.count > 0) {             
            sampleMapView.removeAnnotation(detailMapView.annotations.last!)
        }
Mallard answered 4/7, 2016 at 7:14 Comment(0)
A
-1

Following my comment on Craig's answer, I think the solution could look like something like this :

import MapKit

extension MKMapView {

    func containsAnnotation(annotation: MKAnnotation) -> Bool {

        if let existingAnnotations = self.annotations as? [MKAnnotation] {
            for existingAnnotation in existingAnnotations {
                if existingAnnotation.title == annotation.title
                && existingAnnotation.coordinate.latitude == annotation.coordinate.latitude
                && existingAnnotation.coordinate.longitude == annotation.coordinate.longitude {
                  return true
                }
            }
        }
        return false
    }
}

This code allows you to check if a mapView contains a given annotation. Use this in a "for" loop on all your annotations:

for annotation in annotations {
  if mapView.containsAnnotation(annotation) {
    // do nothing
  } else {
    mapView.addAnnotation(annotation)
  }

PS: this works well if you need to add new annotations to a mapView. But if you need also to remove entries, you may have to do the opposite: check that each existing annotation exists in the new array of annotations ; if not, remove it. Or you could remove everything and add everything again (but then you will have the change animated ...)

Afraid answered 21/8, 2015 at 21:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.