Reputation: 6215
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];
}];
}
}
Upvotes: 1
Views: 321
Reputation:
In reference to this part:
if ([vehicles objectForKey:[route objectForKey:@"RouteID"]] == nil) {
...
[mapView addAnnotation:
[vehicles objectForKey:[route objectForKey:@"RouteID"]]];
}
else {
busLocationDot = [vehicles objectForKey:@"RouteID"];
}
when you call addAnnotation
, you pass:
[vehicles objectForKey:[route objectForKey:@"RouteID"]]
but if it already exists, you use:
[vehicles objectForKey:@"RouteID"]
This means when updating an annotation, a different (most likely wrong) reference is being used.
Either [vehicles objectForKey:@"RouteID"]
is not actually a BusPositionDot
or it's not the same instance that was originally added with that "route id".
Therefore, the setCoordinate
wouldn'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 float
variable (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 if roundedDirection
is within a very small range of the target value or, in your case, just declare roundedDirection
as an int
since it looks like the expression
45 * round(direction/45)
will only return values with no fractions.
The code is setting the image
of the annotation view directly. This is ok but make sure the viewForAnnnotation
delegate method also has the same exact logic to set the image
based 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 a direction
property to BusPositionDot
.
Upvotes: 2