views:

220

answers:

1

Can anyone confirm that setRegion "snaps" to predefined zoom levels and whether or not this behavior is as designed (although undocumented) or a known bug? Specifically, it appears that setRegion snaps to the same zoom levels that correspond to the zoom levels used when the user double-taps the map.

I'm trying to restore a previously saved region but this behavior makes it impossible if the saved region was set via a pinch zoom and not a double-tap zoom.

A big clue to me that things are broken on the mapkit side is what occurs if I call regionThatFits on the map's current region. It should return the same region (since it obviously fits the map's frame) but it returns the region that corresponds to the next higher predefined zoom level instead.

setVisibleMapRect behaves similarly.

Any further insight or information would be appreciated.

I found these related posts but neither included a solution or definitive confirmation that this is in fact a mapkit bug:

http://stackoverflow.com/questions/1365417/mkmapview-setregion-odd-behavior

http://stackoverflow.com/questions/1383296/why-mkmapview-region-is-different-than-requested

EDIT:

Here is an example that demonstrates the problem. All values are valid for my map view's aspect ratio:

MKCoordinateRegion initialRegion;
initialRegion.center.latitude = 47.700200f;
initialRegion.center.longitude = -122.367109f;
initialRegion.span.latitudeDelta = 0.065189f;
initialRegion.span.longitudeDelta = 0.067318f;
[map setRegion:initialRegion animated:NO];
NSLog(@"DEBUG initialRegion:  %f  %f  %f  %f", initialRegion.center.latitude, initialRegion.center.longitude, initialRegion.span.latitudeDelta, initialRegion.span.longitudeDelta);
NSLog(@"DEBUG map.region:  %f  %f  %f  %f", map.region.center.latitude, map.region.center.longitude, map.region.span.latitudeDelta, map.region.span.longitudeDelta);

OUTPUT:

DEBUG initialRegion:  47.700199  -122.367111  0.065189  0.067318
DEBUG map.region:  47.700289  -122.367096  0.106287  0.109863

Note the discrepancy in the latitude/longitude delta values. The map's values are almost double what I requested. The larger values correspond to one of the zoom levels used when the user double-taps the map.

A: 

I restore the region with no problem and with no variance as you describe. It is really impossible to tell what is specifically wrong in your case without some code to look at but here's what works for me:

Save both the center and span values somewhere. When you are restoring them specifically set both the center and span.

Restoring should look like this:

MKCoordinateRegion initialRegion;
initialRegion.center.latitude = Value you've stored
initialRegion.center.longitude = Value you've stored 
initialRegion.span.latitudeDelta = Value you've stored
initialRegion.span.longitudeDelta = Value you've stored
[self.mapView setRegion:initialRegion animated:NO];

Also remember that this method is available in 4.0: `mapRectThatFits:edgePadding: MapRectThatFits helpfully adds a reasonable border to ensure that say a map annotation on the edge is not obscured and the the rect that you're attempting to display is fully visible. If you want to control the border use the call that gives you access to set edgePadding as well.

Nick
Thanks. I've updated my original post with a specific example borrowed from your sample that demonstrates the problem.
charshep
Thanks for the code details. Couple of followup questions. Where did those floats come from? Are you reading them out of the property from the map when you are pinch/spread zooming?What are the dimensions of the map view?This is interesting because I read the values out when my view is unloading and save them to UserSettings. I have no problems restoring my view accurately.
Nick
Yes, I pulled those from my map's region property after a pinch zoom. Dimensions are 460 x 320, running in the iPhone 4 simulator.
charshep
I'm really sorry. I feel like an idiot because I'm seeing this behavior too it seems to be varied depending on zoom levels and positioning I didn't test adequately with pinch zooming. I wonder if working through the new mapRectThatFits: edgePadding: would work. I'll experiment a bit and circle back. Apologies again for my mix up.
Nick
Don't apologize! It's surprisingly easy to miss for how obvious it sounds. It took me a while to notice as well. I'm just relieved you're able to confirm the problem. Thanks again for looking into it.One side note. You'll notice it's not an issue if you restore a region that was set by double-tapping rather than pinch zooming; further evidence that setRegion is "snapping" the region its given. This is why it took me a while to notice. It's much easier to double-tap zoom in the simulator than to pinch zoom so I was always tap-zooming.
charshep
Just curious if you've tried `setVisibleMapRect:edgePadding:animated:`, because for me the edge insets appear to be getting ignored. Does it honor the edge insets for you?
Daniel Dickison