bussireitti.py

changeset 5
a65b680f1774
child 6
88cfb916c852
equal deleted inserted replaced
4:312c432bb9e6 5:a65b680f1774
1 #!/usr/bin/env python3
2 def supista_reitti(reitti, kokonainen = False):
3 if not reitti:
4 return ''
5 kunnat = {'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki'}
6 replacements = {
7 "Ylioppilaskylä-Itä": "Ylioppilaskylä",
8 "Ylioppilaskylä-Länsi": "Ylioppilaskylä",
9 "Caribia": "Ylioppilaskylä",
10 "Jokila": "Lieto",
11 "Piispala": "Lieto",
12 'Saaro': 'Ruissalo',
13 'Silvola': 'Vahto',
14 'Hemmola': 'Vahto',
15 'Paasniittu': 'Ruskon keskusta',
16 'Kahari': 'Ruskon keskusta',
17 }
18 have_already = set()
19 i = 0
20 while i < len(reitti):
21 if reitti[i] in replacements:
22 reitti[i] = replacements[reitti[i]]
23 if reitti[i] in have_already:
24 del reitti[i]
25 else:
26 have_already.add(reitti[i])
27 i += 1
28 prioriteetit = {
29 'Ihala': 150,
30 'Kauppakeskus Mylly': 200,
31 'Kuninkoja': 80,
32 'Moikoinen': 50,
33 'Raision keskusta': 100,
34 'Friskala': 30,
35 'Kukola': 50,
36 'Kaistarniemi': 50,
37 'Papinsaari': 50,
38 'Oriniemi': 50,
39 'Pikisaari': 50,
40 'Häppilä': 50,
41 'Haarla': 50,
42 'Ylioppilaskylä': 50,
43 'Halinen': 70,
44 'Kakskerta': 50,
45 'Pansio': 50,
46 'Räntämäki': 10,
47 'Verkahovi': 20,
48 'Skanssi': 200,
49 'Vaala': 20,
50 'Varissuo': 60,
51 'Kohmo': 80,
52 'Kupittaa': 70,
53 'Kauppatori': 1e15,
54 'Lentoasema': 50,
55 'Runosmäki': 50,
56 'Lieto': 100,
57 'Liedon asemanseutu': 200,
58 'Ilmarinen': 100,
59 'Vahto': 50,
60 'Ruskon keskusta': 200,
61 'Oriketo': 50,
62 'Harittu': 40,
63 'Jäkärlä': 50,
64 'Paattinen': 100,
65 'Kaarinan keskusta': 200,
66 'Naantalin keskusta': 200,
67 'Uittamo': 50,
68 'Piikkiö': 40,
69 'Paimio': 50,
70 'Pargas': 50,
71 'Yli-Maaria': 50,
72 'Saramäki': 50,
73 'Tarvasjoki': 100,
74 'Marttila': 100,
75 'Koski Tl': 100,
76 'Katariina': 50,
77 'Länsikeskus': 50,
78 'Kaanaa': 100,
79 'Satava': 50,
80 }
81
82 if 'Kauppatori' not in reitti:
83 prioriteetit['Länsikeskus'] = prioriteetit['Skanssi'] = prioriteetit['Kauppatori']
84
85 # nimiä joista voidaan joustaa tarvittaessa
86 helpot_supistukset = {
87 'Raision keskusta': 'Raisio',
88 'Ruskon keskusta': 'Rusko',
89 'Naantalin keskusta': 'Naantali',
90 'Kaarinan keskusta': 'Kaarina',
91 'Liedon asemanseutu': 'Lieto as.',
92 'Kauppakeskus Mylly': 'Mylly',
93 }
94
95 # jos ei nyt millään vaan mahdu muuten...
96 vakavat_supistukset = {
97 'Kauppatori': 'Tori',
98 'Ylioppilaskylä': 'Yo-kylä',
99 }
100
101 lähtö = reitti[0]
102 määränpää = reitti[-1]
103 reitti_arvot = {}
104 f = lambda i: i**-0.6
105 jakaja = max(f(i + 1) for i in range(len(reitti)))
106 for i, pysäkki in enumerate(reitti):
107 # muunna indeksi siten että myöhemmät alueet korostuvat
108 i = f(i + 1) / jakaja
109 # ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset
110 i *= prioriteetit.get(pysäkki, 1)
111 reitti_arvot[pysäkki] = i
112 # nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin
113 if lähtö in reitti_arvot:
114 reitti_arvot[lähtö] = 0
115 # varmista että määränpää tulee kylttiin
116 reitti_arvot[määränpää] = 1e10
117 # muodosta kyltti-tiedot järjestettynä reittiarvon mukaan
118 painot = sorted([
119 (pysäkki, reitti_arvot[pysäkki], i) \
120 for i, pysäkki in enumerate(reitti) \
121 if reitti_arvot[pysäkki] >= 1
122 ], key = lambda pysäkki: -pysäkki[1])
123 # enintään neljä tulee kylttiin
124 painot = painot[:4]
125 # jos neljäs kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan neljäs pois
126 if len(painot) == 4 and painot[3][0] != määränpää and painot[3][1] < (4000 / len(reitti) ** 1.5):
127 del painot[3]
128 # sama kolmannelle
129 if len(painot) == 3 and painot[2][0] != määränpää and painot[2][1] < (500 / len(reitti) ** 1.5):
130 del painot[2]
131 if len(painot) == 2 and painot[1][0] != määränpää and painot[1][1] < (100 / len(reitti) ** 1.5):
132 del painot[1]
133 # lajitellaan painoarvot uudestaan reittijärjestykseen jotta kyltti tulee oikeinpäin
134 painot = sorted(painot, key = lambda paino: paino[2])
135 # muodostetaan kyltti..
136 kyltti = [paino[0] for paino in painot]
137
138 # supista nimet jos mahdollista
139 def viimeistele(kyltti, supistus_taso = 0):
140 if supistus_taso > 0:
141 kyltti = [helpot_supistukset.get(paikka, paikka) for paikka in kyltti]
142 if supistus_taso > 1:
143 kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti]
144 return kyltti
145 tulos = viimeistele(kyltti)
146 if len(' - '.join(kyltti)) > 20:
147 tulos = viimeistele(kyltti, supistus_taso = 1)
148 if len(' - '.join(kyltti)) > 70:
149 tulos = viimeistele(kyltti, supistus_taso = 2)
150 if kokonainen:
151 tulos = [lähtö] + tulos
152 lyhyt_lähtö = replacements.get(lähtö, lähtö)
153 if lyhyt_lähtö != tulos[-1] and helpot_supistukset.get(lyhyt_lähtö, lyhyt_lähtö) in kunnat | {'Kauppatori'} and tulos[-1] in kunnat | {'Kauppatori'}:
154 tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos]
155 return tulos

mercurial