buses.py

Tue, 13 Jun 2017 00:47:24 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Tue, 13 Jun 2017 00:47:24 +0300
changeset 21
6a0394d5a159
parent 20
3199e289ae62
child 22
3d094a804af8
permissions
-rw-r--r--

Yleistä päivittelyä

0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 #!/usr/bin/env python3
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
2 import enum, json
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
3 from sys import stderr
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
4 from datetime import date, time, datetime, timedelta
5
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
5 from copy import copy
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
6 from misc import *
7
f3791dccfd03 Käännetty tiedostojen nimet englanniksi
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
7 from geometry import *
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
8 Suunta = enum.Enum('Suunta', [('Taaksepäin', 0), ('Eteenpäin', 1)])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
9
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 def muunna_ajovuoro_tunniste(tunniste):
4
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
11 return tunniste
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
12
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
13 class Ajovuoro:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
14 def __init__(self, tunniste, linja, palvelu, kyltti, suunta):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 self.tunniste, self.linja, self.palvelu, self.kyltti, self.suunta = tunniste, linja, \
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16 palvelu, kyltti, suunta
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 self.reitti = []
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18 self.nimi = muunna_ajovuoro_tunniste(tunniste)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
19 def __repr__(self):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
20 return 'ajot[%r]' % self.nimi
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 def pysäkkiReitillä(self, pysäkki):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 for pysähdys in self.reitti:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 if pysähdys.pysäkki is pysäkki:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 return pysähdys
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
25 else:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 return None
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27 def ajetaan_päivänä(self, päivä):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28 try:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29 return self.palvelu in palvelut_per_päivä[päivä]
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30 except KeyError:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 return False
5
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
32 def suppea_reitti(self, pysäkistä = None):
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
33 if pysäkistä and pysäkistä in self.reitti:
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
34 reitti = copy(self.reitti)
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
35 reitti = reitti[reitti.index(pysäkistä):]
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
36 else:
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
37 reitti = self.reitti
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
38 käytetyt_alueet = set()
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
39 tulos = []
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
40 for pysähdys in reitti:
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
41 pysäkki = pysähdys.pysäkki
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
42 if pysäkki.alue and pysäkki.alue not in käytetyt_alueet:
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
43 käytetyt_alueet.add(pysäkki.alue)
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
44 tulos.append(pysäkki.alue)
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
45 return tulos
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 class Linja:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 def __init__(self, tietue):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 self.tunniste = tietue['route_id']
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50 self.viite = tietue['route_short_name']
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 self.selite = tietue['route_long_name']
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 def __repr__(self):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 return 'linjat[%r]' % self.viite
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 class Palvelu:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 def __init__(self, tunniste):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 self.tunniste = tunniste
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 self.päivät = set()
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 def __repr__(self):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 return 'palvelut[%r]' % self.tunniste
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 class Pysäkki:
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
63 def __init__(self, tunniste, nimi, sijainti):
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
64 self.tunniste, self.nimi, self.sijainti = tunniste, nimi, sijainti
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
65 self.cluster = None
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
66 self.pairs = set() # samannimiset lähellä olevat pysäkit
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 def __repr__(self):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 return 'pysäkit[%r]' % self.tunniste
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
69 def schedule(self, max_amount = 50):
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 '''
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, pysähdys),
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 jossa:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 - `aika` on saapumishetki muotoa datetime ja
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 - `pysähdys` on vastaava Pysähdys olio.
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 Mikäli pysäkille ei ole määrätty riittävästi pysähdyksiä kalenterissa, tuloslista
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 jää alimittaiseksi, mahdollisesti jopa tyhjäksi.
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 '''
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
80 result = []
20
3199e289ae62 - Sivusto hieman edustuksellisempi
Teemu Piippo <teemu@hecknology.net>
parents: 19
diff changeset
81 # -1 päivää yövuoroja varten
3199e289ae62 - Sivusto hieman edustuksellisempi
Teemu Piippo <teemu@hecknology.net>
parents: 19
diff changeset
82 date = tänään() - timedelta(days = 1)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi,
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
84 while len(result) < max_amount:
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 try:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 # hae nykyisen päivän aikataulut ja lisää ne,
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
87 result += self.schedule_for_day(date)
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
88 except ValueError:
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan,
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 break
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 # ja siirry seuraavaan päivään.
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
92 date += timedelta(1)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 # Typistä lopputulos haluttuun tulosmäärään.
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
94 return result[:max_amount]
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
95 def schedule_for_day(self, date):
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
96 '''
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
97 Hakee pysäkin aikataulut tiettynä päivänä.
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
98 '''
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
99 # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
100 # palautettaisiin tyhjä tulos, niin algoritmi jatkaisi etsintää loputtomiin.
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
101 if date > viimeinen_käyttöpäivä:
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
102 raise ValueError('tried to retrieve schedule for date %s which is outside schedule data' % date)
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
103 result = []
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
104 # Jokaiselle ajovuorolle,
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
105 for trip in ajot.values():
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
106 # jos tämä ajovuoro ajetaan tänä päivänä
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
107 if trip.ajetaan_päivänä(date):
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
108 # ja jos tämä ajo pysähtyy tällä pysäkillä, ei kuitenkaan saapuen
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
109 # päätepysäkille,
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
110 stop = trip.pysäkkiReitillä(self)
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
111 if stop and stop is not trip.reitti[-1]:
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
112 # ja jos tämä pysähdys on tulevaisuudessa,
18
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
113 stop_time = datetime.combine(date, time()) + stop.saapumisaika
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
114 if stop_time >= nyt():
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
115 # lisää pysähdys listaan.
18
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
116 result.append({
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
117 'time': stop_time,
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
118 'trip': trip,
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
119 'stop': stop,
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
120 })
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
121 # Lajittele lopputulos saapumisajan mukaan.
18
1c8ff93fbfac Lisää käännöstä
Teemu Piippo <teemu@hecknology.net>
parents: 17
diff changeset
122 result.sort(key = lambda schedule_entry: schedule_entry['time'])
17
fa3c822859b5 Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents: 15
diff changeset
123 return result
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 class Pysähdys:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 def __init__(self, saapumisaika, lähtöaika, pysäkki, ajo):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 self.saapumisaika, self.lähtöaika, self.pysäkki, self.ajo = saapumisaika, lähtöaika, \
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
128 pysäkki, ajo
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
129 def __repr__(self):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 return 'Pysähdys(%r, %r, %r, %r)' % (self.saapumisaika, self.lähtöaika, self.pysäkki, self.ajo)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
131
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
132 linjat = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
133 linjat_per_tunniste = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
134 ajot = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
135 ajot_per_numero = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
136 palvelut = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
137 pysäkit = {}
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
138 all_clusters = set()
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
139
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
140 print('Ladataan linjat... ', file = stderr, end = '', flush = True)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
141 with open('gtfs/routes.txt') as tiedosto:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
142 for rivi in lue_csv(tiedosto):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
143 linja = Linja(rivi)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
144 linja.tunniste = linja.tunniste
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
145 linjat[linja.viite] = linja
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
146 linjat_per_tunniste[linja.tunniste] = linja
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
147 print('%d linjaa' % len(linjat), file = stderr)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
148
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
149 print('Ladataan ajot... ', file = stderr, end = '', flush = True)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
150 with open('gtfs/trips.txt') as tiedosto:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
151 for rivi in lue_csv(tiedosto, muunnokset = {'direction_id': lambda k: Suunta(int(k))}):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
152 if rivi['service_id'] not in palvelut:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
153 palvelut[rivi['service_id']] = Palvelu(rivi['service_id'])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
154 linja = linjat_per_tunniste[rivi['route_id']]
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
155 ajo = Ajovuoro(tunniste = rivi['trip_id'],
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
156 linja = linja,
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
157 palvelu = palvelut[rivi['service_id']],
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
158 kyltti = rivi['trip_headsign'],
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
159 suunta = rivi['direction_id'])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
160 assert ajo.nimi not in ajot
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
161 ajot[ajo.nimi] = ajo
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
162 print('%d ajoa' % len(ajot), file = stderr)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
163
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
164 def lue_päiväys(teksti):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
165 return date(int(teksti[:4]), int(teksti[4:6]), int(teksti[6:]))
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
166
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
167 def lue_aika(teksti):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
168 tunti, minuutti, sekunti = map(int, teksti.split(':'))
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
169 return timedelta(hours = tunti, minutes = minuutti, seconds = sekunti)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
170
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
171 print('Ladataan päiväykset... ', file = stderr, flush = True)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
172
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
173 viimeinen_käyttöpäivä = date.today()
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
174 palvelut_per_päivä = {}
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
175
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
176 with open('gtfs/calendar_dates.txt') as tiedosto:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
177 for rivi in lue_csv(tiedosto):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
178 palvelu = palvelut[rivi['service_id']]
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
179 päivä = lue_päiväys(rivi['date'])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
180 palvelu.päivät.add(päivä)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
181 if päivä not in palvelut_per_päivä:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
182 palvelut_per_päivä[päivä] = set()
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
183 palvelut_per_päivä[päivä].add(palvelu)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
184 viimeinen_käyttöpäivä = max(päivä, viimeinen_käyttöpäivä)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
185
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
186 def palvelut_käytössä(päivä):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
187 for palvelu in palvelut.values():
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
188 if päivä in palvelu.päivät:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
189 yield palvelu
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
190
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
191 print('Ladataan pysäkit... ', file = stderr, end = '', flush = True)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
192 with open('gtfs/stops.txt') as file:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
193 for rivi in lue_csv(file):
5
a65b680f1774 Paljon asioita
Teemu Piippo <teemu@hecknology.net>
parents: 4
diff changeset
194 sijainti = Sijainti(float(rivi['stop_lat']), float(rivi['stop_lon']))
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
195 pysäkki = Pysäkki(rivi['stop_id'], rivi['stop_name'], sijainti)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
196 pysäkit[pysäkki.tunniste] = pysäkki
7
f3791dccfd03 Käännetty tiedostojen nimet englanniksi
Teemu Piippo <teemu@hecknology.net>
parents: 5
diff changeset
197 with open('regions-per-stop.json') as file:
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
198 for pysäkkitunniste, alue in json.load(file).items():
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
199 pysäkit[pysäkkitunniste].alue = alue
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
200 print('%d pysäkkiä' % len(pysäkit), file = stderr)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
201
21
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
202
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
203 class BusStopCluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
204 def __init__(self):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
205 self.stops = set()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
206 self._center = None
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
207 self.name = None
21
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
208 @property
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
209 def url_name(self):
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
210 return self.name.lower().replace('(', '').replace(')', '').replace(' ', '-')
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
211 def add_stop(self, stop):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
212 assert not stop.cluster
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
213 stop.cluster = self
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
214 self.stops.add(stop)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
215 self._center = None
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
216 @property
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
217 def center(self):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
218 if not self._center:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
219 if self.stops:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
220 from statistics import median
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
221 pointtype = type(next(iter(self.stops)).sijainti)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
222 self._center = pointtype(
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
223 median(stop.sijainti.x for stop in self.stops),
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
224 median(stop.sijainti.y for stop in self.stops),
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
225 )
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
226 else:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
227 raise ValueError('an empty cluster has no center point')
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
228 return self._center
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
229 def merge(self, other):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
230 for bus_stop in other.stops:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
231 bus_stop.cluster = self
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
232 self.stops |= other.stops
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
233 other.stops = set()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
234 other._center = None
19
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
235 def schedule(self, max_amount = 50):
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
236 result = []
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
237 for stop in self.stops:
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
238 result += stop.schedule(max_amount)
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
239 result.sort(key = lambda schedule_entry: schedule_entry['time'])
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
240 return result[:max_amount]
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
241
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
242 from collections import defaultdict
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
243 bus_stops_by_name = defaultdict(set)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
244 for bus_stop in pysäkit.values():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
245 bus_stops_by_name[bus_stop.nimi].add(bus_stop)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
246 bus_stops_by_name = dict(bus_stops_by_name)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
247
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
248 # ryhmittele pysäkit nimen mukaan
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
249 all_clusters = []
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
250 def cluster_bus_stops():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
251 sorted_bus_stops = sorted(pysäkit.values(), key = lambda bus_stop: bus_stop.nimi)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
252 for bus_stop in sorted_bus_stops:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
253 if not bus_stop.cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
254 stops_to_cluster = {bus_stop}
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
255 # etsi pysäkin samannimiset vastaparit
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
256 for pair_candidate in bus_stops_by_name[bus_stop.nimi]:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
257 distance = pair_candidate.sijainti.etäisyys(bus_stop.sijainti)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
258 if pair_candidate is not bus_stop and distance <= 0.3:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
259 stops_to_cluster.add(pair_candidate)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
260 for stop_to_cluster in stops_to_cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
261 if stop_to_cluster.cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
262 cluster = stop_to_cluster.cluster
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
263 break
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
264 else:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
265 cluster = BusStopCluster()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
266 all_clusters.append(cluster)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
267 for stop_to_cluster in stops_to_cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
268 if not stop_to_cluster.cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
269 cluster.add_stop(stop_to_cluster)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
270 # Merkitse muistiin pysäkkien vastaparit käyttäen hyväksi tämänhetkistä ryhmittelytietoa
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
271 for bus_stop in pysäkit.values():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
272 if bus_stop.cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
273 bus_stop.pairs = bus_stop.cluster.stops - {bus_stop}
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
274 # Ryhmitä ne pysäkit, joilla ei ollut omaa vastaparia, muiden pysäkkien kanssa
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
275 for bus_stop in sorted_bus_stops:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
276 if len(bus_stop.cluster.stops) == 1:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
277 possibilities = set()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
278 for cluster in all_clusters:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
279 if cluster is not bus_stop.cluster:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
280 distance = cluster.center.etäisyys(bus_stop.sijainti)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
281 if distance <= 0.3:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
282 possibilities.add((distance, cluster))
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
283 if possibilities:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
284 best = min(possibilities)[1]
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
285 all_clusters.remove(bus_stop.cluster)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
286 best.merge(bus_stop.cluster)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
287
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
288 def shared_elements_in_n_sets(sets):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
289 from itertools import combinations
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
290 result = set()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
291 for pair in combinations(sets, 2):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
292 result |= pair[0] & pair[1]
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
293 return result
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
294
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
295 def name_clusters():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
296 from collections import defaultdict
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
297 from pprint import pprint
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
298 clusters_per_name = defaultdict(set)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
299 for cluster in all_clusters:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
300 name_representing_stop = min((len(pysäkki.tunniste), pysäkki.tunniste, pysäkki) for pysäkki in cluster.stops)[2]
21
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
301 clusters_per_name[name_representing_stop.nimi].add(cluster)
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
302 for name, clusters in clusters_per_name.items():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
303 if len(clusters) == 1:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
304 # Ryhmä on ainoa jolla on varaus tälle nimelle. Sen kuin vaan.
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
305 next(iter(clusters)).name = name
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
306 else:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
307 # Olisiko kaikki klusterit eri alueilla?
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
308 common_regions = shared_elements_in_n_sets({stop.alue for stop in cluster.stops} for cluster in clusters)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
309 # Esitys: ryhmä -> ne alueet jotka ovat tälle ryhmälle ainutlaatuisia
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
310 proposal = {
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
311 cluster: {stop.alue for stop in cluster.stops} - common_regions - {None}
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
312 for cluster in clusters
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
313 }
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
314 # Jos enintään yksi klusteri tässä esityksessä on kokonaan ilman omaa aluetta, jolla se voisi eritellä,
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
315 # niin nimetään klusterit näiden alueiden mukaan.
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
316 # Se klusteri jolla ei ole omaa aluetta (jos on) jätetään ilman aluepäätettä.
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
317 if sum([1 for unique_areas in proposal.values() if not unique_areas]) <= 1:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
318 for cluster, unique_areas in proposal.items():
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
319 individual_cluster_name = name
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
320 if unique_areas:
21
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
321 individual_cluster_name += ' (' + min(unique_areas) + ')'
15
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
322 cluster.name = individual_cluster_name
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
323 else:
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
324 # Typerä reunatapaus. Indeksoidaan numeroin...
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
325 for n, (_, cluster) in enumerate(sorted(
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
326 min((stop.tunniste.lower(), cluster) for stop in cluster.stops)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
327 for cluster in clusters
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
328 ), 1):
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
329 individual_cluster_name = name + '-' + str(n)
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
330 cluster.name = individual_cluster_name
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
331
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
332 print('Ryhmitellään pysäkit...')
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
333 cluster_bus_stops()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
334 name_clusters()
a22cdf28930f Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents: 7
diff changeset
335
19
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
336 clusters_by_name = {}
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
337 for cluster in all_clusters:
21
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
338 assert cluster.url_name not in clusters_by_name
6a0394d5a159 Yleistä päivittelyä
Teemu Piippo <teemu@hecknology.net>
parents: 20
diff changeset
339 clusters_by_name[cluster.url_name] = cluster
19
16fa9fb20b32 Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents: 18
diff changeset
340
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
341 print('Ladataan aikataulut... ', end = '', flush = True, file = stderr)
0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
342 with open('gtfs/stop_times.txt') as file:
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
343 rivimäärä = sum(line.count('\n') for line in file)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
344 laskettu = 0
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
345 file.seek(0)
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
346 for rivi in lue_csv(file):
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
347 ajo = ajot[muunna_ajovuoro_tunniste(rivi['trip_id'])]
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
348 saapumisaika = lue_aika(rivi['arrival_time'])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
349 lähtöaika = lue_aika(rivi['departure_time'])
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
350 pysäkki = pysäkit[rivi['stop_id']]
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
351 ajo.reitti.append(Pysähdys(saapumisaika, lähtöaika, pysäkki, ajo))
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
352 laskettu += 1
fc48613c73e5 Alustava versio
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
353 if laskettu % 1000 == 0:
2
48efa8ca14dd Suppea ajovuoroesitys
Teemu Piippo <teemu@hecknology.net>
parents: 0
diff changeset
354 print('\rLadataan aikataulut... %.1f%%' % (laskettu * 100 / rivimäärä), end = ' ', file = stderr)
4
Teemu Piippo <teemu@hecknology.net>
parents: 2
diff changeset
355 print('\rLadataan aikataulut... ladattu', file = stderr)

mercurial