Always use load extent with real world center

This commit is contained in:
Andreas Hocevar
2020-03-29 18:14:31 +02:00
parent 0c9324f398
commit 190cd202a1
4 changed files with 35 additions and 42 deletions

View File

@@ -437,8 +437,7 @@ class Graticule extends VectorLayer {
features: new Collection(), features: new Collection(),
overlaps: false, overlaps: false,
useSpatialIndex: false, useSpatialIndex: false,
wrapX: options.wrapX, wrapX: options.wrapX
loadWrapX: false
}) })
); );

View File

@@ -361,7 +361,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
const center = viewState.center.slice(); const center = viewState.center.slice();
const extent = buffer(frameStateExtent, const extent = buffer(frameStateExtent,
vectorLayerRenderBuffer * resolution); vectorLayerRenderBuffer * resolution);
let loadExtent = extent.slice(); const loadExtent = extent.slice();
const projectionExtent = viewState.projection.getExtent(); const projectionExtent = viewState.projection.getExtent();
if (vectorSource.getWrapX() && viewState.projection.canWrapX() && if (vectorSource.getWrapX() && viewState.projection.canWrapX() &&
@@ -375,11 +375,10 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
const gutter = Math.max(getWidth(extent) / 2, worldWidth); const gutter = Math.max(getWidth(extent) / 2, worldWidth);
extent[0] = projectionExtent[0] - gutter; extent[0] = projectionExtent[0] - gutter;
extent[2] = projectionExtent[2] + gutter; extent[2] = projectionExtent[2] + gutter;
if (vectorSource.getLoadWrapX()) {
loadExtent = extent;
}
const worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth); const worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);
center[0] -= (worldsAway * worldWidth); center[0] -= (worldsAway * worldWidth);
loadExtent[0] -= (worldsAway * worldWidth);
loadExtent[2] -= (worldsAway * worldWidth);
} }
if (!this.dirty_ && if (!this.dirty_ &&

View File

@@ -146,10 +146,6 @@ export class VectorSourceEvent extends Event {
* @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the
* -180° and 180° meridians to work properly, this should be set to `false`. The * -180° and 180° meridians to work properly, this should be set to `false`. The
* resulting geometry coordinates will then exceed the world bounds. * resulting geometry coordinates will then exceed the world bounds.
* @property {boolean} [loadWrapX=true] Call the loader with one world width either side
* of the projection extent when the world is wrapped horizontally. This allows features
* to be loaded in a single request, but may be inefficient. If `false` only the viewport
* extent is used and the loader must determine the appropriate real world requests.
*/ */
@@ -190,12 +186,6 @@ class VectorSource extends Source {
*/ */
this.format_ = options.format; this.format_ = options.format;
/**
* @private
* @type {boolean}
*/
this.loadWrapX_ = options.loadWrapX === undefined ? true : options.loadWrapX;
/** /**
* @private * @private
* @type {boolean} * @type {boolean}
@@ -811,14 +801,6 @@ class VectorSource extends Source {
} }
/**
* @return {boolean} The loadWrapX option used to construct the source.
*/
getLoadWrapX() {
return this.loadWrapX_;
}
/** /**
* @return {boolean} The source can have overlapping geometries. * @return {boolean} The source can have overlapping geometries.
*/ */

View File

@@ -1,7 +1,7 @@
import Feature from '../../../../../src/ol/Feature.js'; import Feature from '../../../../../src/ol/Feature.js';
import Map from '../../../../../src/ol/Map.js'; import Map from '../../../../../src/ol/Map.js';
import View from '../../../../../src/ol/View.js'; import View from '../../../../../src/ol/View.js';
import {buffer as bufferExtent, getWidth} from '../../../../../src/ol/extent.js'; import {buffer as bufferExtent, getWidth, getCenter} from '../../../../../src/ol/extent.js';
import Circle from '../../../../../src/ol/geom/Circle.js'; import Circle from '../../../../../src/ol/geom/Circle.js';
import Point from '../../../../../src/ol/geom/Point.js'; import Point from '../../../../../src/ol/geom/Point.js';
import {fromExtent} from '../../../../../src/ol/geom/Polygon.js'; import {fromExtent} from '../../../../../src/ol/geom/Polygon.js';
@@ -243,7 +243,6 @@ describe('ol.renderer.canvas.VectorLayer', function() {
frameState = { frameState = {
viewHints: [], viewHints: [],
viewState: { viewState: {
center: [0, 0],
projection: projection, projection: projection,
resolution: 1, resolution: 1,
rotation: 0 rotation: 0
@@ -251,58 +250,72 @@ describe('ol.renderer.canvas.VectorLayer', function() {
}; };
}); });
function setExtent(extent) {
frameState.extent = extent;
frameState.viewState.center = getCenter(extent);
}
it('sets correct extent for small viewport near dateline', function() { it('sets correct extent for small viewport near dateline', function() {
frameState.extent = setExtent([projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000]);
[projExtent[0] - 10000, -10000, projExtent[0] + 10000, 10000];
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
], buffer)); ], buffer));
expect(loadExtent).to.eql(renderer.replayGroup_.maxExtent_); expect(loadExtent).to.eql(bufferExtent(frameState.extent, buffer));
}); });
it('sets correct extent for viewport less than 1 world wide', function() { it('sets correct extent for viewport less than 1 world wide', function() {
frameState.extent = setExtent([projExtent[0] - 10000, -10000, projExtent[2] - 10000, 10000]);
[projExtent[0] - 10000, -10000, projExtent[1] - 10000, 10000];
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
], buffer)); ], buffer));
expect(loadExtent).to.eql(renderer.replayGroup_.maxExtent_); expect(loadExtent).to.eql(bufferExtent(frameState.extent, buffer));
}); });
it('sets correct extent for viewport more than 1 world wide', function() { it('sets correct extent for viewport more than 1 world wide', function() {
frameState.extent = setExtent([2 * projExtent[0] + 10000, -10000, 2 * projExtent[2] - 10000, 10000]);
[2 * projExtent[0] - 10000, -10000, 2 * projExtent[1] + 10000, 10000];
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer, projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000 -10000, projExtent[2] + worldWidth - buffer, 10000
], buffer)); ], buffer));
expect(loadExtent).to.eql(renderer.replayGroup_.maxExtent_); expect(loadExtent).to.eql(bufferExtent(frameState.extent, buffer));
}); });
it('sets correct extent for viewport more than 2 worlds wide', function() { it('sets correct extent for viewport more than 2 worlds wide, one world away', function() {
frameState.extent = [ setExtent([projExtent[0] - 2 * worldWidth - 10000,
projExtent[0] - 2 * worldWidth - 10000, -10000, projExtent[0] + 2 * worldWidth + 10000, 10000
-10000, projExtent[1] + 2 * worldWidth + 10000, 10000 ]);
];
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([ expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - 2 * worldWidth - 10000, projExtent[0] - 2 * worldWidth - 10000,
-10000, projExtent[2] + 2 * worldWidth + 10000, 10000 -10000, projExtent[2] + 2 * worldWidth + 10000, 10000
], buffer)); ], buffer));
expect(loadExtent).to.eql(renderer.replayGroup_.maxExtent_); const normalizedExtent = [projExtent[0] - 2 * worldWidth + worldWidth - 10000, -10000, projExtent[0] + 2 * worldWidth + worldWidth + 10000, 10000];
expect(loadExtent).to.eql(bufferExtent(normalizedExtent, buffer));
});
it('sets correct extent for small viewport near dateline, one world away', function() {
setExtent([-worldWidth - 10000, -10000, -worldWidth + 10000, 10000]);
renderer.prepareFrame(frameState);
expect(renderer.replayGroup_.maxExtent_).to.eql(bufferExtent([
projExtent[0] - worldWidth + buffer,
-10000, projExtent[2] + worldWidth - buffer, 10000
], buffer));
const normalizedExtent = [-10000, -10000, 10000, 10000];
expect(loadExtent).to.eql(bufferExtent(normalizedExtent, buffer));
}); });
it('sets replayGroupChanged correctly', function() { it('sets replayGroupChanged correctly', function() {
frameState.extent = [-10000, -10000, 10000, 10000]; setExtent([-10000, -10000, 10000, 10000]);
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);
expect(renderer.replayGroupChanged).to.be(true); expect(renderer.replayGroupChanged).to.be(true);
renderer.prepareFrame(frameState); renderer.prepareFrame(frameState);