Question

I've searched a bit around the web and found a few ideas on how to do what I want, but I would still like to know what you think I should do.

Here is the context :

I'm developing an app for iOS 5. I use MapKit to display a map, and I add around 5000 annotations to it - yup, that seems a lot, but don't worry, I use a clustering library :). In order not to load them every time the user opens the map, I create them in my appDelegate (I create an array of annotations, and call [_mapView addAnnotations:[appDelegate.annotationsToAdd allObjects]]; when I open the map). It takes about roughly 10 seconds to create the annotationsToAdd array, so I think this solution is working pretty well (you have to wait for those 10 seconds before being authorized to open the map, but you only wait once, at the launch of the app). In each of those annotations, I have a "link" to an object, which contains an array of values (15 floats). For now, when I create the annotation, the subtitle method returns one of those values.

In my map's ViewController, I have 2 segmented controls. The first one has 3 segments, the second one has 5, which gives 15 combinations - yup again, that's the same number of values the array of the object in my annotation has :).

So you may have seen my problem coming, I would like to update the subtitle of every annotation on my map (even the ones in the clusters, as the cluster gives an average value based on the pins it holds). What I would also want is to update the annotationView's color/image based on the value of the annotation's subtitle.

I may be wrong, but based on my research, I understand that you have to remove all the annotations, and recreate them all in order to do that. you understand that this is not an option in my case. I can't make the user wait 10 seconds every time he changes the value of one of the controls.

I saw an article on KVO: could that be a working solution ?

I don't know much about NSNotification, but should I use them ?

I would really appreciate your help, and I would even more appreciate a detailed answer, showing me the steps to follow in my apparently uncommon situation.

Thanks in advance.

Was it helpful?

Solution

I am sorry if I haven't finally understood your situation quite well, but I feel like I am moving towards solving a similar problem so I'll try to share my thoughts with you. I will use your words as the guides for my response:

"you have to wait for those 10 seconds before being authorized to open the map"

Do you know about the following <MKOverlayView> protocol methods (see http://developer.apple.com/library/IOs/#documentation/MapKit/Reference/MKOverlayView_class/Reference/Reference.html):

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale

(Assuming that you have 5000 pins on entire world map, not on every fx 1km, i.e. not SO LARGE amount of pins) You can split your five thousands into the portions, so each portion of pins is to be populated by the corresponding MKMapRect region which is being drawn on the map. So your map is populated with pins/annotations, by demand, only for particular region at any given time. Depending on your situation this could bring a huge speed up.

This is a very good demonstration of working with MKMapRect tiles: https://github.com/mtigas/iOS-MapLayerDemo - populate with information only particular pieces of map. Also you may google something like "Map tiles 256px" to understand how the maps are being drawn.

"I understand that you have to remove all the annotations, and recreate them all in order to do that."

Why recreate? You do have an access to all the annotations that are already there on your map - why not just iterate through your associated annotations classes and update theirs subtitles?

Something like:

I hope that my points do address the scope of your question/situation.

OTHER TIPS

First of all, you should just be adding the annotations all at once, not using a clustering library:

When configuring your map interface, you should add all of your annotation objects right away. The map view uses the coordinate data in each annotation object to determine when the corresponding annotation view needs to appear onscreen.

(From MKMapView Class Reference).

MKMapView will manage them for you so your app doesn't slow down. This approach will probably not be any slower than what you're doing, and then you could theoretically do:

[mapView removeAnnotations:mapView.annotations];
//add your annotations here

if you wanted to remove all of them and then add them all back.

However, you're incorrect that you have to remove them all at once. If you know of a specific annotation, you can simply do:

[mapView removeAnnotation:someAnnotation];
[mapView addAnnotation:someOtherAnnotation];

If you have the replacements in an NSArray, you can even:

[mapView removeAnnotations:arrayOfOldAnnotations];
[mapView addAnnotations:arrayOfNewAnnotations];

Finally, if you'd like to modify an annotation, you can do it using KVO (see this Stack Overflow question), but it's just as easy to remove, then add one, and the user won't notice as long as you aren't animating the add.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top