Im adding a bunch of annotations, and sotirng them in an array so i can pull in their new locations and update the map accordingly WITHOUT removing all the annotations first and adding them which causes a flicker. Unfortunately, after their coordinates are initially set and added any setCoordinate call no longer works. Any ideas?
- (void)updateMap:(NSData *)responseData {
//parse out the JSON data
NSError* error;
vehicleData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
//find which Dictionary is for our bus.
for (NSDictionary* route in vehicleData) {
//find our bus in our vehicles dictionary. Key is by routeID.
BusPositionDot *busLocationDot;
if ([vehicles objectForKey:[route objectForKey:@"RouteID"]] == nil) {
busLocationDot = [[BusPositionDot alloc] init];
[vehicles setObject:busLocationDot forKey:[route objectForKey:@"RouteID"]];
[mapView addAnnotation:[vehicles objectForKey:[route objectForKey:@"RouteID"]]];
}
else {
busLocationDot = [vehicles objectForKey:@"RouteID"];
}
float latitude = [[route objectForKey:@"Latitude"] floatValue];
float longitude = [[route objectForKey:@"Longitude"] floatValue];
float groundSpeed = [[route objectForKey:@"GroundSpeed"] floatValue];
float direction = [[route objectForKey:@"Heading"] floatValue];
float roundedDirection=45 * round(direction/45);
if(groundSpeed<=3)
//get view for annotation
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot.png"];
else if((roundedDirection==0)||(roundedDirection==360))
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot0.png"];
else if(roundedDirection==45)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot45.png"];
else if(roundedDirection==90)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot90.png"];
else if(roundedDirection==135)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot135.png"];
else if(roundedDirection==180)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot180.png"];
else if(roundedDirection==225)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot225.png"];
else if(roundedDirection==270)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot270.png"];
else if(roundedDirection==315)
[mapView viewForAnnotation:busLocationDot].image=[UIImage imageNamed:@"buspositiondot315.png"];
CLLocationCoordinate2D currentBusLocation = CLLocationCoordinate2DMake(latitude, longitude);
NSLog(@"setting coord %f & %f",currentBusLocation.latitude,currentBusLocation.longitude);
[UIView animateWithDuration:0.5 animations:^{
[busLocationDot setCoordinate:currentBusLocation];
}];
}
}
In reference to this part:
when you call
addAnnotation, you pass:but if it already exists, you use:
This means when updating an annotation, a different (most likely wrong) reference is being used.
Either
[vehicles objectForKey:@"RouteID"]is not actually aBusPositionDotor it’s not the same instance that was originally added with that “route id”.Therefore, the
setCoordinatewouldn’t work.Using the same reference when updating the annotation should fix it.
There are a couple of other unrelated, potential issues:
The code is doing a direct comparison using a
floatvariable (eg.if(roundedDirection==45)). This is not recommended even if it “seems to work” — there’s the potential for floating-point precision errors. Either check ifroundedDirectionis within a very small range of the target value or, in your case, just declareroundedDirectionas anintsince it looks like the expression45 * round(direction/45)will only return values with no fractions.The code is setting the
imageof the annotation view directly. This is ok but make sure theviewForAnnnotationdelegate method also has the same exact logic to set theimagebased on direction otherwise what may happen is the annotation view’s image will get reset to some default when panning or zooming. You may need to add adirectionproperty toBusPositionDot.