Search code examples
openlayersgeotiff

Rendering hosted GeoTIFF file using OpenLayers WebGL not visualized properly


In a web map application, I am trying to render a GeoTIFF file as an overlay layer on a OSM layer using OpenLayers 6. The layer is rendered on the exact location and it seems fine. Here is the screenshot of my results:

enter image description here

But if I zoom in, in some areas I could see smooth (simplified) edges which is not what I want:

enter image description here

Here is my code:

import React, { useState, useEffect, useRef } from "react";
import "ol/ol.css";

import GeoTIFF from "ol/source/GeoTIFF";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/WebGLTile";

import OSMLayer from "./OSMLayer";
import { fromLonLat } from "ol/proj";

function App() {
  var mapObjectRef = useRef();
  var tifLayer = useRef();

  const pixelValue = [
    "case",
    ["<=", ["band", 1], 0.0],
    -1,
    ["between", ["band", 1], 0.0, 5.0],
    0,
    ["between", ["band", 1], 5.0, 6.0],
    1,
    ["between", ["band", 1], 6.0, 7.0],
    2,
    ["between", ["band", 1], 7.0, 8.0],
    3,
    ["between", ["band", 1], 8.0, 9.0],
    4,
    ["between", ["band", 1], 9.0, 10.0],
    5,
    6,
  ];

  useEffect(() => {
    const source = new GeoTIFF({
      sources: [
        {
          url: "http://../my_image.tif";
          interpolate: false,
        },
      ],
      normalize: false,
    });

    source.on("change", (e) => {
      mapObjectRef.current.addLayer(tifLayer.current);
    });

    tifLayer.current = new TileLayer({
      style: {
        color: [
          "case",
          ["==", pixelValue, -1],
          [0, 0, 0, 0],
          ["==", pixelValue, 0],
          "#FFFFFF",
          ["==", pixelValue, 1],
          [247, 37, 133, 1],
          ["==", pixelValue, 2],
          [181, 23, 158, 1],
          ["==", pixelValue, 3],
          [114, 9, 183, 1],
          ["==", pixelValue, 4],
          [86, 11, 173, 1],
          ["==", pixelValue, 5],
          [63, 55, 201, 1],
          ["==", pixelValue, 6],
          "#ff0000",
          "#0000ff",
        ],
      },
      source: source,
    });

    mapObjectRef.current = new Map({
      target: "map",
      layers: [OSMLayer()],
      view: new View({
        center: fromLonLat([lat, lng]),
        zoom: 15.5,
      }),
    });
  }, []);

  return (
    <div
      id="map"
      style={{ height: "100vh", width: "100%" }}/>
  );
}

export default App;

My issue is achieving something as follow:

enter image description here

More inforamion

The image that I am trying to render is a .tif file and has following metadata (using gdal.Info()):

Band 1 Block=161x12 Type=Float32, ColorInterp=Gray
  Min=5.000 Max=10.000 
  Minimum=5.000, Maximum=10.000, Mean=6.864, StdDev=1.788
  NoData Value=-3.39999995214436425e+38
  Metadata:
    STATISTICS_MAXIMUM=10
    STATISTICS_MEAN=6.8642607683353
    STATISTICS_MINIMUM=5
    STATISTICS_STDDEV=1.7880035940136

Solution

  • interpolate is an option for the GeoTIFF constructor, not for individual sources

    const source = new GeoTIFF({
      sources: [
        {
          url: "http://../my_image.tif";
        },
      ],
      interpolate: false,
      normalize: false,
    });