Best practice for 2000+ annotations in MapKit

I have a JSON file that contains about 2000 locations that I need to display on the map when the camera is less than 750 meters high. Here is my current code:

func addStops() { var path: String! = NSBundle.mainBundle().pathForResource("stops", ofType: "json") var jsonData: NSData! = NSData(contentsOfFile: path) var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary self.busStops = jsonResult["results"] as NSArray for (var i = 0; i < self.busStops.count; i++) { let lat = self.busStops[i]["latitude"] as NSString let lng = self.busStops[i]["longitude"] as NSString var annotation = busAnno() annotation.setCoordinate(CLLocationCoordinate2DMake(CLLocationDegrees(lat.doubleValue), CLLocationDegrees(lng.doubleValue))) annotation.type = "stop" self.mapView.addAnnotation(annotation) } } 

And the annotation view delegate:

 func mapView (mapView: MKMapView!, viewForAnnotation annotation: MKPointAnnotation!) -> busMarker! { var pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point") pinView.location = annotation.location pinView.hidden = true pinView.layer.hidden = true pinView.enabled = false } 

It seemed to me that I can leave just by hiding my eyes, but 20 seconds before the application even responds by adding markers, it takes 20 seconds, and then it is impossible to smoothly move the card (drops to 5 frames per second).

So, if I can’t do this, then which approach is better? I assume that checking for a pair of coordinates within the boundaries of the screen every time the map move will not work properly due to a delay (based on checking 2000 coordinates each time). Any ideas?

EDIT

You will only see 10 annotations of the year 2000, as you have to be very enlarged to see them. This is just the case when I use the quick search method for annotations in this region without this terrifying delay.

+5
source share
2 answers

You can add ~ 1000 annotations to MKMapView easily. Take a look at this sample project, which adds 3000:

https://github.com/incanus/PointTest

There are several things you can do to make this work better.

  • Just use MKPointAnnotation , then you do not need to provide the presentation manually.

  • If you need a custom view, you must use the reuse identifier correctly. You are currently creating a new view for each annotation, when in fact you can reuse similar views over and over to improve performance.

  • You analyze and add your annotations to the main user interface stream, which affects the performance of the touch response. See the project described above to do this in the background using Grand Central Dispatch, but actually adding annotations (all at once, I can add) to the main UI thread.

You do not need to worry about whether the annotations are on screen or not. MapKit does this for you, so it requests a view in the delegate callback, not in the upfront.

The following link is no longer valid (October 2017)

Here's a video of 3,000 annotations found on the iPhone 5s:

https://dl.dropboxusercontent.com/u/575564/3000points.mov

+4
source

Sorry, I'm too new to post a comment, so I will answer your question about the proper use of the reuse identifier here.

Basically you want to replace:

 var pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point") 

from:

 var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("point") if pinView != nil { pinView.annotation = annotation; } else { pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "point") } 
+2
source

Source: https://habr.com/ru/post/1208068/


All Articles