georaster-layer-for-leaflet icon indicating copy to clipboard operation
georaster-layer-for-leaflet copied to clipboard

I don't understand how pixelValuesToColorFn works

Open khannurien opened this issue 5 years ago • 21 comments

Hi, thanks a lot for your work!

I'm new to JS and not sure how to properly use the GeoRasterLayer's pixelValuesToColorFn option.

I want to display transparent zones where the values equal -99.0 in my GeoTIFF file, else the original color.

I wrote that:

pixelValuesToColorFn: values => values[0] === -99.0 ? null : '#000000",

But obviously everything is black where the value !== 99.0.

Could someone give me some hints?

khannurien avatar Jul 30 '19 14:07 khannurien

Just wanted to let you know I saw this. I'll get back to you within 24 hrs with an answer. Thanks! :-)

DanielJDufour avatar Jul 30 '19 16:07 DanielJDufour

@khannurien , how many bands does your raster have?

If it's a simple 3-Band RGB raster you could do:

pixelValuesToColorFn: values => values[0] === -99.0 ? null : `rgb(${values[0]},${values[1]},${values[2]})`

If it's a four-band RGBA raster, you could do:

pixelValuesToColorFn: values => values[0] === -99.0 ? null : `rgba(${values[0]},${values[1]},${values[2]},${values[3]/255})`

If it's not 3 or 4-bands, things get more complicated, but I'm happy to help.

Please let me know if it works or if you have any other questions. I'd like to improve the documentation to make it more clear. Thanks!!

DanielJDufour avatar Jul 31 '19 02:07 DanielJDufour

First I want to be very clear that I'm not familiar neither with JS nor with TIFF/GeoTIFF. Please forgive my newbism :-)

I tried both your solutions and got the same result each time:

image

The original render is as follows:

image

Here is the GeoTIFF file: https://file.io/J4ARZ8

Thanks for your follow-up!

khannurien avatar Jul 31 '19 07:07 khannurien

@khannurien , could you try sharing the file again? I get this error when I go to your link: image You can also email it to me: [email protected]

Thanks

DanielJDufour avatar Aug 01 '19 03:08 DanielJDufour

Done, I emailed it to you!

khannurien avatar Aug 01 '19 11:08 khannurien

Here's some interesting metadata for the image that you sent me. image

DanielJDufour avatar Aug 01 '19 12:08 DanielJDufour

The NoData Value for the raster is -32767. Is this SRTM / elevation data? I this case, you actually want to change your pixelValuesToColorFn to use -32767 and not -99.

Additionally, and this is the most important part, your raster is only 1 band. It holds elevation values not color. Although GeoTIFF files are technically "image" files, they sometimes hold values and not colors. Your job will be in deciding how you want to translate an elevation value (height of 10m) into a color.

georaster-layer-for-leaflet scales things by default linearly between black and white, but it's not pretty.

DanielJDufour avatar Aug 01 '19 12:08 DanielJDufour

Here's a picture of the raster when I boosted resolution of drawn image to 512x512 canvas: image

DanielJDufour avatar Aug 01 '19 12:08 DanielJDufour

Thank you very much for your insight. I'm starting to understand how TIFF works.

Here is the result with the following function:

pixelValuesToColorFn: values => values[0] === -32767.0 ? null : `rgb(${values[0]})`,

Capture d’écran 2019-08-01 à 14 55 52

I don't understand why the gradient is not displayed.

khannurien avatar Aug 01 '19 12:08 khannurien

rgb( is supposed to take 3 values. You have only provided one. This is the same RGB mentioned here: https://www.w3schools.com/cssref/func_rgb.asp

You will also want to scale your values for RGB. Elevation ranges from 2 to 634 in this image, but RGB only goes from 0 to 255.

Keep me updated:-)

DanielJDufour avatar Aug 01 '19 15:08 DanielJDufour

In case anyone is wandering here :-) I manually scale colors:

pixelValuesToColorFn: values => values[0] === -99 ? null :
                            (values[0] > 0 && values[0] <= 1) ? '#eb3434' :
                            (values[0] > 1 && values[0] <= 2) ? '#eb9e34' :
                            (values[0] > 2 && values[0] <= 3) ? '#dbeb34' :
                            (values[0] > 3 && values[0] <= 4) ? '#61eb34' :
                            (values[0] > 4 && values[0] <= 5) ? '#34eba1' :
                            (values[0] > 5 && values[0] <= 6) ? '#34baeb' :
                            (values[0] > 6 && values[0] <= 7) ? '#3455eb' :
                            (values[0] > 7 && values[0] <= 8) ? '#a134eb' :
                            '#eb34cf'

That works, but I'd rather do some statistics on data repartition.

@DanielJDufour, can I access min/max values of the raster from inside the function?

khannurien avatar Aug 30 '19 15:08 khannurien

Sorry, I haven't gotten back to you on this. I'm slammed with work at the moment.

DanielJDufour avatar Sep 25 '19 03:09 DanielJDufour

Hi, first of all, thanks for your module. I'm trying in displaying a geotiff on map, but I'm not able at all to create a coloraturas palette for it. My Geotiff contains values instead of rib band. Could you please address me to a solution? I'm new in the dev field :). Attached you will find my file.

Thanks in advance, Davide temperature.tiff.zip

draro avatar Mar 03 '20 09:03 draro

Hi, @draro . Could you describe a little more how your file is created? It seems that its CRS might be formatted incorrectly. Here is the output from gdalinfo:

Driver: GTiff/GeoTIFF
Files: temp.tif
Size is 393, 348
Coordinate System is:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
Origin = (2762460.472548419609666,3366910.845273250713944)
Pixel Size = (7200.000000000000000,-7200.000000000000000)
Metadata:
  AREA_OR_POINT=Area
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  ( 2762460.473, 3366910.845) (Invalid angle,Invalid angle)
Lower Left  ( 2762460.473,  861310.845) (Invalid angle,Invalid angle)
Upper Right ( 5592060.473, 3366910.845) (Invalid angle,Invalid angle)
Lower Right ( 5592060.473,  861310.845) (Invalid angle,Invalid angle)
Center      ( 4177260.473, 2114110.845) (Invalid angle,Invalid angle)
Band 1 Block=393x2 Type=Float64, ColorInterp=Gray
  Description = 2[m] HTGL (Specified height level above ground)
  Metadata:
    GRIB_COMMENT=Temperature [C]
    GRIB_ELEMENT=TMP
    GRIB_FORECAST_SECONDS=0 sec
    GRIB_REF_TIME=1581897600 sec UTC
    GRIB_SHORT_NAME=2-HTGL
    GRIB_UNIT=[C]
    GRIB_VALID_TIME=1581897600 sec UTC

It seems to be in EPSG 4326, but the pixelSize is not in degrees, which is common.

DanielJDufour avatar Jul 18 '20 04:07 DanielJDufour

Hi @DanielJDufour sorry for the delay in my answer. you are right, GDAL was not able to understand the original Projection (Mercator 1SP) and created GTiff with wrong information. After a long headache on this i was able to manage it and the plugin worked perfectly. Thanks anyway for your time and dedication.

Here the results: image

draro avatar Aug 28 '20 21:08 draro

Awesome @draro . Looks great!

DanielJDufour avatar Aug 28 '20 21:08 DanielJDufour

I have a greyscale single band tiff, and following the example of @khannurien above I get the following. Can anyone advise on a method or mapping for greyscale?

image

robmarkcole avatar Jul 07 '21 11:07 robmarkcole

Hi @DanielJDufour Excellent library developed for GeoTIFF manipulations! I am new to Geospatial data and I am trying to plot a GeoTIFF on a base map. I wish to change the applied colors based on a user-specific range.

var layer = new GeoRasterLayer({
              georaster: georaster,
              opacity: 1,
              resolution: 256,
                pixelValuesToColorFn: function (pixelValues) {
                  var pixelValue = pixelValues[0]; 
                  var color='';
                  if (pixelValue ==0) return null;
                  if(pixelValue>=min && pixelValue<=max){
                    color = colorOb[pixelValue];
                  }else{
                    color = '#ffffff';                
                  }
                  return color;
                }
            });

where colorOb is an Object containing color mapping<float,hex>

I am trying to understand what exactly does pixelValue contains as it does not have float values that are a part of the dataset and it makes the color mapping process difficult for intermediate values.

shivalikasaxena avatar Aug 23 '21 14:08 shivalikasaxena

Hello hope someone can help, thanks in advance.

I am having issues with 3 band RGB tif, I have been only using single band, now I am trying to show 3 band but colors does not show ok all are paster like and very weird colors, the image is a satellite image converted to geotiff. Tested in my map and in http://app.geotiff.io/. tif made with GDAL_translate,and warp from jpg

The tif is posted here https://nube1.on.gt/goes/georef.tif and if I open in QGIS is shows ok (https://i.imgur.com/eZHI2GK.jpg), this is the GDALINFO of TIFF Driver: GTiff/GeoTIFF Files: /vsicurl/https://nube1.on.gt/goes/georef.tif Size is 1864, 868 Coordinate System is: GEOGCRS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84",6378137,298.257223563, LENGTHUNIT["metre",1]]], PRIMEM["Greenwich",0, ANGLEUNIT["degree",0.0174532925199433]], CS[ellipsoidal,2], AXIS["geodetic latitude (Lat)",north, ORDER[1], ANGLEUNIT["degree",0.0174532925199433]], AXIS["geodetic longitude (Lon)",east, ORDER[2], ANGLEUNIT["degree",0.0174532925199433]], ID["EPSG",4326]] Data axis to CRS axis mapping: 2,1 Origin = (-102.368633791430881,41.575757575757578) Pixel Size = (0.050000000000000,-0.050000000000000) Metadata: AREA_OR_POINT=Area Software=Matplotlib version3.3.4, https://matplotlib.org/ Image Structure Metadata: COMPRESSION=YCbCr JPEG INTERLEAVE=PIXEL JPEGTABLESMODE=1 JPEG_QUALITY=50 SOURCE_COLOR_SPACE=YCbCr Corner Coordinates: Upper Left (-102.3686338, 41.5757576) (102d22' 7.08"W, 41d34'32.73"N) Lower Left (-102.3686338, -1.8242424) (102d22' 7.08"W, 1d49'27.27"S) Upper Right ( -9.1686338, 41.5757576) ( 9d10' 7.08"W, 41d34'32.73"N) Lower Right ( -9.1686338, -1.8242424) ( 9d10' 7.08"W, 1d49'27.27"S) Center ( -55.7686338, 19.8757576) ( 55d46' 7.08"W, 19d52'32.73"N) Band 1 Block=1864x16 Type=Byte, ColorInterp=Red Band 2 Block=1864x16 Type=Byte, ColorInterp=Green Band 3 Block=1864x16 Type=Byte, ColorInterp=Blue

navilaufm avatar Sep 06 '21 15:09 navilaufm

Hello, this issue give me lots of inspiration! I hope the plugin offers some flexible color gradient, such as 'rainbow', 'viridis', 'turbo', etc.

gaowqspace avatar Jan 04 '24 14:01 gaowqspace

If you simply omit that function the colors will be chosen automatically according to a gray gradient

working example here: https://jsfiddle.net/joao_pimentel/bv4z7khq/

Screenshot from 2024-04-09 13-54-26

jfoclpf avatar Apr 09 '24 12:04 jfoclpf