PL EN DE

Trzy serwery, ten sam plik EOP — a tylko jeden nadaje się do automatyzacji

Parametry orientacji Ziemi rozdaje kilka instytucji. Pliki bywają bajtowo identyczne, ale różnią się licencją i sposobem dostępu — a jedno ze źródeł potrafi odpowiedzieć 200 OK z nagłówkiem obiecującym 3,7 MB danych, po czym wysłać 434 bajty strony logowania.

Budując serwis udostępniający EOP, trzeba wybrać źródło. Wybór wygląda na techniczny, a jest głównie prawny. Poniżej opisuję, co ustaliłem empirycznie — z komendami, żeby dało się to powtórzyć.

Punkt wyjścia: finals2000A.all

To podstawowy plik z parametrami orientacji Ziemi: ruch bieguna (xp, yp), różnica UT1−UTC, długość doby (LOD) i offsety bieguna niebieskiego (dX, dY). Format stałopozycyjny, około 3,7 MB, seria od 1973 r. wraz z prognozami na rok naprzód.

Ten sam plik wydają co najmniej trzy serwery:

Naturalny odruch: wziąć IERS, bo to instytucja odpowiedzialna za te parametry. Albo NASA, bo brzmi solidnie. Oba odruchy prowadzą do kłopotów, choć z zupełnie różnych powodów.

Pułapka CDDIS: nagłówki kłamią

Zacznijmy od najbardziej podstępnego. Sprawdzamy dostępność pliku metodą HEAD, jak przy każdej sensownej automatyzacji:

$ curl -sSI https://cddis.nasa.gov/archive/products/iers/finals2000A.all

HTTP/1.1 200 OK
Server: Apache
Last-Modified: Thu, 30 Jul 2026 17:43:15 GMT
ETag: "3958e4-657d79b4eceaa"
Content-Length: 3758308

Kod 200. Rozmiar 3 758 308 bajtów — dokładnie tyle, ile powinien mieć plik. Poprawny Last-Modified, sensowny ETag. Wszystko wskazuje, że zasób jest publicznie dostępny.

Wykonujemy GET na dokładnie ten sam adres:

$ curl -sS -D - -o /dev/null https://cddis.nasa.gov/archive/products/iers/finals2000A.all

HTTP/1.1 302 Found
Location: https://urs.earthdata.nasa.gov/oauth/authorize?client_id=...
Content-Length: 434
HEAD mówi „200 OK, 3,7 MB". GET na ten sam URL daje „302, 434 bajty". Ciałem odpowiedzi jest strona przekierowująca na Earthdata Login (OAuth). Bez konta NASA danych nie ma — ale dowiadujesz się o tym dopiero wtedy, gdy sprawdzisz treść, a nie sam status.

Dlaczego to groźne? Typowy skrypt pobierający wygląda mniej więcej tak:

# WERSJA NAIWNA — nie rób tego
r = requests.get(URL)
if r.status_code == 200:
    open(CACHE, "wb").write(r.content)   # nadpisuje cache 434 bajtami HTML-a

Biblioteki HTTP domyślnie podążają za przekierowaniami, więc status_code wyniesie 200 — tyle że będzie to status strony logowania, nie pliku. Warunek przejdzie. Skrypt nadpisze poprawny, wczorajszy cache HTML-em. Serwis przestanie działać, a logi pokażą „pobrano pomyślnie".

Prawidłowa kontrola sprawdza, czy odpowiedź wygląda jak dane:

# Serwery potrafią oddać 200 ze stroną logowania zamiast danych.
# Sam kod HTTP nie wystarcza — sprawdzamy rozmiar i treść.
data = r.content
if len(data) < 1_000_000:
    raise ValueError(f"odpowiedź za mała ({len(data)} B) — to nie są dane")
if not data[:1].isdigit():
    raise ValueError("treść nie wygląda na finals2000A (oczekiwano cyfry roku)")

# dopiero teraz nadpisujemy cache — i to atomowo
open(tmp, "wb").write(data)
os.replace(tmp, CACHE)

Pierwszy znak poprawnego finals2000A.all to cyfra — rekordy zaczynają się od dwucyfrowego roku. HTML zaczyna się od <. Ta jedna linijka odróżnia dane od strony błędu.

Zapis atomowy ma znaczenie os.replace() po zapisie do pliku tymczasowego gwarantuje, że przerwane pobieranie nie zostawi obciętego pliku w miejscu działającego cache'u. Przy pliku ściąganym przez sieć to nie jest teoretyczne ryzyko.

Sama polityka NASA jest przy tym liberalna — dane misji są zwykle w CC0, użycie komercyjne dozwolone, cytowanie zalecane. Problemem nie jest licencja, tylko wymóg logowania, który dyskwalifikuje to źródło do bezobsługowego crona.

USNO kontra IERS: ten sam plik, inna licencja

Zostają dwa źródła. Sprawdźmy, czy w ogóle się różnią:

$ curl -sS -o usno.all https://maia.usno.navy.mil/ser7/finals2000A.all
$ curl -sS -o iers.all https://datacenter.iers.org/data/9/finals2000A.all
$ sha256sum usno.all iers.all

4b828090fc94114168014b61439fa5e6ec0bdfda518075a32baffea90110954d  usno.all
4b828090fc94114168014b61439fa5e6ec0bdfda518075a32baffea90110954d  iers.all

Bajtowo identyczne. Ta sama suma kontrolna, ten sam rozmiar 3 758 308 B, ten sam Last-Modified. Technicznie wybór między nimi jest obojętny.

Prawnie — nie jest.

USNO: „distribution unlimited"

Na stronie maia.usno.navy.mil widnieje klauzula:

„Approved for public release: distribution unlimited." Plik jest dziełem pracowników rządu federalnego USA wykonanym w ramach obowiązków służbowych. Zgodnie z 17 U.S.C. § 105 takie dzieła nie podlegają ochronie prawnoautorskiej i trafiają do domeny publicznej.

W praktyce: nie ma podmiotu praw, który mógłby narzucić warunki redystrybucji. Wolno pobierać, przetwarzać, udostępniać dalej i używać komercyjnie. Atrybucja nie jest wymagana prawnie — choć warto ją stosować jako dobrą praktykę naukową.

IERS: brak jawnej licencji

Data Center IERS prowadzi niemiecki BKG (Bundesamt für Kartographie und Geodäsie). Nota prawna zawiera przede wszystkim wyłączenie odpowiedzialności. Nie ma tam jawnej licencji — ale nie ma też jawnego zakazu.

Dla użytku własnego to bez znaczenia. Problem pojawia się przy redystrybucji: serwis udostępniający te pliki dalej rozpowszechnia cudzy zbiór bez wyraźnej zgody. W Unii dochodzi jeszcze prawo sui generis do bazy danych (dyrektywa 96/9/WE), które chroni sam zbiór, a nie pojedyncze fakty.

Warto wiedzieć: to prawo działa w obie strony — a raczej w żadną Prawo sui generis nie blokuje projektu opartego na danych USNO. Ale też nie ochroni zbudowanego na nich zbioru: samo pobranie cudzego pliku i przekonwertowanie formatu to za mało na „istotną inwestycję" w rozumieniu dyrektywy. Orzecznictwo TSUE odróżnia inwestycję w pozyskanie danych od inwestycji w ich wytworzenie.

ESA: niezależna seria z haczykiem

Europejska Agencja Kosmiczna publikuje własną, niezależną serię EOP przez Navigation Support Office. Kusząca alternatywa — dopóki nie sprawdzi się licencji.

Standardem ESA od 2017 r. jest CC BY-SA 3.0 IGO. Klauzula ShareAlike wymaga, by opracowania pochodne rozpowszechniać na tych samych warunkach.

Konsekwencja dla zbioru mieszanego: włączenie serii ESA do wspólnego pliku wynikowego mogłoby wymusić objęcie licencją CC BY-SA całości — łącznie z częścią opartą na danych z domeny publicznej. Jeśli chcesz zachować dane bez ograniczeń licencyjnych, seria ESA musi zostać w osobnym, wyraźnie oznaczonym module albo poza projektem.

Zestawienie

ŹródłoLicencjaRedystrybucjaDostęp bez kontaDo automatyzacji
USNOdomena publiczna
17 U.S.C. § 105
nieograniczonataktak
IERSbrak jawnejniepewnatakjako zapasowe
NASA CDDISliberalna (CC0)OKEarthdata Loginnie
ESACC BY-SA 3.0 IGOz ShareAliketakosobno

Wnioski praktyczne

  1. Pobieraj z USNO. Plik identyczny co do bajtu, a warunki prawne najczystsze z możliwych. Wybór źródła to tutaj decyzja prawna bez kosztu technicznego.
  2. IERS trzymaj jako zapas. Gdy USNO nie odpowiada, lepiej mieć dane z gorszymi warunkami niż nie mieć ich wcale — pod warunkiem, że odnotowujesz, z którego źródła pochodzą.
  3. Weryfikuj treść, nie kod HTTP. Rozmiar odpowiedzi i pierwszy znak wystarczą, by odróżnić dane od strony logowania. Bez tego jedno przekierowanie potrafi po cichu skasować działający cache.
  4. Nie mieszaj licencji w jednym zbiorze. ShareAlike jest zaraźliwy — raz wpuszczony do wspólnego pliku obejmuje całość.
  5. Zapisuj atomowo. Plik tymczasowy plus os.replace(). Przerwane pobieranie nie może zostawić obciętego pliku w miejscu działającego cache'u.
Jak to wygląda u nas gnss.day pobiera dane wyłącznie z USNO, z IERS jako źródłem zapasowym, i odnotowuje w metadanych, które z nich zostało faktycznie użyte. Kontrola treści odpowiedzi jest wbudowana w pipeline, a stare dane nigdy nie są kasowane, dopóki nowe nie przejdą walidacji. Dane są dostępne na stronie bez logowania oraz przez API.

Wszystkie sumy kontrolne i odpowiedzi serwerów zweryfikowane 2 sierpnia 2026 r. Tekst opisuje warunki źródeł na ten dzień — te bywają zmieniane, więc przed decyzją o komercjalizacji warto je sprawdzić ponownie. To nie jest porada prawna.

EOPGNSSIERSUSNO NASA CDDISlicencjedomena publiczna automatyzacja