Outdooractive / route-me

Open source map library for iOS
Other
122 stars 400 forks source link

rendering snapshot of map view #15

Closed incanus closed 12 years ago

incanus commented 12 years ago

I've been working for quite some time on trying to get a quick UIImage snapshot of the current map view, similar to how you can do with other views using -[CALayer renderInContext:]. I've tried using both RMMapTiledLayerView's drawRect: as well as implementing drawLayer:inContext: but to no avail. The routine is (according to the standard use of CATiledLayer) only meant to handle requests for one tile at a time.

Have you ever experimented with this? I'm currently lost in the translation & scaling math to try to iteratively render tiles manually to a new context in order to stitch them together and capture an image. Wondering if you had any insight.

trasch commented 12 years ago

I haven't thought about it yet, but I think its a good idea. I took your implementation and adapted it to use the tilesource directly instead of using the CATiledLayer, and it crops the final image to the mapview bounds. (I had to bang my head against the wall a few times, but it works). Its not done yet, though.

If you are interested, please have a look at it (in the "snapshot" branch, RMMapView class), but I don't think it solves all of your problems.

If you want to capture the scroll view animations in-flight, I think you would have to do the animation for yourself frame by frame and take a snapshot at each step. Actually, I thought about trying this for the marker synchronization issue (#7, I think), but it wasn't worth the effort.

incanus commented 12 years ago

I will check out your branch.

On the animation front, my app (here, by the way) uses an NSTimer at 1/64th second to run the animations when using the app, as well as subclassing UIScrollView in order to allow for variable-duration pan & zoom animations (I will be contributing this back to your fork eventually). So in live use of the app, say a pan animation takes one second. In video export mode, the timer slows down to 1/8th second and additionally, this animation duration gets changed to eight seconds, but with the same timing curve(s). Then I'm able to more reliably capture frames as images. UIGetScreenImage (private API) works well here and is fast enough. I just need a valid capture method now.

incanus commented 12 years ago

Well, I can't complain. This is pretty good. I think it will do what I need. I've been banging my head against a wall myself for nearly a week with the CATiledLayer approach, in the hopes of either highlighting a change for Apple to make or at least releasing a category on it that supplies the missing functionality.

trasch commented 12 years ago

Btw I found a bug before I left the office. At the moment, snapshots only work for even zoom levels, because there is something wrong with the borderTop computation...

incanus commented 12 years ago

You are right in that this won't work for me because of the animation frame issue. It just knows the start & end points. I'm not sure if manually animating is worth the effort for me, rather than fixing up the snapshotting.

incanus commented 12 years ago

I've got the layer-based method working up to everything except proper cropping now. That is, I get a properly-scaled render of the current map view, with full tiles extending beyond the edge of the visible map view, and I'm just now working on crop. Almost there.

incanus commented 12 years ago

I think this layer-based method is going to fail me the same way, since interpolations of animations aren't able to be captured. Nothing grabs the presentationLayer like UIGetScreenImage() does, unfortunately, that I can figure out anyway.

Thanks for your work here -- this code is great. I will probably end up having to use it or my own method to manually reproduce animations, like you say.

Closing.