Skip to content
Updraft Docs
Türkçe

Quick start: MapLibre GL JS

This example opens the Updraft "pilot eye" vector style and filters the thermal grid by month, time of day and wind direction. The same code runs on this site: live example.

1. Install

npm install @updraft/maps [email protected]

A container for the map:

<div id="map" style="height: 70vh"></div>
<script type="module" src="./main.js"></script>

2. Map and thermal filter

Copy this file into your project (updraft-map.js). The Updraft client package @updraft/maps does most of the work: updraftMapOptions opens the style, adds the X-Api-Key header (when you have a key) to requests for the Updraft tile server only and keeps the attribution box open; setThermalFilter points the thermal source at the filtered address. The package does not import maplibre-gl itself; it works with your copy. The package's API client and types: Authentication.

maplibre/updraft-map.js
// Updraft quick start 1: MapLibre GL JS + the Updraft "pilot eye" vector style + the thermal grid.
// npm install @updraft/maps [email protected]
import { Map as MapLibreMap, NavigationControl, ScaleControl } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { updraftMapOptions } from '@updraft/maps/maplibre';

// setThermalFilter(map, { month, hourBucket, windSector }) points the style's `thermals` source at
// a breakdown; thermalsUrl(filter) gives its TileJSON address.
export { setThermalFilter } from '@updraft/maps/maplibre';
export { thermalsUrl } from '@updraft/maps';

/**
 * Creates the map. `apiKey` is optional: with a key (scope `tiles`) every request to the Updraft
 * tile server, and only to it, carries the `X-Api-Key` header and counts towards your key's usage;
 * without one the public tile path is used, which is limited per client address.
 * `updraftMapOptions` also keeps the attribution box open ("© Updraft · © OpenStreetMap
 * contributors · © OpenMapTiles · Copernicus DEM" must stay visible).
 * @param {object} options
 * @param {HTMLElement | string} options.container
 * @param {string} [options.apiKey]    key with the `tiles` scope (header, never in the URL)
 * @param {'light' | 'dark'} [options.theme]  published style; default light
 * @param {string} [options.style]     your own style URL instead
 * @param {string} [options.tilesUrl]  Updraft tile server root; default https://maps.updraftmaps.com
 * @param {[number, number]} [options.center] [longitude, latitude]
 * @param {number} [options.zoom]
 * @returns {MapLibreMap}
 */
export function createUpdraftMap(options) {
  const map = new MapLibreMap(updraftMapOptions(options));
  map.addControl(new NavigationControl(), 'top-right');
  map.addControl(new ScaleControl({ unit: 'metric' }), 'bottom-left');
  return map;
}

// Usage:
//   const map = createUpdraftMap({ container: 'map', apiKey: 'upd_…' });
//   map.on('load', () => setThermalFilter(map, { month: 7, hourBucket: 6, windSector: 6 }));

Usage (main.js):

import { setWorkerUrl } from 'maplibre-gl';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?url';
import { createUpdraftMap, setThermalFilter } from './updraft-map.js';

// MapLibre 6 loads its worker from a separate file; with a bundler give its address (Vite):
setWorkerUrl(workerUrl);

const map = createUpdraftMap({ container: 'map', apiKey: 'upd_…' }); // the key is optional
map.on('load', () => {
  // July, 12:00–14:00 local time, wind from the west
  setThermalFilter(map, { month: 7, hourBucket: 6, windSector: 6 });
});

3. Thermal parameters

The thermal grid is Martin's thermals function source; the filter is the query string of the TileJSON address (https://maps.updraftmaps.com/thermals?month=7&hour_bucket=6).

Parameter Values "All" Meaning
month 1–12 0 (default) Local month
hour_bucket 0–11 12 (default) Local two-hour slot: 0 = 00–02, 6 = 12–14
wind_sector 0–7 8 (default) 45° sector the 850 hPa wind blows from: 0 north, 2 east, 4 south, 6 west

An invalid value returns an empty tile. The grid is drawn at z8–14 (z8–10 ~5 km², z11–14 ~0.1 km² hexagons); every cell has avg_climb_ms (mean climb, 0.1 m/s), confidence_tier (low, medium, high) and min_pilots (at least N pilots). Cells without enough distinct pilots never arrive (Privacy). Details: Tiles and styles.

4. Key and origin

  • transformRequest adds the key only to requests for the Updraft tile server; it is never written into the URL (?key=), so it stays out of server and CDN logs.
  • A key that goes to the browser can be read by anyone: use a key with the tiles scope only. If it leaks, only tiles can be read and the key is revoked (Authentication).
  • The tile server accepts browser requests from registered origins only (CORS). Tell us your site's origin (https://example.com) when you ask for the key; for local trials also an address such as http://localhost:5173.
  • Requests without a key work too, but they are limited per client address and are not counted for you.

5. Attribution

The style carries its attribution line: "© Updraft · © OpenStreetMap contributors · © OpenMapTiles · Copernicus DEM". The example keeps MapLibre's attribution box expanded; do not hide the line or put it only in a menu. If you use the thermal layer, also put the DWD wind data notice on your licences page (Attribution rules).