David Koňařík
Student MFF UK
Autor JrUtil, softwarového projektu na zpracovávání dat veřejné dopravy, a spousty žádostí o informace.
https://dvdkon.gitlab.io
dvdkon@konarici.cz
Zpracování dat o reálném provozu vlaků.
Vlak Os 10455 dne 2022-08-20
Zastávka | prav.příj. | příjezd | prav.odj. | odjezd |
---|---|---|---|---|
P.-Velká Chuchle z | 13:44 | 13:43 | 13:44 | 13:44 |
Odb Závodiště | 13:45 | 13:45 | 13:45 | 13:45 |
Odb Barrandov | 13:47 | 13:48 | 13:47 | 13:48 |
Pr.-Smíchov již.zhl. | 13:50 | 13:49 | 13:50 | 13:49 |
Praha-Smíchov | 13:53 | 13:51 | 13:54 | 13:54 |
Pr.-Smíchov sev.zhl. | 13:55 | 13:55 | 13:55 | 13:55 |
Výh Praha-Vyšehrad | 13:57 | 13:57 | 13:57 | 13:57 |
Praha hl.n. | 14:01 | 14:01 | ||
Skoro kompletní data za zhruba poslední rok (1. 8. 2021–2022).
16 897 čísel vlaků, 2 718 257 jízd ~7 000 000 celkem minut zpoždění v koncové zastávce, ~900 000 minut náskoku, ~140 sekund průměrné zpoždění (včetně náskoků), 0 minut medián zpoždění.
-- Počet čísel vlaků
SELECT COUNT(*) FROM (SELECT DISTINCT tripid FROM tripdetails) AS i;
-- Počet jízd
SELECT COUNT(*) FROM tripdetails;
CREATE TEMPORARY TABLE final_delays AS (
SELECT DISTINCT ON (tripid, tripstartdate)
tripid, tripstartdate, arrivedat - shouldarriveat AS delay
FROM stophistory AS sh
WHERE arrivedat IS NOT NULL
ORDER BY tripid, tripstartdate, tripstopindex DESC);
-- Součet zpoždění (pro náskok jen otočit nerovnost)
SELECT EXTRACT(epoch FROM SUM(delay))/60
FROM final_delays WHERE delay > '0';
-- Průměrné zpoždění
SELECT EXTRACT(epoch FROM AVG(delay))
FROM final_delays;
-- Medián zpoždění
SELECT EXTRACT(epoch FROM percentile_cont(0.5) within group (order by delay))
FROM final_delays;
1 135 čísel vlaků, 87 107 jízd ~1 1000 000 celkem minut zpoždění v koncové zastávce, ~37 000 minut náskoku, ~740 sekund průměrné zpoždění (včetně náskoků), 5 minut medián zpoždení.
CREATE TEMPORARY TABLE final_delays_longdistance AS (
SELECT * FROM final_delays WHERE tripid ~ '-CZTRAINT-(EC|IC|Ex|SC|rj|LE|RJ)-.*');
SELECT COUNT(DISTINCT tripid) FROM final_delays_longdistance;
SELECT COUNT(*) FROM final_delays_longdistance;
SELECT EXTRACT(epoch FROM SUM(delay))/60
FROM final_delays_longdistance WHERE delay > '0';
SELECT EXTRACT(epoch FROM AVG(delay))
FROM final_delays_longdistance;
SELECT EXTRACT(epoch FROM percentile_cont(0.5) within group (order by delay))
FROM final_delays_longdistance;
Vlak | Den | Zastávka | Zpoždění | Poznámka |
---|---|---|---|---|
Ex 11986 | 2022-02-28 | Mosty u Jablunkova | 19:11:00 | Špatný JŘ? |
Ex 43774 | 2022-02-28 | Mosty u Jablunkova | 19:11:00 | Nedojel, špatný JŘ? |
R 1122 RegioJet | 2022-04-29 | Bohumín os.n. | 19:00:00 | Jediný záznam |
Os 18301 | 2022-06-10 | Kralupy nad Vltavou | 14:20:00 | Jediný záznam |
Os 7906 | 2022-02-17 | Březnice | 14:07:00 | Nedojel |
Ex 566 Západní expres | 2022-02-17 | Plzeň hl.n.os.n. | 13:16:00 | Nedojel |
Os 5055 | 2022-03-01 | Choceň | 13:14:00 | Jediný záznam |
Os 21247 | 2022-01-08 | Včelnička | 12:56:00 | Špatný JŘ? |
-- Nejzpožděnější vlaky
SELECT CONCAT('[', shortname, '](https://rt.jr.ggu.cz/Trip/', tripid, '/', tripstartdate ,')'), tripstartdate, name, delay
FROM (
SELECT DISTINCT ON (i.tripid, i.tripstartdate) td.shortname, s.name, i.tripid, i.tripstartdate, delay
FROM (
SELECT GREATEST(COALESCE(departedat - shoulddepartat, '0'), COALESCE(arrivedat - shoulddepartat, '0')) AS delay, *
FROM stophistory
ORDER BY delay DESC
LIMIT 100) AS i
LEFT JOIN stops AS s ON s.id = i.stopid AND s.validdaterange @> i.tripstartdate
LEFT JOIN tripdetails AS td ON td.tripid = i.tripid AND td.tripstartdate = i.tripstartdate
ORDER BY i.tripid, i.tripstartdate, delay DESC) AS i2
ORDER BY delay DESC;
Vlaky, které dojely a měly na odjezdu z výchozí stanice max. 5h zpoždění.
Vlak | Den | Zastávka | Zpoždění |
---|---|---|---|
Os 13857 | 2021-09-13 | Litovel | 09:23:00 |
R 607 Krušnohor | 2022-02-17 | Odb Dubina | 07:45:00 |
Os 96005 | 2021-10-20 | Šakvice | 07:39:00 |
SC 506 Pendolino | 2022-02-17 | Praha hl.n. | 07:38:00 |
R 705 Vltava | 2022-02-17 | Č.Buděj. býv. st.7 | 07:10:00 |
Os 6058 | 2022-01-16 | M.Boleslav m. předn. | 07:00:00 |
Os 21241 | 2021-12-26 | hi JH-Skrýchov JHMD | 06:56:00 |
SELECT CONCAT('[', shortname, '](https://rt.jr.ggu.cz/Trip/', tripid, '/', tripstartdate ,')'), tripstartdate, name, delay
FROM (
SELECT DISTINCT ON (i.tripid, i.tripstartdate) td.shortname, i.tripstartdate, s.name, i.delay, i.tripid
FROM (
SELECT GREATEST(COALESCE(departedat - shoulddepartat, '0'), COALESCE(arrivedat - shoulddepartat, '0')) AS delay, *
FROM stophistory AS sh
ORDER BY delay DESC
LIMIT 1000) AS i
LEFT JOIN stops AS s ON s.id = i.stopid AND s.validdaterange @> i.tripstartdate
LEFT JOIN tripdetails AS td ON td.tripid = i.tripid AND td.tripstartdate = i.tripstartdate
ORDER BY i.tripid, i.tripstartdate, delay DESC) AS i2
WHERE (SELECT arrivedat
FROM stophistory AS sh2
WHERE sh2.tripid = i2.tripid AND sh2.tripstartdate = i2.tripstartdate
ORDER BY tripstopindex DESC LIMIT 1) IS NOT NULL
AND (SELECT departedat - shoulddepartat
FROM stophistory AS sh2
WHERE sh2.tripid = i2.tripid AND sh2.tripstartdate = i2.tripstartdate
AND tripstopindex = 1) < '5 hours'
ORDER BY delay DESC;
Specificky zpoždění v sekundách v poslední zaznamenané stanici.
Skript delay_histogram.py
Skript stop_histogram.py
.
Počítá “změnu zpoždění”, tedy zpoždění na odjezdu - na příjezdu.
Skript route_histogram.py
.
Z QGISu
Čas od času opravdu divné vlaky, například:
A taky chyby sbírání dat, nejčastěji špatně určené datum.
Vesměs hrubě promazáno.
CREATE TEMPORARY TABLE stophistory_large_change AS
SELECT * FROM
(SELECT
tripid, tripstartdate, tripstopindex,
shouldarriveat - LAG(shouldarriveat, 1) OVER w AS sarr_change,
arrivedat - LAG(arrivedat, 1) OVER w AS arr_change,
shoulddepartat - LAG(shoulddepartat, 1) OVER w AS sdep_change,
departedat - LAG(departedat, 1) OVER w AS dep_change
FROM stophistory
WINDOW w AS (PARTITION BY tripid, tripstartdate ORDER BY tripstopindex ASC)) AS i
WHERE COALESCE(sarr_change > '12 hours' OR sarr_change < '-12 hours', FALSE)
OR COALESCE(arr_change > '12 hours' OR arr_change < '-12 hours', FALSE)
OR COALESCE(sdep_change > '12 hours' OR sdep_change < '-12 hours', FALSE)
OR COALESCE(dep_change > '12 hours' OR dep_change < '-12 hours', FALSE);
CREATE TEMPORARY TABLE stophistory_large_delay AS
SELECT * FROM
(SELECT
tripid, tripstartdate, tripstopindex,
arrivedat - shouldarriveat AS arrdelay,
departedat - shoulddepartat AS depdelay
FROM stophistory) AS i
WHERE COALESCE(arrdelay > '20 hours' OR arrdelay < '-1 hour', FALSE)
OR COALESCE(depdelay > '20 hours' OR depdelay < '-1 hour', FALSE);
DELETE FROM stophistory AS sh
WHERE EXISTS (SELECT FROM stophistory_large_change AS shc
WHERE shc.tripid = sh.tripid
AND shc.tripstartdate = sh.tripstartdate)
OR EXISTS (SELECT FROM stophistory_large_delay AS shd
WHERE shd.tripid = sh.tripid
AND shd.tripstartdate = sh.tripstartdate);
RtCollect, součást JrUtil, periodicky scrapuje všechny vlaky v GRAPPu.
CSV API RtCollect: https://rt.jr.ggu.cz/api.html
prosím opatrně, streamování nemusí fungovat, dotazy raději po
měsících.
Většina vlaků v seznamu zůstane i desítky minut po příjezdu, přeshraniční ne.
Existuje i SOAP rozhraní, ale…
Podle zákona 106/1999 Sb. jsem SŽ žádal o několik věcí:
Žádost: “Aktuální polohy … ve strojově čitelném formátu formou on-line přístupu”
Odpovědi:
Žádost: historické polohy vlaků
Odpověď:
Vlakové JŘ jsou už zveřejňovány
pořádně a úplně.
Včetně kolejí a nástupišť!
Linkové JŘ už ne: Nejprve nic, pak XLS, nyní osekané “skoro-JDF”.
CHAPS odmítá zákonnou povinnost, Ministerstvo buď odkazuje na ně, nebo popírá existenci úplných dat.
Není všem dnům konec: čekám na vyřízení stížnosti.
Data jsou k dispozici, těším se na vaše využití!
Po OpenAltu zveřejním kód na https://dvdkon.gitlab.io/openalt-2022-vlaky
Fórum o datech veřejné dopravy: https://dadof.konarici.cz
Všechny svoje další projekty/data budu oznamovat zde.
V této prezentaci jsou čas od času poznámky, které zobrazíte
stisknutím
Toto je poznámka!