ol
Version:
OpenLayers mapping library
122 lines (109 loc) • 4.42 kB
JavaScript
/**
* @module ol/source/ogcMapUtil
*/
import {decode} from '../Image.js';
import {getHeight, getWidth} from '../extent.js';
import {round} from '../math.js';
import {get as getProjection} from '../proj.js';
import {appendParams} from '../uri.js';
import {getRequestExtent} from './Image.js';
import {DECIMALS} from './common.js';
/**
* @param {string} baseUrl Base URL.
* @param {import("../extent.js").Extent} extent Extent.
* @param {import("../size.js").Size} size Size.
* @param {import("../proj/Projection.js").default} projection Projection.
* @param {Object} params OGC Map params. Will be modified in place.
* @return {string} Request URL.
*/
export function getRequestUrl(baseUrl, extent, size, projection, params) {
params['width'] = size[0];
params['height'] = size[1];
const axisOrientation = projection.getAxisOrientation();
params['crs'] = projection.getCode();
params['bbox-crs'] = projection.getCode();
const bbox = axisOrientation.startsWith('ne')
? [extent[1], extent[0], extent[3], extent[2]]
: extent;
params['bbox'] = bbox.join(',');
return appendParams(baseUrl, params);
}
/**
* @param {import("../extent").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio pixel ratio.
* @param {import("../proj.js").Projection} projection Projection.
* @param {string} url OGC Map service url.
* @param {Object} params OGC Map params.
* @return {string} Image src.
*/
export function getImageSrc(
extent,
resolution,
pixelRatio,
projection,
url,
params,
) {
params = Object.assign({}, params);
const imageResolution = resolution / pixelRatio;
const imageSize = [
round(getWidth(extent) / imageResolution, DECIMALS),
round(getHeight(extent) / imageResolution, DECIMALS),
];
if (pixelRatio !== 1) {
params['mm-per-pixel'] = 0.28 / pixelRatio;
}
return getRequestUrl(url, extent, imageSize, projection, params);
}
/**
* @typedef {Object} LoaderOptions
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
* @property {ReferrerPolicy} [referrerPolicy] The `referrerPolicy` property for loaded images.
* @property {boolean} [hidpi=true] Use the `ol/Map#pixelRatio` value when requesting
* the image from the remote server.
* @property {Object<string,*>} [params] OGC Map request parameters.
* No param is required by default. `width`, `height`, `bbox`, `crs` and `bbox-crs` will be set dynamically.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is 'EPSG:3857'.
* @property {number} [ratio=1.5] Ratio. `1` means image requests are the size of the map viewport, `2` means
* twice the width and height of the map viewport, and so on. Must be `1` or higher.
* @property {string} url OGC Map service URL.
* @property {function(HTMLImageElement, string): Promise<import('../DataTile.js').ImageLike>} [load] Function
* to perform loading of the image. Receives the created `HTMLImageElement` and the desired `src` as argument and
* returns a promise resolving to the loaded or decoded image. Default is {@link module:ol/Image.decode}.
*/
/**
* Creates a loader for OGC Map images.
* @param {LoaderOptions} options Loader options.
* @return {import("../Image.js").ImageObjectPromiseLoader} Loader.
* @api
*/
export function createLoader(options) {
const hidpi = options.hidpi === undefined ? true : options.hidpi;
const projection = getProjection(options.projection || 'EPSG:3857');
const ratio = options.ratio || 1.5;
const load = options.load || decode;
const crossOrigin = options.crossOrigin ?? null;
return (extent, resolution, pixelRatio) => {
extent = getRequestExtent(extent, resolution, pixelRatio, ratio);
if (pixelRatio !== 1 && !hidpi) {
pixelRatio = 1;
}
const src = getImageSrc(
extent,
resolution,
pixelRatio,
projection,
options.url,
options.params,
);
const image = new Image();
image.crossOrigin = crossOrigin;
if (options.referrerPolicy !== undefined) {
image.referrerPolicy = options.referrerPolicy;
}
return load(image, src).then((image) => ({image, extent, pixelRatio}));
};
}