Thu, 22 Jun 2017 19:01:31 +0300
Mööö
0 | 1 | #!/usr/bin/env python3 |
2 | 2 | import enum, json |
3 | from sys import stderr | |
0 | 4 | from datetime import date, time, datetime, timedelta |
5 | 5 | from copy import copy |
2 | 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 | 8 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
9 | def transform_trip_reference(reference): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
10 | return reference |
0 | 11 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
12 | class BusTrip: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
13 | def __init__(self, reference, route, service, length): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
14 | self.reference, self.route, self.service = reference, route, service |
22 | 15 | self.length = length |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
16 | self.schedule = [] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
17 | self.name = transform_trip_reference(reference) |
0 | 18 | def __repr__(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
19 | return 'all_trips[%r]' % self.name |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
20 | def contains_stop(self, stop): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
21 | for halt in self.schedule: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
22 | if halt.stop is stop: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
23 | return halt |
0 | 24 | else: |
25 | return None | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
26 | def is_served_at(self, day): |
0 | 27 | try: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
28 | return self.service in services_for_day[day] |
0 | 29 | except KeyError: |
30 | return False | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
31 | def concise_schedule(self, starting_stop = None): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
32 | if starting_stop and starting_stop in self.schedule: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
33 | schedule = copy(self.schedule) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
34 | schedule = schedule[schedule.index(starting_stop):] |
5 | 35 | else: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
36 | schedule = self.schedule |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
37 | used_areas = set() |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
38 | result = [] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
39 | for halt in schedule: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
40 | stop = halt.stop |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
41 | if stop.region and stop.region not in used_areas: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
42 | used_areas.add(stop.region) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
43 | result.append(stop.region) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
44 | return result |
0 | 45 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
46 | class BusRoute: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
47 | def __init__(self, entry): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
48 | self.id = entry['route_id'] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
49 | self.reference = entry['route_short_name'] |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
50 | self.trips = set() |
0 | 51 | def __repr__(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
52 | return 'routes[%r]' % self.reference |
0 | 53 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
54 | class BusService: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
55 | def __init__(self, reference): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
56 | self.reference = reference |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
57 | self.dates = set() |
0 | 58 | def __repr__(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
59 | return 'services[%r]' % self.reference |
0 | 60 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
61 | class BusStop: |
29 | 62 | def __init__(self, reference, name, location, code = None): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
63 | self.reference, self.name, self.location = reference, name, location |
29 | 64 | self.code = code or reference |
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 |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
67 | self.involved_trips = set() |
0 | 68 | def __repr__(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
69 | return 'bus_stops[%r]' % self.reference |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
70 | def schedule(self, max_amount = 50): |
0 | 71 | ''' |
72 | Hakee tämän pysäkin seuraavat `määrä` lähtöä. Päätepysäkille saapuvia busseja ei | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
73 | lasketa. Palauttaa pysähdykset listana jossa alkiot ovat muotoa (aika, halt), |
0 | 74 | jossa: |
75 | - `aika` on saapumishetki muotoa datetime ja | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
76 | - `halt` on vastaava BusHalt olio. |
0 | 77 | |
78 | Mikäli pysäkille ei ole määrätty riittävästi pysähdyksiä kalenterissa, tuloslista | |
79 | jää alimittaiseksi, mahdollisesti jopa tyhjäksi. | |
80 | ''' | |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
81 | result = [] |
20
3199e289ae62
- Sivusto hieman edustuksellisempi
Teemu Piippo <teemu@hecknology.net>
parents:
19
diff
changeset
|
82 | # -1 päivää yövuoroja varten |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
83 | date = today() - timedelta(days = 1) |
0 | 84 | # Niin kauan kuin aikatauluja ei ole vielä tarpeeksi, |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
85 | while len(result) < max_amount: |
0 | 86 | try: |
87 | # hae nykyisen päivän aikataulut ja lisää ne, | |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
88 | result += self.schedule_for_day(date) |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
89 | except ValueError: |
0 | 90 | # paitsi jos mentiin kalenterin ulkopuolelle, jolloin lopetetaan, |
91 | break | |
92 | # ja siirry seuraavaan päivään. | |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
93 | date += timedelta(1) |
0 | 94 | # Typistä lopputulos haluttuun tulosmäärään. |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
95 | return result[:max_amount] |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
96 | def schedule_for_day(self, date): |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
97 | ''' |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
98 | Hakee pysäkin aikataulut tiettynä päivänä. |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
99 | ''' |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
100 | # Jos päädyttiin aikataulukalenterin ulkopuolelle, niin tuotetaan virhe. Jos vain |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
101 | # palautettaisiin tyhjä result, niin algoritmi jatkaisi etsintää loputtomiin. |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
102 | if date > viimeinen_käyttöpäivä: |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
103 | 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
|
104 | result = [] |
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
105 | # Jokaiselle ajovuorolle, |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
106 | for trip in self.involved_trips: |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
107 | # jos tämä ajovuoro ajetaan tänä päivänä |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
108 | if trip.is_served_at(date): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
109 | # ja jos tämä trip pysähtyy tällä pysäkillä, ei kuitenkaan saapuen |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
110 | # päätepysäkille, |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
111 | stop = trip.contains_stop(self) |
29 | 112 | if stop and not stop.is_arrival: # stop is not trip.schedule[-1]: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
113 | # ja jos tämä halt on tulevaisuudessa, |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
114 | stop_time = datetime.combine(date, time()) + stop.arrival_time |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
115 | if stop_time >= now(): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
116 | # lisää halt listaan. |
18 | 117 | result.append({ |
118 | 'time': stop_time, | |
119 | 'trip': trip, | |
120 | 'stop': stop, | |
121 | }) | |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
122 | # Lajittele lopputulos saapumisajan mukaan. |
18 | 123 | result.sort(key = lambda schedule_entry: schedule_entry['time']) |
17
fa3c822859b5
Refaktorioitu aikatauluhaku
Teemu Piippo <teemu@hecknology.net>
parents:
15
diff
changeset
|
124 | return result |
0 | 125 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
126 | class BusHalt: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
127 | def __init__(self, arrival_time, departure_time, stop, trip, traveled_distance): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
128 | self.arrival_time, self.departure_time, self.stop, self.trip = arrival_time, departure_time, \ |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
129 | stop, trip |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
130 | self.traveled_distance = traveled_distance |
23 | 131 | @property |
29 | 132 | def is_arrival(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
133 | if not hasattr(self, 'cachedIsArrival'): |
29 | 134 | if self.stop.region: |
135 | iterator = iter(self.trip.schedule) | |
23 | 136 | stop = next(iterator) |
29 | 137 | while stop is not self: |
138 | stop = next(iterator) | |
139 | for stop in iterator: | |
140 | if stop.stop.region != self.stop.region: | |
141 | self.cachedIsArrival = False | |
142 | break | |
143 | else: | |
144 | self.cachedIsArrival = True | |
23 | 145 | else: |
29 | 146 | self.cachedIsArrival = False |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
147 | return self.cachedIsArrival |
0 | 148 | def __repr__(self): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
149 | return 'BusHalt(%r, %r, %r, %r)' % (self.arrival_time, self.departure_time, self.stop, self.trip) |
0 | 150 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
151 | routes = {} |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
152 | routes_per_id = {} |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
153 | all_trips = {} |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
154 | services = {} |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
155 | bus_stops = {} |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
156 | all_clusters = set() |
0 | 157 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
158 | print('Ladataan routes... ', file = stderr, end = '', flush = True) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
159 | with open('gtfs/routes.txt') as file: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
160 | for row in read_csv(file): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
161 | route = BusRoute(row) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
162 | routes[route.reference] = route |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
163 | routes_per_id[route.id] = route |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
164 | print('%d linjaa' % len(routes), file = stderr) |
0 | 165 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
166 | print('Ladataan ajovuorot... ', file = stderr, end = '', flush = True) |
22 | 167 | |
168 | shape_distances = {} | |
169 | with open('gtfs/shapes.txt') as file: | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
170 | for row in read_csv(file): |
22 | 171 | shape_distances[row['shape_id']] = max(shape_distances.get(row['shape_id'], 0), float(row['shape_dist_traveled'])) |
172 | ||
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
173 | with open('gtfs/trips.txt') as file: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
174 | for row in read_csv(file): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
175 | if row['service_id'] not in services: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
176 | services[row['service_id']] = BusService(row['service_id']) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
177 | route = routes_per_id[row['route_id']] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
178 | trip = BusTrip( |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
179 | reference = row['trip_id'], |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
180 | route = route, |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
181 | service = services[row['service_id']], |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
182 | length = shape_distances[row['shape_id']] |
22 | 183 | ) |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
184 | route.trips.add(trip) |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
185 | assert trip.name not in all_trips |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
186 | all_trips[trip.name] = trip |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
187 | print('%d ajoa' % len(all_trips), file = stderr) |
0 | 188 | |
29 | 189 | def read_date(teksti): |
0 | 190 | return date(int(teksti[:4]), int(teksti[4:6]), int(teksti[6:])) |
191 | ||
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
192 | def read_time(teksti): |
0 | 193 | tunti, minuutti, sekunti = map(int, teksti.split(':')) |
194 | return timedelta(hours = tunti, minutes = minuutti, seconds = sekunti) | |
195 | ||
2 | 196 | print('Ladataan päiväykset... ', file = stderr, flush = True) |
0 | 197 | |
198 | viimeinen_käyttöpäivä = date.today() | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
199 | services_for_day = {} |
0 | 200 | |
29 | 201 | def date_range(start_date, end_date, *, include_end = False): |
202 | ''' Generates date from start_date to end_date. If include_end is True, then end_date will be yielded. ''' | |
203 | current_date = start_date | |
204 | while current_date < end_date: | |
205 | yield current_date | |
206 | current_date += timedelta(1) | |
207 | if include_end: | |
208 | yield end_date | |
209 | ||
210 | def add_day_to_service(service_name, day): | |
211 | try: | |
212 | service = services[service_name] | |
213 | except KeyError: | |
214 | return | |
215 | else: | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
216 | service.dates.add(day) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
217 | if day not in services_for_day: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
218 | services_for_day[day] = set() |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
219 | services_for_day[day].add(service) |
29 | 220 | global viimeinen_käyttöpäivä |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
221 | viimeinen_käyttöpäivä = max(day, viimeinen_käyttöpäivä) |
0 | 222 | |
29 | 223 | def filter_day(row, day): |
224 | day_names = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] | |
225 | return int(row[day_names[day.isoweekday() - 1]]) | |
226 | ||
227 | with open('gtfs/calendar.txt') as file: | |
228 | for row in read_csv(file): | |
229 | for day in date_range(read_date(row['start_date']), read_date(row['end_date']), include_end = True): | |
230 | if filter_day(row, day): | |
231 | add_day_to_service(service_name = row['service_id'], day = day) | |
232 | ||
233 | with open('gtfs/calendar_dates.txt') as file: | |
234 | for row in read_csv(file): | |
235 | add_day_to_service(service_name = row['service_id'], day = read_date(row['date'])) | |
236 | ||
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
237 | def services_available_at(day): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
238 | for service in services.values(): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
239 | if day in service.dates: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
240 | yield service |
0 | 241 | |
2 | 242 | print('Ladataan pysäkit... ', file = stderr, end = '', flush = True) |
0 | 243 | with open('gtfs/stops.txt') as file: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
244 | for row in read_csv(file): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
245 | location = Sijainti(float(row['stop_lat']), float(row['stop_lon'])) |
29 | 246 | stop = BusStop( |
247 | reference = row['stop_id'], | |
248 | name = row['stop_name'], | |
249 | location = location, | |
250 | code = row['stop_code'], | |
251 | ) | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
252 | bus_stops[stop.reference] = stop |
7
f3791dccfd03
Käännetty tiedostojen nimet englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
5
diff
changeset
|
253 | with open('regions-per-stop.json') as file: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
254 | for stop_reference, region in json.load(file).items(): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
255 | bus_stops[stop_reference].region = region |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
256 | print('%d pysäkkiä' % len(bus_stops), file = stderr) |
0 | 257 | |
21 | 258 | |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
259 | class BusStopCluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
260 | def __init__(self): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
261 | self.stops = set() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
262 | self._center = None |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
263 | self.name = None |
21 | 264 | @property |
265 | def url_name(self): | |
266 | return self.name.lower().replace('(', '').replace(')', '').replace(' ', '-') | |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
267 | def add_stop(self, stop): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
268 | assert not stop.cluster |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
269 | stop.cluster = self |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
270 | self.stops.add(stop) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
271 | self._center = None |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
272 | @property |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
273 | def center(self): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
274 | if not self._center: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
275 | if self.stops: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
276 | from statistics import median |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
277 | pointtype = type(next(iter(self.stops)).location) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
278 | self._center = pointtype( |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
279 | median(stop.location.x for stop in self.stops), |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
280 | median(stop.location.y for stop in self.stops), |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
281 | ) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
282 | else: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
283 | raise ValueError('an empty cluster has no center point') |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
284 | return self._center |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
285 | def merge(self, other): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
286 | for bus_stop in other.stops: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
287 | bus_stop.cluster = self |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
288 | self.stops |= other.stops |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
289 | other.stops = set() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
290 | other._center = None |
19
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
291 | def schedule(self, max_amount = 50): |
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
292 | result = [] |
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
293 | for stop in self.stops: |
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
294 | result += stop.schedule(max_amount) |
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
295 | 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
|
296 | return result[:max_amount] |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
297 | |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
298 | from collections import defaultdict |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
299 | bus_stops_by_name = defaultdict(set) |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
300 | for bus_stop in bus_stops.values(): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
301 | bus_stops_by_name[bus_stop.name].add(bus_stop) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
302 | bus_stops_by_name = dict(bus_stops_by_name) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
303 | |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
304 | # ryhmittele bus_stops nimen mukaan |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
305 | all_clusters = [] |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
306 | def cluster_bus_stops(): |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
307 | sorted_bus_stops = sorted(bus_stops.values(), key = lambda bus_stop: bus_stop.name) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
308 | for bus_stop in sorted_bus_stops: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
309 | if not bus_stop.cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
310 | stops_to_cluster = {bus_stop} |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
311 | # etsi pysäkin samannimiset vastaparit |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
312 | for pair_candidate in bus_stops_by_name[bus_stop.name]: |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
313 | distance = pair_candidate.location.etäisyys(bus_stop.location) |
29 | 314 | if pair_candidate is not bus_stop and distance <= 0.4: |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
315 | stops_to_cluster.add(pair_candidate) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
316 | for stop_to_cluster in stops_to_cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
317 | if stop_to_cluster.cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
318 | cluster = stop_to_cluster.cluster |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
319 | break |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
320 | else: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
321 | cluster = BusStopCluster() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
322 | all_clusters.append(cluster) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
323 | for stop_to_cluster in stops_to_cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
324 | if not stop_to_cluster.cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
325 | cluster.add_stop(stop_to_cluster) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
326 | # Merkitse muistiin pysäkkien vastaparit käyttäen hyväksi tämänhetkistä ryhmittelytietoa |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
327 | for bus_stop in bus_stops.values(): |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
328 | if bus_stop.cluster: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
329 | bus_stop.pairs = bus_stop.cluster.stops - {bus_stop} |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
330 | # Ryhmitä ne bus_stops, joilla ei ollut omaa vastaparia, muiden pysäkkien kanssa |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
331 | for bus_stop in sorted_bus_stops: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
332 | if len(bus_stop.cluster.stops) == 1: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
333 | possibilities = set() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
334 | for cluster in all_clusters: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
335 | if cluster is not bus_stop.cluster: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
336 | distance = cluster.center.etäisyys(bus_stop.location) |
29 | 337 | if distance <= 0.4: |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
338 | possibilities.add((distance, cluster)) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
339 | if possibilities: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
340 | best = min(possibilities)[1] |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
341 | all_clusters.remove(bus_stop.cluster) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
342 | best.merge(bus_stop.cluster) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
343 | |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
344 | def shared_elements_in_n_sets(sets): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
345 | from itertools import combinations |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
346 | result = set() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
347 | for pair in combinations(sets, 2): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
348 | result |= pair[0] & pair[1] |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
349 | return result |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
350 | |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
351 | def name_clusters(): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
352 | from collections import defaultdict |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
353 | from pprint import pprint |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
354 | clusters_per_name = defaultdict(set) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
355 | for cluster in all_clusters: |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
356 | name_representing_stop = min((len(stop.reference), stop.reference, stop) for stop in cluster.stops)[2] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
357 | clusters_per_name[name_representing_stop.name].add(cluster) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
358 | for name, clusters in clusters_per_name.items(): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
359 | if len(clusters) == 1: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
360 | # 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
|
361 | next(iter(clusters)).name = name |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
362 | else: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
363 | # Olisiko kaikki klusterit eri alueilla? |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
364 | common_regions = shared_elements_in_n_sets({stop.region for stop in cluster.stops} for cluster in clusters) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
365 | # 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
|
366 | proposal = { |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
367 | cluster: {stop.region for stop in cluster.stops} - common_regions - {None} |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
368 | for cluster in clusters |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
369 | } |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
370 | # 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
|
371 | # niin nimetään klusterit näiden alueiden mukaan. |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
372 | # 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
|
373 | 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
|
374 | for cluster, unique_areas in proposal.items(): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
375 | individual_cluster_name = name |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
376 | if unique_areas: |
21 | 377 | individual_cluster_name += ' (' + min(unique_areas) + ')' |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
378 | cluster.name = individual_cluster_name |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
379 | else: |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
380 | # Typerä reunatapaus. Indeksoidaan numeroin... |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
381 | for n, (_, cluster) in enumerate(sorted( |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
382 | min((stop.reference.lower(), cluster) for stop in cluster.stops) |
15
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
383 | for cluster in clusters |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
384 | ), 1): |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
385 | individual_cluster_name = name + '-' + str(n) |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
386 | cluster.name = individual_cluster_name |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
387 | |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
388 | print('Ryhmitellään pysäkit...') |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
389 | cluster_bus_stops() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
390 | name_clusters() |
a22cdf28930f
Lisätty bussipysäkkien ryhmittely
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
391 | |
19
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
392 | clusters_by_name = {} |
16fa9fb20b32
Lisätty pysäkkiryhmän aikataulunäkymä
Teemu Piippo <teemu@hecknology.net>
parents:
18
diff
changeset
|
393 | for cluster in all_clusters: |
29 | 394 | if cluster.url_name in clusters_by_name: |
395 | print('Warning: Clusters %r and %r share the same URL name: %r' % (cluster.name, clusters_by_name[cluster.url_name].name, cluster.url_name)) | |
396 | else: | |
397 | 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
|
398 | |
2 | 399 | print('Ladataan aikataulut... ', end = '', flush = True, file = stderr) |
0 | 400 | with open('gtfs/stop_times.txt') as file: |
26 | 401 | row_count = sum(line.count('\n') for line in file) |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
402 | progress = 0 |
0 | 403 | file.seek(0) |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
404 | for row in read_csv(file): |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
405 | trip = all_trips[transform_trip_reference(row['trip_id'])] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
406 | arrival_time = read_time(row['arrival_time']) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
407 | departure_time = read_time(row['departure_time']) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
408 | stop = bus_stops[row['stop_id']] |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
409 | traveled_distance = float(row['shape_dist_traveled']) |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
410 | trip.schedule.append(BusHalt(arrival_time, departure_time, stop, trip, traveled_distance)) |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
411 | stop.involved_trips.add(trip) |
24
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
412 | progress += 1 |
e6bdb9c54096
Yhtenäistetty ohjelmakoodin kieli englanniksi
Teemu Piippo <teemu@hecknology.net>
parents:
23
diff
changeset
|
413 | if progress % 1000 == 0: |
26 | 414 | print('\rLadataan aikataulut... %.1f%%' % (progress * 100 / row_count), end = ' ', file = stderr) |
4 | 415 | print('\rLadataan aikataulut... ladattu', file = stderr) |
28
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
416 | |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
417 | for trip in all_trips.values(): |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
418 | from busroute import simplify_name |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
419 | schedule = trip.concise_schedule() |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
420 | try: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
421 | trip.from_place = simplify_name(schedule[0]) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
422 | trip.to_place = simplify_name(schedule[-1]) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
423 | except IndexError: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
424 | trip.from_place = '' |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
425 | trip.to_place = '' |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
426 | |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
427 | for route in routes.values(): |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
428 | from collections import Counter |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
429 | from busroute import simplify_name |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
430 | tally = Counter() |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
431 | for trip in route.trips: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
432 | schedule = trip.concise_schedule() |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
433 | places = set(schedule) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
434 | do_add = True |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
435 | assert type(schedule) is list |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
436 | for candidate in tally: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
437 | if places.issubset(set(candidate)): |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
438 | do_add = False |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
439 | tally.update({tuple(candidate)}) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
440 | if do_add: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
441 | tally.update({tuple(schedule)}) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
442 | try: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
443 | most_common_route = tally.most_common(1)[0][0] |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
444 | route.description = simplify_name(most_common_route[0]) + ' - ' + simplify_name(most_common_route[-1]) |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
445 | except: |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
446 | route.description = '' |
670ffa424ded
Bussipysäkit tallentavat ajovuoronsa välimuistiin suoritusajan nopeuttamiseksi
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
447 | route.trips = sorted(route.trips, key = lambda trip: trip.schedule[0].departure_time) |