Dropping a MKPinAnnotationView with animation - iphone

I'm confused on how this works. I'm creating a CLGeocoder to drop a pin based on a string value. I have this:
- (void)placeMarkFromString:(NSString *)address {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
[placemarks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSLog(#"%#", [obj description]);
}];
// Check for returned placemarks
if (placemarks && [placemarks count] > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create an MKPlacemark and add it to the mapView
MKPlacemark *place = [[MKPlacemark alloc] initWithPlacemark:topResult];
AddressAnnotation *anAddress = [[AddressAnnotation alloc] init];
anAddress.address = place.subThoroughfare;
anAddress.street = place.thoroughfare;
anAddress.city = place.locality;
anAddress.state = place.administrativeArea;
anAddress.zip = place.postalCode;
anAddress.name = place.name;
//[self.mapView addAnnotation:place];
[self.mapView addAnnotation:anAddress];
self.currentPlacemark = place;
// Center map on that region
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(topResult.location.coordinate, 2000, 2000);
MKCoordinateRegion adjustedRegion = [_mapView regionThatFits:region];
[_mapView setRegion:adjustedRegion animated:YES];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Results Found" message:#"" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
}
}];
}
So originally, I added my MKPlacemark to the map and it shows the red pin. It does not animate however. I basically want the ability to drop any of the 3 MKPinAnnotationView colors, have a callout and the title/subtitle to be the name and address of the place, similar to how google maps does it. But I was not getting any animation.
So I thought that maybe I needed to create my own object that conforms to the MKAnnotation class. So I did that, but when I try to add it to the location, I do not see its annotationView in the viewForAnnotation delegate method. That method is here:
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *placeMarkIdentifier = #"SimplePinIdentifier";
if ([annotation isKindOfClass:[AddressAnnotation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[theMapView dequeueReusableAnnotationViewWithIdentifier:placeMarkIdentifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:placeMarkIdentifier];
}
else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.animatesDrop = YES;
annotationView.draggable = YES;
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.canShowCallout = YES;
// Create a button for the annotation
// UIButton *rightArrowButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
// annotationView.rightCalloutAccessoryView = rightArrowButton;
// [self performSelector:#selector(openCallout:) withObject:annotation afterDelay:0.5];
return annotationView;
}
return nil;
}
So I guess my questions are, do I need to create my own object to do this, am I on the right track, what am I doing wrong, and why is it that in one case, I am adding a MKPlacemark object, and then if I do it the way other way, I add a object, but not necessarily a subclass of MKPlacemark. Thanks!

First, the reason you're probably not seeing the annotation view when you use a custom annotation object (ie. AddressAnnotation) is that its coordinate is not being set (and so it's appearing at 0,0).
In the placeMarkFromString method, the code sets a lot of properties of the AddressAnnotation but not the coordinate and so the annotation is not appearing where expected.
If you set the coordinate, it will appear where expected and with the animation.
Regarding the other question as to why you see no animation when using an MKPlacemark:
By default, the map view will create an MKPinAnnotationView with a red pin but with animatesDrop set to NO.
So in viewForAnnotation, you have to explicitly do it for MKPlacemark just like you are for AddressAnnotation.
If all your annotations will be using MKPinAnnotationView, instead of checking for each different class of annotation you will be creating, you can flip the condition around by returning nil at the top of the method when the annotation class is MKUserLocation and then run the rest of the code without any class-checking (ie. returning MKPinAnnotationView with animatesDrop set to YES in all other cases).

Related

Passing location to different view with segue

very very new to iOS programming, so I appreciate any help with this.
All I actually want to do is pass the variable of my current coordinates to a different view when a button is pressed. I can't work out how to do this using my current work - I'm getting in a total muddle. My project is essentially made from lots of chunks of code from various sources. I'll share with you the parts that I think are relevant, and hopefully somebody can at least point me in the right direction!
This is from my MainViewController.m:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
if (currentPosition == nil) {
MKMapPoint point = MKMapPointForCoordinate(newLocation.coordinate);
double pointsPerMeter = MKMapPointsPerMeterAtLatitude(newLocation.coordinate.latitude);
double visibleDistance = pointsPerMeter * 500.0;
MKMapRect rect = MKMapRectMake(
point.x - visibleDistance, point.y - visibleDistance,
visibleDistance * 2, visibleDistance * 2);
[self.mapView setVisibleMapRect:rect animated:YES];
NSURL *url = [NSURL URLWithString:#"https://url.url/json.json"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if (error != nil)
{
}
CLLocationCoordinate2D location;
NSMutableArray *newAnnotations = [NSMutableArray array];
MKPointAnnotation *newAnnotation;
for (NSDictionary *dictionary in array)
{
location.latitude = [dictionary[#"lat"] doubleValue];
location.longitude = [dictionary[#"lon"] doubleValue];
newAnnotation = [[MKPointAnnotation alloc] init];
newAnnotation.coordinate = location;
HUWMapAnnotation *annotation = [[HUWMapAnnotation alloc] initWithCoordinate:newAnnotation.coordinate];
annotation.messagetitle = dictionary[#"name"];
annotation.email = dictionary[#"message"];
annotation.username = dictionary[#"user"];
[self.mapView addAnnotation:annotation];
[newAnnotations addObject:newAnnotation];
}
}
currentPosition = newLocation;
}
- (void)viewDidLoad { [super viewDidLoad];
// Check if the user has enabled location services.
if ([CLLocationManager locationServicesEnabled]) {
// Create a location manager.
locationManager = [[CLLocationManager alloc] init];
// Set ourselves as it's delegate so that we get notified of position updates.
locationManager.delegate = self;
// Set the desired accuracy.
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Start tracking.
[locationManager startUpdatingLocation];
}
}
Like I said, I've trimmed this down substantially to the bits I think are relevant. Let me know if I have missed something essential. I've got my storyboard set up with a button ready to go, and a segue with its identifier.
I assume that I should be using prepareForSegue - but my issue is that I quite simply don't know how to get my coordinates into that situation.
I hope somebody will be able to help me (and I apologise for the large amount of copy-pasted code!)
To pass objects between view controllers using segues, do something like the following:
1) create a segue between the source and destination view controllers in IB, give it an identifier #"MySegue".
2) let's say the destination vc needs a string to run:
// DestinationVC.h
#interface DestinationVC : UIViewController
#property(strong, nonatomic) NSString *string;
#end
3) the source vc initiates a segue:
[self performSegueWithIdentifier:#"MySegue" sender:self];
4) the source vc prepares by initializing the property on the destination vc:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"MySegue"]) {
DestinationVC *vc = [segue destinationViewController];
vc.string = // some object that the source vc has. this could be your CLLocationCoordinate2D
}
}

Mapkit :How to add annotation on MKLocalSearch results placemarks?

Basically I need a way to put annotation on all the "Walmarts" that search request picks up. I am not using interface builder, I am just using code for this app.
MKMapView * map = [[MKMapView alloc] initWithFrame:
CGRectMake(0, 0, 320, 480)];
map.delegate = self;
[self.view addSubview:map];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = #"Walmart";
request.region = map.region;
I'd suggest simply creating the mapview in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
MKMapView * map = [[MKMapView alloc] initWithFrame:self.view.bounds];
map.delegate = self;
[self.view addSubview:map];
}
But when the user moves the map, look for Walmarts and add the annotations:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
// if on slow network, it's useful to keep track of the previous
// search, and cancel it if it still exists
[self.previousSearch cancel];
// create new search request
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = #"Walmart";
request.region = mapView.region;
// initiate new search
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
NSMutableArray *annotations = [NSMutableArray array];
[response.mapItems enumerateObjectsUsingBlock:^(MKMapItem *item, NSUInteger idx, BOOL *stop) {
// if we already have an annotation for this MKMapItem,
// just return because you don't have to add it again
for (id<MKAnnotation>annotation in mapView.annotations)
{
if (annotation.coordinate.latitude == item.placemark.coordinate.latitude &&
annotation.coordinate.longitude == item.placemark.coordinate.longitude)
{
return;
}
}
// otherwise, add it to our list of new annotations
// ideally, I'd suggest a custom annotation or MKPinAnnotation, but I want to keep this example simple
[annotations addObject:item.placemark];
}];
[mapView addAnnotations:annotations];
}];
// update our "previous" search, so we can cancel it if necessary
self.previousSearch = localSearch;
}
Clearly, this code sample assumes that you have a weak property for the previous search operation. (This is not, strictly speaking, necessary, but may give you better performance if browsing around on a map when you have a slow Internet connection.) Anyway, that property would be defined as follows:
#property (nonatomic, weak) MKLocalSearch *previousSearch;
There are other possible refinements (e.g. UIActivityIndicatorView or network activity indicator if search is in progress, perhaps remove annotations that are not within the map's current region, etc.), but hopefully you get the idea.
Here is the approach:
MKLocalSearch *localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[self.localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
if(error)
{
NSLog(#"localSearch startWithCompletionHandlerFailed! Error: %#", error);
return;
}
else
{
for(MKMapItem *mapItem in response.mapItems)
{
MKPinAnnotation *annotation = [[MKPinAnnotation alloc] initWithCoordinate: mapItem.placemark.location.coordinate];
[map addAnnotation:annotation];
NSLog(#"Name for result: = %#", mapItem.name);
}
}}];

An instance 0x1d58be70 of class MKPlacemark was deallocated

When I tried to add annotation on mapview using MKPlacemark using this code:
for(int i = 0; i < [array count]; i++){
UsersModel *model = [array objectAtIndex:i];
CLLocationCoordinate2D newCoordinate;
newCoordinate.latitude = model.coordinate.latitude;
newCoordinate.longitude = model.coordinate.longitude;
NSLog(#"%f",model.coordinate.latitude);
NSLog(#"%f",model.coordinate.longitude);
//mPlaceMark = [[MKPlacemark alloc] initWithCoordinate:newCoordinate addressDictionary:nil];
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithCoordinate:newCoordinate addressDictionary:nil];
//[self.mapView addAnnotation:mPlaceMark];
[self.mapView addAnnotation:placeMark];
//[placeMark retain];
NSLog(#"%#", self.mPlaceMark);
}
Then it gives an error on my console:
An instance 0x1d58be70 of class MKPlacemark was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x1d53de10> (
<NSKeyValueObservance 0x1d58af30: Observer: 0x1d576690, Key path: coordinate, Options: <New: NO, Old: NO, Prior: YES> Context: 0x0, Property: 0x1d58af90>
)
Seemingly, you forgot to remove some abserver. Try using this code in your class dealloc method.
for (id <MKAnnotation> annotation in self.mapView.annotations)
{
[[self.mapView viewForAnnotation:annotation] removeObserver:self]; // NOTE: remove ALL observer!
}
You should also remember to nil your map delegate:
self.mapView.delegate = nil;

Maximum number of annotations (MKAnnotation) that can be drawn on MKMapView?

I want to add a number of annotations(arround 500) on a mapview but the maximum it seems to display is 100. If I go beyond 100, viewForAnnotation delegate method is not called. However it works perfectly for annotations below 100.
here is the code: (works only when count of annotationArray array is less than 101)
_allPoints = [[NSMutableArray alloc] init];
NSString* responseFile = [[NSBundle mainBundle] pathForResource:#"Datafile" ofType:#"txt"];
NSData *sampleData = [NSData dataWithContentsOfFile:responseFile];
if (sampleData) {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:sampleData
options:kNilOptions
error:&error];
NSArray* response = [json objectForKey:#"response"];
for (NSDictionary *lineDict in response) {
if ([[lineDict objectForKey:#"data"] isKindOfClass:[NSArray class]]) {
SinglePoint *singlePoint = [[SinglePoint alloc] initWithDictionary:lineDict];
[_allPoints addObject:singlePoint];
}
else {
NSLog(#"Error");
}
}
}
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_mapView setDelegate:self];
[self.view addSubview:_mapView];
NSMutableArray *annotationArray = [[NSMutableArray alloc] init];
for (int i=0; i<[_allPoints count]; i++) {
SinglePoint *singlePoint = [_allPoints objectAtIndex:i];
NVPolylineAnnotation *annotation = [[NVPolylineAnnotation alloc] initWithPoint:singlePoint mapView:_mapView];
[annotationArray addObject:annotation];
}
[_mapView addAnnotations:(NSArray *)annotationArray];
CLLocationCoordinate2D centerCoord = { 28.632747, 77.219982 };
[_mapView setCenterCoordinate:centerCoord zoomLevel:12 animated:NO];
The delegate method is:
EDIT: As per comments, started reusing the view but with no luck :(
if ([annotation isKindOfClass:[NVPolylineAnnotation class]]) {
static NSString *viewIdentifier = #"annotationView";
NVPolylineAnnotationView *annotationView = (NVPolylineAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:viewIdentifier];
if (annotationView == nil) {
annotationView = [[NVPolylineAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:viewIdentifier mapView:_mapView];
}
return annotationView;
}
return nil;
I could not find any restriction in the documentation or anywhere else. Could it be memory issue?
The MKMapView has not Limit for annotationViews. But it gets quite laggy and unusable above a certain number of views (+1000).
I believe, that the reason for this is that you handle the annotationView management totally wrong. You shouldn't create a unique view for every single annotation, even if you are using ARC. Your rather should reuse every unused View like the cell of a UITableView.
There are a couple of good tutorials for this like Introduction to MapKit on iOS - Ray Wenderlich.
If this won't resolve your problem, you should try to debug your annotation classes. (NVPolylineAnnotation and NVPolylineAnnotationView). Maybe there's something wrong.
Did you also checked your points array for equal coordinates?
Finally was able to track down the problem. Solved it by setting the center of mapView first and then adding annotations later. I still dont know why 100 annotations were shown earlier (and why the no 100 only). Thank you all for your suggestions and time on this.
This is the code I changed:-
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_mapView setDelegate:self];
[self.view addSubview:_mapView];
CLLocationCoordinate2D centerCoord = { 28.632747, 77.219982 };
[_mapView setCenterCoordinate:centerCoord zoomLevel:12 animated:NO];
NSMutableArray *annotationArray = [[NSMutableArray alloc] init];
for (int i=0; i<[_allPoints count]; i++) {
SinglePoint *singlePoint = [_allPoints objectAtIndex:i];
NVPolylineAnnotation *annotation = [[NVPolylineAnnotation alloc] initWithPoint:singlePoint mapView:_mapView];
[annotationArray addObject:annotation];
}
[_mapView addAnnotations:(NSArray *)annotationArray];
You can add as many annotations as you like. However, the views for each annotation will not be created until that annotation's coordinate property intersects with the visible portion of your map view. MapKit will not create a view just because you added an annotation to the map.

Problem Refreshing iPhone MapView

Hey guys, I am having trouble getting overlays in my map view to refresh via the setNeedsDisplayInMapRect: function. Here is the relevant code:
ParkingMapViewController.m:
for (ParkingRegionOverlay *overlay in mapView.overlays) {
[overlay setNeedsDisplayInMapRect:self.mapView.visibleMapRect];
}
//...
- (MKOverlayView *)mapView:(MKMapView *)mapView
viewForOverlay:(id <MKOverlay>)overlay
{
NSLog(#"ParkingMapViewController.m mapView:viewForOverlay");
//...
}
//...
ParkingRegionOverlay.h:
#interface ParkingRegionOverlay : MKOverlayView <MKOverlay> {
MKPolygon *polygon;
MKMapRect boundingRect;
CLLocationCoordinate2D centerCoord;
//...
}
//...
And I am not getting the "ParkingMapViewController.m mapView:viewForOverlay" output to console I am expecting. I have walked through he debugger and have ensured that the for loop is being reached and executed, however mapView:viewForOverlay: isn't being called for some reason. Anyone know what I am doing wrong? Thanks in advance!
EDIT 1:
I believe I have set the delegate, coordinates, and bounding rect properly, but please take a look...
ParkingMapViewController.h
#interface ParkingMapViewController : UIViewController <MKMapViewDelegate> {
MKMapView *mapView;
//...
ParkingMapViewController.m:
//...
- (void)viewDidLoad {
[super viewDidLoad];
mapView.delegate = self;
//...
ParkingRegionOverlay.m:
//...
//initializes polygon and calculates bounding rect as well as its center coordinate
-(id)initWithPoints:(NSArray *)pointsArray andTitle:(NSString *)overlayTitle{
MKMapPoint points[[pointsArray count]];
double maxX = MIN_COORD_VAL;
double minX = MAX_COORD_VAL;
double maxY = MIN_COORD_VAL;
double minY = MAX_COORD_VAL;
double tempX = 0;
double tempY = 0;
if (self = [super init]) {
int i = 0;
//determine min/max extrema to help calculate the bounding rect
for (id coordDict in pointsArray){
tempX = [[coordDict objectForKey:#"latitude"] doubleValue];
tempY = [[coordDict objectForKey:#"longitude"] doubleValue];
maxX = fmax(tempX, maxX);
minX = fmin(tempX, minX);
maxY = fmax(tempY, maxY);
minY = fmin(tempY, minY);
CLLocationCoordinate2D coord = {tempX,tempY};
points[i] = MKMapPointForCoordinate(coord);
i++;
}//for
CLLocationCoordinate2D northWestCorner = CLLocationCoordinate2DMake(maxX, minY);
CLLocationCoordinate2D southEastCorner = CLLocationCoordinate2DMake(minX, maxY);
MKMapPoint northWestPoint = MKMapPointForCoordinate(northWestCorner);
MKMapPoint southEastPoint = MKMapPointForCoordinate(southEastCorner);
boundingRect = MKMapRectMake(northWestPoint.x, northWestPoint.y,
(southEastPoint.x-northWestPoint.x),
(southEastPoint.y-northWestPoint.y));
centerCoord = CLLocationCoordinate2DMake((maxX-minX)/2,(maxY-minY)/2);
polygon = [MKPolygon polygonWithPoints:points count:[pointsArray count]];
polygon.title = overlayTitle;
[self initAcceptedPermitsBasedOnTitle:overlayTitle];
}//if
return self;
}
//...
Thanks.
EDIT 2:
An alternate method I have tried, to no avail:
ParkingMapViewController.m
NSArray *overlayArray = [[NSArray alloc] initWithArray:[mapView overlays]];
[self.mapView removeOverlays:mapView.overlays];
[self.mapView addOverlays:overlayArray];
Removing and re-adding all overlays ain't working too well for me. It merely crashes when that third line is executed. Any ideas?
EDIT 3:
So I changed the previously posted code to the following:
NSArray *overlayArray = [mapView overlays];
[self.mapView removeOverlays:overlayArray];
[self.mapView addOverlays:overlayArray];
And am now seeing this in the console:
2011-05-05 14:24:54.145 Parking[68501:207] -[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0
2011-05-05 14:24:54.147 Parking[68501:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0'
Chances are you haven't set up the coordinate or boundingMapRect properties on the MKOverlay correctly. The MapView will only ask for the view if it thinks there is a possibility that it is visible, if its visible rect doesn't intersect the boundMapRect, it won't.
Also make sure your delegate for the mapView is set properly.
So I figured it out. Not necessarily the most efficient method, but it works for me. This is what I did:
[self.mapView removeOverlays:[mapView overlays]];
[self loadOverlaysAndAnnotations];
And here is loadOverlaysAndAnnotations:
- (void)loadOverlaysAndAnnotations {
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
CoreDataSingleton *coreDataSingleton = [CoreDataSingleton sharedManager];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"ParkingLot" inManagedObjectContext:[coreDataSingleton managedObjectContext]];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [[coreDataSingleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *overlayEntity in fetchedObjects) {
NSArray *pointsArray = [NSArray arrayWithArray:[overlayEntity valueForKey:#"overlayCoordPoints"]];
ParkingRegionOverlay *regionPolygon = [[ParkingRegionOverlay alloc] initWithPoints:pointsArray andTitle:[overlayEntity valueForKey:#"lotName"]];
[mapView addOverlay:regionPolygon];
[regionPolygon release];
NSSet *annotationsSet = [NSSet setWithSet:[overlayEntity valueForKey:#"parkingAnnotations"]];
NSArray *allAnnotations = [NSArray arrayWithArray:[annotationsSet allObjects]];
CLLocationCoordinate2D workingCoordinate;
for (ParkingAnnotations *annotation in allAnnotations) {
ParkingAnnotation *parkingAnnot = [[ParkingAnnotation alloc] init];
workingCoordinate.latitude = [[annotation latitude] doubleValue];
workingCoordinate.longitude = [[annotation longitude] doubleValue];
[parkingAnnot setCoordinate:workingCoordinate];
[parkingAnnot setTitle:[overlayEntity valueForKey:#"lotName"]];
if ([[overlayEntity valueForKey:#"lotName"] isEqualToString:#"VP 1"]) {
[parkingAnnot setLot:lot1];
}
[mapView addAnnotation:parkingAnnot];
[parkingAnnot release];
}
}
[fetchRequest release];
}//loadOverlaysAndAnnotations
In short, I didn't have to create a new function but merely call the function I used to load overlays into the map view and that works fine! Hope this helps anyone else stuck in a similar situation.
EDIT:
Important to note that I am reloading BOTH annotations and overlays, and, if done without first removing both annotations and overlays, can lead to crashing of your app if the reload function is called too many times. This is what I am currently experiencing. Just something to be aware of. To fix this I am going to have separate load functions, one for overlays, and one for annotations which will be called appropriately.