@metoceanapi/wxtiles-leaflet
v2.3.0-0
Published
WxTile JS lib to render wxtiles datalayers
Downloads
70
Readme
wxtiles
This is a project for weather data visualization. There are three main parts of the project:
- Splitter - a service that splits the datasets into tiles (PNG) and some metadata (JSON) served by a fileserver backend aka NGINX.
- WxTiles-mbox source code, npm @metoceanapi/wxtiles-mbox - a JS API providing work with metadata, dataset manager and an implementation of a Custom MapBox-gl-gs Layer for visualizing the tiles using Mapbox-gl-gs.
- WxTiles-leaflet source code, npm @metoceanapi/wxtiles-leaflet - a JS API providing work with metadata, dataset manager and an implementation of a Custom Leaflet Layer for visualizing the tiles using Leaflet.
API
APIs for Leaflet and Mapbox-gl-gs are similar in many ways. The difference is in framework-specific implementations of the Custom Source/Layer.
Usage and API documentation is mainly equal for both frameworks.
DOCS
- Mapbox-gl: https://metoceanapi.github.io/wxtiles-mbox/docs/
- Leaflet: https://metoceanapi.github.io/wxtiles-leaflet/docs/
Examples
Leaflet
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';start();
/*
start();
/*
import { WxAPI } from '@metoceanapi/wxtiles-leaflet';
async func(){
// Get the API ready - should be ONE per application
// requestInit is used in every request to the server. Add your keys, credentials, mode, etc.
const wxapi = new WxAPI({ dataServerURL: 'https://tiles.metoceanapi.com/data/',
requestInit: { /* headers: new Headers([['x-api-key', 'key']]), */ } });
// Create a dataset manager (may be used for many variables-layers from this dataset)
const wxdatasetManager = await wxapi.createDatasetManager('gfs.global');
// Automatically gets a proper set of variable(s) from the dataset and composes northward or eastward components if needed
const variables = wxdatasetManager.checkCombineVariableIfVector('air.temperature.at-2m'); // 'wind.speed.eastward.at-10m' - Vector example
// create a layer
const leafletOptions: L.GridLayerOptions = { opacity: 1, attribution: 'WxTiles' };
const wxsource = new WxTileSource({ wxdatasetManager, variables }, leafletOptions);
// add the layer to the map
const map = L.map('map', { center: [0, 0], zoom: 2, zoomControl: true });
map.addLayer(wxsource);
await new Promise((done) => wxsource.once('load', done)); // highly recommended to await for the first load
}()
Change the time step
await wxsource.setTimeStep(1); // 1 - index of the time step in the dataset
or
await wxsource.setTimeStep('2020-01-01T00:00:00Z'); // '2020-01-01T00:00:00Z' - time step in the dataset
or
await wxsource.setTimeStep(2345323454); // time in seconds since 1970-01-01T00:00:00Z
or
await wxsource.setTimeStep(new Date('2020-01-01T00:00:00Z')); // Date object
Update the style
await wxsource.updateCurrentStyleObject({ units: 'm/s', levels: undefined }); // set levels to undefined - to automatically calculate the levels from the dataset
Preload the time steps
// load the time step 10 to the cache but do not not render it
const prom = wxsource.preloadTime(10);
// do stuff asyncronously
// ...
await prom; // wait for the time step to finish loading
// now set the time step to 10
await wxsource.setTime(10); // will be fast rendered from the cache
Abort loading
const abortController = new AbortController();
console.log('setTime(5)');
const prom = wxsource.setTime(5, abortController);
abortController.abort(); // aborts the request
await prom; // await always !! even if aborted
console.log('aborted');
Get the current time step
const timeStep = wxsource.getTime();
read lon lat data
map.on('mousemove', (e) => {
if (!wxsource) return;
const pos = position(e); //
const tileInfo: WxTileInfo | undefined = wxsource.getLayerInfoAtLatLon(pos.wrap(), map);
if (tileInfo) {
console.log(tileInfo);
}
});
animated blur effect
(async function step(n: number = 0) {
await wxsource.updateCurrentStyleObject({ isolineText: false, blurRadius: ~~(10 * Math.sin(n / 500) + 10) }); // await always !!
requestAnimationFrame(step);
})();
more interactive - additional level and a bit of the red transparentness around the level made from current mouse position
await wxsource.updateCurrentStyleObject({ levels: undefined }); // reset levels if existed in the style
const levels = wxsource.getCurrentStyleObjectCopy().levels || []; // get current/default/any levels
// generate a new color map from the levels
const colMap: [number, string][] = levels.map((level) => [level, '#' + Math.random().toString(16).slice(2, 8) + 'ff']);
let busy = false;
map.on('mousemove', async (e) => {
if (!wxsource || busy) return;
busy = true;
const tileInfo: WxTileInfo | undefined = wxsource.getLayerInfoAtLatLon(position(e), map);
if (tileInfo) {
await wxsource.updateCurrentStyleObject({ colorMap: [...colMap, [tileInfo.inStyleUnits[0], '#ff000000']] });
onsole.log(tileInfo);
}
busy = false;
});