From 6ca44f6ffa9e0d59341a9fee19afaee39aa358d4 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Fri, 8 Apr 2022 13:06:18 +0100 Subject: [PATCH] add gutter option --- src/ol/source/DataTile.js | 17 +++++++++ src/ol/source/XYZ.js | 16 +++++++++ .../expected.png | Bin 0 -> 3475 bytes .../main.js | 33 ++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 test/rendering/cases/webgl-data-tile-interpolate-gutter/expected.png create mode 100644 test/rendering/cases/webgl-data-tile-interpolate-gutter/main.js diff --git a/src/ol/source/DataTile.js b/src/ol/source/DataTile.js index 3836457d7a..c840d37a46 100644 --- a/src/ol/source/DataTile.js +++ b/src/ol/source/DataTile.js @@ -27,6 +27,9 @@ import {toPromise} from '../functions.js'; * @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided. * @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided. * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The pixel width and height of the tiles. + * @property {number} [gutter=0] The size in pixels of the gutter around data tiles to ignore. + * This allows artifacts of rendering at tile edges to be ignored. + * Supported data should be wider and taller than the tile size by a value of `2 x gutter`. * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided. * @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Tile projection. * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid. @@ -80,6 +83,12 @@ class DataTileSource extends TileSource { interpolate: options.interpolate, }); + /** + * @private + * @type {number} + */ + this.gutter_ = options.gutter !== undefined ? options.gutter : 0; + /** * @private * @type {!Object} @@ -99,6 +108,14 @@ class DataTileSource extends TileSource { this.bandCount = options.bandCount === undefined ? 4 : options.bandCount; // assume RGBA if undefined } + /** + * @param {import("../proj/Projection.js").default} projection Projection. + * @return {number} Gutter. + */ + getGutterForProjection(projection) { + return this.gutter_; + } + /** * @param {Loader} loader The data loader. * @protected diff --git a/src/ol/source/XYZ.js b/src/ol/source/XYZ.js index 15b11cb380..4bf7e73f6d 100644 --- a/src/ol/source/XYZ.js +++ b/src/ol/source/XYZ.js @@ -36,6 +36,9 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js'; * should be set to `2`. * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service. * Not used if `tileGrid` is provided. + * @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore. + * This allows artifacts of rendering at tile edges to be ignored. + * Supported images should be wider and taller than the tile size by a value of `2 x gutter`. * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get * tile URL given a tile coordinate and the projection. * Required if `url` or `urls` are not provided. @@ -114,6 +117,19 @@ class XYZ extends TileImage { attributionsCollapsible: options.attributionsCollapsible, zDirection: options.zDirection, }); + + /** + * @private + * @type {number} + */ + this.gutter_ = options.gutter !== undefined ? options.gutter : 0; + } + + /** + * @return {number} Gutter. + */ + getGutter() { + return this.gutter_; } } diff --git a/test/rendering/cases/webgl-data-tile-interpolate-gutter/expected.png b/test/rendering/cases/webgl-data-tile-interpolate-gutter/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..b2bc53610990486b70201118e8e21058b268d538 GIT binary patch literal 3475 zcmeH~X;4#F7=}-R$W{mUg4KMVj8en|qR)A5h(2XDkq+$Dw4{Xoex`)+(uaG?LXEh)eDweMiG zRnI#qJ@FDsMd!h$`z70QuW44aiX3#}=I%u-)>w}w60}Jq5zK51!(PxXhM4I`N1tGI*r znnsY4mKMYeo2l1nRZ^1_HamFYMj_B!2>^bYLP;^|&}bs@%(^M()HG2$WnggdYF=L6 zusnzrncF{y%j4-4x_B_AR<3Vtktq}k&Il=8H+pV-%#o9lqQ2)46b>pEJ3`QD@g?Fc>zrX*!*(v<|wdu1! z=c(g`R`iowcI>l3CIMs1=r)ssj7VpOy`d=$#GMN_FoK1A@Ty`vr#gZ^cw|sWq}Ie zkyz2Jx~5+D1r;B<*DBnDC{Ci*-LoSJhFimQ$gLe?jv#QjD2epC^r$2;_sYuJ_deQQ|$QwSwt+Nn4 z96_aYK5CsC*j9BGMG}!OKOz|V-~tjQWx`-ZpoQwu#y|!0->f7w(QMwa=TokA)Zp+X zRqnE=K`A~3LeVNx)Fh-=tGRn1$^=K_EJDHcca7-XFfG+c2cZ>-C6|CM$G~*iDf&>r z<&AJ_DH+kb30%DF3sLI~LyzPT333p_B3wYb&on_+wm>U8sdYsK4|)DUXkr`5zENzm zYttq1kk}@66EbHwy_8~}uH73@@5M^UQ9id>3`cQ`pOiNMgNF%gTMY1NKx0%$% zv<>VLo7xg15)KeOgSGu5@;!a4P$XRcHi)4uaK=Q-p)UDkXgx&1oSkoo!Tpa;Ly=h7 zBZGN!92tZcSO`VR*Mhm3c8-m9M;8(%Wsc~Tk|*34jniyU+#Z1B5Jw7qPcY=;0?Km^ zfVw0c6csFLwk4cuuW_R1kxd!yscE7kn|^WE3@DYQvbYP};z>v!?U7A*@yK+j;Bjf| z(E`F?v}pr`Rut2HiNQ^xg5%%U7o<9c5+f2pLiEBxj-A!NM1H5$13>1W%BT++yC0+^(OV5=Pj}=VxHmuvOwU55dRXtm}7qf D(I|`o literal 0 HcmV?d00001 diff --git a/test/rendering/cases/webgl-data-tile-interpolate-gutter/main.js b/test/rendering/cases/webgl-data-tile-interpolate-gutter/main.js new file mode 100644 index 0000000000..d294e8f3f3 --- /dev/null +++ b/test/rendering/cases/webgl-data-tile-interpolate-gutter/main.js @@ -0,0 +1,33 @@ +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 = 260; + +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: 1, + interpolate: true, + loader: () => data, + gutter: 2, + }), + }), + ], + view: new View({ + center: [0, 0], + zoom: 5, + }), +}); + +render();