Analiza 9.2 je za kvalitet vazduha koristila CAMS preko Open-Meteo, ćeliju od ~11 km. Poređen sa zvaničnom mernom stanicom na istim danima, CAMS daje PM2.5 1,58×, PM10 1,98× i NO₂ 4,05× niže od izmerenog, a za NO₂ na dnevnom nivou praktično nema veštinu (r = 0,29). Brojevi na stranici bili su zato pogrešni, a najgore u pravcu koji umiruje. Zamenjeni su validiranim časovnim merenjima tri stanice, od kojih jedna stoji 288 m od staze. Uz to je dodata raspodela NO₂ po deonicama, ukotvljena u izmerenu razliku između stanica, i noise_air.py je razdvojen na buka.py i vazduh.py.
Odakle podaci: EEA, jer SEPA nije dostupna
Domaći izvori su probani prvi i ne rade: sepa.gov.rs, amskv.sepa.gov.rs i data.sepa.gov.rs ne odgovaraju (HTTP 000). OpenAQ v3 traži API ključ. Stari EEA CSV servis AQData_Extract.fmw je ugašen (HTTP 401). Ono što radi jeste novi EEA download servis: Srbija je među 39 zemalja koje izveštavaju, pa se isti SEPA podaci dohvataju bez ključa i bez registracije.
- Metapodaci —
discomap.eea.europa.eu/map/fme/metadata/PanEuropean_metadata.csv, 26 MB, tab-separated. Nosi koordinate, tip stanice (traffic/background/industrial), tip okruženja (urban/rural) i spisak polutanata po mernom mestu. Srbija ima 35 stanica.
- Merenja —
POST /ParquetFile/urls na eeadmz1-downloads-api-appservice.azurewebsites.net vraća javne Azure blob URL-ove, jedan parquet po mernom mestu. dataset: 2 su validirani podaci (E1a); nevalidirani skorašnji (1) se ne koriste. Šifre polutanata su iz EIONET rečnika: 5 = PM10, 8 = NO₂, 6001 = PM2.5.
Kolone u parquet-u: Start, End, Value, Validity, Verification, AggType. Uzimaju se samo redovi sa Validity == 1. Dnevni prosek traži bar 18 validnih sati, godina traži bar 300 takvih dana — inače ne ulazi u izlaz. Saobraćajna stanica ima 105.191 validan časovni zapis za NO₂, od 1. januara 2013.
Tri stanice, tri uloge
Od 35 srpskih stanica, tri su u krugu od 15 km od ose koridora. Rastojanje se meri do najbliže tačke ose, ne do centra grada:
- RS0033A — urban background, 288 m od staze. Reprezentativna: svi nivoi na stranici dolaze odavde. Pozadinski tip je ovde tačan izbor jer kej nije ulica.
- RS0030A — urban traffic, 1.054 m. Služi samo za razliku prema pozadinskoj, koja daje veličinu saobraćajnog doprinosa.
- RS0005R — rural background, 8.848 m severno. Daje regionalni član — koliko zagađenja ima i pre ulaska u Niš.
Sledeća po redu je 56 km daleko, pa nema dileme oko izbora.
Zašto se ne interpolira između stanica, iako je to bio predlog
Predlog je bio da se napravi prostorni indikator sa težinama po relevantnosti stanica, pa da se dobije procena po deonicama. To ne radi: dve urbane stanice su međusobno udaljene 400 m i obe su kod centra koridora. Interpolacija između njih preko 13 km trase ne bi izvlačila prostornu informaciju — ta informacija u podacima ne postoji — nego bi oblikovala gradijent koji je artefakt toga gde su stanice postavljene. To je ista greška zbog koje buka nije u decibelima, samo obrnuta: prave jedinice, izmišljena geografija.
Ono što par stanica jeste izmerio je razlika između dve lokacije. Ona se koristi kao veličina, a raspodela duž trase dolazi iz modela blizine puteva:
C(tačka) = C_regionalno + C_urbano + k · P(tačka)
Regionalni član je izmeren na ruralnoj stanici, urbani je ostatak na pozadinskoj posle oduzimanja regionalnog i saobraćajnog dela, a k je ukotvljeno tako da razlika P između dve stanice reprodukuje izmerenu razliku koncentracija. Modelirana je samo raspodela; dva od tri člana su merenja.
Jezgro opadanja nije isto kao za zvuk
Model deli iste segmente puteva sa buka.py, ali ne i fiziku. Zvuk od linijskog izvora pada sa 1/d² po tačkastom doprinosu; NO₂ uz put pada približno eksponencijalno, sa karakterističnom dužinom od 50–150 m u gradskim uslovima. Uzeto je L = 60 m, svesno na donjoj granici: brže opadanje daje manju razliku između deonica, pa se efekat izbora staze pre potceni nego preceni. Poluprečnik je 400 m (exp(−400/60) ≈ 0,001), segmenti se dele na emitere na svakih 10 m, a bbox za Overpass pokriva i stanice, ne samo osu — bez puteva oko stanica nema sidra.
Dobijeno: P = 127,3 kod saobraćajne i 45,7 kod pozadinske stanice, ΔP = 81,6. Ako ΔP ne bi bilo pozitivno, sidro ne bi važilo i raspodela bi se preskočila — to je provereno u kodu, ne pretpostavljeno.
Greška koju su podaci otkrili: sidro mora da bude letnje
Prva verzija je uzela godišnju razliku saobraćajne i pozadinske stanice: +2,8 µg/m³ NO₂. Provera mesečnog hoda pokazala je zašto je to pogrešno. Pozadinska stanica u januaru ima 41,7 µg/m³ NO₂, a saobraćajna 25,2 — pozadinska je zimi prljavija od saobraćajne. Razlog je da stoji u naselju sa individualnim grejanjem; saobraćajna stanica ima gotovo ravan godišnji hod (25,2 u januaru, 21,3 u junu), jer saobraćaj ne poznaje sezonu.
Godišnja razlika između te dve stanice dakle meša saobraćaj sa dimnjacima i potcenjuje saobraćajni deo. U toploj polovini godine grejanja nema, pa razlika ostaje ono što tvrdimo da jeste — blizina puta. Za maj–septembar ona iznosi +9,6 µg/m³, tri i po puta više. Sidro, urbani i regionalni član sada se svi računaju iz istog, toplog perioda; mešanje sezonskog sidra sa godišnjim nivoom dalo bi broj koji ne opisuje nijedan stvarni period.
Isti test diskvalifikuje čestice kao pokazatelj saobraćaja. Letnja razlika saobraćajne i pozadinske stanice je +3,6 za PM2.5 i −3,7 za PM10 — negativna. Godišnje su te razlike +8,7 i +3,6, sa vrhom u 16–20 h, što je grejanje a ne špic. Zato se po deonicama prikazuje samo NO₂, a ključevi u izlazu se zovu saobracajna_minus_pozadina, ne „saobraćajni doprinos": ime govori šta je izmereno, tumačenje dolazi posle.
Periodi se ne smeju mešati
NO₂ postoji od 2013, PM2.5 tek od 2024. Bez pravila bi se na istoj stranici poredio trinaestogodišnji prosek sa dvogodišnjim. Glavni brojevi se zato računaju iz poslednje tri godine koje sve stanice za taj polutant imaju: NO₂ 2023–2025, PM2.5 i PM10 2024–2025. Cela istorija po godinama ostaje u izlazu, za grafikon prekoračenja.
Šta je ispalo
| Polutant | Stanica | CAMS | Odnos | r |
| PM2.5 | 24,7 | 15,6 | 1,58× | 0,72 |
| PM10 | 36,7 | 18,6 | 1,98× | 0,65 |
| NO₂ | 22,8 | 5,6 | 4,05× | 0,29 |
Vrednosti su µg/m³ na reprezentativnoj stanici i u CAMS-u na istim danima; r je Pirsonova korelacija dnevnih vrednosti.
Za čestice CAMS pogađa oblik krive (r ≈ 0,7) ali ne nivo — korisan je i dalje za sezonski hod polena, koji stanice ne mere. Za NO₂ je ćelija od 11 km jednostavno preširoka da vidi grad: r = 0,29 znači da dnevna vrednost iz modela ne nosi informaciju o dnevnoj vrednosti na stanici. Stranica je do sada tvrdila da NO₂ prelazi dnevnu smernicu SZO u 0,1 % dana; izmereno je 28 % na pozadinskoj i 45 % na saobraćajnoj stanici.
Zakonski deo je najoštriji. Granična vrednost za PM10 je 50 µg/m³ kao dnevni prosek, uz dopuštenih 35 prekoračenja godišnje. Saobraćajna stanica ih ima u svakoj od devet godina sa dovoljno merenja, od 53 (2013) do 106 (2020); 2025. je 103, uz godišnji prosek 44,4 — i preko godišnje granice od 40. Pozadinska stanica, ona kod keja, ima 81 i 72 dana u dve godine koje meri.
Raspodela po deonicama (NO₂, maj–septembar, µg/m³): Niška Banja i Brzi Brod 8,8–9,3, Medoševac 9,5–11,7, Delta–Lidl 11,0–11,5, Centar 14,5–15,5. Donji bedem je dosledno najčistiji, u Medoševcu za 19 % u odnosu na gornji. Ali raspon između najčistije i najizloženije tačke je 6,7 µg/m³, dok 9,1 nosi grad podjednako svuda — izbor staze menja malo, grejna sezona menja sve.
Podela modula i sitnice
noise_air.py je preimenovan u buka.py i iz njega je izbačen ceo blok o vazduhu; data/noise_air.json je sada data/buka.json, schema podignuta na 2. Ime je počelo da laže čim je vazduh dobio sopstvenu prostornu logiku.
vazduh.py uvozi samo standardnu biblioteku, koridor.py i buka.py — namerno bez numpy. Razlog: pyarrow nema wheel za Python 3.14 koji projekat koristi (ni duckdb ga nema), pa se taj korak vrti kroz uv run --python 3.13 --with pyarrow, a izolovano okruženje tako ne mora ništa više da instalira. make vazduh sam bira uv ako postoji.
- Isprekidana linija smernice na mesečnom grafikonu nikada nije radila: vrednost je prosleđivana kao
--szo: 26%, pa je calc(dužina × procenat) nevalidan i linija je padala na dno okvira. Vrednost je sada bezdimenziona. Ista greška bi se ponovila na novom grafikonu po godinama.
- Grafikon prekoračenja iscrtava ceo raspon godina, sa praznim mestima gde merenja nema. Prva verzija je preskakala 2015, 2016, 2018 i 2019 i izgledala kao neprekidan niz.
- Mapa stanica isključuje ruralnu iz okvira (8,8 km je dovoljno da se koridor svede na crticu) i crta isprekidan potez od svake stanice do najbliže tačke trase — to je odgovor na pitanje zašto baš ta stanica.
Terenski materijali
izbor_tacaka.py sada, pored GPX-a i CSV-a, pravi i obrazac.html za štampu (A4 landscape, svih 18 tačaka na jednom listu, uputstvo na poleđini) i data/merne_tacke.json da se tačke vide na mapi u analizi. PDF se pravi kroz Puppeteer, ne kroz PDF biblioteku: obrazac ima dijakritike (č, ć, š, ž, đ), a lake PDF biblioteke za njih traže ručno ugrađen font, dok pregledač to već ume — a usput isti HTML može i da se odštampa direktno.
U zaglavlju su dva QR koda, ka GPX-u i CSV-u na sajtu, generisana kao inline SVG (qrcode, ERROR_CORRECT_M, zona tišine 2 modula). Provereni su modul po modul: obrazac je rasterizovan na 300 dpi i svih 1.369 modula oba koda poređeno sa očekivanom matricom — nula odstupanja, veličina modula 0,63 mm.
CSV je dobio kolone podloga i klupe, koje ne služe buci nego analizi 9.3. Tip podloge nam nedostaje jer ga OpenStreetMap za staze uz Nišavu skoro ne beleži, a klupe su osnov za „mesta predaha". Pošto se ionako prelazi 13 km, beleže se usput.
Šta i dalje nije rešeno
Nijedna stanica ne stoji na keju — najbliža je 288 m i to je rečeno na stranici. Razlika između gornjeg i donjeg bedema u NO₂ izvedena je iz istog modela blizine puteva, pa nosi njegove pretpostavke, ne nezavisnu proveru. Žarišta zagađenja i dalje se ne prikazuju: za njih bi trebalo merenje duž same trase, a ne ekstrapolacija sa dve gradske stanice.