Tl;dr

Napravio sam sajt za prikaz svih biciklističkih staza i traka u gradovima Srbije: https://projekti.openstreetmap.rs/bikepaths. Sajt prikazuje statistiku dužine staza (u km) i nudi mogućnosti da se highlight-uju staze po tipu podloge i po osvetljenosti.

Nadam se da ovakva karta može da poveća svest o tome koliko staza imamo, tj. nemamo, i da pomogne biciklistima da imaju neki pregled gde je moguće ići bajsom, a gde ne. Takođe, voleo bih da ove rupe u podacima koje imamo (podloga i osvetljenost) budu bolje uočljivije preko ovog sajta, pa možda se neko iscima i popuni preostale podatke o biciklističkim stazama zbog njega😀.

Bici staze?

Poslednjih par godina sam pokušavao da popravim sve biciklističke staze po Beogradu, a naročito Novom Beogradu. Obiđem tu i tamo postojeće staze da vidim stanje, a ucrtam novu stazu kada je vidim. Dok sam to radio, uvek sam mislio kako bi bilo dobro imati kartu svih tih biciklističkih staza na jednom mestu. OK, ima nekih stilova karte koji pokazuju bici staze, kao što su CyclOSM stil ili Cycle Map stil, ali oni prikazuju i Eurovelo rute, i mesta za popravku/iznajmljivanje bajseva, pa samim tim nemaju baš jak fokus na biciklističke staze ili biciklističke trake u jednom gradu. A i od kada sam napravio vektorsku kartu Srbije, svrbelo me je da je isprobam na nekom konkretnom primeru. Sad sam se konačno nakanio da napravim ovako nešto!

Tehnikalije

Preprocessing

Zapravo – bilo je lakše nego što sam mislio. Podatke sam uzeo iz Overpass-a. Jedino što sam dodatno radio je pomeranje bici traka da budu na desnoj strani ulice. Tehničkim rečnikom, uradio sam offset na LineString-ovima nekih 3m udesno. Tako sad biciklističke trake na karti deluju da su uz ivicu ulice. I to je bilo sve od masiranja podataka, samo sam izvadio i statistike. Ako nekog zanima, ovo su osnovni podaci:

Grad
Bici staza (km)Bici traka (km)
Beograd
156.2624.6
Novi Sad179.74.6
Niš23.710

Prvo sam uradio Beograd, ali mi se onda uključio programerski mozak koji je krenuo da mi šapuće na uvo “ovo može da se apstrahuje, grad – to je samo parametar” i onda sam uradio i za Novi Sad i za Niš. Međutim, možda sam se zeznuo jer iskreno nema mnogo bici staza van Beograda i Novog Sada. Da li ih fizički nema ili samo nisu ucrtani u OSM – meh, verovatno je od oba.

Pošto ne znam da pišem HTML ni JS, najlakše mi je bilo da u preprocessingu izgenerišem HTML, po jedan za svaki grad.

Na kraju sam napravio bash skriptu koja pokrene preprocessing, izgeneriše HTML-ove i upload-uje ih sve na server. Ceo izvorni kôd je ovde.

Frontend

Dodavanje GeoJSON sloja na vektorsku kartu nije bilo mnogo teško, ali sam udario u neke stvari koje Maplibre ne može da izvuče. Mislim, Maplibre je sjajna JS biblioteka, ali ne može baš sve. Npr. ako imamo LineString, nemoguće je duplirati je i uraditi offset na obe strane puta (npr. kada imamo bici traku sa obe strane ulice, kao u Crnotravskoj). Takođe, offset LineString-a pravi neke čudne blurry mrlje na određenim zumovima i nije moguće koristiti ga (ja sam odustao). To je i bio razlog zašto sam offset bici traka radio u preprocessing-u u Pythonu. Evo kako izgledaju ti artefakti:

Drugi problem na koji sam udario je da sam hteo da za bici staze koristim punu liniju, a za bici trake isprekidanu. To kao može, postoji parametar “line-dasharray“, a takođe postoji koncept dinamičkih izraza (gde može da se kaže – “ako GeoJSON element ima svojstvo X, prikaži ga drugom bojom” ili sl.). I taman sam se naoštrio da iskoristim “case” funkciju i da napravim da bici staze budu pune, a bici trake isprekidane, kad prc – dinamički izrazi baš ne rade u kombinaciji sa “line-dasharray” parametrom ne rade. Kontam da su to sve stvari koje će da se isprave kad-tad, ali deluje sve nekako krhko (kao i ostatak JS ekosistema). Zbog toga sam morao da razdvojim bici staze i bici trake u posebne GeoJSON fajlove i da ih oba posebno učitavam i prikazujem kao odvojene slojeve. Treći problem je što Maplibre ne podržava da LineString može da ima outline koji je širi od 1px. Naime, hteo sam da podebljam highlight-ovane linije, ali Maplibre može samo da ima outline širine 1px. Zvanični workaround je da se napravi novi sloj sa istim podacima ispod prvog sloja i širom debljinom linija. Na kraju je to ispalo ovako nekako, sa sve dva sloja:

Tačnije, imam na kraju 4 sloja – 2 za šire linije koje uključujem i isključujem dinamički i 2 za bici staze i trake.

Interesantno je pomenuti i da je običan rasterski rendering ispao bolji kada pričamo o handle-ovanju nivoima. Npr. uporedite kako izgleda staza ispod mosta na Adi u CyclOSM stilu i kod mene:

Verovatno je do mene samo, i sigurno može da se napravi da se bici staze zavlače ispod puteva i u vektorskoj karti. Međutim, delovalo mi je kao previše posla za istrpeti mali slučaj OCD sindroma – bio sam spreman da to istrpim😀.

Zaključak

Bila mi je ovo lepa vežbica, da isprobam kako izgleda biti korisnik vektorskih karti i Maplibre biblioteke. Zadovoljan sam kako sam brzo izgenerisao sve, i dalje sam očajan koliko je teško uraditi najprostije stvari u HTML-u i koliko sam duduk za CSS i ostalo, ali sam zadovoljan rezultatom. Podelio sam na par biciklističkih grupa, ali niko se ne javlja (ni da hvali, ni da kudi). Ko zna, možda ovo nije neko postignuće, niti izaziva “wow” efekat, ili prosto nikoga ovo ne zanima. Nije ni bitno, meni je bilo lepo napraviti moj san koji sam srećan sanjao sam dok sam vozio bajs i mapirao po Novom Beogradu😀.

Evo na kraju još jednom trenutna slika Beograda (klik za veću verziju) – ili bolje prosto otidite na sajt: