diff --git a/src/ol/View.js b/src/ol/View.js index e1cd60c174..ae435a1c2f 100644 --- a/src/ol/View.js +++ b/src/ol/View.js @@ -1076,7 +1076,7 @@ class View extends BaseObject { * the given size. */ getResolutionForExtentInternal(extent, opt_size) { - const size = opt_size || this.getViewportSize_(); + const size = opt_size || this.getViewportSizeMinusPadding_(); const xResolution = getWidth(extent) / size[0]; const yResolution = getHeight(extent) / size[1]; return Math.max(xResolution, yResolution); @@ -1298,6 +1298,32 @@ class View extends BaseObject { this.fitInternal(geometry, opt_options); } + /** + * Calculate rotated extent + * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry. + * @return {import("./extent").Extent} The rotated extent for the geometry. + */ + rotatedExtentForGeometry(geometry) { + const rotation = this.getRotation(); + const cosAngle = Math.cos(rotation); + const sinAngle = Math.sin(-rotation); + const coords = geometry.getFlatCoordinates(); + const stride = geometry.getStride(); + let minRotX = +Infinity; + let minRotY = +Infinity; + let maxRotX = -Infinity; + let maxRotY = -Infinity; + for (let i = 0, ii = coords.length; i < ii; i += stride) { + const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle; + const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle; + minRotX = Math.min(minRotX, rotX); + minRotY = Math.min(minRotY, rotY); + maxRotX = Math.max(maxRotX, rotX); + maxRotY = Math.max(maxRotY, rotY); + } + return [minRotX, minRotY, maxRotX, maxRotY]; + } + /** * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry. * @param {FitOptions} [opt_options] Options. @@ -1319,44 +1345,28 @@ class View extends BaseObject { } else { minResolution = 0; } - const coords = geometry.getFlatCoordinates(); - // calculate rotated extent - const rotation = this.getRotation(); - const cosAngle = Math.cos(-rotation); - let sinAngle = Math.sin(-rotation); - let minRotX = +Infinity; - let minRotY = +Infinity; - let maxRotX = -Infinity; - let maxRotY = -Infinity; - const stride = geometry.getStride(); - for (let i = 0, ii = coords.length; i < ii; i += stride) { - const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle; - const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle; - minRotX = Math.min(minRotX, rotX); - minRotY = Math.min(minRotY, rotY); - maxRotX = Math.max(maxRotX, rotX); - maxRotY = Math.max(maxRotY, rotY); - } + const rotatedExtent = this.rotatedExtentForGeometry(geometry); // calculate resolution - let resolution = this.getResolutionForExtentInternal( - [minRotX, minRotY, maxRotX, maxRotY], - [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]] - ); + let resolution = this.getResolutionForExtentInternal(rotatedExtent, [ + size[0] - padding[1] - padding[3], + size[1] - padding[0] - padding[2], + ]); resolution = isNaN(resolution) ? minResolution : Math.max(resolution, minResolution); resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1); // calculate center - sinAngle = -sinAngle; // go back to original rotation - let centerRotX = (minRotX + maxRotX) / 2; - let centerRotY = (minRotY + maxRotY) / 2; - centerRotX += ((padding[1] - padding[3]) / 2) * resolution; - centerRotY += ((padding[0] - padding[2]) / 2) * resolution; - const centerX = centerRotX * cosAngle - centerRotY * sinAngle; - const centerY = centerRotY * cosAngle + centerRotX * sinAngle; + const rotation = this.getRotation(); + const sinAngle = Math.sin(rotation); + const cosAngle = Math.cos(rotation); + const centerRot = getCenter(rotatedExtent); + centerRot[0] += ((padding[1] - padding[3]) / 2) * resolution; + centerRot[1] += ((padding[0] - padding[2]) / 2) * resolution; + const centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle; + const centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle; const center = this.getConstrainedCenter([centerX, centerY], resolution); const callback = options.callback ? options.callback : VOID; diff --git a/src/ol/interaction/DragZoom.js b/src/ol/interaction/DragZoom.js index a839367087..46b6d10b27 100644 --- a/src/ol/interaction/DragZoom.js +++ b/src/ol/interaction/DragZoom.js @@ -2,14 +2,7 @@ * @module ol/interaction/DragZoom */ import DragBox from './DragBox.js'; -import { - createOrUpdateFromCoordinates, - getBottomLeft, - getTopRight, - scaleFromCenter, -} from '../extent.js'; import {easeOut} from '../easing.js'; -import {fromExtent as polygonFromExtent} from '../geom/Polygon.js'; import {shiftKeyOnly} from '../events/condition.js'; /** @@ -71,22 +64,17 @@ class DragZoom extends DragBox { onBoxEnd(event) { const map = this.getMap(); const view = /** @type {!import("../View.js").default} */ (map.getView()); - let extent = this.getGeometry().getExtent(); + let geometry = this.getGeometry(); if (this.out_) { - const size = /** @type {!import("../size.js").Size} */ (map.getSize()); - const mapExtent = view.calculateExtentInternal(size); - const boxPixelExtent = createOrUpdateFromCoordinates([ - map.getPixelFromCoordinateInternal(getBottomLeft(extent)), - map.getPixelFromCoordinateInternal(getTopRight(extent)), - ]); - const factor = view.getResolutionForExtentInternal(boxPixelExtent, size); - - scaleFromCenter(mapExtent, 1 / factor); - extent = mapExtent; + const rotatedExtent = view.rotatedExtentForGeometry(geometry); + const resolution = view.getResolutionForExtentInternal(rotatedExtent); + const factor = view.getResolution() / resolution; + geometry = geometry.clone(); + geometry.scale(factor * factor); } - view.fitInternal(polygonFromExtent(extent), { + view.fitInternal(geometry, { duration: this.duration_, easing: easeOut, });