In Openlayers,I want to realize render multiple bands Geotiff by Contrast Stretch Min and Max. Like by QGIS or Geoserver using SLD:
<sld:RasterSymbolizer>
<sld:ChannelSelection>
<sld:RedChannel>
<sld:SourceChannelName>1</sld:SourceChannelName>
<sld:ContrastEnhancement>
<sld:Normalize>
<sld:VendorOption name="minValue">-3.509304523468</sld:VendorOption>
<sld:VendorOption name="maxValue">701.02770996094</sld:VendorOption>
<sld:VendorOption name="algorithm">StretchToMinimumMaximum</sld:VendorOption>
</sld:Normalize>
</sld:ContrastEnhancement>
</sld:RedChannel>
<sld:GreenChannel>
<sld:SourceChannelName>2</sld:SourceChannelName>
<sld:ContrastEnhancement>
<sld:Normalize>
<sld:VendorOption name="minValue">12.172845840454</sld:VendorOption>
<sld:VendorOption name="maxValue">20.350427627563</sld:VendorOption>
<sld:VendorOption name="algorithm">StretchToMinimumMaximum</sld:VendorOption>
</sld:Normalize>
</sld:ContrastEnhancement>
</sld:GreenChannel>
<sld:BlueChannel>
<sld:SourceChannelName>1</sld:SourceChannelName>
<sld:ContrastEnhancement>
<sld:Normalize>
<sld:VendorOption name="minValue">-3.509304523468</sld:VendorOption>
<sld:VendorOption name="maxValue">701.02770996094</sld:VendorOption>
<sld:VendorOption name="algorithm">StretchToMinimumMaximum</sld:VendorOption>
</sld:Normalize>
</sld:ContrastEnhancement>
</sld:BlueChannel>
</sld:ChannelSelection>
<sld:ContrastEnhancement/>
</sld:RasterSymbolizer>
I have seen the examples like https://openlayers.org/en/latest/examples/cog-stretch.html and https://openlayers.org/en/latest/examples/cog-style.html.
But I dit not find the method which I need. Can you help me ? Appreciate any clues or suggestions.Thank you.
There are two ways to replicate that SLD
Either let OpenLayers normalize it and use the default RGBA style. As each band has different min and max values the url will need to be loaded multiple tiles
const rMin = -3.509304523468;
const rMax = 701.02770996094;
const gMin = 12.172845840454;
const gMax = 20.350427627563;
const bMin = -3.509304523468;
const bMax = 701.02770996094;
const source = new GeoTIFF({
sources: [
{
bands: [1],
min: rMin,
max: rMax,
url: url,
},
{
bands: [2],
min: gMin,
max: gMax,
url: url,
},
{
bands: [3],
min: bMin,
max: bMax,
url: url,
},
],
});
const layer = new TileLayer({
source: source,
});
Or normalize it between the min and max values for each band yourself, which should be more efficient
function normalize(band, min, max) {
return [
'/',
['-', ['clamp', ['band', band], min, max], min],
['-', max, min],
];
}
const source = new GeoTIFF({
normalize: false,
sources: [
{
url: url,
},
],
});
const layer = new TileLayer({
source: source,
style: {
color: [
'array',
normalize(1, rMin, rMax),
normalize(2, gMin, gMax),
normalize(3, bMin, bMax),
1,
],
},
});