Edit

PMTiles Image Tiles

pmtiles2 raster6 imagetiles1

Displaying image tiles from a PMTiles archive.

This example shows image tiles from a PMTiles source. A PMTiles archive can contain tiled data in a variety of formats. In this example, the PMTiles archive contains image-encoded tiles. The PMTiles JavaScript API is used to issue range requests for tile data given tile z, x, y coordinates. The ImageTile source is configured with a loader that returns a promise for a loaded image. The loader in this example converts the PMTiles response data into a data URL and then uses the browser's built-in image decoder to turn the data URL into an image.

main.js
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import Layer from 'ol/layer/WebGLTile.js';
import {useGeographic} from 'ol/proj.js';
import Source from 'ol/source/ImageTile.js';
import {PMTiles} from 'pmtiles';

useGeographic();

const tiles = new PMTiles(
  'https://pmtiles.io/stamen_toner(raster)CC-BY+ODbL_z3.pmtiles',
);

/**
 * @param {string} src The image source URL.
 * @return {Promise<HTMLImageElement>} Resolves with the loaded image.
 */
function loadImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener('load', () => resolve(img));
    img.addEventListener('error', () => reject(new Error('load failed')));
    img.src = src;
  });
}

const source = new Source({
  async loader(z, x, y, {signal}) {
    const response = await tiles.getZxy(z, x, y, signal);
    const blob = new Blob([response.data]);
    const src = URL.createObjectURL(blob);
    const image = await loadImage(src);
    URL.revokeObjectURL(src);
    return image;
  },
  attributions:
    'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/4.0">CC BY 4.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.',
});

const map = new Map({
  layers: [new Layer({source})],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2,
    maxZoom: 4,
  }),
});
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>PMTiles Image Tiles</title>
    <link rel="stylesheet" href="node_modules/ol/ol.css">
    <style>
      .map {
        width: 100%;
        height: 400px;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>

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