@allmaps/render
Version:
Render functions for WebGL and image buffers
79 lines (78 loc) • 3.3 kB
JavaScript
import inside from "point-in-polygon-hao";
import { doBboxesIntersect, closeRing, pointToPixel, pixelToIntArrayIndex } from "@allmaps/stdlib";
import { resourcePointInTile, tileToTileOriginPoint, clipTilePointToTile } from "./tiles.js";
import { invertHomogeneousTransform, applyHomogeneousTransform } from "./homogeneous-transform.js";
const CHANNELS = 4;
async function renderToIntArray(warpedMapList, tileCache, viewport, getImageDataValue, getImageDataSize, intArray) {
for (const warpedMap of warpedMapList.getWarpedMaps()) {
if (!doBboxesIntersect(
viewport.projectedGeoRectangleBbox,
warpedMap.projectedGeoMaskBbox
)) {
continue;
}
const cachedTiles = tileCache.getMapCachedTiles(warpedMap.mapId);
const canvasToProjectedGeoHomogeneousTransform = invertHomogeneousTransform(
viewport.projectedGeoToCanvasHomogeneousTransform
);
for (let canvasPixelX = 0; canvasPixelX < viewport.canvasSize[0]; canvasPixelX++) {
for (let canvasPixelY = 0; canvasPixelY < viewport.canvasSize[1]; canvasPixelY++) {
const canvasPixel = [canvasPixelX, canvasPixelY];
const projectedGeoPoint = applyHomogeneousTransform(
canvasToProjectedGeoHomogeneousTransform,
canvasPixel
);
const resourcePoint = warpedMap.projectedTransformer.transformToResource(projectedGeoPoint);
if (inside(resourcePoint, [closeRing(warpedMap.resourceMask)]) === false) {
continue;
}
let cachedTile;
let foundCachedTile = false;
for (cachedTile of cachedTiles) {
if (resourcePointInTile(resourcePoint, cachedTile.fetchableTile.tile)) {
foundCachedTile = true;
break;
}
}
if (foundCachedTile && cachedTile) {
const tile = cachedTile.fetchableTile.tile;
const tileSize = getImageDataSize(cachedTile.data);
const resourceTileOriginPoint = tileToTileOriginPoint(tile);
const tilePoint = resourcePoint.map(
(coordinate, index) => (coordinate - resourceTileOriginPoint[index]) / tile.tileZoomLevel.scaleFactor
);
const tilePointPixels = [
pointToPixel(tilePoint, [0, 0]),
pointToPixel(tilePoint, [1, 0]),
pointToPixel(tilePoint, [0, 1]),
pointToPixel(tilePoint, [1, 1])
];
const canvasPixelIntArrayIndex = pixelToIntArrayIndex(
canvasPixel,
viewport.canvasSize,
CHANNELS
);
for (let color = 0; color < CHANNELS; color++) {
intArray[canvasPixelIntArrayIndex + color] = tilePointPixels.map(
(tilePointPixel) => getImageDataValue(
cachedTile.data,
pixelToIntArrayIndex(
clipTilePointToTile(tilePointPixel, tile),
tileSize,
CHANNELS
) + color
) * bilinearPixelWeight(tilePointPixel, tilePoint)
).reduce((a, c) => a + c, 0);
}
}
}
}
}
}
function bilinearPixelWeight(pixel, point) {
return (1 - Math.abs(point[0] - pixel[0])) * (1 - Math.abs(point[1] - pixel[1]));
}
export {
renderToIntArray
};
//# sourceMappingURL=render-to-int-array.js.map