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

Commit

Permalink
Maintain rotation when fitting to bounds
Browse files Browse the repository at this point in the history
Also fit to the rotated bounds. A little more verbose than necessary due to <http://stackoverflow.com/a/2357688/4585461>.

ref mapbox/mapbox-gl-js#1338
  • Loading branch information
1ec5 committed Jun 26, 2015
1 parent 1d11624 commit bcbb56c
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,31 +147,39 @@ void Map::setLatLngZoom(LatLng latLng, double zoom, Duration duration) {
}

void Map::fitBounds(LatLngBounds bounds, EdgeInsets padding, Duration duration) {
// Zoom level calculation below assumes no rotation.
setBearing(0);
// Calculate the bounds of the possibly rotated `bounds` parameter with respect to the viewport.
vec2<> nwPixel = pixelForLatLng({bounds.ne.latitude, bounds.sw.longitude});
vec2<> swPixel = pixelForLatLng(bounds.sw);
vec2<> sePixel = pixelForLatLng({bounds.sw.latitude, bounds.ne.longitude});
vec2<> nePixel = pixelForLatLng(bounds.ne);
vec2<> visualBounds = {
(std::max(std::max(nwPixel.x, swPixel.x),
std::max(sePixel.x, nePixel.x)) -
std::min(std::min(nwPixel.x, swPixel.x),
std::min(sePixel.x, nePixel.x))),
(std::max(std::max(nwPixel.y, swPixel.y),
std::max(sePixel.y, nePixel.y)) -
std::min(std::min(nwPixel.y, swPixel.y),
std::min(sePixel.y, nePixel.y))),
};

// Calculate the zoom level.
vec2<double> nePixel = pixelForLatLng(bounds.ne);
vec2<double> swPixel = pixelForLatLng(bounds.sw);
vec2<double> size = nePixel - swPixel;
double scaleX = (getWidth() - padding.left - padding.right) / size.x;
double scaleY = (getHeight() - padding.top - padding.bottom) / size.y;
double minZoom = getMinZoom();
double maxZoom = getMaxZoom();
double scaleX = (getWidth() - padding.left - padding.right) / visualBounds.x;
double scaleY = (getHeight() - padding.top - padding.bottom) / visualBounds.y;
double minScale = std::fmin(scaleX, scaleY);
double zoom = std::log2(getScale() * minScale);
zoom = std::fmax(std::fmin(zoom, maxZoom), minZoom);
zoom = std::fmax(std::fmin(zoom, getMaxZoom()), getMinZoom());

// Calculate the center point of a virtual bounds that is extended in all directions by padding.
vec2<double> paddedNEPixel = {
vec2<> paddedNEPixel = {
nePixel.x + padding.right / minScale,
nePixel.y + padding.top / minScale,
};
vec2<double> paddedSWPixel = {
vec2<> paddedSWPixel = {
swPixel.x - padding.left / minScale,
swPixel.y - padding.bottom / minScale,
};
vec2<double> centerPixel = (paddedNEPixel + paddedSWPixel) * 0.5;
vec2<> centerPixel = (paddedNEPixel + paddedSWPixel) * 0.5;
LatLng centerLatLng = latLngForPixel(centerPixel);

setLatLngZoom(centerLatLng, zoom, duration);
Expand Down

0 comments on commit bcbb56c

Please sign in to comment.