Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@maptiler/weather

maptiler1.8k3.0.1TypeScript support: included

Weather layers for MapTiler Cloud and MapTiler SDK

maptiler, plugin, weather, forecast

readme

official page →

Interactive weather layers to customize for MapTiler Cloud and MapTiler SDK JS

Live weather data in your map!

The Weather module for MapTiler SDK contains a set of weather-specific tiled layers to put into your map, just like any layer!

Here are some features:

  • 4-day forecast 📅
  • global coverage 🌐
  • hourly precision ⏱
  • fresh data every few hours (generaly ~6h) 📦
  • animated 🏁
  • highly customizable ✨
  • plenty of built-in color ramps 🎨
  • easy to setup with nice default settings 🙌
  • pick weather values for any lon/lat (and mouse move) 📌
  • included in your FREE MapTiler Cloud plan! 😎

A dedicated layer for each of the following variables:

  • temperatures 🌡️
  • winds ༄
  • presure 🌀
  • precipitations 🌧️
  • radar 📡

Install

npm install --save @maptiler/weather

Every layer requires to use MapTiler SDK (which is built on top MapLibre Gl JS), if you don't have it already as part of your project, you can install the two together:

npm install --save @maptiler/sdk @maptiler/weather

Getting Started

Since all the layers are going to be added to a Map, let's instanciate a map first:

import { Map, config, MapStyle } from "@maptiler/sdk";

// Make sure you set your MapTiler Cloud API key:
config.apiKey = "YOUR_API_KEY";

// Let's assume you have a div container to place your map in
const map = new maptilersdk.Map({
  container: someComtainer,
  style: MapStyle.DATAVIZ.DARK,
});

Then, regardless of the type of weather layer you want to add to your map, keep in mind that it behaves just like a regular SDK/MapLibre layer, so you probably want to place it under some labels and border. What we advice is to place it underneath the water layer that we make partially transparent:

map.on('load', function () {
  // Make the water layer a bit transparent:
  map.setPaintProperty("Water", 'fill-color', "rgba(0, 0, 0, 0.5)");

  // Add the weather layer underneath the `water` layer:
  map.addLayer(layer, 'Water');
});

Layers

Each type of layer comes with a dedicated constructor to which can be provided the same minimal set of options:

  • id of type string. Default: depends on the type of layer.
  • opacity of type number. Default: 1.
  • colorramp of type ColorRamp. Default: depends on the type of layer
  • smooth of type boolean. Default: true (colors are nicely interpolated)

Temperature Layer

Create a temperature layer:

import { TemperatureLayer } from "@maptiler/weather";

// After creating a Map instance like in the `Getting Started`

const layer = new TemperatureLayer(); // using default settings

// or
const layer = new TemperatureLayer({ /* options */ }); // overwriting default

// Add the layer like in the `Getting Started`
  • Forecast for temperatures at 2m above ground
  • The default layer ID is "MapTiler Temperature"
  • The unit is degree Celcius (°C)
  • The default color ramp is ColorRamp.builtin.TEMPERATURE_2, which spans from -70.15°C to 46.85°C
  • Maximum range possible spans from -127°C to 128°C

Pressure Layer

Create a pressure layer:

import { PressureLayer } from "@maptiler/weather";

// After creating a Map instance like in the `Getting Started`

const layer = new PressureLayer(); // using default settings

// or
const layer = new PressureLayer({ /* options */ }); // overwriting default

// Add the layer like in the `Getting Started`
  • Forecast for air pressure at mean sea level
  • The default layer ID is "MapTiler Pressure"
  • The unit is hecto Pascal (hPa) or millibar (mbar)
  • The default color ramp is ColorRamp.builtin.PRESSURE_2, which spans from 900hPa to 1080hPa
  • Maximum range possible spans from 900hPa to 1080hPa

Precipitation Layer

Create a precipitation layer:

import { PrecipitationLayer } from "@maptiler/weather";

// After creating a Map instance like in the `Getting Started`

const layer = new PrecipitationLayer(); // using default settings

// or
const layer = new PrecipitationLayer({ /* options */ }); // overwriting default

// Add the layer like in the `Getting Started`
  • Forecast for precipitation of all sorts (rain, snow, hail, sleet) in amount per hour
  • The default layer ID is "MapTiler Precipitation"
  • The unit is millimeter per hour (mm/h)
  • The default color ramp is ColorRamp.builtin.PRECIPITATION, which spans from 0mm/h to 50mm/h
  • Maximum range possible spans from 0mm/h to 50mm/h

Radar Layer

Create a radar reflectivity layer:

import { RadarLayer } from "@maptiler/weather";

// After creating a Map instance like in the `Getting Started`

const layer = new RadarLayer(); // using default settings

// or
const layer = new RadarLayer({ /* options */ }); // overwriting default

// Add the layer like in the `Getting Started`
  • Forecast for maximum composite radar reflectivity value
  • The default layer ID is "MapTiler Radar"
  • The unit is radar reflectivity factor (dBZ)
  • The default color ramp is ColorRamp.builtin.RADAR, which spans from 0dBZ to 75dBZ
  • Maximum range possible spans from -20dBZ to 80dBZ

Note: the built-in color ramp ColorRamp.builtin.RADAR_CLOUD was specificaly designed by our team to represent cloud coverage, and may be more intuitive for generalistic weather forecast usecases. Give it a try!

<summary>ℹ️ Know more about radar reflectivity 📡</summary>

Radar reflectivity measure the amount and size of particles that are in the sky, but not only precipitation.

  • dust and insects: from -10dBZ to 5dBz
  • light mist / drizzle / flurries: ~10dBZ
  • mist / drizzle / flurries: ~15dBZ
  • very light rain or snow: ~20dBZ
  • light rain or snow: ~25dBZ
  • light to moderate rain or snow: ~30dBZ
  • moderate rain or snow, possible sleet: 35dBZ to 40dBZ
  • moderate to heavy rain or snow, possible sleet: ~45dBZ
  • heavy rain or snow, possible sleet: ~50dBZ
  • very heavy rain or snow, with small hail possible: ~55dBZ
  • extreme rain or snow, with moderate hail possible: ~60dBZ
  • extreme rain or snow, with large hail possible: ~65dBZ

Read more about radar reflectivity

Wind Layer

Create a wind layer:

import { WindLayer } from "@maptiler/weather";

// After creating a Map instance like in the `Getting Started`

const layer = new WindLayer(); // using default settings

// or
const layer = new WindLayer({ /* options */ }); // overwriting default

// Add the layer like in the `Getting Started`
  • Forecast for speed and direction at an altitude of 10m above ground
  • The default layer ID is "MapTiler Wind"
  • The unit is meter per second (m/s)
  • The default color ramp is ColorRamp.builtin.VIRIDIS, which spans from 0m/s to 40m/s
  • Maximum range possible spans from 0m/s to 75m/s

The wind layer contains both a background to which is applied a color ramp and a set of moving particles, for this reason, the constructor WindLayer has more options that then other weather layers. Please refer to our official documentation to have the complete list.

Layer Methods

  • .getAnimationStartDate(): Get the start date of the animated sequence, as a Date object
  • .getAnimationStart(): Get the start date of the animated sequence, as a UNIX timestamp in seconds (number)
  • .getAnimationEndDate(): Get the end date of the animated sequence, as a Date object
  • .getAnimationEnd(): Get the end date of the animated sequence, as a UNIX timestamp in seconds (number)
  • .setOpacity(opacity: number): Set the layer opacity, from 0 (fully transparent) to 1 (fully opaque)
  • .getAnimationTimeDate(): Get the current time of the animation, as a Date object
  • .getAnimationTime(): Get the current time of the animation, as a UNIX timestamp in seconds (number)
  • .setAnimationTime(time: number): Set the animation time, as a UNIX timestamp in seconds (number)
    • Emits event animationTimeSet
  • .animate(factor: number): Plays the animation at a given speed factor. Pauses if factor is 0
    • Emits event playAnimation if factor is greater than 0
    • Emits event pauseAnimation if factor is 0
  • .getAnimationSpeed(): Get the animation speed factor
  • .isPlaying(): Get if the animation is currently playing
  • .pickAt(lng: number, lat: number): Get the value(s) as an object. Depending on the type of layer, the values returned can be in different units. Please refer to the official documetation
  • async .onSourceReadyAsync(): Async function corresponding to the "sourceReady" event. Resolves directly if source is already ready, or awaits the event "sourceReady" if not.

Layer Events

To add a calback function to a layer event, do the following:

layer.on("eventName", (e) => {
  // Do something
})

Here are the possible events:

  • sourceReady
    • ⚡ Called only once after the layer has been added to the map, when all the necessary weather data source are loaded and ready to be used.
    • 🍱 The event callback parameter is as such {map: Map, layer: Layer}
  • playAnimation
    • ⚡ Called when the animation is starting to play or plays after having been on pause after calling .animate(...)
    • 🍱 The event callback parameter is as such {time: number} with time being the timestamp in seconds
  • pauseAnimation
    • ⚡ Called when the animation is being paused after calling .animate(0)
    • 🍱 The event callback parameter is as such {time: number} with time being the timestamp in seconds
  • tick
    • ⚡ Called for each animation update, possibly many times per seconds
    • 🍱 The event callback parameter is as such {time: number} with time being the timestamp in seconds
  • animationTimeSet
    • ⚡ Called when the progress time of the animation is manually set with .setAnimationTime(...)
    • 🍱 The event callback parameter is as such {time: number} with time being the timestamp in seconds

Note that most layer methods can only called after the event sourceReady has been emmited.

Color Ramp

There are many builtin color ramps that are ready to be used. since most of them are defined in the interval [0, 1], they need to be scaled acording to their intended usage. Let's see how to do this:

import { ColorRamp } from "@maptiler/weather";

// Let's use the Viridis color ramp,
// but we want to use it for air pressure, so on a range [900, 1080] hPa
const viridisPressure = ColorRamp.builtin.VIRIDIS.scale(900, 1080);

Note that the .scale() method first clones the color ramp on which it is called so that the original one is not modified.

A color ramp can also be flipped with .reverse() or generate a canvas of itself with .getCanvasStrip() to create UI elements.

To create a new color ramp manually that can be used with any of the weather layers, you must provide a color stop definition as follow:

import { ColorRamp, TemperatureLayer } from "@maptiler/weather";

const myTemperatureColoramp = new ColorRamp({ 
  stops: [
    { value: -65, color: [3, 78, 77, 255] },
    { value: -55, color: [4, 98, 96, 255] },
    { value: -40, color: [5, 122, 120, 255] },
    { value: -25, color: [6, 152, 149, 255] },
    { value: -20, color: [8, 201, 198, 255] },
    { value: -12, color: [20, 245, 241, 255] },
    { value: -8, color: [108, 237, 249, 255] },
    { value: -4, color: [133, 205, 250, 255] },
    { value: 0, color: [186, 227, 252, 255] },
    { value: 4, color: [238, 221, 145, 255] },
    { value: 8, color: [232, 183, 105, 255] },
    { value: 12, color: [232, 137, 69, 255] },
    { value: 20, color: [231, 107, 24, 255] },
    { value: 25, color: [236, 84, 19, 255] },
    { value: 30, color: [236, 44, 19, 255] },
    { value: 40, color: [123, 23, 10, 255] },
    { value: 55, color: [91, 11, 0, 255] },
  ],
})

const layer = new TemperatureLayer({
  colorramp: myTemperatureColoramp,
});

Note that all the color stop's value are in the actual unit of the layer (above: °C) and the colors are in [R, G, B, A].

Again, find more details on what's possible with color ramps on our official documentation;

Color blindness

Color blindness is the decreased ability to see colors or differences in colors.
The most common form is caused by a genetic disorder called congenital red–green color blindness.

source: Wikipedia

Because some forms of color blindness can affect up to 8% of the population, we thought it was fair that our library includes some perceptually uniform color ramps that are more color blind friendly.

The description from TypeScript auto completion will let you know about this information, otherwise, look for the ramps based on one of the following:

  • Mako
  • Turbo
  • Rocket
  • Cividis
<summary>🎨 See all the builtin color ramps</summary>

License

MapTiler Weather JS Module

Copyright © 2023 MapTiler AG. All rights reserved.

The software and files (collectively “Software”) in this repository are licensed for use only with MapTiler service(s).

For the license terms, please reference MapTiler General Terms and Conditions which incorporate MapTiler Weather JS Module Product Terms (collectively “Terms”) and Privacy Policy at Privacy policy.

This license allows users with an active MapTiler account to modify and integrate authorized portions of the Software for use with the relevant MapTiler service(s) in accordance with the MapTiler Terms. This license terminates automatically if a user no longer maintains a MapTiler account or their usage breaches MapTiler Terms.

changelog

MapTiler Client Changelog

3.0.1

  • Fix for bug that only rendered partial surface for weather in globe on higher res screens.

3.0.0

⚠️ Please keep in mind that if you use MapTiler Weather JS v3 you must update version of MapTiler SDK JS to v3.

✨ Features and improvements

  • Globe projection support

🐛 Bug fixes

  • None

🔧 Others

  • Using MapTiler SDK JS v3

2.2.1

Others

  • Updating to MapTiler SDK v2.4

2.2.0

Others

  • Updating to MapTiler SDK v2.3

2.1.0

New Features

  • Inter-tile interpolaltion (opt-in) when using a multi channel coloring fragment
  • Bilinear in terpolation with the picking function (opt-in) of all layers
  • Possible to chose which channels to leverage in a multi channel coloring fragment for both the value and the category
  • Piking now fully relies on WebGL framebuffer rendering and LRU-cached texture (much faster + more reliable)
  • Picking when a single tileset is set now only reads the texture once (vs twice, attempting time interpolation as before)
  • Code quality improvement (thanks to BiomeJS review)

    Others

  • Computing the tile extent no longer relies on OpenLayers
  • Replaced ESLint and Prettier by BiomeJS
  • Using latest MapTiler SDK version (v2.2.2)

2.0.1

Bug Fixes

  • Readme images are now stored on MapTiler CDN to be visible from NPM

2.0.0

New Features

  • Weather layers now have a .onSourceReadyAsync() method to wait for source readyness

    Others

  • Updated to MapTiler SDK v2

1.1.2

Others

  • Improved the pick method, It is now using a canvas context cache and the options willReadFrequently so picking is about 200x faster
  • The webgl based picking (bypassing alpha premultiplication) is still used when using a multi channel coloring fragment, since alpha chan is less likely to be 255.

1.1.1

Bug Fixes

  • Terser was replaced by Vite for producing the minified UMD bundle because the Terser one was buggy on Safari

1.1.0

New Features

ParticleLayer can have the options to render faster particles slightly larger (opt-in options with fastIsLarger)

Bug Fixes

  • ParticleLayer no longer shows tilling pattern
  • ParticleLayer protection to avoid rendering particle splashing artefact (opt-in with option angleDirectionShiftSkip)
  • ParticleLayer can now render particles of similar speed regardless of screen size (opt-in option with uniformSpeed)

1.0.5

Others

  • Exposing more elements to be leveraged by MapTiler Weather Plus library.

1.0.4

New Features

  • pressure color ramp now has a neutral point at 1013hPa
  • enable tile fetching on tiles being .pick()ed even when layer visibility is none

    Bug Fixes

  • No longer trying to fetch tiles with negative indices
  • mtsid is longer added twice (it was when the source contained it already)
  • ColorRamps min and max is now updated with .scale()

    Others

  • Better minification for the prod bundles

1.0.3

Bug Fixes

  • Removed many TS warning fix by using more explicit typing

    Others

  • TS exported types are now per module
  • Now bundling with Vite
  • Building from GH action

1.0.2

Bug Fixes

  • Fixed quite a bit of TypeScript issues

    Others

  • Removed the peer dependency to MapLibre

1.0.1

New Features

  • The MapTiler Session ID (mtsid) is now being propagated to the tile fetching logic internal to the library
  • Same with the API key (key) As a result, no need to specify those as part of the source URL (.addSource())

1.0.0

First release 🎉