leaflet_svelte/WIND_LAYER_IMPLEMENTATION.md

6.8 KiB

Wind Layer Implementation Guide

🌬️ Overview

The project now uses @sakitam-gis/maplibre-wind for professional wind visualization on MapLibre GL maps.

📦 Installation

npm install @sakitam-gis/maplibre-wind --save

Package installed: Version included in package.json

🎨 Features Implemented

Wind Particle Animation

  • 5000 particles flowing with wind direction
  • Color gradient: Blue → Green → Yellow → Orange → Red
  • Smooth animation with WebGL acceleration
  • Configurable speed and fade effects

Heatmap Visualization

  • Color-coded intensity display
  • Opacity control (70% default)
  • Display range: 0-20 m/s
  • Rainbow color scheme: Blue → Cyan → Green → Yellow → Red

🔧 Component Structure

File: src/lib/components/WindVisualisation.svelte

Props:

  • map - MapLibre GL map instance
  • windData - Wind data in GRIB format (U/V components)

State:

  • showHeatmap - Toggle heatmap layer
  • showParticles - Toggle particle animation layer

Functions:

  • initializeWindLayers() - Creates particle and heatmap layers
  • prepareWindData() - Transforms GRIB data to wind-layer format
  • Reactive $effect() - Toggles layer visibility

📊 Data Format

Input: GRIB Wind Data (testVelo.json)

[
  {
    "header": {
      "parameterNumber": 2,  // U-component
      "nx": 360,             // Grid columns
      "ny": 181,             // Grid rows
      "lo1": 0.0,            // Starting longitude
      "la1": 90.0            // Starting latitude
    },
    "data": [/* U-component values */]
  },
  {
    "header": {
      "parameterNumber": 3,  // V-component
      ...
    },
    "data": [/* V-component values */]
  }
]

Output: Wind-Layer Format

{
  uMin: number,        // Min U-component value
  uMax: number,        // Max U-component value
  vMin: number,        // Min V-component value
  vMax: number,        // Max V-component value
  rows: number,        // Grid rows (ny)
  cols: number,        // Grid columns (nx)
  data: [Array, Array] // [U-component, V-component]
}

🎛️ Configuration Options

Particle Layer

{
  renderType: 'particles',
  styleSpec: {
    numParticles: 5000,       // Number of particles
    fadeOpacity: 0.996,       // Trail fade rate (0.9-0.999)
    speedFactor: 0.25,        // Animation speed multiplier
    dropRate: 0.003,          // Particle regeneration rate
    dropRateBump: 0.01,       // Regeneration boost
    colors: [                 // Color gradient
      '#3288bd',  // Blue
      '#66c2a5',  // Green
      '#fee08b',  // Yellow
      '#f46d43',  // Orange
      '#d53e4f'   // Red
    ]
  }
}

Heatmap Layer

{
  renderType: 'colorize',
  styleSpec: {
    opacity: 0.7,
    colors: [
      '#0000ff',  // Blue
      '#00ffff',  // Cyan
      '#00ff00',  // Green
      '#ffff00',  // Yellow
      '#ff0000'   // Red
    ],
    displayRange: [0, 20]  // Min/max wind speed (m/s)
  }
}

🎮 Usage

UI Controls

Located in bottom-left corner of the map:

  • ☑️ Тепловая карта - Toggle heatmap visualization
  • ☑️ Частицы ветра - Toggle particle animation (default: ON)

Programmatic Control

// In Map.svelte
<WindVisualization {map} {windData} />

// Toggle layers via checkbox binding
// Layers automatically add/remove from map

🔄 Data Flow

1. testVelo.json (GRIB format)
   ↓
2. Map.svelte loads data
   ↓
3. WindVisualisation component receives:
   - map instance
   - windData
   ↓
4. prepareWindData() transforms to wind-layer format
   ↓
5. WindLayer instances created:
   - Particle layer
   - Heatmap layer
   ↓
6. Layers added to map
   ↓
7. User toggles visibility via checkboxes

🎯 Key Implementation Details

1. Svelte 5 Runes

Uses modern Svelte 5 syntax:

  • $props() for component props
  • $state() for reactive state
  • $effect() for reactive layer toggling

2. Map Lifecycle

  • Waits for map to load before initializing
  • Checks map.loaded() status
  • Listens to 'load' event if not ready

3. Layer Management

  • Checks if layer exists before adding
  • Removes layers on component destroy
  • Prevents duplicate layer IDs

4. Error Handling

  • Validates wind data structure
  • Catches initialization errors
  • Logs detailed error messages
  • Graceful degradation on failure

🐛 Debugging

Console Logs

// On mount
"WindVisualization mounted with MapLibre map"
"Wind data available: [...]"

// Data processing
"Wind data stats - U: [-21.32, 26.80], V: [-21.57, 21.42]"

// Success
"Wind layers initialized successfully"

// Errors
"Missing U or V wind components"
"Error initializing wind layers: [error]"

Check Layer Status

// In browser console
map.getLayer('wind-particles')  // Should return layer object
map.getLayer('wind-heatmap')    // Should return layer object

📚 Resources

⚙️ Advanced Customization

Adjust Particle Count

numParticles: 10000  // More particles (slower performance)
numParticles: 2000   // Fewer particles (better performance)

Change Animation Speed

speedFactor: 0.5   // Faster animation
speedFactor: 0.1   // Slower animation

Custom Color Schemes

// Wind speed colors
colors: ['#000080', '#0000FF', '#FFFF00', '#FF0000', '#800000']

// Monochrome
colors: ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#000000']

Adjust Display Range

displayRange: [0, 30]  // For stronger winds
displayRange: [0, 10]  // For lighter winds

🚀 Future Enhancements

Potential additions:

  • Timeline control for temporal wind data
  • Arrow vector visualization
  • Wind speed labels
  • Custom tile sources for real-time data
  • Wind barbs (meteorological standard)
  • Integration with prediction module

Testing Checklist

  • Package installed successfully
  • Component imports without errors
  • Wind data loads from testVelo.json
  • Particle animation displays on map
  • Heatmap visualization works
  • Checkboxes toggle layers correctly
  • No console errors on mount/unmount
  • Layers clean up on component destroy

📝 Notes

  • Wind data must be in GRIB format with U/V components
  • Particle layer is GPU-accelerated (requires WebGL)
  • Large particle counts may impact performance
  • Data transformation happens client-side
  • Layers are added above base map tiles
  • Z-index managed by MapLibre layer order

Implementation Date: December 2025 Package Version: @sakitam-gis/maplibre-wind Status: Production Ready