I've problem with Objective C at the moment with developing something special.
So - after the MKMapView is initialized and the users position is shown, I would like to implement a method to show annotations which are next to users position. I've stored all necessary points in an SQLite database in a special table. I've two fields - namely lonand lat- I think it's clear what is meant by that.
Has anybody an idea how to show JUST those annotations which are visible at the screen to be as performant as possible. After the user scrolls the map - it should call the method again to look up in database wether there are also other points which need to be shown...
Thank you very much in advance for your help,
kind regards,
Dominik
You will need to do a few things.
1) Get the center of your map - use the centerCoordinate property of your MKMapView
2) Ask your database for all items within a certain distance from the center of the map.
3) Display them
It's (2) that's the tricky one - you need a method that will return all items near to the lat lng you have.
This link has a handy implementation of how to do that :)
Hope that helps.
A couple of points:
If you're using iOS4, the mapview behaviour has changed so that it automatically saves memory by only creating the annotations which are in the visible view.
Secondly, in the same way that you can create a tableview with thousands of cells and still have it scroll smoothly, the annotations offscreen don't affect the performance that much. You should be keeping your annotations very small so they don't consume much memory. The annotation views are the ones that take up the memory.
Your problem is going to come when the user zooms out and there are too many annotation views visible at the same time. When you're zoomed in, you don't need to worry too much about off-screen annotations.
Related
Using annotations with Map Kit, you can put pins, or even custom images onto the map. Cool.
However, the data I'm using has millions of locations, spread out across the world. I don't want to dump them all on the map, especially since the user is only looking at a small bit of it. It would kill responsiveness, and probably crash.
Is there a standard technique for putting these pins on to the map only when required? i.e only when they need to be on the map view (and the immediately surrounding area). And removing them when the user has scrolled away. Something similar to UITableView's dequeueReusableCell..?
There's MKMapView's dequeueReusableAnnotationViewWithIdentifier: method which seems to do exactly what you want.
Check out this piece of code: http://www.cocoanetics.com/parts/dtclustermaker/
While it's 100 EUR, it certainly depends on your usage for that amount of money. But it might be worth it. If not, it might get you on your way to find something else via Google searching.
I'm in a situation where there will be 500+ annotations to load onto a map. What some ways that you have dealt with the resulting lag with so many annotations on the map?
One thing I've considered: only loading a portion of the annotations based on the current map region in view. But what happens when they zoom out or move around? Reload based on the region displayed?
MKMapView has a dequeueReusableAnnotationViewWithIdentifier: method (documentation) that I believe you're supposed to use. It looks like it works similarly to UITableView's dequeueReusableCellWithIdentifier: method.
Another thing might be to group clustered pins together into one pin. As you zoom in, you can expand these groups.
update: Found a cool open-source library that might be useful for dealing with tons of annotation points: ADClusterMapView
I'm pretty new to iphone development, so this is more of a high-level question. The simplest description of what I am looking to do is create a zoomable/panable field on which I can place a bunch of circle objects. The number of these circles is likely to be in the hundreds, and ideally when the user zooms in close enough, more information can be displayed. From stuff I've read, it seems like UIScrollView provides the simplest way of making a zoomable/panable view but I'm not sure it's the best way to handle a view that includes a hundred graphic objects. I'm trying to figure out if I should progress further down that path or look into things like CALayers, Core Graphics, etc. Any guidance or advice would be greatly appreciated. Thanks in advance,
Roman
I suggest you to use UIScrollView, because it will save a lot of time for handling proper zooming/scrolling. So the workflow is next:
1. Zoom you scroll view
2. In delegate's callback scrollViewDidEndZooming:withView:atScale: you can obtain the scale and determine the level of detail that you need.
3. redraw the visible region (using Core Graphics) with appropriate level of detail (number of circles etc.)
So you should use the mix of Core Graphics and UIKit.
Instead of loading all annotations that are in my array, I would only like to load the annotations that the user could currently see cased on how far they are zoomed in on the map. So, if the user pans to a place where there are annotations, those would be added, and if they pan away, those would be removed. I assume this would help with memory.
Does anyone know how to do something like this? And, is it worth it, or needed?
It is not needed. MapKit takes care of optimizing the display and allocation of annotation views. You should load all your annotations and let the framework do its job, just as the documentation advises.
The annotations themselves should be quite small, and should not have a significant hit on memory use.
Background: I have created an application that allows users to submit an entry to an online database, and view other entries from that database. These entries contain geocodes for latitude and longitude which are used for positioning the annotations on the MapKit. Users can submit the location using either their current location or an address, which is then geocoded.
Question: What is the proper or suggested method of handling annotations that fall on the exact same coordinates?
I was thinking of checking if there are any duplicate geocodes in the XML file pulled from the database and creating a single annotation with a custom annotationView that displays all of the separate ones. In addition, I was thinking of checking for duplicates and displaying "Multiple Entries..." and having the detail view display a table view with all of the entries.
Am I on the right track?
I think you are on the right track, you should check for duplicate geocodes and merge them into one. Displaying many annotations with the same location could be confusing because the pins will stack on top of each other and will be hard to diffrentiate and to click one by one.
Are you talking exact same geocode or kinda sorta close? Because if it's exact, then you're on the right track, but if it's +/- delta-T then you may have to come up with a different way of handling them since when zoomed-in all the way each location could be distinct. An easy way to hanle it is to drop or round-off decimal points in the lat/long value based on the zoom factor before checking for coordinate equality.
Other than that it sounds like you're on the right track. You will probably want to do both the custom annotation view (but that could work for only a few items) with the option to move on to a separate table view if there are more items to show.
One other thing I'd add is you could make it so your placemarker shows the number of items that co-reside in that location. You can do this by sticking a text label on top of your custom placemarker view and putting the number in it or by having pre-rendered icons with say, 1-9 and "..." (for more than that) in the heads of the markers. That way the user can quickly see there's more items to look for.