Tłumaczenie maszynowe, niezweryfikowane przez osobę, dla której polski jest językiem ojczystym. Wzorcem jest wersja angielska.

Zaufanie do odbiornika i żegluga morskaEdytuj na GitHubieŹródło: docs/INTERFERENCE-MAP.md

Mapa zakłóceń i narażenie trasy

kshana interference-map buduje dzienny obraz tego, gdzie statki powietrzne i okręty zgłaszały pogorszone dane nawigacyjne, na podstawie otwarcie licencjonowanych plików śledzenia, które dostarczasz. kshana route-exposure mówi następnie, jaka część planowanej trasy leżała w danym dniu wewnątrz dotkniętych komórek.

Czym to jest: opisem tego, jak wyglądały opublikowane raporty pozycji w minionych dniach. Czym nie jest: pomiarem jakiegokolwiek odbiornika, prognozą ani dowodem zakłóceń. Komórka z pogorszeniem lub anomalią ma kilka możliwych przyczyn (wymienionych poniżej), a komórka bez wpisu po prostu nie była obserwowana.

Wszystko działa na plikach lokalnych. Domyślne polecenia nigdy nie otwierają połączenia sieciowego; jedyny opcjonalny pomocnik pobierania wymaga jawnej flagi.

Dwa syntetyczne dni mapy zakłóceń narysowane z zatwierdzonych próbek w examples/interference-map/output, każdy z własną syntetyczną trasą i udziałami ekspozycji trasy, które podaje silnik. Po lewej dzień ADS-B: 1 komórka z pogorszeniem, 6 bez pogorszenia, 4 nieocenione (kreskowane) oraz komórki bez wpisu, narysowane jako puste, które nie były obserwowane. Trasa ma 525 km: 11,5% jej długości w komórkach z pogorszeniem, 38,3% bez pogorszenia, 9,1% nieocenione i 41,1% nieobserwowane. Po prawej dzień AIS: komórki oznaczone przez detektory okręgu i lądu, komórki bez anomalii i puste komórki; trasa ma 454 km, z 10,5% w komórkach z anomalią, 21,2% bez anomalii, 0,0% nieocenione i 68,3% nieobserwowane. ADS-B i AIS są oddzielnymi warstwami, nigdy niełączonymi. Oznaczona komórka nie jest stwierdzeniem zakłóceń, a komórka bez koloru nie była obserwowana, co nie oznacza, że było czysto. Wszystkie dane są zmyślone, na otwartym środkowym Atlantyku, i nie są pomiarem.Dwa syntetyczne dni mapy zakłóceń narysowane z zatwierdzonych próbek w examples/interference-map/output, każdy z własną syntetyczną trasą i udziałami ekspozycji trasy, które podaje silnik. Po lewej dzień ADS-B: 1 komórka z pogorszeniem, 6 bez pogorszenia, 4 nieocenione (kreskowane) oraz komórki bez wpisu, narysowane jako puste, które nie były obserwowane. Trasa ma 525 km: 11,5% jej długości w komórkach z pogorszeniem, 38,3% bez pogorszenia, 9,1% nieocenione i 41,1% nieobserwowane. Po prawej dzień AIS: komórki oznaczone przez detektory okręgu i lądu, komórki bez anomalii i puste komórki; trasa ma 454 km, z 10,5% w komórkach z anomalią, 21,2% bez anomalii, 0,0% nieocenione i 68,3% nieobserwowane. ADS-B i AIS są oddzielnymi warstwami, nigdy niełączonymi. Oznaczona komórka nie jest stwierdzeniem zakłóceń, a komórka bez koloru nie była obserwowana, co nie oznacza, że było czysto. Wszystkie dane są zmyślone, na otwartym środkowym Atlantyku, i nie są pomiarem.

Oba dni to syntetyczne próbki w examples/interference-map/output/, każdy z syntetyczną trasą w examples/interference-map/input/; udziały ekspozycji trasy to to, co kshana route-exposure wypisuje dla nich. Nic w nich nie jest rzeczywistym miejscem, statkiem powietrznym ani jednostką pływającą.

Dane i licencje#

Wbudowane są tylko źródła przejrzane w data/INTERFERENCE-DATA-SOURCES.md, wybierane za pomocą --dataset:

--dataset Rodzaj Licencja Pole licencji wyniku
adsb-lol ADS-B ODbL 1,0 ODbL-1.0
noaa-marinecadastre AIS domena publiczna USA (CC0 1,0 według wydawcy) domena publiczna
kystverket AIS NLOD 2,0 NLOD-2.0
custom każdy z nich cokolwiek podasz wymagane --licence, --licence-url, --attribution

Każdy plik wynikowy osadza licencję, adres URL licencji, wymaganą informację o autorstwie i ograniczenia pokrycia źródła. Nie ma wbudowanego wpisu dla źródeł, których warunki zabraniają użycia komercyjnego lub redystrybucji map pochodnych.

ODbL i wydania Kshana. Plik ADS-B na komórkę wykonany z danych adsb.lol jest Derived Database i jest wydawany na licencji ODbL 1,0; mówi o tym jego pole licence. Własny kod Kshana pozostaje na AGPL-3.0. Wydania komercyjne Kshana, które zapisują takie pliki, dołączają tę samą informację, a każdy, kto plik ponownie publikuje, musi ją zachować. Wyniki ADS-B i AIS nigdy nie są łączone w jednym pliku, więc ODbL nie obejmuje warstwy AIS.

Obciążenie wynikające z pokrycia. Mapy dziedziczą pokrycie swojego źródła. adsb.lol opiera się na odbiornikach wolontariuszy, więc otwarte morze i słabo pokryte regiony są rzadko obsadzone. Otwarte dane Kystverket pomijają jednostki rybackie poniżej 15 m i rekreacyjne poniżej 45 m, więc jego mapa odzwierciedla większe statki. MarineCadastre obejmuje wyłącznie wody USA.

Identyfikatory. Wiersze wejściowe zawierają identyfikator statku powietrznego lub jednostki pływającej. Jest on haszowany w pamięci z losową solą dla każdego przebiegu, używany wyłącznie do zliczania odrębnych statków powietrznych lub jednostek pływających i nigdy nie jest zapisywany, logowany ani drukowany. Wyniki są zagregowane: nigdzie w nich nie występuje żaden identyfikator.

Tłumienie. Komórka z mniej niż 5 odrębnych statków powietrznych lub jednostek pływających zaobserwowanych tego dnia nie jest publikowana w ogóle, a dla AIS liczba oznaczeń równa jeden lub dwa w opublikowanej komórce jest podawana jako null. Żadna opublikowana wartość nie pozwala wskazać pojedynczego statku powietrznego ani jednostki pływającej.

Formaty wejściowe#

Zwykły CSV z wierszem nagłówka, rozdzielany przecinkami, bez cudzysłowów, czasy w UTC. Kolejność kolumn jest dowolna; nieznane kolumny są ignorowane. Znacznik czasu to sekundy Uniksa lub YYYY-MM-DDTHH:MM:SS[.fff]Z. Wiersze, których nie da się sparsować, są liczone w metadanych wyniku, a nie po cichu pomijane.

ADS-B (kshana interference-map adsb):

Kolumna Wymagana Znaczenie
timestamp tak czas raportu
aircraft_id tak nieprzejrzysty identyfikator (haszowany, nigdy nie przechowywany)
lat, lon tak stopnie
alt_baro_ft tak wysokość w stopach; ground lub puste wyklucza wiersz
nic, nacp co najmniej jedna liczby całkowite od 0 do 11; puste oznacza brak zgłoszenia
source_type nie jeśli występuje, używane są tylko wartości zaczynające się od adsb (MLAT, TIS-B i podobne są wykluczone)

Historia readsb z adsb.lol, czytana bezpośrednio. Dzienne archiwa to dzielony tar plików śladu readsb. Rozpakuj jedno tak, jak opisuje wydawca (połącz części, tar -xf -), a następnie podaj Kshana rozpakowany katalog, pojedynczy plik trace_full_*.json lub plik CSV:

kshana interference-map adsb extracted-day/ --dataset adsb-lol --out maps/

Katalog jest przeszukiwany rekurencyjnie pod kątem plików trace_full_* (inne pliki, takie jak trace_recent_*, są ignorowane, a dowiązania symboliczne nie są podążane). Każdy plik jest skompresowany gzipem lub jest zwykłym JSON, co jest wykrywane po pierwszych bajtach, ponieważ readsb zapisuje gzip pod nazwą .json; dekompresja jest ograniczona do 512 MiB na plik. Z każdego wpisu śladu Kshana odczytuje przesunięcie czasu, szerokość geograficzną, długość geograficzną, wysokość (znacznik ground wyklucza wpis), pola nic i nac_p obiektu szczegółów statku powietrznego oraz ciąg źródła pozycji (wpisy z innego źródła niż ADS-B są wykluczane). Wpis bez obiektu szczegółów nie ma pól dokładności i jest liczony jako wykluczony. Plik, którego nie da się odczytać, jest liczony w trace_files_unreadable w metadanych wyniku i pomijany.

AIS (kshana interference-map ais):

Kolumna Wymagana Znaczenie
timestamp tak czas raportu
vessel_id tak nieprzejrzysty identyfikator (haszowany, nigdy nie przechowywany)
lat, lon tak stopnie; wartości AIS „niedostępne” oraz (0, 0) są odrzucane
sog_kn nie prędkość nad dnem w węzłach; 102,3 (niedostępne) jest traktowane jako brak

Detektor lądu wymaga pliku wielokątów lądów (--land): GeoJSON Polygon lub MultiPolygon. Zamierzonym plikiem jest warstwa lądów Natural Earth w skali 1:10 miliona (domena publiczna). Bez --land detektor jest wyłączony i wynik o tym mówi. Aby ją pobrać (jedyny dostęp do sieci w tej funkcji):

kshana interference-map fetch-land --out ne_10m_land.geojson --allow-network

Uruchamia to systemowy curl (jako listę argumentów, nie przez powłokę) przez HTTPS, jednokrotnie, dla jednego pliku pod stałym adresem wskazującym pojedynczy commit repozytorium źródłowego. Pobrany plik jest zachowywany tylko wtedy, gdy jego SHA-256 jest równy wartości przypiętej w kodzie; niezgodność go usuwa i kończy się niepowodzeniem. Jeśli curl nie jest zainstalowany, polecenie to zgłasza i podaje adres oraz sumę kontrolną, aby plik można było pobrać ręcznie. Nic nie jest dołączone do repozytorium.

Wynik#

Jeden plik GeoJSON na źródło na dzień UTC, w katalogu --out, nazwany <source>-<dataset>-<YYYY-MM-DD>.geojson, gdzie <source> to adsb lub ais, <dataset> to klucz --dataset (adsb-lol, noaa-marinecadastre, kystverket lub custom), a data to dzień UTC raportów: adsb-adsb-lol-2026-03-01.geojson, ais-kystverket-2026-03-01.geojson. Zbiór danych jest w nazwie, aby dwa zbiory danych tego samego rodzaju nie mogły dzielić pliku, a Kshana nigdy nie nadpisuje pliku: jeśli istnieje którykolwiek cel, polecenie kończy się niepowodzeniem, zanim cokolwiek zapisze. CLI wypisuje jeden wiersz na każdy zapisany plik. Czytnik może odzyskać te trzy części za pomocą ^(adsb|ais)-(.+)-(\d{4}-\d{2}-\d{2})\.geojson$; ta sama informacja jest wewnątrz pliku (source_kind, data.dataset, date). Syntetyczne pliki próbek, po jednym na źródło, są w examples/interference-map/output/, wraz z poleceniem, które je odtwarza, do budowania i testowania przeglądarki. Element najwyższego poziomu kshana_interference_map zawiera nazwę schematu, datę, siatkę, identyfikator metody i każdy parametr, wartości dzienne, licencję danych i informację o autorstwie oraz zastrzeżenie. Każdy obiekt to wielokąt komórki z cell_i, cell_j, status, degraded i zagregowanymi liczbami.

Siatka jest stała: kwadratowe komórki o boku --cell-deg stopnia (domyślnie 0,5) w szerokości i długości geograficznej, indeksowane od (-90, -180). Szerokość wschód–zachód zmniejsza się wraz ze szerokością geograficzną: około 55 km na równiku i około 28 km na 60 stopniach dla wartości domyślnej. Szerokość 90 należy do ostatniego wiersza, a długość 180 to ten sam południk co -180. Metody zarejestrowane z góry są zdefiniowane na siatce 0,5 stopnia. Inna wartość --cell-deg działa, ale nie jest metodą zarejestrowaną z góry: CLI o tym informuje, a plik zapisuje grid.preregistered_cell_deg i grid.is_preregistered (false), aby przeglądarka też mogła to powiedzieć.

Wstrzymane liczby. Każda liczba na komórkę poniżej minimum publikacji (5) jest null, łącznie z zerem, więc null nigdy nie oznacza „brak” i żadna opublikowana liczba nie pozwala wskazać pojedynczego statku powietrznego ani jednostki pływającej. Pola status i degraded są nadal podawane. W plikach ADS-B aircraft_observed wynosi dla opublikowanej komórki zawsze co najmniej 5; aircraft_sampled i aircraft_affected są null poniżej 5, a affected_share jest null, chyba że obie wartości wynoszą co najmniej 5 (udział ujawniłby wstrzymaną liczbę). W plikach AIS każdy wpis vessels_flagged jest null poniżej 5.

Wersja formatu i pola#

Format jest ustalony jako schema: "kshana-interference-map/v1", format_version: 1. Zmiana, która usuwa lub zmienia nazwę pola albo zmienia jego znaczenie, podnosi wersję; dodanie pola jej nie podnosi, więc czytnik musi ignorować pola, których nie zna. Liczba równa null jest wstrzymana, a nie równa zeru.

FeatureCollection
  kshana_interference_map
    schema, format_version, kshana_version, notice
    source_kind            "adsb" | "ais"
    date                   "YYYY-MM-DD" (UTC)
    grid                   { type: "fixed_lat_lon", cell_deg, preregistered_cell_deg, is_preregistered }
    method                 { id, summary, parameters{...}, guards[], input_stats{...}, caveats[] }
    day                    day-level figures (ADS-B: background_evaluated, background_share,
                           day_confounded, cells_published, cells_suppressed_below_min_distinct;
                           AIS: on_land_detector, cells_published, cells_suppressed_...)
    data                   { dataset, name, licence, licence_url, attribution, coverage_notes[] }
  features[]               Polygon (one closed ring, [lon, lat], counter-clockwise)
    properties             cell_i, cell_j, status, degraded,
                           ADS-B: aircraft_observed, aircraft_sampled|null, aircraft_affected|null,
                                  affected_share|null
                           AIS:   vessels_observed, vessels_flagged{detector: n|null}, detectors[]

Wartości status: ADS-B degraded, not_degraded, insufficient_sample, withheld_day_confounded, withheld_no_background; AIS anomalous, not_anomalous. degraded ma wartość true tylko dla degraded i anomalous. Raport ekspozycji trasy ma własny schemat kshana-route-exposure/v1.

Obserwatorium: produkt dzienny#

kshana interference-map daily zamienia jeden dzień UTC raportów ADS-B w trzy pliki obserwatorium (GeoJSON, PNG i JSON raportu incydentu) oraz manifest skrótów, a kshana interference-map sensitivity odtwarza ten dzień przy zmianach po jednym z parametrów zarejestrowanych z góry. Polecenie wymusza reguły wydania: co najmniej 24 h po zakończeniu dnia (--delay-hours można tylko zwiększać), komórki 0,5 stopnia lub grubsze, tylko trzy stany (degraded, not_degraded, not_observed), brak przypisania przyczyny i brak danych OpenSky. Notatka o metodzie, formaty plików i ograniczenia są w observatory/METHOD.md. Przebieg regionalny (--bbox south,west,north,east) odczytuje tylko raporty z danego prostokąta i mówi o tym w pliku.

Specyfikacja strony mapy w Studio#

Dla strony mapy w Studio, która wczytuje plik GeoJSON podany przez użytkownika (strona jest budowana w źródłach Studio, a nie w tym repozytorium). Nic nie jest przesyłane: plik jest odczytywany w przeglądarce, a strona nie wysyła żadnych żądań do żadnego źródła danych.

Odczyt pliku. Przyjmij plik tylko wtedy, gdy kshana_interference_map.schema zaczyna się od kshana-interference-map/, a format_version jest liczbą obsługiwaną przez stronę; w przeciwnym razie zgłoś, że plik nie jest obsługiwaną mapą zakłóceń Kshana. Odczytaj pola wymienione wyżej; nieznane ignoruj. Plik zawiera jedno źródło i jeden dzień. Można wczytać kilka plików.

Komórki. Narysuj wielokąt każdego obiektu. Koloruj według status i zawsze wyjaśniaj w legendzie, co oznacza każdy kolor. Cztery stany, z których żadnego nie wolno ukrywać ani łączyć:

Stan Znaczenie Skąd się bierze
Z pogorszeniem (lub z anomalią dla AIS) wysoki odsetek statków powietrznych zgłosił niską dokładność albo jednostki pływające wykazały anomalie tego dnia degraded ma wartość true
Czysta zaobserwowana przy wystarczającej liczbie statków powietrznych lub jednostek pływających i nieoznaczona status to not_degraded lub not_anomalous
Nieoceniona zaobserwowana, ale za mało próbkowanych statków powietrznych, dzień był zakłócony przez czynniki zewnętrzne albo nie można było oszacować tła dnia status to insufficient_sample, withheld_day_confounded lub withheld_no_background
Nieobserwowana zbyt mało statków powietrznych lub jednostek pływających, więc komórka nie została opublikowana brak obiektu dla tej komórki

„Nieobserwowana” oznacza brak obiektu: rysuj ją neutralnie (bez wypełnienia lub z kreskowaniem), nigdy kolorem „czystej”. Użyj schematu kolorów, który nie opiera się wyłącznie na czerwieni wobec zieleni. Szczegóły komórki po najechaniu lub zaznaczeniu pokazują liczby z properties bez zmian, a każdą liczbę null jako „wstrzymana (mniej niż 5)”, nigdy jako zero. Przeglądarka powinna też zgłaszać, gdy grid.is_preregistered ma wartość false, że plik używa rozmiaru komórki spoza metody zarejestrowanej z góry.

Warstwy. ADS-B i AIS są oddzielnymi warstwami z własnymi przełącznikami, legendami i wierszami licencji. Nigdy nie łącz ich w jedno pole kolorów ani jedną liczbę, nigdy nie rysuj ich jako jednej połączonej komórki i nigdy nie sumuj ich komórek. Różne dni to różne pliki: pokazuj jeden dzień naraz, z wyborem dnia, zamiast nakładać dni.

Licencja i autorstwo. Dla każdej widocznej warstwy pokaż, na mapie oraz w każdym eksporcie lub zrzucie ekranu, tekst data.attribution dosłownie, data.licence z odnośnikiem do data.licence_url oraz data.coverage_notes. Jeśli pokazywana jest warstwa ADS-B, jej licencja ODbL dotyczy tylko tej warstwy. Nie oferuj eksportu pliku połączonego.

Metoda. Udostępnij identyfikator metody i parametry (method.id, method.parameters) oraz wartości day w panelu szczegółów, w tym day_confounded (powiedz wprost, że żadna komórka nie została uznana za pogorszoną z powodu tła dnia) oraz input_stats.

Zastrzeżenia do zachowania (pokaż własne method.caveats i notice pliku i utrzymuj to sformułowanie lub jego odpowiednik widoczne przy mapie):

  • Komórka z pogorszeniem lub anomalią nie jest stwierdzeniem zakłóceń. Istnieją inne przyczyny.
  • Komórka bez koloru nie była obserwowana. Nie jest to dowód, że obszar był czysty.
  • Jest to opis minionych raportów pozycji, a nie prognoza ani pomiar jakiegokolwiek odbiornika.
  • Pokrycie zależy od źródła danych; przeczytaj uwagi o pokryciu.

Strona nie może wymieniać ani pokazywać żadnego pojedynczego statku powietrznego ani jednostki pływającej, a pliki ich nie zawierają.

Ekspozycja trasy. Jeśli strona wczytuje także raport kshana-route-exposure/v1, pokaż jego wiersze dla każdego dnia i źródła razem z czterema udziałami (z pogorszeniem, czysta, nieoceniona, nieobserwowana), nigdy sam udział z pogorszeniem, oraz caveats raportu i map_licence i map_attribution każdego wiersza.

Obszar emitera (interference-map locate)#

kshana interference-map locate szacuje, gdzie może znajdować się źródło zakłóceń, na podstawie tych samych otwartych raportów ADS-B lub AIS: obszar na podanych poziomach ufności, centroid z elipsą niepewności oraz sesje w czasie. Nigdy nie zwraca gołego punktu. MODELLED (wiersz rejestru VM-bc70cb57): fizyka to podręcznikowa łączność radiowa w linii wzroku, wiarygodność obszarów zależy od modelu, a jedynym zewnętrznym sprawdzeniem jest porównanie z Jammertest zarejestrowane wstępnie w emitter-region/PREREGISTRATION.md. Publikowanie obszarów emiterów w publicznym obserwatorium jest osobną decyzją właściciela i jest wyłączone: obserwatorium nie czyta tego modułu, a test to przypina.

kshana interference-map locate input.csv --source adsb --dataset adsb-lol --out regions/
kshana interference-map locate day-dir/  --source adsb --dataset adsb-lol --out regions/     # readsb traces
kshana interference-map locate ais.csv   --source ais  --dataset kystverket --land land.geojson --out regions/

Opcje: --levels 0.5,0.9,0.95, --cell-km, --session-gap-min, --emitter-height-m min,max, --ship-height-m (AIS), --tdoa fix.json (połącz pozycję TDOA; poniżej). Każda opcja różniąca się od wartości zarejestrowanej wstępnie jest ogłaszana jako „not the pre-registered method”. Pliki nigdy nie są nadpisywane.

Model. Raporty są grupowane w jednostki (jeden statek powietrzny lub okręt w jednym 2-minutowym przedziale), z których każda jest dotknięta (ADS-B: co najmniej połowa jej raportów ma niskie NIC lub NACp według własnej reguły mapy; AIS: nieprawdopodobna prędkość lub skok albo pozycja w głębi lądu od linii brzegowej) albo nie. Statek powietrzny lub okręt liczy się tylko przy co najmniej 5 dobrych raportach w danych wejściowych (ta sama ochrona bazowa sprzętu co na mapie). Dotknięte jednostki są grupowane w sesje: przerwa dłuższa niż 30 minut dzieli w czasie, a w obrębie skupienia czasowego dwie jednostki należą do siebie, gdy jeden emiter mógłby być w zasięgu obu. Dla jednej sesji każda kandydująca pozycja na siatce otrzymuje wiarygodność:

  • Linia wzroku. Statek powietrzny na wysokości h i antena emitera na h_e widzą się nawzajem do 4.122 (sqrt h + sqrt h_e) km na promieniu 4/3 Ziemi. h_e jest marginalizowane w zakresie od 2 do 100 m (8 wartości rozmieszczonych logarytmicznie).
  • Moc. Moc emitera jest nieznana, więc zasięg ogranicza efektywny zasięg od 12 km do 426 km (kroki co 1,25) albo „tylko linia wzroku”, marginalizowane z równą wagą. Brzeg zasięgu jest miękki: jednostka liczy się jako będąca w zasięgu z wagą, która maleje liniowo na 15% zasięgu po każdej stronie (co najmniej trzy czwarte komórki siatki), ponieważ teren, charakterystyka anteny i tor nie są znane dokładniej.
  • Dotknięte i niedotknięte. Statek powietrzny lub okręt jest podatny z prawdopodobieństwem 0,6 (sprzęt odbiorczy, antena i tor sygnału się różnią), jednostka podatnego w zasięgu jest dotknięta z prawdopodobieństwem 0,9, a każda inna jednostka jest dotknięta z prawdopodobieństwem tła 0,03 (inne przyczyny). Podatność jest ukrytą właściwością statku powietrznego, sumowaną po statkach powietrznych, podobnie jak trwała usterka sprzętu (prawdopodobieństwo 0,03: wszystkie jednostki tego statku powietrznego są dotknięte, gdziekolwiek się znajduje), co powstrzymuje wadliwy transponder przed ciągnięciem obszaru. Tak więc dotknięty statek powietrzny przyciąga rozkład a posteriori ku pozycjom, które go obejmują, a niedotknięty statek powietrzny z linią wzroku odpycha od pozycji, które by go objęły, co najwyżej w wadze jednego statku powietrznego, niezależnie od liczby wysłanych raportów, podczas gdy niedotknięty statek powietrzny bez linii wzroku nic nie mówi.
  • Bez terenu. Teren, kanałowanie i dyfrakcja nie są modelowane (teren może tylko usunąć linię wzroku).
  • Wygładzanie. Logarytm wiarygodności jest mnożony przez 0,3 (rozkład a posteriori z potęgą). Dowody modelu są bardziej zależne, a jego brzegi mniej ostre niż niezależność zakładana przez wiarygodność, a na danych syntetycznych z tymi wadami niewygładzone obszary zawierały prawdziwe źródło znacznie rzadziej niż podany poziom; 0,3 wybrano wyłącznie na danych syntetycznych (wyprowadzenie jest w docs/emitter-region/PREREGISTRATION.md, sekcja 8).

Rozkład a posteriori daje obszary o najwyższej gęstości na podanych poziomach (zagnieżdżone; wielokąty z otworami tam, gdzie trzeba), centroid ważony rozkładem a posteriori i jego elipsę momentów (przeskalowaną do 95% przy rozkładzie Gaussa; skalibrowanymi poziomami są wielokąty, a nie elipsa). Siatka jest gruba (około 5 do 10 km) na całej dziedzinie, a każda gruba komórka zawierająca masę jest dzielona 4 na 4. Błąd pokrycia jest obsługiwany przez warunkowanie na tym, gdzie istnieją raporty: obszar jest szeroki tam, gdzie było mało statków powietrznych, a sesja, której obszar 95% wypełnia ponad 80% jej dziedziny poszukiwań, jest zgłaszana jako unconstrained bez centroidu.

Sesje i profil. Każda opublikowana sesja ma początek, koniec, czas trwania, obszar komórek 0,5 stopnia, które zawierają dotkniętą jednostkę i co najmniej 5 odrębnych statków powietrznych lub okrętów, liczby odrębnych dotkniętych i obserwowanych oraz dowód przeciwny (odrębne niedotknięte z linią wzroku do centroidu; wstrzymane poniżej 5). Sesja z mniej niż 5 odrębnych dotkniętych statków powietrznych lub okrętów jest wstrzymywana i liczona. Profil podaje, na godzinę UTC doby, odrębne dotknięte statki powietrzne (null poniżej 5) i minuty czasu sesji oraz godziny czasu sesji na dobę UTC.

Opcjonalne połączenie TDOA. --tdoa fix.json przyjmuje {"receivers": [[lat, lon, height_m], ...], "tdoa_s": [...], "sigma_s": 1e-7, "start": [lat, lon]} (co najmniej trzy odbiorniki; tdoa_s[i] to odbiornik i+1 minus odbiornik 0). Pozycja jest rozwiązywana na powierzchni Ziemi metodą Gaussa-Newtona na geolocation::tdoa_predict, jej kowariancja to geolocation::tdoa_crlb_on_sphere, a rozkład Gaussa jest mnożony do rozkładu a posteriori. Ograniczenie Craméra-Rao jest dolną granicą dla modelu, a nie zmierzoną dokładnością.

Wyniki (emitter-<source>-<dataset>-<day>): .geojson (obszar MultiPolygon na poziom i sesję, wielokąt elipsy, punkt centroidu niosący swoją elipsę), -summary.json, -sessions.csv, -figure.svg. Każdy zawiera licencję zbioru danych, adres URL licencji i atrybucję, identyfikator metody kshana-interference-map/emitter-region/v1, każdy parametr, założenia i ograniczenia oraz niesie swoją etykietę dowodową (poziom MODELLED, identyfikatory wierszy rejestru; pasek pod rysunkiem, wiersze # evidence w tabeli, element evidence w JSON). Pliki maszynowe są po angielsku niezależnie od języka; tekst rysunku i wiersze wiersza poleceń są lokalizowane. Przykład syntetyczny znajduje się w examples/emitter-region/ (regenerate.sh).

Prywatność i sformułowania. W żadnym wyniku nie pojawia się identyfikator statku powietrznego ani okrętu; nie rysuje się żadnej pozycji raportu; sesja wymaga co najmniej 5 odrębnych statków powietrznych lub okrętów; liczby poniżej 5 są null. Sformułowania są neutralne: „szacowany obszar emitera”, „obszar źródła zakłóceń”. Obszar nie jest pozycją niczyją, nie jest ustaleniem przyczyny i nic nie mówi o tym, kto lub co stoi za źródłem; rozszerzony test sformułowań sprawdza wyniki pod kątem słów o aktorach, zamiarze i konflikcie.

Ograniczenia. Wiarygodność zależy od modelu. Na danych syntetycznych (generator współdzielący model, z brzegami zasięgu niepewnymi o 15% na statek powietrzny, trwałymi usterkami sprzętu, nieznaną mocą i nieznaną wysokością anteny) obszar 95% zawierał prawdziwe źródło w 0,99 sesji (geometria statków powietrznych) i 1,00 (geometria okrętów), a obszar 50% w około 0,77: poziomy są zachowawcze, przez wykładnik wiarygodności 0,3, a błąd centroidu sesji ma medianę 23 km (statki powietrzne) i 12 km (okręty). Kalibrację sprawdzono tylko na danych syntetycznych; porównanie z Jammertest zostało zarejestrowane wstępnie (emitter-region/PREREGISTRATION.md) i uruchomione raz: NOT ASSESSABLE dla obu źródeł (emitter-region/RESULTS.md). Jedno źródło na sesję; kilka bliskich źródeł wygląda jak jedno. Przyczyna regionalna (awaria konstelacji, pogoda kosmiczna) daje obszar, który nie jest źródłem. ADS-B daje mało raportów poza ruchliwą przestrzenią powietrzną, a tylko około jedna czwarta punktów śladu readsb niesie NIC i NACp, więc rzadko pokryte obszary dają szerokie obszary lub ich brak (31% sesji geometrii okrętów było unconstrained).

Metoda ADS-B (kshana-interference-map/adsb/v2)#

Każdy raport ADS-B z powietrza zawiera dwa samoocenione pola jakości nawigacji: NIC (promień ograniczenia pozycji) i NACp (granica dokładności 95%, EPU). Gdy odbiornik na pokładzie traci lub przestaje ufać swojemu rozwiązaniu satelitarnemu, oba spadają, dlatego niosą sygnaturę zakłóceń. Spadają też z innych powodów.

Parametry zarejestrowane z góry (stałe w kodzie, zapisywane w każdym pliku; zmiana oznacza nową wersję metody):

Parametr Wartość
Dolna granica wysokości wysokość barometryczna co najmniej 5000 ft
Raport o niskiej dokładności NACp co najwyżej 6 (zgłoszona granica EPU wynosi 556 m, 0,3 NM, lub więcej, albo jest nieznana) lub NIC co najwyżej 5 (zgłoszona granica promienia ograniczenia wynosi 1852 m, 1 NM, lub więcej, albo jest nieznana)
Dobry raport NACp co najmniej 8 i NIC co najmniej 7; oceniane na podstawie pól, które ma wejście (oba, gdy oba są obecne, w przeciwnym razie to, które jest obecne)
Punkt odniesienia wyposażenia statek powietrzny liczy się w komórce tylko wtedy, gdy ma co najmniej 5 dobrych raportów poza tą komórką tego samego dnia
Statki powietrzne próbkowane w komórce co najmniej 3 raporty w komórce
Statki powietrzne dotknięte w komórce co najmniej 50% jego raportów w komórce ma niską dokładność
Minimalna próba co najmniej 10 próbkowanych statków powietrznych
Z pogorszeniem co najmniej 5 dotkniętych statków powietrznych, udział dotkniętych wśród próbkowanych statków powietrznych co najmniej 0,30 oraz co najmniej 0,15 powyżej mediany udziału w komórkach tego dnia
Dzień zakłócony przez czynniki zewnętrzne mediana udziału w komórkach (z co najmniej 5 komórek z pełną próbą) co najmniej 0,15: żadna komórka nie jest uznawana za pogorszoną
Brak tła mniej niż 5 komórek z pełną próbą, więc nie można oszacować mediany: komórka spełniająca progi jest withheld_no_background, a nie z pogorszeniem
Minimum publikacji zaobserwowano co najmniej 5 odrębnych statków powietrznych

Te wartości ustalono na podstawie definicji kodów NIC i NACp oraz reguły prywatności, zanim spojrzano na jakiekolwiek dane. Nie dostrajano ich na danych rzeczywistych, a testy używają wyłącznie danych syntetycznych. Statusy komórek: degraded, not_degraded, insufficient_sample (opublikowana, ale z mniej niż 10 próbkowanych statków powietrznych), withheld_day_confounded i withheld_no_background.

Wersja 2. Wersja 1 uznawała komórkę za pogorszoną już przy 3 dotkniętych statkach powietrznych, mniej niż minimum publikacji wynoszące 5 statków, i bez zgłaszania pomijała kontrolę tła dnia, gdy w pełni próbkowanych było mniej niż 5 komórek. Wersja 2 wymaga co najmniej 5 dotkniętych statków powietrznych i wstrzymuje ocenę (withheld_no_background), gdy tła nie można oszacować. Obie zmiany zaostrzają metodę (nic, co nie było pogorszone w wersji 1, nie jest pogorszone w wersji 2); powodem jest to, że opublikowana ocena nigdy nie może opierać się na mniejszej liczbie statków powietrznych niż liczba, poniżej której liczby są wstrzymywane. Pliki wersji 1 nie zostały wydane.

Dlaczego pola dokładności spadają z powodów innych niż zakłócenia i jakie jest zabezpieczenie dla każdego z nich:

Przyczyna Zabezpieczenie
Starsze transpondery, które nigdy nie zgłaszają NIC ani NACp albo zgłaszają je ze stałą niską wartością punkt odniesienia wyposażenia: statek powietrzny bez dobrych raportów gdzie indziej tego dnia nie jest liczony
Niska wysokość i operacje na powierzchni (maskowanie przez teren, inne formaty pozycji) dolna granica wysokości; wiersze oznaczone ground są wykluczone
MLAT lub inne pozycje spoza GNSS filtr source_type, gdy kolumna jest obecna
Jeden statek powietrzny wysyłający wiele raportów liczone są odrębne statki powietrzne, a nie raporty
Awaria konstelacji lub augmentacji albo zdarzenie pogody kosmicznej obniżające dokładność na dużym obszarze komórka musi przekroczyć medianę udziału w komórkach tego dnia o margines, a dzień, którego mediana jest sama wysoka, jest oznaczany jako zakłócony przez czynniki zewnętrzne i nie uznaje żadnej komórki
Usterka w wyposażeniu jednego statku powietrznego wymaga udziału wielu odrębnych statków powietrznych, z minimalną próbą
Mało statków powietrznych w komórce minimalna próba; przy zaobserwowanych poniżej 5 komórka nie jest publikowana

Co pozostaje: metoda nie odróżni zakłóceń od przyczyny regionalnej, która jest lokalna, a nie szeroka (lokalny efekt geometrii satelitów lub awaria naziemnej augmentacji wyglądałyby tak samo) i jest zachowawcza w jednym kierunku: statek powietrzny, który przez cały dzień lata wyłącznie wewnątrz dotkniętego regionu, nie ma punktu odniesienia i nie jest liczony, więc trwałe duże obszary są zaniżane w raportach.

Metoda AIS (kshana-interference-map/ais/v2)#

Dla każdej jednostki i dnia, pięć detektorów. Detektor kwalifikuje się w komórce, gdy oznacza co najmniej 5 odrębnych jednostek stanowiących co najmniej 20% jednostek tam zaobserwowanych; komórka jest anomalous, jeśli kwalifikuje się którykolwiek detektor.

Detektor Reguła (zarejestrowana z góry)
on_land co najmniej 3 raporty w komórce w odległości ponad 2000 m w głąb lądu od dostarczonej linii brzegowej
circle okno 20 kolejnych raportów (krok 10, przerwy co najwyżej 30 min), których średni promień od środka ciężkości wynosi od 500 m do 20 km, współczynnik zmienności promienia co najwyżej 0,15, jeden kierunek ruchu z łącznym skrętem co najmniej 270 stopni (kroki co najwyżej 90 stopni, wypadkowy co najmniej 80% sumy) i średnia prędkość co najmniej 2 kn
implausible_jump co najmniej 2 skoki docierające do komórki: kolejne raporty oddalone od siebie o co najmniej 1000 m, w odstępie co najwyżej 1 h, wskazujące na ponad 70 kn (prędkość pośrednia używa co najmniej 1 s między raportami, więc dwa raporty z tym samym znacznikiem czasu i pozycjami oddalonymi o 1 km lub więcej liczą się jako skok)
implausible_speed co najmniej 3 zgłoszone prędkości powyżej 70 kn w komórce
same_position co najmniej 5 odrębnych jednostek zgłaszających tę samą pozycję (zaokrągloną do 1e-4 stopnia, około 11 m) w tym samym 10-minutowym oknie

Komórki z mniej niż 5 odrębnych jednostek nie są publikowane; każda liczba oznaczonych jednostek poniżej 5, łącznie z zerem, jest podawana jako null.

Wersja 2. Wersja 1 kwalifikowała detektor od 3 oznaczonych jednostek i publikowała liczby 3 i 4. Wersja 2 podnosi minimum oznaczonych jednostek do 5, czyli do minimum publikacji, tak aby ocena anomalous nigdy nie opierała się na mniejszej liczbie jednostek niż liczba, poniżej której liczby są wstrzymywane. Zaostrza to metodę i żaden plik wersji 1 nie został wydany.

Znane przyczyny fałszywych alarmów, które reguła udziału i progi ograniczają, ale nie usuwają: jednostki w rzekach, kanałach i portach blisko zgrubnej linii brzegowej (bufor 2 km w głąb lądu istnieje właśnie z tego powodu); dwie jednostki dzielące jeden identyfikator, co wygląda jak skoki; transpondery ze złą pozycją lub sprzęt testowy; oraz krążenie łodzi pilotowych i jednostek poszukiwawczych, które może przypominać okręgi. Plik linii brzegowej w skali 1:10 milionów jest dokładny do około kilometra.

Detektory skoków i prędkości porównują raporty w obrębie jednego pliku wejściowego; ślad podzielony na pliki lub dni nie jest zszywany.

Pamięć. Wejście jest czytane wiersz po wierszu i nigdy nie jest przechowywane w całości. ADS-B zachowuje tylko liczniki dla statku powietrznego i komórki. AIS zachowuje każdy przyjęty raport w zwartym rekordzie (około 40 bajtów), dopóki jego dzień nie zostanie oceniony, więc zużycie pamięci rośnie wraz z liczbą raportów AIS na wejściu; bardzo duże wejście AIS podziel według dni.

Ekspozycja trasy#

kshana route-exposure --route route.geojson --map out/ [--map other/] \
    [--from 2026-03-01] [--to 2026-03-07] [--out report.json] [--json]

--route to GeoJSON LineString (samodzielny, w Feature lub w FeatureCollection) albo CSV z wierszami lat,lon. --map przyjmuje pliki map lub ich katalogi i można go powtarzać. Punkty trasy są łączone liniami prostymi w szerokości i długości geograficznej, więc zagęszczaj długie odcinki; odcinek biegnie krótszą drogą wokół w długości geograficznej, więc odcinek przekraczający antypołudnik (179,5 E do 179,5 W) go przekracza. Trasa jest dzielona na fragmenty po około 250 m. Każdy fragment jest mierzony między własnymi dwoma końcami na sferze o promieniu 6371,0088 km (tą samą ścieżką, która rozstrzyga, w której komórce leży) i przypisywany komórce zawierającej jego środek.

Dla każdego dnia i źródła raport podaje długość trasy i cztery udziały sumujące się do 1: share_degraded, share_not_degraded, share_unassessed (komórka obecna, ale bez oceny) i share_not_observed (komórka nieobecna na mapie). Dwa ostatnie czytaj razem z pierwszym: trasa z niskim udziałem z pogorszeniem i wysokim udziałem nieobserwowanym nie została wykazana jako czysta. Wiersze ADS-B i AIS są podawane osobno i nigdy nie są łączone. Każdy wiersz zawiera licencję i informację o autorstwie mapy.

Funkcje biblioteki#

Dla wywołujących, którzy trzymają dane w pamięci (powiązania, serwer MCP, kompilacja przeglądarkowa), moduł kshana::interference_map::api udostępnia te same metody z tekstem lub bajtami na wejściu i JSON na wyjściu, bez dotykania pliku ani sieci:

Funkcja Wejście Wyjście
adsb_maps_from_csv(csv, &DatasetSpec, cell_deg) tekst CSV ADS-B Vec<DayMap>
adsb_maps_from_readsb_traces(&[&[u8]], &DatasetSpec, cell_deg) jeden wycinek bajtów na plik śladu readsb (gzip lub zwykły) Vec<DayMap>
ais_maps_from_csv(csv, &DatasetSpec, cell_deg, Option<&str>) tekst CSV AIS, opcjonalny tekst GeoJSON lądów Vec<DayMap>
route_exposure(route_text, &[&str], from, to) tekst trasy, teksty GeoJSON map, opcjonalne granice YYYY-MM-DD JSON kshana-route-exposure/v1

DayMap ma file_name (<source>-<dataset>-<date>.geojson), date i geojson (dokument v1). DatasetSpec to Preset("adsb-lol" | "noaa-marinecadastre" | "kystverket") lub Custom { licence, licence_url, attribution }; DEFAULT_CELL_DEG wynosi 0,5. Błędy to MapError. Reguły zbioru danych (zatwierdzone ustawienia predefiniowane, wymagany tekst licencji, zgodność rodzaju) obowiązują dokładnie tak jak w wierszu poleceń.

Walidacja zewnętrzna#

tests/interference_map_reference.rs porównuje Kshana z niezależnymi implementacjami na wejściach syntetycznych, z tolerancjami zarejestrowanymi z góry w tests/fixtures/interference_map_ref/PREREGISTRATION.md: znaczenia kodów NIC i NACp względem dekodowania syntetycznych ramek ADS-B przez pyModeS, wartości „niedostępne” AIS względem dekodowania syntetycznych zdań AIVDM przez pyais, przypisanie do komórek siatki względem shapely, długość trasy w każdym stanie komórki względem shapely i GeographicLib oraz maskowanie lądu względem shapely i pyproj. Dane testowe są tworzone przez scripts/gen_interference_map_ref.py; CI nie potrzebuje Pythona. Waliduje to sposób odczytu kodów i wartości pól oraz geometrię. Nie waliduje, że oznaczona komórka oznacza zakłócenia.

Testy#

Wszystkie testy używają syntetycznie generowanych danych i nie korzystają z sieci: testy jednostkowe w src/interference_map/ oraz tests/interference_map_cli.rs dla poleceń od początku do końca, w tym sprawdzenie, że żaden identyfikator nie trafia do wyniku i że odmowy nie zostawiają żadnych plików.