Tiling annotations with Map Kit - iphone

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.

Related

Finding a free space within current bounds of view on iOS

I have an infinite scrollview in which I add images as the user scrolls. Those images have varying heights and I've been trying to come up with the best way of finding a clear space inside the current bounds of the view that would allow me to add the image view.
Is there anything built-in that would make my search more efficient?
The problem is I want the images to be sort of glued to one another with no blank space between them. Making the search through 320x480 pixels tends to be quite a CPU hog. Does anyone know an efficient method to do it?
Thanks!
It seems that you're scrolling this thing vertically (you mentioned varying image heights).
There's nothing built in to UIScrollView that will do this for you. You'll have to track your UIImageView subviews manually. You could simply maintain the max y coordinate occupied by you images as you add them.
You might consider using UITableView instead, and implementing a very customized tableView:heightForRowAtIndexPath: in your delegate. You would probably need to do something special with the actual cells as well, but it would seem to make your job a little easier.
Also, for what it's worth, you might find a way to avoid making your solution infinite. Be careful about your memory footprint! iOS will shut your app off if things get out of hand.
UPDATE
Ok, now I understand what you're going for. I had imagined that you were presenting photographs or something rectangular like that. If I were trying to cover a scroll view with UILeafs (wah wah) I would take a statistical approach. I would 'paint' leaves randomly along horizontal/vertical strips as the user scrolls. Perhaps that's what you're doing already? Whatever you're doing I think it looks good.
Now I guess that the reason you're asking is to prevent the little random white spots that show through - is that right? If I may suggest a different solution: try to color the background of your scroll view to something earthy that looks good if it shows through here and there.
Also, it occurred to me that you could use a larger template image -- something that already has a nice distribution of leaves -- with transparency all along the outside outline of the leaves but nowhere else. Then you could tile these, but with overlap, so that the alpha just shows through to the leaves below. You could have a number of these images so that it doesn't look obvious. This would take away all of the uncertainty and make your retiling very efficient.
Also, consider learning about CoreAnimation (CALayer in particular) and CoreGraphics/Quartz 2D ). Proper use of these libraries will probably yield great improvements in rendering speed.
UPDATE 2:
If your images are all 150px wide, then split your scrollview into columns and add/remove based on those (as discussed in chat).
Good luck!

How to deal with lag resulting from hundreds of map annotations on an MKMapView?

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

Show annotation on MKMapView based on user location

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.

iPhone: GPS on custom map + CATiledLayer

Really hope someone can help me as I'm a bit stuck :S
I have a custom map of an event using the CATiledLayer so users can zoom in and scroll around the map. What I would like to do now is add the functionality to let the user know where they currently are on the map. I know it can be done as I've seen an app do this before. I'm not sure how to go about doing it though, maybe I need to convert lat/lon into pixels but I'm not sure if thats possible (depending on how big the image is, etc).
On another site it was mentioned to find out the boundaries of the map and then I can add pins to the map, but I'm not sure how to go about doing this? Will I need to find every coordinate (lat/lon) within the boundary so I can add the pin of where the user is currently?
If anyone can give me with any advice or pointers, I'd much appreciate it
You can use the route-me library by adding your own map source class. A good article that explains how to do it is here http://mobilegeo.wordpress.com/2010/07/07/route-me-native-iphone-mapping-framework/
I'm facing a challenge right now in trying to map GPS coords to a map that's an artist's rendition. In particular this is for a ski mountain, so the artist's rendition is a "trail map". The trail map is not accurate in that the whole mountain has been squeezed onto the one view, yet the actual topology of the mountain doesn't conform to the drawing.
I've tried several approaches:
1) Triangulation using known GPS coordinates of the lift stations. This is fairly simple to implement, yet this is not accurate enough and the algorithm fails if the rendition differs enough from the GPS map.
2) Creating a uniform grid for both the GPS map and the Trailmap, then doing a mapping from cells in the GPS map to the Trailmap. The downside to this is it can be a lot of busy work with no easy UI for doing it.
3) Calculating the vectors of each lift (being a straight line), find the closet lift station to a given GPS point, and calculate the estimated Trailmap location using this vector.
I'm considering #2, which is essentially the simplest solution. But if you've found a better way, I'd love to hear it.

Mapkit: Only show annotations in current view

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.