Improve overview map handling of map and view changes

This commit is contained in:
Tim Schaub
2015-04-05 18:31:11 +02:00
parent 0189e11931
commit e1079ab9a3
3 changed files with 161 additions and 41 deletions

View File

@@ -12,9 +12,11 @@ goog.require('ol.Collection');
goog.require('ol.Map');
goog.require('ol.MapEventType');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.Overlay');
goog.require('ol.OverlayPositioning');
goog.require('ol.View');
goog.require('ol.ViewProperty');
goog.require('ol.control.Control');
goog.require('ol.coordinate');
goog.require('ol.css');
@@ -155,54 +157,89 @@ goog.inherits(ol.control.OverviewMap, ol.control.Control);
* @api
*/
ol.control.OverviewMap.prototype.setMap = function(map) {
var currentMap = this.getMap();
if (goog.isNull(map) && !goog.isNull(currentMap)) {
goog.events.unlisten(
currentMap, ol.Object.getChangeEventType(ol.MapProperty.VIEW),
this.handleViewChanged_, false, this);
var oldMap = this.getMap();
if (map === oldMap) {
return;
}
if (oldMap) {
var oldView = oldMap.getView();
if (oldView) {
this.unbindView_(oldView);
}
}
goog.base(this, 'setMap', map);
if (!goog.isNull(map)) {
if (map) {
this.listenerKeys.push(goog.events.listen(
map, ol.ObjectEventType.PROPERTYCHANGE,
this.handleMapPropertyChange_, false, this));
// if no layers were set for the overviewmap map, then bind with
// those in the main map
// TODO: to really support map switching, this would need to be reworked
if (this.ovmap_.getLayers().getLength() === 0) {
this.ovmap_.setLayerGroup(map.getLayerGroup());
}
// bind current map view, or any new one
this.bindView_();
goog.events.listen(
map, ol.Object.getChangeEventType(ol.MapProperty.VIEW),
this.handleViewChanged_, false, this);
this.ovmap_.updateSize();
this.resetExtent_();
var view = map.getView();
if (view) {
this.bindView_(view);
if (view.isDef()) {
this.ovmap_.updateSize();
this.resetExtent_();
}
}
}
};
/**
* Bind some actions to the main map view.
* Handle map property changes. This only deals with changes to the map's view.
* @param {ol.ObjectEvent} event The propertychange event.
* @private
*/
ol.control.OverviewMap.prototype.bindView_ = function() {
var map = this.getMap();
var view = map.getView();
// if the map does not have a view, we can't act upon it
if (goog.isNull(view)) {
return;
ol.control.OverviewMap.prototype.handleMapPropertyChange_ = function(event) {
if (event.key === ol.MapProperty.VIEW) {
var oldView = /** @type {ol.View} */ (event.oldValue);
if (oldView) {
this.unbindView_(oldView);
}
var newView = this.getMap().getView();
this.bindView_(newView);
}
};
// FIXME - the overviewmap view rotation currently follows the one used
// by the main map view. We could support box rotation instead. The choice
// between the 2 modes would be made in a single option
// this.ovmap_.getView().bindTo(ol.ViewProperty.ROTATION, view);
/**
* Register listeners for view property changes.
* @param {ol.View} view The view.
* @private
*/
ol.control.OverviewMap.prototype.bindView_ = function(view) {
goog.events.listen(view,
ol.Object.getChangeEventType(ol.ViewProperty.ROTATION),
this.handleRotationChanged_, false, this);
};
/**
* Unregister listeners for view property changes.
* @param {ol.View} view The view.
* @private
*/
ol.control.OverviewMap.prototype.unbindView_ = function(view) {
goog.events.unlisten(view,
ol.Object.getChangeEventType(ol.ViewProperty.ROTATION),
this.handleRotationChanged_, false, this);
};
/**
* Handle rotation changes to the main map.
* TODO: This should rotate the extent rectrangle instead of the
* overview map's view.
* @private
*/
ol.control.OverviewMap.prototype.handleRotationChanged_ = function() {
this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());
};
@@ -217,16 +254,6 @@ ol.control.OverviewMap.render = function(mapEvent) {
};
/**
* Called on main map view changed.
* @param {goog.events.Event} event Event.
* @private
*/
ol.control.OverviewMap.prototype.handleViewChanged_ = function(event) {
this.bindView_();
};
/**
* Reset the overview map extent if the box size (width or
* height) is less than the size of the overview map size times minRatio

View File

@@ -1,5 +1,6 @@
goog.provide('ol.View');
goog.provide('ol.ViewHint');
goog.provide('ol.ViewProperty');
goog.require('goog.array');
goog.require('goog.asserts');

View File

@@ -0,0 +1,92 @@
goog.provide('ol.test.control.OverviewMap');
describe('ol.control.OverviewMap', function() {
var map, target;
beforeEach(function() {
target = document.createElement('div');
document.body.appendChild(target);
map = new ol.Map({
target: target
});
});
afterEach(function() {
goog.dispose(map);
document.body.removeChild(target);
map = null;
target = null;
});
describe('constructor', function() {
it('creates an overview map with the default options', function() {
var control = new ol.control.OverviewMap();
expect(control).to.be.a(ol.control.OverviewMap);
expect(control).to.be.a(ol.control.Control);
});
});
describe('setMap()', function() {
it('keeps ovmap view rotation in sync with map view rotation', function() {
var view = new ol.View({
center: [0, 0],
zoom: 0,
rotation: 0
});
map.setView(view);
var control = new ol.control.OverviewMap();
map.addControl(control);
var ovView = control.ovmap_.getView();
expect(ovView.getRotation()).to.be(0);
view.setRotation(Math.PI / 4);
expect(ovView.getRotation()).to.be(Math.PI / 4);
});
it('maintains rotation in sync if view added later', function() {
var control = new ol.control.OverviewMap();
map.addControl(control);
var ovView = control.ovmap_.getView();
expect(ovView.getRotation()).to.be(0);
var view = new ol.View({
center: [0, 0],
zoom: 0,
rotation: 0
});
map.setView(view);
view.setRotation(Math.PI / 4);
expect(ovView.getRotation()).to.be(Math.PI / 4);
});
it('stops listening to old maps', function() {
var control = new ol.control.OverviewMap();
var ovView = control.ovmap_.getView();
var view = new ol.View({
center: [0, 0],
zoom: 0,
rotation: 0
});
map.setView(view);
map.addControl(control);
view.setRotation(Math.PI / 8);
expect(ovView.getRotation()).to.be(Math.PI / 8);
map.removeControl(control);
view.setRotation(Math.PI / 4);
expect(ovView.getRotation()).to.be(Math.PI / 8);
});
});
});
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control.Control');
goog.require('ol.control.OverviewMap');