Render map replay group on the correct world instead of wrapping it

By using the frameState's focus, we can adjust extent and transform and
render it for the world of interest instead of wrapping it and rendering
for every visible world.
This commit is contained in:
Andreas Hocevar
2015-04-22 09:11:19 +02:00
parent 23ed120361
commit 513677fecd
7 changed files with 108 additions and 101 deletions

View File

@@ -93,11 +93,10 @@ ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) {
/**
* @param {ol.render.EventType} type Event type.
* @param {olx.FrameState} frameState Frame state.
* @param {boolean} wrapX Wrap the x-axis.
* @private
*/
ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
function(type, frameState, wrapX) {
function(type, frameState) {
var map = this.getMap();
var context = this.context_;
if (map.hasListener(type)) {
@@ -105,21 +104,29 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var projection = viewState.projection;
var projectionExtent = projection.getExtent();
var resolution = viewState.resolution;
var rotation = viewState.rotation;
var repeatReplay = (wrapX && projection.canWrapX() &&
!ol.extent.containsExtent(projectionExtent, extent));
var skippedFeaturesHash = {};
var transform = this.getTransform(frameState, 0);
var offsetX = 0;
if (projection.canWrapX()) {
var projectionExtent = projection.getExtent();
var worldWidth = ol.extent.getWidth(projectionExtent);
var x = frameState.focus[0];
if (x < projectionExtent[0] || x > projectionExtent[2]) {
var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);
offsetX = worldWidth * worldsAway;
extent = [
extent[0] + offsetX, extent[1],
extent[2] + offsetX, extent[3]
];
}
}
var transform = this.getTransform(frameState, offsetX);
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance,
repeatReplay ?
[projectionExtent[0], extent[1], projectionExtent[2], extent[3]] :
extent,
resolution);
var replayGroup = new ol.render.canvas.ReplayGroup(
tolerance, extent, resolution);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, transform, rotation);
@@ -129,30 +136,8 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
replayGroup.finish();
if (!replayGroup.isEmpty()) {
replayGroup.replay(context, pixelRatio, transform, rotation,
skippedFeaturesHash);
replayGroup.replay(context, pixelRatio, transform, rotation, {});
if (repeatReplay) {
var startX = extent[0];
var worldWidth = ol.extent.getWidth(projectionExtent);
var world = 0;
while (startX < projectionExtent[0]) {
--world;
transform = this.getTransform(frameState, worldWidth * world);
replayGroup.replay(context, pixelRatio, transform, rotation,
skippedFeaturesHash);
startX += worldWidth;
}
world = 0;
startX = extent[2];
while (startX > projectionExtent[2]) {
++world;
transform = this.getTransform(frameState, worldWidth * ++world);
replayGroup.replay(context, pixelRatio, transform, rotation,
skippedFeaturesHash);
startX -= worldWidth;
}
}
}
vectorContext.flush();
this.replayGroup = replayGroup;
@@ -174,7 +159,7 @@ ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) {
this.canvas_.width / 2, this.canvas_.height / 2,
pixelRatio / resolution, -pixelRatio / resolution,
-viewState.rotation,
-viewState.center[0] + offsetX,
-viewState.center[0] - offsetX,
-viewState.center[1]);
};
@@ -212,11 +197,10 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
this.calculateMatrices2D(frameState);
this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState, false);
this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState);
var layerStatesArray = frameState.layerStatesArray;
var viewResolution = frameState.viewState.resolution;
var wrapX = false;
var i, ii, layer, layerRenderer, layerState;
for (i = 0, ii = layerStatesArray.length; i < ii; ++i) {
layerState = layerStatesArray[i];
@@ -229,17 +213,12 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
continue;
}
if (layerRenderer.prepareFrame(frameState, layerState)) {
// As soon as a vector layer on the map has wrapX set to true, we make
// feature overlays wrap the x-axis too.
if (layer instanceof ol.layer.Vector && layer.getSource().getWrapX()) {
wrapX = true;
}
layerRenderer.composeFrame(frameState, layerState, context);
}
}
this.dispatchComposeEvent_(
ol.render.EventType.POSTCOMPOSE, frameState, wrapX);
ol.render.EventType.POSTCOMPOSE, frameState);
if (!this.renderedVisible_) {
goog.style.setElementShown(this.canvas_, true);