Merge pull request #9919 from mike-000/patch-2

Revise and correct OverviewMap rotation
This commit is contained in:
Tim Schaub
2019-09-11 17:38:53 -06:00
committed by GitHub
2 changed files with 79 additions and 45 deletions
+70 -42
View File
@@ -11,12 +11,11 @@ import Overlay from '../Overlay.js';
import OverlayPositioning from '../OverlayPositioning.js'; import OverlayPositioning from '../OverlayPositioning.js';
import ViewProperty from '../ViewProperty.js'; import ViewProperty from '../ViewProperty.js';
import Control from './Control.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 {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';
import {replaceNode} from '../dom.js'; import {replaceNode} from '../dom.js';
import {listen, listenOnce} from '../events.js'; import {listen, listenOnce} from '../events.js';
import EventType from '../events/EventType.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. * Layers for the overview map.
* @property {function(import("../MapEvent.js").default)} [render] Function called when the control * @property {function(import("../MapEvent.js").default)} [render] Function called when the control
* should be re-rendered. This is called in a `requestAnimationFrame` callback. * 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 * @property {HTMLElement|string} [target] Specify a target if you want the control
* to be rendered outside of the map's viewport. * to be rendered outside of the map's viewport.
* @property {string} [tipLabel='Overview map'] Text label to use for the button tip. * @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. * defined map.
* *
* @api * @api
@@ -106,6 +106,19 @@ class OverviewMap extends Control {
this.collapsed_ = false; 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 className = options.className !== undefined ? options.className : 'ol-overviewmap';
const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map'; const tipLabel = options.tipLabel !== undefined ? options.tipLabel : 'Overview map';
@@ -178,7 +191,7 @@ class OverviewMap extends Control {
*/ */
this.boxOverlay_ = new Overlay({ this.boxOverlay_ = new Overlay({
position: [0, 0], position: [0, 0],
positioning: OverlayPositioning.BOTTOM_LEFT, positioning: OverlayPositioning.CENTER_CENTER,
element: box element: box
}); });
this.ovmap_.addOverlay(this.boxOverlay_); this.ovmap_.addOverlay(this.boxOverlay_);
@@ -303,12 +316,12 @@ class OverviewMap extends Control {
/** /**
* Handle rotation changes to the main map. * Handle rotation changes to the main map.
* TODO: This should rotate the extent rectangle instead of the
* overview map's view.
* @private * @private
*/ */
handleRotationChanged_() { 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 ovview = ovmap.getView();
const rotation = view.getRotation(); const rotation = this.rotateWithView_ ? 0 : -view.getRotation();
const overlay = this.boxOverlay_; const overlay = this.boxOverlay_;
const box = this.boxOverlay_.getElement(); const box = this.boxOverlay_.getElement();
const extent = view.calculateExtent(mapSize); const center = view.getCenter();
const resolution = view.getResolution();
const ovresolution = ovview.getResolution(); const ovresolution = ovview.getResolution();
const bottomLeft = getBottomLeft(extent); const width = mapSize[0] * resolution / ovresolution;
const topRight = getTopRight(extent); const height = mapSize[1] * resolution / ovresolution;
// set position using bottom left coordinates // set position using center coordinates
const rotateBottomLeft = this.calculateCoordinateRotate_(rotation, bottomLeft); overlay.setPosition(center);
overlay.setPosition(rotateBottomLeft);
// set box size calculated from map extent size and overview map resolution // set box size calculated from map extent size and overview map resolution
if (box) { if (box) {
box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px'; box.style.width = width + 'px';
box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + '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 * @param {MouseEvent} event The event to handle
* @private * @private
@@ -500,7 +492,12 @@ class OverviewMap extends Control {
// manage overview map if it had not been rendered before and control // manage overview map if it had not been rendered before and control
// is expanded // is expanded
const ovmap = this.ovmap_; const ovmap = this.ovmap_;
if (!this.collapsed_ && !ovmap.isRendered()) { if (!this.collapsed_) {
if (ovmap.isRendered()) {
this.viewExtent_ = undefined;
ovmap.render();
return;
}
ovmap.updateSize(); ovmap.updateSize();
this.resetExtent_(); this.resetExtent_();
listenOnce(ovmap, MapEventType.POSTRENDER, listenOnce(ovmap, MapEventType.POSTRENDER,
@@ -559,6 +556,37 @@ class OverviewMap extends Control {
return this.collapsed_; 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 the overview map.
* @return {import("../PluggableMap.js").default} Overview map. * @return {import("../PluggableMap.js").default} Overview map.
+9 -3
View File
@@ -39,7 +39,9 @@ describe('ol.control.OverviewMap', function() {
}); });
map.setView(view); map.setView(view);
const control = new OverviewMap(); const control = new OverviewMap({
rotateWithView: true
});
map.addControl(control); map.addControl(control);
const ovView = control.ovmap_.getView(); const ovView = control.ovmap_.getView();
expect(ovView.getRotation()).to.be(0); 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() { it('maintains rotation in sync if view added later', function() {
const control = new OverviewMap(); const control = new OverviewMap({
rotateWithView: true
});
map.addControl(control); map.addControl(control);
const ovView = control.ovmap_.getView(); const ovView = control.ovmap_.getView();
expect(ovView.getRotation()).to.be(0); expect(ovView.getRotation()).to.be(0);
@@ -65,7 +69,9 @@ describe('ol.control.OverviewMap', function() {
}); });
it('stops listening to old maps', function() { it('stops listening to old maps', function() {
const control = new OverviewMap(); const control = new OverviewMap({
rotateWithView: true
});
const ovView = control.ovmap_.getView(); const ovView = control.ovmap_.getView();
const view = new View({ const view = new View({