Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure custom color maps in xcube server #1046

Closed
forman opened this issue Jul 17, 2024 · 9 comments · Fixed by #1055, #1057 or #1059
Closed

Configure custom color maps in xcube server #1046

forman opened this issue Jul 17, 2024 · 9 comments · Fixed by #1055, #1057 or #1059
Labels
enhancement New feature or request

Comments

@forman
Copy link
Member

forman commented Jul 17, 2024

Is your feature request related to a problem? Please describe.

Since xcube 1.6, xcube server accepts custom color maps from xcube viewer. We want to allow configuring the same type of custom color maps in xcube server, namely

  • Continuous
  • Stepwise
  • Categorical

Describe the solution you'd like

CustomColorMaps:
  - Identifier: my_categorical_cmap
    Type: categorical     # or continuous, stepwise 
    Colors:
    - Value: 0
      Color: red
      Label: low
    - Value: 1
      Color: #0000FF
      Label: medium
    - Value: 2
      Color: 0,0,255
      Label: high
  - ...

EDIT:

An entry in the in the Colors list may have one of the following forms (TypeScript notation):

type ColorEntry = ColorEntryObj | ColorEntryTuple;

interface ColorEntryObj {
  Value: number;
  Color: Color;
  Label?: string;
}

type ColorEntryTuple = [number, Color] | [number, Color: label];

type Color = ColorName | ColorHex | ColorTuple;
type ColorName = <A CSS color name>; 
type ColorHex = <A CSS color in hexdecimal form>;
type ColorTuple = [number, number, number] | [number, number, number, number]
@forman
Copy link
Member Author

forman commented Jul 29, 2024

Here is another practical example for Sentinel 2 level 2, scene classification band SCL:

CustomColorMaps:
  - Identifier: S2_L2_SCL
    Type: categorical 
    Colors:
    - [ 0, red,     no data]
    - [ 1, yellow,  defective]
    - [ 2, black,   dark area pixels]
    - [ 3, gray,    cloud shadows]
    - [ 4, green,   vegetation]
    - [ 5, tan,     bare soils]
    - [ 6, blue,    water]
    - [ 7, "#aaaabb", clouds low prob ]
    - [ 8, "#bbbbcc", clouds medium prob]
    - [ 9, "#ccccdd", clouds high prob]
    - [10, "#ddddee", cirrus]
    - [11, "#ffffff", snow or ice]

@forman
Copy link
Member Author

forman commented Aug 7, 2024

@konstntokas, I just tested PR #1055 with a real-life server configuration and I see several problems, therefore I reopened the issue:

  • The most important use case of the CustomColorMaps is creating categorical color maps. But the endpoint /colorbars drops the labels from the color entries.
  • CustomColorMaps are only returned by the server if they are actually used in the current configuration. That was not the intention. The server must publish all custom color maps for use by the viewer and other clients.
  • Why do you use CustomColorBar instead of the existing ColorBar key in a ColorMappings value? ColorBar should be fine, because CustomColorMaps should be treated like "normal" color maps.

I'm sorry that I didn't discover the problems during the PR review which concentrated on plain code review rather than on practical experience.

@forman
Copy link
Member Author

forman commented Aug 7, 2024

Proof for my point 2: /colorbars returns

[ 
  "Custom", 
  "Custom colormaps, e.g. loaded from SNAP *.cpd files or defined via the xcube server config file.",
  [ 
    [
      "s2_l2_scl", 
      "iVBORw0KGgoAAAA...kSuQmCC", 
      { 
        "name": "s2_l2_scl", 
        "type": "categorical", 
        "colors": [ 
          [ 0, "red" ], [ 1, "yellow" ], [ 2, "black" ], [ 3, "gray" ], [ 4, "green" ], [ 5, "tan" ], [ 6, "blue" ], 
          [ 7, "#aaaabb" ], [ 8, "#bbbbcc" ], [ 9, "#ccccdd" ], [ 10, "#ddddee" ], [ 11, "#ffffff" ] ] 
      } 
    ] 
  ] 
]

for

CustomColorMaps:
  - Identifier: s2_l2_scl
    Type: categorical
    Colors:
    - [ 0, red,     no data]
    - [ 1, yellow,  defective]
    - [ 2, black,   dark area pixels]
    - [ 3, gray,    cloud shadows]
    - [ 4, green,   vegetation]
    - [ 5, tan,     bare soils]
    - [ 6, blue,    water]
    - [ 7, "#aaaabb", clouds low prob ]
    - [ 8, "#bbbbcc", clouds medium prob]
    - [ 9, "#ccccdd", clouds high prob]
    - [10, "#ddddee", cirrus]
    - [11, "#ffffff", snow or ice]

@konstntokas
Copy link
Contributor

@konstntokas, I just tested PR #1055 with a real-life server configuration and I see several problems, therefore I reopened the issue:

* The most important use case of the `CustomColorMaps` is creating categorical color maps. But the endpoint `/colorbars` drops the labels from the color entries.

* `CustomColorMaps` are only returned by the server if they are actually used in the current configuration. That was not the intention. The server must publish all custom color maps for use by the viewer and other clients.

* Why do you use `CustomColorBar` instead of the existing `ColorBar` key in a `ColorMappings` value? `ColorBar` should be fine, because `CustomColorMaps` should be treated like "normal" color maps.

I'm sorry that I didn't discover the problems during the PR review which concentrated on plain code review rather than on practical experience.

No problem; I was thinking about the levels at one point, but then forgot about them as well. The rest mainly comes from the fact that I took the ColorFile case as a analogy. See my comments below regarding the individual points:

  • I will add the labels to the publication at the /colorbar endpoint.
  • Adding all defined custom color maps make sense so the will be available in the color map selector field. But then I would also suggest to apply the same methodology to ColorFile to be consistent.
  • I use CustomColorBar to get a distinctive case in the if/elif/esle statement deciding between ColorFile, CustomColorBar and 'general' colormaps. I think it does not make sense to allow the user using ColorBar and ValueRange for custom color maps.

I suggest to move ColorFile to CustomColorMaps, so that all custom color maps are in one place and cvan be accessed via an identifier. We evaluate all custom color maps and add them to the 'general' color maps, which will be all available at the endpoint /colorbars. In the Styles section, we only use ColorBar for any case where ValueRange is not allowed for custom color bars.

@forman
Copy link
Member Author

forman commented Aug 8, 2024

I will add the labels to the publication at the /colorbar endpoint.

Ok.

Adding all defined custom color maps make sense so the will be available in the color map selector field. But then I would also suggest to apply the same methodology to ColorFile to be consistent.

Ok, but not now. Please apply the changes for CustomColorMaps first.

I use CustomColorBar to get a distinctive case in the if/elif/esle statement deciding between ColorFile, CustomColorBar and 'general' colormaps. I think it does not make sense to allow the user using ColorBar and ValueRange for custom color maps.

Don't do that. Color maps must be identified through their identifier, independently of their type or origin.

@forman
Copy link
Member Author

forman commented Aug 8, 2024

I suggest to move ColorFile to CustomColorMaps.

Not now.

@forman
Copy link
Member Author

forman commented Aug 8, 2024

@konstntokas please create a new issue afterwards for a more consistent handling of color maps from SNAP CPD files.

@konstntokas
Copy link
Contributor

@konstntokas please create a new issue afterwards for a more consistent handling of color maps from SNAP CPD files.

see #1058

@konstntokas
Copy link
Contributor

Colors defined as RGB are making problems in the viewer due to the viewer only accepts uint8 value range (0-255) and not 0-1 ranges. See xcube-dev/xcube-viewer#392 (comment)

To fix this, all RGBs are converted to HEX. Note that matplotlib.colors.rgb2hex only allows value ranges from 0-1. Thus, if RGB is given in a range of 0-255, the range will be converted to 0-1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
2 participants