mapbox-gl
Version:
A WebGL interactive maps library
63 lines (52 loc) • 2.41 kB
JavaScript
// @flow
import DEMData from '../data/dem_data';
import {RGBAImage} from '../util/image';
import window from '../util/window';
import type Actor from '../util/actor';
import type {
WorkerDEMTileParameters,
WorkerDEMTileCallback,
TileParameters
} from './worker_source';
const {ImageBitmap} = window;
class RasterDEMTileWorkerSource {
actor: Actor;
loaded: {[_: string]: DEMData};
offscreenCanvas: OffscreenCanvas;
offscreenCanvasContext: CanvasRenderingContext2D;
constructor() {
this.loaded = {};
}
loadTile(params: WorkerDEMTileParameters, callback: WorkerDEMTileCallback) {
const {uid, encoding, rawImageData} = params;
// Main thread will transfer ImageBitmap if offscreen decode with OffscreenCanvas is supported, else it will transfer an already decoded image.
const imagePixels = (ImageBitmap && rawImageData instanceof ImageBitmap) ? this.getImageData(rawImageData) : rawImageData;
const dem = new DEMData(uid, imagePixels, encoding);
this.loaded = this.loaded || {};
this.loaded[uid] = dem;
callback(null, dem);
}
getImageData(imgBitmap: ImageBitmap): RGBAImage {
// Lazily initialize OffscreenCanvas
if (!this.offscreenCanvas || !this.offscreenCanvasContext) {
// Dem tiles are typically 256x256
this.offscreenCanvas = new OffscreenCanvas(imgBitmap.width, imgBitmap.height);
this.offscreenCanvasContext = this.offscreenCanvas.getContext('2d');
}
this.offscreenCanvas.width = imgBitmap.width;
this.offscreenCanvas.height = imgBitmap.height;
this.offscreenCanvasContext.drawImage(imgBitmap, 0, 0, imgBitmap.width, imgBitmap.height);
// Insert an additional 1px padding around the image to allow backfilling for neighboring data.
const imgData = this.offscreenCanvasContext.getImageData(-1, -1, imgBitmap.width + 2, imgBitmap.height + 2);
this.offscreenCanvasContext.clearRect(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);
return new RGBAImage({width: imgData.width, height: imgData.height}, imgData.data);
}
removeTile(params: TileParameters) {
const loaded = this.loaded,
uid = params.uid;
if (loaded && loaded[uid]) {
delete loaded[uid];
}
}
}
export default RasterDEMTileWorkerSource;