Merge pull request #179 from ahocevar/tile-queue

A tile queue that can be aborted. r=@elemoine,@fredj,@tonio
This commit is contained in:
ahocevar
2012-02-14 10:59:12 -08:00
17 changed files with 318 additions and 169 deletions
+6
View File
@@ -9,6 +9,12 @@ html, body, #map {
#title, #tags, #shortdesc { #title, #tags, #shortdesc {
display: none; display: none;
} }
.olTileImage {
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
div.olControlAttribution { div.olControlAttribution {
position: absolute; position: absolute;
font-size: 10px; font-size: 10px;
+1 -1
View File
@@ -7,7 +7,6 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" href="mobile-wmts-vienna.css" type="text/css"> <link rel="stylesheet" href="mobile-wmts-vienna.css" type="text/css">
<script src="../lib/OpenLayers.js"></script>
</head> </head>
<body> <body>
<h1 id="title">City of Vienna WMTS for Desktop and Mobile Devices</h1> <h1 id="title">City of Vienna WMTS for Desktop and Mobile Devices</h1>
@@ -22,6 +21,7 @@
functionality and uses the Geolocate control. functionality and uses the Geolocate control.
</p> </p>
<div id="map"></div> <div id="map"></div>
<script src="../lib/OpenLayers.js"></script>
<script src="mobile-wmts-vienna.js"></script> <script src="mobile-wmts-vienna.js"></script>
</body> </body>
</html> </html>
-2
View File
@@ -152,7 +152,6 @@ var map;
var defaults = { var defaults = {
requestEncoding: "REST", requestEncoding: "REST",
matrixSet: "google3857", matrixSet: "google3857",
buffer: 4,
attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>' attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>'
}; };
var doc = request.responseText, var doc = request.responseText,
@@ -182,7 +181,6 @@ var map;
requestEncoding: "REST", requestEncoding: "REST",
matrixSet: "google3857", matrixSet: "google3857",
tileFullExtent: extent, tileFullExtent: extent,
buffer: 4,
attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>' attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>'
}; };
fmzk = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({ fmzk = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({
+11
View File
@@ -15,6 +15,16 @@
*/ */
OpenLayers.Animation = (function(window) { OpenLayers.Animation = (function(window) {
/**
* Property: isNative
* {Boolean} true if a native requestAnimationFrame function is available
*/
var isNative = !!(window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame);
/** /**
* Function: requestFrame * Function: requestFrame
* Schedule a function to be called at the next available animation frame. * Schedule a function to be called at the next available animation frame.
@@ -89,6 +99,7 @@ OpenLayers.Animation = (function(window) {
} }
return { return {
isNative: isNative,
requestFrame: requestFrame, requestFrame: requestFrame,
start: start, start: start,
stop: stop stop: stop
+164 -148
View File
@@ -99,11 +99,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** /**
* APIProperty: tileLoadingDelay * APIProperty: tileLoadingDelay
* {Integer} - Number of milliseconds before we shift and load * {Integer} Number of milliseconds before we shift and load
* tiles. Default is 100. * tiles when panning. Ignored if <OpenLayers.Animation.isNative> is
* true. Default is 85.
*/ */
tileLoadingDelay: 100, tileLoadingDelay: 85,
/** /**
* Property: serverResolutions * Property: serverResolutions
* {Array(Number}} This property is documented in subclasses as * {Array(Number}} This property is documented in subclasses as
@@ -112,11 +113,31 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
serverResolutions: null, serverResolutions: null,
/** /**
* Property: timerId * Property: moveTimerId
* {Number} - The id of the tileLoadingDelay timer. * {Number} The id of the <deferMoveGriddedTiles> timer.
*/ */
timerId: null, moveTimerId: null,
/**
* Property: deferMoveGriddedTiles
* {Function} A function that defers execution of <moveGriddedTiles> by
* <tileLoadingDelay>. If <OpenLayers.Animation.isNative> is true, this
* is null and unused.
*/
deferMoveGriddedTiles: null,
/**
* Property: tileQueueId
* {Number} The id of the <drawTileFromQueue> animation.
*/
tileQueueId: null,
/**
* Property: tileQueue
* {Array(<OpenLayers.Tile>)} Tiles queued for drawing.
*/
tileQueue: null,
/** /**
* Property: backBuffer * Property: backBuffer
* {DOMElement} The back buffer. * {DOMElement} The back buffer.
@@ -152,7 +173,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* flash effects caused by tile animation. * flash effects caused by tile animation.
*/ */
backBufferTimerId: null, backBufferTimerId: null,
/** /**
* Register a listener for a particular event with the following syntax: * Register a listener for a particular event with the following syntax:
* (code) * (code)
@@ -187,10 +208,14 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this, OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
arguments); arguments);
this.grid = []; this.grid = [];
this.tileQueue = [];
this._moveGriddedTiles = OpenLayers.Function.bind(
this.moveGriddedTiles, this if (!OpenLayers.Animation.isNative) {
); this.deferMoveGriddedTiles = OpenLayers.Function.bind(function() {
this.moveGriddedTiles(true);
this.moveTimerId = null;
}, this);
}
}, },
/** /**
@@ -201,10 +226,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* map - {<OpenLayers.Map>} The map. * map - {<OpenLayers.Map>} The map.
*/ */
removeMap: function(map) { removeMap: function(map) {
if(this.timerId != null) { if (this.moveTimerId !== null) {
window.clearTimeout(this.timerId); window.clearTimeout(this.moveTimerId);
this.timerId = null; this.moveTimerId = null;
} }
this.clearTileQueue();
if(this.backBufferTimerId !== null) { if(this.backBufferTimerId !== null) {
window.clearTimeout(this.backBufferTimerId); window.clearTimeout(this.backBufferTimerId);
this.backBufferTimerId = null; this.backBufferTimerId = null;
@@ -230,20 +256,20 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* destroy() on each of them to kill circular references * destroy() on each of them to kill circular references
*/ */
clearGrid:function() { clearGrid:function() {
this.clearTileQueue();
if (this.grid) { if (this.grid) {
for(var iRow=0, len=this.grid.length; iRow<len; iRow++) { for(var iRow=0, len=this.grid.length; iRow<len; iRow++) {
var row = this.grid[iRow]; var row = this.grid[iRow];
for(var iCol=0, clen=row.length; iCol<clen; iCol++) { for(var iCol=0, clen=row.length; iCol<clen; iCol++) {
var tile = row[iCol]; var tile = row[iCol];
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
this.grid = []; this.grid = [];
this.gridResolution = null; this.gridResolution = null;
} }
}, },
/** /**
* APIMethod: clone * APIMethod: clone
* Create a clone of this layer * Create a clone of this layer
@@ -299,7 +325,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
// if grid is empty or zoom has changed, we *must* re-tile // if grid is empty or zoom has changed, we *must* re-tile
var forceReTile = !this.grid.length || zoomChanged; var forceReTile = !this.grid.length || zoomChanged;
// total bounds of the tiles // total bounds of the tiles
var tilesBounds = this.getTilesBounds(); var tilesBounds = this.getTilesBounds();
@@ -371,11 +397,66 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} }
this.initGriddedTiles(bounds); this.initGriddedTiles(bounds);
} else { } else {
this.scheduleMoveGriddedTiles(); this.moveGriddedTiles();
} }
} }
} }
}, },
/**
* Method: queueTileDraw
* Adds a tile to the animation queue that will draw it.
*
* Parameters:
* evt - {Object} Listener argument of the tile's beforedraw event
*/
queueTileDraw: function(evt) {
var tile = evt.object;
if (!~OpenLayers.Util.indexOf(this.tileQueue, tile)) {
// queue only if not in queue already
this.tileQueue.push(tile);
}
if (!this.tileQueueId) {
this.tileQueueId = OpenLayers.Animation.start(
OpenLayers.Function.bind(this.drawTileFromQueue, this),
null, this.div
);
}
return false;
},
/**
* Method: drawTileFromQueue
* Draws the first tile from the tileQueue, and unqueues that tile
*/
drawTileFromQueue: function() {
if (this.tileQueue.length === 0) {
this.clearTileQueue();
} else {
this.tileQueue.shift().draw(true);
}
},
/**
* Method: clearTileQueue
* Clears the animation queue
*/
clearTileQueue: function() {
OpenLayers.Animation.stop(this.tileQueueId);
this.tileQueueId = null;
this.tileQueue = [];
},
/**
* Method: destroyTile
*
* Parameters:
* tile - {<OpenLayers.Tile>}
*/
destroyTile: function(tile) {
this.removeTileMonitoringHooks(tile);
tile.destroy();
},
/** /**
* Method: getServerResolution * Method: getServerResolution
@@ -565,24 +646,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/ */
moveByPx: function(dx, dy) { moveByPx: function(dx, dy) {
if (!this.singleTile) { if (!this.singleTile) {
this.scheduleMoveGriddedTiles(); this.moveGriddedTiles();
} }
}, },
/**
* Method: scheduleMoveGriddedTiles
* Schedule the move of tiles.
*/
scheduleMoveGriddedTiles: function() {
if (this.timerId != null) {
window.clearTimeout(this.timerId);
}
this.timerId = window.setTimeout(
this._moveGriddedTiles,
this.tileLoadingDelay
);
},
/** /**
* APIMethod: setTileSize * APIMethod: setTileSize
* Check if we are in singleTile mode and if so, set the size as a ratio * Check if we are in singleTile mode and if so, set the size as a ratio
@@ -633,6 +700,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* bounds - {<OpenLayers.Bounds>} * bounds - {<OpenLayers.Bounds>}
*/ */
initSingleTile: function(bounds) { initSingleTile: function(bounds) {
this.clearTileQueue();
//determine new tile bounds //determine new tile bounds
var center = bounds.getCenterLonLat(); var center = bounds.getCenterLonLat();
@@ -744,6 +812,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* bounds - {<OpenLayers.Bounds>} * bounds - {<OpenLayers.Bounds>}
*/ */
initGriddedTiles:function(bounds) { initGriddedTiles:function(bounds) {
this.clearTileQueue();
// work out mininum number of rows and columns; this is the number of // work out mininum number of rows and columns; this is the number of
// tiles required to cover the viewport plus at least one for panning // tiles required to cover the viewport plus at least one for panning
@@ -776,7 +845,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left); var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top); var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
var tileData = [], center = this.map.getCenter();
do { do {
var row = this.grid[rowidx++]; var row = this.grid[rowidx++];
if (!row) { if (!row) {
@@ -810,6 +879,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} else { } else {
tile.moveTo(tileBounds, px, false); tile.moveTo(tileBounds, px, false);
} }
var tileCenter = tileBounds.getCenterLonLat();
tileData.push({
tile: tile,
distance: Math.pow(tileCenter.lon - center.lon, 2) +
Math.pow(tileCenter.lat - center.lat, 2)
});
tileoffsetlon += tilelon; tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w; tileoffsetx += this.tileSize.w;
@@ -828,7 +903,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.gridResolution = this.getServerResolution(); this.gridResolution = this.getServerResolution();
//now actually draw the tiles //now actually draw the tiles
this.spiralTileLoad(); tileData.sort(function(a, b) {
return a.distance - b.distance;
});
for (var i=0, ii=tileData.length; i<ii; ++i) {
tileData[i].tile.draw();
}
}, },
/** /**
@@ -843,79 +923,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
return this.maxExtent; return this.maxExtent;
}, },
/**
* Method: spiralTileLoad
* Starts at the top right corner of the grid and proceeds in a spiral
* towards the center, adding tiles one at a time to the beginning of a
* queue.
*
* Once all the grid's tiles have been added to the queue, we go back
* and iterate through the queue (thus reversing the spiral order from
* outside-in to inside-out), calling draw() on each tile.
*/
spiralTileLoad: function() {
var tileQueue = [];
var directions = ["right", "down", "left", "up"];
var iRow = 0;
var iCell = -1;
var direction = OpenLayers.Util.indexOf(directions, "right");
var directionsTried = 0;
while( directionsTried < directions.length) {
var testRow = iRow;
var testCell = iCell;
switch (directions[direction]) {
case "right":
testCell++;
break;
case "down":
testRow++;
break;
case "left":
testCell--;
break;
case "up":
testRow--;
break;
}
// if the test grid coordinates are within the bounds of the
// grid, get a reference to the tile.
var tile = null;
if ((testRow < this.grid.length) && (testRow >= 0) &&
(testCell < this.grid[0].length) && (testCell >= 0)) {
tile = this.grid[testRow][testCell];
}
if ((tile != null) && (!tile.queued)) {
//add tile to beginning of queue, mark it as queued.
tileQueue.unshift(tile);
tile.queued = true;
//restart the directions counter and take on the new coords
directionsTried = 0;
iRow = testRow;
iCell = testCell;
} else {
//need to try to load a tile in a different direction
direction = (direction + 1) % 4;
directionsTried++;
}
}
// now we go through and draw the tiles in forward order
for(var i=0, len=tileQueue.length; i<len; i++) {
var tile = tileQueue[i];
tile.draw();
//mark tile as unqueued for the next time (since tiles are reused)
tile.queued = false;
}
},
/** /**
* APIMethod: addTile * APIMethod: addTile
* Create a tile, initialize it, and add it to the layer div. * Create a tile, initialize it, and add it to the layer div.
@@ -928,8 +935,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* {<OpenLayers.Tile>} The added OpenLayers.Tile * {<OpenLayers.Tile>} The added OpenLayers.Tile
*/ */
addTile: function(bounds, position) { addTile: function(bounds, position) {
return new this.tileClass(this, position, bounds, null, var tile = new this.tileClass(
this.tileSize, this.tileOptions); this, position, bounds, null, this.tileSize, this.tileOptions
);
tile.events.register("beforedraw", this, this.queueTileDraw);
return tile;
}, },
/** /**
@@ -955,7 +965,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.numLoadingTiles--; this.numLoadingTiles--;
this.events.triggerEvent("tileloaded"); this.events.triggerEvent("tileloaded");
//if that was the last tile, then trigger a 'loadend' on the layer //if that was the last tile, then trigger a 'loadend' on the layer
if (this.numLoadingTiles == 0) { if (this.tileQueue.length === 0 && this.numLoadingTiles === 0) {
this.events.triggerEvent("loadend"); this.events.triggerEvent("loadend");
if(this.backBuffer) { if(this.backBuffer) {
// the removal of the back buffer is delayed to prevent flash // the removal of the back buffer is delayed to prevent flash
@@ -965,7 +975,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
2500 2500
); );
} }
} }
}; };
tile.events.register("loadend", this, tile.onLoadEnd); tile.events.register("loadend", this, tile.onLoadEnd);
tile.events.register("unload", this, tile.onLoadEnd); tile.events.register("unload", this, tile.onLoadEnd);
@@ -991,39 +1001,47 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** /**
* Method: moveGriddedTiles * Method: moveGriddedTiles
*
* Parameter:
* deferred - {Boolean} true if this is a deferred call that should not
* be delayed.
*/ */
moveGriddedTiles: function() { moveGriddedTiles: function(deferred) {
var shifted = true; if (!deferred && !OpenLayers.Animation.isNative) {
if (this.moveTimerId != null) {
window.clearTimeout(this.moveTimerId);
}
this.moveTimerId = window.setTimeout(
this.deferMoveGriddedTiles, this.tileLoadingDelay
);
return;
}
var buffer = this.buffer || 1; var buffer = this.buffer || 1;
var scale = this.getResolutionScale(); var scale = this.getResolutionScale();
var tlLayer = this.grid[0][0].position.clone(); while(true) {
tlLayer.x *= scale; var tlViewPort = {
tlLayer.y *= scale; x: (this.grid[0][0].position.x * scale) +
tlLayer = tlLayer.add(parseInt(this.div.style.left, 10), parseInt(this.div.style.left, 10) +
parseInt(this.div.style.top, 10)); parseInt(this.map.layerContainerDiv.style.left),
var offsetX = parseInt(this.map.layerContainerDiv.style.left); y: (this.grid[0][0].position.y * scale) +
var offsetY = parseInt(this.map.layerContainerDiv.style.top); parseInt(this.div.style.top, 10) +
var tlViewPort = tlLayer.add(offsetX, offsetY); parseInt(this.map.layerContainerDiv.style.top)
var tileSize = { };
w: this.tileSize.w * scale, var tileSize = {
h: this.tileSize.h * scale w: this.tileSize.w * scale,
}; h: this.tileSize.h * scale
if (tlViewPort.x > -tileSize.w * (buffer - 1)) { };
this.shiftColumn(true); if (tlViewPort.x > -tileSize.w * (buffer - 1)) {
} else if (tlViewPort.x < -tileSize.w * buffer) { this.shiftColumn(true);
this.shiftColumn(false); } else if (tlViewPort.x < -tileSize.w * buffer) {
} else if (tlViewPort.y > -tileSize.h * (buffer - 1)) { this.shiftColumn(false);
this.shiftRow(true); } else if (tlViewPort.y > -tileSize.h * (buffer - 1)) {
} else if (tlViewPort.y < -tileSize.h * buffer) { this.shiftRow(true);
this.shiftRow(false); } else if (tlViewPort.y < -tileSize.h * buffer) {
} else { this.shiftRow(false);
shifted = false; } else {
} break;
if (shifted) { }
// we may have other row or columns to shift, schedule it
// with a setTimeout, to give the user a chance to sneak
// in moveTo's
this.timerId = window.setTimeout(this._moveGriddedTiles, 0);
} }
}, },
@@ -1113,8 +1131,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var row = this.grid.pop(); var row = this.grid.pop();
for (var i=0, l=row.length; i<l; i++) { for (var i=0, l=row.length; i<l; i++) {
var tile = row[i]; var tile = row[i];
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
@@ -1123,8 +1140,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
for (var i=0, l=this.grid.length; i<l; i++) { for (var i=0, l=this.grid.length; i<l; i++) {
var row = this.grid[i]; var row = this.grid[i];
var tile = row.pop(); var tile = row.pop();
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
}, },
+23 -8
View File
@@ -25,6 +25,10 @@ OpenLayers.Tile = OpenLayers.Class({
/** /**
* Supported event types: * Supported event types:
* - *beforedraw* Triggered before the tile is drawn. Used to defer
* drawing to an animation queue. To defer drawing, listeners need
* to return false, which will abort drawing. The queue handler needs
* to call <draw>(true) to actually draw the tile.
* - *loadstart* Triggered when tile loading starts. * - *loadstart* Triggered when tile loading starts.
* - *loadend* Triggered when tile loading ends. * - *loadend* Triggered when tile loading ends.
* - *reload* Triggered when an already loading tile is reloaded. * - *reload* Triggered when an already loading tile is reloaded.
@@ -107,7 +111,7 @@ OpenLayers.Tile = OpenLayers.Class({
* {Boolean} Is the tile loading? * {Boolean} Is the tile loading?
*/ */
isLoading: false, isLoading: false,
/** TBD 3.0 -- remove 'url' from the list of parameters to the constructor. /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
* there is no need for the base tile class to have a url. * there is no need for the base tile class to have a url.
* *
@@ -180,15 +184,26 @@ OpenLayers.Tile = OpenLayers.Class({
* it should actually be re-drawn. This is an example implementation * it should actually be re-drawn. This is an example implementation
* that can be overridden by subclasses. The minimum thing to do here * that can be overridden by subclasses. The minimum thing to do here
* is to call <clear> and return the result from <shouldDraw>. * is to call <clear> and return the result from <shouldDraw>.
*
* Parameters:
* deferred - {Boolean} When drawing was aborted by returning false from a
* *beforedraw* listener, the queue manager needs to pass true, so the
* tile will not be cleared and immediately be drawn. Otherwise, the
* tile will be cleared and a *beforedraw* event will be fired.
* *
* Returns: * Returns:
* {Boolean} Whether or not the tile should actually be drawn. * {Boolean} Whether or not the tile should actually be drawn.
*/ */
draw: function() { draw: function(deferred) {
//clear tile's contents and mark as not drawn if (!deferred) {
this.clear(); //clear tile's contents and mark as not drawn
this.clear();
return this.shouldDraw(); }
var draw = this.shouldDraw();
if (draw && !deferred) {
draw = this.events.triggerEvent("beforedraw") !== false;
}
return draw;
}, },
/** /**
@@ -259,10 +274,10 @@ OpenLayers.Tile = OpenLayers.Class({
/** /**
* Method: clear * Method: clear
* Clear the tile of any bounds/position-related data so that it can * Clear the tile of any bounds/position-related data so that it can
* be reused in a new location. To be implemented by subclasses. * be reused in a new location.
*/ */
clear: function(draw) { clear: function(draw) {
// to be implemented by subclasses // to be extended by subclasses
}, },
CLASS_NAME: "OpenLayers.Tile" CLASS_NAME: "OpenLayers.Tile"
+2
View File
@@ -6,6 +6,7 @@
/** /**
* @requires OpenLayers/Tile.js * @requires OpenLayers/Tile.js
* @requires OpenLayers/Animation.js
*/ */
/** /**
@@ -220,6 +221,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* it can be reused in a new location. * it can be reused in a new location.
*/ */
clear: function() { clear: function() {
OpenLayers.Tile.prototype.clear.apply(this, arguments);
var img = this.imgDiv; var img = this.imgDiv;
if (img) { if (img) {
OpenLayers.Event.stopObservingElement(img); OpenLayers.Event.stopObservingElement(img);
+2 -1
View File
@@ -15,7 +15,8 @@
<script> <script>
function test_all(t) { function test_all(t) {
t.plan(7); t.plan(8);
t.ok(OpenLayers.Animation.isNative !== undefined, "isNative is set.");
t.open_window("Animation.html", function(win) { t.open_window("Animation.html", function(win) {
win.requestFrame(t); win.requestFrame(t);
win.start(t); win.start(t);
+3
View File
@@ -4,6 +4,9 @@
<script type="text/javascript">window.alert = oldAlert;</script> <script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;
+55 -9
View File
@@ -2,6 +2,10 @@
<head> <head>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
var origQueueTileDraw = OpenLayers.Layer.Grid.prototype.queueTileDraw;
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;
@@ -67,6 +71,26 @@
map.destroy(); map.destroy();
} }
function test_queueTileDraw(t) {
t.plan(3);
OpenLayers.Layer.Grid.prototype.queueTileDraw = origQueueTileDraw;
var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params);
map.addLayer(layer);
map.setCenter([0, 0], 3);
var queued = layer.tileQueue.length;
t.ok(layer.tileQueue.length, "Tiles queued for drawing");
map.zoomIn();
t.eq(layer.tileQueue.length, queued, "Tile queue has same length after immediate zoom change");
t.delay_call(1, function() {
t.eq(layer.tileQueue.length, 0, "Tiles from queue processed");
});
map.destroy();
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
}
function test_Layer_Grid_clearTiles (t) { function test_Layer_Grid_clearTiles (t) {
t.plan(4); t.plan(4);
@@ -189,13 +213,35 @@
function test_Layer_Grid_moveTo(t) { function test_Layer_Grid_moveTo(t) {
t.plan(14); t.plan(17);
var origIsNative = OpenLayers.Animation.isNative;
OpenLayers.Animation.isNative = false;
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params); layer = new OpenLayers.Layer.WMS(name, url, params);
layer.destroy = function() {}; //we're going to do funky things with the grid layer.destroy = function() {}; //we're going to do funky things with the grid
layer.applyBackBuffer = function() {}; // backbuffering isn't under test here layer.applyBackBuffer = function() {}; // backbuffering isn't under test here
map.addLayer(layer); map.addLayer(layer);
map.setCenter([-10, 0], 5);
var log = [];
layer.deferMoveGriddedTiles = function() {
log.push("deferMoveGriddedTiles");
OpenLayers.Layer.WMS.prototype.deferMoveGriddedTiles.apply(this, arguments);
}
layer.moveGriddedTiles = function() {
log.push("moveGriddedTiles");
OpenLayers.Layer.WMS.prototype.moveGriddedTiles.apply(this, arguments);
}
map.moveTo([5, 0]);
t.eq(log[0], "moveGriddedTiles", "deferred after moveTo");
map.moveTo([0, 0]);
t.eq(log[1], "moveGriddedTiles", "deferred again after another moveTo");
t.eq(log.length, 2, "no tiles loaded yet");
t.delay_call(0.1, function() {
t.eq(log[2], "deferMoveGriddedTiles", "tiles moved after tileLoadingDelay");
});
//make sure null bounds doesnt cause script error. //make sure null bounds doesnt cause script error.
// no test necessary, just action // no test necessary, just action
@@ -204,7 +250,6 @@
layer.moveTo(); //checks to make sure null bounds doesnt break us layer.moveTo(); //checks to make sure null bounds doesnt break us
//observing globals //observing globals
layer.initSingleTile = function(bounds) { layer.initSingleTile = function(bounds) {
g_WhichFunc = "InitSingle"; g_WhichFunc = "InitSingle";
@@ -214,10 +259,13 @@
g_WhichFunc = "InitGridded"; g_WhichFunc = "InitGridded";
g_Bounds = bounds; g_Bounds = bounds;
}; };
layer._moveGriddedTiles = function() { layer.moveGriddedTiles = function() {
g_WhichFunc = "MoveGridded"; g_WhichFunc = "MoveGridded";
g_Bounds = layer.map.getExtent(); g_Bounds = layer.map.getExtent();
}; };
layer.deferMoveGriddedTiles = function() {
g_WhichFunc = "DeferMoveGridded";
}
var clearTestBounds = function() { var clearTestBounds = function() {
g_WhichFunc = null; g_WhichFunc = null;
g_Bounds = null; g_Bounds = null;
@@ -307,7 +355,7 @@
//gridded //gridded
layer.grid = [ [ {} ] ]; layer.grid = [ [ {position: new OpenLayers.Pixel(0,0)} ] ];
layer.singleTile = false; layer.singleTile = false;
//regular move //regular move
@@ -315,11 +363,8 @@
tilesBounds = new OpenLayers.Bounds(10,10,120,120); tilesBounds = new OpenLayers.Bounds(10,10,120,120);
g_WhichFunc = null; g_WhichFunc = null;
layer.moveTo(null, zoomChanged); layer.moveTo(null, zoomChanged);
t.eq(g_WhichFunc, null, "moveGriddedTiles is delayed - not called yet"); t.eq(g_WhichFunc, "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()");
t.delay_call(0.2, function() { t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds");
t.ok(g_WhichFunc == "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()");
t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds");
});
// drastic pan // drastic pan
clearTestBounds(); clearTestBounds();
@@ -328,6 +373,7 @@
t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()"); t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()");
t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds"); t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds");
OpenLayers.Animation.isNative = origIsNative;
} }
/** THIS WOULD BE WHERE THE TESTS WOULD GO FOR /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR
+3
View File
@@ -6,6 +6,9 @@
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;
+3
View File
@@ -5,6 +5,9 @@
<script type="text/javascript">window.alert = oldAlert;</script> <script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;
+3
View File
@@ -2,6 +2,9 @@
<head> <head>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;
+33
View File
@@ -59,6 +59,39 @@
tearDown(); tearDown();
} }
function test_Tile_draw(t) {
t.plan(6);
setUp();
var position = new OpenLayers.Pixel(10,20);
var bounds = new OpenLayers.Bounds(1,2,3,4);
var url = "bobob";
var size = new OpenLayers.Size(5,6);
tile = new OpenLayers.Tile(layer, position, bounds, url, size);
var log = [];
tile.clear = function() {
log.push("clear");
}
tile.draw();
t.eq(log.length, 1, "Tile cleared before drawing");
log = [];
tile.events.register("beforedraw", this, function() {
log.push("beforedraw");
return false;
});
var drawn = tile.draw();
t.eq(log[0], "clear", "tile cleared");
t.eq(log[1], "beforedraw", "beforedraw event fired");
t.eq(drawn, false, "tile not drawn when beforedraw listener returns false");
drawn = tile.draw(true);
t.eq(log.length, 2, "no beforedraw event fired and tile not cleared when draw called with 'deferred' argument set to true");
t.eq(drawn, true, "tile drawn when draw called with 'deferred' argument set to true");
tearDown();
}
function test_Tile_destroy(t) { function test_Tile_destroy(t) {
t.plan( 6 ); t.plan( 6 );
+3
View File
@@ -2,6 +2,9 @@
<head> <head>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var tile; var tile;
+3
View File
@@ -2,6 +2,9 @@
<head> <head>
<script src="../../OLLoader.js"></script> <script src="../../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var isOpera = (navigator.userAgent.indexOf("Opera") != -1); var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
var isIE = (navigator.userAgent.indexOf("MSIE") != -1); var isIE = (navigator.userAgent.indexOf("MSIE") != -1);
@@ -5,6 +5,9 @@
<script src="../../../../lib/deprecated.js"></script> <script src="../../../../lib/deprecated.js"></script>
<script type="text/javascript"> <script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1); var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;