bussireitti.py

changeset 5
a65b680f1774
child 6
88cfb916c852
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bussireitti.py	Thu May 25 16:41:21 2017 +0300
@@ -0,0 +1,155 @@
+#!/usr/bin/env python3
+def supista_reitti(reitti, kokonainen = False):
+	if not reitti:
+		return ''
+	kunnat = {'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki'}
+	replacements = {
+		"Ylioppilaskylä-Itä": "Ylioppilaskylä",
+		"Ylioppilaskylä-Länsi": "Ylioppilaskylä",
+		"Caribia": "Ylioppilaskylä",
+		"Jokila": "Lieto",
+		"Piispala": "Lieto",
+		'Saaro': 'Ruissalo',
+		'Silvola': 'Vahto',
+		'Hemmola': 'Vahto',
+		'Paasniittu': 'Ruskon keskusta',
+		'Kahari': 'Ruskon keskusta',
+	}
+	have_already = set()
+	i = 0
+	while i < len(reitti):
+		if reitti[i] in replacements:
+			reitti[i] = replacements[reitti[i]]
+		if reitti[i] in have_already:
+			del reitti[i]
+		else:
+			have_already.add(reitti[i])
+			i += 1
+	prioriteetit = {
+		'Ihala': 150,
+		'Kauppakeskus Mylly': 200,
+		'Kuninkoja': 80,
+		'Moikoinen': 50,
+		'Raision keskusta': 100,
+		'Friskala': 30,
+		'Kukola': 50,
+		'Kaistarniemi': 50,
+		'Papinsaari': 50,
+		'Oriniemi': 50,
+		'Pikisaari': 50,
+		'Häppilä': 50,
+		'Haarla': 50,
+		'Ylioppilaskylä': 50,
+		'Halinen': 70,
+		'Kakskerta': 50,
+		'Pansio': 50,
+		'Räntämäki': 10,
+		'Verkahovi': 20,
+		'Skanssi': 200,
+		'Vaala': 20,
+		'Varissuo': 60,
+		'Kohmo': 80,
+		'Kupittaa': 70,
+		'Kauppatori': 1e15,
+		'Lentoasema': 50,
+		'Runosmäki': 50,
+		'Lieto': 100,
+		'Liedon asemanseutu': 200,
+		'Ilmarinen': 100,
+		'Vahto': 50,
+		'Ruskon keskusta': 200,
+		'Oriketo': 50,
+		'Harittu': 40,
+		'Jäkärlä': 50,
+		'Paattinen': 100,
+		'Kaarinan keskusta': 200,
+		'Naantalin keskusta': 200,
+		'Uittamo': 50,
+		'Piikkiö': 40,
+		'Paimio': 50,
+		'Pargas': 50,
+		'Yli-Maaria': 50,
+		'Saramäki': 50,
+		'Tarvasjoki': 100,
+		'Marttila': 100,
+		'Koski Tl': 100,
+		'Katariina': 50,
+		'Länsikeskus': 50,
+		'Kaanaa': 100,
+		'Satava': 50,
+	}
+
+	if 'Kauppatori' not in reitti:
+		prioriteetit['Länsikeskus'] = prioriteetit['Skanssi'] = prioriteetit['Kauppatori']
+
+	# nimiä joista voidaan joustaa tarvittaessa
+	helpot_supistukset = {
+		'Raision keskusta': 'Raisio',
+		'Ruskon keskusta': 'Rusko',
+		'Naantalin keskusta': 'Naantali',
+		'Kaarinan keskusta': 'Kaarina',
+		'Liedon asemanseutu': 'Lieto as.',
+		'Kauppakeskus Mylly': 'Mylly',
+	}
+
+	# jos ei nyt millään vaan mahdu muuten...
+	vakavat_supistukset = {
+		'Kauppatori': 'Tori',
+		'Ylioppilaskylä': 'Yo-kylä',
+	}
+
+	lähtö = reitti[0]
+	määränpää = reitti[-1]
+	reitti_arvot = {}
+	f = lambda i: i**-0.6
+	jakaja = max(f(i + 1) for i in range(len(reitti)))
+	for i, pysäkki in enumerate(reitti):
+		# muunna indeksi siten että myöhemmät alueet korostuvat
+		i = f(i + 1) / jakaja
+		# ota prioriteetti huomioon, jotkin alueet ovat tärkeämpiä kyltissä kuin toiset
+		i *= prioriteetit.get(pysäkki, 1)
+		reitti_arvot[pysäkki] = i
+	# nollaa lähtöpaikan arvo ettei se mitenkään tule kylttiin
+	if lähtö in reitti_arvot:
+		reitti_arvot[lähtö] = 0
+	# varmista että määränpää tulee kylttiin
+	reitti_arvot[määränpää] = 1e10
+	# muodosta kyltti-tiedot järjestettynä reittiarvon mukaan
+	painot = sorted([
+		(pysäkki, reitti_arvot[pysäkki], i) \
+		for i, pysäkki in enumerate(reitti) \
+		if reitti_arvot[pysäkki] >= 1
+		], key = lambda pysäkki: -pysäkki[1])
+	# enintään neljä tulee kylttiin
+	painot = painot[:4]
+	# jos neljäs kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan neljäs pois
+	if len(painot) == 4 and painot[3][0] != määränpää and painot[3][1] < (4000 / len(reitti) ** 1.5):
+		del painot[3]
+	# sama kolmannelle
+	if len(painot) == 3 and painot[2][0] != määränpää and painot[2][1] < (500 / len(reitti) ** 1.5):
+		del painot[2]
+	if len(painot) == 2 and painot[1][0] != määränpää and painot[1][1] < (100 / len(reitti) ** 1.5):
+		del painot[1]
+	# lajitellaan painoarvot uudestaan reittijärjestykseen jotta kyltti tulee oikeinpäin
+	painot = sorted(painot, key = lambda paino: paino[2])
+	# muodostetaan kyltti..
+	kyltti = [paino[0] for paino in painot]
+	
+	# supista nimet jos mahdollista
+	def viimeistele(kyltti, supistus_taso = 0):
+		if supistus_taso > 0:
+			kyltti = [helpot_supistukset.get(paikka, paikka) for paikka in kyltti]
+		if supistus_taso > 1:
+			kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti]
+		return kyltti
+	tulos = viimeistele(kyltti)
+	if len(' - '.join(kyltti)) > 20:
+		tulos = viimeistele(kyltti, supistus_taso = 1)
+	if len(' - '.join(kyltti)) > 70:
+		tulos = viimeistele(kyltti, supistus_taso = 2)
+	if kokonainen:
+		tulos = [lähtö] + tulos
+	lyhyt_lähtö = replacements.get(lähtö, lähtö)
+	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'}:
+		tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos]
+	return tulos

mercurial