diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md
index 50a571b98f..9a5195e351 100644
--- a/changelog/upgrade-notes.md
+++ b/changelog/upgrade-notes.md
@@ -1,5 +1,29 @@
## Upgrade notes
+### Next
+
+#### New `interpolate` option for sources
+
+Sources now have an `interpolate` option. This option controls whether data from the source is interpolated when resampling.
+
+For `ol/source/DataTile` sources, the default is `interpolate: false`. This means that when a data tile source is used with a WebGL tile layer renderer, your style expression will have access to pixel values in the data tiles without interpolation. If this option is set to true, linear interpolation will be used when over- or under-sampling the data.
+
+#### Deprecation of the `imageSmoothing` option for sources
+
+The `imageSmoothing` option for sources has been deprecated and will be removed in the next major release. Use the `interpolate` option instead.
+
+```js
+// if you were using `imageSmoothing`
+const before = new TileSource({
+ imageSmoothing: false
+});
+
+// use the `interpolate` option instead
+const after = new TileSource({
+ interpolate: false
+});
+```
+
### v6.9.0
There should be nothing special required when upgrading from v6.8 to v6.9.
diff --git a/examples/disable-image-smoothing.css b/examples/interpolation.css
similarity index 100%
rename from examples/disable-image-smoothing.css
rename to examples/interpolation.css
diff --git a/examples/disable-image-smoothing.html b/examples/interpolation.html
similarity index 52%
rename from examples/disable-image-smoothing.html
rename to examples/interpolation.html
index 39a452daa6..65ff446f6a 100644
--- a/examples/disable-image-smoothing.html
+++ b/examples/interpolation.html
@@ -1,22 +1,22 @@
---
layout: example.html
-title: Disable Image Smoothing
-shortdesc: Example of disabling image smoothing
+title: Interpolation
+shortdesc: Example of data interpolation
docs: >
- Example of disabling image smoothing when using raster DEM (digital elevation model) data.
- The imageSmoothing: false setting is used to disable canvas image smoothing during
+ Example of data resampling when using raster DEM (digital elevation model) data.
+ The interpolate: false setting is used to disable interpolation of data values during
reprojection and rendering. Elevation data is
calculated from the pixel value returned by forEachLayerAtPixel . For comparison a second map
- with smoothing enabled returns inaccuate elevations which are very noticeable close to 3107 meters
+ with interpolation enabled returns inaccuate elevations which are very noticeable close to 3107 meters
due to how elevation is calculated from the pixel value.
-tags: "disable image smoothing, xyz, maptiler, reprojection"
+tags: "disable image interpolation, xyz, maptiler, reprojection"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/
---
-
Smoothing Disabled
+
Not Interpolated
@@ -24,16 +24,9 @@ cloak:
0.0 meters
-
-
- Imagery opacity
-
- %
-
-
-
Uncorrected Comparison
+
Interpolated
diff --git a/examples/disable-image-smoothing.js b/examples/interpolation.js
similarity index 62%
rename from examples/disable-image-smoothing.js
rename to examples/interpolation.js
index 41318fbcea..b4ca91872f 100644
--- a/examples/disable-image-smoothing.js
+++ b/examples/interpolation.js
@@ -8,7 +8,7 @@ const attributions =
'© MapTiler ' +
'© OpenStreetMap contributors ';
-const disabledLayer = new TileLayer({
+const notInterpolated = new TileLayer({
// specify className so forEachLayerAtPixel can distinguish layers
className: 'ol-layer-dem',
source: new XYZ({
@@ -18,21 +18,11 @@ const disabledLayer = new TileLayer({
tileSize: 512,
maxZoom: 12,
crossOrigin: '',
- imageSmoothing: false,
+ interpolate: false,
}),
});
-const imagery = new TileLayer({
- className: 'ol-layer-imagery',
- source: new XYZ({
- attributions: attributions,
- url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
- maxZoom: 20,
- crossOrigin: '',
- }),
-});
-
-const enabledLayer = new TileLayer({
+const interpolated = new TileLayer({
source: new XYZ({
attributions: attributions,
url:
@@ -43,30 +33,6 @@ const enabledLayer = new TileLayer({
}),
});
-imagery.on('prerender', function (evt) {
- // use opaque background to conceal DEM while fully opaque imagery renders
- if (imagery.getOpacity() === 1) {
- evt.context.fillStyle = 'white';
- evt.context.fillRect(
- 0,
- 0,
- evt.context.canvas.width,
- evt.context.canvas.height
- );
- }
-});
-
-const control = document.getElementById('opacity');
-const output = document.getElementById('output');
-const listener = function () {
- output.innerText = control.value;
- imagery.setOpacity(control.value / 100);
-};
-control.addEventListener('input', listener);
-control.addEventListener('change', listener);
-output.innerText = control.value;
-imagery.setOpacity(control.value / 100);
-
const view = new View({
center: [6.893, 45.8295],
zoom: 16,
@@ -75,13 +41,13 @@ const view = new View({
const map1 = new Map({
target: 'map1',
- layers: [disabledLayer, imagery],
+ layers: [notInterpolated],
view: view,
});
const map2 = new Map({
target: 'map2',
- layers: [enabledLayer],
+ layers: [interpolated],
view: view,
});
@@ -101,7 +67,7 @@ const showElevations = function (evt) {
},
{
layerFilter: function (layer) {
- return layer === disabledLayer;
+ return layer === notInterpolated;
},
}
);
@@ -114,7 +80,7 @@ const showElevations = function (evt) {
},
{
layerFilter: function (layer) {
- return layer === enabledLayer;
+ return layer === interpolated;
},
}
);
diff --git a/examples/reprojection-image.html b/examples/reprojection-image.html
index c4bb7cfa0b..dc04776b56 100644
--- a/examples/reprojection-image.html
+++ b/examples/reprojection-image.html
@@ -8,6 +8,6 @@ tags: "reprojection, projection, proj4js, image, imagestatic"
---
-
- Image smoothing
+
+ Interpolate
diff --git a/examples/reprojection-image.js b/examples/reprojection-image.js
index 24879205cd..20734b0421 100644
--- a/examples/reprojection-image.js
+++ b/examples/reprojection-image.js
@@ -34,7 +34,7 @@ const map = new Map({
}),
});
-const imageSmoothing = document.getElementById('imageSmoothing');
+const interpolate = document.getElementById('interpolate');
function setSource() {
const source = new Static({
@@ -44,10 +44,10 @@ function setSource() {
crossOrigin: '',
projection: 'EPSG:27700',
imageExtent: imageExtent,
- imageSmoothing: imageSmoothing.checked,
+ interpolate: interpolate.checked,
});
imageLayer.setSource(source);
}
setSource();
-imageSmoothing.addEventListener('change', setSource);
+interpolate.addEventListener('change', setSource);
diff --git a/src/ol/DataTile.js b/src/ol/DataTile.js
index 8f40b3fbb8..ecd9fc6509 100644
--- a/src/ol/DataTile.js
+++ b/src/ol/DataTile.js
@@ -13,9 +13,11 @@ import TileState from './TileState.js';
/**
* @typedef {Object} Options
* @property {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
- * @property {function() : Promise} loader Data loader.
+ * @property {function(): Promise} loader Data loader.
* @property {number} [transition=250] A duration for tile opacity
* transitions in milliseconds. A duration of 0 disables the opacity transition.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
* @api
*/
@@ -26,10 +28,27 @@ class DataTile extends Tile {
constructor(options) {
const state = TileState.IDLE;
- super(options.tileCoord, state, {transition: options.transition});
+ super(options.tileCoord, state, {
+ transition: options.transition,
+ interpolate: options.interpolate,
+ });
+ /**
+ * @type {function(): Promise}
+ * @private
+ */
this.loader_ = options.loader;
+
+ /**
+ * @type {Data}
+ * @private
+ */
this.data_ = null;
+
+ /**
+ * @type {Error}
+ * @private
+ */
this.error_ = null;
}
diff --git a/src/ol/Tile.js b/src/ol/Tile.js
index e9d78edcac..feb1097f3c 100644
--- a/src/ol/Tile.js
+++ b/src/ol/Tile.js
@@ -63,6 +63,8 @@ import {easeIn} from './easing.js';
* @typedef {Object} Options
* @property {number} [transition=250] A duration for tile opacity
* transitions in milliseconds. A duration of 0 disables the opacity transition.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
* @api
*/
@@ -123,6 +125,11 @@ class Tile extends EventTarget {
* @type {Object}
*/
this.transitionStarts_ = {};
+
+ /**
+ * @type {boolean}
+ */
+ this.interpolate = !!options.interpolate;
}
/**
diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js
index be4c241811..663b9df498 100644
--- a/src/ol/renderer/canvas/ImageLayer.js
+++ b/src/ol/renderer/canvas/ImageLayer.js
@@ -4,6 +4,7 @@
import CanvasLayerRenderer from './Layer.js';
import ViewHint from '../../ViewHint.js';
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
+import {IMAGE_SMOOTHING_DISABLED} from './common.js';
import {assign} from '../../obj.js';
import {compose as composeTransform, makeInverse} from '../../transform.js';
import {containsExtent, intersects as intersectsExtent} from '../../extent.js';
@@ -179,7 +180,10 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
const dw = img.width * transform[0];
const dh = img.height * transform[3];
- assign(context, this.getLayer().getSource().getContextOptions());
+ if (!this.getLayer().getSource().getInterpolate()) {
+ assign(context, IMAGE_SMOOTHING_DISABLED);
+ }
+
this.preRender(context, frameState);
if (render && dw >= 0.5 && dh >= 0.5) {
const dx = transform[4];
diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js
index e68f3d04af..e8f74a66c9 100644
--- a/src/ol/renderer/canvas/TileLayer.js
+++ b/src/ol/renderer/canvas/TileLayer.js
@@ -4,6 +4,7 @@
import CanvasLayerRenderer from './Layer.js';
import TileRange from '../../TileRange.js';
import TileState from '../../TileState.js';
+import {IMAGE_SMOOTHING_DISABLED} from './common.js';
import {
apply as applyTransform,
compose as composeTransform,
@@ -317,7 +318,10 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
this.clipUnrotated(context, frameState, layerExtent);
}
- assign(context, tileSource.getContextOptions());
+ if (!tileSource.getInterpolate()) {
+ assign(context, IMAGE_SMOOTHING_DISABLED);
+ }
+
this.preRender(context, frameState);
this.renderedTiles.length = 0;
diff --git a/src/ol/renderer/canvas/common.js b/src/ol/renderer/canvas/common.js
new file mode 100644
index 0000000000..0fa7034ccb
--- /dev/null
+++ b/src/ol/renderer/canvas/common.js
@@ -0,0 +1,12 @@
+/**
+ * @module ol/renderer/canvas/common
+ */
+
+/**
+ * Context options to disable image smoothing.
+ * @type {Object}
+ */
+export const IMAGE_SMOOTHING_DISABLED = {
+ imageSmoothingEnabled: false,
+ msImageSmoothingEnabled: false,
+};
diff --git a/src/ol/reproj.js b/src/ol/reproj.js
index 00f9536c99..8b9a011d2a 100644
--- a/src/ol/reproj.js
+++ b/src/ol/reproj.js
@@ -1,7 +1,7 @@
/**
* @module ol/reproj
*/
-import {IMAGE_SMOOTHING_DISABLED} from './source/common.js';
+import {IMAGE_SMOOTHING_DISABLED} from './renderer/canvas/common.js';
import {assign} from './obj.js';
import {
containsCoordinate,
@@ -198,7 +198,7 @@ export function calculateSourceExtentResolution(
* @param {Array} sources Array of sources.
* @param {number} gutter Gutter of the sources.
* @param {boolean} [opt_renderEdges] Render reprojection edges.
- * @param {object} [opt_contextOptions] Properties to set on the canvas context.
+ * @param {object} [opt_interpolate] Use linear interpolation when resampling.
* @return {HTMLCanvasElement} Canvas with reprojected data.
*/
export function render(
@@ -213,13 +213,16 @@ export function render(
sources,
gutter,
opt_renderEdges,
- opt_contextOptions
+ opt_interpolate
) {
const context = createCanvasContext2D(
Math.round(pixelRatio * width),
Math.round(pixelRatio * height)
);
- assign(context, opt_contextOptions);
+
+ if (!opt_interpolate) {
+ assign(context, IMAGE_SMOOTHING_DISABLED);
+ }
if (sources.length === 0) {
return context.canvas;
@@ -244,7 +247,10 @@ export function render(
Math.round((pixelRatio * canvasWidthInUnits) / sourceResolution),
Math.round((pixelRatio * canvasHeightInUnits) / sourceResolution)
);
- assign(stitchContext, opt_contextOptions);
+
+ if (!opt_interpolate) {
+ assign(stitchContext, IMAGE_SMOOTHING_DISABLED);
+ }
const stitchScale = pixelRatio / sourceResolution;
@@ -341,10 +347,7 @@ export function render(
context.save();
context.beginPath();
- if (
- isBrokenDiagonalRendering() ||
- opt_contextOptions === IMAGE_SMOOTHING_DISABLED
- ) {
+ if (isBrokenDiagonalRendering() || !opt_interpolate) {
// Make sure that all lines are horizontal or vertical
context.moveTo(u1, v1);
// This is the diagonal line. Do it in 4 steps
diff --git a/src/ol/reproj/Image.js b/src/ol/reproj/Image.js
index 012007f6ac..4cec8c8cbe 100644
--- a/src/ol/reproj/Image.js
+++ b/src/ol/reproj/Image.js
@@ -32,7 +32,7 @@ class ReprojImage extends ImageBase {
* @param {number} pixelRatio Pixel ratio.
* @param {FunctionType} getImageFunction
* Function returning source images (extent, resolution, pixelRatio).
- * @param {object} [opt_contextOptions] Properties to set on the canvas context.
+ * @param {boolean} interpolate Use linear interpolation when resampling.
*/
constructor(
sourceProj,
@@ -41,7 +41,7 @@ class ReprojImage extends ImageBase {
targetResolution,
pixelRatio,
getImageFunction,
- opt_contextOptions
+ interpolate
) {
const maxSourceExtent = sourceProj.getExtent();
const maxTargetExtent = targetProj.getExtent();
@@ -124,9 +124,9 @@ class ReprojImage extends ImageBase {
/**
* @private
- * @type {object}
+ * @type {boolean}
*/
- this.contextOptions_ = opt_contextOptions;
+ this.interpolate_ = interpolate;
/**
* @private
@@ -191,7 +191,7 @@ class ReprojImage extends ImageBase {
],
0,
undefined,
- this.contextOptions_
+ this.interpolate_
);
}
this.state = sourceState;
diff --git a/src/ol/reproj/Tile.js b/src/ol/reproj/Tile.js
index a44fcba169..1be2fb2d28 100644
--- a/src/ol/reproj/Tile.js
+++ b/src/ol/reproj/Tile.js
@@ -39,7 +39,7 @@ class ReprojTile extends Tile {
* Function returning source tiles (z, x, y, pixelRatio).
* @param {number} [opt_errorThreshold] Acceptable reprojection error (in px).
* @param {boolean} [opt_renderEdges] Render reprojection edges.
- * @param {object} [opt_contextOptions] Properties to set on the canvas context.
+ * @param {boolean} [opt_interpolate] Use linear interpolation when resampling.
*/
constructor(
sourceProj,
@@ -53,9 +53,9 @@ class ReprojTile extends Tile {
getTileFunction,
opt_errorThreshold,
opt_renderEdges,
- opt_contextOptions
+ opt_interpolate
) {
- super(tileCoord, TileState.IDLE);
+ super(tileCoord, TileState.IDLE, {interpolate: !!opt_interpolate});
/**
* @private
@@ -63,12 +63,6 @@ class ReprojTile extends Tile {
*/
this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;
- /**
- * @private
- * @type {object}
- */
- this.contextOptions_ = opt_contextOptions;
-
/**
* @private
* @type {number}
@@ -272,6 +266,7 @@ class ReprojTile extends Tile {
const targetExtent = this.targetTileGrid_.getTileCoordExtent(
this.wrappedTileCoord_
);
+
this.canvas_ = renderReprojected(
width,
height,
@@ -284,7 +279,7 @@ class ReprojTile extends Tile {
sources,
this.gutter_,
this.renderEdges_,
- this.contextOptions_
+ this.interpolate
);
this.state = TileState.LOADED;
diff --git a/src/ol/source/BingMaps.js b/src/ol/source/BingMaps.js
index 63c2912d18..abd03d8354 100644
--- a/src/ol/source/BingMaps.js
+++ b/src/ol/source/BingMaps.js
@@ -53,7 +53,9 @@ const TOS_ATTRIBUTION =
* @property {string} [culture='en-us'] Culture code.
* @property {string} key Bing Maps API key. Get yours at https://www.bingmapsportal.com/.
* @property {string} imagerySet Type of imagery.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {number} [maxZoom=21] Max zoom. Default is what's advertized by the BingMaps service.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
* Higher values can increase reprojection performance, but decrease precision.
@@ -120,10 +122,16 @@ class BingMaps extends TileImage {
constructor(options) {
const hidpi = options.hidpi !== undefined ? options.hidpi : false;
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
cacheSize: options.cacheSize,
crossOrigin: 'anonymous',
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
opaque: true,
projection: getProjection('EPSG:3857'),
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
diff --git a/src/ol/source/DataTile.js b/src/ol/source/DataTile.js
index 5b3cf452c1..207015c6bb 100644
--- a/src/ol/source/DataTile.js
+++ b/src/ol/source/DataTile.js
@@ -34,6 +34,8 @@ import {toPromise} from '../functions.js';
* @property {boolean} [wrapX=false] Render tiles beyond the antimeridian.
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
* @property {number} [bandCount=4] Number of bands represented in the data.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
*/
/**
@@ -71,6 +73,7 @@ class DataTileSource extends TileSource {
tilePixelRatio: options.tilePixelRatio,
wrapX: options.wrapX,
transition: options.transition,
+ interpolate: options.interpolate,
});
/**
diff --git a/src/ol/source/GeoTIFF.js b/src/ol/source/GeoTIFF.js
index aca900f779..99a733b7cd 100644
--- a/src/ol/source/GeoTIFF.js
+++ b/src/ol/source/GeoTIFF.js
@@ -315,6 +315,8 @@ function getMaxForDataType(array) {
* @property {number} [transition=250] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`.
* @property {boolean} [wrapX=false] Render tiles beyond the tile grid extent.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * the linear interpolation is used to resample the data. If false, nearest neighbor is used.
*/
/**
@@ -333,6 +335,7 @@ class GeoTIFFSource extends DataTile {
projection: null,
opaque: options.opaque,
transition: options.transition,
+ interpolate: options.interpolate !== false,
wrapX: options.wrapX,
});
diff --git a/src/ol/source/IIIF.js b/src/ol/source/IIIF.js
index 4eaecbcac2..419947ceb4 100644
--- a/src/ol/source/IIIF.js
+++ b/src/ol/source/IIIF.js
@@ -20,7 +20,9 @@ import {toSize} from '../size.js';
* @property {null|string} [crossOrigin] The value for the crossOrigin option of the request.
* @property {import("../extent.js").Extent} [extent=[0, -height, width, 0]] The extent.
* @property {string} [format='jpg'] Requested image format.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../proj.js").ProjectionLike} [projection] Projection.
* @property {string} [quality] Requested IIIF image quality. Default is 'native'
* for version 1, 'default' for versions 2 and 3.
@@ -69,6 +71,12 @@ class IIIF extends TileImage {
*/
const options = opt_options || {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
let baseUrl = options.url || '';
baseUrl =
baseUrl +
@@ -333,7 +341,7 @@ class IIIF extends TileImage {
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: options.state,
diff --git a/src/ol/source/Image.js b/src/ol/source/Image.js
index 9112078ad8..914f0ab77b 100644
--- a/src/ol/source/Image.js
+++ b/src/ol/source/Image.js
@@ -6,7 +6,6 @@ import ImageState from '../ImageState.js';
import ReprojImage from '../reproj/Image.js';
import Source from './Source.js';
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
-import {IMAGE_SMOOTHING_DISABLED} from './common.js';
import {abstract} from '../util.js';
import {equals} from '../extent.js';
import {equivalent} from '../proj.js';
@@ -76,7 +75,9 @@ export class ImageSourceEvent extends Event {
/**
* @typedef {Object} Options
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../proj.js").ProjectionLike} [projection] Projection.
* @property {Array} [resolutions] Resolutions.
* @property {import("./State.js").default} [state] State.
@@ -96,10 +97,17 @@ class ImageSource extends Source {
* @param {Options} options Single image source options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
projection: options.projection,
state: options.state,
+ interpolate: interpolate,
});
/***
@@ -135,13 +143,6 @@ class ImageSource extends Source {
* @type {number}
*/
this.reprojectedRevision_ = 0;
-
- /**
- * @private
- * @type {object|undefined}
- */
- this.contextOptions_ =
- options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;
}
/**
@@ -151,13 +152,6 @@ class ImageSource extends Source {
return this.resolutions_;
}
- /**
- * @return {Object|undefined} Context options.
- */
- getContextOptions() {
- return this.contextOptions_;
- }
-
/**
* @protected
* @param {number} resolution Resolution.
@@ -218,7 +212,7 @@ class ImageSource extends Source {
sourceProjection
);
}.bind(this),
- this.contextOptions_
+ this.getInterpolate()
);
this.reprojectedRevision_ = this.getRevision();
diff --git a/src/ol/source/ImageArcGISRest.js b/src/ol/source/ImageArcGISRest.js
index 518a560387..10c17c6815 100644
--- a/src/ol/source/ImageArcGISRest.js
+++ b/src/ol/source/ImageArcGISRest.js
@@ -20,7 +20,9 @@ import {containsExtent, getHeight, getWidth} from '../extent.js';
* the remote server.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given
* a URL.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {Object} [params] ArcGIS Rest parameters. This field is optional. Service
* defaults will be used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is
* `IMAGE` by default. `TRANSPARENT` is `true` by default. `BBOX`, `SIZE`, `BBOXSR`, and `IMAGESR`
@@ -57,9 +59,15 @@ class ImageArcGISRest extends ImageSource {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
resolutions: options.resolutions,
});
diff --git a/src/ol/source/ImageCanvas.js b/src/ol/source/ImageCanvas.js
index c1ff2d8d26..2ad1eff348 100644
--- a/src/ol/source/ImageCanvas.js
+++ b/src/ol/source/ImageCanvas.js
@@ -36,7 +36,9 @@ import {
* the value returned by the function is later changed then
* `changed` should be called on the source for the source to
* invalidate the current cached image. See: {@link module:ol/Observable~Observable#changed}
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {number} [ratio=1.5] Ratio. 1 means canvases 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.
@@ -57,9 +59,15 @@ class ImageCanvasSource extends ImageSource {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
resolutions: options.resolutions,
state: options.state,
diff --git a/src/ol/source/ImageMapGuide.js b/src/ol/source/ImageMapGuide.js
index e4a0ff56af..e60281982e 100644
--- a/src/ol/source/ImageMapGuide.js
+++ b/src/ol/source/ImageMapGuide.js
@@ -32,7 +32,9 @@ import {
* @property {Array} [resolutions] Resolutions.
* If specified, requests will be made for these resolutions only.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {Object} [params] Additional parameters.
*/
@@ -48,8 +50,14 @@ class ImageMapGuide extends ImageSource {
* @param {Options} options ImageMapGuide options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
resolutions: options.resolutions,
});
diff --git a/src/ol/source/ImageStatic.js b/src/ol/source/ImageStatic.js
index e002557efc..95c30c808f 100644
--- a/src/ol/source/ImageStatic.js
+++ b/src/ol/source/ImageStatic.js
@@ -6,6 +6,7 @@ import EventType from '../events/EventType.js';
import ImageSource, {defaultImageLoadFunction} from './Image.js';
import ImageState from '../ImageState.js';
import ImageWrapper from '../Image.js';
+import {IMAGE_SMOOTHING_DISABLED} from '../renderer/canvas/common.js';
import {assign} from '../obj.js';
import {createCanvasContext2D} from '../dom.js';
import {getHeight, getWidth, intersects} from '../extent.js';
@@ -20,7 +21,9 @@ import {get as getProjection} from '../proj.js';
* @property {import("../extent.js").Extent} [imageExtent] Extent of the image in map coordinates.
* This is the [left, bottom, right, top] map coordinates of your image.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {import("../size.js").Size} [imageSize] Size of the image in pixels. Usually the image size is auto-detected, so this
* only needs to be set if auto-detection fails for some reason.
@@ -45,9 +48,15 @@ class Static extends ImageSource {
? options.imageLoadFunction
: defaultImageLoadFunction;
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: getProjection(options.projection),
});
@@ -148,7 +157,9 @@ class Static extends ImageSource {
}
if (targetWidth !== imageWidth || targetHeight !== imageHeight) {
const context = createCanvasContext2D(targetWidth, targetHeight);
- assign(context, this.getContextOptions());
+ if (!this.getInterpolate()) {
+ assign(context, IMAGE_SMOOTHING_DISABLED);
+ }
const canvas = context.canvas;
context.drawImage(
image,
diff --git a/src/ol/source/ImageWMS.js b/src/ol/source/ImageWMS.js
index 4d0aaef839..4afe0e0e5d 100644
--- a/src/ol/source/ImageWMS.js
+++ b/src/ol/source/ImageWMS.js
@@ -46,7 +46,9 @@ const GETFEATUREINFO_IMAGE_SIZE = [101, 101];
* @property {import("./WMSServerType.js").default|string} [serverType] The type of
* the remote WMS server: `mapserver`, `geoserver` or `qgis`. Only needed if `hidpi` is `true`.
* @property {import("../Image.js").LoadFunction} [imageLoadFunction] Optional function to load an image given a URL.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {Object} params WMS request parameters.
* At least a `LAYERS` param is required. `STYLES` is
* `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX`
@@ -74,9 +76,15 @@ class ImageWMS extends ImageSource {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
resolutions: options.resolutions,
});
diff --git a/src/ol/source/OGCMapTile.js b/src/ol/source/OGCMapTile.js
index 6b1e557db8..d9f5be644f 100644
--- a/src/ol/source/OGCMapTile.js
+++ b/src/ol/source/OGCMapTile.js
@@ -20,7 +20,9 @@ import {getTileSetInfo} from './ogcTileUtil.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
* Higher values can increase reprojection performance, but decrease precision.
* @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
@@ -45,11 +47,17 @@ class OGCMapTile extends TileImage {
* @param {Options} options OGC map tile options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: SourceState.LOADING,
diff --git a/src/ol/source/OSM.js b/src/ol/source/OSM.js
index e868acc979..91d3907c92 100644
--- a/src/ol/source/OSM.js
+++ b/src/ol/source/OSM.js
@@ -23,7 +23,9 @@ export const ATTRIBUTION =
* @property {null|string} [crossOrigin='anonymous'] 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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {number} [maxZoom=19] Max zoom.
* @property {boolean} [opaque=true] Whether the layer is opaque.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -56,6 +58,12 @@ class OSM extends XYZ {
constructor(opt_options) {
const options = opt_options || {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
let attributions;
if (options.attributions !== undefined) {
attributions = options.attributions;
@@ -76,7 +84,7 @@ class OSM extends XYZ {
attributionsCollapsible: false,
cacheSize: options.cacheSize,
crossOrigin: crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 19,
opaque: options.opaque !== undefined ? options.opaque : true,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
diff --git a/src/ol/source/Source.js b/src/ol/source/Source.js
index 78ff0e2847..1642417d74 100644
--- a/src/ol/source/Source.js
+++ b/src/ol/source/Source.js
@@ -31,6 +31,8 @@ import {get as getProjection} from '../proj.js';
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {import("./State.js").default} [state='ready'] State.
* @property {boolean} [wrapX=false] WrapX.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
*/
/**
@@ -91,6 +93,12 @@ class Source extends BaseObject {
*/
this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;
+ /**
+ * @private
+ * @type {boolean}
+ */
+ this.interpolate_ = !!options.interpolate;
+
/**
* @protected
* @type {function(import("../View.js").ViewOptions):void}
@@ -172,10 +180,10 @@ class Source extends BaseObject {
}
/**
- * @return {Object|undefined} Context options.
+ * @return {boolean} Use linear interpolation when resampling.
*/
- getContextOptions() {
- return undefined;
+ getInterpolate() {
+ return this.interpolate_;
}
/**
diff --git a/src/ol/source/Stamen.js b/src/ol/source/Stamen.js
index bde19902af..ba42733f91 100644
--- a/src/ol/source/Stamen.js
+++ b/src/ol/source/Stamen.js
@@ -87,7 +87,9 @@ const ProviderConfig = {
/**
* @typedef {Object} Options
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.
- * @property {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {string} layer Layer name.
* @property {number} [minZoom] Minimum zoom.
* @property {number} [maxZoom] Maximum zoom.
@@ -119,6 +121,12 @@ class Stamen extends XYZ {
* @param {Options} options Stamen options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
const i = options.layer.indexOf('-');
const provider = i == -1 ? options.layer : options.layer.slice(0, i);
const providerConfig = ProviderConfig[provider];
@@ -137,7 +145,7 @@ class Stamen extends XYZ {
attributions: ATTRIBUTIONS,
cacheSize: options.cacheSize,
crossOrigin: 'anonymous',
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
maxZoom:
options.maxZoom != undefined ? options.maxZoom : providerConfig.maxZoom,
minZoom:
diff --git a/src/ol/source/Tile.js b/src/ol/source/Tile.js
index 03a8038b51..d172824399 100644
--- a/src/ol/source/Tile.js
+++ b/src/ol/source/Tile.js
@@ -38,6 +38,8 @@ import {scale as scaleSize, toSize} from '../size.js';
* @property {number} [transition] Transition.
* @property {string} [key] Key.
* @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0] ZDirection.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
*/
/**
@@ -59,6 +61,7 @@ class TileSource extends Source {
projection: options.projection,
state: options.state,
wrapX: options.wrapX,
+ interpolate: options.interpolate,
});
/***
@@ -122,7 +125,10 @@ class TileSource extends Source {
* @protected
* @type {import("../Tile.js").Options}
*/
- this.tileOptions = {transition: options.transition};
+ this.tileOptions = {
+ transition: options.transition,
+ interpolate: options.interpolate,
+ };
/**
* zDirection hint, read by the renderer. Indicates which resolution should be used
diff --git a/src/ol/source/TileArcGISRest.js b/src/ol/source/TileArcGISRest.js
index 02b2f30aad..55f0d65f3c 100644
--- a/src/ol/source/TileArcGISRest.js
+++ b/src/ol/source/TileArcGISRest.js
@@ -17,7 +17,9 @@ import {hash as tileCoordHash} from '../tilecoord.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {Object} [params] ArcGIS Rest parameters. This field is optional. Service defaults will be
* used for any fields not specified. `FORMAT` is `PNG32` by default. `F` is `IMAGE` by
* default. `TRANSPARENT` is `true` by default. `BBOX`, `SIZE`, `BBOXSR`,
@@ -72,11 +74,17 @@ class TileArcGISRest extends TileImage {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileGrid: options.tileGrid,
diff --git a/src/ol/source/TileImage.js b/src/ol/source/TileImage.js
index 40beffa40f..d49449d469 100644
--- a/src/ol/source/TileImage.js
+++ b/src/ol/source/TileImage.js
@@ -8,7 +8,6 @@ import TileCache from '../TileCache.js';
import TileState from '../TileState.js';
import UrlTile from './UrlTile.js';
import {ENABLE_RASTER_REPROJECTION} from '../reproj/common.js';
-import {IMAGE_SMOOTHING_DISABLED} from './common.js';
import {equivalent, get as getProjection} from '../proj.js';
import {getKey, getKeyZXY} from '../tilecoord.js';
import {getForProjection as getTileGridForProjection} from '../tilegrid.js';
@@ -22,7 +21,9 @@ import {getUid} from '../util.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {boolean} [opaque=false] Whether the layer is opaque.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -70,6 +71,12 @@ class TileImage extends UrlTile {
* @param {!Options} options Image tile options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
@@ -86,6 +93,7 @@ class TileImage extends UrlTile {
urls: options.urls,
wrapX: options.wrapX,
transition: options.transition,
+ interpolate: interpolate,
key: options.key,
attributionsCollapsible: options.attributionsCollapsible,
zDirection: options.zDirection,
@@ -123,13 +131,6 @@ class TileImage extends UrlTile {
*/
this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;
- /**
- * @private
- * @type {object|undefined}
- */
- this.contextOptions_ =
- options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;
-
/**
* @private
* @type {boolean}
@@ -176,13 +177,6 @@ class TileImage extends UrlTile {
}
}
- /**
- * @return {Object|undefined} Context options.
- */
- getContextOptions() {
- return this.contextOptions_;
- }
-
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {number} Gutter.
@@ -212,10 +206,11 @@ class TileImage extends UrlTile {
* @return {string} The key for all tiles.
*/
getKey() {
- return (
- super.getKey() +
- (this.contextOptions_ ? '\n' + JSON.stringify(this.contextOptions_) : '')
- );
+ let key = super.getKey();
+ if (!this.getInterpolate()) {
+ key += ':disable-interpolation';
+ }
+ return key;
}
/**
@@ -365,7 +360,7 @@ class TileImage extends UrlTile {
}.bind(this),
this.reprojectionErrorThreshold_,
this.renderReprojectionEdges_,
- this.contextOptions_
+ this.getInterpolate()
);
newTile.key = key;
diff --git a/src/ol/source/TileJSON.js b/src/ol/source/TileJSON.js
index 33aae2ce4d..b86b413d06 100644
--- a/src/ol/source/TileJSON.js
+++ b/src/ol/source/TileJSON.js
@@ -40,7 +40,9 @@ import {jsonp as requestJSONP} from '../net.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {boolean} [jsonp=false] Use JSONP with callback to load the TileJSON.
* Useful when the server does not support CORS..
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -74,11 +76,17 @@ class TileJSON extends TileImage {
* @param {Options} options TileJSON options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: getProjection('EPSG:3857'),
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: SourceState.LOADING,
diff --git a/src/ol/source/TileWMS.js b/src/ol/source/TileWMS.js
index a41a223564..a1094557df 100644
--- a/src/ol/source/TileWMS.js
+++ b/src/ol/source/TileWMS.js
@@ -25,7 +25,9 @@ import {hash as tileCoordHash} from '../tilecoord.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {Object} params WMS request parameters.
* At least a `LAYERS` param is required. `STYLES` is
* `''` by default. `VERSION` is `1.3.0` by default. `WIDTH`, `HEIGHT`, `BBOX`
@@ -86,6 +88,12 @@ class TileWMS extends TileImage {
constructor(opt_options) {
const options = opt_options ? opt_options : /** @type {Options} */ ({});
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
const params = options.params || {};
const transparent = 'TRANSPARENT' in params ? params['TRANSPARENT'] : true;
@@ -95,7 +103,7 @@ class TileWMS extends TileImage {
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
opaque: !transparent,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
diff --git a/src/ol/source/UrlTile.js b/src/ol/source/UrlTile.js
index db86b77038..1eae6da345 100644
--- a/src/ol/source/UrlTile.js
+++ b/src/ol/source/UrlTile.js
@@ -26,6 +26,8 @@ import {getUid} from '../util.js';
* @property {number} [transition] Transition.
* @property {string} [key] Key.
* @property {number|import("../array.js").NearestDirectionFunction} [zDirection=0] ZDirection.
+ * @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
+ * the nearest neighbor is used when resampling.
*/
/**
@@ -49,6 +51,7 @@ class UrlTile extends TileSource {
tilePixelRatio: options.tilePixelRatio,
wrapX: options.wrapX,
transition: options.transition,
+ interpolate: options.interpolate,
key: options.key,
attributionsCollapsible: options.attributionsCollapsible,
zDirection: options.zDirection,
diff --git a/src/ol/source/WMTS.js b/src/ol/source/WMTS.js
index 4ca3979a6b..b176cd4ed1 100644
--- a/src/ol/source/WMTS.js
+++ b/src/ol/source/WMTS.js
@@ -20,7 +20,9 @@ import {find, findIndex, includes} from '../array.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../tilegrid/WMTS.js").default} tileGrid Tile grid.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -69,6 +71,12 @@ class WMTS extends TileImage {
* @param {Options} options WMTS options.
*/
constructor(options) {
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
// TODO: add support for TileMatrixLimits
const requestEncoding =
@@ -92,7 +100,7 @@ class WMTS extends TileImage {
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileClass: options.tileClass,
diff --git a/src/ol/source/XYZ.js b/src/ol/source/XYZ.js
index 384883c7d7..15b11cb380 100644
--- a/src/ol/source/XYZ.js
+++ b/src/ol/source/XYZ.js
@@ -13,7 +13,9 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
* @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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {boolean} [opaque=false] Whether the layer is opaque.
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -72,6 +74,13 @@ class XYZ extends TileImage {
*/
constructor(opt_options) {
const options = opt_options || {};
+
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
const projection =
options.projection !== undefined ? options.projection : 'EPSG:3857';
@@ -90,7 +99,7 @@ class XYZ extends TileImage {
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
opaque: options.opaque,
projection: projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
diff --git a/src/ol/source/Zoomify.js b/src/ol/source/Zoomify.js
index bf18c5bf46..a7db16dc25 100644
--- a/src/ol/source/Zoomify.js
+++ b/src/ol/source/Zoomify.js
@@ -87,7 +87,9 @@ export class CustomTile extends ImageTile {
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value 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 {boolean} [imageSmoothing=true] Enable image smoothing.
+ * @property {boolean} [imageSmoothing=true] Deprecated. Use the `interpolate` option instead.
+ * @property {boolean} [interpolate=true] Use interpolated values when resampling. By default,
+ * linear interpolation is used when resampling. Set to false to use the nearest neighbor instead.
* @property {import("../proj.js").ProjectionLike} [projection] Projection.
* @property {number} [tilePixelRatio] The pixel ratio used by the tile service. For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px by 512px images (for retina/hidpi devices) then `tilePixelRatio` should be set to `2`
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
@@ -131,6 +133,12 @@ class Zoomify extends TileImage {
constructor(opt_options) {
const options = opt_options;
+ let interpolate =
+ options.imageSmoothing !== undefined ? options.imageSmoothing : true;
+ if (options.interpolate !== undefined) {
+ interpolate = options.interpolate;
+ }
+
const size = options.size;
const tierSizeCalculation =
options.tierSizeCalculation !== undefined
@@ -260,7 +268,7 @@ class Zoomify extends TileImage {
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
- imageSmoothing: options.imageSmoothing,
+ interpolate: interpolate,
projection: options.projection,
tilePixelRatio: tilePixelRatio,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
diff --git a/src/ol/source/common.js b/src/ol/source/common.js
index 4176e1a1a2..ebf0d96808 100644
--- a/src/ol/source/common.js
+++ b/src/ol/source/common.js
@@ -7,12 +7,3 @@
* @type {string}
*/
export const DEFAULT_WMS_VERSION = '1.3.0';
-
-/**
- * Context options to disable image smoothing.
- * @type {Object}
- */
-export const IMAGE_SMOOTHING_DISABLED = {
- imageSmoothingEnabled: false,
- msImageSmoothingEnabled: false,
-};
diff --git a/src/ol/webgl/TileTexture.js b/src/ol/webgl/TileTexture.js
index d67a804d9b..a9a5261382 100644
--- a/src/ol/webgl/TileTexture.js
+++ b/src/ol/webgl/TileTexture.js
@@ -11,21 +11,28 @@ import WebGLArrayBuffer from './Buffer.js';
import {ARRAY_BUFFER, STATIC_DRAW} from '../webgl.js';
import {toSize} from '../size.js';
-function bindAndConfigure(gl, texture) {
+/**
+ * @param {WebGLRenderingContext} gl The WebGL context.
+ * @param {WebGLTexture} texture The texture.
+ * @param {boolean} interpolate Interpolate when resampling.
+ */
+function bindAndConfigure(gl, texture, interpolate) {
+ const resampleFilter = interpolate ? gl.LINEAR : gl.NEAREST;
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, resampleFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, resampleFilter);
}
/**
* @param {WebGLRenderingContext} gl The WebGL context.
* @param {WebGLTexture} texture The texture.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} image The image.
+ * @param {boolean} interpolate Interpolate when resampling.
*/
-function uploadImageTexture(gl, texture, image) {
- bindAndConfigure(gl, texture);
+function uploadImageTexture(gl, texture, image, interpolate) {
+ bindAndConfigure(gl, texture, interpolate);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
}
@@ -36,10 +43,18 @@ function uploadImageTexture(gl, texture, image) {
* @param {import("../DataTile.js").Data} data The pixel data.
* @param {import("../size.js").Size} size The pixel size.
* @param {number} bandCount The band count.
+ * @param {boolean} interpolate Interpolate when resampling.
*/
-function uploadDataTexture(helper, texture, data, size, bandCount) {
+function uploadDataTexture(
+ helper,
+ texture,
+ data,
+ size,
+ bandCount,
+ interpolate
+) {
const gl = helper.getGL();
- bindAndConfigure(gl, texture);
+ bindAndConfigure(gl, texture, interpolate);
const bytesPerRow = data.byteLength / size[1];
let unpackAlignment = 1;
@@ -174,7 +189,7 @@ class TileTexture extends EventTarget {
const texture = gl.createTexture();
this.textures.push(texture);
this.bandCount = 4;
- uploadImageTexture(gl, texture, tile.getImage());
+ uploadImageTexture(gl, texture, tile.getImage(), tile.interpolate);
return;
}
@@ -191,7 +206,14 @@ class TileTexture extends EventTarget {
if (textureCount === 1) {
const texture = gl.createTexture();
this.textures.push(texture);
- uploadDataTexture(helper, texture, data, this.size, this.bandCount);
+ uploadDataTexture(
+ helper,
+ texture,
+ data,
+ this.size,
+ this.bandCount,
+ tile.interpolate
+ );
return;
}
@@ -229,7 +251,14 @@ class TileTexture extends EventTarget {
const texture = this.textures[textureIndex];
const textureData = textureDataArrays[textureIndex];
const bandCount = textureData.length / pixelCount;
- uploadDataTexture(helper, texture, textureData, this.size, bandCount);
+ uploadDataTexture(
+ helper,
+ texture,
+ textureData,
+ this.size,
+ bandCount,
+ tile.interpolate
+ );
}
}
diff --git a/test/browser/spec/ol/source/bingmaps.test.js b/test/browser/spec/ol/source/BingMaps.test.js
similarity index 81%
rename from test/browser/spec/ol/source/bingmaps.test.js
rename to test/browser/spec/ol/source/BingMaps.test.js
index 951699ec80..7195e825a1 100644
--- a/test/browser/spec/ol/source/bingmaps.test.js
+++ b/test/browser/spec/ol/source/BingMaps.test.js
@@ -1,7 +1,7 @@
import BingMaps, {quadKey} from '../../../../../src/ol/source/BingMaps.js';
import {unByKey} from '../../../../../src/ol/Observable.js';
-describe('ol.source.BingMaps', function () {
+describe('ol/source/BingMaps', function () {
describe('quadKey()', function () {
it('returns expected string', function () {
const tileCoord = [3, 3, 5];
@@ -10,6 +10,23 @@ describe('ol.source.BingMaps', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new BingMaps({});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new BingMaps({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new BingMaps({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#tileUrlFunction()', function () {
let source, tileGrid;
diff --git a/test/browser/spec/ol/source/datatile.test.js b/test/browser/spec/ol/source/DataTile.test.js
similarity index 73%
rename from test/browser/spec/ol/source/datatile.test.js
rename to test/browser/spec/ol/source/DataTile.test.js
index 0b3aafd3ef..94beefc616 100644
--- a/test/browser/spec/ol/source/datatile.test.js
+++ b/test/browser/spec/ol/source/DataTile.test.js
@@ -2,7 +2,7 @@ import DataTile from '../../../../../src/ol/DataTile.js';
import DataTileSource from '../../../../../src/ol/source/DataTile.js';
import TileState from '../../../../../src/ol/TileState.js';
-describe('ol.source.DataTile', function () {
+describe('ol/source/DataTile', function () {
/** @type {DataTileSource} */
let source;
beforeEach(function () {
@@ -39,4 +39,16 @@ describe('ol.source.DataTile', function () {
tile.load();
});
});
+
+ describe('#getInterpolate()', function () {
+ it('is false by default', function () {
+ const source = new DataTileSource({loader: () => {}});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is true if constructed with interpoate: true', function () {
+ const source = new DataTileSource({interpolate: true, loader: () => {}});
+ expect(source.getInterpolate()).to.be(true);
+ });
+ });
});
diff --git a/test/browser/spec/ol/source/iiif.test.js b/test/browser/spec/ol/source/IIIF.test.js
similarity index 96%
rename from test/browser/spec/ol/source/iiif.test.js
rename to test/browser/spec/ol/source/IIIF.test.js
index 46ea8bee20..5f3d2f3297 100644
--- a/test/browser/spec/ol/source/iiif.test.js
+++ b/test/browser/spec/ol/source/IIIF.test.js
@@ -2,7 +2,7 @@ import IIIF from '../../../../../src/ol/source/IIIF.js';
import {DEFAULT_TILE_SIZE} from '../../../../../src/ol/tilegrid/common.js';
import {Versions} from '../../../../../src/ol/format/IIIFInfo.js';
-describe('ol.source.IIIF', function () {
+describe('ol/source/IIIF', function () {
const width = 2000,
height = 1500,
size = [width, height],
@@ -141,6 +141,23 @@ describe('ol.source.IIIF', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new IIIF({size: size});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new IIIF({size: size, interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new IIIF({size: size, imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('tileUrlFunction', function () {
it('has only one resolution and one tile if no tiles, resolutions, sizes and supported features are given', function () {
let tileUrlFunction = getSource().getTileUrlFunction();
diff --git a/test/browser/spec/ol/source/imagearcgisrest.test.js b/test/browser/spec/ol/source/ImageArcGISRest.test.js
similarity index 89%
rename from test/browser/spec/ol/source/imagearcgisrest.test.js
rename to test/browser/spec/ol/source/ImageArcGISRest.test.js
index 6a356e1f32..b826617f0d 100644
--- a/test/browser/spec/ol/source/imagearcgisrest.test.js
+++ b/test/browser/spec/ol/source/ImageArcGISRest.test.js
@@ -1,7 +1,7 @@
import ImageArcGISRest from '../../../../../src/ol/source/ImageArcGISRest.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.ImageArcGISRest', function () {
+describe('ol/source/ImageArcGISRest', function () {
let pixelRatio, options, projection, proj3857, resolution;
beforeEach(function () {
pixelRatio = 1;
@@ -14,6 +14,27 @@ describe('ol.source.ImageArcGISRest', function () {
};
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new ImageArcGISRest(options);
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new ImageArcGISRest(
+ Object.assign({interpolate: false}, options)
+ );
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new ImageArcGISRest(
+ Object.assign({imageSmoothing: false}, options)
+ );
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#getImage', function () {
it('returns a image with the expected URL', function () {
const source = new ImageArcGISRest(options);
diff --git a/test/browser/spec/ol/source/imagestatic.test.js b/test/browser/spec/ol/source/ImageStatic.test.js
similarity index 83%
rename from test/browser/spec/ol/source/imagestatic.test.js
rename to test/browser/spec/ol/source/ImageStatic.test.js
index 89f186ce49..ffd415a198 100644
--- a/test/browser/spec/ol/source/imagestatic.test.js
+++ b/test/browser/spec/ol/source/ImageStatic.test.js
@@ -1,7 +1,7 @@
import Static from '../../../../../src/ol/source/ImageStatic.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.ImageStatic', function () {
+describe('ol/source/ImageStatic', function () {
let extent, pixelRatio, projection, resolution;
beforeEach(function () {
extent = [
@@ -13,6 +13,23 @@ describe('ol.source.ImageStatic', function () {
resolution = 38;
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new Static({});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new Static({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new Static({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#getImage', function () {
it('scales image height to fit imageExtent', function (done) {
const source = new Static({
diff --git a/test/browser/spec/ol/source/source.test.js b/test/browser/spec/ol/source/Source.test.js
similarity index 90%
rename from test/browser/spec/ol/source/source.test.js
rename to test/browser/spec/ol/source/Source.test.js
index 56a95f6b70..8c0d5c72c0 100644
--- a/test/browser/spec/ol/source/source.test.js
+++ b/test/browser/spec/ol/source/Source.test.js
@@ -1,7 +1,7 @@
import Source from '../../../../../src/ol/source/Source.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.Source', function () {
+describe('ol/source/Source', function () {
describe('constructor', function () {
it('returns a source', function () {
const source = new Source({
@@ -75,6 +75,18 @@ describe('ol.source.Source', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('returns false by default', function () {
+ const source = new Source({});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('returns true if constructed with interpolate: true', function () {
+ const source = new Source({interpolate: true});
+ expect(source.getInterpolate()).to.be(true);
+ });
+ });
+
describe('#setAttributions()', function () {
let source = null;
diff --git a/test/browser/spec/ol/source/tile.test.js b/test/browser/spec/ol/source/Tile.test.js
similarity index 96%
rename from test/browser/spec/ol/source/tile.test.js
rename to test/browser/spec/ol/source/Tile.test.js
index b867470fcf..08d4b80ac5 100644
--- a/test/browser/spec/ol/source/tile.test.js
+++ b/test/browser/spec/ol/source/Tile.test.js
@@ -48,7 +48,7 @@ MockTile.prototype.getTile = function (z, x, y) {
}
};
-describe('ol.source.Tile', function () {
+describe('ol/source/Tile', function () {
describe('constructor', function () {
it('returns a tile source', function () {
const source = new TileSource({
@@ -109,6 +109,18 @@ describe('ol.source.Tile', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is false by default', function () {
+ const source = new TileSource({});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is true if constructed with interpolate: true', function () {
+ const source = new TileSource({interpolate: true});
+ expect(source.getInterpolate()).to.be(true);
+ });
+ });
+
describe('#setKey()', function () {
it('dispatches a change event', function (done) {
const source = new TileSource({});
diff --git a/test/browser/spec/ol/source/tileimage.test.js b/test/browser/spec/ol/source/TileImage.test.js
similarity index 93%
rename from test/browser/spec/ol/source/tileimage.test.js
rename to test/browser/spec/ol/source/TileImage.test.js
index ce42a09e76..7463919c12 100644
--- a/test/browser/spec/ol/source/tileimage.test.js
+++ b/test/browser/spec/ol/source/TileImage.test.js
@@ -18,7 +18,7 @@ import {getKeyZXY} from '../../../../../src/ol/tilecoord.js';
import {listen} from '../../../../../src/ol/events.js';
import {register} from '../../../../../src/ol/proj/proj4.js';
-describe('ol.source.TileImage', function () {
+describe('ol/source/TileImage', function () {
function createSource(opt_proj, opt_tileGrid, opt_cacheSize) {
const proj = opt_proj || 'EPSG:3857';
return new TileImage({
@@ -31,6 +31,23 @@ describe('ol.source.TileImage', function () {
});
}
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new TileImage({});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new TileImage({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new TileImage({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#getTileCacheForProjection', function () {
it('uses the cacheSize for reprojected tile caches', function () {
const source = createSource(undefined, undefined, 442);
diff --git a/test/browser/spec/ol/source/tilejson.test.js b/test/browser/spec/ol/source/TileJSON.test.js
similarity index 90%
rename from test/browser/spec/ol/source/tilejson.test.js
rename to test/browser/spec/ol/source/TileJSON.test.js
index dd497790ad..0ad44a6355 100644
--- a/test/browser/spec/ol/source/tilejson.test.js
+++ b/test/browser/spec/ol/source/TileJSON.test.js
@@ -3,7 +3,7 @@ import TileJSON from '../../../../../src/ol/source/TileJSON.js';
import {transformExtent} from '../../../../../src/ol/proj.js';
import {unByKey} from '../../../../../src/ol/Observable.js';
-describe('ol.source.TileJSON', function () {
+describe('ol/source/TileJSON', function () {
describe('constructor', function () {
it('returns a tileJSON source', function () {
const source = new TileJSON({
@@ -14,6 +14,29 @@ describe('ol.source.TileJSON', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new TileJSON({url: 'spec/ol/data/tilejson.json'});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new TileJSON({
+ interpolate: false,
+ url: 'spec/ol/data/tilejson.json',
+ });
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new TileJSON({
+ imageSmoothing: false,
+ url: 'spec/ol/data/tilejson.json',
+ });
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#getTileJSON', function () {
it('parses the tilejson file', function () {
const source = new TileJSON({
diff --git a/test/browser/spec/ol/source/tilewms.test.js b/test/browser/spec/ol/source/TileWMS.test.js
similarity index 96%
rename from test/browser/spec/ol/source/tilewms.test.js
rename to test/browser/spec/ol/source/TileWMS.test.js
index ee31470a80..1d3839afe4 100644
--- a/test/browser/spec/ol/source/tilewms.test.js
+++ b/test/browser/spec/ol/source/TileWMS.test.js
@@ -4,7 +4,7 @@ import TileWMS from '../../../../../src/ol/source/TileWMS.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.TileWMS', function () {
+describe('ol/source/TileWMS', function () {
let options, optionsReproj;
beforeEach(function () {
options = {
@@ -32,6 +32,23 @@ describe('ol.source.TileWMS', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new TileWMS();
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new TileWMS({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new TileWMS({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('#getTile', function () {
it('returns a tile with the expected URL', function () {
const source = new TileWMS(options);
diff --git a/test/browser/spec/ol/source/urltile.test.js b/test/browser/spec/ol/source/UrlTile.test.js
similarity index 93%
rename from test/browser/spec/ol/source/urltile.test.js
rename to test/browser/spec/ol/source/UrlTile.test.js
index 6158087b8b..26331a0f07 100644
--- a/test/browser/spec/ol/source/urltile.test.js
+++ b/test/browser/spec/ol/source/UrlTile.test.js
@@ -2,7 +2,7 @@ import UrlTile from '../../../../../src/ol/source/UrlTile.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.UrlTile', function () {
+describe('ol/source/UrlTile', function () {
describe('#setUrl()', function () {
it('sets the URL for the source', function () {
const source = new UrlTile({});
@@ -23,6 +23,18 @@ describe('ol.source.UrlTile', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is false by default', function () {
+ const source = new UrlTile({});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is true if constructed with interpolate: true', function () {
+ const source = new UrlTile({interpolate: true});
+ expect(source.getInterpolate()).to.be(true);
+ });
+ });
+
describe('#setUrls()', function () {
it('sets the URL for the source', function () {
const source = new UrlTile({});
diff --git a/test/browser/spec/ol/source/wmts.test.js b/test/browser/spec/ol/source/WMTS.test.js
similarity index 97%
rename from test/browser/spec/ol/source/wmts.test.js
rename to test/browser/spec/ol/source/WMTS.test.js
index 516b30eb7c..644fa8b985 100644
--- a/test/browser/spec/ol/source/wmts.test.js
+++ b/test/browser/spec/ol/source/WMTS.test.js
@@ -7,7 +7,7 @@ import WMTSTileGrid from '../../../../../src/ol/tilegrid/WMTS.js';
import {getBottomLeft, getTopRight} from '../../../../../src/ol/extent.js';
import {get as getProjection} from '../../../../../src/ol/proj.js';
-describe('ol.source.WMTS', function () {
+describe('ol/source/WMTS', function () {
describe('when creating options from capabilities', function () {
const parser = new WMTSCapabilities();
let capabilities, content;
@@ -230,6 +230,23 @@ describe('ol.source.WMTS', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new WMTS({});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new WMTS({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new WMTS({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('when creating tileUrlFunction', function () {
const defaultTileGrid = new WMTSTileGrid({
origin: [-20037508.342789244, 20037508.342789244],
diff --git a/test/browser/spec/ol/source/xyz.test.js b/test/browser/spec/ol/source/XYZ.test.js
similarity index 92%
rename from test/browser/spec/ol/source/xyz.test.js
rename to test/browser/spec/ol/source/XYZ.test.js
index 6604a24393..f689c1adbe 100644
--- a/test/browser/spec/ol/source/xyz.test.js
+++ b/test/browser/spec/ol/source/XYZ.test.js
@@ -7,7 +7,7 @@ import View from '../../../../../src/ol/View.js';
import XYZ from '../../../../../src/ol/source/XYZ.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
-describe('ol.source.XYZ', function () {
+describe('ol/source/XYZ', function () {
describe('constructor', function () {
it('can be constructed without options', function () {
const source = new XYZ();
@@ -47,6 +47,23 @@ describe('ol.source.XYZ', function () {
});
});
+ describe('getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new XYZ();
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new XYZ({interpolate: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new XYZ({imageSmoothing: false});
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('tileUrlFunction', function () {
let xyzTileSource, tileGrid;
diff --git a/test/browser/spec/ol/source/zoomify.test.js b/test/browser/spec/ol/source/Zoomify.test.js
similarity index 93%
rename from test/browser/spec/ol/source/zoomify.test.js
rename to test/browser/spec/ol/source/Zoomify.test.js
index 0d6e71d44d..3ef21a1ad5 100644
--- a/test/browser/spec/ol/source/zoomify.test.js
+++ b/test/browser/spec/ol/source/Zoomify.test.js
@@ -4,7 +4,7 @@ import Zoomify, {CustomTile} from '../../../../../src/ol/source/Zoomify.js';
import {DEFAULT_TILE_SIZE} from '../../../../../src/ol/tilegrid/common.js';
import {listen} from '../../../../../src/ol/events.js';
-describe('ol.source.Zoomify', function () {
+describe('ol/source/Zoomify', function () {
const w = 1024;
const h = 512;
const size = [w, h];
@@ -141,6 +141,27 @@ describe('ol.source.Zoomify', function () {
});
});
+ describe('#getInterpolate()', function () {
+ it('is true by default', function () {
+ const source = new Zoomify({url: '', size: [47, 11]});
+ expect(source.getInterpolate()).to.be(true);
+ });
+
+ it('is false if constructed with interpolate: false', function () {
+ const source = new Zoomify({interpolate: false, url: '', size: [47, 11]});
+ expect(source.getInterpolate()).to.be(false);
+ });
+
+ it('is false if constructed with imageSmoothing: false', function () {
+ const source = new Zoomify({
+ imageSmoothing: false,
+ url: '',
+ size: [47, 11],
+ });
+ expect(source.getInterpolate()).to.be(false);
+ });
+ });
+
describe('generated tileGrid', function () {
it('has expected extent', function () {
const sources = [getZoomifySource(), getIIPSource()];
diff --git a/test/rendering/cases/webgl-data-tile-interpolate-false/expected.png b/test/rendering/cases/webgl-data-tile-interpolate-false/expected.png
new file mode 100644
index 0000000000..68cc13c505
Binary files /dev/null and b/test/rendering/cases/webgl-data-tile-interpolate-false/expected.png differ
diff --git a/test/rendering/cases/webgl-data-tile-interpolate-false/main.js b/test/rendering/cases/webgl-data-tile-interpolate-false/main.js
new file mode 100644
index 0000000000..a4b64bd472
--- /dev/null
+++ b/test/rendering/cases/webgl-data-tile-interpolate-false/main.js
@@ -0,0 +1,31 @@
+import DataTile from '../../../../src/ol/source/DataTile.js';
+import Map from '../../../../src/ol/Map.js';
+import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
+import View from '../../../../src/ol/View.js';
+
+const size = 256;
+
+const data = new Uint8Array(size * size);
+for (let row = 0; row < size; ++row) {
+ for (let col = 0; col < size; ++col) {
+ data[row * size + col] = (row + col) % 2 === 0 ? 255 : 0;
+ }
+}
+
+new Map({
+ target: 'map',
+ layers: [
+ new TileLayer({
+ source: new DataTile({
+ maxZoom: 0,
+ loader: () => data,
+ }),
+ }),
+ ],
+ view: new View({
+ center: [0, 0],
+ zoom: 4,
+ }),
+});
+
+render();
diff --git a/test/rendering/cases/webgl-data-tile-interpolate-true/expected.png b/test/rendering/cases/webgl-data-tile-interpolate-true/expected.png
new file mode 100644
index 0000000000..b2bc536109
Binary files /dev/null and b/test/rendering/cases/webgl-data-tile-interpolate-true/expected.png differ
diff --git a/test/rendering/cases/webgl-data-tile-interpolate-true/main.js b/test/rendering/cases/webgl-data-tile-interpolate-true/main.js
new file mode 100644
index 0000000000..9e31b82195
--- /dev/null
+++ b/test/rendering/cases/webgl-data-tile-interpolate-true/main.js
@@ -0,0 +1,32 @@
+import DataTile from '../../../../src/ol/source/DataTile.js';
+import Map from '../../../../src/ol/Map.js';
+import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
+import View from '../../../../src/ol/View.js';
+
+const size = 256;
+
+const data = new Uint8Array(size * size);
+for (let row = 0; row < size; ++row) {
+ for (let col = 0; col < size; ++col) {
+ data[row * size + col] = (row + col) % 2 === 0 ? 255 : 0;
+ }
+}
+
+new Map({
+ target: 'map',
+ layers: [
+ new TileLayer({
+ source: new DataTile({
+ maxZoom: 0,
+ interpolate: true,
+ loader: () => data,
+ }),
+ }),
+ ],
+ view: new View({
+ center: [0, 0],
+ zoom: 4,
+ }),
+});
+
+render();
diff --git a/test/rendering/cases/webgl-mixed-layers/expected.png b/test/rendering/cases/webgl-mixed-layers/expected.png
index f058d91062..681d53e683 100644
Binary files a/test/rendering/cases/webgl-mixed-layers/expected.png and b/test/rendering/cases/webgl-mixed-layers/expected.png differ
diff --git a/test/rendering/cases/webgl-multiple-layers/expected.png b/test/rendering/cases/webgl-multiple-layers/expected.png
index 675e3d666d..0a01e8cfed 100644
Binary files a/test/rendering/cases/webgl-multiple-layers/expected.png and b/test/rendering/cases/webgl-multiple-layers/expected.png differ