| |
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 |