From 28146c1adc1a1343aa832eae692f0bd5b412bba2 Mon Sep 17 00:00:00 2001 From: Sirius DevOps Date: Mon, 24 Aug 2026 20:47:50 -0400 Subject: [PATCH] =?UTF-8?q?Map:=20clamp=20GIBS=20daily-layer=20latest=20to?= =?UTF-8?q?=20yesterday=20UTC=20=E2=80=94=20today's=20mosaic=20isn't=20ing?= =?UTF-8?q?ested=20yet=20at=2000:xx=20UTC=20so=20tiles=20404'd=20and=20the?= =?UTF-8?q?=20map=20went=20black?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/gibs_map.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/gibs_map.py b/app/gibs_map.py index 48d0edb..95e7b18 100644 --- a/app/gibs_map.py +++ b/app/gibs_map.py @@ -20,7 +20,7 @@ from __future__ import annotations import asyncio import re import time -from datetime import date, datetime, timedelta +from datetime import date, datetime, timedelta, timezone import httpx @@ -98,9 +98,18 @@ def _parse_time_domain(domain: str) -> dict: 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 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 = [] 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(","): part = part.strip() m = _TIME_RANGE_RE.match(part) @@ -108,6 +117,10 @@ def _parse_time_domain(domain: str) -> dict: continue start = date.fromisoformat(m.group(1)) 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()}) if min_d is None or start < min_d: min_d = start