Skip to content

Commit

Permalink
Updated fitBounds to handle rotation (#1550)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjoelson authored Jun 12, 2023
1 parent 79b54e4 commit 359feda
Show file tree
Hide file tree
Showing 2 changed files with 505 additions and 3 deletions.
29 changes: 26 additions & 3 deletions lib/src/map/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,20 @@ class FlutterMapState extends MapGestureMixin
final paddingOffset = (paddingBR - paddingTL) / 2;
final swPoint = project(bounds.southWest, zoom);
final nePoint = project(bounds.northEast, zoom);
final center = unproject((swPoint + nePoint) / 2 + paddingOffset, zoom);

final CustomPoint<double> projectedCenter;
if (_rotation != 0.0) {
final swPointRotated = swPoint.rotate(-rotationRad);
final nePointRotated = nePoint.rotate(-rotationRad);
final centerRotated =
(swPointRotated + nePointRotated) / 2 + paddingOffset;

projectedCenter = centerRotated.rotate(rotationRad);
} else {
projectedCenter = (swPoint + nePoint) / 2 + paddingOffset;
}

final center = unproject(projectedCenter, zoom);
return CenterZoom(
center: center,
zoom: zoom,
Expand All @@ -528,10 +541,20 @@ class FlutterMapState extends MapGestureMixin
final max = options.maxZoom ?? double.infinity;
final nw = bounds.northWest;
final se = bounds.southEast;
var size = this.size - padding;
var size = nonrotatedSize - padding;
// Prevent negative size which results in NaN zoom value later on in the calculation
size = CustomPoint(math.max(0, size.x), math.max(0, size.y));
final boundsSize = Bounds(project(se, zoom), project(nw, zoom)).size;

var boundsSize = Bounds(project(se, zoom), project(nw, zoom)).size;
if (_rotation != 0.0) {
final cosAngle = math.cos(rotationRad).abs();
final sinAngle = math.sin(rotationRad).abs();
boundsSize = CustomPoint<double>(
(boundsSize.x * cosAngle) + (boundsSize.y * sinAngle),
(boundsSize.y * cosAngle) + (boundsSize.x * sinAngle),
);
}

final scaleX = size.x / boundsSize.x;
final scaleY = size.y / boundsSize.y;
final scale = inside ? math.max(scaleX, scaleY) : math.min(scaleX, scaleY);
Expand Down
Loading

0 comments on commit 359feda

Please sign in to comment.