Merge pull request #12731 from ahocevar/user-resolution

Handle resolution and tile loadingstrategy with user projection
This commit is contained in:
Andreas Hocevar
2021-09-10 17:52:48 +02:00
committed by GitHub
8 changed files with 206 additions and 9 deletions

View File

@@ -2,6 +2,8 @@
* @module ol/loadingstrategy
*/
import {fromUserExtent, fromUserResolution, toUserExtent} from './proj.js';
/**
* Strategy function for loading all features with a single request.
* @param {import("./extent.js").Extent} extent Extent.
@@ -28,7 +30,7 @@ export function bbox(extent, resolution) {
/**
* Creates a strategy function for loading features based on a tile grid.
* @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.
* @return {function(import("./extent.js").Extent, number): Array<import("./extent.js").Extent>} Loading strategy.
* @return {function(import("./extent.js").Extent, number, import("./proj.js").Projection): Array<import("./extent.js").Extent>} Loading strategy.
* @api
*/
export function tile(tileGrid) {
@@ -36,11 +38,17 @@ export function tile(tileGrid) {
/**
* @param {import("./extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {import("./proj.js").Projection} projection Projection.
* @return {Array<import("./extent.js").Extent>} Extents.
*/
function (extent, resolution) {
const z = tileGrid.getZForResolution(resolution);
const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
function (extent, resolution, projection) {
const z = tileGrid.getZForResolution(
fromUserResolution(resolution, projection)
);
const tileRange = tileGrid.getTileRangeForExtentAndZ(
fromUserExtent(extent, projection),
z
);
/** @type {Array<import("./extent.js").Extent>} */
const extents = [];
/** @type {import("./tilecoord.js").TileCoord} */
@@ -55,7 +63,9 @@ export function tile(tileGrid) {
tileCoord[2] <= tileRange.maxY;
++tileCoord[2]
) {
extents.push(tileGrid.getTileCoordExtent(tileCoord));
extents.push(
toUserExtent(tileGrid.getTileCoordExtent(tileCoord), projection)
);
}
}
return extents;

View File

@@ -631,6 +631,44 @@ export function fromUserExtent(extent, destProjection) {
return transformExtent(extent, userProjection, destProjection);
}
/**
* Return the resolution in user projection units per pixel. If no user projection
* is set, or source or user projection are missing units, the original resolution
* is returned.
* @param {number} resolution Resolution in input projection units per pixel.
* @param {ProjectionLike} sourceProjection The input projection.
* @return {number} Resolution in user projection units per pixel.
*/
export function toUserResolution(resolution, sourceProjection) {
if (!userProjection) {
return resolution;
}
const sourceUnits = get(sourceProjection).getUnits();
const userUnits = userProjection.getUnits();
return sourceUnits && userUnits
? (resolution * METERS_PER_UNIT[sourceUnits]) / METERS_PER_UNIT[userUnits]
: resolution;
}
/**
* Return the resolution in user projection units per pixel. If no user projection
* is set, or source or user projection are missing units, the original resolution
* is returned.
* @param {number} resolution Resolution in user projection units per pixel.
* @param {ProjectionLike} destProjection The destination projection.
* @return {number} Resolution in destination projection units per pixel.
*/
export function fromUserResolution(resolution, destProjection) {
if (!userProjection) {
return resolution;
}
const sourceUnits = get(destProjection).getUnits();
const userUnits = userProjection.getUnits();
return sourceUnits && userUnits
? (resolution * METERS_PER_UNIT[userUnits]) / METERS_PER_UNIT[sourceUnits]
: resolution;
}
/**
* Creates a safe coordinate transform function from a coordinate transform function.
* "Safe" means that it can handle wrapping of x-coordinates for global projections,

View File

@@ -36,6 +36,7 @@ import {
getTransformFromProjections,
getUserProjection,
toUserExtent,
toUserResolution,
} from '../../proj.js';
import {getUid} from '../../util.js';
import {wrapX as wrapCoordinateX} from '../../coordinate.js';
@@ -642,9 +643,11 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
let userTransform;
if (userProjection) {
for (let i = 0, ii = loadExtents.length; i < ii; ++i) {
const extent = loadExtents[i];
const userExtent = toUserExtent(extent, projection);
vectorSource.loadFeatures(
toUserExtent(loadExtents[i], projection),
resolution,
userExtent,
toUserResolution(resolution, projection),
userProjection
);
}

View File

@@ -26,7 +26,7 @@ import {xhr} from '../featureloader.js';
* returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this
* is one of the standard {@link module:ol/loadingstrategy} strategies.
*
* @typedef {function(import("../extent.js").Extent, number): Array<import("../extent.js").Extent>} LoadingStrategy
* @typedef {function(import("../extent.js").Extent, number, import("../proj/Projection.js").default): Array<import("../extent.js").Extent>} LoadingStrategy
* @api
*/
@@ -939,7 +939,7 @@ class VectorSource extends Source {
*/
loadFeatures(extent, resolution, projection) {
const loadedExtentsRtree = this.loadedExtentsRtree_;
const extentsToLoad = this.strategy_(extent, resolution);
const extentsToLoad = this.strategy_(extent, resolution, projection);
for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
const extentToLoad = extentsToLoad[i];
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(