On-the-Fly Raster Processing and SLD Application in GeoServer

Dear [GeoServer Support/Community],

I am seeking guidance on whether it is possible to perform an on-the-fly raster calculation in GeoServer to visualize a filtered layer on the map with Openlayers.

Specifically, I am interested in executing an operation similar to the following GRASS GIS r.mapcalc expression:

if(slope_450m_4326@PERMANENT >= MIN_SLOPE_VAL && slope_450m_4326@PERMANENT <= MAX_SLOPE_VAL, sea_depth_450m_4326@PERMANENT, null())

Where MIN_SLOPE_VAL and MAX_SLOPE_VAL values are user input.
Additionally, I would like to know if such an operation can be achieved through the application of an SLD style, like the application of a filter on a single layer. If GeoServer does not support this functionality directly, I would greatly appreciate your advice on the best method to achieve this result.

Thank you for your assistance and expertise on this matter.

Kind regards,
Sara

We recently needed to do this as well. We ended up using the Jiffle transformation in the SLDs of the rasters like so:

  <ogc:Function name="ras:Jiffle">
	<ogc:Function name="parameter">
	  <ogc:Literal>coverage</ogc:Literal>
	</ogc:Function>
	<ogc:Function name="parameter">
	  <ogc:Literal>script</ogc:Literal>
	  <ogc:Function name="Concatenate">
		<ogc:Literal>
		  value = src[0];
		  if (value &lt; 
		</ogc:Literal>
		<ogc:Function name="env">
		  <ogc:Literal>minimum</ogc:Literal>
		  <ogc:Literal>-9999</ogc:Literal>
		</ogc:Function>
		<ogc:Literal>
		   || value &gt;
		</ogc:Literal>
		<ogc:Function name="env">
		  <ogc:Literal>maximum</ogc:Literal>
		  <ogc:Literal>9999999</ogc:Literal>
		</ogc:Function>
		<ogc:Literal>
		  ) {
			value = -9999;
		  } else {
			dest = value;
		  }
		</ogc:Literal>
	  </ogc:Function>
	</ogc:Function>
  </ogc:Function>

You just have to make sure the minimum/maximum values are sent as env parameters in the requests: &env=minimum:10;maximum:100

Hope this helps

Thank you so much for your helpful code!! I also ended up adding this rule in the SLD of a raster

<sld:Rule>
    <sld:RasterSymbolizer>
        <sld:Opacity>1.0</sld:Opacity>
        <sld:ColorMap>
            <!-- Valori minori di maxDepth (opacità 0) -->
            <sld:ColorMapEntry color="#FFFFFF" quantity="${env('maxDepth', -2000)}" label="Below Max Depth" opacity="1"/>
            <!-- Valori tra minDepth e maxDepth -->
            <sld:ColorMapEntry color="#0000FF" quantity="${env('maxDepth', -2000)}" label="${env('maxDepth', -2000)}" opacity="0"/>
            <sld:ColorMapEntry color="#0000FF" quantity="${env('minDepth', -100)}" label="${env('minDepth', -100)}" opacity="0"/>
            <!-- Valori maggiori di minDepth, (opacità 0) -->
            <sld:ColorMapEntry color="#FFFFFF" quantity="${env('minDepth', -100)}" label="Above Min Depth" opacity="1"/>
          
          <sld:ColorMapEntry color="#FFFFFF" quantity="0" label="Below Zero" opacity="1"/>
          <sld:ColorMapEntry color="#f7fbff" quantity="0" opacity="0" label="0"/>  
        </sld:ColorMap>
    </sld:RasterSymbolizer>
</sld:Rule>

I was wondering if it would be possible to apply the same principle but filtering one raster on another one. For example, given a filtered raster, could the same ‘no-data value mask’ be applied to another raster with the same resolution? Do you have any further advice?

Thank you so much again !!