Merge pull request #13832 from mike-000/vector-tile-grids

Base vector tile render tile grid on the source grid
This commit is contained in:
Andreas Hocevar
2022-07-18 10:07:52 +02:00
committed by GitHub
6 changed files with 42 additions and 27 deletions
+3 -1
View File
@@ -496,7 +496,9 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
let hitDetectionImageData = tile.hitDetectionImageData[layerUid]; let hitDetectionImageData = tile.hitDetectionImageData[layerUid];
if (!hitDetectionImageData && !this.animatingOrInteracting_) { if (!hitDetectionImageData && !this.animatingOrInteracting_) {
const tileSize = toSize( const tileSize = toSize(
tileGrid.getTileSize(tileGrid.getZForResolution(resolution)) tileGrid.getTileSize(
tileGrid.getZForResolution(resolution, source.zDirection)
)
); );
const rotation = this.renderedRotation_; const rotation = this.renderedRotation_;
const transforms = [ const transforms = [
+26 -13
View File
@@ -5,19 +5,17 @@
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import Tile from '../VectorTile.js'; import Tile from '../VectorTile.js';
import TileCache from '../TileCache.js'; import TileCache from '../TileCache.js';
import TileGrid from '../tilegrid/TileGrid.js';
import TileState from '../TileState.js'; import TileState from '../TileState.js';
import UrlTile from './UrlTile.js'; import UrlTile from './UrlTile.js';
import VectorRenderTile from '../VectorRenderTile.js'; import VectorRenderTile from '../VectorRenderTile.js';
import {DEFAULT_MAX_ZOOM} from '../tilegrid/common.js';
import { import {
buffer as bufferExtent, buffer as bufferExtent,
getIntersection, getIntersection,
intersects, intersects,
} from '../extent.js'; } from '../extent.js';
import { import {createXYZ, extentFromProjection} from '../tilegrid.js';
createForProjection,
createXYZ,
extentFromProjection,
} from '../tilegrid.js';
import {fromKey, getCacheKeyForTileKey, getKeyZXY} from '../tilecoord.js'; import {fromKey, getCacheKeyForTileKey, getKeyZXY} from '../tilecoord.js';
import {isEmpty} from '../obj.js'; import {isEmpty} from '../obj.js';
import {loadFeaturesXhr} from '../featureloader.js'; import {loadFeaturesXhr} from '../featureloader.js';
@@ -274,7 +272,10 @@ class VectorTile extends UrlTile {
if (sourceExtent) { if (sourceExtent) {
getIntersection(extent, sourceExtent, extent); getIntersection(extent, sourceExtent, extent);
} }
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1); const sourceZ = sourceTileGrid.getZForResolution(
resolution,
this.zDirection
);
sourceTileGrid.forEachTileCoord(extent, sourceZ, (sourceTileCoord) => { sourceTileGrid.forEachTileCoord(extent, sourceZ, (sourceTileCoord) => {
const tileUrl = this.tileUrlFunction( const tileUrl = this.tileUrlFunction(
@@ -428,13 +429,25 @@ class VectorTile extends UrlTile {
// A tile grid that matches the tile size of the source tile grid is more // A tile grid that matches the tile size of the source tile grid is more
// likely to have 1:1 relationships between source tiles and rendered tiles. // likely to have 1:1 relationships between source tiles and rendered tiles.
const sourceTileGrid = this.tileGrid; const sourceTileGrid = this.tileGrid;
tileGrid = createForProjection( const resolutions = sourceTileGrid.getResolutions().slice();
projection, const origins = resolutions.map(function (resolution, z) {
undefined, return sourceTileGrid.getOrigin(z);
sourceTileGrid });
? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) const tileSizes = resolutions.map(function (resolution, z) {
: undefined return sourceTileGrid.getTileSize(z);
); });
const length = DEFAULT_MAX_ZOOM + 1;
for (let z = resolutions.length; z < length; ++z) {
resolutions.push(resolutions[z - 1] / 2);
origins.push(origins[z - 1]);
tileSizes.push(tileSizes[z - 1]);
}
tileGrid = new TileGrid({
extent: sourceTileGrid.getExtent(),
origins: origins,
resolutions: resolutions,
tileSizes: tileSizes,
});
this.tileGrids_[code] = tileGrid; this.tileGrids_[code] = tileGrid;
} }
return tileGrid; return tileGrid;
+1 -1
View File
@@ -51,7 +51,7 @@ const DECIMALS = 5;
* negative because OpenLayers tile coordinates use the top left as the origin. * negative because OpenLayers tile coordinates use the top left as the origin.
* @property {number|import("../size.js").Size} [tileSize] Tile size. * @property {number|import("../size.js").Size} [tileSize] Tile size.
* Default is `[256, 256]`. * Default is `[256, 256]`.
* @property {Array<import("../size.js").Size>} [tileSizes] Tile sizes. If given, the array length * @property {Array<number|import("../size.js").Size>} [tileSizes] Tile sizes. If given, the array length
* should match the length of the `resolutions` array, i.e. each resolution can have a different * should match the length of the `resolutions` array, i.e. each resolution can have a different
* tile size. * tile size.
*/ */
+2 -2
View File
@@ -34,7 +34,7 @@ import {get as getProjection} from '../proj.js';
* an extent is used as `origin` or `origins`, then the `y` value must be * an extent is used as `origin` or `origins`, then the `y` value must be
* negative because OpenLayers tile coordinates use the top left as the origin. * negative because OpenLayers tile coordinates use the top left as the origin.
* @property {number|import("../size.js").Size} [tileSize] Tile size. * @property {number|import("../size.js").Size} [tileSize] Tile size.
* @property {Array<import("../size.js").Size>} [tileSizes] Tile sizes. The length of * @property {Array<number|import("../size.js").Size>} [tileSizes] Tile sizes. The length of
* this array needs to match the length of the `resolutions` array. * this array needs to match the length of the `resolutions` array.
*/ */
@@ -108,7 +108,7 @@ export function createFromCapabilitiesMatrixSet(
const matrixIds = []; const matrixIds = [];
/** @type {!Array<import("../coordinate.js").Coordinate>} */ /** @type {!Array<import("../coordinate.js").Coordinate>} */
const origins = []; const origins = [];
/** @type {!Array<import("../size.js").Size>} */ /** @type {!Array<number|import("../size.js").Size>} */
const tileSizes = []; const tileSizes = [];
/** @type {!Array<import("../size.js").Size>} */ /** @type {!Array<import("../size.js").Size>} */
const sizes = []; const sizes = [];
@@ -228,17 +228,13 @@ describe('ol.source.VectorTile', function () {
}); });
describe('different source and render tile grids', function () { describe('different source and render tile grids', function () {
let source, map, loaded, requested, target; let source, map, loaded, target;
beforeEach(function () { beforeEach(function () {
loaded = []; loaded = [];
requested = 0;
function tileUrlFunction(tileCoord) { function tileUrlFunction(tileCoord) {
++requested; return tileCoord.join('/');
if (tileCoord.toString() == '5,13,-29') {
return tileCoord.join('/');
}
} }
function tileLoadFunction(tile, src) { function tileLoadFunction(tile, src) {
@@ -286,11 +282,10 @@ describe('ol.source.VectorTile', function () {
document.body.removeChild(target); document.body.removeChild(target);
}); });
it('loads available tiles', function (done) { it('loads only required tiles', function (done) {
map.renderSync(); map.renderSync();
setTimeout(function () { setTimeout(function () {
expect(requested).to.be.greaterThan(1); expect(loaded).to.eql(['5/13/-28']);
expect(loaded).to.eql(['5/13/-29']);
done(); done();
}, 0); }, 0);
}); });
@@ -63,6 +63,7 @@ describe('ol.VectorRenderTile', function () {
}); });
it("only loads tiles within the source tileGrid's extent", function (done) { it("only loads tiles within the source tileGrid's extent", function (done) {
let tile;
const url = 'spec/ol/data/point.json'; const url = 'spec/ol/data/point.json';
const source = new VectorTileSource({ const source = new VectorTileSource({
projection: 'EPSG:4326', projection: 'EPSG:4326',
@@ -77,8 +78,12 @@ describe('ol.VectorRenderTile', function () {
}, },
url: url, url: url,
}); });
const tile = source.getTile(0, 0, 0, 1, source.getProjection());
tile = source.getTile(0, 0, 0, 1, source.getProjection());
expect(tile.getState()).to.be(TileState.EMPTY);
tile = source.getTile(0, 16, 9, 1, source.getProjection());
expect(tile.getState()).to.be(TileState.IDLE);
tile.load(); tile.load();
const key = listen(tile, EventType.CHANGE, function () { const key = listen(tile, EventType.CHANGE, function () {
if (tile.getState() === TileState.LOADED) { if (tile.getState() === TileState.LOADED) {