Only create and load tiles within the viewport
This commit is contained in:
@@ -531,6 +531,29 @@ export function getForViewAndSize(
|
|||||||
size,
|
size,
|
||||||
opt_extent
|
opt_extent
|
||||||
) {
|
) {
|
||||||
|
const [x0, y0, x1, y1, x2, y2, x3, y3] = getRotatedViewport(
|
||||||
|
center,
|
||||||
|
resolution,
|
||||||
|
rotation,
|
||||||
|
size
|
||||||
|
);
|
||||||
|
return createOrUpdate(
|
||||||
|
Math.min(x0, x1, x2, x3),
|
||||||
|
Math.min(y0, y1, y2, y3),
|
||||||
|
Math.max(x0, x1, x2, x3),
|
||||||
|
Math.max(y0, y1, y2, y3),
|
||||||
|
opt_extent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("./coordinate.js").Coordinate} center Center.
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} rotation Rotation.
|
||||||
|
* @param {import("./size.js").Size} size Size.
|
||||||
|
* @return {Array<number>} Linear ring representing the viewport.
|
||||||
|
*/
|
||||||
|
export function getRotatedViewport(center, resolution, rotation, size) {
|
||||||
const dx = (resolution * size[0]) / 2;
|
const dx = (resolution * size[0]) / 2;
|
||||||
const dy = (resolution * size[1]) / 2;
|
const dy = (resolution * size[1]) / 2;
|
||||||
const cosRotation = Math.cos(rotation);
|
const cosRotation = Math.cos(rotation);
|
||||||
@@ -541,21 +564,18 @@ export function getForViewAndSize(
|
|||||||
const ySin = dy * sinRotation;
|
const ySin = dy * sinRotation;
|
||||||
const x = center[0];
|
const x = center[0];
|
||||||
const y = center[1];
|
const y = center[1];
|
||||||
const x0 = x - xCos + ySin;
|
return [
|
||||||
const x1 = x - xCos - ySin;
|
x - xCos + ySin,
|
||||||
const x2 = x + xCos - ySin;
|
y - xSin - yCos,
|
||||||
const x3 = x + xCos + ySin;
|
x - xCos - ySin,
|
||||||
const y0 = y - xSin - yCos;
|
y - xSin + yCos,
|
||||||
const y1 = y - xSin + yCos;
|
x + xCos - ySin,
|
||||||
const y2 = y + xSin + yCos;
|
y + xSin + yCos,
|
||||||
const y3 = y + xSin - yCos;
|
x + xCos + ySin,
|
||||||
return createOrUpdate(
|
y + xSin - yCos,
|
||||||
Math.min(x0, x1, x2, x3),
|
x - xCos + ySin,
|
||||||
Math.min(y0, y1, y2, y3),
|
y - xSin - yCos,
|
||||||
Math.max(x0, x1, x2, x3),
|
];
|
||||||
Math.max(y0, y1, y2, y3),
|
|
||||||
opt_extent
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
equals,
|
equals,
|
||||||
getHeight,
|
getHeight,
|
||||||
getIntersection,
|
getIntersection,
|
||||||
|
getRotatedViewport,
|
||||||
getTopLeft,
|
getTopLeft,
|
||||||
getWidth,
|
getWidth,
|
||||||
intersects,
|
intersects,
|
||||||
@@ -308,8 +309,22 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
const tmpExtent = this.tmpExtent;
|
const tmpExtent = this.tmpExtent;
|
||||||
const tmpTileRange = this.tmpTileRange_;
|
const tmpTileRange = this.tmpTileRange_;
|
||||||
this.newTiles_ = false;
|
this.newTiles_ = false;
|
||||||
|
const viewport = rotation
|
||||||
|
? getRotatedViewport(
|
||||||
|
viewState.center,
|
||||||
|
resolution,
|
||||||
|
rotation,
|
||||||
|
frameState.size
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
|
if (
|
||||||
|
rotation &&
|
||||||
|
!tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const tile = this.getTile(z, x, y, frameState);
|
const tile = this.getTile(z, x, y, frameState);
|
||||||
if (this.isDrawableTile(tile)) {
|
if (this.isDrawableTile(tile)) {
|
||||||
const uid = getUid(this);
|
const uid = getUid(this);
|
||||||
@@ -709,6 +724,15 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
const wantedTiles = frameState.wantedTiles[tileSourceKey];
|
||||||
const tileQueue = frameState.tileQueue;
|
const tileQueue = frameState.tileQueue;
|
||||||
const minZoom = tileGrid.getMinZoom();
|
const minZoom = tileGrid.getMinZoom();
|
||||||
|
const rotation = frameState.viewState.rotation;
|
||||||
|
const viewport = rotation
|
||||||
|
? getRotatedViewport(
|
||||||
|
frameState.viewState.center,
|
||||||
|
frameState.viewState.resolution,
|
||||||
|
rotation,
|
||||||
|
frameState.size
|
||||||
|
)
|
||||||
|
: undefined;
|
||||||
let tileCount = 0;
|
let tileCount = 0;
|
||||||
let tile, tileRange, tileResolution, x, y, z;
|
let tile, tileRange, tileResolution, x, y, z;
|
||||||
for (z = minZoom; z <= currentZ; ++z) {
|
for (z = minZoom; z <= currentZ; ++z) {
|
||||||
@@ -716,6 +740,12 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
|||||||
tileResolution = tileGrid.getResolution(z);
|
tileResolution = tileGrid.getResolution(z);
|
||||||
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) {
|
||||||
|
if (
|
||||||
|
rotation &&
|
||||||
|
!tileGrid.tileCoordIntersectsViewport([z, x, y], viewport)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (currentZ - z <= preload) {
|
if (currentZ - z <= preload) {
|
||||||
++tileCount;
|
++tileCount;
|
||||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {assert} from '../asserts.js';
|
|||||||
import {ceil, clamp, floor} from '../math.js';
|
import {ceil, clamp, floor} from '../math.js';
|
||||||
import {createOrUpdate, getTopLeft} from '../extent.js';
|
import {createOrUpdate, getTopLeft} from '../extent.js';
|
||||||
import {createOrUpdate as createOrUpdateTileCoord} from '../tilecoord.js';
|
import {createOrUpdate as createOrUpdateTileCoord} from '../tilecoord.js';
|
||||||
|
import {intersectsLinearRing} from '../geom/flat/intersectsextent.js';
|
||||||
import {isSorted, linearFindNearest} from '../array.js';
|
import {isSorted, linearFindNearest} from '../array.js';
|
||||||
import {toSize} from '../size.js';
|
import {toSize} from '../size.js';
|
||||||
|
|
||||||
@@ -656,6 +657,22 @@ class TileGrid {
|
|||||||
return clamp(z, this.minZoom, this.maxZoom);
|
return clamp(z, this.minZoom, this.maxZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tile with the provided tile coordinate intersects the given viewport.
|
||||||
|
* @param {import('../tilecoord.js').TileCoord} tileCoord Tile coordinate.
|
||||||
|
* @param {Array<number>} viewport Viewport as returned from {@link module:ol/extent.getRotatedViewport}.
|
||||||
|
* @return {boolean} The tile with the provided tile coordinate intersects the given viewport.
|
||||||
|
*/
|
||||||
|
tileCoordIntersectsViewport(tileCoord, viewport) {
|
||||||
|
return intersectsLinearRing(
|
||||||
|
viewport,
|
||||||
|
0,
|
||||||
|
viewport.length,
|
||||||
|
2,
|
||||||
|
this.getTileCoordExtent(tileCoord)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!import("../extent.js").Extent} extent Extent for this tile grid.
|
* @param {!import("../extent.js").Extent} extent Extent for this tile grid.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
Reference in New Issue
Block a user