diff --git a/src/ol/Map.js b/src/ol/Map.js index 8690522657..b524710bc8 100644 --- a/src/ol/Map.js +++ b/src/ol/Map.js @@ -87,6 +87,12 @@ ol.Map = function() { * @type {Element} */ this.viewport_ = null; + + /** + * @private + * @type {goog.math.Size} + */ + this.viewportSize_ = null; /** * @private @@ -274,32 +280,50 @@ ol.Map.prototype.getResolution = function() { /** + * 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 * @return {ol.Loc} */ -ol.Map.prototype.getLocForPixel = function(pixel) { - return goog.isDef(this.renderer_) ? - this.renderer_.getLocForPixel(pixel) : null; +ol.Map.prototype.getLocForViewportPixel = function(pixel) { + var size = this.getViewportSize(); + 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 * @return {{x: number, y: number}} */ -ol.Map.prototype.getPixelForLoc = function(loc) { - return goog.isDef(this.renderer_) ? - this.renderer_.getPixelForLoc(loc) : null; +ol.Map.prototype.getViewportPixelForLoc = function(loc) { + var size = this.getViewportSize(); + 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() { - //TODO consider caching this when we have something like updateSize - return goog.isDef(this.renderer_) ? this.renderer_.getSize() : null; +ol.Map.prototype.getViewportSize = function() { + // TODO: listen for resize and set this.viewportSize_ 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. */ @@ -335,8 +359,8 @@ ol.Map.prototype.setZoom = function(zoom, opt_anchor) { return; } if (goog.isDef(opt_anchor)) { - var size = this.getSize(), - anchorLoc = this.getLocForPixel(opt_anchor), + var size = this.getViewportSize(), + anchorLoc = this.getLocForViewportPixel(opt_anchor), newRes = this.getResolutionForZoom(newZoom); newCenter = anchorLoc.add( (size.width/2 - opt_anchor.x) * newRes, @@ -511,10 +535,13 @@ ol.Map.prototype.getEvents = 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} 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_)) { var resolution = this.getResolutionForZoom(this.zoom_), center = new ol.Loc( diff --git a/src/ol/Popup.js b/src/ol/Popup.js index 8ec7018aee..5a5beff366 100644 --- a/src/ol/Popup.js +++ b/src/ol/Popup.js @@ -243,7 +243,7 @@ ol.Popup.prototype.setAnchorOffset_ = function() { this.pos_ = new ol.geom.Point(this.anchor_.getX(), this.anchor_.getY()); } 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_); switch(this.placement_) { diff --git a/src/ol/control/Navigation.js b/src/ol/control/Navigation.js index 8c9fbaafc9..e56a41b2f4 100644 --- a/src/ol/control/Navigation.js +++ b/src/ol/control/Navigation.js @@ -55,7 +55,7 @@ ol.control.Navigation.prototype.deactivate = function() { * @param {Object} evt */ ol.control.Navigation.prototype.moveMap = function(evt) { - this.map_.moveByPx(evt.deltaX, evt.deltaY); + this.map_.moveByViewportPx(evt.deltaX, evt.deltaY); return false; }; diff --git a/src/ol/renderer/MapRenderer.js b/src/ol/renderer/MapRenderer.js index 911d4f8891..5fc37f62b9 100644 --- a/src/ol/renderer/MapRenderer.js +++ b/src/ol/renderer/MapRenderer.js @@ -108,38 +108,3 @@ ol.renderer.MapRenderer.pickRendererType = function(preferences) { // if we didn't find any of the preferred renderers, use the first 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_); -}; diff --git a/tests/Map.html b/tests/Map.html index e09f132442..1b7c5c2e60 100644 --- a/tests/Map.html +++ b/tests/Map.html @@ -1935,12 +1935,12 @@ map.destroy(); } - function test_moveByPx(t) { + function test_moveByViewportPx(t) { t.plan(16); var moved; var Layer = OpenLayers.Class(OpenLayers.Layer, { - moveByPx: function(dx, dy) { + moveByViewportPx: function(dx, dy) { moved[this.name] = true; } }); @@ -1972,7 +1972,7 @@ // move to a valid position moved = {}; - map.moveByPx(-455, 455); + map.moveByViewportPx(-455, 455); t.eq(map.layerContainerDiv.style.left, '455px', '[valid position] layer container left correct'); t.eq(map.layerContainerDiv.style.top, '-455px', @@ -1984,7 +1984,7 @@ // move outside the max extent moved = {}; - map.moveByPx(-4500, 4500); + map.moveByViewportPx(-4500, 4500); t.eq(map.layerContainerDiv.style.left, '455px', '[outside max extent] layer container left correct'); t.eq(map.layerContainerDiv.style.top, '-455px', @@ -1996,7 +1996,7 @@ // move outside the restricted extent moved = {}; - map.moveByPx(-500, 500); + map.moveByViewportPx(-500, 500); t.eq(map.layerContainerDiv.style.left, '455px', '[outside restricted extent] layer container left correct'); t.eq(map.layerContainerDiv.style.top, '-455px', @@ -2011,7 +2011,7 @@ } // test for http://trac.osgeo.org/openlayers/ticket/3388 - function test_moveByPx_restrictedExtent(t) { + function test_moveByViewportPx_restrictedExtent(t) { t.plan(2); var map = new OpenLayers.Map({ @@ -2024,7 +2024,7 @@ 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.top, '0px', 'layer container top correct'); }