Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use a fixed tile grid for vector rendering #799

Merged
merged 10 commits into from
Jun 23, 2013
81 changes: 61 additions & 20 deletions src/ol/renderer/canvas/canvasvectorlayerrenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ goog.require('goog.vec.Mat4');
goog.require('ol.Pixel');
goog.require('ol.TileCache');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.ViewHint');
goog.require('ol.extent');
goog.require('ol.filter.Extent');
Expand All @@ -22,6 +23,17 @@ goog.require('ol.renderer.canvas.VectorRenderer');
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
Expand Down Expand Up @@ -140,6 +152,15 @@ ol.renderer.canvas.VectorLayer = function(mapRenderer, layer) {
*/
this.tileGrid_ = null;

/**
* Tile range before the current animation or interaction. This is updated
* whenever the view is idle.
*
* @private
* @type {ol.TileRange}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing require for ol.TileRange.

*/
this.tileRange_ = null;

/**
* @private
* @type {function()}
Expand Down Expand Up @@ -219,8 +240,7 @@ ol.renderer.canvas.VectorLayer.prototype.getFeaturesForPixel =

var layer = this.getLayer();
var location = map.getCoordinateFromPixel(pixel);
var tileCoord = this.tileGrid_.getTileCoordForCoordAndResolution(
location, this.getMap().getView().getView2D().getResolution());
var tileCoord = this.tileGrid_.getTileCoordForCoordAndZ(location, 0);
var key = tileCoord.toString();
if (this.tileCache_.containsKey(key)) {
var cachedTile = this.tileCache_.get(key);
Expand Down Expand Up @@ -301,28 +321,49 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =

var view2DState = frameState.view2DState,
resolution = view2DState.resolution,
projection = view2DState.projection,
extent = frameState.extent,
layer = this.getVectorLayer(),
tileGrid = this.tileGrid_;
tileGrid = this.tileGrid_,
tileSize = [512, 512],
idle = !frameState.viewHints[ol.ViewHint.ANIMATING] &&
!frameState.viewHints[ol.ViewHint.INTERACTING];

// lazy tile grid creation
if (idle) {
// avoid rendering issues for very high zoom levels
var gridResolution = Math.max(resolution,
ol.renderer.canvas.MIN_RESOLUTION /
ol.METERS_PER_UNIT[projection.getUnits()]);
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)) {
// lazy tile grid creation to match the view projection
tileGrid = ol.tilegrid.createForProjection(
view2DState.projection,
20, // should be no harm in going big here - ideally, it would be ∞
[512, 512]);
this.tileGrid_ = 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
var z = tileGrid.getZForResolution(resolution),
tileResolution = tileGrid.getResolution(z),
tileRange = tileGrid.getTileRangeForExtentAndResolution(
extent, tileResolution),
tileRangeExtent = tileGrid.getTileRangeExtent(z, tileRange),
tileSize = tileGrid.getTileSize(z),
sketchOrigin = ol.extent.getTopLeft(tileRangeExtent),
transform = this.transform_;
var tileResolution = tileGrid.getResolution(0);
if (idle) {
this.tileRange_ = tileGrid.getTileRangeForExtentAndResolution(
extent, tileResolution);
}
var transform = this.transform_,
tileRange = this.tileRange_,
tileRangeExtent = tileGrid.getTileRangeExtent(0, tileRange),
sketchOrigin = ol.extent.getTopLeft(tileRangeExtent);

goog.vec.Mat4.makeIdentity(transform);
goog.vec.Mat4.translate(transform,
Expand Down Expand Up @@ -399,7 +440,7 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
var tilesOnSketchCanvas = {};
// TODO make gutter configurable?
var tileGutter = 15 * tileResolution;
var tile, tileCoord, key, tileState, x, y;
var tile, tileCoord, key, x, y;
// render features by geometry type
var filters = this.geometryFilters_,
numFilters = filters.length,
Expand All @@ -409,11 +450,11 @@ ol.renderer.canvas.VectorLayer.prototype.renderFrame =
groups, group, j, numGroups, featuresObject, tileHasFeatures;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
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();
if (this.tileCache_.containsKey(key)) {
tilesToRender[key] = tileCoord;
} else if (!frameState.viewHints[ol.ViewHint.ANIMATING]) {
} else if (idle) {
tileExtent = tileGrid.getTileCoordExtent(tileCoord);
tileExtent[0] -= tileGutter;
tileExtent[1] += tileGutter;
Expand Down