I'm developing an app where I want to show fictional planes flying from and to airports. This may not be the only things that I want to represent flying through the map.
For this I used the sample code from LocationReminders (the MKOverlayPathView subclass they have, ReminderCircleView) and connected it to an MKOverlay of my own representing the plane. This class subscribes for KVO notifications on the coordinate and radius properties of the overlay class and invalidates its path everytime there's an update.
The overlay updates its position at several frames per second and I also update it's radius so I can simulate perspective (not very smart considering it's an model object but still the best solution I've found).
I'm using a simple circle path for testing.
This setup works fine. The overlay view gets updated and it behaves correctly, scaling along with the map and all.
The problem is that in a simulated flight the overlay won't be drawn over some of the tiles, normally near the destination. The circle looks like is going behind these tiles.
I was able to understand one thing in this problem: whenever I observe the circle not being drawn over some tile if I zoom out the circle will be drawn correctly. Zooming in or panning doesn't solve anything however.
My theory is that some of the tiles (or their map rects) are not being marked for redrawing and so, only by zooming out I can force that. But still I think that's not consistent with the fact that zooming in doesn't seem to help.
I don't know if I'm doing anything wrong or if I'm bumping into a bug or something. I've used annotations instead and it was working but with that I lose the ability to represent a plane that gets smaller if you zoom out without observing the zoom scale myself.
I've tested in versions 5.1, 6.0 and 6.1 and the behavior is the same.
I have understood what was causing that behavior.
On my MKOverlay
I was changing the boundingMapRect
to match the position of the plane at every position update.
Actually the MKMapView only asks the MKOverlay
for it in the beginning (I got to know this by checking the calls to -(BOOL)intersectsMapRect:(MKMapRect)mapRect
).
As a test I changed the boundingMapRect
to match the whole world (boundingMapRect = MKMapRectWorld;
) and it worked. Then it was only a matter of creating a MKMapRect
around the path of my plane and that was it.
Well, Apple states the following regarding boundingMapRect
:
The projected rectangle that encompasses the overlay. (required) (read-only) This property contains the smallest rectangle that completely encompasses the overlay area. Implementers of this protocol must set this area when implementing their overlay class. The rectangle should be specified using projected coordinates—that is, coordinates obtained by projecting the globe onto a two-dimensional surface.
And I'd say something like:
The projected rectangle that encompasses the overlay. (required) (read-only) This property contains the smallest rectangle that completely encompasses the area that the overlay can be presented in. Implementers of this protocol must set this area when implementing their overlay class. The rectangle should be specified using projected coordinates—that is, coordinates obtained by projecting the globe onto a two-dimensional surface.