Aperture Radar — radar & optical satellite monitoring

Two live demos. Demo 1 uses optical imagery (Sentinel-2, 10 m visible-light) to track sand-dune migration over six years and forecast when each dune will reach a pipeline. Demo 2 uses sub-metre radar imagery (synthetic-aperture radar, day/night, cloud-piercing) for a deep-zoom time-lapse of an active industrial site. Both demos run on the same modular pipeline — drop in a new AOI polygon and a new STAC catalog and the analysis carries over.

Sentinel-2 optical, 10 m, free Capella sub-metre SAR Python rasterio · scikit-image · OpenCV OpenSeadragon deep-zoom Leaflet interactive map
Demo 1 · Optical · Dune migration & pipeline forecast

Predicting when sand dunes will bury a pipeline

Six years of monthly optical imagery over the Mauritanian Atlantic dune field (21.5°N, 16.7°W). We detect every individual barchan in every frame, stitch them into trajectories with a multi-target tracker, fit a velocity vector per dune with ordinary least squares, and project each forward in time. The viewer lets you draw a pipeline on the map and asks the system to predict — dune by dune — when and where each one will reach the line.

Play, slide, draw a pipeline, then Find next collision.
56

Monthly frames

Cloud-free optical scenes, Jan 2020 → Apr 2026 over a ~45 × 45 km AOI.

1 274

Tracked dunes

Individual barchans linked across ≥ 6 monthly observations spanning a median of 1.6 yr within the 6-year window.

25.6 m/yr

Median speed

Direction overwhelmingly S/SSW — matches the prevailing trade-wind regime.

100 yr

Forecast horizon

Kinematic extrapolation per dune. Useful at ≤ 10-yr horizons; longer is illustrative — dunes accelerate as they shrink and wind direction varies ±20° year-to-year.

Science behind it
  1. Acquisition. Query a public satellite catalog for all Sentinel-2 scenes intersecting the AOI with cloud cover under 5 %, keep one per month with the lowest cloud value. Each scene is downloaded only over the AOI and reprojected to Web Mercator at 10 m / pixel.
  2. Detection. Dry sand reflects more red light than the surrounding gravel pavement, so dunes appear as bright blobs. Per frame: high-percentile threshold, connected-component labelling, keep blobs of area 5 000–200 000 m² and eccentricity ≤ 0.95 — about 700-1 400 dune polygons per scene.
  3. Tracking. A greedy nearest-neighbour matcher links each detection to the closest detection in the next frame (max link 60 m, area-consistency |ΔA|/max < 0.3). Tracks surviving ≥ 6 observations across ≥ 1 year are kept.
  4. Velocity fit. Per-axis ordinary least-squares regression on UTM coords vs time → (vx, vy) in m / day, plus a heading and R².
  5. Forecast. Each dune is projected forward at its measured velocity, with radius derived from its observed area. The collision detector samples the predicted trajectory in 0.1-year steps and reports the first time the dune body intersects any segment of the user-drawn pipeline. Dunes already touching the pipeline at t = 0 are skipped.
Filters in the viewer

Straightness = ‖net displacement‖ / cumulative path length, on a 5-month smoothed trajectory. 1.0 = perfectly linear motion. Near 0 = wandering (the matcher kept hopping between neighbouring dunes). Wind-direction-agnostic — it doesn't assume the SSW wind.

= quality of the linear velocity fit. Low R² means residuals are large compared with the regression line.

Min observations = how many monthly samples a dune must have to count. The default (6) drops short-lived tracks.

Future prediction shifts each dune forward at its measured 2020-2026 velocity. Uncertainty grows roughly with √time, so very long horizons are illustrative only.

Raise the filters for strict / cleanest tracks; lower them to see every candidate. Predictions update instantly.

Validation & uncertainty

Track-level distributions on the unfiltered set of 1 274 trajectories:

  • Migration rate: 25.6 m/yr median, MAD 10.3 m/yr, IQR [16.0, 36.8] m/yr.
  • OLS fit quality (R²): median 0.50, MAD 0.24, IQR [0.25, 0.73]. Wide spread — many tracks are short or noisy.
  • Straightness (5-month smoothed): median 0.88, MAD 0.12 — most tracks are physically monotonic after smoothing, the long tail near 0 is what the slider filters out.
  • Trajectory length: median 10 monthly observations across a 1.6-year span.

Filter survival. Default thresholds (S ≥ 0.7, R² ≥ 0.4, n ≥ 6) retain ~660 tracks. Strict (S ≥ 0.9, R² ≥ 0.8) retains 169. Stricter filtering raises the median rate (the dropped tracks were disproportionately near-stationary mismatches), which is the expected behaviour of a quality filter.

Known gaps. We have not yet performed manual ground-truth digitisation in Google Earth Pro for an independent error measurement; the published 13–29 m/yr SSW range for the same region is our external sanity check rather than a per-dune validation. Per-dune velocity confidence intervals from the OLS fit (Var(β̂) = σ²(XX)−1) are computable but not yet surfaced in the viewer.

Demo 2 · Radar (SAR) · High-resolution change detection

Deep-zoom radar time-lapse of an active mining site

56 sub-metre SAR frames over Telfer (Western Australia), one of Australia's largest gold-mining complexes. Radar sees through cloud and dust day or night, so we can monitor pit expansion, haul-truck traffic, tailings-dam growth, and equipment movement — features invisible to optical sensors when the weather is poor and untrackable after dark. The viewer stitches every frame into a tile pyramid that smoothly zooms from the full ~6.8 km AOI crop down to individual vehicles.

Slide through dates. Toggle change heat-map and particle flow in the sidebar.
56

SAR acquisitions

Sub-metre stripmap frames at 3-day cadence over 178 days. AOI crop 16 583 × 16 450 px at 0.41 m / px (~6.8 × 6.7 km).

15

Zoom levels

Tile pyramid built with libvips — same UI as gigapixel deep-zoom viewers.

log-ratio

Change detector

Per-tile shift-tolerant block matching + amplitude log-ratio. Robust to speckle.

flow

Particle overlay

Dense change field rendered as drifting particles — wind-map metaphor for change.

Science behind it
  1. Acquisition. Sub-metre stripmap SAR scenes are calibrated and geocoded by the provider. We unzip each one, extract the VV amplitude, and store the raw float32 data locally.
  2. Tile pyramid. Each scene is converted to an 8-bit percentile-stretched PNG, then run through libvips dzsave to build a Deep-Zoom-Image pyramid: 512-px JPG tiles at quality 85, 15 zoom levels. The viewer pulls only the tiles it needs at the current zoom and viewport — bandwidth per pan/zoom action is bounded by viewport size, not by scene size.
  3. Co-registration. SAR amplitudes can drift by a pixel or two between passes due to satellite-orbit variations. For each pair of consecutive scenes, normalised cross-correlation (cv2.matchTemplate with TM_CCOEFF_NORMED) on a sliding ±6 px window finds the best-fit local shift before comparing radiometry.
  4. Log-ratio change. On the co-registered pair, |mean(log A) − mean(log B)| per 64-px tile. The log domain is natural for SAR: it converts multiplicative speckle into additive noise and makes the metric symmetric under bright/dark inversion. We subtract the per-pair median to remove global radiometric drift.
  5. Particle flow. The dense scalar change field is promoted to a vector field by gradient + 90° rotation, then 4 000 particles are integrated through it on a canvas overlay aligned to the SAR pyramid. Particles trail along regions of high change.

Why SAR, not optical, for industrial monitoring. Radar backscatter depends on surface roughness and dielectric properties, not illumination — so a 6 a.m. winter pass and a 1 p.m. summer pass produce comparable images. Optical comparisons are confounded by sun angle, cloud cover, dust plumes, and seasonal vegetation. For a 24/7 operational site, SAR is the only modality that gives a regular baseline independent of weather and daylight.

Direct transfer to pipeline-corridor monitoring. The same processing chain — sub-metre stripmap acquisitions, NCC co-registration, log-ratio change with per-pair drift normalisation, particle-flow visualisation — applies unchanged to a Saudi pipeline right-of-way. At 3-day cadence it would surface dune-crest movement onto the alignment, third-party encroachment on the easement, new excavation activity, and surface-deformation patterns indicative of subsidence — all in conditions where optical, ground crews and aerial overflights are limited (night, dust storms, restricted-access terrain).

Pipeline

The end-to-end stack we built

Both demos run on the same modular pipeline. Swap the AOI, the date range, and the sensor — the analysis carries over. The processed outputs (GeoJSON trajectories, tile pyramids, scene manifests) are pre-computed and rendered client-side, so the viewers themselves are static assets.

Step 1 — Catalog

STAC-API query (Element-84 Earth-Search, ASF) by AOI polygon and date interval, filtered on eo:cloud_cover for optical and orbit geometry for SAR.

Step 2 — Window-read

Read only the AOI tiles from each cloud-optimised GeoTIFF via GDAL VSI + range-GET — gigabytes saved per scene versus a full download.

Step 3 — Reproject

rasterio.WarpedVRT warps every scene to Web Mercator at the analysis resolution. One CRS for detection, visualisation, and overlays — zero offset between layers.

Step 4 — Detect / change

Optical: per-frame percentile threshold + skimage.measure.label connected components. SAR: NCC co-registration via cv2.matchTemplate + log-ratio per tile with per-pair median normalisation.

Step 5 — Track / fit

Greedy nearest-neighbour tracker with area-consistency gating. Per-axis OLS regression of UTM coords vs time per trajectory, returning v = (vx, vy), heading and R².

Step 6 — Forecast

Linear projection p̂(t) = p0 + v · t. Sand-burial check by point-to-segment distance against a user-drawn polyline, sampled in 0.1-yr steps within a 100-yr horizon.

Mathematical core

The core of the pipeline reduces to a handful of well-posed numerical operations — each one a standard tool from image processing, statistical estimation, or computational geometry. Display-side smoothing kernels and per-pair median normalisations are omitted here for brevity but are documented in the source.

T  =  P92{ R[𝟙valid] }
Detection threshold (optical). Per-frame brightness cutoff at the 92nd percentile of red-band reflectance over valid pixels. Adaptive — it tracks scene-wide radiometric drift across the 6-year stack.
e  =  √(1 − b2/a2)  ≤  0.95
Shape filter. Eccentricity of the equivalent ellipse from the second-moment matrix of each labelled blob. Crescent-shaped barchans satisfy this; elongated ridge lines and noise streaks are rejected.
s*  =  argmaxs‖ ≤ 6 px   ρ( A,  B+s )
Local co-registration (radar). Normalised cross-correlation between consecutive amplitude patches over a ±6 px search window. cv2.matchTemplate(TM_CCOEFF_NORMED) returns the integer-pixel shift that maximises the correlation coefficient ρ, applied per tile before the log-ratio change is computed.
Δ(x, y)  =  |⟨log A⟩ − ⟨log B⟩|  −  medianpair
Log-ratio change (radar). Cell-wise difference of mean log-amplitudes after registration. The log transform converts multiplicative speckle into additive noise; subtracting the per-pair median cancels global radiometric drift between acquisitions.
j*  =  argminjxi(t)xj(t+1)‖    subject to  ‖·‖ < 60 m,   |ΔA| / max(A) < 0.3
Greedy multi-target tracker. Each detection at time t+1 is linked to its nearest predecessor in L2 within a maximum link distance, gated by an area-consistency check. Conflicts (two detections claiming the same predecessor) are resolved by the closest pair.
β̂  =  (XX)−1 Xy    ⇒   (t) = 0 + v · t
Velocity fit (OLS). Per-axis ordinary least-squares regression of UTM coordinates against time, yielding a measured 2-D velocity vector v = (vx, vy) for every long-lived trajectory. Goodness-of-fit reported as R².
S  =  ‖ ∑k Δxk ‖  /  ∑k ‖Δxk‖  ∈  [0, 1]
Straightness index. Ratio of net displacement to cumulative path length over a 5-month rolling-smoothed trajectory. S → 1 means motion is monotonic and linear; S → 0 means the matcher hopped between dunes. Wind-direction-agnostic — the demo uses it as the principal track-quality filter.
thit  =  argmint > 0 {  d( (t),  Γpipe )  ≤  √(A / π)  }
Sand-burial collision. Earliest future time at which a dune's projected centre comes within one equivalent radius of the pipeline polyline Γ. Solved by linear sampling in 0.1-year increments; dunes with thit ≤ 0 are assumed to have been engineered around when the line was built.