Az biztos, hogy a végén rányomtak pl. egy zipet, de előtte is elég komoly tömörítést kellet, hogy alkalmazzanak, akár "kézzel" (nem beépített eszközök segítségével).
De ha már a stops táblánál járunk, akkor érdemes megjegyezni, hogy ők az azonos nevű megállókat mind összevonták, ami viszont néhol gondokhoz vezet.
Mindenesetre én egy 5 MB alatti tömörített és 20 MB alatti tömörítetlen adatbázissal elégedett lennék, ami szerintem elérhető csak a menetidők letárolásával. A további optimalizáció (legalábbis nekem) aránytalanul sok munkát igényelne (ugyanúgy az adatok tömörítése, mint a tömörített adatokkal való későbbi dolgozás), a funkcionalitásból meg nem akarok engedni.
De egyszerűen nem értem, hogy hogy lehet 360KB az egész adatbázis. Egy Varchar az a hosszának megfelelően L + 1 byte helyet foglal, ahol L a karakterlánc hossza. A Stops táblában ahol a megállók adatai vannak 5573 rekord van nálam jelenleg. Ha átlagban mondjuk 15 karakterrel számolunk megállónévnél, akkor 89 168 byte helyet foglal, így már ezzel el is megy a negyede szóval nem tudom hogy oldották meg. Lehet valamilyen módon tömörítve van az adatbázis, sőt biztos :)
De a "visszafejtett" kódban is találni ilyesmiket hogy GZIPInputStream, úgyhogy valamilyen tömörítés ott tuti van.
A calendarnál a rekordok számának csökkentésével lehet a legtöbbet nyerni, nekem a friss adatbázisban 74 rekord lett az eredmény, pedig még így is vannak duplikátumok.
Egyébként, hogy kis kontextust adjak, nekem a 67 MB-os adatbázisból 57 MB a stop_times és 9 MB a trips. Ha a stop_times-tól meg lehetne szabadulni (mondjuk csak a menetidők tárolásával), az jó eredmény lenne. :)
Meg egy kis statisztika: összesen 145 megállóban különbözik az érkezési és indulási időpont.
A mobilos alkalmazásfejlesztéshez érdemben nem tudok hozzászólni, de van egy-két lehetőség, amivel csökkenteni lehet az adatbázis méretét. Nem fogok sok újdonságot mondani, inkább csak összefoglalok néhány dolgot.
Stop_times tábla: néhány kivételtől eltekintve az arrival_time és a departure_time azonos, az érkezési idő kidobható. Ezenkívül a stop_sequence is redundáns olyan értelemben, hogy a trip_id-n belül időben rendezve megvan a megállók sorrendje, feltéve, hogy egyik járat sem megy vissza az időben. :-) A shape_dist_traveled meg az alkalmazás jellegétől függően lehet, hogy fölösleges.
A többi táblában elérhető helymegtakarítás ehhez képest elenyésző méretű, de azért összefoglalom azokat is.
Calendar: 1250 rekordból 1242 esetben (az általam letöltött, nem a legfrissebb verzióban) hétfőtől-csütörtökig azonosak a bejegyzések, tehát egyforma a menetrend, elég lehet egy mező (ezzel spóroltunk 157 byte-ot :-) )
Routes: a route_desc szövegmezőnek nincs valós adattartalma, csak kiegészítő információ, a végállomások a menetrendből is kikövetkeztethetők.
Trips: a trip_headsign szövegmező redundáns, erről is tegnap beszélgettünk.
Egyelőre androidra tervezem először az alkalmazást, de még az androidos telefonomat sem vettem meg... Az app előtt viszont csinálok prototípust.
A 70 MB az azonosítók intekre konvertálásával sikerült, de mobilra ez a méret még mindig sok lesz. A menetidő alapú tömörítés viszont nem rossz ötlet, azzal további jelentős méretcsökkenést lehet elérni. SQLite-ra konvertálással viszont szerintem nőni fog a méret a változó mezőhosszak miatt (bár igazából a keresés gyorsasága miatt aggódom, még soha nem használtam SQLite-ot).
Az androidos GTFS appról most olvastam, hogy maga a program 40 kB, és eredetileg a teljes csomag 400 kB volt, tehát a kettő különbözete az adatbázis. Ez elég szép teljesítmény.
A GTFS szerintem jó, csak nem az a célja, amit mi csinálunk vele. Útvonaltervezésre van kitalálva, és arra jól működik. Meg persze ez egy köztes, szabványos(!) formátum, ezúton válik lehetővé, hogy egyáltalán valahogy eljussanak hozzánk a menetrendi infók. A legjobban én azt hiányolom belőle, hogy nincsenek feltüntetve az alacsonypadlós járatok, pedig erre már létezik egy nagyjából elfogadott szabvány kiegészítés.
Az érdekes az lesz egyébként, amikor majd a real time adatok elérhetővé válnak.
MySQL-ben 70MB-nál úgy tartasz hogy módosítottál rajta gondolom. Ha SQLite-ra átdobot az adatbázist, még többet fogsz tudni faragni a méretén. Az Androidos alkalmazást (már ha egyről beszélünk) néztem én is és csodálkozok hogy 500KB az egész app mérete. Csak emulátoron néztem mivel ilyen készülékem nincs, memóriából 20Mb-ot eszik, szóval valamilyen módon tuti hogy tömörítve van az adatbázis.
Milyen platformra tervezed az alkalmazás kiadását? Mert én például a Windows Phone 7-es platformban gondolkozok, az alkalmazás maga már teljesen kész, még az adatbázison dolgozok.
A GTFS-ről viszont az a véleményem hogy több vele a nyűg mint amennyi hasznot hoz. Bármerre nézek, mindenhol csak arról olvasni, hogy "én így módosítottam az egészet hogy használható legyen". De legalább így a BKK-tól is kapunk hivatalos adatbázist amivel dolgozhatunk.
Nekem is mobilalkalmazás készítése van a terveimben, csak egyelőre nincs rá időm (viszont a GTFS-ben rejlő lehetőségek már nagyon izgattak, ezért csináltam meg az adatbázis részét).
A tömörítésen már én is gondolkodtam. Eleve a GTFS adatbázis formátum alkalmatlan menetrendek hatékony tárolására, ezért módosítottam a sémán (lásd a GTFS adatokból dolgozó Android alkalmazást, ami néhány járat esetében szinte egyáltalán nem működik). A másik pedig, hogy a GTFS egy köztes formátum, jó adatmegosztásra, de keresésre/tárolásra már nem hatékony pl. a rengeteg string miatt. Én eddig MySQL-t használtam, SQLite-ra még nem próbáltam portolni, de MySQL-ben 70 MB-nál járok (ebből 60 MB a stop_times).
Azt tudom, hogy van amelyiknek a menetrendje napszakonként változik. Mobiltelefonos alkalmazáson dolgozok, ami magában tárolja az adatbázist, tehát egy offline menetrendről van szó. Ezáltal szeretném a lehető legkisebb méretben hozzácsapni az adatbázist a programhoz anélkül, hogy veszítenék a tartalomból. A stoptimes táblában sikerült is redukálnom az adatmennyiséget, a menetidőkből pedig minden útvonalhoz kettőt csináltam volna (oda vissza 1-1), ahogyan a BKV oldalán is található.
Egyelőre még gondolkozok, hogyan is valósíthatnám meg ezt az egészet. A legnagyobb probléma tényleg az adatbázis méretével van, egy 200 megabyte méretű állományt nem sokan szeretnének letölteni és tárolni a telefonjukon :D
Amúgy azzal szenvedek, hogy a járatoknak a menetidejét kiszedjem valahogy. Mindegyiknek egyszer legyen meg a teljes útvonal menetideje.
Ez nem teljesen egyértelmű feladat, mert a járatok menetideje napszakonként változhat.
Egyébként csak hogy a saját munkámat reklámozzam :), az adatbázisomban minden egyes tripnél szerepel az indulási és érkezési időpont, ez talán segíthet valamit. Meg szerepelnek benne szeparáltan a különböző útvonalak is, így könnyebb lehet azok közül kiválasztani a teljes útvonalat az adott irányban.
Bontott útvonalak: ez engem is bosszant, még nem jöttem rá, mi a haszna.
A bontott útvonalak szerintem azért vannak így, mert eleve a BKV adatbázisában így vannak benne az időkiegyenlítő pontok miatt. Ahogy láttam, az időkiegyenlítők pontoknál a munkalapokon is új sor kezdődik.
trip_headsign: Ennek más közlekedési szolgáltatóknál valószínűleg több haszna van, a BKV-nál gondolom azért rakták bele (annak ellenére, hogy opcionális), hogy a Google Mapsen jobban nézzen ki valami. Bár ennek ellentmond, hogy mindig csak a következő időkiegyenlítő pont neve szerepel itt, ami elég megtévesztő lehet (lásd pl. hogy a Deák térről induló 47-49-eseknél Móricz Zsigmond körtér szerepel végállomásként).
Általánosságban szerintem az mondható el, hogy az egész formátum útvonaltervezésre van szabva, menetrend generálására korlátozottan alkalmas (persze jobb, mint a semmi).
Ha hiányzik az első megálló, az vagy azt jelenti, hogy az a járat a második megállónál indul, vagy azt hogy az adatbázis hibás. Azzal viszont semmi gond nincs, hogy több részre vannak törve az egyes indulások.
Egyébként itt egy lista, ahol nem 0-val kezdődik a shape_dist_traveled (előfordulhat, hogy a lista nem teljes, bár nem valószínű; a zárójelben az induló érték van):
H5: Békásmegyer 2. vg. -> Budapest, Batthyány tér 3.vágány M (573) H5: Békásmegyer 2. vg. -> Budapest, Batthyány tér 2.vágány M (573)
H5: Békásmegyer 2. vg. -> Budapest, Batthyány tér 1.vágány M (573) 28V: Teleki László tér -> Blaha Lujza tér M (Népszínház utca) (855) 1: Puskás Ferenc Stadion M -> Fiumei út (237) 3: Epreserdő utca -> Mexikói út M (463) 24: Haller utca (Soroksári út) -> Ferencváros vasútállomás (221) 99: Besence utca -> Blaha Lujza tér M (Népszínház utca) (358) 28A: Kőbányai út 21. -> Új köztemető (Kozma utca) (371) 996A: Erzsébet utca -> Cinkotai autóbuszgarázs (331) 6V: Széna tér -> Móricz Zsigmond körtér (Karinthy Fr.út) (177) 6V: Széna tér -> Blaha Lujza tér M (177) 66: Schenker főbejárat -> MNB (611) 66E: Schenker főbejárat -> MNB (611) H7: Vágóhíd H -> II. Rákóczi Ferenc út (1526)
Az, hogy ezt menengedi-e a szabvány, szerintem kérdéses. A szabvány csak azt mondja, hogy ennek a mezőnek a járathoz rendelt alakzat relatív helyét kell jelölnie, tehát nem mondja meg kifejezetten, hogy 0-val kell kezdődnie. De ha nem 0-val kezdődik, akkor az azt jelenti, hogy a járat útvonalán van egy olyan rész a térképen, ami fel van tüntetve, de ahol a jármű nem szállít utasokat, aminek nincs sok értelme. Egyébként ha megnézitek 6470-es route_id-jű tripeket, akkor lehet látni, hogy ott trip_headsignként "Békásmegyer, fordítóvágányok" szerepel, és így is van feltüntetve a Google Maps-en.
Na még egy rendszertelenség, ami miatt úgy tűnik ezt tényleg nem fogom tudni megoldani, van olyan útvonal ahol az első megálló a kiinduló állomás, van ahol viszont a kiinduló állomás az hiányzik, azt nem rakják bele, a második állomással kezdődik a lista. Ilyen például a H7-es (HÉV) pótló járat A8374413-as Trip-je.
Amúgy azzal szenvedek, hogy a járatoknak a menetidejét kiszedjem valahogy. Mindegyiknek egyszer legyen meg a teljes útvonal menetideje.
Tényleg, úgy tűnik, a békási HÉV szerelvényeket a kihúzóból kezdték mérni, így az első utasforgalmi megállóig már megtesznek 573 métert. Bár ez meg soknak tűnik, lehet, hogy a jobb vágányon lepakolástól a bal vágányra beállásig ennyi a távolság.
Ugyanakkor néhány reggeli és esti járat mégis nulláról indul. Lehet, hogy ezek a reggeliek megállás nélkül jönnek a kocsiszínből Békásmegyerig, az estiek meg mondjuk egyből beállnak a bal vágányra? (Nem vagyok nagyon ismerős arrafelé.)
Villamosoknál viszont akkor is nulláról indul a számláló, ha van kihúzóvágány (pl. Széll Kálmán tér 4/6).
A 6470-es azonosítóval rendelkező H5-ös HÉV-nél találtam ilyet, hogy nem 0-val kezdődik.
Route Id: 6470
Direction Id: 0
Trip Id: A7315199
Másrészt még azt sem értem, hogy ha alapul vesszük például a 81-es trolit, a A749484-es trip alapján az első megálló a Fischer utca. Ilyen megálló nincs is azon az útvonalon a BKV oldala szerint :/
stop_sequence: valóban, tizesével a jellemző, de néhány van egyesével is. Nekem ez eddig nem okozott problémát, de persze lehet olyan lekérdezést csinálni, ahol ez zavaró.
shape_dist_traveled: melyik viszonylaton találkoztál olyannal, hogy nem nulláról indul? Csináltam egy gyors lekérdezést, de nem találtam ilyet (legalábbi szerdai napokon, 1-es menetirányokon).
trip_headsign: végülis érthető, hogy ez nem mindig teljesen azonos a végállomás nevével, mert különben redundáns adat lenne. Ennek ellenére nagy segítség, hogy látom, hogy melyik menetirányt jelzi a direction_id 0 vagy 1 értéke. Hasonló a helyzet a routes / route_desc mezővel, amibe "csak úgy" beírták a két végállomást, ez arra jó, hogy könnyebb beazonosítani egy ismeretlen viszonylatot. Ezeknek a mezőknek a hátránya, hogy pl. közterület-átnevezéskor több mezőben kell átírni, de emiatt ne a mi fejünk fájjon. :-)
Bontott útvonalak: ez engem is bosszant, még nem jöttem rá, mi a haszna.
Kicsit már kezd elegem lenni ebből az adatbázisból. Az adatokat tekintve semmi egységesség nincs. Van ahol a stop_sequence tizesével nő, van ahol egyesével. Van ahol a shape_dist_traveled a kiinduló állomásnál 0, van ahol nem. Van ahol a trip_headsign nem ugyanolyan formátumban tartalmazza a végállomás nevét, mert a végállomás nevéhez pl hozzá van írva hogy 3. vágány, M+H meg mindenféle ilyesmi.
Ja és még egy, van ahol ha szét van bontva több részre az útvonal. Némely útvonalon meg van duplázva a "csatlakozási" megálló, néhol pedig nincs. Ezt úgy értem, hogy kétszer van ugyanaz a megálló név ahol az útvonal kettévágásánál tovább közlekedik a buszjárat.
Egy kérdésem had legyen. Tegyül fel, hogy van egy Service:
2012-03-01 és 2012-03-31 között érvényes minden hétfőn és kedden.
Az adott Service-hoz tartozik egy Exception a CalendarDates táblában miszerint:
2012-03-15 | 1
Azaz március 15-én szintén érvényben van. Ez azt jelenti, hogy ilyen esetben teljes mértékben figyelmen kívül kell hagyni hogy a menetrend hétfőn és kedden érvényes, mivel 15-e csütörtökre esik? Mert így már végre értelmet nyer számomra ez az egész :D
Köszi a jelzést, valóban van jelentős számú viszonylat, ahol hiányzik a route_stops, a trips és a stop_times tartalma! Igyekszem kijavítani, amint sikerül jelentkezem újra.
Az adatbázisodban most szúrópróba szerűen megnéztem a 103-as buszt és ahhoz nem tartoznak rekordok a route_stops táblában. Sok másik járat megállóinak listája is hiányzik onnan, erre figyeljen oda mindenki aki használja az adatbázist :)
Amennyiben SQL-ben dolgozol, a következő függvénnyel meg tudod nézni melyik járatokról van szó. Ahol nincs rekord a route_stops-ban, ott NULL értékkel tér vissza:
SELECT `lines`.line_id, route_stops.line_id AS stops FROM `lines` LEFT JOIN route_stops ON `lines`.line_id = route_stops.line_id GROUP BY `lines`.line_id ORDER BY stops ASC;
Ettől függetlenül továbbra is köszönöm az adatbázist! :)
Boccs, mint említettem, nincs Access a gépemen, egyáltalán nem gondoltam volna, hogy nem tud ilyet. Este megnézem otthon, ha más nincs, megpróbálok csv-t létrehozni.
Ki kell csomagolni a zip-et, és az abban lévő SQL fájlt kell importálni. Ha nem megy, este felrakok egy Access-t, és megnézem hogyan működik az importálás.
Nem rossz, ezer köszönet. Én is most épp azon szöszölök, hogy valahogy összevonjam az olyan járatokat mint az 5-ös busz, hogy ne 4 részben legyen egy útvonal...
Kicsit feldolgoztam a GTFS adatokat a saját céljaimnak megfelelően, pl. összevontam a részletekre bontott utazásokat, ill. meghatároztam az egyes járatokon belül a különböző útvonalakat (pl. csonkamenetek), meg még van egy-két kisebb kényelmi dolog (pl. a trips-eknél szerepel az indulás az első megállóból és az érkezés az utolsó megállóba). Ehhez természetesen egy kicsit változtatnom kellett az adatstruktúrán, de a módosítások könnyen érthetőek. Gondoltam megosztom, hátha érdekel valakit: http://users.phpbb.hu/fberci/temp/gtfs-120312.zip Ez egy zipelt SQL fájl, elvileg importálható kell hogy legyen Accessbe (nem próbáltam).