Glen Cloake
Glen Cloake

Reputation: 61

Limit number of shown annotations

Hi I have my app working well, it loads annotations to several different maps from different plists.

My issue is there are approximately 5000 annotations on one of my plist's and the map view takes approximately 20 seconds to show the annotations.

Is there any way to perhaps limit the amount of annotations loaded to say a 20km radius of the current location?

Will this shorten the load time?

I don't want to have to redo all from scratch and set up a database as I am basically done so a plist is what I have.

Upvotes: 1

Views: 325

Answers (2)

Abhi Beckert
Abhi Beckert

Reputation: 33369

5,000 points is not very many, I've got databases with 100,000 points and it's still significantly faster than that (I am not using MapKit). If it is taking 20 seconds, then it must be doing some kind of network traffic for each marker?

Does your plist contain the latitude/longitude of each marker? If so, then you can create a CLLocation object for each marker on the map, and a CLLocation object for the centre of the map, and then use [mapCentre distanceFromLocation:markerLocation] to calculate the distance (in metres) from the centre to the marker.

Drop anything that isn't on the map, and you should be good to go.

If you want to split your plist into smaller files, I would split them up by their location. For example any marker who's latitude/longitude begins with 125.1/-19.1 would be in a single file.

My experience working with australia, is cities like melbourne have a ton of stuff in a very small area, while the rest of the country is pretty much empty. So it's hard to split things up into smaller chunks.

Also, run your app through the "Time Profile" feature in Instruments to find out what is actually taking so long. This is the Product -> Profile menu item in Xcode. You can find plenty of tutorials how to use it online.

Upvotes: 1

user467105
user467105

Reputation:

The option I'm suggesting, if you want to stay with plists, is to break the large plist into smaller ones that cover smaller regions.

If breaking them up into the 7 Australian states gives the level of performance you need, then that's fine. But I would instead create smaller regions (all rectangular) each covering some fixed N number of degrees on a side. N should not be too small but not too large either (it depends on how far away from the current location you want to show data).

For example, you could break up the single plist into 16 regions like this (it doesn't have to be a square number):

         North

        A B C D
 West   E F G H   East
        I J K L
        M N O P

         South

Plist "A" would contain annotation data for say Lat 50 to 51 and Lon 100 to 110.
Plist "B" would contain annotation data for Lat 50 to 51 and Lon 110 to 120.
Plist "E" would contain annotation data for Lat 49 to 50 and Lon 100 to 110.
Etc.

I would also have an additional "index" plist that would let the app figure out which plist a given coordinate is in and what that plist's neighbors are. The app could then read the annotation data from the current location's plist and its neighbors in case the current location is near the edge of a region.

The index plist's structure might look like this:

PlistName  NWCoordinate  SECoordinate  Neighbors
A          51,100        50,110        B, E, F
F          50,110        49,120        A, B, C, E, G, I, J, K

The index plist would be read once at the start of the app.

Then once the app has the current location (or whenever it changes significantly enough), the app would do the following:

  • Remove existing annotations from the map.
  • Use the index to figure out which plist(s) to load the new annotations from. Assume the current location is 49.25, 112.3. Using the index, the app loads the F plist and its neighbors into some array (not directly to the map one at a time).
  • Add the annotations in the array in one shot using addAnnotations.

Upvotes: 1

Related Questions