Foreword

Technical Overview of PowFinder Pipeline

PowFinder was born from my frustration with existing ski weather forecasting tools. Previously, planning a ski tour required manually cross-referencing multiple weather variables: snowfall but also over the intevening days, temperature, wind, cloud cover. I wanted a single intuitive visualization that combined all these factors into one glanceable map. And while SQH finds powder the attenuation from skiability makes it very clear - the pink splotches are where powder & sun are to be found together.

Initially, I built a fully client-side prototype that ran a detailed snowpack model directly in JavaScript. While the snowpack physics and modeling logic were robust, the client-side approach was slow, ugly, and impractical. I kept the snowpack physics and rebuilt the pipeline properly as a Python-based backend, which now runs efficiently on my laptop. The entire pipeline—fetching data, interpolating, running snowpack physics, generating visualizations, and compressing outputs—completes in under an hour for the entire Tirol region. The compressed outputs are then uploaded directly to AWS S3 for hosting.


Technical Pipeline Overview

The pipeline consists of these main steps:

1. Data Acquisition

Every three hours, I fetch weather data from the Open-Meteo API, which provides point-based forecasts across Tirol. Variables include:

  • Temperature (°C): Directly from API.
  • Relative Humidity (%): Directly from API.
  • Dew Point: Derived from temperature and relative humidity using the Magnus-Tetens equation.
  • Snowfall (mm): Directly from API, enhanced by elevation differences.
  • Wind Speed (m/s): Directly from API, interpolated spatially.
  • Cloud Cover (%): Directly from API, interpolated spatially.
  • Shortwave Radiation (W/m²): Directly from API, adjusted by terrain shading.

2. Spatial Interpolation and Extrapolation

I interpolate each weather variable from sparse API points onto a 100m resolution grid covering Tirol using inverse-distance weighting (IDW) interpolation. Specifically:

  • Temperature (°C): Interpolated using inverse-distance weighting, then adjusted vertically using a moist adiabatic lapse rate (~6.5°C/km) based on elevation differences.
  • Dew Point (°C): Derived from temperature and relative humidity using the Magnus-Tetens approximation.
  • Snowfall (mm): Interpolated using inverse-distance weighting, then enhanced orographically by applying a linear elevation-based multiplier (e.g., +10% snowfall per 100m elevation gain).
  • Snow Depth (mm): Forward-integrated through time using a simplified snowpack model (see below).
  • Wind Speed (m/s): Interpolated using inverse-distance weighting without elevation adjustment.
  • Cloud Cover (%): Interpolated using inverse-distance weighting.
  • Shortwave Radiation (W/m²): Interpolated spatially, then adjusted for terrain shading using a precomputed shadow map.

K-D Tree Implementation

To efficiently interpolate weather data from sparse API points onto my 100m-resolution grid, I build a K-D tree spatial index of all API points. For each grid cell, I query the nearest neighbors using the K-D tree and perform inverse-distance weighting interpolation. Elevation adjustments (lapse rates, orographic enhancements) are applied after interpolation.

3. Snowpack Model (4D Integration)

The snowpack model integrates snowfall, temperature, radiation, and wind over time, creating a four-dimensional snowpack state (3D spatial + time). At each timestep, the previous snowpack state is updated:

  • Accumulation: New snowfall (mm) converted to snow depth (cm) using a density factor.
  • Compaction and Melting: Temperature and radiation-driven melting and compaction reduce snow depth and degrade quality.
  • Wind Scouring: High wind speeds reduce snow depth and degrade quality.
  • Quality: Degrades over time due to melting, wind scouring, and solar radiation exposure.

This approach closely resembles a simplified 1D snowpack model applied spatially across Tirol, providing realistic powder evolution.

Shadow and Hillshade Generation

  • Hillshade: Computed from terrain elevation data using the angle between the terrain surface normal and the sun's position (zenith and azimuth angles). Specifically, hillshade intensity is calculated as the cosine of the angle between the terrain surface normal and the sun's zenith and azimuth angles.
  • Shadow Map: Precomputed binary raster indicating terrain shading based on solar zenith and azimuth angles, used to adjust shortwave radiation.

These layers are computationally expensive but rarely change, so they're precomputed and cached.

4. Visualization (SQH and Skiability)

The Snow Quality Heatmap (SQH) combines snow depth (opacity) and snow quality (color):

  • Opacity: Directly indicates snow depth. No snow = transparent; deep snow = fully opaque.
  • Color: Red (poor snow) → Blue (good snow) → Bright Pink (excellent powder). Bright pink opaque splotches indicate deep, high-quality powder.

The Skiability index further attenuates SQH based on real-time weather conditions (wind, visibility, precipitation):

  • Skiability = SQH × Weather Penalties
  • Areas with no snow become transparent (no color)
  • Areas with poor conditions become red (low skiability)
  • Areas with good conditions become blue
  • Areas with excellent powder conditions become bright pink opaque splotches, clearly highlighting the best skiing spots.

This intuitive visualization simplifies ski trip planning dramatically.

5. Interactive Validation (Point Click)

When a user clicks the map:

  • The frontend fetches live weather data from the API at that exact location.
  • It compares this real data to my interpolated values at the same location.
  • It displays the deltas clearly, allowing validation of interpolation accuracy.

Future Improvements: Neural Network Interpolation

Currently, interpolation uses physics-based extrapolation methods. In the future, I plan to train a neural network to predict real-world station data from Open-Meteo inputs. This neural network will:

  • Use ICON's 2.2km grid data as inputs.
  • Predict precise weather values at finer resolutions (100m).
  • Minimize a loss function based on real station measurements.
  • Provide more accurate forecasts than ICON's native 2.2km grid.

Current Limitations and Known Issues

  • Large JSON files: Currently mitigated by compression and lazy loading.
  • Static hosting: Real-time updates are not yet implemented, but the pipeline runs quickly enough (under an hour) to update every three hours manually.
  • Swapped colors on some browsers: This issue is under investigation. Not really, I have shit to do.

Visual Pipeline Overview

Hillshade Series - Visual representation of the PowFinder pipeline processing stages
Launch PowFinder →