busroute.py

changeset 7
f3791dccfd03
parent 6
88cfb916c852
child 12
a47c9bde457d
equal deleted inserted replaced
6:88cfb916c852 7:f3791dccfd03
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': 20,
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': 50,
59 'Vahto': 50,
60 'Ruskon keskusta': 200,
61 'Oriketo': 30,
62 'Harittu': 40,
63 'Jäkärlä': 50,
64 'Paattinen': 100,
65 'Kaarinan keskusta': 200,
66 'Naantalin keskusta': 200,
67 'Uittamo': 50,
68 'Piikkiö': 100,
69 'Paimio': 100,
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 'Suikkila': 50,
81 'Raunistula': 50,
82 'Räntämäki': 50,
83 'Moisio': 25,
84 }
85
86 if 'Kauppatori' not in reitti:
87 prioriteetit['Länsikeskus'] = prioriteetit['Skanssi'] = prioriteetit['Kauppatori']
88
89 # nimiä joista voidaan joustaa tarvittaessa
90 helpot_supistukset = {
91 'Raision keskusta': 'Raisio',
92 'Ruskon keskusta': 'Rusko',
93 'Naantalin keskusta': 'Naantali',
94 'Kaarinan keskusta': 'Kaarina',
95 'Liedon asemanseutu': 'Lieto as.',
96 'Kauppakeskus Mylly': 'Mylly',
97 }
98
99 # jos ei nyt millään vaan mahdu muuten...
100 vakavat_supistukset = {
101 'Kauppatori': 'Tori',
102 'Ylioppilaskylä': 'Yo-kylä',
103 }
104
105 lähtö = reitti[0]
106 määränpää = reitti[-1]
107 reitti_arvot = {}
108 f = lambda i: i**-0.6
109 jakaja = max(f(i + 1) for i in range(len(reitti)))
110 for i, pysäkki in enumerate(reitti):
111 # muunna indeksi siten että myöhemmät alueet korostuvat
112 i = f(i + 1) / jakaja
113 # ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset
114 i *= prioriteetit.get(pysäkki, 1)
115 reitti_arvot[pysäkki] = i
116 # nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin
117 if lähtö in reitti_arvot:
118 reitti_arvot[lähtö] = 0
119 # varmista että määränpää tulee kylttiin
120 reitti_arvot[määränpää] = 1e10
121 # muodosta kyltti-tiedot järjestettynä reittiarvon mukaan
122 painot = sorted([
123 (pysäkki, reitti_arvot[pysäkki], i) \
124 for i, pysäkki in enumerate(reitti) \
125 if reitti_arvot[pysäkki] >= 1
126 ], key = lambda pysäkki: -pysäkki[1])
127 # enintään neljä tulee kylttiin
128 painot = painot[:4]
129 # jos neljäs kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan neljäs pois
130 if len(painot) == 4 and painot[3][0] != määränpää and painot[3][1] < (4000 / len(reitti) ** 1.5):
131 del painot[3]
132 # sama kolmannelle
133 if len(painot) == 3 and painot[2][0] != määränpää and painot[2][1] < (500 / len(reitti) ** 1.5):
134 del painot[2]
135 if len(painot) == 2 and painot[1][0] != määränpää and painot[1][1] < (100 / len(reitti) ** 1.5):
136 del painot[1]
137 # lajitellaan painoarvot uudestaan reittijärjestykseen jotta kyltti tulee oikeinpäin
138 painot = sorted(painot, key = lambda paino: paino[2])
139 # muodostetaan kyltti..
140 kyltti = [paino[0] for paino in painot]
141
142 # supista nimet jos mahdollista
143 def viimeistele(kyltti, supistus_taso = 0):
144 if supistus_taso > 0:
145 kyltti = [helpot_supistukset.get(paikka, paikka) for paikka in kyltti]
146 if supistus_taso > 1:
147 kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti]
148 return kyltti
149 tulos = viimeistele(kyltti)
150 if len(' - '.join(kyltti)) > 20:
151 tulos = viimeistele(kyltti, supistus_taso = 1)
152 if len(' - '.join(kyltti)) > 70:
153 tulos = viimeistele(kyltti, supistus_taso = 2)
154 if kokonainen:
155 tulos = [lähtö] + tulos
156 lyhyt_lähtö = replacements.get(lähtö, lähtö)
157 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'}:
158 tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos]
159 return tulos

mercurial