Getting explicit about pixels and size.

Eventually, well have to ask renderers for all pixel and size related stuff.  And the map overlay renderer will do all pixel<->loc math.  For now, we let the map do this math based on its viewport - as this is where the mouse events are handled and it is pixels relative to the viewport that are being generated.  For now, the getViewportPixelForLoc and getLocForViewportPixel are now more explicitly named.
This commit is contained in:
Tim Schaub
2012-07-08 20:57:36 -06:00
parent 3d130d3325
commit 5a485ea856
5 changed files with 50 additions and 58 deletions

View File

@@ -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(

View File

@@ -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_) {

View File

@@ -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;
};

View File

@@ -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_);
};

View File

@@ -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');
}