GeoTIFF / georaster

Wrapper around Georeferenced Rasters like GeoTIFF and soon JPG and PNG that provides a standard interface
Apache License 2.0
81 stars 32 forks source link

COG area displayed, but COG itself appears to not be shown #89

Open TheTiGuR opened 4 months ago

TheTiGuR commented 4 months ago

I am trying to display a COG as an overlay on my map, and the layer itself exists, but the image is not actually displayed. Zooming in and out shows calls being made to grab the data at particular points, but nothing ever displays.

To Reproduce I presume I am missing something simple, but my basic code that I have tried variations of messing around with:

      parseGeoraster(cogPath).then(async (georaster) => {
        const tiff = georaster._geotiff;
        const img = await tiff.getImage();
        console.log(img.getGDALMetadata());
        console.log(
          georaster,
          georaster.mins,
          georaster.maxs,
          georaster.ranges,
        ); // This shows the georaster and 3 undefined values
        const layer = new GeoRasterLayer({
          georaster: georaster,
          opacity: 1,
          pixelValuesToColorFn: (values) => {
            if (values[0] === 42) {
              console.log(values);
            } // This never logs a value, but without it the area where the COG would be shows nothing
            return values[0] === 42 ? '#ffffff' : '#00F';
          },
          resolution: 32,
        });
        layer.addTo(this.map);
        this.map.fitBounds(layer.getBounds());
      });

image

Current environment: MacOS 14.4.1, Chrome Latest, Apple MBP M3

The actual COG loads fine in QGIS fine, for what its worth. I can't provide a sample of the whole code, but the maps otherwise work fine, just this integration of the COGs into it is having a problem. Thanks for any suggestions.

Edit: Noting that the rectangle drawn (red line) comes from other layers drawn

DanielJDufour commented 4 months ago

Hi, happy to help debug. Could you try the prerelease version and let me know if that works?

npm install georaster-layer-for-leaflet@next

TheTiGuR commented 4 months ago

The output: image

I have gotten it to work better (on the release version), but I'm not sure where to get to get proper coloring of the COG. The displayed image: image The same area in the image as shown in QGIS:

image

The layer looks like this to generate the dark color (After posting this I realized the red value was wrong, so the image is actually black/darkish, not reddish, but still not true color :

        const layer = new GeoRasterLayer({
          georaster,
          pixelValuesToColorFn: (values: number[]) =>
            values[0] === 0
              ? `rgba(0,0,0,0)`
              : `rgba(${values[0] / 155},${values[1] / 255},${values[2] / 255},${values[3] / 255})`,
        });

I presume I'm just doing some incorrect calculations for the values, based on other posts here, but I haven't found anything to work well. (It's also possible this will need to vary based on type (EO or SAR), and if you know how to detect that difference, that would be amazing)

TheTiGuR commented 4 months ago

Continued messing around has gotten me closer (but not in a sustainable way):

     // Pulled these min/max values from QGIS since they aren't available in the georaster data (getGDAL function fails)
     const params = {
        r: { min: 4753, max: 6996 },
        g: { min: 4065, max: 7028 },
        b: { min: 3453, max: 6817 },
        gamma: [1.7, 1.7, 1.4]
      }
      const height = georaster.height;
      const imageryLayer = new GeoRasterLayer({
        georaster,
        debugLevel: 0,
        resolution: 64,
        // pixelValuesToColorFn: (values: number[]) => values[0] === 0 ? `rgba(0,0,0,0)` : `rgba(${values[0]/height},${values[1]/height},${values[2]/height},${values[4]/height})`, 
        pixelValuesToColorFn: (values: number[]) => {
          if (values.some(value => value === 9999 || value === 0)) {
            // If any band has a value of 9999 or 0, return transparent color
            return 'rgba(0, 0, 0, 0)'; // Transparent color
          } else {
            // Apply min-max normalization to each band
            const r = (values[0] - params.r.min) / (params.r.max - params.r.min);
            const g = (values[1] - params.g.min) / (params.g.max - params.g.min);
            const b = (values[2] - params.b.min) / (params.b.max - params.b.min);

            // Apply gamma correction to each band
            const gammaR = Math.pow(r, 1 / params.gamma[0]);
            const gammaG = Math.pow(g, 1 / params.gamma[1]);
            const gammaB = Math.pow(b, 1 / params.gamma[2]);

            // Return RGB color
            return `rgba(${gammaR * 255},${gammaG * 255},${gammaB * 255},1)`;
          }
        },
      });

Here is the output, for reference: image

DanielJDufour commented 3 months ago

Oh very interesting. Thanks for sharing all of this!

Could you also share the output when you run gdalinfo /vsicurl/http://localhost:4200/api/diss...FULL_PATH_HERE...cog.tif

If possible, it'd also be great to see the output of

  import { fromUrl } from "geotiff";

  const tif = await fromUrl(url);
  const img = await tif.getImage();
  console.log(img.fileDirectory);

Thank you!

I should also mention that I can help debug if you want to email me the tif at daniel.j.dufour@gmail.com (doesn't have to be shared publicly).

TheTiGuR commented 3 months ago

I emailed you with the information requested. Thanks for your assistance!