Sam
Sam

Reputation: 25

Openlayers webglLayers band index restriction (4)

I have a "simple" problem to solve: visualize a timeseries of raster data in a web application (using openlayers, if possible). The original format of the raster data is in .asc files. Lets say I have a series 1.asc, 2.asc, ....N.asc, each representing water depth at different times let's say. This rasters can be arbitrarily large, so let's assume huge arrays. I'm in control of this data and can transform it and store in any format that is required to solve this problem.

What I want is the ability to (with a slider let's say) transition in time smoothly, that's all. Ofcourse, one way would be to fetch server side rendered images, but that ofc is not practical (huge load times).

I have tried so many things in openlayers and nothing is working properly. The first approach was to generate a tiles directory of png images for each raster. Then, on the client side, have each raster be its own layer. This does not solve the problem since transitioning from layer to layer has an initial loading time, which is the main problem.

Then I thought, what if I combine the whole timeserie data? i.e. generate a tif file with N bands, with COG format? Or many tif images, with 1 band each, and let openlayers handle it? Yeah, that must be the way. But ofc, openlayers must make my life harder by not making an freaking sense... let me explain:

I generate single band geotif files:

gdal_translate -of GTiff 1.asc 1.tif
gdal_translate -of GTiff 2.asc 2.tif
...
gdal_translate -of GTiff N.asc N.tif

running gdalinfo 1.tif:

...
Band 1 Block=2100x1 Type=Float32, ColorInterp=Gray
Computed Min/Max=0.000,4.262

which shows the tiffs are single banded. I also tried with -of COD for performance, same results. Now, following the freaking examples from openlayers, I do the following:

import GeoTIFF from 'ol/source/GeoTIFF.js';
import Map from 'ol/Map.js';
import WebGLTileLayer from 'ol/layer/WebGLTile.js';
import { register } from 'ol/proj/proj4.js';
import { View } from "ol";
import { OSM } from "ol/source";

const genurl = (i: number) => `https://blablabla/cogs/${i}.tif`
const urls = [...Array.from({ length: 10 }, (_, index) => index)].map(i => genurl(i))

const sources = [
    new GeoTIFF({
        sources: urls.map(x => ({ url: x, bands: [1] })),
        normalize: false,
    }),

];
let band = 1
const layer = new WebGLTileLayer({
    variables: {band}
    sources: sources,
    style: {
        color: [
            "case",
            ["<", ["var", "band"], 0.5],
            [0, 0, 255, 1],
            [255, 0, 0, 1]

    
        ],
    },
});
const onRight = () => {
    band++
    layer.updateStyleVariables({ band });
}

const onLeft = () => {
    band--
    layer.updateStyleVariables({ band });
}

Now, this works exactly the way I want for the first 4 bands. When tiles (or whatever we call it) needs to be loaded, all bands are fetched (all, not just 4). When i move left or right, the rendering occurs directly, since everything is fetched.

BUT IT DOES NOT WORK IF band >= 5. I've been searching in the damn docs and examples for days and THERE IS NOTHING ABOUT THIS **** issue. Why on earth would openlayers now allow for this!!!

I cant be the only human on earth who wants to achieve this behaviour. Please help me, I'm going insane.

Upvotes: 0

Views: 50

Answers (0)

Related Questions