Merge pull request #799 from ahocevar/dynamic-canvas-tilegrid
Do not use a fixed tile grid for vector rendering. r=@elemoine,@tschaub,@twpayne
This commit is contained in:
@@ -9,6 +9,7 @@ goog.require('goog.vec.Mat4');
|
|||||||
goog.require('ol.Pixel');
|
goog.require('ol.Pixel');
|
||||||
goog.require('ol.TileCache');
|
goog.require('ol.TileCache');
|
||||||
goog.require('ol.TileCoord');
|
goog.require('ol.TileCoord');
|
||||||
|
goog.require('ol.TileRange');
|
||||||
goog.require('ol.ViewHint');
|
goog.require('ol.ViewHint');
|
||||||
goog.require('ol.extent');
|
goog.require('ol.extent');
|
||||||
goog.require('ol.filter.Extent');
|
goog.require('ol.filter.Extent');
|
||||||
@@ -22,6 +23,17 @@ goog.require('ol.renderer.canvas.VectorRenderer');
|
|||||||
goog.require('ol.tilegrid.TileGrid');
|
goog.require('ol.tilegrid.TileGrid');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolution at zoom level 21 in a web mercator default tiling scheme. This
|
||||||
|
* is a workaround for browser bugs that cause line segments to disappear when
|
||||||
|
* they get too long. TODO: Use line clipping as a better work around. See
|
||||||
|
* https://github.com/openlayers/ol3/issues/404.
|
||||||
|
*
|
||||||
|
* @define {number} The lowest supported resolution value.
|
||||||
|
*/
|
||||||
|
ol.renderer.canvas.MIN_RESOLUTION = 0.14929107086948487;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
@@ -140,6 +152,15 @@ ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) {
|
|||||||
*/
|
*/
|
||||||
this.tileGrid_ = null;
|
this.tileGrid_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tile range before the current animation or interaction. This is updated
|
||||||
|
* whenever the view is idle.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {ol.TileRange}
|
||||||
|
*/
|
||||||
|
this.tileRange_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {function()}
|
* @type {function()}
|
||||||
@@ -219,8 +240,7 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =
|
|||||||
|
|
||||||
var layer = this.getLayer();
|
var layer = this.getLayer();
|
||||||
var location = map.getCoordinateFromPixel(pixel);
|
var location = map.getCoordinateFromPixel(pixel);
|
||||||
var tileCoord = this.tileGrid_.getTileCoordForCoordAndResolution(
|
var tileCoord = this.tileGrid_.getTileCoordForCoordAndZ(location, 0);
|
||||||
location, this.getMap().getView().getView2D().getResolution());
|
|
||||||
var key = tileCoord.toString();
|
var key = tileCoord.toString();
|
||||||
if (this.tileCache_.containsKey(key)) {
|
if (this.tileCache_.containsKey(key)) {
|
||||||
var cachedTile = this.tileCache_.get(key);
|
var cachedTile = this.tileCache_.get(key);
|
||||||
@@ -301,28 +321,49 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
|||||||
|
|
||||||
var view2DState = frameState.view2DState,
|
var view2DState = frameState.view2DState,
|
||||||
resolution = view2DState.resolution,
|
resolution = view2DState.resolution,
|
||||||
|
projection = view2DState.projection,
|
||||||
extent = frameState.extent,
|
extent = frameState.extent,
|
||||||
layer = this.getVectorLayer(),
|
layer = this.getVectorLayer(),
|
||||||
tileGrid = this.tileGrid_;
|
tileGrid = this.tileGrid_,
|
||||||
|
tileSize = [512, 512],
|
||||||
|
idle = !frameState.viewHints[ol.ViewHint.ANIMATING] &&
|
||||||
|
!frameState.viewHints[ol.ViewHint.INTERACTING];
|
||||||
|
|
||||||
if (goog.isNull(tileGrid)) {
|
// lazy tile grid creation
|
||||||
// lazy tile grid creation to match the view projection
|
if (idle) {
|
||||||
tileGrid = ol.tilegrid.createForProjection(
|
// avoid rendering issues for very high zoom levels
|
||||||
view2DState.projection,
|
var gridResolution = Math.max(resolution,
|
||||||
20, // should be no harm in going big here - ideally, it would be ∞
|
ol.renderer.canvas.MIN_RESOLUTION /
|
||||||
[512, 512]);
|
ol.METERS_PER_UNIT[projection.getUnits()]);
|
||||||
this.tileGrid_ = tileGrid;
|
if (gridResolution !== this.renderedResolution_) {
|
||||||
|
tileGrid = new ol.tilegrid.TileGrid({
|
||||||
|
origin: [0, 0],
|
||||||
|
projection: projection,
|
||||||
|
resolutions: [gridResolution],
|
||||||
|
tileSize: tileSize
|
||||||
|
});
|
||||||
|
this.tileCache_.clear();
|
||||||
|
this.tileGrid_ = tileGrid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (goog.isNull(tileGrid)) {
|
||||||
|
// We should only get here when the first call to renderFrame happens during
|
||||||
|
// an animation. Try again in the next renderFrame call.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// set up transform for the layer canvas to be drawn to the map canvas
|
// set up transform for the layer canvas to be drawn to the map canvas
|
||||||
var z = tileGrid.getZForResolution(resolution),
|
var tileResolution = tileGrid.getResolution(0);
|
||||||
tileResolution = tileGrid.getResolution(z),
|
if (idle) {
|
||||||
tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
this.tileRange_ = tileGrid.getTileRangeForExtentAndResolution(
|
||||||
extent, tileResolution),
|
extent, tileResolution);
|
||||||
tileRangeExtent = tileGrid.getTileRangeExtent(z, tileRange),
|
}
|
||||||
tileSize = tileGrid.getTileSize(z),
|
var transform = this.transform_,
|
||||||
sketchOrigin = ol.extent.getTopLeft(tileRangeExtent),
|
tileRange = this.tileRange_,
|
||||||
transform = this.transform_;
|
tileRangeExtent = tileGrid.getTileRangeExtent(0, tileRange),
|
||||||
|
sketchOrigin = ol.extent.getTopLeft(tileRangeExtent);
|
||||||
|
|
||||||
goog.vec.Mat4.makeIdentity(transform);
|
goog.vec.Mat4.makeIdentity(transform);
|
||||||
goog.vec.Mat4.translate(transform,
|
goog.vec.Mat4.translate(transform,
|
||||||
@@ -399,7 +440,7 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
|||||||
var tilesOnSketchCanvas = {};
|
var tilesOnSketchCanvas = {};
|
||||||
// TODO make gutter configurable?
|
// TODO make gutter configurable?
|
||||||
var tileGutter = 15 * tileResolution;
|
var tileGutter = 15 * tileResolution;
|
||||||
var tile, tileCoord, key, tileState, x, y;
|
var tile, tileCoord, key, x, y;
|
||||||
// render features by geometry type
|
// render features by geometry type
|
||||||
var filters = this.geometryFilters_,
|
var filters = this.geometryFilters_,
|
||||||
numFilters = filters.length,
|
numFilters = filters.length,
|
||||||
@@ -409,11 +450,11 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
|
|||||||
groups, group, j, numGroups, featuresObject, tileHasFeatures;
|
groups, group, j, numGroups, featuresObject, tileHasFeatures;
|
||||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
tileCoord = new ol.TileCoord(z, x, y);
|
tileCoord = new ol.TileCoord(0, x, y);
|
||||||
key = tileCoord.toString();
|
key = tileCoord.toString();
|
||||||
if (this.tileCache_.containsKey(key)) {
|
if (this.tileCache_.containsKey(key)) {
|
||||||
tilesToRender[key] = tileCoord;
|
tilesToRender[key] = tileCoord;
|
||||||
} else if (!frameState.viewHints[ol.ViewHint.ANIMATING]) {
|
} else if (idle) {
|
||||||
tileExtent = tileGrid.getTileCoordExtent(tileCoord);
|
tileExtent = tileGrid.getTileCoordExtent(tileCoord);
|
||||||
tileExtent[0] -= tileGutter;
|
tileExtent[0] -= tileGutter;
|
||||||
tileExtent[1] += tileGutter;
|
tileExtent[1] += tileGutter;
|
||||||
|
|||||||
Reference in New Issue
Block a user