Opened 5 years ago

Closed 5 years ago

#2127 closed enhancement (fixed)

support for values, interval and ramp color tables in encode

Reported by: Vlad Merticariu Owned by: dkamov
Priority: major Milestone: 10.0
Component: conversion Version: 9.8
Keywords: Cc: Dimitar Misev, Peter Baumann, Bang Pham Huu
Complexity: Medium

Description

Context:

The encode function supports gdal color tables as format parameter (see http://doc.rasdaman.org/04_ql-guide.html#encode, colorPalette).

The colorPalette represents an array of 256 colors, which is passed to gdal in encoding for producing an image with colors mapped by the colorPalette, i.e. pixels with value 0 get colored with the first entry in the colorPalette, pixels with value 1 get colored with the 2nd entry and so on.

This works well for datasets with values in range 0-255 (pixel type unsigned char), where the user wants to map each value to 1 color, but not so much if the dataset is of type float for example, with a range of values in 0-1.

For these cases, we should support color tables as defined by the SLD standard (some examples here: https://docs.geoserver.org/stable/en/user/styling/sld/reference/rastersymbolizer.html).

Task description:

In rasql, this means adding another format parameter in the encode function, called "colorMap". A colorMap has 2 components:

  • type: can be one of "values", "intervals" and "ramp"
  • colorTable: a map of pixelValue: colorValue, where pixelValue is any number, and colorValue is an array of 1,3 or 4 unsigned chars (1 value when the desired result is grey scale, 3 when it's RGB, 4 when it's RGBA). Requirement: all entries in the colorTable have the same number of components (all 1 entry, all 3 entries or all 4 entries, no mixes).

Example:

"colorMap": {
    "type": "values",       
    "colorTable": {
      "-1": [255, 255, 255, 0],
      "-0.5": [125, 125, 125, 255],
      "1": [0, 0, 0, 255] 
    } 
  }

Depending on the type, a colorMap changes the pixel values of the array argument of encode according to the following rules:

  • if type = "values", each pixel is replaced by the entry in the colorTable where the key is the pixel value. In the example above, it means that all pixels with value -1 are replaced by 255, 255, 255, 0. Pixels with values not present in the colorTable are not rendered: they are replaced with a color having all components set to 0, or, if the encode argument has null values, to an arbitrarely chosen null value (the first one by convention).
  • if type = "intervals", all pixels with values between 2 consecutive entries are rendered using the color of the first (lowest-value) entry. Pixels with values less than the first entry of the colorTable are not rendered. Requirement: the keys of the colorTable map (the pixel values) must be provided in ascending order.

Example:

"colorMap": {
    "type": "intervals",       
    "colorTable": {
      "-1": [255, 255, 255, 0],
      "-0.5": [125, 125, 125, 255],
      "1": [0, 0, 0, 255] 
    } 
  }

In this case, all pixels with values in the interval [-1, -0.5) get replaced with 255, 255, 255, 0. All pixels in the interval [-0.5, 1) get replaced with 125, 125, 125, 255. All pixels with value ≥ 1 get replaced with 0, 0, 0, 255.

  • if type = "ramp": same as "intervals", but instead of using the color of the lowest value entry, linear interpolation between the lowest value entry and highest value entry, based on the pixel value, is performed.

Example

"colorMap": {
    "type": "ramp",       
    "colorTable": {
      "-1": [255, 255, 255, 0],
      "-0.5": [125, 125, 125, 255],
      "1": [0, 0, 0, 255] 
    } 
  }

Pixels with value -0.75 are replaced with color 189, 189, 189, 127, because they sit in the middle of the distance between -1 and -0.5, so they get, on each channel, the color value in the middle.
The interpolation formula for a pixel of value x, where 2 consecutive entries in the colorTable a,b with a ⇐ x < b, is:
resultColor = ((b - x) / (b - a))*colorTable[b] + ((x - a) / (b - a))*colorTable[a]

For the example above, a = -1, x = -0.75, b = -0.5, colorTable[a] = 255,255,255,0, colorTable[b] = 125, 125, 125, 255, so:
resultColor = (-0.5 + 0.75) / (-0.5 + 1) * [255, 255, 255, 0] + (-0.75 + 1) / (-0.5 + 1) * [125, 125, 125, 255] = 0.5 * [255, 255, 255, 0] + 0.5 * [125, 125, 125, 255] = [127, 127, 127, 0] + [62, 62, 62, 127] = [189, 189, 189, 127]

Note the integer division, because the colors are of type unsigned char.

Change History (3)

comment:1 by Bang Pham Huu, 5 years ago

Cc: Peter Baumann Bang Pham Huu added
Component: undecidedconversion

comment:2 by Bang Pham Huu, 5 years ago

Type: defectenhancement

comment:3 by dkamov, 5 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.