bussit.py

changeset 2
48efa8ca14dd
parent 0
fc48613c73e5
child 4
312c432bb9e6
equal deleted inserted replaced
1:22c22ff63e66 2:48efa8ca14dd
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 import enum 2 import enum, json
3 from sys import stderr
3 from datetime import date, time, datetime, timedelta 4 from datetime import date, time, datetime, timedelta
5 from misc import *
4 Suunta = enum.Enum('Suunta', [('Taaksepäin', 0), ('Eteenpäin', 1)]) 6 Suunta = enum.Enum('Suunta', [('Taaksepäin', 0), ('Eteenpäin', 1)])
5
6 def lue_csv(tiedosto, muunnokset = None):
7 import csv
8 lukija = csv.reader(tiedosto)
9 otsakkeet = next(lukija)
10 for rivi in lukija:
11 tietue = dict(zip(otsakkeet, rivi))
12 if muunnokset:
13 for avain, muunnos in muunnokset.items():
14 tietue[avain] = muunnos(tietue[avain])
15 yield tietue
16 7
17 def muunna_ajovuoro_tunniste(tunniste): 8 def muunna_ajovuoro_tunniste(tunniste):
18 return int(tunniste.split('_')[0]) 9 return int(tunniste.split('_')[0])
19 10
20 class Ajovuoro: 11 class Ajovuoro:
51 self.päivät = set() 42 self.päivät = set()
52 def __repr__(self): 43 def __repr__(self):
53 return 'palvelut[%r]' % self.tunniste 44 return 'palvelut[%r]' % self.tunniste
54 45
55 class Pysäkki: 46 class Pysäkki:
56 def __init__(self, tunniste, nimi): 47 def __init__(self, tunniste, nimi, sijainti):
57 self.tunniste, self.nimi = tunniste, nimi 48 self.tunniste, self.nimi, self.sijainti = tunniste, nimi, sijainti
58 def __repr__(self): 49 def __repr__(self):
59 return 'pysäkit[%r]' % self.tunniste 50 return 'pysäkit[%r]' % self.tunniste
60 def aikataulu(self, määrä = 50): 51 def aikataulu(self, määrä = 50):
61 ''' 52 '''
62 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei 53 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei
120 ajot = {} 111 ajot = {}
121 ajot_per_numero = {} 112 ajot_per_numero = {}
122 palvelut = {} 113 palvelut = {}
123 pysäkit = {} 114 pysäkit = {}
124 115
125 print('Ladataan linjat... ', end = '', flush = True) 116 print('Ladataan linjat... ', file = stderr, end = '', flush = True)
126 with open('gtfs/routes.txt') as tiedosto: 117 with open('gtfs/routes.txt') as tiedosto:
127 for rivi in lue_csv(tiedosto): 118 for rivi in lue_csv(tiedosto):
128 linja = Linja(rivi) 119 linja = Linja(rivi)
129 linja.tunniste = linja.tunniste 120 linja.tunniste = linja.tunniste
130 linjat[linja.viite] = linja 121 linjat[linja.viite] = linja
131 linjat_per_tunniste[linja.tunniste] = linja 122 linjat_per_tunniste[linja.tunniste] = linja
132 print('%d linjaa' % len(linjat)) 123 print('%d linjaa' % len(linjat), file = stderr)
133 124
134 print('Ladataan ajot... ', end = '', flush = True) 125 print('Ladataan ajot... ', file = stderr, end = '', flush = True)
135 with open('gtfs/trips.txt') as tiedosto: 126 with open('gtfs/trips.txt') as tiedosto:
136 for rivi in lue_csv(tiedosto, muunnokset = {'direction_id': lambda k: Suunta(int(k))}): 127 for rivi in lue_csv(tiedosto, muunnokset = {'direction_id': lambda k: Suunta(int(k))}):
137 if rivi['service_id'] not in palvelut: 128 if rivi['service_id'] not in palvelut:
138 palvelut[rivi['service_id']] = Palvelu(rivi['service_id']) 129 palvelut[rivi['service_id']] = Palvelu(rivi['service_id'])
139 linja = linjat_per_tunniste[rivi['route_id']] 130 linja = linjat_per_tunniste[rivi['route_id']]
142 palvelu = palvelut[rivi['service_id']], 133 palvelu = palvelut[rivi['service_id']],
143 kyltti = rivi['trip_headsign'], 134 kyltti = rivi['trip_headsign'],
144 suunta = rivi['direction_id']) 135 suunta = rivi['direction_id'])
145 assert ajo.nimi not in ajot 136 assert ajo.nimi not in ajot
146 ajot[ajo.nimi] = ajo 137 ajot[ajo.nimi] = ajo
147 print('%d ajoa' % len(ajot)) 138 print('%d ajoa' % len(ajot), file = stderr)
148 139
149 def lue_päiväys(teksti): 140 def lue_päiväys(teksti):
150 return date(int(teksti[:4]), int(teksti[4:6]), int(teksti[6:])) 141 return date(int(teksti[:4]), int(teksti[4:6]), int(teksti[6:]))
151 142
152 def lue_aika(teksti): 143 def lue_aika(teksti):
153 tunti, minuutti, sekunti = map(int, teksti.split(':')) 144 tunti, minuutti, sekunti = map(int, teksti.split(':'))
154 return timedelta(hours = tunti, minutes = minuutti, seconds = sekunti) 145 return timedelta(hours = tunti, minutes = minuutti, seconds = sekunti)
155 146
156 print('Ladataan päiväykset... ', flush = True) 147 print('Ladataan päiväykset... ', file = stderr, flush = True)
157 148
158 viimeinen_käyttöpäivä = date.today() 149 viimeinen_käyttöpäivä = date.today()
159 palvelut_per_päivä = {} 150 palvelut_per_päivä = {}
160 151
161 with open('gtfs/calendar_dates.txt') as tiedosto: 152 with open('gtfs/calendar_dates.txt') as tiedosto:
171 def palvelut_käytössä(päivä): 162 def palvelut_käytössä(päivä):
172 for palvelu in palvelut.values(): 163 for palvelu in palvelut.values():
173 if päivä in palvelu.päivät: 164 if päivä in palvelu.päivät:
174 yield palvelu 165 yield palvelu
175 166
176 print('Ladataan pysäkit... ', end = '', flush = True) 167 print('Ladataan pysäkit... ', file = stderr, end = '', flush = True)
177 with open('gtfs/stops.txt') as file: 168 with open('gtfs/stops.txt') as file:
178 for rivi in lue_csv(file): 169 for rivi in lue_csv(file):
179 pysäkki = Pysäkki(rivi['stop_id'], rivi['stop_name']) 170 sijainti = (float(rivi['stop_lat']), float(rivi['stop_lon']))
171 pysäkki = Pysäkki(rivi['stop_id'], rivi['stop_name'], sijainti)
180 pysäkit[pysäkki.tunniste] = pysäkki 172 pysäkit[pysäkki.tunniste] = pysäkki
181 print('%d pysäkkiä' % len(pysäkit)) 173 with open('pysäkkialueet.json') as file:
174 for pysäkkitunniste, alue in json.load(file).items():
175 pysäkit[pysäkkitunniste].alue = alue
176 print('%d pysäkkiä' % len(pysäkit), file = stderr)
182 177
183 print('Ladataan aikataulut... ', end = '', flush = True) 178 print('Ladataan aikataulut... ', end = '', flush = True, file = stderr)
184 with open('gtfs/stop_times.txt') as file: 179 with open('gtfs/stop_times.txt') as file:
185 rivimäärä = sum(line.count('\n') for line in file) 180 rivimäärä = sum(line.count('\n') for line in file)
186 laskettu = 0 181 laskettu = 0
187 file.seek(0) 182 file.seek(0)
188 for rivi in lue_csv(file): 183 for rivi in lue_csv(file):
191 lähtöaika = lue_aika(rivi['departure_time']) 186 lähtöaika = lue_aika(rivi['departure_time'])
192 pysäkki = pysäkit[rivi['stop_id']] 187 pysäkki = pysäkit[rivi['stop_id']]
193 ajo.reitti.append(Pysähdys(saapumisaika, lähtöaika, pysäkki, ajo)) 188 ajo.reitti.append(Pysähdys(saapumisaika, lähtöaika, pysäkki, ajo))
194 laskettu += 1 189 laskettu += 1
195 if laskettu % 1000 == 0: 190 if laskettu % 1000 == 0:
196 print('\rLadataan aikataulut... %.1f%%' % (laskettu * 100 / rivimäärä), end = ' ') 191 print('\rLadataan aikataulut... %.1f%%' % (laskettu * 100 / rivimäärä), end = ' ', file = stderr)
197 print('\rLadataan aikataulut... ladattu') 192 print('\rLadataan aikataulut... ladattu', file = stderr)

mercurial