Map: clamp GIBS daily-layer latest to yesterday UTC — today's mosaic isn't ingested yet at 00:xx UTC so tiles 404'd and the map went black
All checks were successful
build-and-deploy / build (push) Successful in 1m39s

This commit is contained in:
Sirius DevOps 2026-08-24 20:47:50 -04:00
parent f122740d56
commit 28146c1adc

View file

@ -20,7 +20,7 @@ from __future__ import annotations
import asyncio import asyncio
import re import re
import time import time
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta, timezone
import httpx import httpx
@ -98,9 +98,18 @@ def _parse_time_domain(domain: str) -> dict:
Returns {min, max, latest, ranges:[{start,end}]} where ranges keep the Returns {min, max, latest, ranges:[{start,end}]} where ranges keep the
raw GIBS windows so the frontend can warn when a picked date is outside raw GIBS windows so the frontend can warn when a picked date is outside
every window (GIBS still serves nearest-time tiles, but this is honest). every window (GIBS still serves nearest-time tiles, but this is honest).
GIBS' published windows include the current UTC day as soon as it starts,
but daily mosaics (MODIS/VIIRS true color, night lights) aren't actually
ingested until hours later tiles for "today" 404 until then. So we clamp
daily-layer window ends to *yesterday* UTC: 'latest' then always points at
imagery that really exists.
""" """
windows = [] windows = []
min_d, max_d = None, None min_d, max_d = None, None
# 00:00~03:00+ UTC the newest full day is always yesterday; use a small
# margin so we never advertise a same-day mosaic that isn't ingested yet.
cutoff = datetime.now(timezone.utc).date() - timedelta(days=1)
for part in domain.split(","): for part in domain.split(","):
part = part.strip() part = part.strip()
m = _TIME_RANGE_RE.match(part) m = _TIME_RANGE_RE.match(part)
@ -108,6 +117,10 @@ def _parse_time_domain(domain: str) -> dict:
continue continue
start = date.fromisoformat(m.group(1)) start = date.fromisoformat(m.group(1))
end = date.fromisoformat(m.group(2)) end = date.fromisoformat(m.group(2))
if m.group(3) == "P1D" and end > cutoff:
end = cutoff
if start > end:
continue # whole window was "not yet ingested" days
windows.append({"start": start.isoformat(), "end": end.isoformat()}) windows.append({"start": start.isoformat(), "end": end.isoformat()})
if min_d is None or start < min_d: if min_d is None or start < min_d:
min_d = start min_d = start