← TTastro Design & Theory 中文
Astrophotography Assistant · Rating System · Design & Technical Doc v0.1

Dynamic Light Pollution Rating

The light-pollution rating a site can actually deliver for stargazing on a specific night, at a specific time. It follows the Bortle 1–9 scale, but with the SQM correspondences recalibrated and made to shift dynamically with sky conditions. Built entirely on public data (David Lorenz light-pollution atlas + Mapzen terrain tiles + Unihedron field-measurement calibration).

Static baseline = f( zenith darkness , terrain-aware surrounding glow )
effective SQM(t) = baseline − Δmoonlight(t) − ΔMilkyWay(t) − Δtwilight(t)  →  dynamic Bortle class(t)
Observability axis (independent) = cloud (gate) + humidity + transparency
Data 16,074 Unihedron measurementsBase map David Lorenz 2024Calibration all ready except the "downgrade coefficient"

0Core Concept

Dynamic light pollution rating differs from the traditional "static Bortle" in three ways:

  • Follows Bortle (1–9), but recalibrates the SQM correspondences—replacing the long-circulated, convention-based reference numbers with real field measurements (Bortle's original text never gave SQM values).
  • The dark end is set by geography, not the zenith reading—zenith SQM saturates above ~21.8, so classes 1–3 are separated by "surrounding dark-area extent + terrain shielding".
  • The rating shifts dynamically with the sky—moon phase/position, the Milky Way, cloud, and humidity all temporarily pull down the actual rating for a given night.

Output is on two axes: the light-pollution axis (dynamic effective SQM → dynamic Bortle) and the observability axis (cloud + humidity + transparency, deciding "whether you can observe tonight, and how clearly").

1Data Sources (all public, no authentication)

DataSourceNotes
Light-pollution SQM tilesdjlorenz.github.io
/astronomy/lp2024
David Lorenz 2024; 5°×5° per tile, 600×600 grid (~0.9km); WGS-84
Terrain DEMs3.amazonaws.com
/elevation-tiles-prod/terrarium
Mapzen terrarium; z12 (~37m/px); WGS-84
Calibration measurementsunihedron.com
/projects/darksky/database
16,074 globally crowdsourced measurements (2005–2026), used for fitting and calibration

The atlas is published publicly as binary gridded tiles; a deterministic decode of the tiles turns coordinates into SQM values—reproducing the algorithm below yields results that are bit-for-bit identical to the atlas.

2SQM Tile Decoding Algorithm (reproduced from public tiles)

input: lat, lon (WGS-84)
lonD  = ((lon+180) mod 360 + 360) mod 360
tileX = floor(lonD/5)+1 ;  tileY = floor((lat+65)/5)+1        # tileY∈[1,28]
file  = binary_tile_{tileX}_{tileY}.dat.gz → gzip decompress (360001 bytes)
ix = round(120*((lonD - 5*(tileX-1)) + 1/240))               # ∈[1,600]
iy = round(120*(((lat+65) - 5*(tileY-1)) + 1/240))
first  = data[0]*128 + data[1]
latSum = Σ_{i=1}^{iy-1} signed(data[600*i + 1])              # signed: b<128?b:b-256
lonSum = Σ_{i=1}^{ix-1} signed(data[600*(iy-1) + 1 + i])
C      = clamp(first + latSum + lonSum, 0, 10000)
brightnessRatio = (5/195)*(exp(0.0195*C) - 1)
SQM    = 22.0 - 5*log10(1+brightnessRatio) / log10(100)               # mag/arcsec²

Vectorization: precompute per-tile cumcol[iy] and cr[r][k], then C = first + cumcol[iy-1] + cr[iy-1][ix-1] is an O(1) lookup. Verified against the official stored values with max|diff|=0.0000.

3Zenith SQM ↔ Bortle: Recalibration Table

The most widely circulated Bortle–SQM correspondence is actually misleading (it labels class 1 as 22.0)—it comes neither from Bortle's original text nor from any authoritative definition, just years of convention; measure for real and you only get ~21.7. The table below recalibrates using 6,438 "clear · moonless · zenith" measurements, giving the estimated measured zenith SQM:

ClassEnvironmentMap SQM (classifying)Est. measured p25/median/p75Median dist. to domeDark-area share
1Pristine dark≥21.99 +vast openness21.61 / 21.72 / 21.86105 km100%
2Typical dark21.89–21.99 +medium openness21.45 / 21.60 / 21.797796%
3Rural dark21.69–21.8921.40 / 21.58 / 21.734464%
4Rural/suburban20.49–21.6921.03 / 21.29 / 21.471818%
5Suburban19.50–20.4919.78 / 20.25 / 20.5805%
6Bright suburban18.94–19.5018.95 / 19.25 / 19.61——
7Suburban–urban transition18.38–18.9418.30 / 18.58 / 18.81——
8–9Urban<18.3817.84 / 18.14 / 18.26——
Key: the measured medians for classes 1/2/3 (21.72 / 21.60 / 21.58) are nearly identical—zenith SQM cannot separate them; but the "distance to the nearest light dome" separates them cleanly (105 / 77 / 44 km).

3.1 Crossover (when the zenith stops working)

  • Zenith standard deviation by class: B4 0.346 → B3 0.058 → B2 0.031 → B1 0.005 (collapses to zero).
  • Around SQM 21.7 (from Bortle 3) the zenith begins to saturate; by SQM 21.9 (Bortle 2) it is completely pinned.
  • Physical floor ~21.9–22.0 (airglow / zodiacal light / Milky Way); measurements >22.0 are physically impossible (196 removed, 71% from a single bad station).

4Static Baseline Rating (intrinsic to a site; moonless clear night)

Effective Bortle baseline = f( zenith darkness , terrain-aware surrounding glow )
  · class ≥4 (map SQM<21.7): zenith-dominated, look up table §3 directly
  · class 1–3 (map SQM≥21.7): zenith + surrounding glow (incl. terrain shielding) jointly classify/downgrade

4.1 Surrounding Glow Index (distance-weighted, using only the light-pollution tiles)

glow_raw = Σ_surroundingCells  A(s) / d^2.5        # d=distance km, sample ±120km/step 4km, exclude d<3km
A(s)     = max(0, 10^(8-0.4·s) - 10^(-0.8))   # this cell's linear amount of "artificial light above the natural floor"
glowIndex = log10(glow_raw + 1e-9)

The distance exponent 2.5 = the Walker/Garstang light-propagation law; radius, exponent, and floor are all tunable parameters. It captures the whole surrounding glow, not just the single nearest dome.

4.2 Terrain-Shielding Gate (key)

for each azimuth φ (every 5°): along φ sample elevation out to ~50km, compute the horizon angle
  = atan((elevation - site elevation - curvature correction)/distance)   curvature correction = d²/(2·(7/6)·R_earth)
  shield[φ] = distance where horizon angle first >2°
glow_terrain = Σ A(s)/d^2.5 × visibility(φ,d)
visibility = 0 if d > shield[φ]  (blocked by mountains below the horizon) ; otherwise 1
Validation pointZenithRaw glowTerrain glowBlocked
Tivoli (Namibia desert)22.00−3.70−3.700%
Wiruna (Australia)21.96−2.42−2.420%
Kendrick Park (near Flagstaff)21.91−2.07−2.3952%
Crestone (backed by a 4300m ridge)21.85−2.25−2.6156%

Crestone's eastern half is shielded by the 5–16° Sangre de Cristo ridge from the Front Range cities 100km away → cutting 56%, actually surpassing Wiruna. Kendrick Park is shielded 52% by the San Francisco Peaks (3850m) → rescued from a "dark-pocket downgrade to class 3" back to class 2.

4.3 Downgrade Thresholds (dark end, classes 1–3; map SQM ≥21.89)

Terrain glow indexVerdictObservational meaning (Bortle definition)
< −3.0Class 1No light dome anywhere on the horizon
−3.0 ~ −2.2Class 21–2 faint distant light domes
> −2.2Downgrade to class 3Prominent light domes (dark pocket)

The thresholds are currently supported by "physical model + 4 benchmark points + Bortle definition + Walker distances", at v0.1; awaiting fine-tuning from dark-site measurements (§7).

5Dynamic Layer (Same-Night Sky Corrections)

effective SQM(t) = baseline SQM(loc) − Δmoonlight(t) − ΔMilkyWay(t) − Δtwilight(t)
dynamic class(t) = use the §3 recalibration table to reverse-lookup effective SQM(t)

5.1 Moonlight Curve (fitted from the 16k measurements)

Let u = moon phase% / 100 × sin(moon altitude); zenith brightening ΔSQM (mag):

Moon alt \ phase<30%30–70%70–100%
0–15°+0.08+0.07+0.22
15–30°+0.07+0.11+0.42
30–45°+0.20+0.21+0.69
45°+—+1.02+1.78
  • Smooth approximation: ΔSQM ≈ 1.18 · u^0.65 (production should interpolate the table above directly; per-point scatter is large, R²≈0.10).
  • Moonlight is blocked by terrain too: at field point 1 a full moon brightens by 2.35 mag, but only 1.75 once the moon is blocked by mountains (0.6 less) → the moonlight term also passes through the §4.2 terrain gate (using the moon's azimuth at the time).
  • Production can add a "moon–target angular distance" refinement, or switch to the Krisciunas-Schaefer form.

5.2 Milky Way / Twilight (v2)

  • Milky Way: when the galactic plane/center is near the zenith, the zenith brightens by ~±0.2–0.4 mag; compute the zenith's galactic coordinates from time and location.
  • Twilight: when the sun's altitude is > −18° the sky is brighter (can be >0.5 mag); check whether it is within astronomical night.

6Observability Axis (independent of the light-pollution class)

6.1 Cloud (bidirectional effect; coefficients derived from measurements)

SQM change from overcast relative to clear, by environment:

Environment (map SQM)Few cloudsCloudyOvercast
Urban/bright (<19)−0.2−0.4−2.2
Suburban (19–20.5)−0.2−0.5−3.8
Rural (20.5–21.3)−0.1—−1.8
Very dark (>21.3)00+0.3
Key pitfall: at very dark sites overcast actually raises SQM (cloud blocks the natural airglow), yet observing is ruined. Cloud cannot be folded into the effective-SQM formula; it needs a separate "observability gate" (overcast = not observable, regardless of SQM). Cloud "brightening" is only a correction term in light-polluted environments.

6.2 Humidity + Nearby Streetlights (sub-grid local pollution)

  • Field point 2: map 20.84, measured only 20.20 (−0.64 mag), due to a few nearby streetlights + high-humidity scattering by a creek.
  • These are below the resolution of the map (~0.9km) and the glow sampling (4km), so they cannot be captured.
  • Requires external data: humidity (weather API) + high-resolution local lighting (OSM streetlights / VIIRS). This is v2.

7Calibration Status & External Anchoring

Quantity to calibrateFittable from 16k zenith measurements?Status
Zenith↔SQM recalibration✅ YesDone (§3)
Cloud effect coefficients✅ YesDone (§6.1)
Moonlight curve✅ YesDone (§5.1)
Surrounding/terrain → zenith residual✅ YesDoable (not yet run)
Surrounding glow → how many classes to downgrade❌ NoNeeds external ground truth

Why the downgrade coefficient cannot be fitted: the measurements are zenith, while Bortle is whole-sky; surrounding light domes mainly affect the horizon, which the zenith SQM barely sees → with "the zenith fixed" the data contains no quantity that varies with the horizon. A structural limitation.

External anchoring (in place of dark-site measurements):

  • The very definition of Bortle 1 vs 2 is "whether there are light domes on the horizon": class 1 = no distant light pollution; class 2 = 1–2 faint domes on the horizon; SQM differs by only 0.15–0.4 mag. → Directly validates §4 and gives a qualitative threshold.
  • SQM fails at the dark end: the vendor acknowledges accuracy drops below 21.5 and that class 1–2 readings are only approximate.
  • NPS/Duriscoe use whole-sky "average sky luminance (ASL)", precisely because "domes are brighter on the horizon than at the zenith" → the same approach used by professionals.
  • Walker's law distances: population 1000 → avoidable at 32km, 10000 → 80km; large-city domes are visible 150+ miles away. → Calibrates the glow/distance thresholds.

8Field Validation (ground truth)

8.1 China Field Points (user-provided)

PointCoordinatesMap SQMMeasuredUser ratingModel
Point 123.820, 114.09921.2421.25Class 4✅ zenith-dominated, matches
Point 223.834, 112.88620.8420.20Below class 4✅ local pollution −0.64 → class 5

Point 1: the map is accurate, zenith-dominated, class 4 matches; the moon blocked by mountains brightens 0.6 mag less (validating terrain blocking of moonlight). Point 2: the map overestimates by 0.64 mag, revealing "sub-grid local pollution" (§6.2); a city to the E corresponds to "the Milky Way being invisible to the E".

8.2 Benchmark Dark Sites

Tivoli / Hakos (Namibia), Wiruna (Australia), Crestone / Kendrick Park (USA) — see §4.2; the terrain gate correctly separates "valleys backed by mountains" from "open dark pockets".

9Implementation Roadmap

v1 (doable now, all public data)

SQM tiles → recalibrated rating (§3) → terrain-aware glow (§4) → moonlight dynamic layer (§5.1) → cloud observability gate (§6.1). Downgrade thresholds use v0.1 (§4.3).

v2

Milky Way/twilight terms (§5.2); humidity + local lighting (§6.2, needs external data); fine-tune the downgrade thresholds with user-measured dark-site points.

Performance: terrain analysis is heavy (a dozen-plus DEM tiles per point + a full horizon sweep), so it must be cached by coordinate (terrain doesn't change—compute once, store forever). Terrain analysis is best run as an async task + permanent cache.

10Constants & Formulas Quick Reference

SQM formula             SQM = 22 − 5·log10(1 + (5/195)(e^(0.0195·C)−1)) / log10(100)
Glow                    Σ max(0,10^(8−0.4s)−10^(−0.8)) / d^2.5   R=120km, step=4km, exclude d<3km, exponent 2.5
Terrain gate            horizon angle > 2° blocks (incl. curvature correction d²/(2·(7/6)·R_earth))
Downgrade thresholds    terrain glow index <−3.0→class 1 / −3.0~−2.2→class 2 / >−2.2→class 3
Moonlight               ΔSQM ≈ 1.18·u^0.65 , u=moonPhase/100×sin(moonAlt)  (or use §5.1 table interpolation)
Cloud gate              overcast=not observable; cloud "brightening" only used in light-polluted environments
Natural floor           SQM upper limit ~22.0, >22.0 treated as bad data and removed