2

My server is statically serving several different PNG images of the same object, each taken with a different spectral filter (for example, just a red channel or just a blue channel). I'd like to show a slippy, false-colored map of that object. I do so by creating three separate images sources like so:

extent = [0, 0, ncols, nrows];
pixelProjection = new ol.proj.Projection({
    code: 'some-image',
    units: 'pixels',
    extent: extent
});

rsource = new ol.source.ImageStatic({
    url: "static/imgs/band_1.png",
    projection: pixelProjection,
    imageExtent: extent
});
gsource = new ol.source.ImageStatic({
    url: "static/imgs/band_2.png",
    projection: pixelProjection,
    imageExtent: extent
});
bsource = new ol.source.ImageStatic({
    url: "static/imgs/band_3.png",
    projection: pixelProjection,
    imageExtent: extent
});

Next, I use these sources as inputs to a raster source which can compose them:

rgbSources = [rsource, gsource, bsource];
raster = new ol.source.Raster({
    sources: rgbSources,
    operation: function(bands, data) {
        var rband = bands[0];
        var gband = bands[1];
        var bband = bands[2];

        var composed = [
            rband[0],
            gband[0],
            bband[0],
            255
        ];
        return composed;
    }
});

I then create a layer that uses this raster as its source:

colorLayer = new ol.layer.Image({
    source: raster
});

Lastly, I can create a map and add my raster layer to the map:

var map = new ol.Map({
    target: 'map',
    view: new ol.View({
        center:ol.extent.getCenter(extent),
        projection: pixelProjection,
        zoom: 1.5
    })
});
map.addLayer(colorLayer);

So far so good! This displays a colorized version of the image as expected. The problem arises when the user triggers a change to a color channel by inputting a new channel index to pull from. I handle a blue channel change like this:

var index = 4;  // actually gets passed in from user
bsource = new ol.source.ImageStatic({
    url: "static/imgs/band_" + index + ".png",
    projection: pixelProjection,
    imageExtent: extent
});
rgbSources[2] = bsource;   // this was in global scope from before
raster.sources = rgbSources;  // as was this

Expected behavior is that the map would immediately change colors, or at least it would change when I zoom in or pan but neither of those things happens. I am unable to get the new colors to appear at all. Am I updating the wrong thing? Perhaps the raster.sources field has an associated setter function that I am unable to find?

1 Answer 1

1

Found a solution! It looks like setting a raster's source directly is not allowed, but setting a layer's source is. So unfortunately, I have to create a new raster object (new source entirely), but at least I don't need a new layer:

raster = new ol.source.Raster({
    sources: rgbSources,
    operation: composeBands
});
colorLayer.setSource(raster);

Accepting my own answer but willing to accept someone else's solution if it means I don't need to create a new source.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.