### Initialize WeatherLayers-GL Client and Deck.gl Application Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck/map.html This JavaScript snippet demonstrates the initial setup of the WeatherLayers-GL client, including authentication and linking the GeoTIFF library. It then initializes a deck.gl instance for map visualization and integrates various UI controls such as info panels, logo, legend, timeline, tooltip, and attribution, configuring their event handlers and attaching them to the DOM. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, isMetalWebGl2 } from '../config.js'; import { BASEMAP_RASTER_STYLE_URL, BASEMAP_ATTRIBUTION } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; // deck.gl const deckgl = window.deckgl = new deck.Deck({ parent: document.getElementById('deck'), initialViewState: { longitude: 30, latitude: 10, zoom: 0, /* // screenshot Twitter 600x335, slide 1440x810 zoom: 1, */ }, controller: { normalize: false, }, views: [ new deck.MapView({ repeat: true }), ], layers: [], }); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // legend const legendControl = new WeatherLayers.LegendControl(); legendControl.prependTo(document.getElementById('bottom-left')); // timeline const timelineControl = new WeatherLayers.TimelineControl({ onPreload: datetimes => datetimes.map(datetime => client.loadDatasetData(config.dataset, datetime)), onUpdate: datetime => { config.datetime = datetime || NO_DATA; update(); }, }); timelineControl.prependTo(document.getElementById('bottom-left')); // tooltip const tooltipControl = new WeatherLayers.TooltipControl({ followCursor: true }); deckgl.setProps({ onLoad: () => deckgl.getCanvas() && tooltipControl.addTo(deckgl.getCanvas().parentElement), onHover: event => tooltipControl.updatePickingInfo(event), }); deckgl.props.onLoad(); // attribution const basemapAttributionControl = new WeatherLayers.AttributionControl({ attribution: BASEMAP_ATTRIBUTION }); basemapAttributionControl.prependTo(document.getElementById('bottom-right')); const attributionControl = new WeatherLayers.AttributionControl(); attributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); // config async function update(forceUpdateDatetime) { // ... (rest of update function) } }); ``` -------------------------------- ### Initialize WeatherLayers Client and MapLibre GL JS Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-interleaved/maplibre-globe.html This snippet demonstrates the initial setup of the WeatherLayers client, MapLibre GL JS map, and Deck.gl overlay. It loads the dataset catalog, configures the application, and sets up the base map with a globe projection, preparing it for weather data visualization. ```javascript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, waitForDeck } from '../config.js'; import { BASEMAP_VECTOR_STYLE_URL, BASEMAP_VECTOR_LAYER_BEFORE_ID, updateBasemapVectorStyle } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true, globe: true }); let gui; // Mapbox const map = window.map = new maplibregl.Map({ container: 'maplibre', style: BASEMAP_VECTOR_STYLE_URL, center: [7, 46], zoom: 1.5, }); await new Promise(resolve => map.once('style.load', resolve)); updateBasemapVectorStyle(map); map.setProjection({ type: 'globe' }); // interleaved deck.gl const deckLayer = new deck.MapboxOverlay({ interleaved: true, // creating a custom GlobeView without id=mapbox fixes BitmapLayer artifacts, but is incompatible with interleaving Maplibre and deck.gl layers views: [new deck._GlobeView({ id: 'mapbox', resolution: 5 })], layers: [], }); map.addControl(deckLayer); const deckgl = window.deckgl = await waitForDeck(() => deckLayer._deck); ``` -------------------------------- ### Initialize WeatherLayers Client, MapLibre GL, and Deck.gl with UI Controls Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/maplibre-globe.html This snippet demonstrates the comprehensive setup of a WeatherLayers application. It initializes the WeatherLayersClient for data access, configures a maplibregl instance with a globe projection, integrates deck.gl as an overlay for visualization, and adds various interactive UI controls such as info panels, logo, legend, timeline, tooltip, attribution, and an FPS meter. Dependencies include `WeatherLayersClient`, `maplibregl`, and `deck.gl`. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, waitForDeck, isMetalWebGl2 } from '../config.js'; import { BASEMAP_VECTOR_STYLE_URL, updateBasemapVectorStyle } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true, globe: true }); let gui; // Mapbox const map = window.map = new maplibregl.Map({ container: 'maplibre', style: BASEMAP_VECTOR_STYLE_URL, center: [7, 46], zoom: 1.5, /* // screenshot Twitter 600x335, slide 1440x810 zoom: 0, */ /* // screenshot Gitbook 750x422 zoom: -0.15, */ /* // banner 1500x500 center: [7, 46], zoom: 3.5, pitch: 40, bearing: 0, */ }); await new Promise(resolve => map.once('style.load', resolve)); updateBasemapVectorStyle(map); map.setProjection({ type: 'globe' }); /* // screenshot, banner // hide borders map.setLayoutProperty('border_other', 'visibility', 'none'); map.setLayoutProperty('border_other-dash', 'visibility', 'none'); map.setLayoutProperty('border_disputed', 'visibility', 'none'); map.setLayoutProperty('border_country', 'visibility', 'none'); // hide labels map.setLayoutProperty('water_point', 'visibility', 'none'); map.setLayoutProperty('water_line', 'visibility', 'none'); map.setLayoutProperty('road', 'visibility', 'none'); map.setLayoutProperty('place', 'visibility', 'none'); map.setLayoutProperty('town', 'visibility', 'none'); map.setLayoutProperty('state', 'visibility', 'none'); map.setLayoutProperty('city', 'visibility', 'none'); map.setLayoutProperty('country', 'visibility', 'none'); map.setLayoutProperty('continent', 'visibility', 'none'); */ // overlaid deck.gl const deckLayer = new deck.MapboxOverlay({ interleaved: false, views: [new deck._GlobeView({ id: 'mapbox', resolution: 5 })], layers: [], }); map.addControl(deckLayer); const deckgl = window.deckgl = await waitForDeck(() => deckLayer._deck); // rotate const rotateAnimation = new WeatherLayers.Animation({ onUpdate: () => { const center = map.getCenter(); map.setCenter({ lng: center.lng + 0.3, lat: center.lat }); } }); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // legend const legendControl = new WeatherLayers.LegendControl(); legendControl.prependTo(document.getElementById('bottom-left')); // timeline const timelineControl = new WeatherLayers.TimelineControl({ onPreload: datetimes => datetimes.map(datetime => client.loadDatasetData(config.dataset, datetime)), onUpdate: datetime => { config.datetime = datetime || NO_DATA; update(); }, }); timelineControl.prependTo(document.getElementById('bottom-left')); // tooltip const tooltipControl = new WeatherLayers.TooltipControl({ followCursor: true }); deckgl.setProps({ onLoad: () => deckgl.getCanvas() && tooltipControl.addTo(deckgl.getCanvas().parentElement), onHover: event => tooltipControl.updatePickingInfo(event), }); deckgl.props.onLoad(); // attribution const attributionControl = new WeatherLayers.AttributionControl(); attributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); // config ``` -------------------------------- ### Initialize WeatherLayers GUI Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/maplibre.html This snippet shows the final steps of initializing the graphical user interface (GUI) for the WeatherLayers-GL application. It includes an asynchronous update call and the initialization of the GUI with the current configuration and rendering options. ```JavaScript await update(); gui = initGui(config, update, { deckgl, webgl2: true }); }); ``` -------------------------------- ### Initial Application Setup and Utility Functions Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/front.html This snippet handles initial module imports, defines a mapping for front data types, a utility function for converting seconds to degrees, and sets up the main DOMContentLoaded event listener to kick off the application's asynchronous initialization process. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { initConfig, initGui, cssToColor } from '../config.js'; import { BASEMAP_RASTER_STYLE_URL, BASEMAP_ATTRIBUTION } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const FrontDataTypeToFrontType = { CFRONT: WeatherLayers.FrontType.COLD, WFRONT: WeatherLayers.FrontType.WARM, OFRONT: WeatherLayers.FrontType.OCCLUDED, SFRONT: WeatherLayers.FrontType.STATIONARY, }; function secToDeg(value) { return value / 60 / 60; } window.addEventListener('DOMContentLoaded', async () => { const FRONT_DATA = await (await fetch('./front-data.json')).json(); const config = await initConfig({ deckgl: true, webgl2: true }); let gui; ``` -------------------------------- ### Initialize WeatherLayers-GL Client with Mapbox GL JS and Deck.gl Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-interleaved/mapbox.html This JavaScript snippet demonstrates the complete setup of a WeatherLayers-GL application. It initializes the WeatherLayers client, integrates with Mapbox GL JS for the base map, and uses Deck.gl as an interleaved overlay for rendering weather data. It also sets up various UI controls like info, FPS, logo, legend, timeline, tooltip, and attribution, and defines an asynchronous 'update' function to fetch and render dynamic weather layers (HighLowLayer, RasterLayer) based on user configuration and time. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN, MAPBOX_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, waitForDeck } from '../config.js'; import { BASEMAP_VECTOR_STYLE_URL, BASEMAP_VECTOR_LAYER_BEFORE_ID, updateBasemapVectorStyle } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; // Mapbox const map = window.map = new mapboxgl.Map({ container: 'mapbox', accessToken: MAPBOX_ACCESS_TOKEN, style: BASEMAP_VECTOR_STYLE_URL, center: [30, 10], zoom: 1, }); await new Promise(resolve => map.once('style.load', resolve)); updateBasemapVectorStyle(map); // interleaved deck.gl const deckLayer = new deck.MapboxOverlay({ interleaved: true, layers: [], }); map.addControl(deckLayer); const deckgl = window.deckgl = await waitForDeck(() => deckLayer._deck); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // legend const legendControl = new WeatherLayers.LegendControl(); legendControl.prependTo(document.getElementById('bottom-left')); // timeline const timelineControl = new WeatherLayers.TimelineControl({ onPreload: datetimes => datetimes.map(datetime => client.loadDatasetData(config.dataset, datetime)), onUpdate: datetime => { config.datetime = datetime || NO_DATA; update(); }, }); timelineControl.prependTo(document.getElementById('bottom-left')); // tooltip const tooltipControl = new WeatherLayers.TooltipControl({ followCursor: true }); deckgl.setProps({ onLoad: () => deckgl.getCanvas() && tooltipControl.addTo(deckgl.getCanvas().parentElement), onHover: event => tooltipControl.updatePickingInfo(event), }); deckgl.props.onLoad(); // attribution const attributionControl = new WeatherLayers.AttributionControl(); attributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); // config async function update(forceUpdateDatetime) { const dataset = config.dataset !== NO_DATA ? config.dataset : undefined; const {title, unitFormat, attribution, palette} = await client.loadDataset(dataset, { unitSystem: config.unitSystem }); const {datetimes} = await client.loadDatasetSlice(dataset, config.datetimeRange.split('/'), { datetimeStep: config.datetimeStep }); const datetime = config.datetime !== NO_DATA && datetimes[0] <= config.datetime && config.datetime <= datetimes[datates.length - 1] && !forceUpdateDatetime ? config.datetime : datetimes[0]; const {image, image2, imageWeight, imageType, imageUnscale, bounds} = await client.loadDatasetData(dataset, datetime, { datetimeInterpolate: config.datetimeInterpolate }); config.datetimes = datetimes; config.datetime = datetime; deckLayer.setProps({ layers: [ // HighLowLayer must be before RasterLayer and ContourLayer in Mapbox interleaved, see https://docs.weatherlayers.com/weatherlayers-gl/troubleshooting new WeatherLayers.HighLowLayer({ id: 'highLow', // data properties image, image2, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageWeight, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.highLow.enabled && !timelineControl.running, unitFormat, radius: config.highLow.radius, textSize: config.highLow.textSize, textColor: cssToColor(config.highLow.textColor), textOutlineColor: cssToColor(config.highLow.textOutlineColor), textOutlineWidth: config.highLow.textOutlineWidth, palette: config.highLow.palette ? palette : null, opacity: config.highLow.opacity, getPolygonOffset: () => [0, -1000], beforeId: BASEMAP_VECTOR_LAYER_BEFORE_ID, }), new WeatherLayers.RasterLayer({ id: 'raster', // data properties image, image2, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageWeight, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.raster.enabled, palette, gridEnabled: config.raster.gridEnabled, opacity: config.raster.opacity, pickable: true, extensions: [new deck.ClipExtension()], clipBounds: [-181, -85.051129, ``` -------------------------------- ### Initialize WeatherLayers Client and Global Configuration Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/openlayers.html This snippet initializes the WeatherLayers client with an access token and sets up the GeoTIFF library. It then loads the data catalog and initializes the application's configuration, including dataset and rendering options, upon DOM content loading. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, isMetalWebGl2 } from '../config.js'; import { BASEMAP_RASTER_STYLE_URL, BASEMAP_ATTRIBUTION } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; ``` -------------------------------- ### Initialize GUI and Trigger Application Update Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/arcgis-renderer.html This snippet demonstrates the initialization of the graphical user interface (GUI) with a configuration object and an update function, and then triggers an initial update of the application state to reflect the configured layers and controls. ```javascript await update(); gui = initGui(config, update, { deckgl, webgl2: true }); ``` -------------------------------- ### Initialize WeatherLayers Client and Application Configuration Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/arcgis-renderer.html This code block sets up the WeatherLayers client with an access token, loads the catalog, and initializes the application configuration based on available datasets. It also prepares the main DOM elements for rendering. ```javascript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, isMetalWebGl2 } from '../config.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; }); ``` -------------------------------- ### Configure ArcGIS Map and SceneView for 3D Visualization Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/arcgis-renderer.html This snippet demonstrates how to load ArcGIS modules, create a new Map instance with a basemap, and set up a SceneView for 3D visualization. It configures the camera position and UI components, ensuring the view is ready before further operations. ```javascript const { DeckRenderer, modules: [Map, SceneView, externalRenderers, reactiveUtils] } = await deck.loadArcGISModules([ 'esri/Map', 'esri/views/SceneView', 'esri/views/3d/externalRenderers', 'esri/core/reactiveUtils', ], { version: '4.29' }); const map = new Map({ basemap: 'dark-gray-vector', layers: [], }); const view = new SceneView({ container: 'arcgis', map: map, camera: { position: { longitude: 30, latitude: 10, z: 100000 * 1000, // 100000 km }, }, viewingMode: 'local', }); view.ui.components = ['attribution']; await reactiveUtils.whenOnce(() => !view.updating); ``` -------------------------------- ### Initialize OpenLayers Map with Basemap Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/openlayers.html This code block sets up a basic OpenLayers map instance. It targets a specific DOM element, configures the initial view (center and zoom), and adds a tile layer using a predefined basemap URL, enabling the display of geographical context. ```JavaScript // OpenLayers const map = new ol.Map({ target: document.getElementById('openlayers'), controls: [], view: new ol.View({ center: ol.proj.fromLonLat([30, 10]), zoom: 0, }), layers: [], }); map.addLayer(new ol.layer.Tile({ source: new ol.source.XYZ({ url: BASEMAP_RASTER_STYLE_URL }), maxZoom: 22 })); ``` -------------------------------- ### Configure WeatherLayers-GL Particle and Grid Layers Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/map.html This snippet demonstrates the instantiation and configuration of `WeatherLayers.ParticleLayer` and other layers within a `deck.gl` context. It sets various visual and data-related properties such as particle count, animation, color, bounds, and visibility for weather visualization, along with grid layer properties. ```javascript new WeatherLayers.ParticleLayer({ id: 'particle', // data properties image, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.particle.enabled, numParticles: config.particle.numParticles, maxAge: config.particle.maxAge, speedFactor: config.particle.speedFactor, width: config.particle.width, color: cssToColor(config.particle.color), palette: config.particle.palette ? palette : null, opacity: config.particle.opacity, animate: config.particle.animate, extensions: [new deck.ClipExtension()], clipBounds: [-181, -85.051129, 181, 85.051129], getPolygonOffset: () => [0, -1000] }) ``` -------------------------------- ### Initialize WeatherLayers-GL Layers and Update Controls Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-interleaved/arcgis.html This snippet demonstrates the instantiation of `WeatherLayers.ContourLayer`, `WeatherLayers.RasterLayer`, and `WeatherLayers.GridLayer` with various configuration options. It also shows how to update the configurations of `legendControl`, `timelineControl`, `tooltipControl`, and `attributionControl` instances, likely part of a `deck.gl` or similar visualization setup. The configuration includes data properties, style properties, and extensions like `deck.ClipExtension`. ```JavaScript opacity: config.contour.opacity, extensions: \[new deck.ClipExtension()\] , clipBounds: \[-181, -85.051129, 181, 85.051129\], }), new WeatherLayers.RasterLayer({ id: 'raster', // data properties image, image2, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageWeight, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.raster.enabled, palette, gridEnabled: config.raster.gridEnabled, opacity: config.raster.opacity, pickable: !isMetalWebGl2(), extensions: \[new deck.ClipExtension()\] , clipBounds: \[-181, -85.051129, 181, 85.051129\], }), new WeatherLayers.GridLayer({ id: 'grid', // data properties image, image2, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageWeight, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.grid.enabled, style: config.grid.style, density: config.grid.density, unitFormat, textSize: config.grid.textSize, textColor: cssToColor(config.grid.textColor), textOutlineWidth: config.grid.textOutlineWidth, textOutlineColor: cssToColor(config.grid.textOutlineColor), iconBounds: config.grid.iconBounds, iconSize: config.grid.style === WeatherLayers.GridStyle.ARROW ? \[config.grid.iconSize / 8, config.grid.iconSize\] : config.grid.iconSize, iconColor: cssToColor(config.grid.iconColor), palette: config.grid.palette ? palette : null, opacity: config.grid.opacity, }), \], }); legendControl.updateConfig({ title, unitFormat, palette }); timelineControl.updateConfig({ datetimes, datetime, datetimeInterpolate: config.datetimeInterpolate }); tooltipControl.updateConfig({ unitFormat, directionType: config.tooltip.directionType, directionFormat: config.tooltip.directionFormat, followCursorOffset: config.tooltip.followCursorOffset, followCursorPlacement: config.tooltip.followCursorPlacement, }); attributionControl.updateConfig({ attribution }); } await update(); gui = initGui(config, update, { deckgl }); }); ``` -------------------------------- ### Define and Apply Dynamic WeatherLayers Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/grid-local.html This asynchronous JavaScript function, `update`, is responsible for defining and applying the data layers to the deck.gl instance. It creates a `TileLayer` for the basemap and integrates custom `WeatherLayers.RasterLayer` and `WeatherLayers.GridLayer` for visualizing weather data, along with an example `ScatterplotLayer`. The function demonstrates how to dynamically update the map's layers based on configuration and data, including setting properties like visibility, opacity, and extensions. ```javascript // config async function update(forceUpdateDatetime) { const width = 5; const height = 5; const data = new Array(width * height).fill(undefined).map((_, i) => i % 2 === (width % 2 ? 0 : Math.floor(i / width) % 2)); const image = {data: new Float32Array(data), width, height}; const imageInterpolation = WeatherLayers.ImageInterpolation.NEAREST; const imageType = WeatherLayers.ImageType.SCALAR; const bounds = [-10, -10, 10, 10]; const palette = [ [0, [255, 0, 0]], [1, [0, 255, 0]], ]; deckgl.setProps({ layers: [ new deck.TileLayer({ id: 'basemap', data: BASEMAP_RASTER_STYLE_URL, minZoom: 0, maxZoom: 22, tileSize: 256, renderSubLayers: props => { const {bbox: {west, south, east, north}} = props.tile; return new deck.BitmapLayer(props, { data: null, image: props.data, bounds: [west, south, east, north], }); }, }), new WeatherLayers.RasterLayer({ id: 'raster', // data properties image, imageInterpolation, imageType, bounds, // style properties visible: config.raster.enabled, palette, gridEnabled: true, opacity: config.raster.opacity, pickable: !isMetalWebGl2(), extensions: [new deck.ClipExtension()], clipBounds: [-181, -85.051129, 181, 85.051129], }), new WeatherLayers.GridLayer({ id: 'grid', // data properties image, imageInterpolation, imageType, bounds, // style properties visible: config.grid.enabled, opacity: config.grid.opacity, }), new deck.ScatterplotLayer({ data: [[0, 0]], getPosition: d => d.position, getRadius: 4, getFillColor: [255, 0, 0], radiusUnits: 'pixels', }), ], }); } await update(); }); ``` -------------------------------- ### Configure WeatherLayers UI Controls Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-interleaved/arcgis-renderer-globe.html This section demonstrates the setup of various user interface controls provided by the WeatherLayers library. It includes controls for information display, branding (logo), data legends, time navigation (timeline), interactive tooltips, attribution, and an FPS meter, attaching them to specific DOM elements. ```JavaScript // rotate const rotateAnimation = new WeatherLayers.Animation({ onUpdate: () => { const camera = view.camera.clone(); camera.position.longitude += 0.3; view.goTo(camera, { animate: false }); } }); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // legend const legendControl = new WeatherLayers.LegendControl(); legendControl.prependTo(document.getElementById('bottom-left')); // timeline const timelineControl = new WeatherLayers.TimelineControl({ onPreload: datetimes => datetimes.map(datetime => client.loadDatasetData(config.dataset, datetime)), onUpdate: datetime => { config.datetime = datetime || NO_DATA; update(); }, }); timelineControl.prependTo(document.getElementById('bottom-left')); // tooltip const tooltipControl = new WeatherLayers.TooltipControl({ followCursor: true }); deckgl.setProps({ onLoad: () => deckgl.getCanvas() && tooltipControl.addTo(deckgl.getCanvas().parentElement), onHover: event => tooltipControl.updatePickingInfo(event), }); deckgl.props.onLoad(); // attribution const attributionControl = new WeatherLayers.AttributionControl(); attributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); ``` -------------------------------- ### Initialize WeatherLayers GL Application with Deck.gl Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/front-globe.html This snippet demonstrates the main entry point of the WeatherLayers GL application. It initializes the deck.gl instance, sets up the initial view state, and prepares the configuration for subsequent layer rendering. It also includes utility imports and constants. ```text ``` -------------------------------- ### Configure WeatherLayers-GL Grid and Particle Layers Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/globe.html This JavaScript snippet illustrates how to instantiate and configure `WeatherLayers.GridLayer` and `WeatherLayers.ParticleLayer` objects. It sets properties such as text and icon styling for the grid, and animation, color, and particle count for the particle layer. This configuration is typically part of a larger deck.gl or map application setup, defining how weather data is rendered. ```javascript fig.grid.textColor), textOutlineWidth: config.grid.textOutlineWidth, textOutlineColor: cssToColor(config.grid.textOutlineColor), iconBounds: config.grid.iconBounds, iconSize: config.grid.style === WeatherLayers.GridStyle.ARROW ? \[config.grid.iconSize / 8, config.grid.iconSize\] : config.grid.iconSize, iconColor: cssToColor(config.grid.iconColor), palette: config.grid.palette ? palette : null, opacity: config.grid.opacity, }), new WeatherLayers.ParticleLayer({ id: 'particle', // data properties image, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.particle.enabled, numParticles: config.particle.numParticles, maxAge: config.particle.maxAge, speedFactor: config.particle.speedFactor, width: config.particle.width, color: cssToColor(config.particle.color), palette: config.particle.palette ? palette : null, opacity: config.particle.opacity, animate: config.particle.animate, getPolygonOffset: () => \[0, -1000\], }), \], }); } await update(); }); ``` -------------------------------- ### Initialize Deck.gl Map and UI Controls Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/grid-local.html This JavaScript snippet demonstrates the initialization of a deck.gl map instance within a web page. It sets up the initial view state, integrates various UI controls such as info panels, a logo, attribution, and an FPS meter, and configures event listeners for view state changes. It showcases the basic structure for setting up a deck.gl application with custom controls. ```javascript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { initConfig, cssToColor, isMetalWebGl2 } from '../config.js'; import { BASEMAP_RASTER_STYLE_URL, BASEMAP_ATTRIBUTION } from '../basemap.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; window.addEventListener('DOMContentLoaded', async () => { const config = await initConfig({ deckgl: true, webgl2: true }); // deck.gl const deckgl = window.deckgl = new deck.Deck({ parent: document.getElementById('deck'), initialViewState: { longitude: 30, latitude: 0, zoom: 0, }, controller: { normalize: false, }, views: [ new deck.MapView({ repeat: true }), ], layers: [], }); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // attribution const basemapAttributionControl = new WeatherLayers.AttributionControl({ attribution: BASEMAP_ATTRIBUTION }); basemapAttributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); ``` -------------------------------- ### WeatherLayers Client and ArcGIS/deck.gl Integration Example Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/arcgis.html This comprehensive JavaScript example demonstrates how to initialize the WeatherLayers client, integrate it with ArcGIS and deck.gl for map visualization, and add various interactive UI controls. It covers loading datasets, synchronizing map views between ArcGIS and deck.gl, handling user input, and dynamically updating weather data layers based on user configurations and timeline selections. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, isMetalWebGl2 } from '../config.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; // ArcGIS const { DeckLayer, modules: [Map, MapView, reactiveUtils] } = await deck.loadArcGISModules([ 'esri/Map', 'esri/views/MapView', 'esri/core/reactiveUtils', ], { version: '4.29' }); const map = new Map({ basemap: 'dark-gray-vector', layers: [], }); const view = new MapView({ container: 'arcgis', map: map, center: [30, 10], zoom: 0, }); view.ui.components = ['attribution']; await reactiveUtils.whenOnce(() => !view.updating); // overlaid deck.gl const deckgl = window.deckgl = new deck.Deck({ parent: document.getElementById('deck'), initialViewState: {}, controller: false, views: [ new deck.MapView({ repeat: true }), ], layers: [], }); function updateDeckView() { const viewState = { longitude: view.center.longitude, latitude: view.center.latitude, zoom: view.zoom, bearing: -view.rotation, }; deckgl.setProps({ viewState }); } view.watch('center', updateDeckView); view.watch('zoom', updateDeckView); view.watch('rotation', updateDeckView); updateDeckView(); function dispatchMouseEvent(event) { document.querySelector('#arcgis .esri-view- ``` -------------------------------- ### Deck.gl WeatherLayers Layer Configuration Example Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/test/front.html This JavaScript snippet demonstrates the instantiation and configuration of `WeatherLayers.HighLowLayer` and `WeatherLayers.FrontLayer` for use with Deck.gl. It shows how to define data sources, apply styling (colors, sizes, opacities), and map data properties for geographical visualization. The snippet also includes a basic structure for integrating with a GUI and an update mechanism. ```JavaScript config.contour.opacity, extensions: [new deck.ClipExtension()], clipBounds: [-181, -85.051129, 181, 85.051129], }), new WeatherLayers.HighLowLayer({ id: 'highLow', // data properties image, imageSmoothing: config.imageSmoothing, imageInterpolation: config.imageInterpolation, imageType, imageUnscale, imageMinValue: config.imageMinValue > 0 ? config.imageMinValue : null, imageMaxValue: config.imageMaxValue > 0 ? config.imageMaxValue : null, bounds, // style properties visible: config.highLow.enabled, unitFormat, radius: config.highLow.radius, textSize: config.highLow.textSize, textColor: cssToColor(config.highLow.textColor), textOutlineWidth: config.highLow.textOutlineWidth, textOutlineColor: cssToColor(config.highLow.textOutlineColor), palette: config.highLow.palette ? palette : null, opacity: config.highLow.opacity, }), new WeatherLayers.FrontLayer({ id: 'front', // data properties data: FRONT_DATA.FT[6].obj, // indexes with all front types: 5, 6+, 10, 11, 12, 14+, 17+, 18 getType: d => FrontDataTypeToFrontType[d.TYPE], getPath: d => d.point.map(point => [secToDeg(point.LON), secToDeg(point.LAT)]), coldColor: [37, 99, 235], // Tailwind CSS blue-600 warmColor: [220, 38, 38], // Tailwind CSS red-600 occludedColor: [124, 58, 237], // Tailwind CSS violet-600 }), ], }); } await update(); gui = initGui(config, update, { deckgl, webgl2: true }); }); ``` -------------------------------- ### Initialize WeatherLayers Client with Google Maps and Deck.gl Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/google-maps.html This snippet initializes the WeatherLayers client, sets up a Google Maps instance, overlays Deck.gl for rendering, and integrates various UI controls such as info panels, logo, legend, timeline, tooltip, attribution, and an FPS meter. It demonstrates the core application structure for a weather visualization dashboard. ```JavaScript import { WEATHER_LAYERS_ACCESS_TOKEN } from '../auth.js'; import { NO_DATA, initConfig, initGui, cssToColor, waitForDeck, isMetalWebGl2 } from '../config.js'; import { InfoControl } from '../info-control.js'; import { FpsControl } from '../fps-control.js'; const client = window.client = new WeatherLayersClient.Client({ accessToken: WEATHER_LAYERS_ACCESS_TOKEN, }); WeatherLayersClient.setLibrary('geotiff', GeoTIFF); window.addEventListener('DOMContentLoaded', async () => { const datasets = await client.loadCatalog(); const config = await initConfig({ datasets, deckgl: true, webgl2: true }); let gui; // Google Maps const map = new google.maps.Map(document.getElementById('google-maps'), { center: { lng: 30, lat: 10 }, zoom: 1, mapId: 'ac3c83c0af8794fe', isFractionalZoomEnabled: true, backgroundColor: 'none', disableDefaultUI: true, }); await new Promise(resolve => google.maps.event.addListenerOnce(map, 'tilesloaded', resolve)); // overlaid deck.gl const deckLayer = new deck.GoogleMapsOverlay({ interleaved: false, layers: [], }); deckLayer.setMap(map); const deckgl = window.deckgl = await waitForDeck(() => deckLayer._deck); // info panels const infoControl = new InfoControl(); infoControl.prependTo(document.getElementById('top-left')); deckgl.setProps({ onViewStateChange: ({ viewState }) => infoControl.update(viewState), }); // logo const logoControl = new WeatherLayers.LogoControl(); logoControl.prependTo(document.getElementById('bottom-left')); // legend const legendControl = new WeatherLayers.LegendControl(); legendControl.prependTo(document.getElementById('bottom-left')); // timeline const timelineControl = new WeatherLayers.TimelineControl({ onPreload: datetimes => datetimes.map(datetime => client.loadDatasetData(config.dataset, datetime)), onUpdate: datetime => { config.datetime = datetime || NO_DATA; update(); }, }); timelineControl.prependTo(document.getElementById('bottom-left')); // tooltip const tooltipControl = new WeatherLayers.TooltipControl({ followCursor: true }); deckgl.setProps({ onLoad: () => deckgl.getCanvas() && tooltipControl.addTo(deckgl.getCanvas().parentElement), onHover: event => tooltipControl.updatePickingInfo(event), }); deckgl.props.onLoad(); // attribution const attributionControl = new WeatherLayers.AttributionControl(); attributionControl.prependTo(document.getElementById('bottom-right')); // FPS meter const fpsControl = new FpsControl(); fpsControl.prependTo(document.getElementById('bottom-right')); ``` -------------------------------- ### Update WeatherLayers UI Controls Configuration Source: https://github.com/weatherlayers/weatherlayers-gl/blob/main/docs/deck-overlaid/arcgis-renderer.html This snippet shows how to update the configuration for various UI controls in the WeatherLayers application, including legendControl, timelineControl, tooltipControl, and attributionControl, with relevant data and formatting options. ```javascript legendControl.updateConfig({ title, unitFormat, palette }); timelineControl.updateConfig({ datetimes, datetime, datetimeInterpolate: config.datetimeInterpolate }); tooltipControl.updateConfig({ unitFormat, directionType: config.tooltip.directionType, directionFormat: config.tooltip.directionFormat, followCursorOffset: config.tooltip.followCursorOffset, followCursorPlacement: config.tooltip.followCursorPlacement }); attributionControl.updateConfig({ attribution }); ```