@openglobus/og 1.0.0-rc35 → 1.0.0-rc36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/lib/Globe.d.ts +1 -0
  2. package/lib/assets/RasterWorker.worker-BLX-1P4n.js.map +1 -0
  3. package/lib/assets/RgbTerrainWorker.worker-Bxbv73rB.js.map +1 -0
  4. package/lib/assets/TerrainWorker.worker-DIGKd23M.js.map +1 -1
  5. package/lib/camera/Camera.d.ts +1 -1
  6. package/lib/camera/PlanetCamera.d.ts +9 -0
  7. package/lib/control/PoweredBy.d.ts +15 -0
  8. package/lib/control/TouchNavigation.d.ts +1 -0
  9. package/lib/control/depthCamera/DepthCamera.d.ts +1 -0
  10. package/lib/control/entityEditor/ProjectorEditorView.d.ts +2 -0
  11. package/lib/control/index.d.ts +1 -0
  12. package/lib/index.d.ts +3 -3
  13. package/lib/layer/GeoTIFFLayer.d.ts +0 -7
  14. package/lib/layer/geotiff/GeoTIFFReader.d.ts +17 -1
  15. package/lib/layer/geotiff/warp.d.ts +25 -0
  16. package/lib/og.css +1 -1
  17. package/lib/og.es.js +1 -1
  18. package/lib/og.es.js.map +1 -1
  19. package/lib/renderer/Renderer.d.ts +2 -0
  20. package/lib/renderer/projectors/Projector.d.ts +49 -3
  21. package/lib/renderer/projectors/ProjectorManager.d.ts +88 -5
  22. package/lib/segment/Segment.d.ts +1 -0
  23. package/lib/shaders/common/uniforms.d.ts +7 -0
  24. package/lib/terrain/EmptyTerrain.d.ts +16 -1
  25. package/lib/terrain/GeoTiffTerrain.d.ts +46 -0
  26. package/lib/terrain/GlobusTerrain.d.ts +2 -1
  27. package/lib/terrain/ProceduralTerrain.d.ts +49 -12
  28. package/lib/terrain/RgbTerrain.d.ts +6 -1
  29. package/lib/terrain/index.d.ts +5 -3
  30. package/lib/terrain/terrainUtils.d.ts +46 -0
  31. package/lib/utils/LRUCache.d.ts +39 -0
  32. package/lib/utils/RasterWorker.d.ts +36 -0
  33. package/lib/utils/RasterWorker.worker.d.ts +1 -0
  34. package/package.json +4 -4
  35. package/lib/assets/RgbTerrainWorker.worker-BL6dQGZ3.js.map +0 -1
package/lib/Globe.d.ts CHANGED
@@ -63,6 +63,7 @@ export interface IGlobeParams {
63
63
  disableTilt?: boolean;
64
64
  };
65
65
  layers?: Layer[];
66
+ poweredBy?: boolean;
66
67
  viewExtent?: Extent | NumberArray4;
67
68
  autoActivate?: boolean;
68
69
  fontsSrc?: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RasterWorker.worker-BLX-1P4n.js","names":["getEdgeHeight","p0","p1","p2","s0","s1","Math","abs","interpolateRow","pixels","offset","size","halfSteps","out","last","min","max","prev","k","h","createVertexGrid","noDataHeight","pixelCenters","gs","columns","Float32Array","rowColumns","subarray","lastRow","vi","u","dst","needRow","set","c0","c1","c2","vj","averagePixels","ui","uj","ki","kj","sum","count","i","i1","j","j1","_around","Uint8Array","compareNeighbours","around","a","b","ha","hb","findPeaks","scale","length","fill","r","row","end","rowStart","Int32Array","cols","isPeak","c","_deviations","sampleSubGrid","grid","row0","col0","cells","gridSize","outOffset","peaks","NaN","outGs","step","src","half","inner","pr0","ceil","pr1","floor","pc0","pc1","pr","p","hi","m","y","ci","fy","top","bottom","vertexRow","x","cj","fx","h00","h01","h10","h11","surface","deviation","v","keepPeaks","isPixelCentersGrid","levels","createHeightsLevelsSource","decodeRow","getGridCells","createTileHeights","source","level","tilePixels","w","windowPixels","createLevelHeights","tileLength","tilesCount","d","createHeightsLevels","warpRasters","rasters","gridU","gridV","imgWidth","imgHeight","tileSize","bilinear","maskRaster","winX0","winY0","winX1","winY1","window","winWidth","winHeight","side","cellSize","checkNoData","nodata","Number","isNaN","val","fNodata","fround","absDiff","maxVal","getFastNoDataChecker","push","gy","j0","gx","i0","n00","n10","n01","n11","w00","w10","w01","w11","sx","sy","outIdx","mx","round","x0","y0","tx","ty","x1","y1","cx0","cy0","i00","i10","i01","i11","v00","v10","v01","v11","px","srcIdx","self","onmessage","e","result","transfer","type","heights","buffer","map","makeResult","data","err","console","error","postMessage","id","t","e","n","a","i","o","f","h","s","u","M","m","c","N","x","l","y","b","g","d","w","A","p","z","F","S","k","U","H","v","D","I","P","R","V","W"],"sources":["../../src/terrain/terrainUtils.ts","../../src/layer/geotiff/ColorScale.ts","../../src/layer/geotiff/warp.ts","../../src/utils/RasterWorker.worker.js"],"sourcesContent":["import type { TypedArray } from \"../utils/shared\";\nimport type { Extent } from \"../Extent\";\n\nexport const RGB_ENCODING_CUSTOM = -1;\nexport const RGB_ENCODING_RGB = 0;\nexport const RGB_ENCODING_TERRARIUM = 1;\n\n/** Segment grid sizes by zoom of the elevation terrains. */\nexport const TERRAIN_GRID_SIZE_BY_ZOOM = [\n 64, 32, 16, 8, 8, 8, 16, 16, 16, 32, 32, 32, 32, 32, 32, 64, 64, 64, 32, 32, 16, 8\n];\n\n/** Writes a row of pixel heights, NaN for no data pixels. */\nexport type DecodeHeightsRowFunc = (row: number, outHeights: Float32Array) => void;\n\nexport interface IRgbDecodeParams {\n encoding: number;\n minHeight: number;\n resolution: number;\n heightFactor: number;\n noDataValues: number[] | TypedArray;\n parentData: number[] | TypedArray | null;\n parentOffsetX: number;\n parentOffsetY: number;\n parentZoomDiff: number;\n skipPositiveHeights: boolean;\n}\n\nexport interface IRgbHeightsParams {\n decode: IRgbDecodeParams;\n size: number;\n gridSize: number;\n levels: number;\n noDataHeight: number;\n}\n\n/**\n * Returns pixel grid cells for the image size, 2^n and (2^n + 1) sizes only.\n * @param {number} size - Image size.\n * @returns {number} -\n */\nexport function getGridCells(size: number): number {\n return (size & (size - 1)) === 0 ? size : size - 1;\n}\n\n/**\n * Returns vertex grid cells for the image size. 2^n images have vertices at the pixel centers and corners,\n * (2^n + 1) images are the grid itself.\n * @param {number} size - Image size.\n * @returns {number} -\n */\nexport function getVertexGridCells(size: number): number {\n let cells = getGridCells(size);\n return cells === size ? cells * 2 : cells;\n}\n\n/**\n * Returns subdivision levels of the image tile. Native zoom levels are not finer than the image pixels,\n * finer data comes with their own tiles. Levels above the native zooms go down to the vertex grid.\n * @param {number} size - Image size.\n * @param {number} gridSize - Tile grid size.\n * @param {number} tileZoom - Image tile zoom.\n * @param {number} maxZoom - Maximal terrain zoom.\n * @param {number} maxNativeZoom - Maximal zoom of the terrain tiles.\n * @returns {number} -\n */\nexport function getSubdivisionLevels(\n size: number,\n gridSize: number,\n tileZoom: number,\n maxZoom: number,\n maxNativeZoom: number\n): number {\n let pixelCells = getGridCells(size),\n vertexCells = getVertexGridCells(size),\n levels = 0;\n\n for (let k = 1; tileZoom + k <= maxZoom; k++) {\n if ((tileZoom + k > maxNativeZoom ? vertexCells : pixelCells) >> k < gridSize) {\n break;\n }\n levels = k;\n }\n\n return levels;\n}\n\nfunction isNoDataValue(noDataValues: number[] | TypedArray, ndMin: number, ndMax: number, h: number): boolean {\n if (h > 50000) {\n return true;\n }\n if (h <= ndMin || h >= ndMax) {\n return false;\n }\n let start = 0,\n end = noDataValues.length - 1;\n while (start <= end) {\n let k = (start + end) >> 1;\n if (Math.abs(noDataValues[k] - h) < 1e-3) {\n return true;\n } else if (noDataValues[k] < h) {\n start = k + 1;\n } else {\n end = k - 1;\n }\n }\n return false;\n}\n\nexport function getParentHeight(\n oneByDz2: number,\n offsetX: number,\n offsetY: number,\n heights: TypedArray | number[],\n i: number,\n j: number,\n skipPositiveHeights?: boolean\n) {\n let parentGridSize = Math.sqrt(heights.length);\n let pi = Math.floor(offsetY * oneByDz2 * parentGridSize + i * oneByDz2),\n pj = Math.floor(offsetX * oneByDz2 * parentGridSize + j * oneByDz2);\n let h = heights[pi * parentGridSize + pj];\n return skipPositiveHeights ? (h > 0 ? 0 : h) : h;\n}\n\n/**\n * Decodes \"rgb\" or \"terrarium\" encoded pixel row heights.\n * @param {number[] | TypedArray} rgbaData - Image RGBA data.\n * @param {number} row - Pixel row.\n * @param {number} size - Image size.\n * @param {number} parentScale - Parent grid cells by image grid cells.\n * @param {IRgbDecodeParams} p - Decode parameters.\n * @param {Float32Array} outHeights - Row heights.\n * @param {number} noDataHeight - Height for no data pixels.\n */\nexport function decodeRgbHeightsRow(\n rgbaData: number[] | TypedArray,\n row: number,\n size: number,\n parentScale: number,\n p: IRgbDecodeParams,\n outHeights: Float32Array,\n noDataHeight: number\n) {\n let ndv = p.noDataValues,\n ndMin = ndv.length ? ndv[0] - 1e-3 : 0,\n ndMax = ndv.length ? ndv[ndv.length - 1] + 1e-3 : 0;\n\n let isTerrarium = p.encoding === RGB_ENCODING_TERRARIUM,\n minHeight = p.minHeight,\n resolution = p.resolution,\n heightFactor = p.heightFactor,\n parentData = p.parentData;\n\n let pi = Math.floor(row * parentScale);\n\n for (let j = 0, k4 = row * size * 4; j < size; j++, k4 += 4) {\n let r = rgbaData[k4],\n g = rgbaData[k4 + 1],\n b = rgbaData[k4 + 2];\n\n let height = isTerrarium\n ? r * 256 + g + b / 256 - 32768\n : r === 255\n ? minHeight\n : minHeight + resolution * (r * 65536 + g * 256 + b);\n\n height *= heightFactor;\n\n let isNoData = isNoDataValue(ndv, ndMin, ndMax, height);\n\n if ((isNoData || height === 0) && parentData) {\n height = getParentHeight(\n p.parentZoomDiff,\n p.parentOffsetX,\n p.parentOffsetY,\n parentData,\n pi,\n Math.floor(j * parentScale),\n p.skipPositiveHeights\n );\n isNoData = isNoDataValue(ndv, ndMin, ndMax, height);\n }\n\n outHeights[j] = isNoData ? noDataHeight : height;\n }\n}\n\n/**\n * Returns the height at the tile edge, extrapolated from the edge pixel p0 inwards through p1 and p2.\n * The slope is limited (minmod), so peaks, pits and slope breaks at the edge are not overshot.\n * @param {number} p0 - Edge pixel height.\n * @param {number} p1 - Next pixel height.\n * @param {number} p2 - Pixel height after the next.\n * @returns {number} -\n */\nexport function getEdgeHeight(p0: number, p1: number, p2: number): number {\n let s0 = p0 - p1,\n s1 = p1 - p2;\n return p0 + 0.5 * (s0 * s1 <= 0 ? 0 : Math.abs(s0) < Math.abs(s1) ? s0 : s1);\n}\n\n/**\n * Returns the ground height at the point of the tile heights grid, on the grid triangles as they are rendered.\n * @param {number} x - Point x in the tile extent projection.\n * @param {number} y - Point y in the tile extent projection.\n * @param {Extent} extent - Tile extent.\n * @param {number[] | TypedArray} heights - Tile heights grid, rows from north to south.\n * @returns {number} -\n */\nexport function getGroundHeight(x: number, y: number, extent: Extent, heights: number[] | TypedArray): number {\n let gs = Math.sqrt(heights.length),\n cells = gs - 1,\n col = ((x - extent.southWest.lon) / extent.getWidth()) * cells,\n row = ((extent.northEast.lat - y) / extent.getHeight()) * cells,\n j = Math.min(Math.max(Math.floor(col), 0), cells - 1),\n i = Math.min(Math.max(Math.floor(row), 0), cells - 1),\n fx = col - j,\n fy = 1 - (row - i);\n\n /*\n v2-----------v3\n | \\ |\n | \\ |\n | \\ |\n v0-----------v1\n */\n let k = i * gs + j,\n h2 = heights[k],\n h3 = heights[k + 1],\n h0 = heights[k + gs],\n h1 = heights[k + gs + 1];\n\n return fx + fy <= 1 ? h0 + fx * (h1 - h0) + fy * (h2 - h0) : h3 + (1 - fx) * (h2 - h3) + (1 - fy) * (h1 - h3);\n}\n\n/**\n * Writes the pixel row heights at the vertex columns: the edges, the pixel corners and, with half pixel steps,\n * the pixel centers.\n */\nfunction interpolateRow(pixels: Float32Array, offset: number, size: number, halfSteps: number, out: Float32Array) {\n let last = offset + size - 1;\n\n out[0] = getEdgeHeight(pixels[offset], pixels[Math.min(offset + 1, last)], pixels[Math.min(offset + 2, last)]);\n\n out[(size * 2) / halfSteps] = getEdgeHeight(\n pixels[last],\n pixels[Math.max(last - 1, offset)],\n pixels[Math.max(last - 2, offset)]\n );\n\n if (halfSteps === 1) {\n let prev = pixels[offset];\n out[1] = prev;\n for (let k = 1; k < size; k++) {\n let h = pixels[offset + k];\n out[k * 2] = 0.5 * (prev + h);\n out[k * 2 + 1] = h;\n prev = h;\n }\n } else {\n for (let k = 1; k < size; k++) {\n out[k] = 0.5 * (pixels[offset + k - 1] + pixels[offset + k]);\n }\n }\n}\n\n/**\n * Converts size x size pixel heights to the vertex grid in the pixel corners, (size + 1) x (size + 1),\n * or in the pixel centers and corners, (2 * size + 1) x (2 * size + 1). Pixel center vertices keep the pixel heights.\n * @param {Float32Array} pixels - Pixel heights, NaN for no data.\n * @param {number} size - Image size.\n * @param {number} noDataHeight - Height for vertices without data around.\n * @param {boolean} [pixelCenters=true] - Vertices at the pixel centers too.\n * @returns {Float32Array} -\n */\nexport function createVertexGrid(\n pixels: Float32Array,\n size: number,\n noDataHeight: number,\n pixelCenters: boolean = true\n): Float32Array {\n let halfSteps = pixelCenters ? 1 : 2,\n gs = (size * 2) / halfSteps + 1,\n last = size - 1;\n\n // Heights at the vertex columns of the last three pixel rows, pixel row r is kept at (r % 3)\n let columns = new Float32Array(gs * 3),\n rowColumns = [columns.subarray(0, gs), columns.subarray(gs, gs * 2), columns.subarray(gs * 2)],\n lastRow = -1;\n\n let out = new Float32Array(gs * gs);\n\n for (let vi = 0; vi < gs; vi++) {\n let u = vi * halfSteps,\n k = u >> 1,\n dst = vi * gs;\n\n let needRow = u === 0 ? Math.min(2, last) : Math.min(k, last);\n\n while (lastRow < needRow) {\n lastRow++;\n interpolateRow(pixels, lastRow * size, size, halfSteps, rowColumns[lastRow % 3]);\n }\n\n if (u & 1) {\n out.set(rowColumns[k % 3], dst);\n } else if (k === 0 || k === size) {\n let c0 = rowColumns[(k === 0 ? 0 : last) % 3],\n c1 = rowColumns[(k === 0 ? Math.min(1, last) : Math.max(last - 1, 0)) % 3],\n c2 = rowColumns[(k === 0 ? Math.min(2, last) : Math.max(last - 2, 0)) % 3];\n\n for (let vj = 0; vj < gs; vj++) {\n out[dst + vj] = getEdgeHeight(c0[vj], c1[vj], c2[vj]);\n }\n } else {\n let c0 = rowColumns[(k - 1) % 3],\n c1 = rowColumns[k % 3];\n\n for (let vj = 0; vj < gs; vj++) {\n out[dst + vj] = 0.5 * (c0[vj] + c1[vj]);\n }\n }\n\n for (let vj = 0; vj < gs; vj++) {\n if (out[dst + vj] !== out[dst + vj]) {\n out[dst + vj] = averagePixels(pixels, size, u, vj * halfSteps, noDataHeight);\n }\n }\n }\n\n return out;\n}\n\nfunction averagePixels(pixels: Float32Array, size: number, ui: number, uj: number, noDataHeight: number): number {\n let last = size - 1,\n ki = ui >> 1,\n kj = uj >> 1,\n sum = 0,\n count = 0;\n\n for (let i = Math.max(ki - 1, 0), i1 = Math.min(ki + (ui & 1), last); i <= i1; i++) {\n for (let j = Math.max(kj - 1, 0), j1 = Math.min(kj + (uj & 1), last); j <= j1; j++) {\n let h = pixels[i * size + j];\n if (h === h) {\n sum += h;\n count++;\n }\n }\n }\n\n return count ? sum / count : noDataHeight;\n}\n\n/** Peak and pit pixels, and their place in the vertex grid. */\nexport interface IGridPeaks {\n pixels: Float32Array;\n size: number;\n /** Peaks by pixel rows, columns of row r are cols[rowStart[r]] ... cols[rowStart[r + 1] - 1]. */\n rowStart: Int32Array;\n cols: Int32Array;\n /** 1 for peaks, 0 for pits. */\n isPeak: Uint8Array;\n /** Pixel p is at (p + offset) * scale vertex. */\n offset: number;\n scale: number;\n}\n\nconst HIGHER_AROUND = 1,\n LOWER_AROUND = 2;\n\nlet _around = new Uint8Array(0);\n\n/** Marks pixels a and b with the neighbour higher or lower flags, NaN pixels are not compared. */\nfunction compareNeighbours(pixels: Float32Array, around: Uint8Array, a: number, b: number) {\n let ha = pixels[a],\n hb = pixels[b];\n\n if (hb > ha) {\n around[a] |= HIGHER_AROUND;\n around[b] |= LOWER_AROUND;\n } else if (hb < ha) {\n around[a] |= LOWER_AROUND;\n around[b] |= HIGHER_AROUND;\n }\n}\n\n/**\n * Finds the pixels that are not lower (peaks) or not higher (pits) than the pixels around,\n * and differ from at least one of them.\n * @param {Float32Array} pixels - Pixel heights, NaN for no data.\n * @param {number} size - Image size.\n * @param {number} offset - Pixel p is at (p + offset) * scale vertex of the grid.\n * @param {number} scale - Grid vertices by pixel.\n * @returns {IGridPeaks} -\n */\nexport function findPeaks(pixels: Float32Array, size: number, offset: number, scale: number): IGridPeaks {\n let last = size - 1,\n length = size * size;\n\n if (_around.length < length) {\n _around = new Uint8Array(length);\n } else {\n _around.fill(0, 0, length);\n }\n\n let around = _around;\n\n // Every neighbour pair is compared once, in 2x2 squares a b / c d: a-b, a-c, a-d and b-c\n for (let r = 0; r < last; r++) {\n let row = r * size;\n for (let k = row, end = row + last; k < end; k++) {\n compareNeighbours(pixels, around, k, k + 1);\n compareNeighbours(pixels, around, k, k + size);\n compareNeighbours(pixels, around, k, k + size + 1);\n compareNeighbours(pixels, around, k + 1, k + size);\n }\n compareNeighbours(pixels, around, row + last, row + last + size);\n }\n for (let k = last * size, end = k + last; k < end; k++) {\n compareNeighbours(pixels, around, k, k + 1);\n }\n\n let rowStart = new Int32Array(size + 1),\n count = 0;\n\n for (let k = 0; k < length; k++) {\n if (around[k] === HIGHER_AROUND || around[k] === LOWER_AROUND) {\n count++;\n }\n }\n\n let cols = new Int32Array(count),\n isPeak = new Uint8Array(count);\n\n count = 0;\n\n for (let r = 0; r < size; r++) {\n rowStart[r] = count;\n for (let c = 0, k = r * size; c < size; c++, k++) {\n if (around[k] === HIGHER_AROUND || around[k] === LOWER_AROUND) {\n cols[count] = c;\n isPeak[count] = around[k] === LOWER_AROUND ? 1 : 0;\n count++;\n }\n }\n }\n\n rowStart[size] = count;\n\n return { pixels, size, rowStart, cols, isPeak, offset, scale };\n}\n\n// Peak deviations of the sampled grid vertices, reused\nlet _deviations = new Float32Array(0);\n\n/**\n * Takes (gridSize + 1) x (gridSize + 1) vertices of the cells x cells square starting at\n * the row0, col0 vertex of the (size + 1) x (size + 1) grid. Cells must be gridSize multiplied by a power of two.\n *\n * With peaks, peaks and pits are moved to the nearest inner vertices, slopes and edge vertices stay sampled.\n */\nexport function sampleSubGrid(\n grid: Float32Array,\n size: number,\n row0: number,\n col0: number,\n cells: number,\n gridSize: number,\n out: Float32Array = new Float32Array((gridSize + 1) * (gridSize + 1)),\n outOffset: number = 0,\n peaks: IGridPeaks | null = null,\n noDataHeight: number = NaN\n): Float32Array {\n let gs = size + 1,\n outGs = gridSize + 1,\n step = cells / gridSize;\n\n for (let i = 0; i < outGs; i++) {\n let src = (row0 + i * step) * gs + col0,\n dst = outOffset + i * outGs;\n for (let j = 0; j < outGs; j++) {\n out[dst + j] = grid[src + j * step];\n }\n }\n\n if (peaks && step > 1 && gridSize > 1) {\n keepPeaks(grid, gs, row0, col0, cells, gridSize, out, outOffset, peaks, noDataHeight);\n }\n\n return out;\n}\n\nfunction keepPeaks(\n grid: Float32Array,\n gs: number,\n row0: number,\n col0: number,\n cells: number,\n gridSize: number,\n out: Float32Array,\n outOffset: number,\n peaks: IGridPeaks,\n noDataHeight: number\n) {\n let outGs = gridSize + 1,\n step = cells / gridSize,\n half = step >> 1,\n inner = gridSize - 1,\n { pixels, size, rowStart, cols, isPeak, offset, scale } = peaks;\n\n // Pixels in the square\n let pr0 = Math.max(Math.ceil(row0 / scale - offset), 0),\n pr1 = Math.min(Math.floor((row0 + cells) / scale - offset), size - 1),\n pc0 = Math.max(Math.ceil(col0 / scale - offset), 0),\n pc1 = Math.min(Math.floor((col0 + cells) / scale - offset), size - 1);\n\n if (_deviations.length < outGs * outGs) {\n _deviations = new Float32Array(outGs * outGs);\n }\n\n _deviations.fill(0, 0, outGs * outGs);\n\n for (let pr = pr0; pr <= pr1; pr++) {\n let p = rowStart[pr],\n end = rowStart[pr + 1];\n\n for (let hi = end; p < hi;) {\n let m = (p + hi) >> 1;\n if (cols[m] < pc0) {\n p = m + 1;\n } else {\n hi = m;\n }\n }\n\n if (p === end || cols[p] > pc1) {\n continue;\n }\n\n let y = (pr + offset) * scale - row0,\n ci = Math.min(Math.floor(y / step), inner),\n fy = y / step - ci,\n i = Math.min(Math.max(Math.floor((y + half) / step), 1), inner),\n top = (row0 + ci * step) * gs + col0,\n bottom = top + step * gs,\n vertexRow = (row0 + i * step) * gs + col0;\n\n for (; p < end && cols[p] <= pc1; p++) {\n let x = (cols[p] + offset) * scale - col0,\n cj = Math.min(Math.floor(x / step), inner),\n fx = x / step - cj,\n k = cj * step;\n\n let h00 = grid[top + k],\n h01 = grid[top + k + step],\n h10 = grid[bottom + k],\n h11 = grid[bottom + k + step];\n\n if (h00 === noDataHeight || h01 === noDataHeight || h10 === noDataHeight || h11 === noDataHeight) {\n continue;\n }\n\n let surface = (1 - fy) * ((1 - fx) * h00 + fx * h01) + fy * ((1 - fx) * h10 + fx * h11),\n h = pixels[pr * size + cols[p]],\n deviation = isPeak[p] ? h - surface : surface - h;\n\n if (deviation <= 0 || h === noDataHeight) {\n continue;\n }\n\n let j = Math.min(Math.max(Math.floor((x + half) / step), 1), inner),\n v = i * outGs + j;\n\n if (deviation > _deviations[v] && deviation > Math.abs(surface - grid[vertexRow + j * step])) {\n _deviations[v] = deviation;\n out[outOffset + v] = h;\n }\n }\n }\n}\n\n/**\n * Returns (gridSize + 1) x (gridSize + 1) mesh heights of (fileGridSize + 1) x (fileGridSize + 1) elevations,\n * their peaks and pits are moved to the nearest mesh vertices.\n * @param {Float32Array} elevations - Elevations grid, rows from north to south.\n * @param {number} fileGridSize - Elevations grid size.\n * @param {number} gridSize - Mesh grid size, fileGridSize divided by a power of two.\n * @param {number} noDataHeight - Height of no data elevations.\n * @param {Float32Array} [out] - Mesh heights.\n * @returns {Float32Array} -\n */\nexport function getMeshHeights(\n elevations: Float32Array,\n fileGridSize: number,\n gridSize: number,\n noDataHeight: number,\n out: Float32Array = new Float32Array((gridSize + 1) * (gridSize + 1))\n): Float32Array {\n return sampleSubGrid(\n elevations,\n fileGridSize,\n 0,\n 0,\n fileGridSize,\n gridSize,\n out,\n 0,\n findPeaks(elevations, fileGridSize + 1, 0, 1),\n noDataHeight\n );\n}\n\n/**\n * Tile pixels, the source of its subdivision level tiles made one by one with createLevelHeights.\n */\nexport interface IHeightsLevelsSource {\n /** Pixel heights, NaN for no data. (2^n + 1) images are the vertex grid, no data are noDataHeight there. */\n pixels: Float32Array;\n size: number;\n gridSize: number;\n levels: number;\n noDataHeight: number;\n /** Peaks of the (2^n + 1) vertex grid, 2^n images find them around every level tile. */\n peaks: IGridPeaks | null;\n}\n\n// Vertices at the pixel centers are needed when the last level is not coarser than the pixels,\n// pixel corners alone would average its peaks and pits away\nfunction isPixelCentersGrid(size: number, gridSize: number, levels: number): boolean {\n return size >> levels <= gridSize;\n}\n\n/**\n * Decodes the tile pixels for its subdivision level tiles.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels.\n * @param {DecodeHeightsRowFunc} decodeRow - Decodes pixel row heights, NaN for no data.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {IHeightsLevelsSource} -\n */\nexport function createHeightsLevelsSource(\n size: number,\n gridSize: number,\n levels: number,\n decodeRow: DecodeHeightsRowFunc,\n noDataHeight: number\n): IHeightsLevelsSource {\n let pixels = new Float32Array(size * size),\n peaks: IGridPeaks | null = null;\n\n for (let row = 0; row < size; row++) {\n decodeRow(row, pixels.subarray(row * size, (row + 1) * size));\n }\n\n if (getGridCells(size) !== size) {\n peaks = findPeaks(pixels, size, 0, 1);\n for (let k = 0; k < pixels.length; k++) {\n if (pixels[k] !== pixels[k]) {\n pixels[k] = noDataHeight;\n }\n }\n }\n\n return { pixels, size, gridSize, levels, noDataHeight, peaks };\n}\n\n// Pixels around a level tile in its window: vertices and peaks depend on the next pixels only, at the image\n// edges the window is shifted inside and keeps the three pixels the edge vertices are extrapolated from\nconst LEVEL_TILE_MARGIN = 1;\n\n/**\n * Returns the heights of the level tile in the row i and the column j, the same as createHeightsLevels makes.\n * 2^n images make the vertex grid and find the peaks in the window of the tile pixels with a margin around,\n * so a tile costs its own pixels only.\n * @param {IHeightsLevelsSource} source - Tile pixels.\n * @param {number} level - Subdivision level, 0 is the tile itself.\n * @param {number} i - Level tile row, from the north.\n * @param {number} j - Level tile column, from the west.\n * @param {Float32Array} [out] - Level tile heights.\n * @returns {Float32Array} -\n */\nexport function createLevelHeights(\n source: IHeightsLevelsSource,\n level: number,\n i: number,\n j: number,\n out: Float32Array = new Float32Array((source.gridSize + 1) * (source.gridSize + 1))\n): Float32Array {\n let { pixels, size, gridSize, levels, noDataHeight, peaks } = source;\n\n if (peaks) {\n let c = (size - 1) >> level;\n return sampleSubGrid(pixels, size - 1, i * c, j * c, c, gridSize, out, 0, peaks, noDataHeight);\n }\n\n let pixelCenters = isPixelCentersGrid(size, gridSize, levels),\n scale = pixelCenters ? 2 : 1,\n tilePixels = size >> level,\n w = Math.min(tilePixels + 2 * LEVEL_TILE_MARGIN, size),\n row0 = Math.min(Math.max(i * tilePixels - LEVEL_TILE_MARGIN, 0), size - w),\n col0 = Math.min(Math.max(j * tilePixels - LEVEL_TILE_MARGIN, 0), size - w);\n\n let windowPixels = pixels;\n\n if (w < size) {\n windowPixels = new Float32Array(w * w);\n for (let r = 0; r < w; r++) {\n let src = (row0 + r) * size + col0;\n windowPixels.set(pixels.subarray(src, src + w), r * w);\n }\n }\n\n return sampleSubGrid(\n createVertexGrid(windowPixels, w, noDataHeight, pixelCenters),\n w * scale,\n (i * tilePixels - row0) * scale,\n (j * tilePixels - col0) * scale,\n tilePixels * scale,\n gridSize,\n out,\n 0,\n findPeaks(windowPixels, w, 0.5, scale),\n noDataHeight\n );\n}\n\n/**\n * Returns the (gridSize + 1) x (gridSize + 1) heights of the tile pixels, peaks and pits stay. Subdivision levels\n * the pixels are kept for change the vertex grid, so the tile is made as its level 0.\n * @param {Float32Array} pixels - Pixel heights, rows from north to south, NaN for no data.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels of the tile pixels.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {Float32Array} -\n */\nexport function createTileHeights(\n pixels: Float32Array,\n size: number,\n gridSize: number,\n levels: number,\n noDataHeight: number\n): Float32Array {\n let decodeRow = (row: number, out: Float32Array) => out.set(pixels.subarray(row * size, (row + 1) * size));\n\n if (!levels) {\n return createHeightsLevels(size, gridSize, 0, decodeRow, noDataHeight);\n }\n\n return createLevelHeights(createHeightsLevelsSource(size, gridSize, levels, decodeRow, noDataHeight), 0, 0, 0);\n}\n\n/**\n * Creates the tile heights grid and its subdivision levels, each tile is (gridSize + 1) x (gridSize + 1).\n * Output order is the tile itself, then 2x2 tiles of the first level, 4x4 of the second and so on, row by row.\n * Peaks and pits of the pixels stay in all the levels.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels.\n * @param {DecodeHeightsRowFunc} decodeRow - Decodes pixel row heights, NaN for no data.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {Float32Array} -\n */\nexport function createHeightsLevels(\n size: number,\n gridSize: number,\n levels: number,\n decodeRow: DecodeHeightsRowFunc,\n noDataHeight: number\n): Float32Array {\n let source = createHeightsLevelsSource(size, gridSize, levels, decodeRow, noDataHeight),\n pixels = source.pixels;\n\n let grid: Float32Array, cells: number, peaks: IGridPeaks;\n\n if (source.peaks) {\n grid = pixels;\n cells = size - 1;\n peaks = source.peaks;\n } else {\n let pixelCenters = isPixelCentersGrid(size, gridSize, levels);\n grid = createVertexGrid(pixels, size, noDataHeight, pixelCenters);\n cells = pixelCenters ? size * 2 : size;\n peaks = findPeaks(pixels, size, 0.5, cells / size);\n }\n\n let tileLength = (gridSize + 1) * (gridSize + 1),\n tilesCount = 0;\n\n for (let k = 0; k <= levels; k++) {\n tilesCount += 1 << (2 * k);\n }\n\n let out = new Float32Array(tilesCount * tileLength);\n\n for (let k = 0, c = cells, offset = 0; k <= levels; k++, c >>= 1) {\n let d = 1 << k;\n for (let i = 0; i < d; i++) {\n for (let j = 0; j < d; j++) {\n sampleSubGrid(grid, cells, i * c, j * c, c, gridSize, out, offset, peaks, noDataHeight);\n offset += tileLength;\n }\n }\n }\n\n return out;\n}\n","import type { ColorScaleName, ColorStop, IMultiBandRenderOptions, ISingleBandRenderOptions } from \"./types\";\n\nexport type TypedRasterArray =\n | Int8Array\n | Uint8Array\n | Uint8ClampedArray\n | Int16Array\n | Uint16Array\n | Int32Array\n | Uint32Array\n | Float32Array\n | Float64Array\n | number[];\n\ninterface ColorScaleDefinition {\n colors: string[] | Uint8Array;\n positions?: number[];\n}\n\nexport const COLORSCALES: Record<string, ColorScaleDefinition> = {\n viridis: {\n colors: new Uint8Array([\n 68, 1, 84, 255, 68, 2, 86, 255, 69, 4, 87, 255, 69, 5, 89, 255, 70, 7, 90, 255, 70, 8, 92, 255, 70, 10, 93,\n 255, 70, 11, 94, 255, 71, 13, 96, 255, 71, 14, 97, 255, 71, 16, 99, 255, 71, 17, 100, 255, 71, 19, 101, 255,\n 72, 20, 103, 255, 72, 22, 104, 255, 72, 23, 105, 255, 72, 24, 106, 255, 72, 26, 108, 255, 72, 27, 109, 255,\n 72, 28, 110, 255, 72, 29, 111, 255, 72, 31, 112, 255, 72, 32, 113, 255, 72, 33, 115, 255, 72, 35, 116, 255,\n 72, 36, 117, 255, 72, 37, 118, 255, 72, 38, 119, 255, 72, 40, 120, 255, 72, 41, 121, 255, 71, 42, 122, 255,\n 71, 44, 122, 255, 71, 45, 123, 255, 71, 46, 124, 255, 71, 47, 125, 255, 70, 48, 126, 255, 70, 50, 126, 255,\n 70, 51, 127, 255, 70, 52, 128, 255, 69, 53, 129, 255, 69, 55, 129, 255, 69, 56, 130, 255, 68, 57, 131, 255,\n 68, 58, 131, 255, 68, 59, 132, 255, 67, 61, 132, 255, 67, 62, 133, 255, 66, 63, 133, 255, 66, 64, 134, 255,\n 66, 65, 134, 255, 65, 66, 135, 255, 65, 68, 135, 255, 64, 69, 136, 255, 64, 70, 136, 255, 63, 71, 136, 255,\n 63, 72, 137, 255, 62, 73, 137, 255, 62, 74, 137, 255, 62, 76, 138, 255, 61, 77, 138, 255, 61, 78, 138, 255,\n 60, 79, 138, 255, 60, 80, 139, 255, 59, 81, 139, 255, 59, 82, 139, 255, 58, 83, 139, 255, 58, 84, 140, 255,\n 57, 85, 140, 255, 57, 86, 140, 255, 56, 88, 140, 255, 56, 89, 140, 255, 55, 90, 140, 255, 55, 91, 141, 255,\n 54, 92, 141, 255, 54, 93, 141, 255, 53, 94, 141, 255, 53, 95, 141, 255, 52, 96, 141, 255, 52, 97, 141, 255,\n 51, 98, 141, 255, 51, 99, 141, 255, 50, 100, 142, 255, 50, 101, 142, 255, 49, 102, 142, 255, 49, 103, 142,\n 255, 49, 104, 142, 255, 48, 105, 142, 255, 48, 106, 142, 255, 47, 107, 142, 255, 47, 108, 142, 255, 46, 109,\n 142, 255, 46, 110, 142, 255, 46, 111, 142, 255, 45, 112, 142, 255, 45, 113, 142, 255, 44, 113, 142, 255, 44,\n 114, 142, 255, 44, 115, 142, 255, 43, 116, 142, 255, 43, 117, 142, 255, 42, 118, 142, 255, 42, 119, 142,\n 255, 42, 120, 142, 255, 41, 121, 142, 255, 41, 122, 142, 255, 41, 123, 142, 255, 40, 124, 142, 255, 40, 125,\n 142, 255, 39, 126, 142, 255, 39, 127, 142, 255, 39, 128, 142, 255, 38, 129, 142, 255, 38, 130, 142, 255, 38,\n 130, 142, 255, 37, 131, 142, 255, 37, 132, 142, 255, 37, 133, 142, 255, 36, 134, 142, 255, 36, 135, 142,\n 255, 35, 136, 142, 255, 35, 137, 142, 255, 35, 138, 141, 255, 34, 139, 141, 255, 34, 140, 141, 255, 34, 141,\n 141, 255, 33, 142, 141, 255, 33, 143, 141, 255, 33, 144, 141, 255, 33, 145, 140, 255, 32, 146, 140, 255, 32,\n 146, 140, 255, 32, 147, 140, 255, 31, 148, 140, 255, 31, 149, 139, 255, 31, 150, 139, 255, 31, 151, 139,\n 255, 31, 152, 139, 255, 31, 153, 138, 255, 31, 154, 138, 255, 30, 155, 138, 255, 30, 156, 137, 255, 30, 157,\n 137, 255, 31, 158, 137, 255, 31, 159, 136, 255, 31, 160, 136, 255, 31, 161, 136, 255, 31, 161, 135, 255, 31,\n 162, 135, 255, 32, 163, 134, 255, 32, 164, 134, 255, 33, 165, 133, 255, 33, 166, 133, 255, 34, 167, 133,\n 255, 34, 168, 132, 255, 35, 169, 131, 255, 36, 170, 131, 255, 37, 171, 130, 255, 37, 172, 130, 255, 38, 173,\n 129, 255, 39, 173, 129, 255, 40, 174, 128, 255, 41, 175, 127, 255, 42, 176, 127, 255, 44, 177, 126, 255, 45,\n 178, 125, 255, 46, 179, 124, 255, 47, 180, 124, 255, 49, 181, 123, 255, 50, 182, 122, 255, 52, 182, 121,\n 255, 53, 183, 121, 255, 55, 184, 120, 255, 56, 185, 119, 255, 58, 186, 118, 255, 59, 187, 117, 255, 61, 188,\n 116, 255, 63, 188, 115, 255, 64, 189, 114, 255, 66, 190, 113, 255, 68, 191, 112, 255, 70, 192, 111, 255, 72,\n 193, 110, 255, 74, 193, 109, 255, 76, 194, 108, 255, 78, 195, 107, 255, 80, 196, 106, 255, 82, 197, 105,\n 255, 84, 197, 104, 255, 86, 198, 103, 255, 88, 199, 101, 255, 90, 200, 100, 255, 92, 200, 99, 255, 94, 201,\n 98, 255, 96, 202, 96, 255, 99, 203, 95, 255, 101, 203, 94, 255, 103, 204, 92, 255, 105, 205, 91, 255, 108,\n 205, 90, 255, 110, 206, 88, 255, 112, 207, 87, 255, 115, 208, 86, 255, 117, 208, 84, 255, 119, 209, 83, 255,\n 122, 209, 81, 255, 124, 210, 80, 255, 127, 211, 78, 255, 129, 211, 77, 255, 132, 212, 75, 255, 134, 213, 73,\n 255, 137, 213, 72, 255, 139, 214, 70, 255, 142, 214, 69, 255, 144, 215, 67, 255, 147, 215, 65, 255, 149,\n 216, 64, 255, 152, 216, 62, 255, 155, 217, 60, 255, 157, 217, 59, 255, 160, 218, 57, 255, 162, 218, 55, 255,\n 165, 219, 54, 255, 168, 219, 52, 255, 170, 220, 50, 255, 173, 220, 48, 255, 176, 221, 47, 255, 178, 221, 45,\n 255, 181, 222, 43, 255, 184, 222, 41, 255, 186, 222, 40, 255, 189, 223, 38, 255, 192, 223, 37, 255, 194,\n 223, 35, 255, 197, 224, 33, 255, 200, 224, 32, 255, 202, 225, 31, 255, 205, 225, 29, 255, 208, 225, 28, 255,\n 210, 226, 27, 255, 213, 226, 26, 255, 216, 226, 25, 255, 218, 227, 25, 255, 221, 227, 24, 255, 223, 227, 24,\n 255, 226, 228, 24, 255, 229, 228, 25, 255, 231, 228, 25, 255, 234, 229, 26, 255, 236, 229, 27, 255, 239,\n 229, 28, 255, 241, 229, 29, 255, 244, 230, 30, 255, 246, 230, 32, 255, 248, 230, 33, 255, 251, 231, 35, 255,\n 253, 231, 37, 255\n ])\n },\n turbo: {\n colors: [\n \"#30123b\",\n \"#321543\",\n \"#33184a\",\n \"#341b51\",\n \"#351e58\",\n \"#36215f\",\n \"#372466\",\n \"#38276d\",\n \"#392a73\",\n \"#3a2d79\",\n \"#3b2f80\",\n \"#3c3286\",\n \"#3d358b\",\n \"#3e3891\",\n \"#3f3b97\",\n \"#3f3e9c\",\n \"#4040a2\",\n \"#4143a7\",\n \"#4146ac\",\n \"#4249b1\",\n \"#424bb5\",\n \"#434eba\",\n \"#4451bf\",\n \"#4454c3\",\n \"#4456c7\",\n \"#4559cb\",\n \"#455ccf\",\n \"#455ed3\",\n \"#4661d6\",\n \"#4664da\",\n \"#4666dd\",\n \"#4669e0\",\n \"#466be3\",\n \"#476ee6\",\n \"#4771e9\",\n \"#4773eb\",\n \"#4776ee\",\n \"#4778f0\",\n \"#477bf2\",\n \"#467df4\",\n \"#4680f6\",\n \"#4682f8\",\n \"#4685fa\",\n \"#4687fb\",\n \"#458afc\",\n \"#458cfd\",\n \"#448ffe\",\n \"#4391fe\",\n \"#4294ff\",\n \"#4196ff\",\n \"#4099ff\",\n \"#3e9bfe\",\n \"#3d9efe\",\n \"#3ba0fd\",\n \"#3aa3fc\",\n \"#38a5fb\",\n \"#37a8fa\",\n \"#35aaf8\",\n \"#33acf7\",\n \"#31aff5\",\n \"#2fb1f4\",\n \"#2eb3f2\",\n \"#2cb6f0\",\n \"#2ab8ee\",\n \"#28baeb\",\n \"#27bde9\",\n \"#25bfe7\",\n \"#23c1e4\",\n \"#22c3e2\",\n \"#20c5df\",\n \"#1fc7dd\",\n \"#1ec9da\",\n \"#1ccbd8\",\n \"#1bced5\",\n \"#1ad0d2\",\n \"#19d2d0\",\n \"#18d4cd\",\n \"#18d5cb\",\n \"#17d7c8\",\n \"#17d9c5\",\n \"#17dbc2\",\n \"#17ddc0\",\n \"#17dfbd\",\n \"#17e0ba\",\n \"#18e2b8\",\n \"#19e3b5\",\n \"#1ae4b2\",\n \"#1ce6af\",\n \"#1de7ac\",\n \"#1fe8a9\",\n \"#20e9a6\",\n \"#22eba3\",\n \"#25eca0\",\n \"#27eda0\",\n \"#2aeea0\",\n \"#2ceea0\",\n \"#2feea0\",\n \"#32eea0\",\n \"#35efa0\",\n \"#38efa0\",\n \"#3befa0\",\n \"#3eefa0\",\n \"#42eea0\",\n \"#45eea0\",\n \"#48eea0\",\n \"#4beea0\",\n \"#4eeea0\",\n \"#51eda0\",\n \"#55eda0\",\n \"#58eda0\",\n \"#5beca0\",\n \"#5eeca0\",\n \"#62eca0\",\n \"#65eba0\",\n \"#69eba0\",\n \"#6ceaa0\",\n \"#70eaa0\",\n \"#73e9a0\",\n \"#77e8a0\",\n \"#7ae8a0\",\n \"#7ee7a0\",\n \"#81e6a0\",\n \"#85e5a0\",\n \"#89e4a0\",\n \"#8ce3a0\",\n \"#90e2a0\",\n \"#94e1a0\",\n \"#97e0a0\",\n \"#9bdfa0\",\n \"#9fdda0\",\n \"#a2dca0\",\n \"#a6dba0\",\n \"#a9d9a0\",\n \"#add8a0\",\n \"#b0d6a0\",\n \"#b4d5a0\",\n \"#b7d3a0\",\n \"#bbd2a0\",\n \"#bed0a0\",\n \"#c1cea0\",\n \"#c5cda0\",\n \"#c8cba0\",\n \"#cbc9a0\",\n \"#cec7a0\",\n \"#d1c5a0\",\n \"#d4c3a0\",\n \"#d7c1a0\",\n \"#d9bfa0\",\n \"#dcbea0\",\n \"#dfbca0\",\n \"#e1baa0\",\n \"#e4b8a0\",\n \"#e6b6a0\",\n \"#e8b4a0\",\n \"#ebb2a0\",\n \"#edb0a0\",\n \"#efaea0\",\n \"#f1aca0\",\n \"#f3aaa0\",\n \"#f5a8a0\",\n \"#f6a6a0\",\n \"#f8a4a0\",\n \"#f9a2a0\",\n \"#fba0a0\",\n \"#fc9ea0\",\n \"#fd9ca0\",\n \"#fe9aa0\",\n \"#ff98a0\",\n \"#ff96a0\",\n \"#ff94a0\"\n ]\n },\n inferno: {\n colors: [\n \"#000004\",\n \"#010005\",\n \"#010106\",\n \"#010108\",\n \"#02010a\",\n \"#02020c\",\n \"#02020e\",\n \"#030210\",\n \"#040312\",\n \"#040314\",\n \"#050417\",\n \"#060419\",\n \"#07051b\",\n \"#08051d\",\n \"#09061f\",\n \"#0a0722\",\n \"#0b0724\",\n \"#0c0826\",\n \"#0d0829\",\n \"#0e092b\",\n \"#10092d\",\n \"#110a30\",\n \"#120a32\",\n \"#140b34\",\n \"#150b37\",\n \"#160b39\",\n \"#180c3c\",\n \"#190c3e\",\n \"#1b0c41\",\n \"#1c0c43\",\n \"#1e0c45\",\n \"#1f0c48\",\n \"#210c4a\",\n \"#230c4c\",\n \"#240c4f\",\n \"#260c51\",\n \"#280b53\",\n \"#290b55\",\n \"#2b0b57\",\n \"#2d0b59\",\n \"#2f0a5b\",\n \"#310a5c\",\n \"#320a5e\",\n \"#340a5f\",\n \"#360961\",\n \"#380962\",\n \"#390963\",\n \"#3b0964\",\n \"#3d0965\",\n \"#3e0966\",\n \"#400a67\",\n \"#420a68\",\n \"#440a68\",\n \"#450a69\",\n \"#470b6a\",\n \"#490b6a\",\n \"#4a0c6b\",\n \"#4c0c6b\",\n \"#4d0d6c\",\n \"#4f0d6c\",\n \"#510e6c\",\n \"#520e6d\",\n \"#540f6d\",\n \"#550f6d\",\n \"#57106e\",\n \"#59106e\",\n \"#5a116e\",\n \"#5c126e\",\n \"#5d126e\",\n \"#5f136e\",\n \"#61136e\",\n \"#62146e\",\n \"#64156e\",\n \"#65156e\",\n \"#67166e\",\n \"#69166e\",\n \"#6a176e\",\n \"#6c186e\",\n \"#6d186e\",\n \"#6f196e\",\n \"#71196e\",\n \"#721a6e\",\n \"#741a6e\",\n \"#751b6e\",\n \"#771c6d\",\n \"#781c6d\",\n \"#7a1d6d\",\n \"#7c1d6d\",\n \"#7d1e6d\",\n \"#7f1e6c\",\n \"#801f6c\",\n \"#82206c\",\n \"#84206b\",\n \"#85216b\",\n \"#87216b\",\n \"#88226a\",\n \"#8a226a\",\n \"#8c2369\",\n \"#8d2369\",\n \"#8f2469\",\n \"#902568\",\n \"#922568\",\n \"#932667\",\n \"#952667\",\n \"#972766\",\n \"#982766\",\n \"#9a2865\",\n \"#9b2964\",\n \"#9d2964\",\n \"#9f2a63\",\n \"#a02a63\",\n \"#a22b62\",\n \"#a32c61\",\n \"#a52c60\",\n \"#a62d60\",\n \"#a82e5f\",\n \"#a92e5e\",\n \"#ab2f5e\",\n \"#ad305d\",\n \"#ae305c\",\n \"#b0315b\",\n \"#b1325a\",\n \"#b3325a\",\n \"#b43359\",\n \"#b63458\",\n \"#b73557\",\n \"#b93556\",\n \"#ba3655\",\n \"#bc3754\",\n \"#bd3853\",\n \"#bf3952\",\n \"#c03a51\",\n \"#c13a50\",\n \"#c33b4f\",\n \"#c43c4e\",\n \"#c63d4d\",\n \"#c73e4c\",\n \"#c83f4b\",\n \"#ca404a\",\n \"#cb4149\",\n \"#cc4248\",\n \"#ce4347\",\n \"#cf4446\",\n \"#d04545\",\n \"#d24644\",\n \"#d34743\",\n \"#d44842\",\n \"#d54a41\",\n \"#d74b3f\",\n \"#d84c3e\",\n \"#d94d3d\",\n \"#da4e3c\",\n \"#db503b\",\n \"#dc513a\",\n \"#de5238\",\n \"#df5337\",\n \"#e05536\",\n \"#e15635\",\n \"#e25734\",\n \"#e35933\",\n \"#e45a31\",\n \"#e55c30\",\n \"#e65d2f\",\n \"#e75e2e\",\n \"#e8602d\",\n \"#e9612b\",\n \"#ea632a\",\n \"#eb6429\",\n \"#eb6628\",\n \"#ec6726\",\n \"#ed6925\",\n \"#ee6a24\",\n \"#ef6c23\",\n \"#ef6e21\",\n \"#f06f20\",\n \"#f1711f\",\n \"#f1731d\",\n \"#f2741c\",\n \"#f3761b\",\n \"#f37819\",\n \"#f47918\",\n \"#f57b17\",\n \"#f57d15\",\n \"#f67e14\",\n \"#f68013\",\n \"#f78212\",\n \"#f78410\",\n \"#f8850f\",\n \"#f8870e\",\n \"#f8890c\",\n \"#f98b0b\",\n \"#f98c0a\",\n \"#f98e09\",\n \"#fa9008\",\n \"#fa9207\",\n \"#fa9407\",\n \"#fb9606\",\n \"#fb9706\",\n \"#fb9906\",\n \"#fb9b06\",\n \"#fb9d07\",\n \"#fc9f07\",\n \"#fca108\",\n \"#fca309\",\n \"#fca50a\",\n \"#fca60c\",\n \"#fca80d\",\n \"#fcaa0f\",\n \"#fcac11\",\n \"#fcae12\",\n \"#fcb014\",\n \"#fcb216\",\n \"#fcb418\",\n \"#fbb61a\",\n \"#fbb81d\",\n \"#fbbb1f\",\n \"#fbbd21\",\n \"#fbbf23\",\n \"#fbc126\",\n \"#fac328\",\n \"#fac52b\",\n \"#fac72d\",\n \"#f9c930\",\n \"#f9cb33\",\n \"#f8cd35\",\n \"#f8cf38\",\n \"#f7d13b\",\n \"#f7d33e\",\n \"#f6d541\",\n \"#f6d744\",\n \"#f5d947\",\n \"#f5db4a\",\n \"#f4dd4d\",\n \"#f4df51\",\n \"#f3e154\",\n \"#f3e357\",\n \"#f3e55a\",\n \"#f2e75e\",\n \"#f2e961\",\n \"#f1eb65\",\n \"#f1ed68\",\n \"#f1ef6c\",\n \"#f1f170\",\n \"#f2f274\",\n \"#f2f479\",\n \"#f3f67d\",\n \"#f4f882\",\n \"#f5f986\",\n \"#f6fa8b\",\n \"#f8fb90\"\n ]\n },\n rainbow: {\n colors: [\"#96005A\", \"#0000C8\", \"#0019FF\", \"#0098FF\", \"#2CFF96\", \"#97FF00\", \"#FFEA00\", \"#FF6F00\", \"#FF0000\"],\n positions: [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n },\n jet: {\n colors: [\"#000083\", \"#003CAA\", \"#05FFFF\", \"#FFFF00\", \"#FA0000\", \"#800000\"],\n positions: [0, 0.125, 0.375, 0.625, 0.875, 1]\n },\n greys: {\n colors: [\"#000000\", \"#ffffff\"],\n positions: [0, 1]\n },\n earth: {\n colors: [\"#000082\", \"#00b4b4\", \"#28d228\", \"#e6e632\", \"#784614\", \"#ffffff\"],\n positions: [0, 0.1, 0.2, 0.4, 0.6, 1]\n },\n coolwarm: {\n colors: [\"#0000ff\", \"#ffffff\", \"#ff0000\"],\n positions: [0, 0.5, 1]\n },\n hot: {\n colors: [\"#000000\", \"#e60000\", \"#ffd200\", \"#ffffff\"],\n positions: [0, 0.3, 0.6, 1]\n },\n cool: {\n colors: [\"#00ffff\", \"#ff00ff\"],\n positions: [0, 1]\n }\n};\n\n/**\n * Parses a hex, rgb, or named color string into RGBA [0..255] values.\n */\nexport function parseColor(color: string): [number, number, number, number] {\n const trimmed = color.trim().toLowerCase();\n\n if (trimmed.startsWith(\"#\")) {\n const hex = trimmed.slice(1);\n if (hex.length === 3) {\n return [parseInt(hex[0] + hex[0], 16), parseInt(hex[1] + hex[1], 16), parseInt(hex[2] + hex[2], 16), 255];\n }\n if (hex.length === 6) {\n return [parseInt(hex.slice(0, 2), 16), parseInt(hex.slice(2, 4), 16), parseInt(hex.slice(4, 6), 16), 255];\n }\n if (hex.length === 8) {\n return [\n parseInt(hex.slice(0, 2), 16),\n parseInt(hex.slice(2, 4), 16),\n parseInt(hex.slice(4, 6), 16),\n parseInt(hex.slice(6, 8), 16)\n ];\n }\n }\n\n if (trimmed.startsWith(\"rgb\")) {\n const parts = trimmed\n .replace(/[rgba()]/g, \"\")\n .split(\",\")\n .map((s) => parseFloat(s.trim()));\n return [\n Math.round(parts[0] || 0),\n Math.round(parts[1] || 0),\n Math.round(parts[2] || 0),\n parts.length > 3 ? Math.round((parts[3] ?? 1) * 255) : 255\n ];\n }\n\n // Default fallback (black)\n return [0, 0, 0, 255];\n}\n\n/**\n * Builds a 256-color RGBA Lookup Table (Uint8Array of size 1024) from render options.\n */\nexport function buildColorLUT(options?: ISingleBandRenderOptions): Uint8Array {\n const lut = new Uint8Array(256 * 4);\n\n let stops: { pos: number; color: [number, number, number, number] }[] = [];\n\n if (options?.colors && options.colors.length > 0) {\n if (Array.isArray(options.colors[0])) {\n const arr = options.colors as ColorStop[];\n stops = arr.map(([pos, col]) => ({\n pos: Math.max(0, Math.min(1, pos)),\n color: parseColor(col)\n }));\n } else {\n const colList = options.colors as string[];\n const count = colList.length;\n stops = colList.map((col, idx) => ({\n pos: count > 1 ? idx / (count - 1) : 0,\n color: parseColor(col)\n }));\n }\n stops.sort((a, b) => a.pos - b.pos);\n } else {\n const scaleName = (options?.colorScale || \"viridis\").toLowerCase();\n const def = COLORSCALES[scaleName] || COLORSCALES.viridis;\n\n if (def.colors instanceof Uint8Array) {\n // Already a precomputed 256*4 table\n if (def.colors.length === 256 * 4) {\n lut.set(def.colors);\n return lut;\n }\n }\n\n const colList = def.colors as string[];\n const positions = def.positions || colList.map((_, i) => i / Math.max(1, colList.length - 1));\n stops = colList.map((col, idx) => ({\n pos: positions[idx] ?? idx / (colList.length - 1),\n color: parseColor(col)\n }));\n }\n\n if (stops.length === 0) {\n stops = [\n { pos: 0, color: [0, 0, 0, 255] },\n { pos: 1, color: [255, 255, 255, 255] }\n ];\n }\n\n // Interpolate 256 entries\n for (let i = 0; i < 256; i++) {\n const t = i / 255;\n let c0 = stops[0];\n let c1 = stops[stops.length - 1];\n\n for (let j = 0; j < stops.length - 1; j++) {\n if (t >= stops[j].pos && t <= stops[j + 1].pos) {\n c0 = stops[j];\n c1 = stops[j + 1];\n break;\n }\n }\n\n const range = c1.pos - c0.pos;\n const localT = range > 0 ? (t - c0.pos) / range : 0;\n\n const r = Math.round(c0.color[0] + (c1.color[0] - c0.color[0]) * localT);\n const g = Math.round(c0.color[1] + (c1.color[1] - c0.color[1]) * localT);\n const b = Math.round(c0.color[2] + (c1.color[2] - c0.color[2]) * localT);\n const a = Math.round(c0.color[3] + (c1.color[3] - c0.color[3]) * localT);\n\n const offset = i * 4;\n lut[offset] = r;\n lut[offset + 1] = g;\n lut[offset + 2] = b;\n lut[offset + 3] = a;\n }\n\n return lut;\n}\n\n/**\n * Parses and normalizes a nodata value from various representations (number, null, string \"NaN\", NaN, etc.).\n */\nexport function parseNoDataValue(val: any): number | null | undefined {\n if (val === undefined) return undefined;\n if (val === null) return null;\n if (typeof val === \"string\") {\n const lower = val.trim().toLowerCase();\n if (lower === \"nan\" || lower === \"-nan\" || lower === \"+nan\") return NaN;\n if (lower === \"none\" || lower === \"null\" || lower === \"\") return null;\n const parsed = Number(val);\n return Number.isNaN(parsed) ? null : parsed;\n }\n if (typeof val === \"number\") {\n return val;\n }\n return undefined;\n}\n\n/**\n * Checks if a raster value represents NoData, taking NaN, null, and float precision into account.\n */\nexport function isNoData(val: number, nodata: number | null | undefined): boolean {\n if (Number.isNaN(val)) return true;\n if (nodata === null || nodata === undefined || Number.isNaN(nodata)) return false;\n if (val === nodata) return true;\n if (Math.fround(val) === Math.fround(nodata)) return true;\n const absDiff = Math.abs(val - nodata);\n if (absDiff < 1e-6) return true;\n const maxVal = Math.max(Math.abs(val), Math.abs(nodata));\n if (maxVal > 0 && absDiff / maxVal < 1e-5) return true;\n return false;\n}\n\n/**\n * Returns a high-performance nodata checking predicate for inner pixel loops.\n */\nexport function getFastNoDataChecker(nodata: number | null | undefined): (val: number) => boolean {\n if (nodata === null || nodata === undefined || Number.isNaN(nodata)) {\n return (val: number) => Number.isNaN(val);\n }\n const fNodata = Math.fround(nodata);\n return (val: number) => {\n if (val === nodata || Number.isNaN(val)) return true;\n if (Math.fround(val) === fNodata) return true;\n const absDiff = Math.abs(val - nodata);\n if (absDiff < 1e-6) return true;\n const maxVal = Math.max(Math.abs(val), Math.abs(nodata));\n return maxVal > 0 && absDiff / maxVal < 1e-5;\n };\n}\n\n/**\n * Calculates min and max from a raster array, ignoring NaN and NoData.\n */\nexport function getRasterMinMax(\n data: TypedRasterArray,\n nodata: number | null | undefined\n): { min: number; max: number } {\n let min = Infinity;\n let max = -Infinity;\n const len = data.length;\n\n for (let i = 0; i < len; i++) {\n const val = data[i];\n if (isNoData(val, nodata)) {\n continue;\n }\n if (val < min) min = val;\n if (val > max) max = val;\n }\n\n if (min === Infinity || max === -Infinity) {\n return { min: 0, max: 1 };\n }\n return { min, max };\n}\n\n/**\n * Creates an ImageData instance with fallback for non-browser/worker/test environments.\n */\nexport function createImageData(width: number, height: number): ImageData {\n if (typeof ImageData !== \"undefined\") {\n return new ImageData(width, height);\n }\n return {\n width,\n height,\n data: new Uint8ClampedArray(width * height * 4),\n colorSpace: \"srgb\"\n } as unknown as ImageData;\n}\n\n/**\n * Renders a single band raster to an ImageData using a color LUT.\n */\nexport function renderSingleBandToImageData(\n raster: TypedRasterArray,\n width: number,\n height: number,\n options?: ISingleBandRenderOptions,\n nodata: number | null = null,\n outImageData?: ImageData\n): ImageData {\n const imgData = outImageData || createImageData(width, height);\n const rgba = imgData.data;\n const lut = buildColorLUT(options);\n\n let [min, max] = options?.domain || [undefined, undefined];\n if (min === undefined || max === undefined) {\n const minMax = getRasterMinMax(raster, nodata);\n min = min ?? minMax.min;\n max = max ?? minMax.max;\n }\n\n const diff = max - min || 1e-6;\n const scale = 255 / diff;\n const displayRange = options?.displayRange;\n const clampLow = options?.clampLow ?? true;\n const clampHigh = options?.clampHigh ?? true;\n const pixelCount = width * height;\n const hasNoData = nodata !== null && nodata !== undefined && !Number.isNaN(nodata);\n const checkNoData = hasNoData ? getFastNoDataChecker(nodata) : null;\n\n for (let i = 0; i < pixelCount; i++) {\n const val = raster[i];\n const outIdx = i * 4;\n\n if (checkNoData ? checkNoData(val) : Number.isNaN(val)) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n if (displayRange && (val < displayRange[0] || val > displayRange[1])) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n let norm255 = ((val - min) * scale + 0.5) | 0;\n\n if (clampLow && norm255 < 0) norm255 = 0;\n if (clampHigh && norm255 > 255) norm255 = 255;\n\n if (norm255 < 0 || norm255 > 255) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n const lutIdx = norm255 * 4;\n rgba[outIdx] = lut[lutIdx];\n rgba[outIdx + 1] = lut[lutIdx + 1];\n rgba[outIdx + 2] = lut[lutIdx + 2];\n rgba[outIdx + 3] = lut[lutIdx + 3];\n }\n\n return imgData;\n}\n\n/**\n * Renders 3 separate band arrays into an RGB ImageData.\n */\nexport function renderMultiBandToImageData(\n rBand: TypedRasterArray,\n gBand: TypedRasterArray,\n bBand: TypedRasterArray,\n width: number,\n height: number,\n options?: IMultiBandRenderOptions,\n nodata: number | null = null,\n outImageData?: ImageData\n): ImageData {\n const imgData = outImageData || createImageData(width, height);\n const rgba = imgData.data;\n const pixelCount = width * height;\n\n const rMin = options?.r?.min ?? 0;\n const rMax = options?.r?.max ?? 255;\n const rDiff = rMax - rMin || 1;\n\n const gMin = options?.g?.min ?? 0;\n const gMax = options?.g?.max ?? 255;\n const gDiff = gMax - gMin || 1;\n\n const bMin = options?.b?.min ?? 0;\n const bMax = options?.b?.max ?? 255;\n const bDiff = bMax - bMin || 1;\n\n const rScale = 255 / rDiff;\n const gScale = 255 / gDiff;\n const bScale = 255 / bDiff;\n\n const hasNoData = nodata !== null && nodata !== undefined && !Number.isNaN(nodata);\n\n if (!hasNoData) {\n for (let i = 0; i < pixelCount; i++) {\n const outIdx = i * 4;\n\n const rVal = rBand[i];\n const gVal = gBand[i];\n const bVal = bBand[i];\n\n if (Number.isNaN(rVal) || Number.isNaN(gVal) || Number.isNaN(bVal)) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n let r = ((rVal - rMin) * rScale + 0.5) | 0;\n if (r < 0) r = 0;\n else if (r > 255) r = 255;\n\n let g = ((gVal - gMin) * gScale + 0.5) | 0;\n if (g < 0) g = 0;\n else if (g > 255) g = 255;\n\n let b = ((bVal - bMin) * bScale + 0.5) | 0;\n if (b < 0) b = 0;\n else if (b > 255) b = 255;\n\n rgba[outIdx] = r;\n rgba[outIdx + 1] = g;\n rgba[outIdx + 2] = b;\n rgba[outIdx + 3] = 255;\n }\n } else {\n const checkNoData = getFastNoDataChecker(nodata);\n for (let i = 0; i < pixelCount; i++) {\n const outIdx = i * 4;\n const rVal = rBand[i];\n const gVal = gBand[i];\n const bVal = bBand[i];\n\n if (checkNoData(rVal) || checkNoData(gVal) || checkNoData(bVal)) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n let r = ((rVal - rMin) * rScale + 0.5) | 0;\n if (r < 0) r = 0;\n else if (r > 255) r = 255;\n\n let g = ((gVal - gMin) * gScale + 0.5) | 0;\n if (g < 0) g = 0;\n else if (g > 255) g = 255;\n\n let b = ((bVal - bMin) * bScale + 0.5) | 0;\n if (b < 0) b = 0;\n else if (b > 255) b = 255;\n\n rgba[outIdx] = r;\n rgba[outIdx + 1] = g;\n rgba[outIdx + 2] = b;\n rgba[outIdx + 3] = 255;\n }\n }\n\n return imgData;\n}\n\n/**\n * Converts raw RGB/RGBA raster array(s) directly to an ImageData.\n */\nexport function renderRgbRastersToImageData(\n rasters: TypedRasterArray[],\n width: number,\n height: number,\n nodata: number | null = null,\n outImageData?: ImageData\n): ImageData {\n const imgData = outImageData || createImageData(width, height);\n const rgba = imgData.data;\n const pixelCount = width * height;\n const isRgba = rasters.length >= 4;\n\n const rBand = rasters[0];\n const gBand = rasters[1] || rasters[0];\n const bBand = rasters[2] || rasters[0];\n const aBand = isRgba ? rasters[3] : null;\n\n const hasNoData = nodata !== null && nodata !== undefined && !Number.isNaN(nodata);\n\n if (!hasNoData) {\n for (let i = 0; i < pixelCount; i++) {\n const outIdx = i * 4;\n const r = rBand[i];\n const g = gBand[i];\n const b = bBand[i];\n\n if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n rgba[outIdx] = r;\n rgba[outIdx + 1] = g;\n rgba[outIdx + 2] = b;\n rgba[outIdx + 3] = isRgba ? aBand![i] : 255;\n }\n } else {\n const checkNoData = getFastNoDataChecker(nodata);\n for (let i = 0; i < pixelCount; i++) {\n const outIdx = i * 4;\n const r = rBand[i];\n const g = gBand[i];\n const b = bBand[i];\n const a = aBand ? aBand[i] : 255;\n\n if (checkNoData(r) || checkNoData(g) || checkNoData(b)) {\n rgba[outIdx + 3] = 0;\n continue;\n }\n\n rgba[outIdx] = r;\n rgba[outIdx + 1] = g;\n rgba[outIdx + 2] = b;\n rgba[outIdx + 3] = a;\n }\n }\n\n return imgData;\n}\n","import type { TypedArray } from \"geotiff\";\nimport { getFastNoDataChecker } from \"./ColorScale\";\n\n/**\n * Tile resampling data, the window rasters and the grid of the source positions of the tile pixels.\n */\nexport interface IWarpParams {\n /** Window rasters, one by band. */\n rasters: TypedArray[];\n /** Source positions of the grid nodes, normalized to 0..1, v grows down the raster rows. */\n gridU: Float64Array;\n gridV: Float64Array;\n gridSize: number;\n imgWidth: number;\n imgHeight: number;\n window: [number, number, number, number];\n tileSize: number;\n bilinear: boolean;\n nodata: number | null;\n /** Valid pixels of the window, if the file has a mask. */\n maskRaster?: TypedArray | null;\n}\n\n/**\n * Returns the tile rasters resampled from the window rasters, the nearest or bilinear. Tile pixels out of\n * the image, of no data or out of the mask are NaN.\n */\nexport function warpRasters(p: IWarpParams): Float32Array[] {\n const { rasters, gridU, gridV, gridSize, imgWidth, imgHeight, tileSize, bilinear, maskRaster } = p;\n const [winX0, winY0, winX1, winY1] = p.window;\n const winWidth = winX1 - winX0;\n const winHeight = winY1 - winY0;\n\n const side = gridSize + 1;\n const cellSize = tileSize / gridSize;\n\n const checkNoData = p.nodata !== null ? getFastNoDataChecker(p.nodata) : null;\n\n const out: Float32Array[] = [];\n for (let b = 0; b < rasters.length; b++) {\n out.push(new Float32Array(tileSize * tileSize).fill(NaN));\n }\n\n for (let y = 0; y < tileSize; y++) {\n // Grid nodes sit on tile pixel borders, so pixel centers are used here\n const gy = (y + 0.5) / cellSize;\n const j0 = Math.min(gridSize - 1, gy | 0);\n const fy = gy - j0;\n\n for (let x = 0; x < tileSize; x++) {\n const gx = (x + 0.5) / cellSize;\n const i0 = Math.min(gridSize - 1, gx | 0);\n const fx = gx - i0;\n\n // Bilinear interpolation of the source position between the grid nodes\n const n00 = j0 * side + i0;\n const n10 = n00 + 1;\n const n01 = n00 + side;\n const n11 = n01 + 1;\n\n const w00 = (1 - fx) * (1 - fy);\n const w10 = fx * (1 - fy);\n const w01 = (1 - fx) * fy;\n const w11 = fx * fy;\n\n const u = gridU[n00] * w00 + gridU[n10] * w10 + gridU[n01] * w01 + gridU[n11] * w11;\n const v = gridV[n00] * w00 + gridV[n10] * w10 + gridV[n01] * w01 + gridV[n11] * w11;\n\n if (u < 0 || u >= 1 || v < 0 || v >= 1) continue;\n\n // Source position inside the window, in pixel centers\n const sx = u * imgWidth - winX0 - 0.5;\n const sy = v * imgHeight - winY0 - 0.5;\n\n const outIdx = y * tileSize + x;\n\n // Pixels the mask marks as invalid stay NaN, which is rendered as transparent\n if (maskRaster) {\n const mx = Math.max(0, Math.min(winWidth - 1, Math.round(sx)));\n const my = Math.max(0, Math.min(winHeight - 1, Math.round(sy)));\n if (!maskRaster[my * winWidth + mx]) continue;\n }\n\n if (bilinear) {\n const x0 = Math.floor(sx);\n const y0 = Math.floor(sy);\n const tx = sx - x0;\n const ty = sy - y0;\n const x1 = Math.min(winWidth - 1, x0 + 1);\n const y1 = Math.min(winHeight - 1, y0 + 1);\n const cx0 = Math.max(0, Math.min(winWidth - 1, x0));\n const cy0 = Math.max(0, Math.min(winHeight - 1, y0));\n\n const i00 = cy0 * winWidth + cx0;\n const i10 = cy0 * winWidth + x1;\n const i01 = y1 * winWidth + cx0;\n const i11 = y1 * winWidth + x1;\n\n for (let b = 0; b < rasters.length; b++) {\n const src = rasters[b];\n const v00 = src[i00],\n v10 = src[i10],\n v01 = src[i01],\n v11 = src[i11];\n\n if (\n checkNoData\n ? checkNoData(v00) || checkNoData(v10) || checkNoData(v01) || checkNoData(v11)\n : Number.isNaN(v00) || Number.isNaN(v10) || Number.isNaN(v01) || Number.isNaN(v11)\n ) {\n continue;\n }\n\n out[b][outIdx] = (v00 * (1 - tx) + v10 * tx) * (1 - ty) + (v01 * (1 - tx) + v11 * tx) * ty;\n }\n } else {\n const px = Math.max(0, Math.min(winWidth - 1, Math.round(sx)));\n const py = Math.max(0, Math.min(winHeight - 1, Math.round(sy)));\n const srcIdx = py * winWidth + px;\n\n for (let b = 0; b < rasters.length; b++) {\n const val = rasters[b][srcIdx];\n if (checkNoData ? checkNoData(val) : Number.isNaN(val)) continue;\n out[b][outIdx] = val;\n }\n }\n }\n }\n\n return out;\n}\n","\"use strict\";\n//\n// Raster pixels worker: terrain grid heights of the tile pixels and the GeoTIFF tile resampling\n//\nimport { createTileHeights } from \"../terrain/terrainUtils\";\nimport { warpRasters } from \"../layer/geotiff/warp\";\n\nfunction makeResult(d) {\n if (d.type === \"heights\") {\n let heights = createTileHeights(d.pixels, d.size, d.gridSize, d.levels, d.noDataHeight);\n return [heights, [heights.buffer]];\n }\n\n let rasters = warpRasters(d);\n return [rasters, rasters.map((r) => r.buffer)];\n}\n\nself.onmessage = function (e) {\n let result = null,\n transfer = [];\n\n try {\n [result, transfer] = makeResult(e.data);\n } catch (err) {\n console.error(err);\n }\n\n self.postMessage({ id: e.data.id, result: result }, transfer);\n};\n"],"mappings":"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I,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IACvG,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACtG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,IACvG,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACtG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GACzG,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IACpG,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IACxG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GA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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RgbTerrainWorker.worker-Bxbv73rB.js","names":["getGridCells","size","isNoDataValue","noDataValues","ndMin","ndMax","h","start","end","length","k","Math","abs","getParentHeight","oneByDz2","offsetX","offsetY","heights","i","j","skipPositiveHeights","parentGridSize","sqrt","floor","getEdgeHeight","p0","p1","p2","s0","s1","interpolateRow","pixels","offset","halfSteps","out","last","min","max","prev","averagePixels","ui","uj","noDataHeight","ki","kj","sum","count","i1","j1","_around","Uint8Array","compareNeighbours","around","a","b","ha","hb","findPeaks","scale","fill","r","row","rowStart","Int32Array","cols","isPeak","c","_deviations","Float32Array","sampleSubGrid","grid","row0","col0","cells","gridSize","outOffset","peaks","NaN","gs","outGs","step","src","dst","half","inner","pr0","ceil","pr1","pc0","pc1","pr","p","hi","m","y","ci","fy","top","bottom","vertexRow","x","cj","fx","h00","h01","h10","h11","surface","deviation","v","keepPeaks","createHeightsLevels","levels","decodeRow","source","subarray","createHeightsLevelsSource","pixelCenters","isPixelCentersGrid","columns","rowColumns","lastRow","vi","u","needRow","set","c0","c1","c2","vj","createVertexGrid","tileLength","tilesCount","d","ctx","self","onmessage","e","id","params","data","parentData","decode","encoding","minHeight","resolution","heightFactor","parentOffsetX","parentOffsetY","parentZoomDiff","bitmap","rgbaData","canvas","width","OffscreenCanvas","getContext","willReadFrequently","clearRect","drawImage","getImageData","parentScale","outHeights","ndv","isTerrarium","pi","k4","g","height","isNoData","decodeRgbHeightsRow","err","console","error","close","postMessage","buffer","t","e","a","l","n","i","f","s","h","u","c","M","g","p","d","y","w","x","z","A","b","D","F","v","k","H","S","O","I","N","P","U","q"],"sources":["../../src/terrain/terrainUtils.ts","../../src/utils/RgbTerrainWorkerParams.ts","../../src/utils/RgbTerrainWorker.worker.js"],"sourcesContent":["import type { TypedArray } from \"../utils/shared\";\nimport type { Extent } from \"../Extent\";\n\nexport const RGB_ENCODING_CUSTOM = -1;\nexport const RGB_ENCODING_RGB = 0;\nexport const RGB_ENCODING_TERRARIUM = 1;\n\n/** Segment grid sizes by zoom of the elevation terrains. */\nexport const TERRAIN_GRID_SIZE_BY_ZOOM = [\n 64, 32, 16, 8, 8, 8, 16, 16, 16, 32, 32, 32, 32, 32, 32, 64, 64, 64, 32, 32, 16, 8\n];\n\n/** Writes a row of pixel heights, NaN for no data pixels. */\nexport type DecodeHeightsRowFunc = (row: number, outHeights: Float32Array) => void;\n\nexport interface IRgbDecodeParams {\n encoding: number;\n minHeight: number;\n resolution: number;\n heightFactor: number;\n noDataValues: number[] | TypedArray;\n parentData: number[] | TypedArray | null;\n parentOffsetX: number;\n parentOffsetY: number;\n parentZoomDiff: number;\n skipPositiveHeights: boolean;\n}\n\nexport interface IRgbHeightsParams {\n decode: IRgbDecodeParams;\n size: number;\n gridSize: number;\n levels: number;\n noDataHeight: number;\n}\n\n/**\n * Returns pixel grid cells for the image size, 2^n and (2^n + 1) sizes only.\n * @param {number} size - Image size.\n * @returns {number} -\n */\nexport function getGridCells(size: number): number {\n return (size & (size - 1)) === 0 ? size : size - 1;\n}\n\n/**\n * Returns vertex grid cells for the image size. 2^n images have vertices at the pixel centers and corners,\n * (2^n + 1) images are the grid itself.\n * @param {number} size - Image size.\n * @returns {number} -\n */\nexport function getVertexGridCells(size: number): number {\n let cells = getGridCells(size);\n return cells === size ? cells * 2 : cells;\n}\n\n/**\n * Returns subdivision levels of the image tile. Native zoom levels are not finer than the image pixels,\n * finer data comes with their own tiles. Levels above the native zooms go down to the vertex grid.\n * @param {number} size - Image size.\n * @param {number} gridSize - Tile grid size.\n * @param {number} tileZoom - Image tile zoom.\n * @param {number} maxZoom - Maximal terrain zoom.\n * @param {number} maxNativeZoom - Maximal zoom of the terrain tiles.\n * @returns {number} -\n */\nexport function getSubdivisionLevels(\n size: number,\n gridSize: number,\n tileZoom: number,\n maxZoom: number,\n maxNativeZoom: number\n): number {\n let pixelCells = getGridCells(size),\n vertexCells = getVertexGridCells(size),\n levels = 0;\n\n for (let k = 1; tileZoom + k <= maxZoom; k++) {\n if ((tileZoom + k > maxNativeZoom ? vertexCells : pixelCells) >> k < gridSize) {\n break;\n }\n levels = k;\n }\n\n return levels;\n}\n\nfunction isNoDataValue(noDataValues: number[] | TypedArray, ndMin: number, ndMax: number, h: number): boolean {\n if (h > 50000) {\n return true;\n }\n if (h <= ndMin || h >= ndMax) {\n return false;\n }\n let start = 0,\n end = noDataValues.length - 1;\n while (start <= end) {\n let k = (start + end) >> 1;\n if (Math.abs(noDataValues[k] - h) < 1e-3) {\n return true;\n } else if (noDataValues[k] < h) {\n start = k + 1;\n } else {\n end = k - 1;\n }\n }\n return false;\n}\n\nexport function getParentHeight(\n oneByDz2: number,\n offsetX: number,\n offsetY: number,\n heights: TypedArray | number[],\n i: number,\n j: number,\n skipPositiveHeights?: boolean\n) {\n let parentGridSize = Math.sqrt(heights.length);\n let pi = Math.floor(offsetY * oneByDz2 * parentGridSize + i * oneByDz2),\n pj = Math.floor(offsetX * oneByDz2 * parentGridSize + j * oneByDz2);\n let h = heights[pi * parentGridSize + pj];\n return skipPositiveHeights ? (h > 0 ? 0 : h) : h;\n}\n\n/**\n * Decodes \"rgb\" or \"terrarium\" encoded pixel row heights.\n * @param {number[] | TypedArray} rgbaData - Image RGBA data.\n * @param {number} row - Pixel row.\n * @param {number} size - Image size.\n * @param {number} parentScale - Parent grid cells by image grid cells.\n * @param {IRgbDecodeParams} p - Decode parameters.\n * @param {Float32Array} outHeights - Row heights.\n * @param {number} noDataHeight - Height for no data pixels.\n */\nexport function decodeRgbHeightsRow(\n rgbaData: number[] | TypedArray,\n row: number,\n size: number,\n parentScale: number,\n p: IRgbDecodeParams,\n outHeights: Float32Array,\n noDataHeight: number\n) {\n let ndv = p.noDataValues,\n ndMin = ndv.length ? ndv[0] - 1e-3 : 0,\n ndMax = ndv.length ? ndv[ndv.length - 1] + 1e-3 : 0;\n\n let isTerrarium = p.encoding === RGB_ENCODING_TERRARIUM,\n minHeight = p.minHeight,\n resolution = p.resolution,\n heightFactor = p.heightFactor,\n parentData = p.parentData;\n\n let pi = Math.floor(row * parentScale);\n\n for (let j = 0, k4 = row * size * 4; j < size; j++, k4 += 4) {\n let r = rgbaData[k4],\n g = rgbaData[k4 + 1],\n b = rgbaData[k4 + 2];\n\n let height = isTerrarium\n ? r * 256 + g + b / 256 - 32768\n : r === 255\n ? minHeight\n : minHeight + resolution * (r * 65536 + g * 256 + b);\n\n height *= heightFactor;\n\n let isNoData = isNoDataValue(ndv, ndMin, ndMax, height);\n\n if ((isNoData || height === 0) && parentData) {\n height = getParentHeight(\n p.parentZoomDiff,\n p.parentOffsetX,\n p.parentOffsetY,\n parentData,\n pi,\n Math.floor(j * parentScale),\n p.skipPositiveHeights\n );\n isNoData = isNoDataValue(ndv, ndMin, ndMax, height);\n }\n\n outHeights[j] = isNoData ? noDataHeight : height;\n }\n}\n\n/**\n * Returns the height at the tile edge, extrapolated from the edge pixel p0 inwards through p1 and p2.\n * The slope is limited (minmod), so peaks, pits and slope breaks at the edge are not overshot.\n * @param {number} p0 - Edge pixel height.\n * @param {number} p1 - Next pixel height.\n * @param {number} p2 - Pixel height after the next.\n * @returns {number} -\n */\nexport function getEdgeHeight(p0: number, p1: number, p2: number): number {\n let s0 = p0 - p1,\n s1 = p1 - p2;\n return p0 + 0.5 * (s0 * s1 <= 0 ? 0 : Math.abs(s0) < Math.abs(s1) ? s0 : s1);\n}\n\n/**\n * Returns the ground height at the point of the tile heights grid, on the grid triangles as they are rendered.\n * @param {number} x - Point x in the tile extent projection.\n * @param {number} y - Point y in the tile extent projection.\n * @param {Extent} extent - Tile extent.\n * @param {number[] | TypedArray} heights - Tile heights grid, rows from north to south.\n * @returns {number} -\n */\nexport function getGroundHeight(x: number, y: number, extent: Extent, heights: number[] | TypedArray): number {\n let gs = Math.sqrt(heights.length),\n cells = gs - 1,\n col = ((x - extent.southWest.lon) / extent.getWidth()) * cells,\n row = ((extent.northEast.lat - y) / extent.getHeight()) * cells,\n j = Math.min(Math.max(Math.floor(col), 0), cells - 1),\n i = Math.min(Math.max(Math.floor(row), 0), cells - 1),\n fx = col - j,\n fy = 1 - (row - i);\n\n /*\n v2-----------v3\n | \\ |\n | \\ |\n | \\ |\n v0-----------v1\n */\n let k = i * gs + j,\n h2 = heights[k],\n h3 = heights[k + 1],\n h0 = heights[k + gs],\n h1 = heights[k + gs + 1];\n\n return fx + fy <= 1 ? h0 + fx * (h1 - h0) + fy * (h2 - h0) : h3 + (1 - fx) * (h2 - h3) + (1 - fy) * (h1 - h3);\n}\n\n/**\n * Writes the pixel row heights at the vertex columns: the edges, the pixel corners and, with half pixel steps,\n * the pixel centers.\n */\nfunction interpolateRow(pixels: Float32Array, offset: number, size: number, halfSteps: number, out: Float32Array) {\n let last = offset + size - 1;\n\n out[0] = getEdgeHeight(pixels[offset], pixels[Math.min(offset + 1, last)], pixels[Math.min(offset + 2, last)]);\n\n out[(size * 2) / halfSteps] = getEdgeHeight(\n pixels[last],\n pixels[Math.max(last - 1, offset)],\n pixels[Math.max(last - 2, offset)]\n );\n\n if (halfSteps === 1) {\n let prev = pixels[offset];\n out[1] = prev;\n for (let k = 1; k < size; k++) {\n let h = pixels[offset + k];\n out[k * 2] = 0.5 * (prev + h);\n out[k * 2 + 1] = h;\n prev = h;\n }\n } else {\n for (let k = 1; k < size; k++) {\n out[k] = 0.5 * (pixels[offset + k - 1] + pixels[offset + k]);\n }\n }\n}\n\n/**\n * Converts size x size pixel heights to the vertex grid in the pixel corners, (size + 1) x (size + 1),\n * or in the pixel centers and corners, (2 * size + 1) x (2 * size + 1). Pixel center vertices keep the pixel heights.\n * @param {Float32Array} pixels - Pixel heights, NaN for no data.\n * @param {number} size - Image size.\n * @param {number} noDataHeight - Height for vertices without data around.\n * @param {boolean} [pixelCenters=true] - Vertices at the pixel centers too.\n * @returns {Float32Array} -\n */\nexport function createVertexGrid(\n pixels: Float32Array,\n size: number,\n noDataHeight: number,\n pixelCenters: boolean = true\n): Float32Array {\n let halfSteps = pixelCenters ? 1 : 2,\n gs = (size * 2) / halfSteps + 1,\n last = size - 1;\n\n // Heights at the vertex columns of the last three pixel rows, pixel row r is kept at (r % 3)\n let columns = new Float32Array(gs * 3),\n rowColumns = [columns.subarray(0, gs), columns.subarray(gs, gs * 2), columns.subarray(gs * 2)],\n lastRow = -1;\n\n let out = new Float32Array(gs * gs);\n\n for (let vi = 0; vi < gs; vi++) {\n let u = vi * halfSteps,\n k = u >> 1,\n dst = vi * gs;\n\n let needRow = u === 0 ? Math.min(2, last) : Math.min(k, last);\n\n while (lastRow < needRow) {\n lastRow++;\n interpolateRow(pixels, lastRow * size, size, halfSteps, rowColumns[lastRow % 3]);\n }\n\n if (u & 1) {\n out.set(rowColumns[k % 3], dst);\n } else if (k === 0 || k === size) {\n let c0 = rowColumns[(k === 0 ? 0 : last) % 3],\n c1 = rowColumns[(k === 0 ? Math.min(1, last) : Math.max(last - 1, 0)) % 3],\n c2 = rowColumns[(k === 0 ? Math.min(2, last) : Math.max(last - 2, 0)) % 3];\n\n for (let vj = 0; vj < gs; vj++) {\n out[dst + vj] = getEdgeHeight(c0[vj], c1[vj], c2[vj]);\n }\n } else {\n let c0 = rowColumns[(k - 1) % 3],\n c1 = rowColumns[k % 3];\n\n for (let vj = 0; vj < gs; vj++) {\n out[dst + vj] = 0.5 * (c0[vj] + c1[vj]);\n }\n }\n\n for (let vj = 0; vj < gs; vj++) {\n if (out[dst + vj] !== out[dst + vj]) {\n out[dst + vj] = averagePixels(pixels, size, u, vj * halfSteps, noDataHeight);\n }\n }\n }\n\n return out;\n}\n\nfunction averagePixels(pixels: Float32Array, size: number, ui: number, uj: number, noDataHeight: number): number {\n let last = size - 1,\n ki = ui >> 1,\n kj = uj >> 1,\n sum = 0,\n count = 0;\n\n for (let i = Math.max(ki - 1, 0), i1 = Math.min(ki + (ui & 1), last); i <= i1; i++) {\n for (let j = Math.max(kj - 1, 0), j1 = Math.min(kj + (uj & 1), last); j <= j1; j++) {\n let h = pixels[i * size + j];\n if (h === h) {\n sum += h;\n count++;\n }\n }\n }\n\n return count ? sum / count : noDataHeight;\n}\n\n/** Peak and pit pixels, and their place in the vertex grid. */\nexport interface IGridPeaks {\n pixels: Float32Array;\n size: number;\n /** Peaks by pixel rows, columns of row r are cols[rowStart[r]] ... cols[rowStart[r + 1] - 1]. */\n rowStart: Int32Array;\n cols: Int32Array;\n /** 1 for peaks, 0 for pits. */\n isPeak: Uint8Array;\n /** Pixel p is at (p + offset) * scale vertex. */\n offset: number;\n scale: number;\n}\n\nconst HIGHER_AROUND = 1,\n LOWER_AROUND = 2;\n\nlet _around = new Uint8Array(0);\n\n/** Marks pixels a and b with the neighbour higher or lower flags, NaN pixels are not compared. */\nfunction compareNeighbours(pixels: Float32Array, around: Uint8Array, a: number, b: number) {\n let ha = pixels[a],\n hb = pixels[b];\n\n if (hb > ha) {\n around[a] |= HIGHER_AROUND;\n around[b] |= LOWER_AROUND;\n } else if (hb < ha) {\n around[a] |= LOWER_AROUND;\n around[b] |= HIGHER_AROUND;\n }\n}\n\n/**\n * Finds the pixels that are not lower (peaks) or not higher (pits) than the pixels around,\n * and differ from at least one of them.\n * @param {Float32Array} pixels - Pixel heights, NaN for no data.\n * @param {number} size - Image size.\n * @param {number} offset - Pixel p is at (p + offset) * scale vertex of the grid.\n * @param {number} scale - Grid vertices by pixel.\n * @returns {IGridPeaks} -\n */\nexport function findPeaks(pixels: Float32Array, size: number, offset: number, scale: number): IGridPeaks {\n let last = size - 1,\n length = size * size;\n\n if (_around.length < length) {\n _around = new Uint8Array(length);\n } else {\n _around.fill(0, 0, length);\n }\n\n let around = _around;\n\n // Every neighbour pair is compared once, in 2x2 squares a b / c d: a-b, a-c, a-d and b-c\n for (let r = 0; r < last; r++) {\n let row = r * size;\n for (let k = row, end = row + last; k < end; k++) {\n compareNeighbours(pixels, around, k, k + 1);\n compareNeighbours(pixels, around, k, k + size);\n compareNeighbours(pixels, around, k, k + size + 1);\n compareNeighbours(pixels, around, k + 1, k + size);\n }\n compareNeighbours(pixels, around, row + last, row + last + size);\n }\n for (let k = last * size, end = k + last; k < end; k++) {\n compareNeighbours(pixels, around, k, k + 1);\n }\n\n let rowStart = new Int32Array(size + 1),\n count = 0;\n\n for (let k = 0; k < length; k++) {\n if (around[k] === HIGHER_AROUND || around[k] === LOWER_AROUND) {\n count++;\n }\n }\n\n let cols = new Int32Array(count),\n isPeak = new Uint8Array(count);\n\n count = 0;\n\n for (let r = 0; r < size; r++) {\n rowStart[r] = count;\n for (let c = 0, k = r * size; c < size; c++, k++) {\n if (around[k] === HIGHER_AROUND || around[k] === LOWER_AROUND) {\n cols[count] = c;\n isPeak[count] = around[k] === LOWER_AROUND ? 1 : 0;\n count++;\n }\n }\n }\n\n rowStart[size] = count;\n\n return { pixels, size, rowStart, cols, isPeak, offset, scale };\n}\n\n// Peak deviations of the sampled grid vertices, reused\nlet _deviations = new Float32Array(0);\n\n/**\n * Takes (gridSize + 1) x (gridSize + 1) vertices of the cells x cells square starting at\n * the row0, col0 vertex of the (size + 1) x (size + 1) grid. Cells must be gridSize multiplied by a power of two.\n *\n * With peaks, peaks and pits are moved to the nearest inner vertices, slopes and edge vertices stay sampled.\n */\nexport function sampleSubGrid(\n grid: Float32Array,\n size: number,\n row0: number,\n col0: number,\n cells: number,\n gridSize: number,\n out: Float32Array = new Float32Array((gridSize + 1) * (gridSize + 1)),\n outOffset: number = 0,\n peaks: IGridPeaks | null = null,\n noDataHeight: number = NaN\n): Float32Array {\n let gs = size + 1,\n outGs = gridSize + 1,\n step = cells / gridSize;\n\n for (let i = 0; i < outGs; i++) {\n let src = (row0 + i * step) * gs + col0,\n dst = outOffset + i * outGs;\n for (let j = 0; j < outGs; j++) {\n out[dst + j] = grid[src + j * step];\n }\n }\n\n if (peaks && step > 1 && gridSize > 1) {\n keepPeaks(grid, gs, row0, col0, cells, gridSize, out, outOffset, peaks, noDataHeight);\n }\n\n return out;\n}\n\nfunction keepPeaks(\n grid: Float32Array,\n gs: number,\n row0: number,\n col0: number,\n cells: number,\n gridSize: number,\n out: Float32Array,\n outOffset: number,\n peaks: IGridPeaks,\n noDataHeight: number\n) {\n let outGs = gridSize + 1,\n step = cells / gridSize,\n half = step >> 1,\n inner = gridSize - 1,\n { pixels, size, rowStart, cols, isPeak, offset, scale } = peaks;\n\n // Pixels in the square\n let pr0 = Math.max(Math.ceil(row0 / scale - offset), 0),\n pr1 = Math.min(Math.floor((row0 + cells) / scale - offset), size - 1),\n pc0 = Math.max(Math.ceil(col0 / scale - offset), 0),\n pc1 = Math.min(Math.floor((col0 + cells) / scale - offset), size - 1);\n\n if (_deviations.length < outGs * outGs) {\n _deviations = new Float32Array(outGs * outGs);\n }\n\n _deviations.fill(0, 0, outGs * outGs);\n\n for (let pr = pr0; pr <= pr1; pr++) {\n let p = rowStart[pr],\n end = rowStart[pr + 1];\n\n for (let hi = end; p < hi;) {\n let m = (p + hi) >> 1;\n if (cols[m] < pc0) {\n p = m + 1;\n } else {\n hi = m;\n }\n }\n\n if (p === end || cols[p] > pc1) {\n continue;\n }\n\n let y = (pr + offset) * scale - row0,\n ci = Math.min(Math.floor(y / step), inner),\n fy = y / step - ci,\n i = Math.min(Math.max(Math.floor((y + half) / step), 1), inner),\n top = (row0 + ci * step) * gs + col0,\n bottom = top + step * gs,\n vertexRow = (row0 + i * step) * gs + col0;\n\n for (; p < end && cols[p] <= pc1; p++) {\n let x = (cols[p] + offset) * scale - col0,\n cj = Math.min(Math.floor(x / step), inner),\n fx = x / step - cj,\n k = cj * step;\n\n let h00 = grid[top + k],\n h01 = grid[top + k + step],\n h10 = grid[bottom + k],\n h11 = grid[bottom + k + step];\n\n if (h00 === noDataHeight || h01 === noDataHeight || h10 === noDataHeight || h11 === noDataHeight) {\n continue;\n }\n\n let surface = (1 - fy) * ((1 - fx) * h00 + fx * h01) + fy * ((1 - fx) * h10 + fx * h11),\n h = pixels[pr * size + cols[p]],\n deviation = isPeak[p] ? h - surface : surface - h;\n\n if (deviation <= 0 || h === noDataHeight) {\n continue;\n }\n\n let j = Math.min(Math.max(Math.floor((x + half) / step), 1), inner),\n v = i * outGs + j;\n\n if (deviation > _deviations[v] && deviation > Math.abs(surface - grid[vertexRow + j * step])) {\n _deviations[v] = deviation;\n out[outOffset + v] = h;\n }\n }\n }\n}\n\n/**\n * Returns (gridSize + 1) x (gridSize + 1) mesh heights of (fileGridSize + 1) x (fileGridSize + 1) elevations,\n * their peaks and pits are moved to the nearest mesh vertices.\n * @param {Float32Array} elevations - Elevations grid, rows from north to south.\n * @param {number} fileGridSize - Elevations grid size.\n * @param {number} gridSize - Mesh grid size, fileGridSize divided by a power of two.\n * @param {number} noDataHeight - Height of no data elevations.\n * @param {Float32Array} [out] - Mesh heights.\n * @returns {Float32Array} -\n */\nexport function getMeshHeights(\n elevations: Float32Array,\n fileGridSize: number,\n gridSize: number,\n noDataHeight: number,\n out: Float32Array = new Float32Array((gridSize + 1) * (gridSize + 1))\n): Float32Array {\n return sampleSubGrid(\n elevations,\n fileGridSize,\n 0,\n 0,\n fileGridSize,\n gridSize,\n out,\n 0,\n findPeaks(elevations, fileGridSize + 1, 0, 1),\n noDataHeight\n );\n}\n\n/**\n * Tile pixels, the source of its subdivision level tiles made one by one with createLevelHeights.\n */\nexport interface IHeightsLevelsSource {\n /** Pixel heights, NaN for no data. (2^n + 1) images are the vertex grid, no data are noDataHeight there. */\n pixels: Float32Array;\n size: number;\n gridSize: number;\n levels: number;\n noDataHeight: number;\n /** Peaks of the (2^n + 1) vertex grid, 2^n images find them around every level tile. */\n peaks: IGridPeaks | null;\n}\n\n// Vertices at the pixel centers are needed when the last level is not coarser than the pixels,\n// pixel corners alone would average its peaks and pits away\nfunction isPixelCentersGrid(size: number, gridSize: number, levels: number): boolean {\n return size >> levels <= gridSize;\n}\n\n/**\n * Decodes the tile pixels for its subdivision level tiles.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels.\n * @param {DecodeHeightsRowFunc} decodeRow - Decodes pixel row heights, NaN for no data.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {IHeightsLevelsSource} -\n */\nexport function createHeightsLevelsSource(\n size: number,\n gridSize: number,\n levels: number,\n decodeRow: DecodeHeightsRowFunc,\n noDataHeight: number\n): IHeightsLevelsSource {\n let pixels = new Float32Array(size * size),\n peaks: IGridPeaks | null = null;\n\n for (let row = 0; row < size; row++) {\n decodeRow(row, pixels.subarray(row * size, (row + 1) * size));\n }\n\n if (getGridCells(size) !== size) {\n peaks = findPeaks(pixels, size, 0, 1);\n for (let k = 0; k < pixels.length; k++) {\n if (pixels[k] !== pixels[k]) {\n pixels[k] = noDataHeight;\n }\n }\n }\n\n return { pixels, size, gridSize, levels, noDataHeight, peaks };\n}\n\n// Pixels around a level tile in its window: vertices and peaks depend on the next pixels only, at the image\n// edges the window is shifted inside and keeps the three pixels the edge vertices are extrapolated from\nconst LEVEL_TILE_MARGIN = 1;\n\n/**\n * Returns the heights of the level tile in the row i and the column j, the same as createHeightsLevels makes.\n * 2^n images make the vertex grid and find the peaks in the window of the tile pixels with a margin around,\n * so a tile costs its own pixels only.\n * @param {IHeightsLevelsSource} source - Tile pixels.\n * @param {number} level - Subdivision level, 0 is the tile itself.\n * @param {number} i - Level tile row, from the north.\n * @param {number} j - Level tile column, from the west.\n * @param {Float32Array} [out] - Level tile heights.\n * @returns {Float32Array} -\n */\nexport function createLevelHeights(\n source: IHeightsLevelsSource,\n level: number,\n i: number,\n j: number,\n out: Float32Array = new Float32Array((source.gridSize + 1) * (source.gridSize + 1))\n): Float32Array {\n let { pixels, size, gridSize, levels, noDataHeight, peaks } = source;\n\n if (peaks) {\n let c = (size - 1) >> level;\n return sampleSubGrid(pixels, size - 1, i * c, j * c, c, gridSize, out, 0, peaks, noDataHeight);\n }\n\n let pixelCenters = isPixelCentersGrid(size, gridSize, levels),\n scale = pixelCenters ? 2 : 1,\n tilePixels = size >> level,\n w = Math.min(tilePixels + 2 * LEVEL_TILE_MARGIN, size),\n row0 = Math.min(Math.max(i * tilePixels - LEVEL_TILE_MARGIN, 0), size - w),\n col0 = Math.min(Math.max(j * tilePixels - LEVEL_TILE_MARGIN, 0), size - w);\n\n let windowPixels = pixels;\n\n if (w < size) {\n windowPixels = new Float32Array(w * w);\n for (let r = 0; r < w; r++) {\n let src = (row0 + r) * size + col0;\n windowPixels.set(pixels.subarray(src, src + w), r * w);\n }\n }\n\n return sampleSubGrid(\n createVertexGrid(windowPixels, w, noDataHeight, pixelCenters),\n w * scale,\n (i * tilePixels - row0) * scale,\n (j * tilePixels - col0) * scale,\n tilePixels * scale,\n gridSize,\n out,\n 0,\n findPeaks(windowPixels, w, 0.5, scale),\n noDataHeight\n );\n}\n\n/**\n * Returns the (gridSize + 1) x (gridSize + 1) heights of the tile pixels, peaks and pits stay. Subdivision levels\n * the pixels are kept for change the vertex grid, so the tile is made as its level 0.\n * @param {Float32Array} pixels - Pixel heights, rows from north to south, NaN for no data.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels of the tile pixels.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {Float32Array} -\n */\nexport function createTileHeights(\n pixels: Float32Array,\n size: number,\n gridSize: number,\n levels: number,\n noDataHeight: number\n): Float32Array {\n let decodeRow = (row: number, out: Float32Array) => out.set(pixels.subarray(row * size, (row + 1) * size));\n\n if (!levels) {\n return createHeightsLevels(size, gridSize, 0, decodeRow, noDataHeight);\n }\n\n return createLevelHeights(createHeightsLevelsSource(size, gridSize, levels, decodeRow, noDataHeight), 0, 0, 0);\n}\n\n/**\n * Creates the tile heights grid and its subdivision levels, each tile is (gridSize + 1) x (gridSize + 1).\n * Output order is the tile itself, then 2x2 tiles of the first level, 4x4 of the second and so on, row by row.\n * Peaks and pits of the pixels stay in all the levels.\n * @param {number} size - Image size, 2^n or (2^n + 1).\n * @param {number} gridSize - Tile grid size.\n * @param {number} levels - Subdivision levels.\n * @param {DecodeHeightsRowFunc} decodeRow - Decodes pixel row heights, NaN for no data.\n * @param {number} noDataHeight - Height for vertices without data.\n * @returns {Float32Array} -\n */\nexport function createHeightsLevels(\n size: number,\n gridSize: number,\n levels: number,\n decodeRow: DecodeHeightsRowFunc,\n noDataHeight: number\n): Float32Array {\n let source = createHeightsLevelsSource(size, gridSize, levels, decodeRow, noDataHeight),\n pixels = source.pixels;\n\n let grid: Float32Array, cells: number, peaks: IGridPeaks;\n\n if (source.peaks) {\n grid = pixels;\n cells = size - 1;\n peaks = source.peaks;\n } else {\n let pixelCenters = isPixelCentersGrid(size, gridSize, levels);\n grid = createVertexGrid(pixels, size, noDataHeight, pixelCenters);\n cells = pixelCenters ? size * 2 : size;\n peaks = findPeaks(pixels, size, 0.5, cells / size);\n }\n\n let tileLength = (gridSize + 1) * (gridSize + 1),\n tilesCount = 0;\n\n for (let k = 0; k <= levels; k++) {\n tilesCount += 1 << (2 * k);\n }\n\n let out = new Float32Array(tilesCount * tileLength);\n\n for (let k = 0, c = cells, offset = 0; k <= levels; k++, c >>= 1) {\n let d = 1 << k;\n for (let i = 0; i < d; i++) {\n for (let j = 0; j < d; j++) {\n sampleSubGrid(grid, cells, i * c, j * c, c, gridSize, out, offset, peaks, noDataHeight);\n offset += tileLength;\n }\n }\n }\n\n return out;\n}\n","import type { IRgbHeightsParams } from \"../terrain/terrainUtils\";\n\nconst PARAMS_ID = 0,\n PARAMS_SIZE = 1,\n PARAMS_GRID_SIZE = 2,\n PARAMS_LEVELS = 3,\n PARAMS_ENCODING = 4,\n PARAMS_MIN_HEIGHT = 5,\n PARAMS_RESOLUTION = 6,\n PARAMS_HEIGHT_FACTOR = 7,\n PARAMS_PARENT_OFFSET_X = 8,\n PARAMS_PARENT_OFFSET_Y = 9,\n PARAMS_PARENT_ZOOM_DIFF = 10,\n PARAMS_SKIP_POSITIVE_HEIGHTS = 11,\n PARAMS_NO_DATA_HEIGHT = 12,\n PARAMS_NO_DATA_VALUES = 13;\n\n/**\n * Packs height parameters to the buffer for the worker message.\n * @param {number} id - Worker task id.\n * @param {IRgbHeightsParams} p - Heights parameters, parent data is sent separately.\n * @returns {Float64Array} -\n */\nexport function packRgbHeightsParams(id: number, p: IRgbHeightsParams): Float64Array {\n let d = p.decode,\n ndv = d.noDataValues;\n let params = new Float64Array(PARAMS_NO_DATA_VALUES + ndv.length);\n\n params[PARAMS_ID] = id;\n params[PARAMS_SIZE] = p.size;\n params[PARAMS_GRID_SIZE] = p.gridSize;\n params[PARAMS_LEVELS] = p.levels;\n params[PARAMS_ENCODING] = d.encoding;\n params[PARAMS_MIN_HEIGHT] = d.minHeight;\n params[PARAMS_RESOLUTION] = d.resolution;\n params[PARAMS_HEIGHT_FACTOR] = d.heightFactor;\n params[PARAMS_PARENT_OFFSET_X] = d.parentOffsetX;\n params[PARAMS_PARENT_OFFSET_Y] = d.parentOffsetY;\n params[PARAMS_PARENT_ZOOM_DIFF] = d.parentZoomDiff;\n params[PARAMS_SKIP_POSITIVE_HEIGHTS] = d.skipPositiveHeights ? 1 : 0;\n params[PARAMS_NO_DATA_HEIGHT] = p.noDataHeight;\n\n for (let i = 0; i < ndv.length; i++) {\n params[PARAMS_NO_DATA_VALUES + i] = ndv[i];\n }\n return params;\n}\n\n/**\n * Unpacks height parameters from the worker message buffer.\n * @param {Float64Array} params - Packed parameters.\n * @param {Float32Array | null} parentData - Parent segment elevations.\n * @returns {Array} - Task id and parameters (exactly 2 entries).\n */\nexport function unpackRgbHeightsParams(\n params: Float64Array,\n parentData: Float32Array | null\n): [number, IRgbHeightsParams] {\n return [\n params[PARAMS_ID],\n {\n decode: {\n encoding: params[PARAMS_ENCODING],\n minHeight: params[PARAMS_MIN_HEIGHT],\n resolution: params[PARAMS_RESOLUTION],\n heightFactor: params[PARAMS_HEIGHT_FACTOR],\n noDataValues: params.subarray(PARAMS_NO_DATA_VALUES),\n parentData: parentData,\n parentOffsetX: params[PARAMS_PARENT_OFFSET_X],\n parentOffsetY: params[PARAMS_PARENT_OFFSET_Y],\n parentZoomDiff: params[PARAMS_PARENT_ZOOM_DIFF],\n skipPositiveHeights: params[PARAMS_SKIP_POSITIVE_HEIGHTS] === 1\n },\n size: params[PARAMS_SIZE],\n gridSize: params[PARAMS_GRID_SIZE],\n levels: params[PARAMS_LEVELS],\n noDataHeight: params[PARAMS_NO_DATA_HEIGHT]\n }\n ];\n}\n","\"use strict\";\n//\n// RGB terrain heights worker\n//\nimport { createHeightsLevels, decodeRgbHeightsRow, getGridCells } from \"../terrain/terrainUtils\";\nimport { unpackRgbHeightsParams } from \"./RgbTerrainWorkerParams\";\n\nlet ctx = null;\n\nfunction getImageData(bitmap, size) {\n if (!ctx || ctx.canvas.width !== size) {\n ctx = new OffscreenCanvas(size, size).getContext(\"2d\", {\n willReadFrequently: true\n });\n }\n\n ctx.clearRect(0, 0, size, size);\n ctx.drawImage(bitmap, 0, 0);\n\n return ctx.getImageData(0, 0, size, size).data;\n}\n\nself.onmessage = function (e) {\n const [id, p] = unpackRgbHeightsParams(e.data.params, e.data.parentData);\n const bitmap = e.data.bitmap;\n\n let heights = null;\n\n try {\n const rgbaData = getImageData(bitmap, p.size);\n const parentScale = p.gridSize / getGridCells(p.size);\n\n heights = createHeightsLevels(\n p.size,\n p.gridSize,\n p.levels,\n (row, outHeights) => decodeRgbHeightsRow(rgbaData, row, p.size, parentScale, p.decode, outHeights, NaN),\n p.noDataHeight\n );\n } catch (err) {\n console.error(err);\n }\n\n bitmap.close();\n\n self.postMessage(\n {\n id: id,\n heights: heights\n },\n heights ? [heights.buffer] : []\n );\n};\n"],"mappings":"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"}