Merge branch 'master' into event

Conflicts:
	src/ol/Map.js
	src/ol/event/Drag.js
This commit is contained in:
Éric Lemoine
2012-07-09 08:57:55 +02:00
14 changed files with 670 additions and 381 deletions
+2 -31
View File
@@ -1,36 +1,7 @@
/** /**
Adds the plovr generated script to the document. The following default Adds the plovr generated script to the document.
values may be overridden with query string parameters:
* hostname - localhost
* port - 9810
* mode - SIMPLE
* id - ol
*/ */
(function() { (function() {
var search = window.location.search.substring(1); var url = "http://" + window.location.hostname + ":9810/compile?id=ol";
var params = {
hostname: "localhost",
port: "9810",
mode: "SIMPLE",
id: "ol"
};
var chunks = search.split("&");
var pair;
for (var i=chunks.length-1; i>=0; --i) {
pair = chunks[i].split("=");
params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
var host = params.hostname + ":" + params.port;
delete params.hostname;
delete params.port;
var pairs = [];
for (var key in params) {
pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
}
var url = "http://" + host + "/compile?" + pairs.join("&");
document.write("<script type='text/javascript' src='" + url + "'></script>"); document.write("<script type='text/javascript' src='" + url + "'></script>");
})(); })();
+50 -15
View File
@@ -90,6 +90,12 @@ ol.Map = function() {
* @type {Element} * @type {Element}
*/ */
this.viewport_ = null; this.viewport_ = null;
/**
* @private
* @type {goog.math.Size}
*/
this.viewportSize_ = null;
/** /**
* @private * @private
@@ -266,34 +272,60 @@ ol.Map.prototype.getResolutionForZoom = function(zoom) {
} }
}; };
/**
* @return {number} the resolution for the map at the given zoom level
*/
ol.Map.prototype.getResolution = function() {
goog.asserts.assert(goog.isDef(this.renderer_));
return this.renderer_.getResolution();
};
/** /**
* TODO: We'll have to ask the map overlay renderer for this. This method will
* not work once map space is not aligned with pixel space.
*
* @param {goog.math.Coordinate|{x: number, y: number}} pixel * @param {goog.math.Coordinate|{x: number, y: number}} pixel
* @return {ol.Loc} * @return {ol.Loc}
*/ */
ol.Map.prototype.getLocForPixel = function(pixel) { ol.Map.prototype.getLocForViewportPixel = function(pixel) {
return goog.isDef(this.renderer_) ? var size = this.getViewportSize();
this.renderer_.getLocForPixel(pixel) : null; var center = this.center_;
var resolution = this.getResolution();
var x = center.getX() + (resolution * (pixel.x - (size.width / 2)));
var y = center.getY() - (resolution * (pixel.y - (size.height / 2)));
return new ol.Loc(x, y, undefined, this.getProjection());
}; };
/** /**
* TODO: We'll have to ask the map overlay renderer for this. This method will
* not work once map space is not aligned with pixel space.
*
* @param {ol.Loc} loc * @param {ol.Loc} loc
* @return {{x: number, y: number}} * @return {{x: number, y: number}}
*/ */
ol.Map.prototype.getPixelForLoc = function(loc) { ol.Map.prototype.getViewportPixelForLoc = function(loc) {
return goog.isDef(this.renderer_) ? var size = this.getViewportSize();
this.renderer_.getPixelForLoc(loc) : null; var center = this.center_;
var resolution = this.getResolution();
return {
x: ((loc.getX() - center.getX()) / resolution) + (size.width / 2),
y: ((center.getY() - loc.getY()) / resolution) + (size.height / 2)
};
}; };
/** /**
* @return {goog.math.Size} The currently rendered map size in pixels. * @return {goog.math.Size}
*/ */
ol.Map.prototype.getSize = function() { ol.Map.prototype.getViewportSize = function() {
//TODO consider caching this when we have something like updateSize // TODO: listen for resize and set this.viewportSize_ null
return goog.isDef(this.renderer_) ? this.renderer_.getSize() : null; // https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.viewportSize_)) {
this.viewportSize_ = goog.style.getSize(this.viewport_);
}
return this.viewportSize_;
}; };
/** /**
* @param {ol.Loc} center Center in map projection. * @param {ol.Loc} center Center in map projection.
*/ */
@@ -329,8 +361,8 @@ ol.Map.prototype.setZoom = function(zoom, opt_anchor) {
return; return;
} }
if (goog.isDef(opt_anchor)) { if (goog.isDef(opt_anchor)) {
var size = this.getSize(), var size = this.getViewportSize(),
anchorLoc = this.getLocForPixel(opt_anchor), anchorLoc = this.getLocForViewportPixel(opt_anchor),
newRes = this.getResolutionForZoom(newZoom); newRes = this.getResolutionForZoom(newZoom);
newCenter = anchorLoc.add( newCenter = anchorLoc.add(
(size.width/2 - opt_anchor.x) * newRes, (size.width/2 - opt_anchor.x) * newRes,
@@ -491,7 +523,7 @@ ol.Map.prototype.createRenderer = function() {
this.mapOverlay_ = goog.dom.createDom('div', 'ol-overlay-map'); this.mapOverlay_ = goog.dom.createDom('div', 'ol-overlay-map');
this.staticOverlay_ = goog.dom.createDom('div', { this.staticOverlay_ = goog.dom.createDom('div', {
'class': staticCls, 'class': staticCls,
'style': 'width:100%;height:100%;top:0;left:0;position:absolute' 'style': 'width:100%;height:100%;top:0;left:0;position:absolute;z-index:1'
}); });
} }
if (!goog.isNull(viewport)) { if (!goog.isNull(viewport)) {
@@ -500,10 +532,13 @@ ol.Map.prototype.createRenderer = function() {
}; };
/** /**
* TODO: This method will need to be reworked/revisited when renderers can
* display a map that is rotated or otherwise not aligned with pixel space.
*
* @param {number} dx pixels to move in x direction * @param {number} dx pixels to move in x direction
* @param {number} dy pixels to move in x direction * @param {number} dy pixels to move in x direction
*/ */
ol.Map.prototype.moveByPx = function(dx, dy) { ol.Map.prototype.moveByViewportPx = function(dx, dy) {
if (!goog.isNull(this.center_) && goog.isDef(this.zoom_)) { if (!goog.isNull(this.center_) && goog.isDef(this.zoom_)) {
var resolution = this.getResolutionForZoom(this.zoom_), var resolution = this.getResolutionForZoom(this.zoom_),
center = new ol.Loc( center = new ol.Loc(
+1 -1
View File
@@ -243,7 +243,7 @@ ol.Popup.prototype.setAnchorOffset_ = function() {
this.pos_ = new ol.geom.Point(this.anchor_.getX(), this.anchor_.getY()); this.pos_ = new ol.geom.Point(this.anchor_.getX(), this.anchor_.getY());
} }
var pos = /** @type {ol.Loc} */ (this.pos_); var pos = /** @type {ol.Loc} */ (this.pos_);
var popupPosPx = this.map_.getPixelForLoc(pos); var popupPosPx = this.map_.getViewportPixelForLoc(pos);
var popupSize = goog.style.getSize(this.container_); var popupSize = goog.style.getSize(this.container_);
switch(this.placement_) { switch(this.placement_) {
+2 -13
View File
@@ -43,9 +43,7 @@ ol.control.Attribution.prototype.setMap = function(map) {
var staticOverlay = map.getStaticOverlay(); var staticOverlay = map.getStaticOverlay();
if (goog.isNull(this.container_)) { if (goog.isNull(this.container_)) {
this.container_ = goog.dom.createDom('div', this.CLS); this.container_ = goog.dom.createDom('div', this.CLS);
// This is not registered as priority listener, so priority listeners goog.events.listen(this.container_, 'click', ol.event.stopPropagation);
// can still get the click event.
map.getEvents().register('click', this.stopLinkClick, this);
} }
if (!goog.isNull(staticOverlay)) { if (!goog.isNull(staticOverlay)) {
goog.dom.append(staticOverlay, this.container_); goog.dom.append(staticOverlay, this.container_);
@@ -53,16 +51,6 @@ ol.control.Attribution.prototype.setMap = function(map) {
goog.base(this, 'setMap', map); goog.base(this, 'setMap', map);
}; };
/**
* Prevent clicks on links in the attribution from getting through to
* listeners.
*/
ol.control.Attribution.prototype.stopLinkClick = function(evt) {
var node = evt.target;
return node.nodeName !== 'A' ||
!goog.dom.getAncestorByClass(node, this.CLS);
};
/** @inheritDoc */ /** @inheritDoc */
ol.control.Attribution.prototype.activate = function() { ol.control.Attribution.prototype.activate = function() {
var active = goog.base(this, 'activate'); var active = goog.base(this, 'activate');
@@ -96,6 +84,7 @@ ol.control.Attribution.prototype.update = function() {
}; };
ol.control.Attribution.prototype.destroy = function() { ol.control.Attribution.prototype.destroy = function() {
goog.events.unlisten(this.container_, 'click', ol.event.stopPropagation);
goog.dom.removeNode(this.container_); goog.dom.removeNode(this.container_);
goog.base(this, 'destroy'); goog.base(this, 'destroy');
}; };
+16 -5
View File
@@ -20,6 +20,12 @@ ol.control.Navigation = function(opt_autoActivate) {
this.autoActivate_ = this.autoActivate_ =
goog.isDef(opt_autoActivate) ? opt_autoActivate : true; goog.isDef(opt_autoActivate) ? opt_autoActivate : true;
/**
* @type {number?}
* @private
*/
this.zoomBlocked_ = null;
}; };
goog.inherits(ol.control.Navigation, ol.control.Control); goog.inherits(ol.control.Navigation, ol.control.Control);
@@ -52,7 +58,7 @@ ol.control.Navigation.prototype.deactivate = function() {
* @param {Object} evt * @param {Object} evt
*/ */
ol.control.Navigation.prototype.moveMap = function(evt) { ol.control.Navigation.prototype.moveMap = function(evt) {
this.map_.moveByPx(evt.deltaX, evt.deltaY); this.map_.moveByViewportPx(evt.deltaX, evt.deltaY);
return false; return false;
}; };
@@ -60,12 +66,17 @@ ol.control.Navigation.prototype.moveMap = function(evt) {
* @param {Event} evt * @param {Event} evt
*/ */
ol.control.Navigation.prototype.zoomMap = function(evt) { ol.control.Navigation.prototype.zoomMap = function(evt) {
var map = this.map_, var me = this;
delta = ((evt.deltaY / 3) | 0); if (evt.deltaY === 0 || me.zoomBlocked_) {
if (Math.abs(delta) === 0) {
return; return;
} }
map.setZoom(map.getZoom()-delta, map.getEvents().getPointerPosition(evt)); me.zoomBlocked_ = window.setTimeout(function() {
me.zoomBlocked_ = null;
}, 200);
var map = me.map_,
step = evt.deltaY / Math.abs(evt.deltaY);
map.setZoom(map.getZoom()-step, map.getEvents().getPointerPosition(evt));
// We don't want the page to scroll. // We don't want the page to scroll.
evt.preventDefault(); evt.preventDefault();
return false; return false;
+35 -34
View File
@@ -12,13 +12,23 @@ goog.require('goog.dom');
* @param {boolean|undefined} opt_autoActivate * @param {boolean|undefined} opt_autoActivate
*/ */
ol.control.Zoom = function(opt_autoActivate) { ol.control.Zoom = function(opt_autoActivate) {
goog.base(this, opt_autoActivate); goog.base(this, opt_autoActivate);
/**
* @type {Node}
*/
this.inButton_ = null;
/**
* @type {Node}
*/
this.outButton_ = null;
/** /**
* Activate this control when it is added to a map. Default is true. * Activate this control when it is added to a map. Default is true.
* *
* @type {boolean} autoActivate * @type {boolean}
*/ */
this.autoActivate_ = this.autoActivate_ =
goog.isDef(opt_autoActivate) ? opt_autoActivate : true; goog.isDef(opt_autoActivate) ? opt_autoActivate : true;
@@ -30,38 +40,38 @@ goog.inherits(ol.control.Zoom, ol.control.Control);
* @param {ol.Map} map * @param {ol.Map} map
*/ */
ol.control.Zoom.prototype.setMap = function(map) { ol.control.Zoom.prototype.setMap = function(map) {
goog.base(this, 'setMap', map);
var container = goog.dom.createDom('div', ol.control.Zoom.RES.CLS); var container = goog.dom.createDom('div', ol.control.Zoom.RES.CLS);
var inButton = goog.dom.createDom( this.inButton_ = goog.dom.createDom(
'div', ol.control.Zoom.RES.IN_CLS, 'div', ol.control.Zoom.RES.IN_CLS,
goog.dom.createDom('a', {'href': '#zoomIn'}) goog.dom.createDom('a', {'href': '#zoomIn'})
); );
goog.dom.setTextContent( goog.dom.setTextContent(
/** @type {Element} */ (inButton.firstChild), /** @type {Element} */ (this.inButton_.firstChild),
ol.control.Zoom.RES.IN_TEXT ol.control.Zoom.RES.IN_TEXT
); );
var outButton = goog.dom.createDom( this.outButton_ = goog.dom.createDom(
'div', ol.control.Zoom.RES.OUT_CLS, 'div', ol.control.Zoom.RES.OUT_CLS,
goog.dom.createDom('a', {'href': '#zoomOut'}) goog.dom.createDom('a', {'href': '#zoomOut'})
); );
goog.dom.setTextContent( goog.dom.setTextContent(
/** @type {Element} */ (outButton.firstChild), /** @type {Element} */ (this.outButton_.firstChild),
ol.control.Zoom.RES.OUT_TEXT ol.control.Zoom.RES.OUT_TEXT
); );
goog.dom.append(container, inButton, outButton); goog.dom.append(container, this.inButton_, this.outButton_);
var overlay = map.getStaticOverlay(); var overlay = map.getStaticOverlay();
if (goog.isDefAndNotNull(overlay)) { if (goog.isDefAndNotNull(overlay)) {
goog.dom.append(overlay, container); goog.dom.append(overlay, container);
} }
goog.base(this, 'setMap', map);
}; };
/** @inheritDoc */ /** @inheritDoc */
ol.control.Zoom.prototype.activate = function() { ol.control.Zoom.prototype.activate = function() {
var active = goog.base(this, 'activate'); var active = goog.base(this, 'activate');
if (active) { if (active) {
this.map_.getEvents().register('click', this.handle, this); goog.events.listen(this.inButton_, 'click', this.handleIn, false, this);
this.map_.getEvents().register('keypress', this.handle, this); goog.events.listen(this.outButton_, 'click', this.handleOut, false, this);
} }
return active; return active;
}; };
@@ -70,37 +80,28 @@ ol.control.Zoom.prototype.activate = function() {
ol.control.Zoom.prototype.deactivate = function() { ol.control.Zoom.prototype.deactivate = function() {
var inactive = goog.base(this, 'deactivate'); var inactive = goog.base(this, 'deactivate');
if (inactive) { if (inactive) {
this.map_.getEvents().unregister('click', this.handle, this); goog.events.unlisten(this.inButton_, 'click', this.handleIn, false, this);
this.map_.getEvents().unregister('keypress', this.handle, this); goog.events.unlisten(this.outButton_, 'click', this.handleOut, false, this);
} }
return inactive; return inactive;
}; };
/** /**
* @param {Event} evt * @param {Event} evt
* @return {boolean}
*/ */
ol.control.Zoom.prototype.handle = function(evt) { ol.control.Zoom.prototype.handleIn = function(evt) {
var target = /** @type {Node} */ (evt.target), this.map_.zoomIn();
handled = false; evt.preventDefault();
if (evt.type === 'click' || ol.event.isEnterOrSpace(evt)) { evt.stopPropagation();
if (goog.dom.getAncestorByClass(target, ol.control.Zoom.RES.IN_CLS)) { };
this.map_.zoomIn();
handled = true; /**
} else * @param {Event} evt
if (goog.dom.getAncestorByClass(target, ol.control.Zoom.RES.OUT_CLS)) { */
this.map_.zoomOut(); ol.control.Zoom.prototype.handleOut = function(evt) {
handled = true; this.map_.zoomOut();
} evt.preventDefault();
if (handled) { evt.stopPropagation();
// Stop default behavior (i.e. don't follow link to anchor)
evt.preventDefault();
// On Android 2.3, the above does not prevent the link from being
// followed, but stopPropagation does.
evt.stopPropagation();
}
}
return !handled;
}; };
ol.control.Zoom.prototype.destroy = function() { ol.control.Zoom.prototype.destroy = function() {
+95
View File
@@ -0,0 +1,95 @@
goog.provide('ol.event.Drag');
goog.require('ol.event');
goog.require('ol.event.ISequence');
goog.require('goog.functions');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.DragEvent');
goog.require('goog.fx.Dragger.EventType');
/**
* Event sequence that provides a 'dragstart', 'drag' and 'dragend' events.
* Event objects of the 'drag' events have 'deltaX' and 'deltaY' values with
* the relative pixel movement since the previous 'drag' or 'dragstart' event.
*
* @constructor
* @param {ol.event.Events} target The Events instance that handles events.
* @implements {ol.event.ISequence}
* @export
*/
ol.event.Drag = function(target) {
var previousX = 0, previousY = 0,
element = target.getElement(),
dragger = new goog.fx.Dragger(element);
/**
* @private
* @type {goog.fx.Dragger}
*/
this.dragger_ = dragger;
/**
* @private
* @type {ol.event.Events}
*/
this.target_ = target;
// We want to swallow the click event that gets fired after dragging.
var newSequence;
function unregisterClickStopper() {
target.unregister('click', goog.functions.FALSE, undefined, true);
}
// no default for mousemove and touchmove events to avoid page scrolling.
target.register('mousemove', ol.event.preventDefault);
target.register('touchmove', ol.event.preventDefault);
dragger.defaultAction = function(x, y) {};
dragger.addEventListener(goog.fx.Dragger.EventType.START, function(evt) {
evt.target = element;
evt.type = 'dragstart';
previousX = evt.clientX;
previousY = evt.clientY;
newSequence = true;
target.triggerEvent(evt.type, evt);
});
dragger.addEventListener(goog.fx.Dragger.EventType.DRAG, function(evt) {
evt.target = element;
evt.deltaX = evt.clientX - previousX;
evt.deltaY = evt.clientY - previousY;
previousX = evt.clientX;
previousY = evt.clientY;
if (newSequence) {
// Once we are in the drag sequence, we know that we need to
// get rid of the click event that gets fired when we are done
// dragging.
target.register('click', goog.functions.FALSE, undefined, true);
newSequence = false;
}
target.triggerEvent(evt.type, evt);
});
dragger.addEventListener(goog.fx.Dragger.EventType.END, function(evt) {
evt.target = element;
evt.type = 'dragend';
target.triggerEvent(evt.type, evt);
// Unregister the click stopper in the next cycle
window.setTimeout(unregisterClickStopper, 0);
});
// Don't swallow the click event if our sequence cancels early.
dragger.addEventListener(
goog.fx.Dragger.EventType.EARLY_CANCEL, unregisterClickStopper
);
};
/** @inheritDoc */
ol.event.Drag.prototype.destroy = function() {
this.target_.unregister('mousemove', ol.event.preventDefault);
this.target_.unregister('touchmove', ol.event.preventDefault);
this.dragger_.dispose();
goog.object.clear(this);
};
ol.event.addSequenceProvider('drag', ol.event.Drag);
+14 -9
View File
@@ -42,16 +42,21 @@ ol.event.isMultiTouch = function(evt) {
}; };
/** /**
* Is the event a keyboard event with Enter or Space pressed? * Call preventDefault on the provided event.
* *
* @param {!Event} evt * @param {!Event} evt
* @return {boolean}
*/ */
ol.event.isEnterOrSpace = function(evt) { ol.event.preventDefault = function(evt) {
return evt.type === "keypress" && evt.preventDefault();
(evt.keyCode === goog.events.KeyCodes.ENTER || };
evt.keyCode === goog.events.KeyCodes.SPACE ||
evt.keyCode === goog.events.KeyCodes.MAC_ENTER); /**
* Call stopPropagation on the provided event.
*
* @param {!Event} evt
*/
ol.event.stopPropagation = function(evt) {
evt.stopPropagation();
}; };
@@ -155,7 +160,7 @@ ol.event.Events.prototype.setElement = function(element) {
if (this.element_) { if (this.element_) {
for (t in types) { for (t in types) {
goog.events.unlisten( goog.events.unlisten(
this.element_, types[t], this.handleBrowserEvent, true, this this.element_, types[t], this.handleBrowserEvent, false, this
); );
} }
this.destroySequences(); this.destroySequences();
@@ -166,7 +171,7 @@ ol.event.Events.prototype.setElement = function(element) {
this.createSequences(); this.createSequences();
for (t in types) { for (t in types) {
goog.events.listen( goog.events.listen(
element, types[t], this.handleBrowserEvent, true, this element, types[t], this.handleBrowserEvent, false, this
); );
} }
} }
+174 -20
View File
@@ -4,7 +4,11 @@ goog.require('ol.renderer.MapRenderer');
goog.require('ol.renderer.LayerRenderer'); goog.require('ol.renderer.LayerRenderer');
goog.require('ol.layer.Layer'); goog.require('ol.layer.Layer');
goog.require('ol.Loc'); goog.require('ol.Loc');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.style');
goog.require('goog.math.Coordinate');
/** /**
* @constructor * @constructor
@@ -21,21 +25,43 @@ ol.renderer.Composite = function(container) {
*/ */
this.renderers_ = []; this.renderers_ = [];
var target = document.createElement("div");
target.className = "ol-renderer-composite";
target.style.position = "absolute";
target.style.height = "100%";
target.style.width = "100%";
container.appendChild(target);
/** /**
* @type Element * Pixel buffer for renderer container.
*
* @type {number}
* @private * @private
*/ */
this.target_ = target; this.buffer_ = 128;
/**
* @type {Element}
* @private
*/
this.target_ = null;
/**
* The current top left corner location of the target element (map coords).
*
* @type {ol.Loc}
* @private
*/
this.targetOrigin_ = null;
/**
* The pixel offset of the target element with respect to its container.
*
* @type {goog.math.Coordinate}
* @private
*/
this.targetOffset_ = null;
/**
* @type {Object}
* @private
*/
this.layerContainers_ = {};
}; };
goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer); goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer);
/** /**
@@ -45,22 +71,129 @@ goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer);
* @param {boolean} animate * @param {boolean} animate
*/ */
ol.renderer.Composite.prototype.draw = function(layers, center, resolution, animate) { ol.renderer.Composite.prototype.draw = function(layers, center, resolution, animate) {
if (goog.isNull(this.target_)) {
// first rendering
this.createTarget_(center, resolution);
}
// TODO: deal with layer order and removal // TODO: deal with layer order and removal
for (var i=0, ii=layers.length; i<ii; ++i) {
this.getOrCreateRenderer(layers[i], i).draw(center, resolution); if (this.renderedResolution_) {
if (resolution !== this.renderedResolution_) {
// TODO: apply transition to old target
this.resetTarget_(center, resolution);
}
}
this.renderedResolution_ = resolution;
// shift target element to account for center change
if (this.renderedCenter_) {
this.shiftTarget_(center, resolution);
} }
this.renderedCenter_ = center; this.renderedCenter_ = center;
this.renderedResolution_ = resolution;
// update each layer renderer
var renderer;
for (var i=0, ii=layers.length; i<ii; ++i) {
renderer = this.getOrCreateRenderer_(layers[i], i);
renderer.draw(center, resolution);
}
}; };
/**
* Create a new target element for layer renderer containers.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.createTarget_ = function(center, resolution) {
this.targetOrigin_ = this.getOriginForCenterAndRes_(center, resolution);
var containerSize = this.getContainerSize();
var containerWidth = containerSize.width;
var containerHeight = containerSize.height;
var buffer = this.buffer_;
var targetWidth = containerWidth + (2 * buffer);
var targetHeight = containerHeight + (2 * buffer);
var offset = new goog.math.Coordinate(-buffer, -buffer);
var target = goog.dom.createDom('div', {
'class': 'ol-renderer-composite',
'style': 'width:' + targetWidth + 'px;height:' + targetHeight + 'px;' +
'top:' + offset.y + 'px;left:' + offset.x + 'px;' +
'position:absolute'
});
this.target_ = target;
this.targetOffset_ = offset;
this.renderedCenter_ = center;
goog.dom.appendChild(this.container_, target);
};
/**
* @param {ol.Loc} center
* @param {number} resolution
* @return {ol.Loc}
*/
ol.renderer.Composite.prototype.getOriginForCenterAndRes_ = function(center, resolution) {
var containerSize = this.getContainerSize();
var containerWidth = containerSize.width;
var containerHeight = containerSize.height;
var buffer = this.buffer_;
var targetWidth = containerWidth + (2 * buffer);
var targetHeight = containerHeight + (2 * buffer);
return new ol.Loc(
center.getX() - (resolution * targetWidth / 2),
center.getY() + (resolution * targetHeight / 2)
);
};
/**
* Adjust the position of the renderer target given the new center.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.shiftTarget_ = function(center, resolution) {
var oldCenter = this.renderedCenter_;
var dx = Math.round((oldCenter.getX() - center.getX()) / resolution);
var dy = Math.round((center.getY() - oldCenter.getY()) / resolution);
if (!(dx == 0 && dy == 0)) {
var offset = this.targetOffset_;
offset.x += Math.round((oldCenter.getX() - center.getX()) / resolution);
offset.y += Math.round((center.getY() - oldCenter.getY()) / resolution);
goog.style.setPosition(this.target_, offset);
}
};
/**
* Reposition the target element back to the original offset.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.resetTarget_ = function(center, resolution) {
this.targetOrigin_ = this.getOriginForCenterAndRes_(center, resolution);
for (var i=0, ii=this.renderers_.length; i<ii; ++i) {
this.renderers_[i].setContainerOrigin(this.targetOrigin_);
}
var offset = new goog.math.Coordinate(-this.buffer_, -this.buffer_);
this.targetOffset_ = offset;
this.renderedCenter_ = center;
goog.style.setPosition(this.target_, offset);
};
/** /**
* @param {ol.layer.Layer} layer * @param {ol.layer.Layer} layer
* @param {number} index * @param {number} index
*/ */
ol.renderer.Composite.prototype.getOrCreateRenderer = function(layer, index) { ol.renderer.Composite.prototype.getOrCreateRenderer_ = function(layer, index) {
var renderer = this.getRenderer(layer); var renderer = this.getRenderer_(layer);
if (goog.isNull(renderer)) { if (goog.isNull(renderer)) {
renderer = this.createRenderer(layer); renderer = this.createRenderer_(layer);
goog.array.insertAt(this.renderers_, renderer, index); goog.array.insertAt(this.renderers_, renderer, index);
} }
return renderer; return renderer;
@@ -68,21 +201,42 @@ ol.renderer.Composite.prototype.getOrCreateRenderer = function(layer, index) {
/** /**
* @param {ol.layer.Layer} layer * @param {ol.layer.Layer} layer
* @return {ol.renderer.LayerRenderer}
*/ */
ol.renderer.Composite.prototype.getRenderer = function(layer) { ol.renderer.Composite.prototype.getRenderer_ = function(layer) {
function finder(candidate) { function finder(candidate) {
return candidate.getLayer() === layer; return candidate.getLayer() === layer;
} }
return goog.array.find(this.renderers_, finder); var renderer = goog.array.find(this.renderers_, finder);
return /** @type {ol.renderer.LayerRenderer} */ renderer;
}; };
/** /**
* @param {ol.layer.Layer} layer * @param {ol.layer.Layer} layer
*/ */
ol.renderer.Composite.prototype.createRenderer = function(layer) { ol.renderer.Composite.prototype.createRenderer_ = function(layer) {
var Renderer = this.pickRendererType(layer); var Renderer = this.pickRendererType(layer);
goog.asserts.assert(Renderer, "No supported renderer for layer: " + layer); goog.asserts.assert(Renderer, "No supported renderer for layer: " + layer);
return new Renderer(this.target_, layer);
var container = goog.dom.createDom('div', {
'class': 'ol-renderer-composite-layer',
'style': 'width:100%;height:100%;top:0;left:0;position:absolute'
});
goog.dom.appendChild(this.target_, container);
var renderer = new Renderer(container, layer);
renderer.setContainerOrigin(this.targetOrigin_);
this.layerContainers_[goog.getUid(renderer)] = container;
return renderer;
};
/**
* @param {ol.renderer.LayerRenderer} renderer
* @return {Element}
*/
ol.renderer.Composite.prototype.getRendererContainer_ = function(renderer) {
var container = this.layerContainers_[goog.getUid(renderer)];
goog.asserts.assert(goog.isDef(container));
return container;
}; };
/** /**
+38 -11
View File
@@ -1,5 +1,8 @@
goog.provide('ol.renderer.LayerRenderer'); goog.provide('ol.renderer.LayerRenderer');
goog.require('goog.math.Coordinate');
goog.require('goog.math.Size');
/** /**
* A single layer renderer that will be created by the composite map renderer. * A single layer renderer that will be created by the composite map renderer.
* *
@@ -15,24 +18,48 @@ ol.renderer.LayerRenderer = function(container, layer) {
*/ */
this.container_ = container; this.container_ = container;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
/**
* Location of the top-left corner of the renderer container in map coords.
*
* @type {ol.Loc}
* @protected
*/
this.containerOrigin_ = null;
/** /**
* @type {!ol.layer.Layer} * @type {!ol.layer.Layer}
* @protected * @protected
*/ */
this.layer_ = layer; this.layer_ = layer;
var target = goog.dom.createDom('div', { };
'class': 'ol-renderer-layer',
'style': 'position:absolute;height:1px:width:1px'
});
goog.dom.appendChild(container, target);
/** /**
* @type Element * @return {goog.math.Size}
* @protected * @protected
*/ */
this.target_ = target; ol.renderer.LayerRenderer.prototype.getContainerSize = function() {
// TODO: listen for resize and set this.constainerSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.containerSize_)) {
this.containerSize_ = goog.style.getSize(this.container_);
}
return this.containerSize_;
};
/**
* Set the location of the top-left corner of the renderer container.
*
* @param {ol.Loc} origin The container origin.
*/
ol.renderer.LayerRenderer.prototype.setContainerOrigin = function(origin) {
this.containerOrigin_ = origin;
}; };
/** /**
+28 -35
View File
@@ -1,6 +1,7 @@
goog.provide('ol.renderer.MapRenderer'); goog.provide('ol.renderer.MapRenderer');
goog.require('goog.style'); goog.require('goog.style');
goog.require('goog.math.Size');
/** /**
* @constructor * @constructor
@@ -13,6 +14,12 @@ ol.renderer.MapRenderer = function(container) {
* @protected * @protected
*/ */
this.container_ = container; this.container_ = container;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
/** /**
* @type {ol.Loc} * @type {ol.Loc}
@@ -28,6 +35,20 @@ ol.renderer.MapRenderer = function(container) {
}; };
/**
* @return {goog.math.Size}
* @protected
*/
ol.renderer.MapRenderer.prototype.getContainerSize = function() {
// TODO: listen for resize and set this.constainerSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.containerSize_)) {
this.containerSize_ = goog.style.getSize(this.container_);
}
return this.containerSize_;
};
/** /**
* @param {Array.<ol.layer.Layer>} layers * @param {Array.<ol.layer.Layer>} layers
* @param {ol.Loc} center * @param {ol.Loc} center
@@ -37,6 +58,13 @@ ol.renderer.MapRenderer = function(container) {
ol.renderer.MapRenderer.prototype.draw = function(layers, center, resolution, animate) { ol.renderer.MapRenderer.prototype.draw = function(layers, center, resolution, animate) {
}; };
/**
* @return {number} The rendered resolution.
*/
ol.renderer.MapRenderer.prototype.getResolution = function() {
return this.renderedResolution_;
};
/** /**
* TODO: determine a closure friendly way to register map renderers. * TODO: determine a closure friendly way to register map renderers.
* @type {Array} * @type {Array}
@@ -80,38 +108,3 @@ ol.renderer.MapRenderer.pickRendererType = function(preferences) {
// if we didn't find any of the preferred renderers, use the first // if we didn't find any of the preferred renderers, use the first
return Renderer || Candidates[0] || null; return Renderer || Candidates[0] || null;
}; };
/**
* @param {goog.math.Coordinate|{x: number, y: number}} pixel
* @return {ol.Loc}
*/
ol.renderer.MapRenderer.prototype.getLocForPixel = function(pixel) {
var center = this.renderedCenter_,
resolution = this.renderedResolution_,
size = goog.style.getSize(this.container_);
return center.add(
(pixel.x - size.width/2) * resolution,
(size.height/2 - pixel.y) * resolution
);
};
/**
* @param {ol.Loc} loc
* @return {{x: number, y: number}}
*/
ol.renderer.MapRenderer.prototype.getPixelForLoc = function(loc) {
var center = this.renderedCenter_,
resolution = this.renderedResolution_,
size = this.getSize();
return {
x: (size.width*resolution/2 + loc.getX() - center.getX())/resolution,
y: (size.height*resolution/2 - loc.getY() + center.getY())/resolution
};
};
/**
* @return {goog.math.Size} The currently rendered map size in pixels.
*/
ol.renderer.MapRenderer.prototype.getSize = function() {
return goog.style.getSize(this.container_);
};
+208 -194
View File
@@ -7,6 +7,7 @@ goog.require('ol.TileSet');
goog.require('ol.Bounds'); goog.require('ol.Bounds');
goog.require('goog.style'); goog.require('goog.style');
goog.require('goog.math.Box');
/** /**
@@ -37,14 +38,14 @@ ol.renderer.TileLayerRenderer = function(container, layer) {
this.tileSize_ = layer.getTileSize(); this.tileSize_ = layer.getTileSize();
/** /**
* @type {number} * @type {boolean}
*/ */
this.xRight_ = layer.getXRight() ? 1 : -1; this.xRight_ = layer.getXRight();
/** /**
* @type {number} * @type {boolean}
*/ */
this.yDown_ = layer.getYDown() ? 1 : -1; this.yDown_ = layer.getYDown();
/** /**
* @type {number|undefined} * @type {number|undefined}
@@ -52,86 +53,15 @@ ol.renderer.TileLayerRenderer = function(container, layer) {
*/ */
this.renderedResolution_ = undefined; this.renderedResolution_ = undefined;
/**
* @type {number|undefined}
* @private
*/
this.renderedTop_ = undefined;
/**
* @type {number|undefined}
* @private
*/
this.renderedRight_ = undefined;
/**
* @type {number|undefined}
* @private
*/
this.renderedBottom_ = undefined;
/**
* @type {number|undefined}
* @private
*/
this.renderedLeft_ = undefined;
/** /**
* @type {number|undefined} * @type {number|undefined}
* @private * @private
*/ */
this.renderedZ_ = undefined; this.renderedZ_ = undefined;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
}; };
goog.inherits(ol.renderer.TileLayerRenderer, ol.renderer.LayerRenderer); goog.inherits(ol.renderer.TileLayerRenderer, ol.renderer.LayerRenderer);
/**
* @param {number} resolution
* @return {Array.<number>}
*/
ol.renderer.TileLayerRenderer.prototype.getPreferredResAndZ_ = function(resolution) {
var minDiff = Number.POSITIVE_INFINITY;
var candidate, diff, z, r;
for (var i=0, ii=this.layerResolutions_.length; i<ii; ++i) {
// assumes sorted resolutions
candidate = this.layerResolutions_[i];
diff = Math.abs(resolution - candidate);
if (diff < minDiff) {
z = i;
r = candidate;
minDiff = diff;
} else {
break;
}
}
return [r, z];
};
/**
* @return {goog.math.Size}
*/
ol.renderer.TileLayerRenderer.prototype.getContainerSize_ = function() {
// TODO: listen for resize and set this.constainerSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.containerSize_)) {
this.containerSize_ = goog.style.getSize(this.container_);
}
return this.containerSize_;
};
/**
* Tiles rendered at the current resolution;
* @type {Object}
*/
ol.renderer.TileLayerRenderer.prototype.renderedTiles_ = {};
/** /**
* Render the layer. * Render the layer.
* *
@@ -140,152 +70,234 @@ ol.renderer.TileLayerRenderer.prototype.renderedTiles_ = {};
*/ */
ol.renderer.TileLayerRenderer.prototype.draw = function(center, resolution) { ol.renderer.TileLayerRenderer.prototype.draw = function(center, resolution) {
if (resolution !== this.renderedResolution_) { if (resolution !== this.renderedResolution_) {
this.changeResolution_(center, resolution); this.changeResolution_(resolution);
} }
var pair = this.getPreferredResAndZ_(resolution); var z = this.renderedZ_;
var tileResolution = pair[0]; var tileOrigin = this.tileOrigin_;
var tileZ = pair[1];
var scale = resolution / tileResolution;
var pxMapSize = this.getContainerSize_();
var xRight = this.xRight_;
var yDown = this.yDown_;
var halfMapWidth = (resolution * pxMapSize.width) / 2; var offset = this.getTileOffset_();
var halfMapHeight = (resolution * pxMapSize.height) / 2; var tileBox = this.getTileBox_(center, resolution);
var centerX = center.getX();
var centerY = center.getY();
var mapMinX = centerX - halfMapWidth;
var mapMaxY = centerY + halfMapHeight;
var pxOffsetX = Math.round((mapMinX - this.tileOrigin_[0]) / resolution);
var pxOffsetY = Math.round((this.tileOrigin_[1] - mapMaxY) / resolution);
// this gives us the desired size in fractional pixels
var pxTileWidth = this.tileSize_[0] / scale;
var pxTileHeight = this.tileSize_[1] / scale;
// this is the index of the top left tile
var leftTileX = Math.floor(xRight * pxOffsetX / pxTileWidth);
var topTileY = Math.floor(yDown * pxOffsetY / pxTileHeight);
var pxMinX;
if (xRight > 0) {
pxMinX = Math.round(leftTileX * pxTileWidth) - pxOffsetX;
} else {
pxMinX = Math.round((-leftTileX-1) * pxTileWidth) - pxOffsetX;
}
var pxMinY;
if (yDown > 0) {
pxMinY = Math.round(topTileY * pxTileHeight) - pxOffsetY;
} else {
pxMinY = Math.round((-topTileY-1) * pxTileHeight) - pxOffsetY;
}
var pxTileLeft = pxMinX;
var pxTileTop = pxMinY;
var numTilesWide = Math.ceil(pxMapSize.width / pxTileWidth);
var numTilesHigh = Math.ceil(pxMapSize.height / pxTileHeight);
// assume a buffer of zero for now
if (pxMinX < 0) {
numTilesWide += 1;
}
if (pxMinY < 0) {
numTilesHigh += 1;
}
var tileX, tileY, tile, img, pxTileRight, pxTileBottom, xyz, append;
var fragment = document.createDocumentFragment(); var fragment = document.createDocumentFragment();
var newTiles = false; var ijz, key, tile, xyz, box, img, newTiles = false;
for (var i=0; i<numTilesWide; ++i) { for (var i=tileBox.left; i<tileBox.right; ++i) {
pxTileTop = pxMinY; for (var j=tileBox.top; j<tileBox.bottom; ++j) {
tileX = leftTileX + (i * xRight); ijz = [i, j, z];
if (scale !== 1) { key = ijz.join(",");
pxTileRight = Math.round(pxMinX + ((i+1) * pxTileWidth)); tile = this.renderedTiles_[key];
} else {
pxTileRight = pxTileLeft + pxTileWidth;
}
for (var j=0; j<numTilesHigh; ++j) {
append = false;
tileY = topTileY + (j * yDown);
xyz = tileX + "," + tileY + "," + tileZ;
if (scale !== 1) {
pxTileBottom = Math.round(pxMinY + ((j+1) * pxTileHeight));
} else {
pxTileBottom = pxTileTop + pxTileHeight;
}
img = null;
tile = this.renderedTiles_[xyz];
if (!tile) { if (!tile) {
tile = this.layer_.getTileForXYZ(tileX, tileY, tileZ); xyz = this.getTileCoordsFromNormalizedCoords_(ijz);
tile = this.layer_.getTileForXYZ(xyz[0], xyz[1], xyz[2]);
if (tile) { if (tile) {
if (!tile.isLoaded() && !tile.isLoading()) { if (!tile.isLoaded() && !tile.isLoading()) {
tile.load(); tile.load();
} }
this.renderedTiles_[xyz] = tile; this.renderedTiles_[key] = tile;
box = this.getTilePixelBox_(ijz, resolution);
img = tile.getImg(); img = tile.getImg();
img.style.top = (box.top - offset.y) + "px";
img.style.left = (box.left - offset.x) + "px";
/**
* We need to set the size here even if the scale is 1
* because the image may have been scaled previously. If
* we want to avoid setting size unnecessarily, the tile
* should keep track of the scale.
*/
img.style.height = (box.bottom - box.top) + "px";
img.style.width = (box.right - box.left) + "px";
goog.dom.appendChild(fragment, img); goog.dom.appendChild(fragment, img);
newTiles = true; newTiles = true;
} }
} else {
img = tile.getImg();
} }
if (img) {
img.style.top = pxTileTop + "px";
img.style.left = pxTileLeft + "px";
if (scale !== 1) {
img.style.height = (pxTileRight - pxTileLeft) + "px";
img.style.width = (pxTileBottom - pxTileTop) + "px";
}
}
pxTileTop = pxTileBottom;
} }
pxTileLeft = pxTileRight;
} }
if (newTiles) { if (newTiles) {
this.target_.appendChild(fragment); this.container_.appendChild(fragment);
} }
this.renderedResolution_ = resolution;
this.renderedTop_ = topTileY; this.renderedTileBox_ = tileBox;
this.renderedRight_ = tileX;
this.renderedBottom_ = tileY;
this.renderedLeft_ = leftTileX;
this.renderedZ_ = tileZ;
this.removeInvisibleTiles_(); this.removeInvisibleTiles_();
}; };
/**
* Get the pixel offset between the tile origin and the container origin.
* TODO: cache this and invalidate it with changes to the container origin.
*
* @return {goog.math.Coordinate}
*/
ol.renderer.TileLayerRenderer.prototype.getTileOffset_ = function() {
var resolution = this.renderedResolution_;
return new goog.math.Coordinate(
Math.round((this.containerOrigin_.getX() - this.tileOrigin_[0]) / resolution),
Math.round((this.tileOrigin_[1] - this.containerOrigin_.getY()) / resolution)
);
};
/**
* @param {Array.<number>} ijz
* @param {number} resolution
* @return {goog.math.Box}
*/
ol.renderer.TileLayerRenderer.prototype.getTilePixelBox_ = function(ijz, resolution) {
var tileResolution = this.layerResolutions_[ijz[2]];
var scale = resolution / tileResolution;
var tileSize = this.tileSize_;
// desired tile size (in fractional pixels)
var fpxTileWidth = tileSize[0] / scale;
var fpxTileHeight = tileSize[1] / scale;
var col = ijz[0];
var left = Math.round(col * fpxTileWidth); // inclusive
var right = Math.round((col + 1) * fpxTileWidth); // exclusive
var row = ijz[1];
var top = Math.round(row * fpxTileHeight); // inclusive
var bottom = Math.round((row + 1) * fpxTileWidth); // exclusive
return new goog.math.Box(top, right, bottom, left);
};
/**
* @param {ol.Loc} loc
* @param {number} resolution
* @return {goog.math.Coordinate}
*/
ol.renderer.TileLayerRenderer.prototype.getNormalizedTileCoord_ = function(loc, resolution) {
var tileOrigin = this.tileOrigin_;
var tileSize = this.tileSize_;
var pair = this.getPreferredResAndZ_(resolution);
var tileResolution = pair[0];
var z = pair[1];
var scale = resolution / tileResolution;
// offset from tile origin in pixel space
var dx = Math.round((loc.getX() - tileOrigin[0]) / resolution);
var dy = Math.round((tileOrigin[1] - loc.getY()) / resolution);
// desired tile size (in fractional pixels)
var fpxTileWidth = tileSize[0] / scale;
var fpxTileHeight = tileSize[1] / scale;
// determine normalized col number (0 based, ascending right)
var col = Math.floor(dx / fpxTileWidth);
// determine normalized row number (0 based, ascending down)
var row = Math.floor(dy / fpxTileHeight);
var box = this.getTilePixelBox_([col, row, z], resolution);
// adjust col to allow for stretched tiles
if (dx < box.left) {
col -= 1;
} else if (dx >= box.right) {
col += 1;
}
// adjust row to allow for stretched tiles
if (dy < box.top) {
row -= 1;
} else if (dy >= box.bottom) {
row += 1;
}
return new goog.math.Coordinate(col, row);
};
/**
* @param {number} resolution
* @return {Array.<number>}
*/
ol.renderer.TileLayerRenderer.prototype.getPreferredResAndZ_ = (function() {
var cache = {};
return function(resolution) {
if (resolution in cache) {
return cache[resolution];
}
var minDiff = Number.POSITIVE_INFINITY;
var candidate, diff, z, r;
for (var i=0, ii=this.layerResolutions_.length; i<ii; ++i) {
// assumes sorted resolutions
candidate = this.layerResolutions_[i];
diff = Math.abs(resolution - candidate);
if (diff < minDiff) {
z = i;
r = candidate;
minDiff = diff;
} else {
break;
}
}
var pair = cache[resolution] = [r, z];
return pair;
};
})();
/**
* Tiles rendered at the current resolution;
* @type {Object}
*/
ol.renderer.TileLayerRenderer.prototype.renderedTiles_ = {};
/**
* @param {Array.<number>} ijz
* @return {Array.<number>}
*/
ol.renderer.TileLayerRenderer.prototype.getTileCoordsFromNormalizedCoords_ = function(ijz) {
return [
this.xRight_ ? ijz[0] : -ijz[0] - 1,
this.yDown_ ? ijz[1] : -ijz[1] - 1,
ijz[2]
];
};
/**
* @param {ol.Loc} center
* @param {number} resolution
* @return {goog.math.Box}
*/
ol.renderer.TileLayerRenderer.prototype.getTileBox_ = function(center, resolution) {
var size = this.getContainerSize();
var halfWidth = size.width / 2;
var halfHeight = size.height / 2;
var leftTop = new ol.Loc(
center.getX() - (resolution * halfWidth),
center.getY() + (resolution * halfHeight));
var rightBottom = new ol.Loc(
center.getX() + (resolution * halfWidth),
center.getY() - (resolution * halfHeight));
var ltCoord = this.getNormalizedTileCoord_(leftTop, resolution);
var rbCoord = this.getNormalizedTileCoord_(rightBottom, resolution);
// right and bottom are treated as excluded, so we increment for the box
rbCoord.x += 1;
rbCoord.y += 1;
return goog.math.Box.boundingBox(ltCoord, rbCoord);
};
/** /**
* Get rid of tiles outside the rendered extent. * Get rid of tiles outside the rendered extent.
*/ */
ol.renderer.TileLayerRenderer.prototype.removeInvisibleTiles_ = function() { ol.renderer.TileLayerRenderer.prototype.removeInvisibleTiles_ = function() {
var index, prune, x, y, z, tile; var index, prune, i, j, z, tile;
var xRight = (this.xRight_ > 0); var box = this.renderedTileBox_;
var yDown = (this.yDown_ > 0); for (var ijz in this.renderedTiles_) {
var top = this.renderedTop_; index = ijz.split(",");
var right = this.renderedRight_; i = +index[0];
var bottom = this.renderedBottom_; j = +index[1];
var left = this.renderedLeft_;
for (var xyz in this.renderedTiles_) {
index = xyz.split(",");
x = +index[0];
y = +index[1];
z = +index[2]; z = +index[2];
prune = this.renderedZ_ !== z || prune = this.renderedZ_ !== z ||
// beyond on the left side i < box.left || // beyond on the left side
(xRight ? x < left : x > left) || i >= box.right || // beyond on the right side
// beyond on the right side j < box.top || // above
(xRight ? x > right : x < right) || j >= box.bottom; // below
// above
(yDown ? y < top : y > top) ||
// below
(yDown ? y > bottom : y < bottom);
if (prune) { if (prune) {
tile = this.renderedTiles_[xyz]; tile = this.renderedTiles_[ijz];
delete this.renderedTiles_[xyz]; delete this.renderedTiles_[ijz];
this.target_.removeChild(tile.getImg()); this.container_.removeChild(tile.getImg());
} }
} }
}; };
@@ -294,12 +306,14 @@ ol.renderer.TileLayerRenderer.prototype.removeInvisibleTiles_ = function() {
* Deal with changes in resolution. * Deal with changes in resolution.
* TODO: implement the animation * TODO: implement the animation
* *
* @param {ol.Loc} center New center.
* @param {number} resolution New resolution. * @param {number} resolution New resolution.
*/ */
ol.renderer.TileLayerRenderer.prototype.changeResolution_ = function(center, resolution) { ol.renderer.TileLayerRenderer.prototype.changeResolution_ = function(resolution) {
var pair = this.getPreferredResAndZ_(resolution);
this.renderedZ_ = pair[1];
this.renderedResolution_ = resolution;
this.renderedTiles_ = {}; this.renderedTiles_ = {};
goog.dom.removeChildren(this.target_); goog.dom.removeChildren(this.container_);
}; };
-6
View File
@@ -172,10 +172,4 @@ describe("ol.event.Events", function() {
expect(ol.event.isMultiTouch({})).toBe(false); expect(ol.event.isMultiTouch({})).toBe(false);
}); });
it("provides an isEnterOrSpace() function", function() {
expect(ol.event.isEnterOrSpace({type: 'keypress', keyCode: 13})).toBe(true);
expect(ol.event.isEnterOrSpace({type: 'keypress', keyCode: 32})).toBe(true);
expect(ol.event.isEnterOrSpace({type: 'keypress', keyCode: 3})).toBe(true);
});
}); });
+7 -7
View File
@@ -1935,12 +1935,12 @@
map.destroy(); map.destroy();
} }
function test_moveByPx(t) { function test_moveByViewportPx(t) {
t.plan(16); t.plan(16);
var moved; var moved;
var Layer = OpenLayers.Class(OpenLayers.Layer, { var Layer = OpenLayers.Class(OpenLayers.Layer, {
moveByPx: function(dx, dy) { moveByViewportPx: function(dx, dy) {
moved[this.name] = true; moved[this.name] = true;
} }
}); });
@@ -1972,7 +1972,7 @@
// move to a valid position // move to a valid position
moved = {}; moved = {};
map.moveByPx(-455, 455); map.moveByViewportPx(-455, 455);
t.eq(map.layerContainerDiv.style.left, '455px', t.eq(map.layerContainerDiv.style.left, '455px',
'[valid position] layer container left correct'); '[valid position] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px', t.eq(map.layerContainerDiv.style.top, '-455px',
@@ -1984,7 +1984,7 @@
// move outside the max extent // move outside the max extent
moved = {}; moved = {};
map.moveByPx(-4500, 4500); map.moveByViewportPx(-4500, 4500);
t.eq(map.layerContainerDiv.style.left, '455px', t.eq(map.layerContainerDiv.style.left, '455px',
'[outside max extent] layer container left correct'); '[outside max extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px', t.eq(map.layerContainerDiv.style.top, '-455px',
@@ -1996,7 +1996,7 @@
// move outside the restricted extent // move outside the restricted extent
moved = {}; moved = {};
map.moveByPx(-500, 500); map.moveByViewportPx(-500, 500);
t.eq(map.layerContainerDiv.style.left, '455px', t.eq(map.layerContainerDiv.style.left, '455px',
'[outside restricted extent] layer container left correct'); '[outside restricted extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px', t.eq(map.layerContainerDiv.style.top, '-455px',
@@ -2011,7 +2011,7 @@
} }
// test for http://trac.osgeo.org/openlayers/ticket/3388 // test for http://trac.osgeo.org/openlayers/ticket/3388
function test_moveByPx_restrictedExtent(t) { function test_moveByViewportPx_restrictedExtent(t) {
t.plan(2); t.plan(2);
var map = new OpenLayers.Map({ var map = new OpenLayers.Map({
@@ -2024,7 +2024,7 @@
map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25)); map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25));
map.moveByPx(-10, -10); map.moveByViewportPx(-10, -10);
t.eq(map.layerContainerDiv.style.left, '10px', 'layer container left correct'); t.eq(map.layerContainerDiv.style.left, '10px', 'layer container left correct');
t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct'); t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct');
} }