From 88ad67df792738eab5841b90f84c0b58db47fcbe Mon Sep 17 00:00:00 2001 From: Bouillaguet Quentin Date: Thu, 21 Nov 2024 14:27:29 +0100 Subject: [PATCH] refacto: migrate Tile to typescript --- src/Core/Tile/{Tile.js => Tile.ts} | 52 +++++++++++++--------- src/Core/Tile/{TileGrid.js => TileGrid.ts} | 19 ++++---- 2 files changed, 43 insertions(+), 28 deletions(-) rename src/Core/Tile/{Tile.js => Tile.ts} (81%) rename src/Core/Tile/{TileGrid.js => TileGrid.ts} (72%) diff --git a/src/Core/Tile/Tile.js b/src/Core/Tile/Tile.ts similarity index 81% rename from src/Core/Tile/Tile.js rename to src/Core/Tile/Tile.ts index 7be73427ca..0d1b6199bb 100644 --- a/src/Core/Tile/Tile.js +++ b/src/Core/Tile/Tile.ts @@ -8,7 +8,7 @@ const _tmsCoord = new THREE.Vector2(); const _dimensionTile = new THREE.Vector2(); const r = { row: 0, col: 0, invDiff: 0 }; -function _rowColfromParent(/** @type {Tile} */ tile, /** @type {number} */ zoom) { +function _rowColfromParent(tile: Tile, zoom: number) { const diffLevel = tile.zoom - zoom; const diff = 2 ** diffLevel; r.invDiff = 1 / diff; @@ -24,6 +24,13 @@ const _extent2 = new Extent('EPSG:4326'); const _c = new Coordinates('EPSG:4326', 0, 0); class Tile { + readonly isTile: true; + + crs: string; + zoom: number; + row: number; + col: number; + /** * Tile is a geographical bounding rectangle defined by zoom, row and column. * @@ -32,7 +39,7 @@ class Tile { * @param {number} [row=0] row value * @param {number} [col=0] column value */ - constructor(crs, zoom = 0, row = 0, col = 0) { + constructor(crs: string, zoom = 0, row = 0, col = 0) { this.isTile = true; this.crs = crs; @@ -55,20 +62,20 @@ class Tile { * @param {Extent} target copy the destination to target. * @return {Extent} */ - toExtent(crs, target) { + toExtent(crs: string, target = new Extent('EPSG:4326')) { CRS.isValid(crs); - target = target || new Extent('EPSG:4326'); const { epsg, globalExtent, globalDimension } = getInfoTms(this.crs); const countTiles = getCountTiles(this.crs, this.zoom); _dimensionTile.set(1, 1).divide(countTiles).multiply(globalDimension); - target.west = globalExtent.west + (globalDimension.x - _dimensionTile.x * (countTiles.x - this.col)); + target.west = globalExtent.west + + (globalDimension.x - _dimensionTile.x * (countTiles.x - this.col)); target.east = target.west + _dimensionTile.x; - target.south = globalExtent.south + _dimensionTile.y * (countTiles.y - this.row - 1); + target.south = globalExtent.south + + _dimensionTile.y * (countTiles.y - this.row - 1); target.north = target.south + _dimensionTile.y; target.crs = epsg; - target.zoom = this.zoom; return crs == epsg ? target : target.as(crs, target); } @@ -80,14 +87,14 @@ class Tile { * * @return {boolean} */ - isInside(tile) { + isInside(tile: Tile) { if (this.zoom == tile.zoom) { return this.row == tile.row && this.col == tile.col; } else if (this.zoom < tile.zoom) { return false; } else { - _rowColfromParent(this, tile.zoom); + const r = _rowColfromParent(this, tile.zoom); return r.row == tile.row && r.col == tile.col; } } @@ -99,12 +106,12 @@ class Tile { * @param {THREE.Vector4} target copy the result to target. * @return {THREE.Vector4} {x: translation on west-east, y: translation on south-north, z: scale on west-east, w: scale on south-north} */ - offsetToParent(tile, target = new THREE.Vector4()) { + offsetToParent(tile: Tile, target = new THREE.Vector4()) { if (this.crs != tile.crs) { throw new Error('unsupported mix'); } - _rowColfromParent(this, tile.zoom); + const r = _rowColfromParent(this, tile.zoom); return target.set( this.col * r.invDiff - r.col, this.row * r.invDiff - r.row, @@ -117,9 +124,9 @@ class Tile { * @param {number} levelParent level of parent. * @return {Tile} */ - tiledExtentParent(levelParent) { + tiledExtentParent(levelParent: number) { if (levelParent && levelParent < this.zoom) { - _rowColfromParent(this, levelParent); + const r = _rowColfromParent(this, levelParent); return new Tile(this.crs, levelParent, r.row, r.col); } else { return this; @@ -148,7 +155,7 @@ class Tile { * @param {Tile} tile * @return {Tile} copied extent */ - copy(tile) { + copy(tile: Tile): this { this.crs = tile.crs; return this.set(tile.zoom, tile.row, tile.col); } @@ -168,7 +175,7 @@ class Tile { * @param {string} tms * @returns {Tile[]} */ -export function tiledCovering(e, tms) { +export function tiledCovering(e: Extent, tms: string) { if (e.crs == 'EPSG:4326' && tms == 'EPSG:3857') { const WMTS_PM = []; const extent = _extent.copy(e).as(tms, _extent2); @@ -176,7 +183,8 @@ export function tiledCovering(e, tms) { extent.clampByExtent(globalExtent); extent.planarDimensions(_dimensionTile); - const zoom = (e.zoom + 1) || Math.floor(Math.log2(Math.round(globalDimension.x / (_dimensionTile.x * sTs.x)))); + const zoom = Math.floor(Math.log2( + Math.round(globalDimension.x / (_dimensionTile.x * sTs.x)))); const countTiles = getCountTiles(tms, zoom); const center = extent.center(_c); @@ -185,7 +193,8 @@ export function tiledCovering(e, tms) { _tmsCoord.divide(globalDimension).multiply(countTiles).floor(); // ]N; N+1] => N - const maxRow = Math.ceil((globalExtent.north - extent.south) / globalDimension.x * countTiles.y) - 1; + const maxRow = Math.ceil( + (globalExtent.north - extent.south) / globalDimension.x * countTiles.y) - 1; for (let r = maxRow; r >= _tmsCoord.y; r--) { WMTS_PM.push(new Tile(tms, zoom, r, _tmsCoord.x)); @@ -198,12 +207,15 @@ export function tiledCovering(e, tms) { const center = e.center(_c); e.planarDimensions(_dimensionTile); // Each level has 2^n * 2^n tiles... - // ... so we count how many tiles of the same width as tile we can fit in the layer + // ... so we count how many tiles of the same width as tile we can fit + // in the layer // ... 2^zoom = tilecount => zoom = log2(tilecount) - const zoom = Math.floor(Math.log2(Math.round(globalDimension.x / (_dimensionTile.x * sTs.x)))); + const zoom = Math.floor(Math.log2( + Math.round(globalDimension.x / (_dimensionTile.x * sTs.x)))); const countTiles = getCountTiles(tms, zoom); - // Now that we have computed zoom, we can deduce x and y (or row / column) + // Now that we have computed zoom, we can deduce x and y (or row / + // column) _tmsCoord.x = center.x - globalExtent.west; _tmsCoord.y = isInverted ? globalExtent.north - center.y : center.y - globalExtent.south; _tmsCoord.divide(globalDimension).multiply(countTiles).floor(); diff --git a/src/Core/Tile/TileGrid.js b/src/Core/Tile/TileGrid.ts similarity index 72% rename from src/Core/Tile/TileGrid.js rename to src/Core/Tile/TileGrid.ts index a6eb619b35..f1fad053fa 100644 --- a/src/Core/Tile/TileGrid.js +++ b/src/Core/Tile/TileGrid.ts @@ -4,8 +4,8 @@ import Extent from '../Geographic/Extent'; const _countTiles = new THREE.Vector2(); const _dim = new THREE.Vector2(); -export const globalExtentTMS = new Map(); -export const schemeTiles = new Map(); +export const globalExtentTMS: Map = new Map(); +export const schemeTiles: Map = new Map(); const extent4326 = new Extent('EPSG:4326', -180, 180, -90, 90); globalExtentTMS.set('EPSG:4326', extent4326); @@ -17,14 +17,17 @@ const extent3857 = extent4326.as('EPSG:3857'); extent3857.clampSouthNorth(extent3857.west, extent3857.east); globalExtentTMS.set('EPSG:3857', extent3857); -schemeTiles.set('default', new THREE.Vector2(1, 1)); -schemeTiles.set('EPSG:3857', schemeTiles.get('default')); +const defaultScheme = new THREE.Vector2(1, 1); +schemeTiles.set('EPSG:3857', defaultScheme); schemeTiles.set('EPSG:4326', new THREE.Vector2(2, 1)); -export function getInfoTms(/** @type {string} */ crs) { +export function getInfoTms(crs: string) { const globalExtent = globalExtentTMS.get(crs); + if (!globalExtent) { + throw new Error(`The tile matrix set ${crs} is not defined.`); + } const globalDimension = globalExtent.planarDimensions(_dim); - const sTs = schemeTiles.get(crs) || schemeTiles.get('default'); + const sTs = schemeTiles.get(crs) ?? defaultScheme; // The isInverted parameter is to be set to the correct value, true or false // (default being false) if the computation of the coordinates needs to be // inverted to match the same scheme as OSM, Google Maps or other system. @@ -35,8 +38,8 @@ export function getInfoTms(/** @type {string} */ crs) { return { epsg: crs, globalExtent, globalDimension, sTs, isInverted }; } -export function getCountTiles(/** @type {string} */ crs, /** @type {number} */ zoom) { - const sTs = schemeTiles.get(crs) || schemeTiles.get('default'); +export function getCountTiles(crs: string, zoom: number) { + const sTs = schemeTiles.get(crs) || defaultScheme; const count = 2 ** zoom; _countTiles.set(count, count).multiply(sTs); return _countTiles;