Edit

Interpolation

disableimageinterpolation1 xyz7 maptiler27 reprojection8

Not Interpolated

Interpolated

Example of data interpolation

Example of data resampling when using raster DEM (digital elevation model) data. The interpolate: false setting is used to disable interpolation of data values during reprojection and rendering. Elevation data is calculated from the pixel value returned by getData. For comparison a second map reprojected with interpolation enabled returns inaccurate elevations which are very noticeable close to 3107 meters due to how elevation is calculated from the pixel value.

main.js
import Map from 'ol/Map.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
import XYZ from 'ol/source/XYZ.js';

const key = 'Get your own API key at https://www.maptiler.com/cloud/';
const attributions =
  '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
  '<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>';

const notInterpolated = new TileLayer({
  source: new XYZ({
    attributions: attributions,
    url:
      'https://api.maptiler.com/tiles/terrain-rgb-v2/{z}/{x}/{y}.webp?key=' +
      key,
    tileSize: 512,
    maxZoom: 12,
    crossOrigin: '',
    interpolate: false,
  }),
});

const interpolated = new TileLayer({
  source: new XYZ({
    attributions: attributions,
    url:
      'https://api.maptiler.com/tiles/terrain-rgb-v2/{z}/{x}/{y}.webp?key=' +
      key,
    tileSize: 512,
    maxZoom: 12,
    crossOrigin: '',
  }),
});

const view = new View({
  center: [6.893, 45.8295],
  zoom: 16,
  projection: 'EPSG:4326',
});

const map1 = new Map({
  target: 'map1',
  layers: [notInterpolated],
  view: view,
});

const map2 = new Map({
  target: 'map2',
  layers: [interpolated],
  view: view,
});

function getHeight(rgba) {
  return -10000 + (rgba[0] * 256 * 256 + rgba[1] * 256 + rgba[2]) * 0.1;
}

const info1 = document.getElementById('info1');
const info2 = document.getElementById('info2');
const showElevations = function (evt) {
  if (evt.dragging) {
    return;
  }
  const notInterpolatedPixel = notInterpolated.getData(evt.pixel);
  info1.innerText = notInterpolatedPixel
    ? getHeight(notInterpolatedPixel).toFixed(1)
    : '-';

  const interpolatedPixel = interpolated.getData(evt.pixel);
  info2.innerText = interpolatedPixel
    ? getHeight(interpolatedPixel).toFixed(1)
    : '-';
};

map1.on('pointermove', showElevations);
map2.on('pointermove', showElevations);
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Interpolation</title>
    <link rel="stylesheet" href="node_modules/ol/ol.css">
    <style>
      .map {
        width: 100%;
        height: 400px;
      }
      @media (min-width: 800px) {
        .wrapper {
          display: flex;
        }
        .half {
          padding: 0 10px;
          width: 50%;
          float: left;
        }
      }
      #opacity {
        display: inline-block;
        width: 150px;
        vertical-align: text-bottom;
      }
    </style>
  </head>
  <body>
    <div class="wrapper">
      <div class="half">
        <h4>Not Interpolated</h4>
        <div id="map1" class="map"></div>
        <div>
          <label>
            Elevation
            <span id="info1">-</span> meters
          </label>
        </div>
      </div>
      <div class="half">
        <h4>Interpolated</h4>
        <div id="map2" class="map"></div>
        <div>
          <label>
            Elevation
            <span id="info2">-</span> meters
          </label>
        </div>
      </div>
    </div>

    <script type="module" src="main.js"></script>
  </body>
</html>
package.json
{
  "name": "interpolation",
  "dependencies": {
    "ol": "9.2.4"
  },
  "devDependencies": {
    "vite": "^3.2.3"
  },
  "scripts": {
    "start": "vite",
    "build": "vite build"
  }
}