Merge pull request #13648 from tschaub/data-tile-size
Explicit data tile size
This commit is contained in:
@@ -1,6 +1,17 @@
|
|||||||
## Upgrade notes
|
## Upgrade notes
|
||||||
|
|
||||||
### v6.15.0
|
### Next Release
|
||||||
|
|
||||||
|
#### Deprecated `tilePixelRatio` option for data tile sources.
|
||||||
|
|
||||||
|
If you were previously trying to scale data tiles using the `tilePixelRatio` property for data tile sources (this is rare), you should now use the explicit `tileSize` and `tileGrid` properties. The source's `tileSize` represents the source tile dimensions and the tile grid's `tileSize` represents the desired rendered dimensions.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const source = new DataTileSource({
|
||||||
|
tileSize: [512, 512], // source tile size
|
||||||
|
tileGrid: createXYZ({tileSize: [256, 256]}), // rendered tile size
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
#### Fixed coordinate dimension handling in `ol/proj`'s `addCoordinateTransforms`
|
#### Fixed coordinate dimension handling in `ol/proj`'s `addCoordinateTransforms`
|
||||||
|
|
||||||
|
|||||||
Generated
+12
-31
@@ -9,7 +9,7 @@
|
|||||||
"version": "6.14.2-dev",
|
"version": "6.14.2-dev",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"geotiff": "^2.0.2",
|
"geotiff": "2.0.4",
|
||||||
"ol-mapbox-style": "^8.0.5",
|
"ol-mapbox-style": "^8.0.5",
|
||||||
"pbf": "3.2.1",
|
"pbf": "3.2.1",
|
||||||
"rbush": "^3.0.1"
|
"rbush": "^3.0.1"
|
||||||
@@ -5294,19 +5294,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/geotiff": {
|
"node_modules/geotiff": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.4.tgz",
|
||||||
"integrity": "sha512-U5kVYm118YAmw2swiLu8rhfrYnDKOFI7VaMjuQwcq6Intuuid9Pyb4jjxYUxxkq8kOu2r7Am0Rmb52PObGp4pQ==",
|
"integrity": "sha512-aG8h9bJccGusioPsEWsEqx8qdXpZN71A20WCvRKGxcnHSOWLKmC5ZmsAmodfxb9TRQvs+89KikGuPzxchhA+Uw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@petamoriken/float16": "^3.4.7",
|
"@petamoriken/float16": "^3.4.7",
|
||||||
"lerc": "^3.0.0",
|
"lerc": "^3.0.0",
|
||||||
|
"lru-cache": "^6.0.0",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
"parse-headers": "^2.0.2",
|
"parse-headers": "^2.0.2",
|
||||||
"quick-lru": "^6.1.0",
|
|
||||||
"web-worker": "^1.2.0",
|
"web-worker": "^1.2.0",
|
||||||
"xml-utils": "^1.0.2"
|
"xml-utils": "^1.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
"browsers": "defaults",
|
||||||
"node": ">=10.19"
|
"node": ">=10.19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -6811,7 +6812,6 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
},
|
},
|
||||||
@@ -8033,17 +8033,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/quick-lru": {
|
|
||||||
"version": "6.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.1.tgz",
|
|
||||||
"integrity": "sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/quickselect": {
|
"node_modules/quickselect": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
||||||
@@ -10334,8 +10323,7 @@
|
|||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "17.4.1",
|
"version": "17.4.1",
|
||||||
@@ -14384,15 +14372,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"geotiff": {
|
"geotiff": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.4.tgz",
|
||||||
"integrity": "sha512-U5kVYm118YAmw2swiLu8rhfrYnDKOFI7VaMjuQwcq6Intuuid9Pyb4jjxYUxxkq8kOu2r7Am0Rmb52PObGp4pQ==",
|
"integrity": "sha512-aG8h9bJccGusioPsEWsEqx8qdXpZN71A20WCvRKGxcnHSOWLKmC5ZmsAmodfxb9TRQvs+89KikGuPzxchhA+Uw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@petamoriken/float16": "^3.4.7",
|
"@petamoriken/float16": "^3.4.7",
|
||||||
"lerc": "^3.0.0",
|
"lerc": "^3.0.0",
|
||||||
|
"lru-cache": "^6.0.0",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
"parse-headers": "^2.0.2",
|
"parse-headers": "^2.0.2",
|
||||||
"quick-lru": "^6.1.0",
|
|
||||||
"web-worker": "^1.2.0",
|
"web-worker": "^1.2.0",
|
||||||
"xml-utils": "^1.0.2"
|
"xml-utils": "^1.0.2"
|
||||||
}
|
}
|
||||||
@@ -15499,7 +15487,6 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"yallist": "^4.0.0"
|
"yallist": "^4.0.0"
|
||||||
}
|
}
|
||||||
@@ -16412,11 +16399,6 @@
|
|||||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"quick-lru": {
|
|
||||||
"version": "6.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.1.tgz",
|
|
||||||
"integrity": "sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q=="
|
|
||||||
},
|
|
||||||
"quickselect": {
|
"quickselect": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
||||||
@@ -18150,8 +18132,7 @@
|
|||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"yargs": {
|
"yargs": {
|
||||||
"version": "17.4.1",
|
"version": "17.4.1",
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@
|
|||||||
"url": "https://opencollective.com/openlayers"
|
"url": "https://opencollective.com/openlayers"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"geotiff": "^2.0.2",
|
"geotiff": "2.0.4",
|
||||||
"ol-mapbox-style": "^8.0.5",
|
"ol-mapbox-style": "^8.0.5",
|
||||||
"pbf": "3.2.1",
|
"pbf": "3.2.1",
|
||||||
"rbush": "^3.0.1"
|
"rbush": "^3.0.1"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import TileState from './TileState.js';
|
|||||||
* transitions in milliseconds. A duration of 0 disables the opacity transition.
|
* transitions in milliseconds. A duration of 0 disables the opacity transition.
|
||||||
* @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
|
* @property {boolean} [interpolate=false] Use interpolated values when resampling. By default,
|
||||||
* the nearest neighbor is used when resampling.
|
* the nearest neighbor is used when resampling.
|
||||||
|
* @property {import('./size.js').Size} [size=[256, 256]] Tile size.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -50,6 +51,20 @@ class DataTile extends Tile {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.error_ = null;
|
this.error_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('./size.js').Size}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.size_ = options.size || [256, 256];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tile size.
|
||||||
|
* @return {import('./size.js').Size} Tile size.
|
||||||
|
*/
|
||||||
|
getSize() {
|
||||||
|
return this.size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -318,7 +318,6 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
const tileLayer = this.getLayer();
|
const tileLayer = this.getLayer();
|
||||||
const tileSource = tileLayer.getRenderSource();
|
const tileSource = tileLayer.getRenderSource();
|
||||||
const tileGrid = tileSource.getTileGridForProjection(viewState.projection);
|
const tileGrid = tileSource.getTileGridForProjection(viewState.projection);
|
||||||
const tilePixelRatio = tileSource.getTilePixelRatio(frameState.pixelRatio);
|
|
||||||
const gutter = tileSource.getGutterForProjection(viewState.projection);
|
const gutter = tileSource.getGutterForProjection(viewState.projection);
|
||||||
|
|
||||||
const tileSourceKey = getUid(tileSource);
|
const tileSourceKey = getUid(tileSource);
|
||||||
@@ -371,7 +370,6 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
|
|||||||
tile: tile,
|
tile: tile,
|
||||||
grid: tileGrid,
|
grid: tileGrid,
|
||||||
helper: this.helper,
|
helper: this.helper,
|
||||||
tilePixelRatio: tilePixelRatio,
|
|
||||||
gutter: gutter,
|
gutter: gutter,
|
||||||
});
|
});
|
||||||
tileTextureCache.set(cacheKey, tileTexture);
|
tileTextureCache.set(cacheKey, tileTexture);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
|||||||
import {getKeyZXY} from '../tilecoord.js';
|
import {getKeyZXY} from '../tilecoord.js';
|
||||||
import {getUid} from '../util.js';
|
import {getUid} from '../util.js';
|
||||||
import {toPromise} from '../functions.js';
|
import {toPromise} from '../functions.js';
|
||||||
|
import {toSize} from '../size.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data tile loading function. The function is called with z, x, and y tile coordinates and
|
* Data tile loading function. The function is called with z, x, and y tile coordinates and
|
||||||
@@ -26,7 +27,8 @@ import {toPromise} from '../functions.js';
|
|||||||
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
|
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
|
||||||
* @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.
|
* @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} [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|import("../size.js").Size} [tileSize=[256, 256]] The pixel width and height of the source tiles.
|
||||||
|
* This may be different than the rendered pixel size if a `tileGrid` is provided.
|
||||||
* @property {number} [gutter=0] The size in pixels of the gutter around data tiles to ignore.
|
* @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.
|
* 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`.
|
* Supported data should be wider and taller than the tile size by a value of `2 x gutter`.
|
||||||
@@ -35,7 +37,8 @@ import {toPromise} from '../functions.js';
|
|||||||
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
||||||
* @property {boolean} [opaque=false] Whether the layer is opaque.
|
* @property {boolean} [opaque=false] Whether the layer is opaque.
|
||||||
* @property {import("./State.js").default} [state] The source state.
|
* @property {import("./State.js").default} [state] The source state.
|
||||||
* @property {number} [tilePixelRatio] Tile pixel ratio.
|
* @property {number} [tilePixelRatio] Deprecated. To have tiles scaled, pass a `tileSize` representing
|
||||||
|
* the source tile size and a `tileGrid` with the desired rendered tile size.
|
||||||
* @property {boolean} [wrapX=false] Render tiles beyond the antimeridian.
|
* @property {boolean} [wrapX=false] Render tiles beyond the antimeridian.
|
||||||
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
|
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
|
||||||
* @property {number} [bandCount=4] Number of bands represented in the data.
|
* @property {number} [bandCount=4] Number of bands represented in the data.
|
||||||
@@ -89,6 +92,25 @@ class DataTileSource extends TileSource {
|
|||||||
*/
|
*/
|
||||||
this.gutter_ = options.gutter !== undefined ? options.gutter : 0;
|
this.gutter_ = options.gutter !== undefined ? options.gutter : 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {import('../size.js').Size|null}
|
||||||
|
*/
|
||||||
|
this.tileSize_ = options.tileSize ? toSize(options.tileSize) : null;
|
||||||
|
if (!this.tileSize_ && options.tilePixelRatio && tileGrid) {
|
||||||
|
const renderTileSize = toSize(tileGrid.getTileSize(0));
|
||||||
|
this.tileSize_ = [
|
||||||
|
renderTileSize[0] * options.tilePixelRatio,
|
||||||
|
renderTileSize[1] * options.tilePixelRatio,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Array<import('../size.js').Size>|null}
|
||||||
|
*/
|
||||||
|
this.tileSizes_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {!Object<string, boolean>}
|
* @type {!Object<string, boolean>}
|
||||||
@@ -108,6 +130,34 @@ class DataTileSource extends TileSource {
|
|||||||
this.bandCount = options.bandCount === undefined ? 4 : options.bandCount; // assume RGBA if undefined
|
this.bandCount = options.bandCount === undefined ? 4 : options.bandCount; // assume RGBA if undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the source tile sizes. The length of the array is expected to match the number of
|
||||||
|
* levels in the tile grid.
|
||||||
|
* @protected
|
||||||
|
* @param {Array<import('../size.js').Size>} tileSizes An array of tile sizes.
|
||||||
|
*/
|
||||||
|
setTileSizes(tileSizes) {
|
||||||
|
this.tileSizes_ = tileSizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the source tile size at the given zoom level. This may be different than the rendered tile
|
||||||
|
* size.
|
||||||
|
* @protected
|
||||||
|
* @param {number} z Tile zoom level.
|
||||||
|
* @return {import('../size.js').Size} The source tile size.
|
||||||
|
*/
|
||||||
|
getTileSize(z) {
|
||||||
|
if (this.tileSizes_) {
|
||||||
|
return this.tileSizes_[z];
|
||||||
|
}
|
||||||
|
if (this.tileSize_) {
|
||||||
|
return this.tileSize_;
|
||||||
|
}
|
||||||
|
const tileGrid = this.getTileGrid();
|
||||||
|
return tileGrid ? toSize(tileGrid.getTileSize(z)) : [256, 256];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../proj/Projection.js").default} projection Projection.
|
* @param {import("../proj/Projection.js").default} projection Projection.
|
||||||
* @return {number} Gutter.
|
* @return {number} Gutter.
|
||||||
@@ -133,6 +183,7 @@ class DataTileSource extends TileSource {
|
|||||||
* @return {!DataTile} Tile.
|
* @return {!DataTile} Tile.
|
||||||
*/
|
*/
|
||||||
getTile(z, x, y, pixelRatio, projection) {
|
getTile(z, x, y, pixelRatio, projection) {
|
||||||
|
const size = this.getTileSize(z);
|
||||||
const tileCoordKey = getKeyZXY(z, x, y);
|
const tileCoordKey = getKeyZXY(z, x, y);
|
||||||
if (this.tileCache.containsKey(tileCoordKey)) {
|
if (this.tileCache.containsKey(tileCoordKey)) {
|
||||||
return this.tileCache.get(tileCoordKey);
|
return this.tileCache.get(tileCoordKey);
|
||||||
@@ -146,9 +197,16 @@ class DataTileSource extends TileSource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const tile = new DataTile(
|
const options = assign(
|
||||||
assign({tileCoord: [z, x, y], loader: loader}, this.tileOptions)
|
{
|
||||||
|
tileCoord: [z, x, y],
|
||||||
|
loader: loader,
|
||||||
|
size: size,
|
||||||
|
},
|
||||||
|
this.tileOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const tile = new DataTile(options);
|
||||||
tile.key = this.getKey();
|
tile.key = this.getKey();
|
||||||
tile.addEventListener(EventType.CHANGE, this.handleTileChange_);
|
tile.addEventListener(EventType.CHANGE, this.handleTileChange_);
|
||||||
|
|
||||||
|
|||||||
+47
-23
@@ -13,7 +13,6 @@ import {
|
|||||||
} from '../proj.js';
|
} from '../proj.js';
|
||||||
import {clamp} from '../math.js';
|
import {clamp} from '../math.js';
|
||||||
import {getCenter, getIntersection} from '../extent.js';
|
import {getCenter, getIntersection} from '../extent.js';
|
||||||
import {toSize} from '../size.js';
|
|
||||||
import {fromCode as unitsFromCode} from '../proj/Units.js';
|
import {fromCode as unitsFromCode} from '../proj/Units.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,15 +111,17 @@ function getOrigin(image) {
|
|||||||
* the width of the image is compared with the reference image.
|
* the width of the image is compared with the reference image.
|
||||||
* @param {GeoTIFFImage} image The image.
|
* @param {GeoTIFFImage} image The image.
|
||||||
* @param {GeoTIFFImage} referenceImage The reference image.
|
* @param {GeoTIFFImage} referenceImage The reference image.
|
||||||
* @return {number} The image resolution.
|
* @return {Array<number>} The map x and y units per pixel.
|
||||||
*/
|
*/
|
||||||
function getResolution(image, referenceImage) {
|
function getResolutions(image, referenceImage) {
|
||||||
try {
|
try {
|
||||||
return image.getResolution(referenceImage)[0];
|
return image.getResolution(referenceImage);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return (
|
return [
|
||||||
referenceImage.fileDirectory.ImageWidth / image.fileDirectory.ImageWidth
|
referenceImage.fileDirectory.ImageWidth / image.fileDirectory.ImageWidth,
|
||||||
);
|
referenceImage.fileDirectory.ImageHeight /
|
||||||
|
image.fileDirectory.ImageHeight,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,7 +450,8 @@ class GeoTIFFSource extends DataTile {
|
|||||||
configure_(sources) {
|
configure_(sources) {
|
||||||
let extent;
|
let extent;
|
||||||
let origin;
|
let origin;
|
||||||
let tileSizes;
|
let commonRenderTileSizes;
|
||||||
|
let commonSourceTileSizes;
|
||||||
let resolutions;
|
let resolutions;
|
||||||
const samplesPerPixel = new Array(sources.length);
|
const samplesPerPixel = new Array(sources.length);
|
||||||
const nodataValues = new Array(sources.length);
|
const nodataValues = new Array(sources.length);
|
||||||
@@ -464,6 +466,7 @@ class GeoTIFFSource extends DataTile {
|
|||||||
let sourceExtent;
|
let sourceExtent;
|
||||||
let sourceOrigin;
|
let sourceOrigin;
|
||||||
const sourceTileSizes = new Array(imageCount);
|
const sourceTileSizes = new Array(imageCount);
|
||||||
|
const renderTileSizes = new Array(imageCount);
|
||||||
const sourceResolutions = new Array(imageCount);
|
const sourceResolutions = new Array(imageCount);
|
||||||
|
|
||||||
nodataValues[sourceIndex] = new Array(imageCount);
|
nodataValues[sourceIndex] = new Array(imageCount);
|
||||||
@@ -490,8 +493,17 @@ class GeoTIFFSource extends DataTile {
|
|||||||
sourceOrigin = getOrigin(image);
|
sourceOrigin = getOrigin(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceResolutions[level] = getResolution(image, images[0]);
|
const imageResolutions = getResolutions(image, images[0]);
|
||||||
sourceTileSizes[level] = [image.getTileWidth(), image.getTileHeight()];
|
sourceResolutions[level] = imageResolutions[0];
|
||||||
|
|
||||||
|
const sourceTileSize = [image.getTileWidth(), image.getTileHeight()];
|
||||||
|
sourceTileSizes[level] = sourceTileSize;
|
||||||
|
|
||||||
|
const aspectRatio = imageResolutions[0] / Math.abs(imageResolutions[1]);
|
||||||
|
renderTileSizes[level] = [
|
||||||
|
sourceTileSize[0],
|
||||||
|
sourceTileSize[1] / aspectRatio,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extent) {
|
if (!extent) {
|
||||||
@@ -531,11 +543,23 @@ class GeoTIFFSource extends DataTile {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tileSizes) {
|
if (!commonRenderTileSizes) {
|
||||||
tileSizes = sourceTileSizes;
|
commonRenderTileSizes = renderTileSizes;
|
||||||
} else {
|
} else {
|
||||||
assertEqual(
|
assertEqual(
|
||||||
tileSizes.slice(minZoom, tileSizes.length),
|
commonRenderTileSizes.slice(minZoom, commonRenderTileSizes.length),
|
||||||
|
renderTileSizes,
|
||||||
|
0.01,
|
||||||
|
`Tile size mismatch for source ${sourceIndex}`,
|
||||||
|
this.viewRejector
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!commonSourceTileSizes) {
|
||||||
|
commonSourceTileSizes = sourceTileSizes;
|
||||||
|
} else {
|
||||||
|
assertEqual(
|
||||||
|
commonSourceTileSizes.slice(minZoom, commonSourceTileSizes.length),
|
||||||
sourceTileSizes,
|
sourceTileSizes,
|
||||||
0,
|
0,
|
||||||
`Tile size mismatch for source ${sourceIndex}`,
|
`Tile size mismatch for source ${sourceIndex}`,
|
||||||
@@ -612,10 +636,11 @@ class GeoTIFFSource extends DataTile {
|
|||||||
minZoom: minZoom,
|
minZoom: minZoom,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
resolutions: resolutions,
|
resolutions: resolutions,
|
||||||
tileSizes: tileSizes,
|
tileSizes: commonRenderTileSizes,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.tileGrid = tileGrid;
|
this.tileGrid = tileGrid;
|
||||||
|
this.setTileSizes(commonSourceTileSizes);
|
||||||
|
|
||||||
this.setLoader(this.loadTile_.bind(this));
|
this.setLoader(this.loadTile_.bind(this));
|
||||||
this.setState(State.READY);
|
this.setState(State.READY);
|
||||||
@@ -629,8 +654,7 @@ class GeoTIFFSource extends DataTile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadTile_(z, x, y) {
|
loadTile_(z, x, y) {
|
||||||
const size = toSize(this.tileGrid.getTileSize(z));
|
const sourceTileSize = this.getTileSize(z);
|
||||||
|
|
||||||
const sourceCount = this.sourceImagery_.length;
|
const sourceCount = this.sourceImagery_.length;
|
||||||
const requests = new Array(sourceCount);
|
const requests = new Array(sourceCount);
|
||||||
const addAlpha = this.addAlpha_;
|
const addAlpha = this.addAlpha_;
|
||||||
@@ -642,10 +666,10 @@ class GeoTIFFSource extends DataTile {
|
|||||||
const source = sourceInfo[sourceIndex];
|
const source = sourceInfo[sourceIndex];
|
||||||
const resolutionFactor = this.resolutionFactors_[sourceIndex];
|
const resolutionFactor = this.resolutionFactors_[sourceIndex];
|
||||||
const pixelBounds = [
|
const pixelBounds = [
|
||||||
Math.round(x * (size[0] * resolutionFactor)),
|
Math.round(x * (sourceTileSize[0] * resolutionFactor)),
|
||||||
Math.round(y * (size[1] * resolutionFactor)),
|
Math.round(y * (sourceTileSize[1] * resolutionFactor)),
|
||||||
Math.round((x + 1) * (size[0] * resolutionFactor)),
|
Math.round((x + 1) * (sourceTileSize[0] * resolutionFactor)),
|
||||||
Math.round((y + 1) * (size[1] * resolutionFactor)),
|
Math.round((y + 1) * (sourceTileSize[1] * resolutionFactor)),
|
||||||
];
|
];
|
||||||
const image = this.sourceImagery_[sourceIndex][z];
|
const image = this.sourceImagery_[sourceIndex][z];
|
||||||
let samples;
|
let samples;
|
||||||
@@ -671,8 +695,8 @@ class GeoTIFFSource extends DataTile {
|
|||||||
|
|
||||||
requests[sourceIndex] = image[this.readMethod_]({
|
requests[sourceIndex] = image[this.readMethod_]({
|
||||||
window: pixelBounds,
|
window: pixelBounds,
|
||||||
width: size[0],
|
width: sourceTileSize[0],
|
||||||
height: size[1],
|
height: sourceTileSize[1],
|
||||||
samples: samples,
|
samples: samples,
|
||||||
fillValue: fillValue,
|
fillValue: fillValue,
|
||||||
pool: getWorkerPool(),
|
pool: getWorkerPool(),
|
||||||
@@ -680,7 +704,7 @@ class GeoTIFFSource extends DataTile {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const pixelCount = size[0] * size[1];
|
const pixelCount = sourceTileSize[0] * sourceTileSize[1];
|
||||||
const dataLength = pixelCount * bandCount;
|
const dataLength = pixelCount * bandCount;
|
||||||
const normalize = this.normalize_;
|
const normalize = this.normalize_;
|
||||||
const metadata = this.metadata_;
|
const metadata = this.metadata_;
|
||||||
|
|||||||
+45
-26
@@ -138,7 +138,6 @@ function createPixelContext() {
|
|||||||
* @property {TileType} tile The tile.
|
* @property {TileType} tile The tile.
|
||||||
* @property {import("../tilegrid/TileGrid.js").default} grid Tile grid.
|
* @property {import("../tilegrid/TileGrid.js").default} grid Tile grid.
|
||||||
* @property {import("../webgl/Helper.js").default} helper WebGL helper.
|
* @property {import("../webgl/Helper.js").default} helper WebGL helper.
|
||||||
* @property {number} [tilePixelRatio=1] Tile pixel ratio.
|
|
||||||
* @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore.
|
* @property {number} [gutter=0] The size in pixels of the gutter around image tiles to ignore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -162,14 +161,11 @@ class TileTexture extends EventTarget {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import("../size.js").Size}
|
* @type {import("../size.js").Size}
|
||||||
*/
|
|
||||||
this.size = toSize(options.grid.getTileSize(options.tile.tileCoord[0]));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.tilePixelRatio_ = options.tilePixelRatio || 1;
|
this.renderSize_ = toSize(
|
||||||
|
options.grid.getTileSize(options.tile.tileCoord[0])
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -247,9 +243,10 @@ class TileTexture extends EventTarget {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sourceTileSize = tile.getSize();
|
||||||
const pixelSize = [
|
const pixelSize = [
|
||||||
(this.size[0] + 2 * this.gutter_) * this.tilePixelRatio_,
|
sourceTileSize[0] + 2 * this.gutter_,
|
||||||
(this.size[1] + 2 * this.gutter_) * this.tilePixelRatio_,
|
sourceTileSize[1] + 2 * this.gutter_,
|
||||||
];
|
];
|
||||||
const data = tile.getData();
|
const data = tile.getData();
|
||||||
const isFloat = data instanceof Float32Array;
|
const isFloat = data instanceof Float32Array;
|
||||||
@@ -339,34 +336,43 @@ class TileTexture extends EventTarget {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get data for a pixel. If the tile is not loaded, null is returned.
|
* Get data for a pixel. If the tile is not loaded, null is returned.
|
||||||
* @param {number} col The column index.
|
* @param {number} renderCol The column index (in rendered tile space).
|
||||||
* @param {number} row The row index.
|
* @param {number} renderRow The row index (in rendered tile space).
|
||||||
* @return {import("../DataTile.js").Data|null} The data.
|
* @return {import("../DataTile.js").Data|null} The data.
|
||||||
*/
|
*/
|
||||||
getPixelData(col, row) {
|
getPixelData(renderCol, renderRow) {
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
const renderWidth = this.renderSize_[0];
|
||||||
const gutter = Math.round(this.tilePixelRatio_ * this.gutter_);
|
const renderHeight = this.renderSize_[1];
|
||||||
col = Math.floor(this.tilePixelRatio_ * col) + gutter;
|
const gutter = this.gutter_;
|
||||||
row = Math.floor(this.tilePixelRatio_ * row) + gutter;
|
|
||||||
|
|
||||||
if (this.tile instanceof DataTile) {
|
if (this.tile instanceof DataTile) {
|
||||||
|
const sourceSize = this.tile.getSize();
|
||||||
|
|
||||||
|
const sourceWidthWithoutGutter = sourceSize[0];
|
||||||
|
const sourceHeightWithoutGutter = sourceSize[1];
|
||||||
|
const sourceWidth = sourceWidthWithoutGutter + 2 * gutter;
|
||||||
|
const sourceHeight = sourceHeightWithoutGutter + 2 * gutter;
|
||||||
|
|
||||||
|
const sourceCol =
|
||||||
|
gutter +
|
||||||
|
Math.floor(sourceWidthWithoutGutter * (renderCol / renderWidth));
|
||||||
|
|
||||||
|
const sourceRow =
|
||||||
|
gutter +
|
||||||
|
Math.floor(sourceHeightWithoutGutter * (renderRow / renderHeight));
|
||||||
|
|
||||||
const data = this.tile.getData();
|
const data = this.tile.getData();
|
||||||
let size = this.size;
|
|
||||||
if (gutter > 0) {
|
|
||||||
size = [size[0] + 2 * this.gutter_, size[1] + 2 * this.gutter_];
|
|
||||||
}
|
|
||||||
const pixelsPerRow = Math.floor(this.tilePixelRatio_ * size[0]);
|
|
||||||
if (data instanceof DataView) {
|
if (data instanceof DataView) {
|
||||||
const bytesPerPixel = data.byteLength / (size[0] * size[1]);
|
const bytesPerPixel = data.byteLength / (sourceWidth * sourceHeight);
|
||||||
const offset = row * pixelsPerRow * bytesPerPixel + col * bytesPerPixel;
|
const offset = bytesPerPixel * (sourceRow * sourceWidth + sourceCol);
|
||||||
const buffer = data.buffer.slice(offset, offset + bytesPerPixel);
|
const buffer = data.buffer.slice(offset, offset + bytesPerPixel);
|
||||||
return new DataView(buffer);
|
return new DataView(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const offset = row * pixelsPerRow * this.bandCount + col * this.bandCount;
|
const offset = this.bandCount * (sourceRow * sourceWidth + sourceCol);
|
||||||
return data.slice(offset, offset + this.bandCount);
|
return data.slice(offset, offset + this.bandCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,10 +381,23 @@ class TileTexture extends EventTarget {
|
|||||||
}
|
}
|
||||||
pixelContext.clearRect(0, 0, 1, 1);
|
pixelContext.clearRect(0, 0, 1, 1);
|
||||||
|
|
||||||
let data;
|
|
||||||
const image = this.tile.getImage();
|
const image = this.tile.getImage();
|
||||||
|
const sourceWidth = image.width;
|
||||||
|
const sourceHeight = image.height;
|
||||||
|
|
||||||
|
const sourceWidthWithoutGutter = sourceWidth - 2 * gutter;
|
||||||
|
const sourceHeightWithoutGutter = sourceHeight - 2 * gutter;
|
||||||
|
|
||||||
|
const sourceCol =
|
||||||
|
gutter + Math.floor(sourceWidthWithoutGutter * (renderCol / renderWidth));
|
||||||
|
|
||||||
|
const sourceRow =
|
||||||
|
gutter +
|
||||||
|
Math.floor(sourceHeightWithoutGutter * (renderRow / renderHeight));
|
||||||
|
|
||||||
|
let data;
|
||||||
try {
|
try {
|
||||||
pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);
|
pixelContext.drawImage(image, sourceCol, sourceRow, 1, 1, 0, 0, 1, 1);
|
||||||
data = pixelContext.getImageData(0, 0, 1, 1).data;
|
data = pixelContext.getImageData(0, 0, 1, 1).data;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
pixelContext = null;
|
pixelContext = null;
|
||||||
|
|||||||
@@ -33,6 +33,28 @@ describe('ol/DataTile', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getSize()', function () {
|
||||||
|
it('returns [256, 256] by default', function () {
|
||||||
|
const tileCoord = [0, 0, 0];
|
||||||
|
const tile = new DataTile({
|
||||||
|
tileCoord: tileCoord,
|
||||||
|
loader: loader,
|
||||||
|
});
|
||||||
|
expect(tile.getSize()).to.eql([256, 256]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects what is provided in the constructor', function () {
|
||||||
|
const size = [123, 456];
|
||||||
|
const tileCoord = [0, 0, 0];
|
||||||
|
const tile = new DataTile({
|
||||||
|
size: size,
|
||||||
|
tileCoord: tileCoord,
|
||||||
|
loader: loader,
|
||||||
|
});
|
||||||
|
expect(tile.getSize()).to.eql(size);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('#load()', function () {
|
describe('#load()', function () {
|
||||||
it('handles loading states correctly', function (done) {
|
it('handles loading states correctly', function (done) {
|
||||||
const tileCoord = [0, 0, 0];
|
const tileCoord = [0, 0, 0];
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import View from '../../../../../src/ol/View.js';
|
|||||||
import WebGLHelper from '../../../../../src/ol/webgl/Helper.js';
|
import WebGLHelper from '../../../../../src/ol/webgl/Helper.js';
|
||||||
import WebGLTileLayer from '../../../../../src/ol/layer/WebGLTile.js';
|
import WebGLTileLayer from '../../../../../src/ol/layer/WebGLTile.js';
|
||||||
import {createCanvasContext2D} from '../../../../../src/ol/dom.js';
|
import {createCanvasContext2D} from '../../../../../src/ol/dom.js';
|
||||||
|
import {createXYZ} from '../../../../../src/ol/tilegrid.js';
|
||||||
import {getForViewAndSize} from '../../../../../src/ol/extent.js';
|
import {getForViewAndSize} from '../../../../../src/ol/extent.js';
|
||||||
import {getRenderPixel} from '../../../../../src/ol/render.js';
|
import {getRenderPixel} from '../../../../../src/ol/render.js';
|
||||||
|
|
||||||
@@ -81,7 +82,8 @@ describe('ol/layer/WebGLTile', function () {
|
|||||||
it('retrieves pixel data', (done) => {
|
it('retrieves pixel data', (done) => {
|
||||||
const layer = new WebGLTileLayer({
|
const layer = new WebGLTileLayer({
|
||||||
source: new DataTileSource({
|
source: new DataTileSource({
|
||||||
tilePixelRatio: 1 / 256,
|
tileSize: 1,
|
||||||
|
tileGrid: createXYZ(),
|
||||||
loader(z, x, y) {
|
loader(z, x, y) {
|
||||||
return new Uint8Array([5, 4, 3, 2, 1]);
|
return new Uint8Array([5, 4, 3, 2, 1]);
|
||||||
},
|
},
|
||||||
@@ -106,7 +108,8 @@ describe('ol/layer/WebGLTile', function () {
|
|||||||
it('preserves the original data type', (done) => {
|
it('preserves the original data type', (done) => {
|
||||||
const layer = new WebGLTileLayer({
|
const layer = new WebGLTileLayer({
|
||||||
source: new DataTileSource({
|
source: new DataTileSource({
|
||||||
tilePixelRatio: 1 / 256,
|
tileSize: 1,
|
||||||
|
tileGrid: createXYZ(),
|
||||||
loader(z, x, y) {
|
loader(z, x, y) {
|
||||||
return new Float32Array([1.11, 2.22, 3.33, 4.44, 5.55]);
|
return new Float32Array([1.11, 2.22, 3.33, 4.44, 5.55]);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -40,6 +40,30 @@ describe('ol/source/DataTile', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getTileSize()', function () {
|
||||||
|
it('returns [256, 256] by default', function () {
|
||||||
|
const source = new DataTileSource({});
|
||||||
|
expect(source.getTileSize(0)).to.eql([256, 256]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects a tileSize passed to the constructor', function () {
|
||||||
|
const size = [1234, 5678];
|
||||||
|
const source = new DataTileSource({tileSize: size});
|
||||||
|
expect(source.getTileSize(0)).to.eql(size);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('picks from an array of sizes passed to setTileSizes()', function () {
|
||||||
|
const sizes = [
|
||||||
|
[123, 456],
|
||||||
|
[234, 567],
|
||||||
|
[345, 678],
|
||||||
|
];
|
||||||
|
const source = new DataTileSource({});
|
||||||
|
source.setTileSizes(sizes);
|
||||||
|
expect(source.getTileSize(1)).to.eql(sizes[1]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('#getInterpolate()', function () {
|
describe('#getInterpolate()', function () {
|
||||||
it('is false by default', function () {
|
it('is false by default', function () {
|
||||||
const source = new DataTileSource({loader: () => {}});
|
const source = new DataTileSource({loader: () => {}});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import DataTile from '../../../../src/ol/source/DataTile.js';
|
|||||||
import Map from '../../../../src/ol/Map.js';
|
import Map from '../../../../src/ol/Map.js';
|
||||||
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
|
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
|
||||||
import View from '../../../../src/ol/View.js';
|
import View from '../../../../src/ol/View.js';
|
||||||
|
// import {createXYZ} from '../../../../src/ol/tilegrid.js';
|
||||||
|
|
||||||
const size = 512;
|
const size = 512;
|
||||||
|
|
||||||
@@ -17,9 +18,14 @@ new Map({
|
|||||||
layers: [
|
layers: [
|
||||||
new TileLayer({
|
new TileLayer({
|
||||||
source: new DataTile({
|
source: new DataTile({
|
||||||
|
// remove this in the next major release
|
||||||
|
tilePixelRatio: 2,
|
||||||
|
|
||||||
|
// instead use an explicit source and render tile size
|
||||||
|
// tileSize: size,
|
||||||
|
// tileGrid: createXYZ({maxZoom: 0}),
|
||||||
maxZoom: 0,
|
maxZoom: 0,
|
||||||
loader: () => data,
|
loader: () => data,
|
||||||
tilePixelRatio: 2,
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
@@ -0,0 +1,21 @@
|
|||||||
|
import GeoTIFF from '../../../../src/ol/source/GeoTIFF.js';
|
||||||
|
import Map from '../../../../src/ol/Map.js';
|
||||||
|
import TileLayer from '../../../../src/ol/layer/WebGLTile.js';
|
||||||
|
|
||||||
|
const source = new GeoTIFF({
|
||||||
|
convertToRGB: true,
|
||||||
|
sources: [{url: '/data/raster/non-square-pixels.tif'}],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Map({
|
||||||
|
target: 'map',
|
||||||
|
layers: [new TileLayer({source})],
|
||||||
|
view: source.getView().then((config) => ({
|
||||||
|
...config,
|
||||||
|
rotation: Math.PI / 6,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
|
||||||
|
render({
|
||||||
|
message: 'properly renders rotated non-square pixels',
|
||||||
|
});
|
||||||
Binary file not shown.
Reference in New Issue
Block a user