Přehled obcí, které nabízejí veřejnosti otevřená geodata

Praha dnes otevřela spoustu geodat pod otevřenou licencí CC BY-SA. Můžete si stáhnout například mapu všech budov včetně jejich výšek (nad mořem i nad povrchem), digitální modely terénu nebo ortofotomapy s vysokým rozlišením. Praze a Institutu Plánování a Rozvoje za tento čin patří naše velké uznání a věříme, že další města a obce budou následovat.

Při této příležitosti jsme připravili komplexní přehled obcí, které geodata nabízejí (včetně odkazu na jejich databázi) a které si naopak data nechávají pro sebe. Seznam budeme průběžně aktualizovat.
Continue reading

Seznam odtahů / odlovenou zvěř / diagnózy klientů vám nedáme. Prostě to neumíme

Autor: Jan Boček

Před měsícem jsme se zeptali BKOMu – důležité brněnské akciovky a správce místních komunikací – kolik aut, kdy a odkud odtáhla při blokovém čištění. Odpověď “sory, náš systém to neumí vyexportovat, za to my nemůžem a dejte pokoj” jsme od různých úřadů slyšeli tolikrát, že už stojí za to hodit je na blog. A samozřejmě napovědět, jak data z úřadů nakonec vydolovat. Continue reading

Tech: Na pozadí komunálních voleb

V samizdatím nepravidelníku Tech se budu příležitostně rozepisovat o zajímavých technických řešeních, která obstála (nebo naopak velkolepě selhala) v nově vznikajícím odvětví novinářského programování. První díl se bude věnovat technickému řešení realtimové volební aplikace, kterou jsme tvořili pro webové zpravodajství Českého rozhlasu.

Právě proběhlé komunální a senátní volby pro mě byly druhou příležitostí, jak národu co nejrychleji sdělit výsledky demokracie – minule to byly podstatně sledovanější parlametní volby, kde se nám obevila vcelku slušná řada chyb, neočekávaných situací a všeobecného chaosu. Je mi potěšením psát, že tentokrát byl průběh znatelně klidnější.

Zatímco minule byly kromě backendového “processoru” výsledků již jen generické “frontendy” bez bližšího zaměření, tentokrát byla architektura pestřejší. Backend přepočítávající výsledky z ČSÚ byl jediný, který víceméně zůstal, pouze se pochopitelně upravily algoritmy pro komunální a senátní volby. Oddělil se z něj však Redis master server, na který jsme tentokrát použili dedikovanou Redis Cache v rámci Azure portfolia. Původní frontend se pak rozdělil na tři díly – hlavní server samizdat.cz sloužil jako poskytovatel statického obsahu a jako reverzní proxy + SSL terminátor pro server realtime updatů, dále běžel samotný server realtime updatů a jako poskytovatele všech výsledkových souborů jsme zvolili Azure Blob Storage.

Backend vytvářel po jednom souboru pro každou obec (přes 6000 unikátních, každou minutu se měnících necachovatelných souborů) a dále jeden s celkovými výsledky senátních a jeden komunálních voleb (příklady JSONů: obec, výsledky komunálek, senátu). Ty pak uploadoval do Storage, a po úspěšném uploadu dal přes Redis pub/sub vědět RT updateru, že se daný resultset změnil. A zatímco backend i nějakou verzi CDNky s výsledky měla snad všechna média (snad jen s rozdílem přepočítávání průběžných výsledků na mandáty), u nás se k tomu celému přidal právě realtime update server, o kterém bude většina následujícího povídání. Díky němu jsme mohli na připomínky redakce “na iDnesu to vychází jinak” odpovídat pyšným “protože jsou dvě minuty za námi“.

Socket.io: Dobrý, ale…

Zásadní změnou oproti minule bylo opuštění technologie WebSockets, zvláště pak knihovny Socket.io. Sockety jsou skvělé pro obousměrnou komunikaci, umí přenášet binárku a zvláště Socket.io je se svými fallbacky výtečná technologie např. pro hry, ale pro volby se příliš nehodí. Sockety v jejich režii totiž mají vcelku majestátní overhead a rozumné maximum bylo kolem 1000 spojení na server (dedikované jádro a 1.5GB RAM, žádné ořezávátko) přičemž o trablích s horizontálním škálováním jsem psal už před rokem. Navíc minule jsem udělal tu chybu, že jsem sockety prakticky nahradil HTTP, které tehdy sloužilo pouze k dodání statických assetů – všechny dynamické výsledky se tahaly až v nadstavbových spojeních.

Letos jsme tedy místo WS použili Server Sent Events (SSE), které jsou jednodušší, nevyžadují složitý handshake, dají se snáze škálovat a fungují na čístém HTTP protokolu. Zjednodušeně řečeno se vlastně jedná o svérázně formátovaný chunked transfer. I díky tomu mají přes párkilobajtové polyfilly podporu i u prohlížečů, které je nenabízí nativně (jedinou významnou výjimkou jsou staré Androidí browsery). Nadto umí nativně gzip kompresi, reconnect včetně advertisingu poslední přijaté zprávy a hlavně jejich serverovou implementaci lze pochopit a upravovat za pět minut. Samozřejmě, není to zadarmo – narozdíl od WS umí komunikovat pouze jednosměrně, od serveru ke klientovi, upstream (z pohledu klienta) je třeba řešit out-of-band. Pro volební aplikaci, kde uživatel neposílá příkazy, které by měnily stav serveru, jsou však ideální.

K dalšímu snížení zátěže na realtime server přispělo rozložení odpovědnosti na několik serverů a na klienta. Minule se klienti po připojení k serveru přihlašovali ke konkrétním informačním kanálům (celkové výsledky, výsledky za konkrétní kraj, okres, obec) a server při updatu některého kanálu ze svého výkonu vybral přihlášené adresáty a jim pak poslal všechna požadovaná data. To znamenalo, že si server musel držet v paměti všechny kanály (a obcí máme přes 6000) a jejich adresáty, případně při každém updatu projít tisíce příhlášených klientů a vyfiltrovat pouze relevantní, což opět přispělo k velké náročnosti loňské aplikace.

Tentokrát jsme místo toho z RT serveru distribuovali všem klientům pouze identifikátor změněného zdroje. Pokud se tedy updatovaly výsledky obce Adamov, rozeslala se tato informace všem přihlášeným klientům a na nich bylo zvážit, zda je vůbec Adamov zajímá (tj. uživatel má obec otevřenou v detailním pohledu) a pokud ano, tak si z Storage serveru stáhnout aktualizované výsledky. Tím jsme sice přidali cca 2-3 RTT latence, to se ale na většině připojení přetaví do méně než 1s zpoždění, což je u volebních výsledků akceptovatelné.

Binárka v UTF

Datové požadavky na toto řešení byly minimální díky formátu přenášených dat – nepřenášeli jsme IDčka v plaintextu (např. 581291 pro Adamov), ale místo toho jsme využili faktu, že uživatel má kvůli našeptávači a detekci nejbližších obcí v detailu již stažený seznam všech obcí. Mohli jsme se tedy udkazovat na index pole (0 pro první Adamov, 1 pro následující Adršpach apod.) a tento pak přenášet svým způsobem binárně. JavaScript a UTF-8 totiž poskytují univerzální built-in podporu pro de facto binární transfery nezáporných celých čísel mezi serverem a klientem – stačí na serveru vytvořit character přes String.fromCharCode(ord) a na klientovi ho číst přes string.charCodeAt(index). Bez jediné řádky programování navíc tedy je možné přenášet hodnoty menší než 127 v 1 Bajtu, 128-1023 v 2B a větší než 1024 v 3B.

Na serveru ještě fungovala sekundová agregace, pokud se tedy během vteřiny updatovaly obce Adamov i Adršpach, posílaly se ID 0 a 1 v jedné zprávě, které opět díky UTF “binárce” mohly být encodovány bez oddělovače – klientský JS nás od variabilní délky prefixované binárky odstíní a druhou obec vždy najdeme na charCodeAt(1).

Přes tyto optimalizace jsem na rozdíl od minule architekturu navrhoval tak, aby realtime updater byl zcela separátním modulem, v případě jehož selhání aplikace spadla do režimu pravidelného refreshování požadovaných zdrojů. To by sice snížilo celkovou efektivitu služby (refreshovaly by se většinou ještě stále aktuální obce), Azure Blob Storage má ale SLA kapacitu 20 000 requestů/s, my jsme ve špičce využili cca 100. Zdroje tedy byly, jen by to stálo trochu víc.

V praxi k překvapení mému i kolegů tato architektura opravdu funovala, jak měla. Realtime updaty klientům docházely, na jejich základě si stahovali nová data, celé se to krásně hýbalo. Backend tedy proběhl neobvykle klidně, o to veselejší byla práce na frontendu. Jak se kolegové několikrát vyjádřili, komunálky jsou volby s nejhorším poměrem cena/výkon. Parlamentní i prezidentské volby se volí do jedné instituce, s jedněmi výsledky, které navíc jdou vcelku slušně agregovat. Komunálky se ale děli na obecní, dále na volby do zastupitelstev městských částí a obvodů a nad to se ještě volí do senátu, to však pouze v některých okrscích. Toto jsem tentokrát o to hruběji podcenil, výsledkem bylo, že aplikace byla ke spuštění připravena v 13:53 (sčítat se začínalo v 14:00), nejnutnější úpravy probíhaly do 14:49 a drobnější detaily se ladily do noci. Postupující frustraci dobře ilustruje následující výpis změn z verzovacího systému Git (čas postupoval odspodu nahoru):

git log z těsně předvolebního času

git log z těsně předvolebního času

Nakonec však vše dobře dopadlo a vyšel i můj vedlejší experiment s tím, že jsme byli jediný kryptograficky důvěryhodný zdroj volebních zpráv (jako jediní jsme všechny informace posílali přes zabezpečené https připojení). A právě o tom, proč je důležité, aby zabezpečené připojení použivaly i jiné instituce než vaše banka (a konkrétně proč by zrovna média měla tento trend vést) bude přístí příspěvek.

A v duchu datového novinářství se rozloučím pár grafy z provozu:

Vytížení procesoru na SSL terminátoru a statickém hostingu (fialově), realtime updateru pro cca 1200 klientů (zeleně) a procesor XMLek (modře).

Vytížení procesoru na SSL terminátoru a statickém hostingu (fialově), realtime updateru pro cca 1200 klientů (zeleně) a procesor XMLek (modře).

Redis jsme použili i jako cache průběžných výsledků, agregátor po obcích (sloučení výsledků obcí/magistrátů a městských částí) a detektor, zda se v obci stala změna. Šlo na něj tedy cca 100 requestů za sekundu…

Redis jsme použili i jako cache průběžných výsledků, agregátor po obcích (sloučení výsledků obcí/magistrátů a městských částí) a detektor, zda se v obci stala změna. Šlo na něj tedy cca 100 requestů za sekundu…

…což ho moc nevytížilo

…což ho moc nevytížilo

Vytížení Blob Storage

Vytížení Blob Storage. Před polednem je vidět plnění “prázdnými” daty pro každou obec

 

Brněnská politika: Kdo s kým hlasoval v zastupitelstvu?

Jan Boček

Kdo s kým vstoupí po volbách do koalice? Stoprocentně to samozřejmě vědět nemůžeme, ale data z minulého zastupitelstva můžou naznačit. Podívejte se, které strany a kteří zastupitelé hlasovaly a hlasovali v uplynulých čtyřech letech společně. 

V polovině června jsem na magistrátním webu objevil seznam všech hlasování zastupitelstva. Jsou lehce skrytá a pokud v nich chcete něco najít, tak nenajdete. Ze zvědavosti jsem poprosil Jabloně, jestli by mi je pomohl postahovat, a za týden jsem měl krásnou tabulku s kompletním hlasováním každého zastupitele za poslední dvě volební období. Tady je. Jupí.

Jupí. Jenže co teď s tím.

Vzpomněl jsem si na výbornou analýzu hlasování pražského zastupitelstva Josefa Šlerky i novější analýzu parlamentního hlasování Kamila Gregora. Od Kamila jsem si půjčil statistickou metodu nominate, která z dat o hlasování vytvoří dvojrozměrnou mapu. Z blízkosti jednotlivých zastupitelů na ploše je vidět, kdo s kým. Mapa vztahů pak umožňuje třeba ukázat prstem na budoucí přeběhlíky, popsat vztah dvou stran nebo odhalit pnutí mezi dvěma zastupiteli uvnitř jedné strany. Pokud jsou k dispozici data za delší dobu, dokáže divy – třeba ukázat rostoucí ideologickou vzdálenost obou stran v americkém senátu. (Kdyby si podobnou analýzu chtěl někdo zkusit, návod najdete pod čarou na konci textu.)

Funguje to kupodivu i pro brněnské zastupitelstvo. Nejprve se podívejte na výsledky za téměř celé uplynulé období (10/2010 až 5/2014). Všechno se zdá být, jak má. Vlevo se drží koalice ODS (modrá) s ČSSD (žlutá), vpravo zastupitelé čtyř opozičních stran: KDU-ČSL (žlutozelená), KSČM (červená), TOP 09 (světle modrá) a Strany zelených (zelená). Za nepřesné barvy se omlouvám, do voleb už je bohužel nestihnu napravit.

Jakmile se ale podíváte na jednotlivá kratší období, začnou se vynořovat zajímavé detaily. V prvním období, kdy se pozice stran teprve formovala, jsou koalici poměrně blízko komunisti. Je to zřejmě i tím, že komunistická zastupitelka Sýkorová získala – tradičně – křeslo předsedkyně kontrolního výboru. Koalici zase ohraničují čtyři pilíře ODS: Šťástka, Hos, letošní primátorský kandidát Vižďa a jeho předchůdce Kotzian.

Na jaře 2011 dochází k zajímavé změně: komunisty nahrazují na pozici mostu mezi koalicí a opozicí lidovci, nejblíž koalici je Suchý. Stojí také za to sledovat tmavozelenou tečku Levíčka, komplikovaného šéfa TOP 09.

O pár měsíců později už Levíček hlasuje s koalicí, navíc tak daleko od své strany, jak to jen jde. Zajímavé je, že v tomhle období jde stále o předsedu brněnské TOP 09 a jejího zastupitele. KDU-ČSL je stále nerozhodná.

Další dva roky se toho moc neděje, s výjimkou Levíčkova bloumání po grafu od koalice k opozici a zase zpátky. Skočíme tedy na konec spolehlivých dat, do prosince 2013. Levíček, zdá se, zakotvil v ODS. Oproti tomu dvě další zastupitelky za TOP 09, o kterých už víme, že zanedlouho změní kabát, stále hlasují se svou původní stranou. Levíček nakonec ještě jednou změnil barvu a v letošních volbách kandiduje spolu s Matonohovou za Starosty a nezávislé; Vítková za A co Brno.

A ještě jedna poznámka na závěr: KDU-ČSL i v posledním období představuje poměrně rozptýlenou stranu, kde trio Suchý-Beran-Crha tíhne ke koalici, zatímco Rychnovský s Ivičičovou k opozici. Tenhle obrázek se ostatně opakuje po většinu volebního období. Ani v dalším období, pro které ovšem nemám dost dat, by se zřejmě lidovci s koalicí drželi blízko – v této době koalici pomáhali prohlasovat Amazon.

Pěkné je, že brněnskou politiku v posledním období ohraničuje z jedné strany bývalý předseda dopravní komise Novotný z ČSSD, z druhé strany ostře zelený Vlašín.

Teď si to celé můžete prohlédnout v pohybu. Kliknutím na tečku si zobrazíte její jméno. Pokud nechcete, aby zanechávala stopu, odklikněte tlačítko Trails vpravo dole. Dole na časové ose vidíte přibližné datum.

A teď dokonce se zvukem a humorem! (Záznam ze zářijové Pecha Kucha.)

Pokud vás podrobněji zajímají přesuny mezi brněnskými stranami, podívejte se na mapu přeběhlíků, kterou jsme vytvořili pro Český rozhlas.


Pro kutily: statistická metoda, která slouží k vytvoření mapy hlasování, se jmenuje nominate a patřičná knihovna pro R je wnominate. Poběží vám sice jen ve starší verzi R, ale v RStudiu není problém mít nainstalovaných verzí hned několik. Pokud vám stačí statické grafy, vystačíte si s Rkem a balíčkem wnominate. Pro dynamický graf nechejte wnominate spočítat souřadnice, ty zkopírujte do Google Docs a vytvořte pohyblivý graf podle vzoru. Je potřeba, aby každý analyzovaný úsek obsahoval nejméně 200 (ale spíš 300) hlasování, jinak bude výsledkem chaos.