Partial tile layer renderer.

This commit is contained in:
Tim Schaub
2012-06-21 19:59:32 +02:00
parent 948e792ddd
commit c67ca2660d
3 changed files with 136 additions and 39 deletions

View File

@@ -1,8 +1,10 @@
goog.provide('ol.renderer.Composite');
goog.require('ol.renderer.MapRenderer');
goog.require('ol.renderer.LayerRenderer');
goog.require('ol.layer.Layer');
goog.require('ol.Loc');
goog.require('goog.array');
/**
* @constructor
@@ -14,11 +16,20 @@ ol.renderer.Composite = function(container) {
goog.base(this, container);
/**
* @type Array.<ol.renderer.LayerRenderer>
* @type {Array.<ol.renderer.LayerRenderer>}
* @private
*/
this.renderers_ = [];
var target = document.createElement("div");
target.className = "ol-renderer-composite";
/**
* @type Element
* @private
*/
this.target_ = target;
};
goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer);
@@ -30,6 +41,23 @@ goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer);
* @param {boolean} animate
*/
ol.renderer.Composite.prototype.draw = function(layers, center, resolution, animate) {
// 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);
}
};
/**
* @param {ol.layer.Layer} layer
* @param {number} index
*/
ol.renderer.Composite.prototype.getOrCreateRenderer = function(layer, index) {
var renderer = this.getRenderer(layer);
if (goog.isNull(renderer)) {
renderer = this.createRenderer(layer);
goog.array.insertAt(this.renderers_, renderer, index);
}
return renderer;
};
/**
@@ -46,6 +74,9 @@ ol.renderer.Composite.prototype.getRenderer = function(layer) {
* @param {ol.layer.Layer} layer
*/
ol.renderer.Composite.prototype.createRenderer = function(layer) {
var Renderer = this.pickRendererType(layer);
goog.asserts.assert(Renderer, "No supported renderer for layer: " + layer);
return new Renderer(layer, this.target_);
};
/**

View File

@@ -3,23 +3,39 @@ goog.provide('ol.renderer.LayerRenderer');
/**
* A single layer renderer that will be created by the composite map renderer.
*
* @interface
* @param {Element} target
* @constructor
* @param {!Element} container
* @param {!ol.layer.Layer} layer
*/
ol.renderer.LayerRenderer = function(target, layer) {};
ol.renderer.LayerRenderer = function(container, layer) {
/**
* @type {!Element}
* @protected
*/
this.container_ = container;
/**
* @type {!ol.layer.Layer}
* @protected
*/
this.layer_ = layer;
};
/**
* Get layer being rendered.
*
* @returns {!ol.layer.Layer}
*/
ol.renderer.LayerRenderer.prototype.getLayer = function() {};
ol.renderer.LayerRenderer.prototype.getLayer = function() {
return this.layer_;
};
/**
* Get an identifying string for this renderer.
*
* @returns {string}
* @returns {string|undefined}
*/
ol.renderer.LayerRenderer.prototype.getType = function() {};
@@ -28,7 +44,9 @@ ol.renderer.LayerRenderer.prototype.getType = function() {};
*
* @returns {boolean}
*/
ol.renderer.LayerRenderer.isSupported = function() {};
ol.renderer.LayerRenderer.isSupported = function() {
return false;
};
/**
* Determine if this renderer is capable of renderering the given layer.
@@ -36,4 +54,6 @@ ol.renderer.LayerRenderer.isSupported = function() {};
* @param {ol.layer.Layer} layer
* @returns {boolean}
*/
ol.renderer.LayerRenderer.canRender = function(layer) {};
ol.renderer.LayerRenderer.canRender = function(layer) {
return false;
};

View File

@@ -6,37 +6,61 @@ goog.require('ol.renderer.Composite');
goog.require('ol.TileSet');
goog.require('ol.Bounds');
goog.require('goog.style');
/**
* A single layer renderer that will be created by the composite map renderer.
*
* @constructor
* @implements {ol.renderer.LayerRenderer}
* @param {!Element} container
* @param {!ol.layer.Layer} layer
* @extends {ol.renderer.LayerRenderer}
*/
ol.renderer.TileLayerRenderer = function(container, layer) {
/**
* @type {!Element}
* @private
*/
this.container_ = container;
/**
* @type {!ol.layer.Layer}
* @private
*/
this.layer_ = layer;
goog.base(this, container, layer);
/**
* @type {ol.Bounds}
* @private
*/
this.rendererdBounds = null;
this.rendererdBounds_ = null;
/**
* @type {number|undefined}
* @private
*/
this.renderedResolution_ = undefined;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
};
goog.inherits(ol.renderer.TileLayerRenderer, ol.renderer.LayerRenderer);
/**
* @return {goog.math.Size}
*/
ol.renderer.TileLayerRenderer.prototype.getContainerSize_ = function() {
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.
*
@@ -44,17 +68,19 @@ ol.renderer.TileLayerRenderer = function(container, layer) {
* @param {number} resolution
*/
ol.renderer.TileLayerRenderer.prototype.draw = function(center, resolution) {
var mapSize = goog.style.getSize(this.container_);
if (resolution !== this.renderedResolution_) {
this.renderedTiles_ = {};
}
var mapSize = this.getContainerSize_();
var halfMapWidth = (resolution * mapSize.width) / 2;
var halfMapHeight = (resolution * mapSize.height) / 2;
var x = center.getX();
var y = center.getY();
var mapMinX = x - halfMapWidth;
var mapMaxY = y + halfMapHeight;
var projection = center.getProjection();
var bounds = new ol.Bounds(
mapMinX, y - halfMapHeight, x + halfMapWidth, mapMaxY,
center.getProjection()
);
mapMinX, y - halfMapHeight, x + halfMapWidth, mapMaxY, projection);
var tileSet = this.layer_.getData(bounds, resolution);
var tiles = tileSet.getTiles();
var rows = tiles.length;
@@ -66,35 +92,55 @@ ol.renderer.TileLayerRenderer.prototype.draw = function(center, resolution) {
// TODO: implement ol.TileSet#getBounds
var firstBounds = first.getBounds();
var tileMinX = firstBounds.getMinX();
var tileMaxX = tileMinX;
var tileMaxY = firstBounds.getMaxY();
var tileMinY = tileMaxY;
var pxOriginX = (tileMinX - mapMinX) / resolution;
var pxOriginY = (mapMaxY - tileMaxY) / resolution;
var tileHeight = tileSet.getTileHeight();
var tileWidth = tileSet.getTileWidth();
var pxTileHeight = tileSet.getTileHeight();
var pxTileWidth = tileSet.getTileWidth();
var tileHeight = tileResolution * pxTileHeight;
var tileWidth = tileResolution * pxTileWidth;
var fragment = document.createDocumentFragment();
var tile, img;
for (var j=0, tileTop=pxOriginY; j<rows; ++j, tileTop+=tileHeight) {
for (var i=0, tileLeft=pxOriginX; i<cols; ++i, tileLeft+=tileWidth) {
for (var j=0, pxTileTop=pxOriginY; j<rows; ++j, pxTileTop+=pxTileHeight) {
tileMinY -= tileHeight;
for (var i=0, pxTileLeft=pxOriginX; i<cols; ++i, pxTileLeft+=pxTileWidth) {
tileMaxX += tileWidth;
tile = tiles[j][i];
img = tile.getImg();
// TODO: scale is almost always 1, set size on the archetype img
img.style.height = Math.round(tileHeight * scale) + "px";
img.style.width = Math.round(tileWidth * scale) + "px";
img.style.top = tileTop + "px";
img.style.left = tileLeft + "px";
img.style.height = Math.round(pxTileHeight * scale) + "px";
img.style.width = Math.round(pxTileWidth * scale) + "px";
img.style.top = pxTileTop + "px";
img.style.left = pxTileLeft + "px";
tile.load();
this.renderedTiles_[tile.getUrl()] = tile;
fragment.appendChild(img);
}
}
var renderedBounds = new ol.Bounds(
tileMinX, tileMinY, tileMaxX, tileMaxY, projection);
this.pruneUnrenderedTiles_(renderedBounds);
this.renderedBounds_ = renderedBounds;
this.renderedResolution_ = resolution;
this.container_.appendChild(fragment);
}
};
/** @inheritDoc */
ol.renderer.TileLayerRenderer.prototype.getLayer = function() {
return this.layer_;
/**
* Get rid of tiles outside the newly rendered extent.
*
* @param {ol.Bounds} newBounds Newly rendered bounds.
* @private
*/
ol.renderer.TileLayerRenderer.prototype.pruneUnrenderedTiles_ = function(newBounds) {
for (var url in this.renderedTiles_) {
var tile = this.renderedTiles_[url];
}
};
/** @inheritDoc */
ol.renderer.TileLayerRenderer.prototype.getType = function() {
// TODO: revisit
@@ -104,7 +150,7 @@ ol.renderer.TileLayerRenderer.prototype.getType = function() {
/**
* Determine if this renderer type is supported in this environment.
*
* @returns {boolean} This renderer is supported.
* @return {boolean} This renderer is supported.
*/
ol.renderer.TileLayerRenderer.isSupported = function() {
return true;
@@ -114,7 +160,7 @@ ol.renderer.TileLayerRenderer.isSupported = function() {
* Determine if this renderer can render the given layer.
*
* @param {ol.layer.Layer} layer The candidate layer.
* @returns {boolean} This renderer is capable of rendering the layer.
* @return {boolean} This renderer is capable of rendering the layer.
*/
ol.renderer.TileLayerRenderer.canRender = function(layer) {
return layer instanceof ol.layer.TileLayer;