View / add a constrainResolution option

This introduces a breaking change.

This options replaces the various `constrainResolution` options on interactions
and the `fit` method.

Since constraints are now the responsibility of the View, the fact that intermediary
zoom levels are allowed or not is now set in the view options.

By default, the view resolution is unconstrained.
This commit is contained in:
Olivier Guyot
2019-01-20 16:05:10 +01:00
parent 48ad1ffcbf
commit 49662b019c
11 changed files with 120 additions and 126 deletions
+1 -3
View File
@@ -21,8 +21,6 @@ tags: "center, rotation, openstreetmap"
<div class="padding-bottom"></div> <div class="padding-bottom"></div>
<div class="center"></div> <div class="center"></div>
</div> </div>
<button id="zoomtoswitzerlandbest">Zoom to Switzerland</button> (best fit),<br/> <button id="zoomtoswitzerland">Zoom to Switzerland</button> (best fit).<br/>
<button id="zoomtoswitzerlandconstrained">Zoom to Switzerland</button> (respect resolution constraint).<br/>
<button id="zoomtoswitzerlandnearest">Zoom to Switzerland</button> (nearest),<br/>
<button id="zoomtolausanne">Zoom to Lausanne</button> (with min resolution),<br/> <button id="zoomtolausanne">Zoom to Lausanne</button> (with min resolution),<br/>
<button id="centerlausanne">Center on Lausanne</button> <button id="centerlausanne">Center on Lausanne</button>
+3 -18
View File
@@ -47,29 +47,14 @@ const map = new Map({
view: view view: view
}); });
const zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest'); const zoomtoswitzerland =
zoomtoswitzerlandbest.addEventListener('click', function() { document.getElementById('zoomtoswitzerland');
const feature = source.getFeatures()[0]; zoomtoswitzerland.addEventListener('click', function() {
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
view.fit(polygon, {padding: [170, 50, 30, 150], constrainResolution: false});
}, false);
const zoomtoswitzerlandconstrained =
document.getElementById('zoomtoswitzerlandconstrained');
zoomtoswitzerlandconstrained.addEventListener('click', function() {
const feature = source.getFeatures()[0]; const feature = source.getFeatures()[0];
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry()); const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
view.fit(polygon, {padding: [170, 50, 30, 150]}); view.fit(polygon, {padding: [170, 50, 30, 150]});
}, false); }, false);
const zoomtoswitzerlandnearest =
document.getElementById('zoomtoswitzerlandnearest');
zoomtoswitzerlandnearest.addEventListener('click', function() {
const feature = source.getFeatures()[0];
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
view.fit(polygon, {padding: [170, 50, 30, 150], nearest: true});
}, false);
const zoomtolausanne = document.getElementById('zoomtolausanne'); const zoomtolausanne = document.getElementById('zoomtolausanne');
zoomtolausanne.addEventListener('click', function() { zoomtolausanne.addEventListener('click', function() {
const feature = source.getFeatures()[1]; const feature = source.getFeatures()[1];
+1 -1
View File
@@ -7,7 +7,7 @@ import OSM from '../src/ol/source/OSM.js';
const map = new Map({ const map = new Map({
interactions: defaultInteractions({ interactions: defaultInteractions({
constrainResolution: true, onFocusOnly: true onFocusOnly: true
}), }),
layers: [ layers: [
new TileLayer({ new TileLayer({
+4 -5
View File
@@ -6,10 +6,8 @@ import OSM from '../src/ol/source/OSM.js';
const map = new Map({ const map = new Map({
interactions: defaultInteractions({pinchZoom: false}).extend([ interactions: defaultInteractions().extend([
new PinchZoom({ new PinchZoom()
constrainResolution: true // force zooming to a integer zoom
})
]), ]),
layers: [ layers: [
new TileLayer({ new TileLayer({
@@ -19,6 +17,7 @@ const map = new Map({
target: 'map', target: 'map',
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 2 zoom: 2,
constrainResolution: true
}) })
}); });
+33 -14
View File
@@ -23,6 +23,7 @@ import {createProjection, METERS_PER_UNIT} from './proj.js';
import Units from './proj/Units.js'; import Units from './proj/Units.js';
import {equals} from './coordinate'; import {equals} from './coordinate';
import {easeOut} from './easing'; import {easeOut} from './easing';
import {createMinMaxResolution} from './resolutionconstraint';
/** /**
@@ -60,9 +61,8 @@ import {easeOut} from './easing';
* @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be
* cleared inside the view. Values in the array are top, right, bottom and left * cleared inside the view. Values in the array are top, right, bottom and left
* padding. * padding.
* @property {boolean} [constrainResolution=true] Constrain the resolution. * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,
* @property {boolean} [nearest=false] If `constrainResolution` is `true`, get * get the nearest extent instead of the closest that actually fits the view.
* the nearest extent instead of the closest that actually fits the view.
* @property {number} [minResolution=0] Minimum resolution that we zoom to. * @property {number} [minResolution=0] Minimum resolution that we zoom to.
* @property {number} [maxZoom] Maximum zoom level that we zoom to. If * @property {number} [maxZoom] Maximum zoom level that we zoom to. If
* `minResolution` is given, this property is ignored. * `minResolution` is given, this property is ignored.
@@ -120,6 +120,9 @@ import {easeOut} from './easing';
* resolution constraint. It is used together with `maxZoom` (or * resolution constraint. It is used together with `maxZoom` (or
* `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also * `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also
* provided, it is given precedence over `minZoom`. * provided, it is given precedence over `minZoom`.
* @property {boolean} [constrainResolution] If true, the view will always
* animate to the closest zoom level after an interaction; false means
* intermediary zoom levels are allowed. Default is false.
* @property {import("./proj.js").ProjectionLike} [projection='EPSG:3857'] The * @property {import("./proj.js").ProjectionLike} [projection='EPSG:3857'] The
* projection. The default is Spherical Mercator. * projection. The default is Spherical Mercator.
* @property {number} [resolution] The initial resolution for the view. The * @property {number} [resolution] The initial resolution for the view. The
@@ -621,7 +624,7 @@ class View extends BaseObject {
} }
if (!this.getAnimating()) { if (!this.getAnimating()) {
this.resolveConstraints_(); setTimeout(this.resolveConstraints_.bind(this), 0);
} }
} }
@@ -790,6 +793,15 @@ class View extends BaseObject {
this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom})); this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));
} }
/**
* Set whether the view shoud allow intermediary zoom levels.
* @param {boolean} enabled Whether the resolution is constrained.
* @api
*/
setConstrainResolution(enabled) {
this.applyOptions_(this.getUpdatedOptions_({constrainResolution: enabled}));
}
/** /**
* Get the view projection. * Get the view projection.
* @return {import("./proj/Projection.js").default} The projection of the view. * @return {import("./proj/Projection.js").default} The projection of the view.
@@ -1001,8 +1013,6 @@ class View extends BaseObject {
} }
const padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0]; const padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];
const constrainResolution = options.constrainResolution !== undefined ?
options.constrainResolution : true;
const nearest = options.nearest !== undefined ? options.nearest : false; const nearest = options.nearest !== undefined ? options.nearest : false;
let minResolution; let minResolution;
if (options.minResolution !== undefined) { if (options.minResolution !== undefined) {
@@ -1038,9 +1048,7 @@ class View extends BaseObject {
[size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]); [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]);
resolution = isNaN(resolution) ? minResolution : resolution = isNaN(resolution) ? minResolution :
Math.max(resolution, minResolution); Math.max(resolution, minResolution);
if (constrainResolution) { resolution = this.getValidResolution(resolution, nearest ? 0 : 1);
resolution = this.getValidResolution(resolution, nearest ? 0 : 1);
}
// calculate center // calculate center
sinAngle = -sinAngle; // go back to original rotation sinAngle = -sinAngle; // go back to original rotation
@@ -1346,8 +1354,14 @@ export function createResolutionConstraint(options) {
maxResolution = resolutions[minZoom]; maxResolution = resolutions[minZoom];
minResolution = resolutions[maxZoom] !== undefined ? minResolution = resolutions[maxZoom] !== undefined ?
resolutions[maxZoom] : resolutions[resolutions.length - 1]; resolutions[maxZoom] : resolutions[resolutions.length - 1];
resolutionConstraint = createSnapToResolutions(resolutions,
!options.constrainOnlyCenter && options.extent); if (options.constrainResolution) {
resolutionConstraint = createSnapToResolutions(resolutions,
!options.constrainOnlyCenter && options.extent);
} else {
resolutionConstraint = createMinMaxResolution(maxResolution, minResolution,
!options.constrainOnlyCenter && options.extent);
}
} else { } else {
// calculate the default min and max resolution // calculate the default min and max resolution
const projection = createProjection(options.projection, 'EPSG:3857'); const projection = createProjection(options.projection, 'EPSG:3857');
@@ -1391,9 +1405,14 @@ export function createResolutionConstraint(options) {
Math.log(maxResolution / minResolution) / Math.log(zoomFactor)); Math.log(maxResolution / minResolution) / Math.log(zoomFactor));
minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom); minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);
resolutionConstraint = createSnapToPower( if (options.constrainResolution) {
zoomFactor, maxResolution, minResolution, resolutionConstraint = createSnapToPower(
!options.constrainOnlyCenter && options.extent); zoomFactor, maxResolution, minResolution,
!options.constrainOnlyCenter && options.extent);
} else {
resolutionConstraint = createMinMaxResolution(maxResolution, minResolution,
!options.constrainOnlyCenter && options.extent);
}
} }
return {constraint: resolutionConstraint, maxResolution: maxResolution, return {constraint: resolutionConstraint, maxResolution: maxResolution,
minResolution: minResolution, minZoom: minZoom, zoomFactor: zoomFactor}; minResolution: minResolution, minZoom: minZoom, zoomFactor: zoomFactor};
-4
View File
@@ -44,8 +44,6 @@ export {default as Translate} from './interaction/Translate.js';
* focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is
* useful when page scroll is desired for maps that do not have the browser's * useful when page scroll is desired for maps that do not have the browser's
* focus. * focus.
* @property {boolean} [constrainResolution=false] Zoom to the closest integer
* zoom level after the wheel/trackpad or pinch gesture ends.
* @property {boolean} [doubleClickZoom=true] Whether double click zoom is * @property {boolean} [doubleClickZoom=true] Whether double click zoom is
* desired. * desired.
* @property {boolean} [keyboard=true] Whether keyboard interaction is desired. * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.
@@ -127,7 +125,6 @@ export function defaults(opt_options) {
const pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true; const pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;
if (pinchZoom) { if (pinchZoom) {
interactions.push(new PinchZoom({ interactions.push(new PinchZoom({
constrainResolution: options.constrainResolution,
duration: options.zoomDuration duration: options.zoomDuration
})); }));
} }
@@ -146,7 +143,6 @@ export function defaults(opt_options) {
if (mouseWheelZoom) { if (mouseWheelZoom) {
interactions.push(new MouseWheelZoom({ interactions.push(new MouseWheelZoom({
condition: options.onFocusOnly ? focus : undefined, condition: options.onFocusOnly ? focus : undefined,
constrainResolution: options.constrainResolution,
duration: options.zoomDuration duration: options.zoomDuration
})); }));
} }
+1 -10
View File
@@ -34,9 +34,6 @@ export const Mode = {
* {@link module:ol/events/condition~always}. * {@link module:ol/events/condition~always}.
* @property {number} [duration=250] Animation duration in milliseconds. * @property {number} [duration=250] Animation duration in milliseconds.
* @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds. * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.
* @property {boolean} [constrainResolution=false] When using a trackpad or
* magic mouse, zoom to the closest integer zoom level after the scroll gesture
* ends.
* @property {boolean} [useAnchor=true] Enable zooming using the mouse's * @property {boolean} [useAnchor=true] Enable zooming using the mouse's
* location as the anchor. When set to `false`, zooming in and out will zoom to * location as the anchor. When set to `false`, zooming in and out will zoom to
* the center of the screen instead of zooming on the mouse's location. * the center of the screen instead of zooming on the mouse's location.
@@ -82,12 +79,6 @@ class MouseWheelZoom extends Interaction {
*/ */
this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true; this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;
/**
* @private
* @type {boolean}
*/
this.constrainResolution_ = options.constrainResolution || false;
/** /**
* @private * @private
* @type {import("../events/condition.js").Condition} * @type {import("../events/condition.js").Condition}
@@ -238,7 +229,7 @@ class MouseWheelZoom extends Interaction {
} }
view.setResolution(resolution); view.setResolution(resolution);
if (rebound === 0 && this.constrainResolution_) { if (rebound === 0) {
const zoomDelta = delta > 0 ? -1 : 1; const zoomDelta = delta > 0 ? -1 : 1;
const newZoom = view.getValidZoomLevel(view.getZoom() + zoomDelta); const newZoom = view.getValidZoomLevel(view.getZoom() + zoomDelta);
view.animate({ view.animate({
-8
View File
@@ -10,8 +10,6 @@ import PointerInteraction, {centroid as centroidFromPointers} from './Pointer.js
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {number} [duration=400] Animation duration in milliseconds. * @property {number} [duration=400] Animation duration in milliseconds.
* @property {boolean} [constrainResolution=false] Zoom to the closest integer
* zoom level after the pinch gesture ends.
*/ */
@@ -37,12 +35,6 @@ class PinchZoom extends PointerInteraction {
super(pointerOptions); super(pointerOptions);
/**
* @private
* @type {boolean}
*/
this.constrainResolution_ = options.constrainResolution || false;
/** /**
* @private * @private
* @type {import("../coordinate.js").Coordinate} * @type {import("../coordinate.js").Coordinate}
+40 -17
View File
@@ -4,13 +4,24 @@
import {linearFindNearest} from './array.js'; import {linearFindNearest} from './array.js';
import {clamp} from './math.js'; import {clamp} from './math.js';
import {getHeight, getWidth} from './extent'; import {getHeight, getWidth} from './extent';
import {clamp} from './math';
/** /**
* @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type * @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type
*/ */
/**
* @param {number} resolution Resolution
* @param {import("./extent.js").Extent=} maxExtent Maximum allowed extent.
* @param {import("./size.js").Size} viewportSize Viewport size.
* @return {number} Capped resolution.
*/
function getCappedResolution(resolution, maxExtent, viewportSize) {
const xResolution = getWidth(maxExtent) / viewportSize[0];
const yResolution = getHeight(maxExtent) / viewportSize[1];
return Math.min(resolution, Math.min(xResolution, yResolution));
}
/** /**
* @param {Array<number>} resolutions Resolutions. * @param {Array<number>} resolutions Resolutions.
@@ -28,14 +39,7 @@ export function createSnapToResolutions(resolutions, opt_maxExtent) {
*/ */
function(resolution, direction, size, opt_isMoving) { function(resolution, direction, size, opt_isMoving) {
if (resolution !== undefined) { if (resolution !== undefined) {
let cappedRes = resolution; const cappedRes = opt_maxExtent ? getCappedResolution(resolution, opt_maxExtent, size) : resolution;
// apply constraint related to max extent
if (opt_maxExtent) {
const xResolution = getWidth(opt_maxExtent) / size[0];
const yResolution = getHeight(opt_maxExtent) / size[1];
cappedRes = Math.min(cappedRes, Math.min(xResolution, yResolution));
}
// during interacting or animating, allow intermediary values // during interacting or animating, allow intermediary values
if (opt_isMoving) { if (opt_isMoving) {
@@ -72,14 +76,7 @@ export function createSnapToPower(power, maxResolution, opt_minResolution, opt_m
*/ */
function(resolution, direction, size, opt_isMoving) { function(resolution, direction, size, opt_isMoving) {
if (resolution !== undefined) { if (resolution !== undefined) {
let cappedRes = Math.min(resolution, maxResolution); const cappedRes = opt_maxExtent ? getCappedResolution(resolution, opt_maxExtent, size) : resolution;
// apply constraint related to max extent
if (opt_maxExtent) {
const xResolution = getWidth(opt_maxExtent) / size[0];
const yResolution = getHeight(opt_maxExtent) / size[1];
cappedRes = Math.min(cappedRes, Math.min(xResolution, yResolution));
}
// during interacting or animating, allow intermediary values // during interacting or animating, allow intermediary values
if (opt_isMoving) { if (opt_isMoving) {
@@ -98,3 +95,29 @@ export function createSnapToPower(power, maxResolution, opt_minResolution, opt_m
} }
}); });
} }
/**
* @param {number} maxResolution Max resolution.
* @param {number} minResolution Min resolution.
* @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.
* @return {Type} Zoom function.
*/
export function createMinMaxResolution(maxResolution, minResolution, opt_maxExtent) {
return (
/**
* @param {number|undefined} resolution Resolution.
* @param {number} direction Direction.
* @param {import("./size.js").Size} size Viewport size.
* @param {boolean=} opt_isMoving True if an interaction or animation is in progress.
* @return {number|undefined} Resolution.
*/
function(resolution, direction, size, opt_isMoving) {
if (resolution !== undefined) {
const cappedRes = opt_maxExtent ? getCappedResolution(resolution, opt_maxExtent, size) : resolution;
return clamp(cappedRes, minResolution, maxResolution);
} else {
return undefined;
}
}
);
}
-16
View File
@@ -565,7 +565,6 @@ describe('ol.Map', function() {
const interactions = defaultInteractions(options); const interactions = defaultInteractions(options);
expect(interactions.getLength()).to.eql(1); expect(interactions.getLength()).to.eql(1);
expect(interactions.item(0)).to.be.a(MouseWheelZoom); expect(interactions.item(0)).to.be.a(MouseWheelZoom);
expect(interactions.item(0).constrainResolution_).to.eql(false);
expect(interactions.item(0).useAnchor_).to.eql(true); expect(interactions.item(0).useAnchor_).to.eql(true);
interactions.item(0).setMouseAnchor(false); interactions.item(0).setMouseAnchor(false);
expect(interactions.item(0).useAnchor_).to.eql(false); expect(interactions.item(0).useAnchor_).to.eql(false);
@@ -601,21 +600,6 @@ describe('ol.Map', function() {
const interactions = defaultInteractions(options); const interactions = defaultInteractions(options);
expect(interactions.getLength()).to.eql(1); expect(interactions.getLength()).to.eql(1);
expect(interactions.item(0)).to.be.a(PinchZoom); expect(interactions.item(0)).to.be.a(PinchZoom);
expect(interactions.item(0).constrainResolution_).to.eql(false);
});
});
describe('set constrainResolution option', function() {
it('set constrainResolution option', function() {
options.pinchZoom = true;
options.mouseWheelZoom = true;
options.constrainResolution = true;
const interactions = defaultInteractions(options);
expect(interactions.getLength()).to.eql(2);
expect(interactions.item(0)).to.be.a(PinchZoom);
expect(interactions.item(0).constrainResolution_).to.eql(true);
expect(interactions.item(1)).to.be.a(MouseWheelZoom);
expect(interactions.item(1).constrainResolution_).to.eql(true);
}); });
}); });
+37 -30
View File
@@ -239,7 +239,8 @@ describe('ol.View', function() {
it('works with minResolution and maxResolution', function() { it('works with minResolution and maxResolution', function() {
const constraint = getConstraint({ const constraint = getConstraint({
maxResolution: 500, maxResolution: 500,
minResolution: 100 minResolution: 100,
constrainResolution: true
}); });
expect(constraint(600, 0, 0)).to.be(500); expect(constraint(600, 0, 0)).to.be(500);
@@ -255,7 +256,8 @@ describe('ol.View', function() {
const constraint = getConstraint({ const constraint = getConstraint({
maxResolution: 500, maxResolution: 500,
minResolution: 1, minResolution: 1,
zoomFactor: 10 zoomFactor: 10,
constrainResolution: true
}); });
expect(constraint(1000, 0, 0)).to.be(500); expect(constraint(1000, 0, 0)).to.be(500);
@@ -1327,14 +1329,40 @@ describe('ol.View', function() {
zoom: 5 zoom: 5
}); });
}); });
it('fits correctly to the geometry', function() { it('fits correctly to the geometry (with unconstrained resolution)', function() {
view.fit( view.fit(
new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]), new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]),
{size: [200, 200], padding: [100, 0, 0, 100], constrainResolution: false}); {size: [200, 200], padding: [100, 0, 0, 100]});
expect(view.getResolution()).to.be(11); expect(view.getResolution()).to.be(11);
expect(view.getCenter()[0]).to.be(5950); expect(view.getCenter()[0]).to.be(5950);
expect(view.getCenter()[1]).to.be(47100); expect(view.getCenter()[1]).to.be(47100);
view.fit(
new Circle([6000, 46000], 1000),
{size: [200, 200]});
expect(view.getResolution()).to.be(10);
expect(view.getCenter()[0]).to.be(6000);
expect(view.getCenter()[1]).to.be(46000);
view.setRotation(Math.PI / 8);
view.fit(
new Circle([6000, 46000], 1000),
{size: [200, 200]});
expect(view.getResolution()).to.roughlyEqual(10, 1e-9);
expect(view.getCenter()[0]).to.roughlyEqual(6000, 1e-9);
expect(view.getCenter()[1]).to.roughlyEqual(46000, 1e-9);
view.setRotation(Math.PI / 4);
view.fit(
new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]),
{size: [200, 200], padding: [100, 0, 0, 100]});
expect(view.getResolution()).to.roughlyEqual(14.849242404917458, 1e-9);
expect(view.getCenter()[0]).to.roughlyEqual(5200, 1e-9);
expect(view.getCenter()[1]).to.roughlyEqual(46300, 1e-9);
});
it('fits correctly to the geometry', function() {
view.setConstrainResolution(true);
view.fit( view.fit(
new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]), new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]),
{size: [200, 200], padding: [100, 0, 0, 100]}); {size: [200, 200], padding: [100, 0, 0, 100]});
@@ -1363,30 +1391,8 @@ describe('ol.View', function() {
expect(view.getZoom()).to.be(6); expect(view.getZoom()).to.be(6);
expect(view.getCenter()[0]).to.be(5900); expect(view.getCenter()[0]).to.be(5900);
expect(view.getCenter()[1]).to.be(46100); expect(view.getCenter()[1]).to.be(46100);
view.fit(
new Circle([6000, 46000], 1000),
{size: [200, 200], constrainResolution: false});
expect(view.getResolution()).to.be(10);
expect(view.getCenter()[0]).to.be(6000);
expect(view.getCenter()[1]).to.be(46000);
view.setRotation(Math.PI / 8);
view.fit(
new Circle([6000, 46000], 1000),
{size: [200, 200], constrainResolution: false});
expect(view.getResolution()).to.roughlyEqual(10, 1e-9);
expect(view.getCenter()[0]).to.roughlyEqual(6000, 1e-9);
expect(view.getCenter()[1]).to.roughlyEqual(46000, 1e-9);
view.setRotation(Math.PI / 4);
view.fit(
new LineString([[6000, 46000], [6000, 47100], [7000, 46000]]),
{size: [200, 200], padding: [100, 0, 0, 100], constrainResolution: false});
expect(view.getResolution()).to.roughlyEqual(14.849242404917458, 1e-9);
expect(view.getCenter()[0]).to.roughlyEqual(5200, 1e-9);
expect(view.getCenter()[1]).to.roughlyEqual(46300, 1e-9);
}); });
it('fits correctly to the extent', function() { it('fits correctly to the extent', function() {
view.fit([1000, 1000, 2000, 2000], {size: [200, 200]}); view.fit([1000, 1000, 2000, 2000], {size: [200, 200]});
expect(view.getResolution()).to.be(5); expect(view.getResolution()).to.be(5);
@@ -1409,7 +1415,6 @@ describe('ol.View', function() {
{ {
size: [200, 200], size: [200, 200],
padding: [100, 0, 0, 100], padding: [100, 0, 0, 100],
constrainResolution: false,
duration: 25 duration: 25
}); });
@@ -1531,7 +1536,8 @@ describe('ol.View', function() {
view = new View({ view = new View({
maxResolution: 2500, maxResolution: 2500,
zoomFactor: 5, zoomFactor: 5,
maxZoom: 4 maxZoom: 4,
constrainResolution: true
}); });
expect(view.getValidResolution(90, 1)).to.be(100); expect(view.getValidResolution(90, 1)).to.be(100);
expect(view.getValidResolution(90, -1)).to.be(20); expect(view.getValidResolution(90, -1)).to.be(20);
@@ -1542,7 +1548,8 @@ describe('ol.View', function() {
it('works correctly with a specific resolution set', function() { it('works correctly with a specific resolution set', function() {
view = new View({ view = new View({
zoom: 0, zoom: 0,
resolutions: [512, 256, 128, 64, 32, 16, 8] resolutions: [512, 256, 128, 64, 32, 16, 8],
constrainResolution: true
}); });
expect(view.getValidResolution(1000, 1)).to.be(512); expect(view.getValidResolution(1000, 1)).to.be(512);
expect(view.getValidResolution(260, 1)).to.be(512); expect(view.getValidResolution(260, 1)).to.be(512);