Skip to content

Commit

Permalink
Merge pull request openlayers#3806 from ahocevar/clip-wrapx
Browse files Browse the repository at this point in the history
Do not clip canvas for vector layers when wrapping the world
  • Loading branch information
ahocevar committed Jul 3, 2015
2 parents 2adf3be + 7463a58 commit 86d9d69
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 11 deletions.
14 changes: 11 additions & 3 deletions src/ol/renderer/canvas/canvasvectorlayerrenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
skippedFeatureUids);
startX -= worldWidth;
}
// restore original transform for render and compose events
transform = this.getTransform(frameState, 0);
}

if (replayContext != context) {
Expand Down Expand Up @@ -236,9 +238,15 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =

if (vectorSource.getWrapX() && viewState.projection.canWrapX() &&
!ol.extent.containsExtent(projectionExtent, frameState.extent)) {
// do not clip when the view crosses the -180° or 180° meridians
extent[0] = projectionExtent[0];
extent[2] = projectionExtent[2];
// For the replay group, we need an extent that intersects the real world
// (-180° to +180°). To support geometries in a coordinate range from -540°
// to +540°, we add at least 1 world width on each side of the projection
// extent. If the viewport is wider than the world, we need to add half of
// the viewport width to make sure we cover the whole viewport.
var worldWidth = ol.extent.getWidth(projectionExtent);
var buffer = Math.max(ol.extent.getWidth(extent) / 2, worldWidth);
extent[0] = projectionExtent[0] - buffer;
extent[2] = projectionExtent[2] + buffer;
}

if (!this.dirty_ &&
Expand Down
5 changes: 1 addition & 4 deletions test/spec/ol/proj/epsg3857projection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@ goog.provide('ol.test.proj.EPSG3857');

describe('ol.proj.EPSG3857', function() {

beforeEach(function() {
ol.proj.common.add();
});

afterEach(function() {
ol.proj.clearAllProjections();
ol.proj.common.add();
});

describe('getPointResolution', function() {
Expand Down
5 changes: 1 addition & 4 deletions test/spec/ol/proj/proj.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ goog.provide('ol.test.proj');

describe('ol.proj', function() {

beforeEach(function() {
ol.proj.common.add();
});

afterEach(function() {
ol.proj.clearAllProjections();
ol.proj.common.add();
});

describe('projection equivalence', function() {
Expand Down
74 changes: 74 additions & 0 deletions test/spec/ol/renderer/canvas/canvasvectorlayerrenderer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,88 @@ describe('ol.renderer.canvas.VectorLayer', function() {
});
});

describe('#prepareFrame', function() {
var frameState, projExtent, renderer, worldWidth, buffer;

beforeEach(function() {
var layer = new ol.layer.Vector({
source: new ol.source.Vector({wrapX: true})
});
renderer = new ol.renderer.canvas.VectorLayer(layer);
var projection = ol.proj.get('EPSG:3857');
projExtent = projection.getExtent();
worldWidth = ol.extent.getWidth(projExtent);
buffer = layer.getRenderBuffer();
frameState = {
skippedFeatureUids: {},
viewHints: [],
viewState: {
projection: projection,
resolution: 1,
rotation: 0
}
};
});

it('sets correct extent for small viewport near dateline', function() {

frameState.extent =
[projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000];
renderer.prepareFrame(frameState, {});
expect(renderer.replayGroup_.maxExtent_).to.eql(ol.extent.buffer([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));

});

it('sets correct extent for viewport less than 1 world wide', function() {

frameState.extent =
[projExtent[0] - 10000, -10000, projExtent[1] - 10000, 10000];
renderer.prepareFrame(frameState, {});
expect(renderer.replayGroup_.maxExtent_).to.eql(ol.extent.buffer([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
});

it('sets correct extent for viewport more than 1 world wide', function() {

frameState.extent =
[2 * projExtent[0] - 10000, -10000, 2 * projExtent[1] + 10000, 10000];
renderer.prepareFrame(frameState, {});
expect(renderer.replayGroup_.maxExtent_).to.eql(ol.extent.buffer([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
});

it('sets correct extent for viewport more than 2 worlds wide', function() {

frameState.extent = [
projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[1] + 2 * worldWidth + 10000, 10000
];
renderer.prepareFrame(frameState, {});
expect(renderer.replayGroup_.maxExtent_).to.eql(ol.extent.buffer([
projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[2] + 2 * worldWidth + 10000, 10000
], buffer));
});

});

});


goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.extent');
goog.require('ol.geom.Point');
goog.require('ol.layer.Vector');
goog.require('ol.proj');
goog.require('ol.renderer.canvas.VectorLayer');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
Expand Down

0 comments on commit 86d9d69

Please sign in to comment.