Merge pull request #9919 from mike-000/patch-2
Revise and correct OverviewMap rotation
This commit is contained in:
@@ -11,12 +11,11 @@ import Overlay from '../Overlay.js';
|
||||
import OverlayPositioning from '../OverlayPositioning.js';
|
||||
import ViewProperty from '../ViewProperty.js';
|
||||
import Control from './Control.js';
|
||||
import {rotate as rotateCoordinate, add as addCoordinate} from '../coordinate.js';
|
||||
import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';
|
||||
import {replaceNode} from '../dom.js';
|
||||
import {listen, listenOnce} from '../events.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {containsExtent, equals as equalsExtent, getBottomLeft, getBottomRight, getTopLeft, getTopRight, scaleFromCenter} from '../extent.js';
|
||||
import {containsExtent, equals as equalsExtent, getBottomRight, getTopLeft, scaleFromCenter} from '../extent.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -55,6 +54,7 @@ class ControlledMap extends PluggableMap {
|
||||
* Layers for the overview map.
|
||||
* @property {function(import("../MapEvent.js").default)} [render] Function called when the control
|
||||
* should be re-rendered. This is called in a `requestAnimationFrame` callback.
|
||||
* @property {boolean} [rotateWithView=false] Whether the control view should rotate with the main map view.
|
||||
* @property {HTMLElement|string} [target] Specify a target if you want the control
|
||||
* to be rendered outside of the map's viewport.
|
||||
* @property {string} [tipLabel='Overview map'] Text label to use for the button tip.
|
||||
@@ -64,7 +64,7 @@ class ControlledMap extends PluggableMap {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new control with a map acting as an overview map for an other
|
||||
* Create a new control with a map acting as an overview map for another
|
||||
* defined map.
|
||||
*
|
||||
* @api
|
||||
@@ -106,6 +106,19 @@ class OverviewMap extends Control {
|
||||
this.collapsed_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rotateWithView_ = options.rotateWithView !== undefined ?
|
||||
options.rotateWithView : false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../extent.js").Extent|undefined}
|
||||
*/
|
||||
this.viewExtent_ = undefined;
|
||||
|
||||
const className = options.className !== undefined ? options.className : 'ol-overviewmap';
|
||||
|
||||
const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map';
|
||||
@@ -178,7 +191,7 @@ class OverviewMap extends Control {
|
||||
*/
|
||||
this.boxOverlay_ = new Overlay({
|
||||
position: [0, 0],
|
||||
positioning: OverlayPositioning.BOTTOM_LEFT,
|
||||
positioning: OverlayPositioning.CENTER_CENTER,
|
||||
element: box
|
||||
});
|
||||
this.ovmap_.addOverlay(this.boxOverlay_);
|
||||
@@ -303,12 +316,12 @@ class OverviewMap extends Control {
|
||||
|
||||
/**
|
||||
* Handle rotation changes to the main map.
|
||||
* TODO: This should rotate the extent rectangle instead of the
|
||||
* overview map's view.
|
||||
* @private
|
||||
*/
|
||||
handleRotationChanged_() {
|
||||
this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());
|
||||
if (this.rotateWithView_) {
|
||||
this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,51 +444,30 @@ class OverviewMap extends Control {
|
||||
|
||||
const ovview = ovmap.getView();
|
||||
|
||||
const rotation = view.getRotation();
|
||||
const rotation = this.rotateWithView_ ? 0 : -view.getRotation();
|
||||
|
||||
const overlay = this.boxOverlay_;
|
||||
const box = this.boxOverlay_.getElement();
|
||||
const extent = view.calculateExtent(mapSize);
|
||||
const center = view.getCenter();
|
||||
const resolution = view.getResolution();
|
||||
const ovresolution = ovview.getResolution();
|
||||
const bottomLeft = getBottomLeft(extent);
|
||||
const topRight = getTopRight(extent);
|
||||
const width = mapSize[0] * resolution / ovresolution;
|
||||
const height = mapSize[1] * resolution / ovresolution;
|
||||
|
||||
// set position using bottom left coordinates
|
||||
const rotateBottomLeft = this.calculateCoordinateRotate_(rotation, bottomLeft);
|
||||
overlay.setPosition(rotateBottomLeft);
|
||||
// set position using center coordinates
|
||||
overlay.setPosition(center);
|
||||
|
||||
// set box size calculated from map extent size and overview map resolution
|
||||
if (box) {
|
||||
box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px';
|
||||
box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px';
|
||||
box.style.width = width + 'px';
|
||||
box.style.height = height + 'px';
|
||||
const transform = 'rotate(' + rotation + 'rad)';
|
||||
box.style.msTransform = transform;
|
||||
box.style.webkitTransform = transform;
|
||||
box.style.transform = transform;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} rotation Target rotation.
|
||||
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
|
||||
* @return {import("../coordinate.js").Coordinate|undefined} Coordinate for rotation and center anchor.
|
||||
* @private
|
||||
*/
|
||||
calculateCoordinateRotate_(rotation, coordinate) {
|
||||
let coordinateRotate;
|
||||
|
||||
const map = this.getMap();
|
||||
const view = map.getView();
|
||||
|
||||
const currentCenter = view.getCenter();
|
||||
|
||||
if (currentCenter) {
|
||||
coordinateRotate = [
|
||||
coordinate[0] - currentCenter[0],
|
||||
coordinate[1] - currentCenter[1]
|
||||
];
|
||||
rotateCoordinate(coordinateRotate, rotation);
|
||||
addCoordinate(coordinateRotate, currentCenter);
|
||||
}
|
||||
return coordinateRotate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MouseEvent} event The event to handle
|
||||
* @private
|
||||
@@ -500,7 +492,12 @@ class OverviewMap extends Control {
|
||||
// manage overview map if it had not been rendered before and control
|
||||
// is expanded
|
||||
const ovmap = this.ovmap_;
|
||||
if (!this.collapsed_ && !ovmap.isRendered()) {
|
||||
if (!this.collapsed_) {
|
||||
if (ovmap.isRendered()) {
|
||||
this.viewExtent_ = undefined;
|
||||
ovmap.render();
|
||||
return;
|
||||
}
|
||||
ovmap.updateSize();
|
||||
this.resetExtent_();
|
||||
listenOnce(ovmap, MapEventType.POSTRENDER,
|
||||
@@ -559,6 +556,37 @@ class OverviewMap extends Control {
|
||||
return this.collapsed_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return `true` if the overview map view can rotate, `false` otherwise.
|
||||
* @return {boolean} True if the control view can rotate.
|
||||
* @api
|
||||
*/
|
||||
getRotateWithView() {
|
||||
return this.rotateWithView_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the overview map view should rotate with the main map view.
|
||||
* @param {boolean} rotateWithView True if the control view should rotate.
|
||||
* @api
|
||||
*/
|
||||
setRotateWithView(rotateWithView) {
|
||||
if (this.rotateWithView_ === rotateWithView) {
|
||||
return;
|
||||
}
|
||||
this.rotateWithView_ = rotateWithView;
|
||||
if (this.getMap().getView().getRotation() !== 0) {
|
||||
if (this.rotateWithView_) {
|
||||
this.handleRotationChanged_();
|
||||
} else {
|
||||
this.ovmap_.getView().setRotation(0);
|
||||
}
|
||||
this.viewExtent_ = undefined;
|
||||
this.validateExtent_();
|
||||
this.updateBox_();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the overview map.
|
||||
* @return {import("../PluggableMap.js").default} Overview map.
|
||||
|
||||
@@ -39,7 +39,9 @@ describe('ol.control.OverviewMap', function() {
|
||||
});
|
||||
map.setView(view);
|
||||
|
||||
const control = new OverviewMap();
|
||||
const control = new OverviewMap({
|
||||
rotateWithView: true
|
||||
});
|
||||
map.addControl(control);
|
||||
const ovView = control.ovmap_.getView();
|
||||
expect(ovView.getRotation()).to.be(0);
|
||||
@@ -49,7 +51,9 @@ describe('ol.control.OverviewMap', function() {
|
||||
});
|
||||
|
||||
it('maintains rotation in sync if view added later', function() {
|
||||
const control = new OverviewMap();
|
||||
const control = new OverviewMap({
|
||||
rotateWithView: true
|
||||
});
|
||||
map.addControl(control);
|
||||
const ovView = control.ovmap_.getView();
|
||||
expect(ovView.getRotation()).to.be(0);
|
||||
@@ -65,7 +69,9 @@ describe('ol.control.OverviewMap', function() {
|
||||
});
|
||||
|
||||
it('stops listening to old maps', function() {
|
||||
const control = new OverviewMap();
|
||||
const control = new OverviewMap({
|
||||
rotateWithView: true
|
||||
});
|
||||
const ovView = control.ovmap_.getView();
|
||||
|
||||
const view = new View({
|
||||
|
||||
Reference in New Issue
Block a user