Skip to content

Commit

Permalink
Tile.Image improvements and partial rewrite. Thanks erilem for the ex…
Browse files Browse the repository at this point in the history
…cellent collaboration during the review phase. p=me,erilem r=erilem (closes #3419)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@12241 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
  • Loading branch information
ahocevar committed Aug 13, 2011
1 parent a8d3d6a commit 23c9092
Show file tree
Hide file tree
Showing 14 changed files with 722 additions and 777 deletions.
4 changes: 2 additions & 2 deletions examples/wms-long-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ var map = new OpenLayers.Map( 'map' );
var base = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic', makeTheUrlLong: longText},
{tileOptions: {maxGetUrlLength: 2048}}
{tileOptions: {maxGetUrlLength: 2048}, transitionEffect: 'resize'}
);
var overlay = new OpenLayers.Layer.WMS("Overlay",
"http://suite.opengeo.org/geoserver/wms",
{layers: "usa:states", transparent: true, makeTheUrlLong: longText},
{ratio: 1, singleTile: true, tileOptions: {maxGetUrlLength: 2048}}
{ratio: 1, singleTile: true, tileOptions: {maxGetUrlLength: 2048}, transitionEffect: 'resize'}
);
map.addLayers([base, overlay]);
map.zoomToMaxExtent();
Expand Down
1 change: 1 addition & 0 deletions lib/OpenLayers.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"OpenLayers/Marker/Box.js",
"OpenLayers/Popup.js",
"OpenLayers/Tile.js",
"OpenLayers/Tile/BackBufferable.js",
"OpenLayers/Tile/Google.js",
"OpenLayers/Tile/Image.js",
"OpenLayers/Tile/Image/IFrame.js",
Expand Down
2 changes: 1 addition & 1 deletion lib/OpenLayers/Layer/Bing.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/
getURL: function(bounds) {
if (!this.url) {
return OpenLayers.Util.getImagesLocation() + "blank.gif";
return;
}
var xyz = this.getXYZ(bounds), x = xyz.x, y = xyz.y, z = xyz.z;
var quadDigits = [];
Expand Down
80 changes: 21 additions & 59 deletions lib/OpenLayers/Tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ OpenLayers.Tile = OpenLayers.Class({
* {<OpenLayers.Pixel>} Top Left pixel of the tile
*/
position: null,

/**
* Property: isLoading
* {Boolean} Is the tile loading?
Expand Down Expand Up @@ -144,53 +144,37 @@ OpenLayers.Tile = OpenLayers.Class({
},

/**
* Method: clone
*
* Parameters:
* obj - {<OpenLayers.Tile>} The tile to be cloned
*
* Method: draw
* Clear whatever is currently in the tile, then return whether or not
* it should actually be re-drawn. This is an example implementation
* that can be overridden by subclasses. The minimum thing to do here
* is to call <clear> and return the result from <shouldDraw>.
*
* Returns:
* {<OpenLayers.Tile>} An exact clone of this <OpenLayers.Tile>
* {Boolean} Whether or not the tile should actually be drawn.
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Tile(this.layer,
this.position,
this.bounds,
this.url,
this.size);
}

// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
draw: function() {
//clear tile's contents and mark as not drawn
this.clear();

return obj;
return this.shouldDraw();
},

/**
* Method: draw
* Clear whatever is currently in the tile, then return whether or not
* it should actually be re-drawn.
* Method: shouldDraw
* Return whether or not the tile should actually be (re-)drawn. The only
* case where we *wouldn't* want to draw the tile is if the tile is outside
* its layer's maxExtent
*
* Returns:
* {Boolean} Whether or not the tile should actually be drawn. Note that
* this is not really the best way of doing things, but such is
* the way the code has been developed. Subclasses call this and
* depend on the return to know if they should draw or not.
* {Boolean} Whether or not the tile should actually be drawn.
*/
draw: function() {
shouldDraw: function() {
var maxExtent = this.layer.maxExtent;
var withinMaxExtent = (maxExtent &&
this.bounds.intersectsBounds(maxExtent, false));

// The only case where we *wouldn't* want to draw the tile is if the
// tile is outside its layer's maxExtent.
this.shouldDraw = (withinMaxExtent || this.layer.displayOutsideMaxExtent);

//clear tile's contents and mark as not drawn
this.clear();

return this.shouldDraw;
return withinMaxExtent || this.layer.displayOutsideMaxExtent;
},

/**
Expand Down Expand Up @@ -220,7 +204,7 @@ OpenLayers.Tile = OpenLayers.Class({
* Clear the tile of any bounds/position-related data so that it can
* be reused in a new location. To be implemented by subclasses.
*/
clear: function() {
clear: function(draw) {
// to be implemented by subclasses
},

Expand Down Expand Up @@ -260,29 +244,7 @@ OpenLayers.Tile = OpenLayers.Class({
bottomRight.lon,
topLeft.lat);
return bounds;
},

/**
* Method: showTile
* Show the tile only if it should be drawn.
*/
showTile: function() {
if (this.shouldDraw) {
this.show();
}
},

/**
* Method: show
* Show the tile. To be implemented by subclasses.
*/
show: function() { },

/**
* Method: hide
* Hide the tile. To be implemented by subclasses.
*/
hide: function() { },

CLASS_NAME: "OpenLayers.Tile"
});
201 changes: 201 additions & 0 deletions lib/OpenLayers/Tile/BackBufferable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */


/*
* @requires OpenLayers/Tile.js
* @requires OpenLayers/Util.js
*/

/*
* Class: OpenLayers.Tile.BackBufferable
* Base class for tiles that can have backbuffers during transitions. Do not
* create instances of this class.
*/
OpenLayers.Tile.BackBufferable = OpenLayers.Class(OpenLayers.Tile, {

/**
* Property: backBufferMode
* {Integer} Bitmap: 0 for no backbuffering at all, 1 for singleTile
* layers, 2 for transition effect set, 3 for both.
*/
backBufferMode: null,

/**
* Property: backBufferData
* {Object} Object including the necessary data for the back
* buffer.
*
* The object includes three properties:
* tile - {DOMElement} The DOM element for the back buffer.
* bounds - {<OpenLayers.Bounds>} The bounds of the tile to back.
* resolution - {Number} The resolution of the tile to back.
*/
backBufferData: null,

/**
* Method: initialize
* Determines the backBuffer mode and registers events
*/
initialize: function() {
OpenLayers.Tile.prototype.initialize.apply(this, arguments);

var transitionSupported = OpenLayers.Util.indexOf(
this.layer.SUPPORTED_TRANSITIONS,
this.layer.transitionEffect) != -1;
this.backBufferMode = (this.layer.singleTile && 1) |
(transitionSupported && 2);

this.backBufferData = {};
if (!this.size) {
this.size = new OpenLayers.Size(256, 256);
}
},

/**
* Method: draw
* Check that a tile should be drawn, and draw it.
*
* Returns:
* {Boolean} Was a tile drawn?
*/
draw: function() {
var draw = OpenLayers.Tile.prototype.shouldDraw.apply(this, arguments),
backBufferMode = this.backBufferMode;
if (draw) {
this.updateBackBuffer();
}
this.clear();
if (!draw) {
this.resetBackBuffer();
};
return draw;
},

/**
* Method: getTile
* Get the tile's markup. To be implemented by subclasses.
*
* Returns:
* {DOMElement} The tile's markup
*/

/**
* Method: createBackBuffer
* Create a copy of this tile's markup for the back buffer. To be
* implemented by subclasses.
*
* Returns:
* {DOMElement} A copy of the tile's markup.
*/

/**
* Method: setBackBufferData
* Stores the current bounds and resolution, for offset and ratio
* calculations
*/
setBackBufferData: function() {
this.backBufferData = OpenLayers.Util.extend(this.backBufferData, {
bounds: this.bounds,
resolution: this.layer.map.getResolution()
});
},

/**
* Method: updateBackBuffer
* Update the <backBufferData>, and return a new or reposition the
* backBuffer. When a backbuffer is returned, the tile's markup is not
* available any more.
*
* Returns:
* {HTMLDivElement} the tile's markup in a cloned element, or undefined if
* no backbuffer is currently available or needed
*/
updateBackBuffer: function() {
var layer = this.layer, map = layer.map,
backBufferMode = this.backBufferMode,
data = this.backBufferData,
tile = this.getTile(),
backBuffer = data.tile,
resolution = data.resolution,
ratio = resolution ? resolution / map.getResolution() : 1,

// Cases where we don't position and return a back buffer, but only
// update backBufferData and return undefined:
// (1) current ratio and backBufferMode dont't require a backbuffer
notNeeded = !(ratio == 1 ? backBufferMode & 1 : backBufferMode & 2),
// (2) the tile is not appended to the layer's div
noParent = tile && tile.parentNode !== layer.div,
// (3) we don't have a tile available that we could use as buffer
noTile = !(tile && tile.childNodes.length > 0),
// (4) no backbuffer is displayed for a tile that's still loading
noBackBuffer = data.tile && !this.isLoading;
if (notNeeded || noParent || noTile || noBackBuffer) {
this.setBackBufferData();
return;
}

// Create a back buffer tile and add it to the DOM
if (!backBuffer) {
backBuffer = this.createBackBuffer();
// some browsers fire the onload event before the image is
// displayed, so we keep the buffer until the whole layer finished
// loading to avoid visual glitches
layer.events.register("loadend", this, this.resetBackBuffer);
data.tile = backBuffer;
layer.div.insertBefore(backBuffer, tile);
}

// Position the back buffer now that we have one
var lonLat = {lon: data.bounds.left, lat: data.bounds.top},
position = map.getPixelFromLonLat(lonLat),
containerStyle = map.layerContainerDiv.style,
leftOffset = parseInt(containerStyle.left, 10),
topOffset = parseInt(containerStyle.top, 10),
style = backBuffer.style;
style.left = (position.x - leftOffset) + "px";
style.top = (position.y - topOffset) + "px";
style.width = (this.size.w * ratio) + "px";
style.height = (this.size.h * ratio) + "px";

return backBuffer;
},

/**
* Method: resetBackBuffer
* Handler for the layer's loadend event.
*/
resetBackBuffer: function() {
this.layer.events.unregister("loadend", this, this.resetBackBuffer);
this.removeBackBuffer();
this.setBackBufferData();
},

/**
* Method: removeBackBuffer
* Removes the backBuffer for this tile.
*/
removeBackBuffer: function() {
var backBufferData = this.backBufferData;
var backBuffer = backBufferData.tile;
delete backBufferData.tile;
var parent = backBuffer && backBuffer.parentNode;
if (backBuffer) {
parent.removeChild(backBuffer);
}
},

/**
* APIMethod: destroy
* nullify references to prevent circular references and memory leaks
*/
destroy: function() {
this.removeBackBuffer();
this.layer.events.unregister("loadend", this, this.resetBackBuffer);
this.backBufferData = null;
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
}

});
Loading

0 comments on commit 23c9092

Please sign in to comment.