Refactor DOM renderer to use only CSS transforms

This commit is contained in:
Tom Payne
2013-01-04 21:25:52 +01:00
parent 032aa8b7c8
commit aba686d22d
3 changed files with 315 additions and 339 deletions

View File

@@ -1,6 +1,7 @@
goog.provide('ol.renderer.dom.Layer');
goog.require('ol.Coordinate');
goog.require('ol.layer.Layer');
goog.require('ol.renderer.Layer');
@@ -13,6 +14,7 @@ goog.require('ol.renderer.Layer');
* @param {!Element} target Target.
*/
ol.renderer.dom.Layer = function(mapRenderer, layer, target) {
goog.base(this, mapRenderer, layer);
/**
@@ -21,27 +23,15 @@ ol.renderer.dom.Layer = function(mapRenderer, layer, target) {
*/
this.target = target;
/**
* Top left corner of the target in map coords.
*
* @type {ol.Coordinate}
* @protected
*/
this.origin = null;
this.handleLayerOpacityChange();
this.handleLayerVisibleChange();
};
goog.inherits(ol.renderer.dom.Layer, ol.renderer.Layer);
/**
* @inheritDoc
* @return {ol.renderer.Map} Map renderer.
* @return {!Element} Target.
*/
ol.renderer.dom.Layer.prototype.getMapRenderer = function() {
return /** @type {ol.renderer.dom.Map} */ (goog.base(this, 'getMapRenderer'));
ol.renderer.dom.Layer.prototype.getTarget = function() {
return this.target;
};
@@ -57,7 +47,7 @@ ol.renderer.dom.Layer.prototype.handleLayerLoad = function() {
* @inheritDoc
*/
ol.renderer.dom.Layer.prototype.handleLayerOpacityChange = function() {
goog.style.setOpacity(this.target, this.getLayer().getOpacity());
this.getMap().render();
};
@@ -65,22 +55,11 @@ ol.renderer.dom.Layer.prototype.handleLayerOpacityChange = function() {
* @inheritDoc
*/
ol.renderer.dom.Layer.prototype.handleLayerVisibleChange = function() {
goog.style.showElement(this.target, this.getLayer().getVisible());
this.getMap().render();
};
/**
* Render.
* @param {number} time Time.
*/
ol.renderer.dom.Layer.prototype.renderFrame = goog.abstractMethod;
/**
* Set the location of the top left corner of the target.
*
* @param {ol.Coordinate} origin Origin.
*/
ol.renderer.dom.Layer.prototype.setOrigin = function(origin) {
this.origin = origin;
};

View File

@@ -1,3 +1,5 @@
// FIXME re-enable rotation when supported
goog.provide('ol.renderer.dom.Map');
goog.require('goog.asserts');
@@ -36,69 +38,10 @@ ol.renderer.dom.Map = function(container, map) {
goog.dom.insertChildAt(container, this.layersPane_, 0);
/**
* @type {Object}
* @private
*/
this.layerPanes_ = {};
/**
* @type {ol.Coordinate}
* @private
*/
this.renderedCenter_ = null;
/**
* @type {number | undefined}
* @private
*/
this.renderedResolution_ = undefined;
/**
* @type {ol.Size}
* @private
*/
this.renderedSize_ = null;
/**
* @type {number | undefined}
* @private
*/
this.renderedRotation_ = undefined;
/**
* The origin (top left) of the layers pane in map coordinates.
*
* @type {ol.Coordinate}
* @private
*/
this.layersPaneOrigin_ = null;
};
goog.inherits(ol.renderer.dom.Map, ol.renderer.Map);
/**
* Apply the given transform to the layers pane.
* @param {number} dx Translation along the x-axis.
* @param {number} dy Translation along the y-axis.
* @param {number} rotation Rotation angle.
* @private
*/
ol.renderer.dom.Map.prototype.applyTransform_ = function(dx, dy, rotation) {
var transform =
'translate(' + Math.round(dx) + 'px, ' + Math.round(dy) + 'px) ' +
'rotate(' + rotation.toFixed(6) + 'rad) ' +
'scale3d(1, 1, 1)';
var style = this.layersPane_.style;
style.WebkitTransform = transform;
style.MozTransform = transform;
style.OTransform = transform;
style.msTransform = transform;
style.transform = transform;
};
/**
* @inheritDoc
*/
@@ -109,20 +52,10 @@ ol.renderer.dom.Map.prototype.canRotate = goog.functions.TRUE;
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
if (layer instanceof ol.layer.TileLayer) {
var layerPane = goog.dom.createElement(goog.dom.TagName.DIV);
layerPane.className = 'ol-layer';
layerPane.style.position = 'absolute';
goog.dom.appendChild(this.layersPane_, layerPane);
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer, layerPane);
this.layerPanes_[goog.getUid(layerRenderer)] = layerPane;
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
return layerRenderer;
} else {
goog.asserts.assert(false);
return null;
@@ -158,123 +91,28 @@ ol.renderer.dom.Map.prototype.handleViewChanged = function() {
/**
* Render the map. Sets up the layers pane on first render and adjusts its
* position as needed on subsequent calls.
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.renderFrame = function(time) {
var map = this.getMap();
if (!map.isDef()) {
return;
}
var view = map.getView().getView2D();
var mapCenter = view.getCenter();
var mapSize = map.getSize();
var mapResolution = view.getResolution();
var mapRotation = view.getRotation();
goog.asserts.assert(goog.isDefAndNotNull(mapCenter));
goog.asserts.assert(goog.isDef(mapResolution));
goog.asserts.assert(goog.isDef(mapRotation));
goog.asserts.assert(goog.isDefAndNotNull(mapSize));
if (goog.isNull(this.renderedCenter_)) {
// first rendering
goog.asserts.assert(!goog.isDef(this.renderedResolution_));
goog.asserts.assert(!goog.isDef(this.renderedRotation_));
goog.asserts.assert(goog.isNull(this.renderedSize_));
this.resetLayersPane_();
} else {
goog.asserts.assert(goog.isDef(this.renderedResolution_));
goog.asserts.assert(!goog.isNull(this.renderedSize_));
if (mapResolution !== this.renderedResolution_ ||
!mapSize.equals(this.renderedSize_)) {
// resolution or size changed, adjust layers pane
this.resetLayersPane_();
} else if (!mapCenter.equals(this.renderedCenter_) ||
mapRotation !== this.renderedRotation_) {
// same resolution and size, new center or rotation
this.transformLayersPane_();
}
}
this.renderedCenter_ = mapCenter;
this.renderedResolution_ = mapResolution;
this.renderedRotation_ = mapRotation;
this.renderedSize_ = mapSize;
var requestRenderFrame = false;
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
if (layerRenderer.renderFrame(time)) {
requestRenderFrame = true;
}
});
var layers = map.getLayers();
if (goog.isDef(layers)) {
layers.forEach(function(layer) {
var layerRenderer = this.getLayerRenderer(layer);
if (layerRenderer.renderFrame(time)) {
requestRenderFrame = true;
}
}, this);
}
if (requestRenderFrame) {
map.requestRenderFrame();
}
};
/**
* Reset the layers pane to its initial position.
* @private
*/
ol.renderer.dom.Map.prototype.resetLayersPane_ = function() {
var map = this.map;
var mapSize = map.getSize();
var halfWidth = mapSize.width / 2;
var halfHeight = mapSize.height / 2;
var view = /** @type {ol.View2D} */ (map.getView().getView2D());
var center = view.getCenter();
var resolution = view.getResolution();
var origin = new ol.Coordinate(
center.x - resolution * halfWidth,
center.y + resolution * halfHeight);
this.layersPaneOrigin_ = origin;
this.setTransformOrigin_(halfWidth, halfHeight);
this.applyTransform_(0, 0, view.getRotation());
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
layerRenderer.setOrigin(origin);
});
};
/**
* Set the transform-origin CSS property of the layers pane.
* @param {number} x The x-axis origin.
* @param {number} y The y-axis origin.
* @private
*/
ol.renderer.dom.Map.prototype.setTransformOrigin_ = function(x, y) {
var origin = Math.round(x) + 'px ' + Math.round(y) + 'px';
var style = this.layersPane_.style;
style.WebkitTransformOrigin = origin;
style.MozTransformOrigin = origin;
style.OTransformOrigin = origin;
style.msTransformOrigin = origin;
style.transformOrigin = origin;
};
/**
* Apply the appropriate transform to the layers pane.
* @private
*/
ol.renderer.dom.Map.prototype.transformLayersPane_ = function() {
var map = this.map;
var view = map.getView();
var resolution = view.getResolution();
var center = view.getCenter();
var size = map.getSize();
var origin = this.layersPaneOrigin_;
var ox = (center.x - origin.x) / resolution;
var oy = (origin.y - center.y) / resolution;
this.setTransformOrigin_(ox, oy);
var dx = ox - (size.width / 2);
var dy = oy - (size.height / 2);
this.applyTransform_(-dx, -dy, view.getRotation());
};

View File

@@ -1,13 +1,22 @@
// FIXME probably need to reset TileLayerZ if offsets get too large
// FIXME when zooming out, preserve higher Z divs to avoid white flash
goog.provide('ol.renderer.dom.TileLayer');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.math.Vec2');
goog.require('goog.style');
goog.require('goog.vec.Mat4');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.dom');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.tilegrid.TileGrid');
@@ -16,73 +25,42 @@ goog.require('ol.renderer.dom.Layer');
* @extends {ol.renderer.dom.Layer}
* @param {ol.renderer.Map} mapRenderer Map renderer.
* @param {ol.layer.TileLayer} tileLayer Tile layer.
* @param {!Element} target Target.
*/
ol.renderer.dom.TileLayer = function(mapRenderer, tileLayer, target) {
ol.renderer.dom.TileLayer = function(mapRenderer, tileLayer) {
var target = goog.dom.createElement(goog.dom.TagName.DIV);
target.className = 'ol-layer';
target.style.position = 'absolute';
goog.base(this, mapRenderer, tileLayer, target);
/**
* @type {Object}
* @private
* @type {boolean}
*/
this.renderedTiles_ = {};
this.renderedVisible_ = true;
/**
* @type {number|undefined}
* @private
* @type {number}
*/
this.renderedMapResolution_ = undefined;
this.renderedOpacity_ = 1;
/**
* @private
* @type {Object.<number, ol.renderer.dom.TileLayerZ_>}
*/
this.tileLayerZs_ = {};
};
goog.inherits(ol.renderer.dom.TileLayer, ol.renderer.dom.Layer);
/**
* @inheritDoc
* @return {ol.layer.TileLayer} Layer.
* @return {ol.layer.TileLayer} Tile layer.
*/
ol.renderer.dom.TileLayer.prototype.getLayer = function() {
return /** @type {ol.layer.TileLayer} */ (goog.base(this, 'getLayer'));
};
/**
* Get the pixel offset between the tile origin and the container origin.
* @private
* @param {number} z Z.
* @param {number} resolution Resolution.
* @return {ol.Coordinate} Offset.
*/
ol.renderer.dom.TileLayer.prototype.getTileOffset_ = function(z, resolution) {
var tileLayer = this.getLayer();
var tileSource = tileLayer.getTileSource();
var tileGrid = tileSource.getTileGrid();
var tileOrigin = tileGrid.getOrigin(z);
var offset = new ol.Coordinate(
Math.round((this.origin.x - tileOrigin.x) / resolution),
Math.round((tileOrigin.y - this.origin.y) / resolution));
return offset;
};
/**
* Get rid of all tiles that weren't drawn in the most recent rendering.
* @param {Object.<number, Object.<string, ol.Tile>>} tilesDrawnByZ Tiles just
* rendered.
* @private
*/
ol.renderer.dom.TileLayer.prototype.removeExtraTiles_ =
function(tilesDrawnByZ) {
var key, tileCoord, tilesDrawn, tile;
for (key in this.renderedTiles_) {
tileCoord = ol.TileCoord.createFromString(key);
tilesDrawn = tilesDrawnByZ[tileCoord.z];
if (!(tilesDrawn && key in tilesDrawn)) {
tile = this.renderedTiles_[key];
delete this.renderedTiles_[key];
goog.dom.removeNode(tile.getImage(this));
}
}
ol.renderer.dom.TileLayer.prototype.getTileLayer = function() {
return /** @type {ol.layer.TileLayer} */ (this.getLayer());
};
@@ -92,74 +70,85 @@ ol.renderer.dom.TileLayer.prototype.removeExtraTiles_ =
ol.renderer.dom.TileLayer.prototype.renderFrame = function(time) {
var map = this.getMap();
if (!map.isDef()) {
goog.asserts.assert(map.isDef());
var view = map.getView().getView2D();
var mapCenter = /** @type {!ol.Coordinate} */ (view.getCenter());
var mapResolution = /** @type {number} */ (view.getResolution());
var mapSize = /** @type {!ol.Size} */ (map.getSize());
var mapRotatedExtent = /** @type {!ol.Extent} */
(view.getRotatedExtent(mapSize));
var mapRotation = view.getRotation();
var mapScale = 1 / mapResolution;
var tileLayer = this.getTileLayer();
var visible = tileLayer.getVisible();
if (!visible) {
if (this.renderedVisible_) {
goog.style.showElement(this.target, false);
this.renderedVisible_ = false;
}
return;
}
var mapSize = /** @type {ol.Size} */ (map.getSize());
var view = map.getView().getView2D();
var mapExtent = /** @type {!ol.Extent} */ (view.getRotatedExtent(mapSize));
var mapResolution = /** @type {number} */ (view.getResolution());
var resolutionChanged = (mapResolution !== this.renderedMapResolution_);
var tileLayer = this.getLayer();
var opacity = tileLayer.getOpacity();
if (opacity != this.renderedOpacity_) {
goog.style.setOpacity(this.target, opacity);
this.renderedOpacity_ = opacity;
}
var tileSource = tileLayer.getTileSource();
var tileGrid = tileSource.getTileGrid();
// z represents the "best" resolution
var z = tileGrid.getZForResolution(mapResolution);
/**
* @type {Object.<number, Object.<string, ol.Tile>>}
*/
/** @type {Object.<number, Object.<string, ol.Tile>>} */
var tilesToDrawByZ = {};
tilesToDrawByZ[z] = {};
var tileRange =
tileGrid.getTileRangeForExtentAndResolution(mapExtent, mapResolution);
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
mapRotatedExtent, mapResolution);
var allTilesLoaded = true;
// first pass through the tile range to determine all the tiles needed
tilesToDrawByZ[z] = {};
tileRange.forEachTileCoord(z, function(tileCoord) {
var tile = tileSource.getTile(tileCoord);
if (goog.isNull(tile)) {
// we're outside the source's extent, continue
return;
}
var key = tile.tileCoord.toString();
var state = tile.getState();
if (state == ol.TileState.IDLE) {
var tileState = tile.getState();
if (tileState == ol.TileState.IDLE) {
tile.load();
} else if (state == ol.TileState.LOADED) {
tilesToDrawByZ[z][key] = tile;
} else if (tileState == ol.TileState.LOADED) {
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
return;
} else if (tileState == ol.TileState.ERROR) {
return;
}
allTilesLoaded = false;
/**
* Look for already loaded tiles at alternate z that can serve as
* placeholders until tiles at the current z have loaded.
*
* TODO: make this more efficent for filling partial holes
*/
// FIXME this could be more efficient about filling partial holes
tileGrid.forEachTileCoordParentTileRange(
tileCoord,
function(altZ, altTileRange) {
function(z, tileRange) {
var fullyCovered = true;
altTileRange.forEachTileCoord(altZ, function(altTileCoord) {
var tileKey = altTileCoord.toString();
if (tilesToDrawByZ[altZ] && tilesToDrawByZ[altZ][tileKey]) {
tileRange.forEachTileCoord(z, function(tileCoord) {
var tileCoordKey = tileCoord.toString();
if (tilesToDrawByZ[z] && tilesToDrawByZ[z][tileCoordKey]) {
return;
}
var altTile = tileSource.getTile(altTileCoord);
if (!goog.isNull(altTile) &&
altTile.getState() == ol.TileState.LOADED) {
if (!(altZ in tilesToDrawByZ)) {
tilesToDrawByZ[altZ] = {};
var tile = tileSource.getTile(tileCoord);
if (!goog.isNull(tile) &&
tile.getState() == ol.TileState.LOADED) {
if (!tilesToDrawByZ[z]) {
tilesToDrawByZ[z] = {};
}
tilesToDrawByZ[altZ][tileKey] = altTile;
tilesToDrawByZ[z][tileCoordKey] = tile;
} else {
fullyCovered = false;
}
@@ -173,57 +162,227 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = function(time) {
var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number);
goog.array.sort(zs);
var fragment = document.createDocumentFragment();
var altFragment = document.createDocumentFragment();
var newTiles = false;
var newAltTiles = false;
for (var i = 0, ii = zs.length; i < ii; ++i) {
var tileZ = zs[i];
var tilesToDraw = tilesToDrawByZ[tileZ];
var tileOffset = this.getTileOffset_(tileZ, mapResolution);
for (var key in tilesToDraw) {
var tile = tilesToDraw[key];
var tileCoord = tile.tileCoord;
var pixelBounds = tileGrid.getPixelBoundsForTileCoordAndResolution(
tileCoord, mapResolution);
var img = tile.getImage(this);
var style = img.style;
var append = !(key in this.renderedTiles_);
if (append || resolutionChanged) {
style.left = (pixelBounds.minX - tileOffset.x) + 'px';
style.top = (-pixelBounds.maxY - tileOffset.y) + 'px';
style.width = pixelBounds.getWidth() + 'px';
style.height = pixelBounds.getHeight() + 'px';
}
if (append) {
this.renderedTiles_[key] = tile;
style.position = 'absolute';
if (tileZ === z) {
goog.dom.appendChild(fragment, img);
newTiles = true;
} else {
goog.dom.appendChild(altFragment, img);
newAltTiles = true;
/** @type {Object.<number, boolean>} */
var newTileLayerZKeys = {};
var tileSize = tileGrid.getTileSize();
var iz, tileCoordKey, tileCoordOrigin, tileLayerZ, tileLayerZKey, tilesToDraw;
for (iz = 0; iz < zs.length; ++iz) {
tileLayerZKey = zs[iz];
if (tileLayerZKey in this.tileLayerZs_) {
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
} else {
tileCoordOrigin =
tileGrid.getTileCoordForCoordAndZ(mapCenter, tileLayerZKey);
tileLayerZ = new ol.renderer.dom.TileLayerZ_(tileGrid, tileCoordOrigin);
newTileLayerZKeys[tileLayerZKey] = true;
this.tileLayerZs_[tileLayerZKey] = tileLayerZ;
}
tilesToDraw = tilesToDrawByZ[tileLayerZKey];
for (tileCoordKey in tilesToDraw) {
tileLayerZ.addTile(tilesToDraw[tileCoordKey]);
}
tileLayerZ.finalizeAddTiles();
}
/** @type {Array.<number>} */
var tileLayerZKeys =
goog.array.map(goog.object.getKeys(this.tileLayerZs_), Number);
goog.array.sort(tileLayerZKeys);
var i, j, origin, resolution;
var transform = goog.vec.Mat4.createNumber();
for (i = 0; i < tileLayerZKeys.length; ++i) {
tileLayerZKey = tileLayerZKeys[i];
tileLayerZ = this.tileLayerZs_[tileLayerZKey];
if (!(tileLayerZKey in tilesToDrawByZ)) {
goog.dom.removeNode(tileLayerZ.target);
delete this.tileLayerZs_[tileLayerZKey];
continue;
}
resolution = tileLayerZ.getResolution();
origin = tileLayerZ.getOrigin();
goog.vec.Mat4.makeIdentity(transform);
goog.vec.Mat4.translate(
transform, mapSize.width / 2, mapSize.height / 2, 0);
if (goog.isDef(mapRotation)) {
goog.vec.Mat4.rotateZ(transform, mapRotation);
}
goog.vec.Mat4.scale(
transform, resolution / mapResolution, resolution / mapResolution, 1);
goog.vec.Mat4.translate(transform, (origin.x - mapCenter.x) / resolution,
(mapCenter.y - origin.y) / resolution, 0);
tileLayerZ.setTransform(transform);
if (tileLayerZKey in newTileLayerZKeys) {
for (j = tileLayerZKey - 1; j >= 0; --j) {
if (j in this.tileLayerZs_) {
goog.dom.insertSiblingAfter(
tileLayerZ.target, this.tileLayerZs_[j].target);
break;
}
}
}
}
if (newAltTiles) {
var child = this.target.firstChild;
if (child) {
goog.dom.insertSiblingBefore(altFragment, child);
if (j < 0) {
goog.dom.insertChildAt(this.target, tileLayerZ.target, 0);
}
} else {
goog.dom.appendChild(this.target, altFragment);
tileLayerZ.removeTilesOutsideExtent(mapRotatedExtent);
}
}
if (newTiles) {
goog.dom.appendChild(this.target, fragment);
if (visible && !this.renderedVisible_) {
goog.style.showElement(this.target, true);
this.renderedVisible_ = true;
}
this.renderedMapResolution_ = mapResolution;
this.removeExtraTiles_(tilesToDrawByZ);
return !allTilesLoaded;
};
/**
* @constructor
* @private
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
* @param {ol.TileCoord} tileCoordOrigin Tile coord origin.
*/
ol.renderer.dom.TileLayerZ_ = function(tileGrid, tileCoordOrigin) {
/**
* @type {!Element}
*/
this.target = goog.dom.createElement(goog.dom.TagName.DIV);
this.target.style.position = 'absolute';
/**
* @private
* @type {ol.tilegrid.TileGrid}
*/
this.tileGrid_ = tileGrid;
/**
* @private
* @type {ol.TileCoord}
*/
this.tileCoordOrigin_ = tileCoordOrigin;
/**
* @private
* @type {!ol.Coordinate}
*/
this.origin_ = /** @type {!ol.Coordinate} */
(tileGrid.getTileCoordExtent(tileCoordOrigin).getTopLeft());
/**
* @private
* @type {number}
*/
this.resolution_ = tileGrid.getResolution(tileCoordOrigin.z);
/**
* @private
* @type {Object.<string, ol.Tile>}
*/
this.tiles_ = {};
/**
* @private
* @type {DocumentFragment}
*/
this.documentFragment_ = null;
/**
* @private
* @type {goog.vec.Mat4.AnyType}
*/
this.transform_ = goog.vec.Mat4.createNumberIdentity();
};
/**
* @param {ol.Tile} tile Tile.
*/
ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile) {
var tileCoord = tile.tileCoord;
goog.asserts.assert(tileCoord.z == this.tileCoordOrigin_.z);
var tileCoordKey = tileCoord.toString();
if (tileCoordKey in this.tiles_) {
return;
}
var tileSize = this.tileGrid_.getTileSize();
var image = tile.getImage(this);
var style = image.style;
style.position = 'absolute';
style.left =
((tileCoord.x - this.tileCoordOrigin_.x) * tileSize.width) + 'px';
style.top =
((this.tileCoordOrigin_.y - tileCoord.y) * tileSize.height) + 'px';
if (goog.isNull(this.documentFragment_)) {
this.documentFragment_ = document.createDocumentFragment();
}
goog.dom.appendChild(this.documentFragment_, image);
this.tiles_[tileCoordKey] = tile;
};
/**
*/
ol.renderer.dom.TileLayerZ_.prototype.finalizeAddTiles = function() {
if (!goog.isNull(this.documentFragment_)) {
goog.dom.appendChild(this.target, this.documentFragment_);
this.documentFragment_ = null;
}
};
/**
* @return {!ol.Coordinate} Origin.
*/
ol.renderer.dom.TileLayerZ_.prototype.getOrigin = function() {
return this.origin_;
};
/**
* @return {number} Resolution.
*/
ol.renderer.dom.TileLayerZ_.prototype.getResolution = function() {
return this.resolution_;
};
/**
* @param {ol.Extent} extent Extent.
*/
ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent =
function(extent) {
var tileRange =
this.tileGrid_.getTileRangeForExtentAndZ(extent, this.tileCoordOrigin_.z);
var tilesToRemove = [];
var tile, tileCoordKey;
for (tileCoordKey in this.tiles_) {
tile = this.tiles_[tileCoordKey];
if (!tileRange.contains(tile.tileCoord)) {
tilesToRemove.push(tile);
}
}
var i;
for (i = 0; i < tilesToRemove.length; ++i) {
tile = tilesToRemove[i];
tileCoordKey = tile.tileCoord.toString();
goog.dom.removeNode(tile.getImage(this));
delete this.tiles_[tileCoordKey];
}
};
/**
* @param {goog.vec.Mat4.AnyType} transform Transform.
*/
ol.renderer.dom.TileLayerZ_.prototype.setTransform = function(transform) {
if (!goog.vec.Mat4.equals(transform, this.transform_)) {
ol.dom.transformElement2D(this.target, transform);
goog.vec.Mat4.setFromArray(this.transform_, transform);
}
};