GDAL – gdalbuildvrt Does Not Support Heterogeneous Band Scale

gdalgdalbuildvrt

I need to merge about 300 geotiff files, and I choose to use the gdalbuildvrt. However I got one problematic file, which caused the error as following:
Warning 6: gdalbuildvrt does not support heterogeneous band scale: expected (1,0.010000), got (0,1.000000).

Does anyone know how to revise the band scale for the geotiff file? I tried the rasterio, but failed:

    with rio.open(output_image, 'w', scale=0.01) as dst:
        dst.write(img, 1)

The gdalinfo of the wrong file is

Files: ********
Size is 1200, 1200
Coordinate System is:
PROJCRS["unnamed",
    BASEGEOGCRS["Unknown datum based upon the custom spheroid",
        DATUM["Not_specified_based_on_custom_spheroid",
            ELLIPSOID["Custom spheroid",6371007.181,0,
                LENGTHUNIT["metre",1,
                    ID["EPSG",9001]]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433,
                ID["EPSG",9122]]]],
    CONVERSION["Sinusoidal",
        METHOD["Sinusoidal"],
        PARAMETER["Longitude of natural origin",0,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["False easting",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["easting",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["northing",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]
Data axis to CRS axis mapping: 1,2
Origin = (6671703.117999999783933,6671703.117999999783933)
Pixel Size = (926.625433055833810,-926.625433055833014)
Metadata:
  AREA_OR_POINT=Area
  HDFEOSVersion=HDFEOS_V2.17
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  ( 6671703.118, 6671703.118) (120d 0' 0.00"E, 60d 0' 0.00"N)
Lower Left  ( 6671703.118, 5559752.598) ( 93d20'36.35"E, 50d 0' 0.00"N)
Upper Right ( 7783653.638, 6671703.118) (140d 0' 0.00"E, 60d 0' 0.00"N)
Lower Right ( 7783653.638, 5559752.598) (108d54' 2.40"E, 50d 0' 0.00"N)
Center      ( 7227678.378, 6115727.858) (113d19'26.55"E, 55d 0' 0.00"N)
Band 1 Block=1200x1 Type=Float64, ColorInterp=Gray

The gdalinfo of the right file is

Files: ********
Size is 1200, 1200
Coordinate System is:
PROJCRS["unnamed",
    BASEGEOGCRS["Unknown datum based upon the custom spheroid",
        DATUM["Not_specified_based_on_custom_spheroid",
            ELLIPSOID["Custom spheroid",6371007.181,0,
                LENGTHUNIT["metre",1,
                    ID["EPSG",9001]]]],
        PRIMEM["Greenwich",0,
            ANGLEUNIT["degree",0.0174532925199433,
                ID["EPSG",9122]]]],
    CONVERSION["Sinusoidal",
        METHOD["Sinusoidal"],
        PARAMETER["Longitude of natural origin",0,
            ANGLEUNIT["degree",0.0174532925199433],
            ID["EPSG",8802]],
        PARAMETER["False easting",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8806]],
        PARAMETER["False northing",0,
            LENGTHUNIT["metre",1],
            ID["EPSG",8807]]],
    CS[Cartesian,2],
        AXIS["easting",east,
            ORDER[1],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]],
        AXIS["northing",north,
            ORDER[2],
            LENGTHUNIT["metre",1,
                ID["EPSG",9001]]]]
Data axis to CRS axis mapping: 1,2
Origin = (6671703.117999999783933,5559752.598333000205457)
Pixel Size = (926.625433055833810,-926.625433055000258)
Metadata:
  AREA_OR_POINT=Area
  ASSOCIATEDINSTRUMENTSHORTNAME.1=MODIS
  ASSOCIATEDPLATFORMSHORTNAME.1=Terra
  ASSOCIATEDSENSORSHORTNAME.1=MODIS
  BANDDEFINITION=END_OBJECT
  CHARACTERISTICBINSIZE=926.6
  DATACOLUMNS=1200
  DATAROWS=1200
  DATASETNAME=GLASS06A01
  DAYNIGHTFLAG=Both
  EASTHBOUNDINGCOORDINATE=109.112804
  EXCLUSIONGRINGFLAG=N
  GLOBALGRIDCOLUMNS=43200
  GLOBALGRIDROWS=21600
  GRIDTYPE=Sinusoidal
  GRINGPOINTLATITUDE.1=50.091797,49.984305,39.771465,39.849042
  GRINGPOINTLONGITUDE.1=93.392666,109.112804,91.359893,78.151152
  GRINGPOINTSEQUENCENO.1=1,2,3,4
  HDFEOSVersion=HDFEOS_V2.20
  HORIZONTALTILENUMBER=24
  INPUTFILESNAME=Multi-Source Data
  INPUTPOINTER=Multi-Source Data
  INSTITUTENAME=BEIJING
  LOCALGRANULEID=GLASS06A01.V01.A2010090.h24v04.2021212.hdf
  LOCALVERSIONID=V01
  long_name=Land surface temperature 1km SIN Grid
  NORTHBOUNDINGCOORDINATE=50.091797
  PARAMETERNAME.1=GLASS06A01
  PGEVERSION=V01
  PROCESSINGENVIRONMENT=High Performance Computing System
  PRODUCTDATEANDTIME=2021-07-31 16:25:41
  PRODUCTIONDATETIME=2021-07-31 16:25:41
  PRODUCTNAME=END_OBJECT
  PRODUCTQUALITY=CLOUDREMOVED
  REPROCESSINGACTUAL=reprocessed
  REPROCESSINGPLANNED=further update is anticipated
  scale_factor=0.01
  SHORTNAME=GLASS06A01
  SOUTHBOUNDINGCOORDINATE=39.771465
  TILENUMBER=H24V04
  units=K
  VERSIONID=1
  VERTICALTILENUMBER=04
  WEBSITE=http://glass-product.bnu.edu.cn
  WESTHBOUNDINGCOORDINATE=78.151152
  _FillValue=0
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  ( 6671703.118, 5559752.598) ( 93d20'36.35"E, 50d 0' 0.00"N)
Lower Left  ( 6671703.118, 4447802.079) ( 78d19'27.97"E, 40d 0' 0.00"N)
Upper Right ( 7783653.638, 5559752.598) (108d54' 2.40"E, 50d 0' 0.00"N)
Lower Right ( 7783653.638, 4447802.079) ( 91d22'42.64"E, 40d 0' 0.00"N)
Center      ( 7227678.378, 5003777.339) ( 91d55'25.97"E, 45d 0' 0.00"N)
Band 1 Block=1200x3 Type=UInt16, ColorInterp=Gray
  Description = Land surface temperature 1km SIN Grid
  NoData Value=0
  Unit Type: K
  Offset: 0,   Scale:0.01

Best Answer

The gdal_edit.py Python script https://gdal.org/programs/gdal_edit.html can be used for editing the metadata of GeoTIFF and other raster files. The utility has a special switches for editing the scale and offset values. You need to use just -scale.

-scale <value>

Assign a specified scale value to output bands. If a single scale value is provided it will be set for all bands. Alternatively one scale value per band can be provided, in which case the number of scale values must match the number of bands. If no scale is needed, it it recommended to set the value to 1. Scale and Offset are generally used together. For example, scale and offset might be used to store elevations in a unsigned 16bit integer file with a precision of 0.1, and starting from -100. True values would be calculated as: true_value = (pixel_value * scale) + offset

Note

These values can be applied using -unscale during a gdal_translate run.

-offset <value>

Assign a specified offset value to output bands. If a single offset value is provided it will be set for all bands. Alternatively one offset value per band can be provided, in which case the number of offset values must match the number of bands. If no offset is needed, it recommended to set the value to 0. For more see scale.

Related Question