Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[MGLMapView zoomToSouthWestCoordinate:northEastCoordinate:] not coordinates deterministic #1433

Closed
friedbunny opened this issue May 5, 2015 · 1 comment · Fixed by #1783
Assignees
Labels
bug iOS Mapbox Maps SDK for iOS
Milestone

Comments

@friedbunny
Copy link
Contributor

Using [MGMapView zoomToSouthWestCoordinate:northEastCoordinate:animated:] produces a different result based on the zoom/scale of the map.

I expected the method to always fit the given coordinates on the screen — instead, it zooms in on their center point at a zoom level calculated based on _mbglMap->getScale(). This often results in z18 and never actually fits the viewport to the exact coordinate bounds.

Calling the method repeatedly with the same coordinates but at different zooms yields this:

Mapbox GL: input-zoom: 13.45   scale: 11161.71     output-zoom: 18.00
Mapbox GL: input-zoom: 15.78   scale: 56414.93     output-zoom: 18.00
Mapbox GL: input-zoom: 3.69    scale: 12.91        output-zoom: 9.18
Mapbox GL: input-zoom: 9.18    scale: 578.48       output-zoom: 14.66
Mapbox GL: input-zoom: 14.66   scale: 25918.91     output-zoom: 18.00

[MGMapView zoomToSouthWestCoordinate:northEastCoordinate:animated:] is only used right now for centering the map on the user location annotation and is somewhat broken for that purpose, too, besides not being a public method. (#1092 tracks what to do about this API decision.)

I would like to use this method for bounds-based syncing in the demo app I'm working on, so I've hacked together an interim solution, but the maths are absolutely wrong:

- (void)fitBoundsToSouthWestCoordinate:(CLLocationCoordinate2D)southWestCoordinate northEastCoordinate:(CLLocationCoordinate2D)northEastCoordinate animated:(BOOL)animated
{
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake((northEastCoordinate.latitude + southWestCoordinate.latitude) / 2, (northEastCoordinate.longitude + southWestCoordinate.longitude) / 2);

    CGFloat scaleX = _mbglMap->getWidth() / (northEastCoordinate.longitude - southWestCoordinate.longitude);
    CGFloat scaleY = _mbglMap->getHeight() / (northEastCoordinate.latitude - southWestCoordinate.latitude);
    CGFloat minZoom = _mbglMap->getMinZoom();
    CGFloat maxZoom = _mbglMap->getMaxZoom();
    CGFloat hack = ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait) ? 0.5f : 1.f;
    CGFloat zoomLevel = log(MIN(scaleX, scaleY)) / log(2) - hack;
    zoomLevel = MAX(MIN(zoomLevel, maxZoom), minZoom);

    [self setCenterCoordinate:center zoomLevel:zoomLevel animated:animated];
}

I put together a demonstration of this bug and my hack in a branch here. Use the action sheet's "Zoom to Oregon" option to see new default behavior.

/cc @incanus @1ec5

@friedbunny
Copy link
Contributor Author

My hack inexplicably appears to work very well, I can make it match Google's fitBounds perfectly (although without UIEdgeInsets support). This will be sufficient for Treble, but clearly our bounds fitting code needs cleaning up and somebody to explain/correct the math.

@friedbunny friedbunny changed the title [MGMapView zoomToSouthWestCoordinate:northEastCoordinate:] not coordinates deterministic [MGLMapView zoomToSouthWestCoordinate:northEastCoordinate:] not coordinates deterministic May 24, 2015
@1ec5 1ec5 self-assigned this Jun 23, 2015
@1ec5 1ec5 added this to the iOS Beta 3 milestone Jun 23, 2015
@1ec5 1ec5 added bug iOS Mapbox Maps SDK for iOS labels Jun 23, 2015
@1ec5 1ec5 mentioned this issue Jun 23, 2015
9 tasks
@1ec5 1ec5 removed the in progress label Jun 26, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants