lisää muutoksia

Tue, 20 Jun 2017 09:37:43 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Tue, 20 Jun 2017 09:37:43 +0300
changeset 22
3d094a804af8
parent 21
6a0394d5a159
child 23
3a495bc4b7b5

lisää muutoksia

buses.py file | annotate | diff | comparison | revisions
busroute.py file | annotate | diff | comparison | revisions
region-representatives.json file | annotate | diff | comparison | revisions
regions.gmp file | annotate | diff | comparison | revisions
service.py file | annotate | diff | comparison | revisions
static/style.css file | annotate | diff | comparison | revisions
templates/ajovuoro-suppea.html file | annotate | diff | comparison | revisions
templates/ajovuoro.html file | annotate | diff | comparison | revisions
templates/cluster.html file | annotate | diff | comparison | revisions
templates/pysäkki.html file | annotate | diff | comparison | revisions
tr/en.ini file | annotate | diff | comparison | revisions
tr/fi.ini file | annotate | diff | comparison | revisions
tr/sv.ini file | annotate | diff | comparison | revisions
--- a/buses.py	Tue Jun 13 00:47:24 2017 +0300
+++ b/buses.py	Tue Jun 20 09:37:43 2017 +0300
@@ -11,9 +11,10 @@
 	return tunniste
 
 class Ajovuoro:
-	def __init__(self, tunniste, linja, palvelu, kyltti, suunta):
+	def __init__(self, tunniste, linja, palvelu, kyltti, suunta, length):
 		self.tunniste, self.linja, self.palvelu, self.kyltti, self.suunta = tunniste, linja, \
 			palvelu, kyltti, suunta
+		self.length = length
 		self.reitti = []
 		self.nimi = muunna_ajovuoro_tunniste(tunniste)
 	def __repr__(self):
@@ -108,7 +109,7 @@
 				# ja jos tämä ajo pysähtyy tällä pysäkillä, ei kuitenkaan saapuen
 				# päätepysäkille,
 				stop = trip.pysäkkiReitillä(self)
-				if stop and stop is not trip.reitti[-1]:
+				if stop and not stop.isArrival(): # stop is not trip.reitti[-1]:
 					# ja jos tämä pysähdys on tulevaisuudessa,
 					stop_time = datetime.combine(date, time()) + stop.saapumisaika
 					if stop_time >= nyt():
@@ -123,9 +124,19 @@
 		return result
 
 class Pysähdys:
-	def __init__(self, saapumisaika, lähtöaika, pysäkki, ajo):
+	def __init__(self, saapumisaika, lähtöaika, pysäkki, ajo, ajettu_matka):
 		self.saapumisaika, self.lähtöaika, self.pysäkki, self.ajo = saapumisaika, lähtöaika, \
 			pysäkki, ajo
+		self.ajettu_matka = ajettu_matka
+	def isArrival(self):
+		iterator = iter(self.ajo.reitti)
+		stop = next(iterator)
+		while stop is not self:
+			stop = next(iterator)
+		for stop in iterator:
+			if stop.pysäkki.alue != self.pysäkki.alue:
+				return False
+		return True
 	def __repr__(self):
 		return 'Pysähdys(%r, %r, %r, %r)' % (self.saapumisaika, self.lähtöaika, self.pysäkki, self.ajo)
 
@@ -147,16 +158,25 @@
 print('%d linjaa' % len(linjat), file = stderr)
 
 print('Ladataan ajot... ', file = stderr, end = '', flush = True)
+
+shape_distances = {}
+with open('gtfs/shapes.txt') as file:
+	for row in lue_csv(file):
+		shape_distances[row['shape_id']] = max(shape_distances.get(row['shape_id'], 0), float(row['shape_dist_traveled']))
+
 with open('gtfs/trips.txt') as tiedosto:
 	for rivi in lue_csv(tiedosto, muunnokset = {'direction_id': lambda k: Suunta(int(k))}):
 		if rivi['service_id'] not in palvelut:
 			palvelut[rivi['service_id']] = Palvelu(rivi['service_id'])
 		linja = linjat_per_tunniste[rivi['route_id']]
-		ajo = Ajovuoro(tunniste = rivi['trip_id'],
+		ajo = Ajovuoro(
+			tunniste = rivi['trip_id'],
 			linja = linja,
 			palvelu = palvelut[rivi['service_id']],
 			kyltti = rivi['trip_headsign'],
-			suunta = rivi['direction_id'])
+			suunta = rivi['direction_id'],
+			length = shape_distances[rivi['shape_id']]
+		)
 		assert ajo.nimi not in ajot
 		ajot[ajo.nimi] = ajo
 print('%d ajoa' % len(ajot), file = stderr)
@@ -348,7 +368,8 @@
 		saapumisaika = lue_aika(rivi['arrival_time'])
 		lähtöaika = lue_aika(rivi['departure_time'])
 		pysäkki = pysäkit[rivi['stop_id']]
-		ajo.reitti.append(Pysähdys(saapumisaika, lähtöaika, pysäkki, ajo))
+		ajettu_matka = float(rivi['shape_dist_traveled'])
+		ajo.reitti.append(Pysähdys(saapumisaika, lähtöaika, pysäkki, ajo, ajettu_matka))
 		laskettu += 1
 		if laskettu % 1000 == 0:
 			print('\rLadataan aikataulut... %.1f%%' % (laskettu * 100 / rivimäärä), end = ' ', file = stderr)
--- a/busroute.py	Tue Jun 13 00:47:24 2017 +0300
+++ b/busroute.py	Tue Jun 20 09:37:43 2017 +0300
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
-def supista_reitti(reitti, kokonainen = False):
+def supista_reitti(reitti, ajomatka, kokonainen = False):
+	length = ((ajomatka / 600) + len(reitti)) / 2
 	def abstract_sign(sign):
 		abstractions = {
 			'Moikoinen': 'Hirvensalo',
@@ -29,7 +30,10 @@
 		return result
 	if not reitti:
 		return ''
-	kunnat = {'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki'}
+	eksoalueet = {
+		'Turku', 'Naantali', 'Lieto', 'Aura', 'Kaarina', 'Pargas', 'Marttila', 'Somero', 'Koski Tl', 'Tarvasjoki',
+		'Kaivopuisto',
+	}
 	replacements = {
 		"Ylioppilaskylä-Itä": "Ylioppilaskylä",
 		"Ylioppilaskylä-Länsi": "Ylioppilaskylä",
@@ -41,6 +45,8 @@
 		'Hemmola': 'Vahto',
 		'Paasniittu': 'Ruskon keskusta',
 		'Kahari': 'Ruskon keskusta',
+		'Kemiö': 'Kemiönsaari',
+		'Kasnäs': 'Kemiönsaari',
 	}
 	have_already = set()
 	i = 0
@@ -56,7 +62,7 @@
 		'Ihala': 150,
 		'Kauppakeskus Mylly': 200,
 		'Kuninkoja': 80,
-		'Moikoinen': 50,
+		'Moikoinen': 35,
 		'Raision keskusta': 100,
 		'Friskala': 20,
 		'Kukola': 50,
@@ -81,7 +87,7 @@
 		'Lentoasema': 50,
 		'Runosmäki': 50,
 		'Lieto': 100,
-		'Liedon asemanseutu': 200,
+		'Lieto as': 200,
 		'Ilmarinen': 50,
 		'Vahto': 50,
 		'Ruskon keskusta': 200,
@@ -109,8 +115,10 @@
 		'Räntämäki': 50,
 		'Moisio': 25,
 		'Pääskyvuori': 100,
-		'Rautatieasema': 100,
+		'Rautatieasema': 50,
 		'Rymättylä': 50,
+		"Sauvo": 500,
+		"Kemiönsaari": 500,
 	}
 
 	if 'Kauppatori' not in reitti:
@@ -122,7 +130,6 @@
 		'Ruskon keskusta': 'Rusko',
 		'Naantalin keskusta': 'Naantali',
 		'Kaarinan keskusta': 'Kaarina',
-		'Liedon asemanseutu': 'Lieto as.',
 		'Kauppakeskus Mylly': 'Mylly',
 	}
 
@@ -135,7 +142,7 @@
 	lähtö = reitti[0]
 	määränpää = reitti[-1]
 	reitti_arvot = {}
-	f = lambda i: i**-0.6
+	f = lambda i: i**-0.3
 	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
@@ -155,20 +162,23 @@
 		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] < (150 / len(reitti) ** 1.5):
-		del painot[1]
+	painot = painot[:3]
+	# jos kolmas kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan se pois
+	try:
+		if painot[2][0] != määränpää and painot[2][1] < (1000 / length ** 1.15):
+			del painot[2]
+	except IndexError:
+		pass
+	try:
+		if painot[1][0] != määränpää and painot[1][1] < (500 / length ** 1.15):
+			del painot[1]
+	except IndexError:
+		pass
 	# 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]
-	kyltti = abstract_sign(kyltti)
+	#kyltti = abstract_sign(kyltti)
 	# supista nimet jos mahdollista
 	def viimeistele(kyltti, supistus_taso = 0):
 		if supistus_taso > 0:
@@ -177,6 +187,9 @@
 			kyltti = [vakavat_supistukset.get(paikka, paikka) for paikka in kyltti]
 		return kyltti
 	tulos = viimeistele(kyltti)
+	for i in range(len(kyltti) - 1):
+		if kyltti[i + 1].startswith(kyltti[i]):
+			del kyltti[i]
 	if len(' - '.join(kyltti)) > 20:
 		tulos = viimeistele(kyltti, supistus_taso = 1)
 	if len(' - '.join(kyltti)) > 70:
@@ -184,6 +197,6 @@
 	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'}:
+	if lyhyt_lähtö != tulos[-1] and helpot_supistukset.get(lyhyt_lähtö, lyhyt_lähtö) in eksoalueet | {'Kauppatori'} and tulos[-1] in eksoalueet | {'Kauppatori'}:
 		tulos = ['Turku' if k == 'Kauppatori' else k for k in tulos]
 	return tulos
--- a/region-representatives.json	Tue Jun 13 00:47:24 2017 +0300
+++ b/region-representatives.json	Tue Jun 20 09:37:43 2017 +0300
@@ -24,10 +24,15 @@
 	"Jokila": "5035",
 	"Vieru": "5018",
 	"Ilmarinen": "5070",
-	"Liedon asemanseutu": "5112",
+	"Lieto as": "5112",
 	"Tarvasjoki": "5423",
 	"Avanti": "5470",
 
+	"Kemiö": "8930",
+	"Kasnäs": "8925",
+
+	"Sauvo": "8940",
+
 	"Aura": "8024",
 	"Salo": "8900",
 	"Korpo": "8960",
@@ -50,6 +55,8 @@
 	"Ajola": "3282",
 	"Ylttinen": "3192",
 	"Tamminiemi": "3279",
+	"Kaivopuisto": "3120",
+	
 	"Artukainen": "1513",
 	"Asikko": "3036",
 	"Hämölä": "3270",
@@ -196,7 +203,6 @@
 	"Yliopistonmäki": "1797",
 	"Ylioppilaskylä-Länsi": "445",
 	"Ylioppilaskylä-Itä": "448",
-	"Caribia": "1643",
 	"Meripirtti": "3179",
 
 	"Pargas": "8137",
--- a/regions.gmp	Tue Jun 13 00:47:24 2017 +0300
+++ b/regions.gmp	Tue Jun 20 09:37:43 2017 +0300
@@ -1,13 +1,13 @@
-roadmap^60.44207116353432, 22.33963034681381^15@undefined^#FF0000,5,1,#ff8800,0.4^^60.39482,22.2577~60.40037,22.27521~60.39147,22.28456~60.38851,22.27179
+roadmap^60.47037672221607, 22.021348696270596^16@undefined^#FF0000,5,1,#ff8800,0.4^^60.39482,22.2577~60.40037,22.27521~60.39147,22.28456~60.38851,22.27179
 polygon^#FF0000,5,1,#ff8800,0.4^^60.3977,22.24465~60.40772,22.24046~60.40792,22.26057~60.40076,22.27409~60.3952,22.25642
 polygon^#FF0000,5,1,#ff8800,0.4^^60.3977,22.22706~60.38719,22.23676~60.38341,22.22466~60.38518,22.21205~60.39359,22.20706~60.39816,22.21341
-undefined^#FF0000,5,1,#ff8800,0.4^^60.39868,22.21599~60.39804,22.22852~60.38876,22.23916~60.38952,22.24843~60.39329,22.25135~60.40217,22.23474~60.4019,22.21689
-undefined^#FF0000,5,1,#ff8800,0.4^^60.38871,22.16432~60.39236,22.18483~60.39972,22.188~60.40171,22.1823~60.39919,22.15413~60.39151,22.15633
-undefined^#FF0000,5,1,#ff8800,0.4^^60.42123,22.17264~60.41472,22.15422~60.40622,22.14277~60.40003,22.15599~60.40577,22.17143~60.41357,22.18174
-undefined^#FF0000,5,1,#ff8800,0.4^^60.43275,22.20869~60.4239,22.21632~60.41889,22.19831~60.42495,22.19216~60.43033,22.19648
-undefined^#FF0000,5,1,#ff8800,0.4^^60.42148,22.17333~60.42584,22.18964~60.41902,22.1971~60.41534,22.18056
-undefined^#FF0000,5,1,#ff8800,0.4^^60.49702,22.21496~60.49936,22.22028~60.50048,22.23744~60.49676,22.2392~60.49373,22.23435~60.49306,22.23554~60.49178,22.23402~60.48872,22.22903~60.48729,22.2221~60.49085,22.21505
-undefined^#FF0000,5,1,#ff8800,0.4^^60.45775,22.29049~60.4599,22.29787~60.45951,22.29945~60.45688,22.3026~60.45537,22.29751~60.45501,22.29585~60.45465,22.29285~60.45619,22.29141
+polygon^#FF0000,5,1,#ff8800,0.4^^60.39868,22.21599~60.39804,22.22852~60.38876,22.23916~60.38952,22.24843~60.39329,22.25135~60.40217,22.23474~60.4019,22.21689
+polygon^#FF0000,5,1,#ff8800,0.4^^60.38871,22.16432~60.39236,22.18483~60.39972,22.188~60.40171,22.1823~60.39919,22.15413~60.39151,22.15633
+polygon^#FF0000,5,1,#ff8800,0.4^^60.42123,22.17264~60.41472,22.15422~60.40622,22.14277~60.40003,22.15599~60.40577,22.17143~60.41357,22.18174
+polygon^#FF0000,5,1,#ff8800,0.4^^60.43275,22.20869~60.4239,22.21632~60.41889,22.19831~60.42495,22.19216~60.43033,22.19648
+polygon^#FF0000,5,1,#ff8800,0.4^^60.42148,22.17333~60.42584,22.18964~60.41902,22.1971~60.41534,22.18056
+polygon^#FF0000,5,1,#ff8800,0.4^^60.49702,22.21496~60.49936,22.22028~60.50048,22.23744~60.49676,22.2392~60.49373,22.23435~60.49306,22.23554~60.49178,22.23402~60.48872,22.22903~60.48729,22.2221~60.49085,22.21505
+polygon^#FF0000,5,1,#ff8800,0.4^^60.45775,22.29049~60.4599,22.29787~60.45951,22.29945~60.45688,22.3026~60.45537,22.29751~60.45501,22.29585~60.45465,22.29285~60.45619,22.29141
 undefined^#FF0000,5,1,#ff8800,0.4^^60.45331,22.2865~60.45033,22.29068~60.45113,22.29322~60.45198,22.29413~60.45225,22.29741~60.45399,22.29853~60.45529,22.2975~60.45495,22.29585~60.45446,22.2915~60.45386,22.28832~60.45369,22.28748
 undefined^#FF0000,5,1,#ff8800,0.4^^60.4445,22.25538~60.44359,22.25256~60.44121,22.24824~60.43617,22.25517~60.43897,22.26358
 undefined^#FF0000,5,1,#ff8800,0.4^^60.4537,22.25043~60.45203,22.25283~60.45345,22.25685~60.45493,22.25432
@@ -81,9 +81,6 @@
 undefined^#FF0000,5,1,#ff8800,0.4^^60.44594,22.19951~60.4478,22.19877~60.44824,22.21556~60.44775,22.22051~60.44611,22.22006~60.44378,22.22384~60.44355,22.23234~60.44448,22.23491~60.44422,22.23603~60.43618,22.23813~60.43201,22.22567~60.43402,22.21505~60.43541,22.20654~60.44264,22.2068
 undefined^#FF0000,5,1,#ff8800,0.4^^60.44896,22.2171~60.44767,22.22204~60.44837,22.22394~60.44827,22.23472~60.4463,22.2371~60.45119,22.24507~60.45133,22.24013~60.45296,22.23209~60.45315,22.22472
 undefined^#FF0000,5,1,#ff8800,0.4^^60.47143,22.30907~60.46766,22.3065~60.46638,22.30976~60.46627,22.32465~60.46868,22.33113~60.47168,22.33288~60.47388,22.329~60.47425,22.32349~60.47351,22.31668
-undefined^#FF0000,5,1,#ff8800,0.4^^60.46155,22.29103~60.46086,22.29293~60.45902,22.28974~60.45965,22.28794~60.46039,22.28656~60.46118,22.28815~60.46077,22.28918
-undefined^#FF0000,5,1,#ff8800,0.4^^60.4604,22.28644~60.46128,22.28815~60.46084,22.28915~60.4616,22.29102~60.46318,22.29159~60.46421,22.29127~60.46459,22.2903~60.46406,22.28743~60.46227,22.28269~60.46082,22.28075~60.46038,22.28315~60.46058,22.28521
-undefined^#FF0000,5,1,#ff8800,0.4^^60.46037,22.28649~60.4595,22.28811~60.45894,22.28975~60.45835,22.29101~60.45731,22.2896~60.45527,22.2912~60.45464,22.29024~60.45344,22.28649~60.45281,22.28577~60.45162,22.28202~60.45278,22.28007~60.45487,22.27889~60.45787,22.27826~60.45933,22.27867~60.46069,22.28068~60.46024,22.2831~60.46048,22.28519
 undefined^#FF0000,5,1,#ff8800,0.4^^60.45199,22.27478~60.45005,22.27763~60.45144,22.28188~60.45277,22.27968~60.45313,22.27621
 undefined^#FF0000,5,1,#ff8800,0.4^^60.44999,22.27767~60.45277,22.28687~60.45026,22.29051~60.44722,22.2813
 undefined^#FF0000,5,1,#ff8800,0.4^^60.41489,22.29662~60.40966,22.30021~60.41175,22.31038~60.41516,22.31797~60.41864,22.31381~60.41797,22.30828~60.41666,22.3036
@@ -224,4 +221,10 @@
 undefined^#FF0000,5,1,#ff8800,0.4^^60.57752,22.31255~60.56217,22.37125~60.59623,22.42342~60.63292,22.45499~60.65058,22.46426~60.65584,22.36526~60.63174,22.35328~60.59817,22.33307~60.58865,22.32559
 undefined^#FF0000,5,1,#ff8800,0.4^^60.44566,22.32894~60.44287,22.33761~60.44321,22.34782~60.44984,22.34589~60.45284,22.34048~60.45192,22.3356~60.44968,22.33216
 undefined^#FF0000,5,1,#ff8800,0.4^^60.44342,22.35014~60.44365,22.36593~60.45433,22.36259~60.4541,22.34633
+undefined^#FF0000,5,1,#ff8800,0.4^^60.45325,22.27598~60.45286,22.27984~60.45163,22.28199~60.45289,22.28662~60.45341,22.28622~60.45409,22.28811~60.4547,22.29174~60.4581,22.28897~60.45934,22.28666~60.45933,22.28296~60.45869,22.27967~60.4577,22.27773
+undefined^#FF0000,5,1,#ff8800,0.4^^59.98508,22.40559~59.96861,22.46199~59.90874,22.41863~59.91541,22.38107
+undefined^#FF0000,5,1,#ff8800,0.4^^60.18318,22.75921~60.16474,22.7853~60.14331,22.70053~60.1664,22.67258~60.18195,22.7181
+undefined^#FF0000,5,1,#ff8800,0.4^^60.36619,22.69037~60.35583,22.75114~60.30695,22.70246~60.32315,22.59175~60.359,22.64749
+undefined^#FF0000,5,1,#ff8800,0.4^^60.46456,22.29205~60.4637,22.29341~60.46181,22.29109~60.46104,22.29223~60.45895,22.28907~60.4601,22.2872~60.46092,22.28459~60.46213,22.28363~60.46398,22.28696
+undefined^#FF0000,5,1,#ff8800,0.4^^60.47333,22.01433~60.47077,22.02031~60.46786,22.01456~60.47116,22.00777
 @@@@@@
--- a/service.py	Tue Jun 13 00:47:24 2017 +0300
+++ b/service.py	Tue Jun 20 09:37:43 2017 +0300
@@ -58,7 +58,8 @@
 
 def sign(schedule_entry):
 	from math import ceil
-	sign = supista_reitti(schedule_entry['trip'].suppea_reitti(schedule_entry['stop']))
+	ajomatka = schedule_entry['trip'].length - schedule_entry['stop'].ajettu_matka
+	sign = supista_reitti(schedule_entry['trip'].suppea_reitti(schedule_entry['stop']), ajomatka = ajomatka)
 	sign = [tr(paikka, 'paikat') for paikka in sign]
 	sign_representation = ' - '.join(sign)
 	#if len(sign_representation) > 25:
@@ -82,6 +83,10 @@
 			'ajovuoro': schedule_entry['stop'].ajo.nimi,
 			'yö': is_night_time(schedule_entry['time']),
 		})
+	from os import path
+	tausta = path.join('static', 'tausta-' + (pysäkki.alue or 'pysäkki').lower().replace(' ', '-') + '.png')
+	if not path.isfile(tausta):
+		tausta = None
 	return render_template(
 		'pysäkki.html',
 		aikataulu = aikataulu,
@@ -91,6 +96,7 @@
 		sijainti = pysäkki.sijainti,
 		cluster = pysäkki.cluster.url_name if len(pysäkki.cluster.stops) > 1 else None,
 		tr = tr,
+		tausta = tausta,
 	)
 
 def time_representation(aika, suhteellinen = True):
@@ -150,7 +156,6 @@
 		ajovuoro = ajot[numero]
 	except KeyError:
 		abort(404)
-	suppea = request.args.get('suppea') is not None
 	reitti = []
 	suppea_reitti = []
 	käydyt_alueet = set()
@@ -168,13 +173,14 @@
 			if alue not in käydyt_alueet:
 				suppea_reitti.append({
 					'aika': muotoiltu_aika,
-					'alue': tr(alue or '', 'paikat'),
+					'alue': alue or '',
 				})
 				käydyt_alueet.add(alue)
-	kyltti = supista_reitti([k['alue'] for k in suppea_reitti], kokonainen = True)
+	kyltti = supista_reitti([k['alue'] for k in suppea_reitti], kokonainen = True, ajomatka = ajovuoro.length)
 	kyltti = [kyltti[0], kyltti[-1]]
-	sivu = suppea and 'ajovuoro-suppea.html' or 'ajovuoro.html'
-	return render_template(sivu,
+	for entry in suppea_reitti:
+		entry['alue'] = tr(entry['alue'], 'paikat')
+	return render_template('ajovuoro.html',
 		reitti = reitti,
 		suppea_reitti = suppea_reitti,
 		numero = numero,
@@ -182,6 +188,7 @@
 		selite = ' - '.join(tr(paikka, 'paikat') for paikka in kyltti),
 		yö = is_night_time(datetime.combine(tänään(), time()) + ajovuoro.reitti[-1].saapumisaika),
 		tr = tr,
+		length = ajovuoro.length / 1000
 		)
 
 @app.route('/static/<path:path>')
--- a/static/style.css	Tue Jun 13 00:47:24 2017 +0300
+++ b/static/style.css	Tue Jun 20 09:37:43 2017 +0300
@@ -1,6 +1,9 @@
+*
+{
+	font-family: FreeSans, helvetica, Arial, sans-serif;
+}
 body
 {
-	font-family: FreeSans, helvetica, Arial, sans-serif;
 	background: white;
 	color: black;
 	margin: 0;
@@ -18,6 +21,7 @@
 }
 h1
 {
+	margin: 0;
 	padding-top: 10pt;
 	padding-bottom: 20pt;
 	text-align: center;
@@ -35,10 +39,13 @@
 {
 	vertical-align: middle;
 }
-#aikataulu
+
+.aikataulu
 {
 	margin: auto;
+	margin-bottom: 30pt;
 	min-width: 50%;
+	border: 1px solid gray;
 }
 
 .sarake-aika, .sarake-linja
@@ -51,7 +58,7 @@
 	font-size: 24pt;
 }
 
-#aikataulu th, #aikataulu td
+.aikataulu th, .aikataulu td
 {
 	padding-left: 40pt;
 	padding-right: 40pt;
@@ -59,30 +66,37 @@
 	padding-top: 10px;
 }
 
-#aikataulu tr td
+.aikataulu tr td
 {
 	border-top: 1px solid gray;
+	background-color: rgba(0, 0, 0, 0.05);
 }
 
-#aikataulu tr:nth-child(even) {
-	background-color: #F8F8F8;
+.aikataulu tr:nth-child(even)
+{
+	background-color: rgba(0, 0, 0, 0.1);
 }
 
-#aikataulu tr.yö td
+.aikataulu tr.yö td
 {
 	/*
 	background-color: #d8d8ff;
 	color: #008;
 	border-bottom: 1px solid #00A;
 	*/
+	/*
 	background-color: #004;
 	color: #bef;
 	border-top: 1px solid #008;
+	*/
+	background-color: rgba(0, 0, 192, 0.25);
+	color: #22A;
+	border-top: 1px solid #00A;
 }
 
-#aikataulu tr.yö:nth-child(even) td
+.aikataulu th
 {
-	background-color: #003;
+	background: #ffd90f;
 }
 
 #pysäkki-info
@@ -104,3 +118,38 @@
 {
 	text-align: center
 }
+
+/* --- Navigointipalkki -- */
+.tab-bar
+{
+	margin: 0;
+	width: 100%;
+	overflow: hidden;
+	background: #906700;
+	display: flex;
+	justify-content: space-between;
+}
+
+.tab-bar button
+{
+	background: inherit;
+	float: left;
+	border: none;
+	outline: none;
+	cursor: pointer;
+	padding: 14px 16px;
+	transition: 0.3s;
+	color: white;
+	font-size: 22pt;
+}
+
+.tab-bar button.active
+{
+	font-weight: bold;
+}
+
+nav
+{
+	box-shadow: 0px 0px 10px black;
+	margin-bottom: 30pt;
+}
--- a/templates/ajovuoro-suppea.html	Tue Jun 13 00:47:24 2017 +0300
+++ b/templates/ajovuoro-suppea.html	Tue Jun 20 09:37:43 2017 +0300
@@ -12,26 +12,10 @@
 	{
 		text-align: center;
 	}
-	.sarake-alue
-	{
-		text-align: left;
-	}
 	</style>
 	<title>{{linja}} {{selite}}</title>
 </head>
 <body>
 	<h1>{{linja}} {{selite}}</h1>
-	<table id='aikataulu' cellspacing='0'>
-		<tr>
-			<th class='sarake-aika'>Aika</th>
-			<th class='sarake-alue'>Alue</th>
-		</tr>
-		{% for rivi in suppea_reitti %}
-		<tr>
-			<td class='sarake-aika'>{{rivi['aika']}}</td>
-			<td class='sarake-alue'>{{rivi['alue']}}</td>
-		</tr>
-		{% endfor %}
-	</table>
 </body>
 </html>
--- a/templates/ajovuoro.html	Tue Jun 13 00:47:24 2017 +0300
+++ b/templates/ajovuoro.html	Tue Jun 20 09:37:43 2017 +0300
@@ -3,29 +3,37 @@
 	<link rel="icon" type="image/png" href="/static/favicon.png" />
 	<link rel="stylesheet" type="text/css" href="/static/style.css" />
 	<meta charset='UTF-8' />
-
 	<style>
-	#aikataulu
-	{
-		margin: auto;
-	}
-	#aikataulu td
-	{
-		text-align: center;
-	}
-	#aikataulu .sarake-pysäkki
+	.sarake-pysäkki, .sarake-pysäkkiviite, .sarake-alue
 	{
 		text-align: left;
 	}
 	td, th, body
 	{
 		font-size: 24pt;
-	}
-	.sarake-aika, .sarake-tunniste
+	}/*
+	body
+	{
+		background: url('/static/tausta-bussi.png') no-repeat center center fixed;
+		background-size: cover;
+	}*/
+	</style>
+	<script>
+	function openTab(event, category)
 	{
-		width: 15%;
-	}
-	</style>
+		var tabcontent = document.getElementsByClassName("tab");
+		for (var i = 0; i < tabcontent.length; i++)
+			tabcontent[i].style.display = "none";
+
+		var tablinks = document.getElementsByClassName("tab-button");
+		for (var i = 0; i < tablinks.length; i++)
+			tablinks[i].className = tablinks[i].className.replace(" active", "");
+
+		document.getElementById(category).style.display = "block";
+		event.currentTarget.className += " active";
+		window.scrollTo(0, 0);
+	} 
+	</script>
 	<title>{{linja}} {{selite}}</title>
 </head>
 <body>
@@ -33,24 +41,49 @@
 	{% if yö %}
 	&#127769;
 	{% endif %}
-	<!--Ajo {{numero}}: -->{{linja}} {{selite}}</h1>
-	<table id='aikataulu' cellspacing='0'>
-		<tr>
-			<th class='sarake-aika'>Aika</th>
-			<th class='sarake-pysäkkiviite'>Pysäkki</th>
-			<th class='sarake-pysäkki'>Nimi</th>
-		</tr>
-		{% for rivi in reitti %}
-		<tr>
-			<td class='sarake-aika'>{{rivi['aika']}}</td>
-			<td class='sarake-pysäkkiviite'>
-				<a href="/pysäkki/{{rivi['tunniste']}}"><img src='/static/pysäkki.png' height='24' /> {{rivi['tunniste']}}</a>
-			</td>
-			<td class='sarake-pysäkki'>
-				<a href="/pysäkki/{{rivi['tunniste']}}">{{rivi['nimi']}}</a>
-			</td>
-		</tr>
-		{% endfor %}
-	</table>
+	{{linja}} {{selite}}</h1>
+	<nav>
+	<div class="tab-bar">
+	<span></span>
+	<button class="tab-button active" onclick="openTab(event, 'tab-overview')">Reitti</button>
+	<button class="tab-button" onclick="openTab(event, 'tab-stops')">Pysäkit</button>
+	<span></span>
+	</div>
+	</nav>
+	<center>Ajomatka: {{'%.1f' % length}}km</center>
+	<div id="tab-overview" class="tab">
+		<table class='aikataulu' cellspacing='0'>
+			<tr>
+				<th class='sarake-aika'>Aika</th>
+				<th class='sarake-alue'>Alue</th>
+			</tr>
+			{% for rivi in suppea_reitti %}
+			<tr>
+				<td class='sarake-aika'>{{rivi['aika']}}</td>
+				<td class='sarake-alue'>{{rivi['alue']}}</td>
+			</tr>
+			{% endfor %}
+		</table>
+	</div>
+	<div id="tab-stops" class="tab" style="display: none">
+		<table class='aikataulu' cellspacing='0'>
+			<tr>
+				<th class='sarake-aika'>Aika</th>
+				<th class='sarake-pysäkkiviite'>Pysäkki</th>
+				<th class='sarake-pysäkki'>Nimi</th>
+			</tr>
+			{% for rivi in reitti %}
+			<tr>
+				<td class='sarake-aika'>{{rivi['aika']}}</td>
+				<td class='sarake-pysäkkiviite'>
+					<a href="/pysäkki/{{rivi['tunniste']}}"><img src='/static/pysäkki.png' height='24' /> {{rivi['tunniste']}}</a>
+				</td>
+				<td class='sarake-pysäkki'>
+					<a href="/pysäkki/{{rivi['tunniste']}}">{{rivi['nimi']}}</a>
+				</td>
+			</tr>
+			{% endfor %}
+		</table>
+	</div>
 </body>
 </html>
--- a/templates/cluster.html	Tue Jun 13 00:47:24 2017 +0300
+++ b/templates/cluster.html	Tue Jun 20 09:37:43 2017 +0300
@@ -12,8 +12,17 @@
 	}
 	div.stops-in-cluster ul
 	{
-		columns: 3;
+		columns: 2;
 	}
+	div.stops-in-cluster li
+	{
+		text-align: center;
+	}/*
+	body
+	{
+		background: url('/static/tausta-pysäkki.png') no-repeat center center fixed;
+		background-size: cover;
+	}*/
 	</style>
 </head>
 <body>
@@ -29,7 +38,7 @@
 	{% endfor %}
 	</ul>
 	</div>
-	<table id='aikataulu' cellspacing="0">
+	<table class='aikataulu' cellspacing="0">
 		<tr>
 			<th class='sarake-aika'>{{tr('time', 'headings')}}</th>
 			<th class='sarake-linja'>{{tr('route', 'headings')}}</th>
--- a/templates/pysäkki.html	Tue Jun 13 00:47:24 2017 +0300
+++ b/templates/pysäkki.html	Tue Jun 20 09:37:43 2017 +0300
@@ -10,6 +10,15 @@
 		text-align: left;
 	}
 	</style>
+	{% if tausta %}
+	<style>
+	/*body
+	{
+		background: url('/{{tausta}}') no-repeat center center fixed;
+		background-size: cover;
+	}*/
+	</style>
+	{% endif %}
 </head>
 <body>
 	<h1><img src="/static/iso-pysäkki.png" height="96" /> <span>{{nimi}}</span></h1>
@@ -23,7 +32,7 @@
 	<a href="/pysäkkiryhmä/{{cluster}}">{{tr('nearby-area-schedule', 'misc-text')}}</a>
 	</p>
 	{% endif %}
-	<table id='aikataulu' cellspacing="0">
+	<table class='aikataulu' cellspacing="0">
 		<tr>
 			<th class='sarake-aika'>{{tr('time', 'headings')}}</th>
 			<th class='sarake-linja'>{{tr('route', 'headings')}}</th>
--- a/tr/en.ini	Tue Jun 13 00:47:24 2017 +0300
+++ b/tr/en.ini	Tue Jun 20 09:37:43 2017 +0300
@@ -7,7 +7,7 @@
 raision keskusta = Raisio Centrum
 naantalin keskusta = Naantali Centrum
 linja-autoasema = Bus Station
-rautatieasema = 🚉 Central Railway Station
+rautatieasema = Railway Station
 kaarinan keskusta = Kaarina
 
 [misc-text]
--- a/tr/fi.ini	Tue Jun 13 00:47:24 2017 +0300
+++ b/tr/fi.ini	Tue Jun 20 09:37:43 2017 +0300
@@ -5,7 +5,9 @@
 satama = ⚓ Satama
 kauppakeskus mylly = Mylly
 kaarinan keskusta = Kaarina
-rautatieasema = 🚉 Rautatieasema
+naantalin keskusta = Naantali
+raision keskusta = Raisio
+rautatieasema = Rautatieasema
 
 [headings]
 time = Aika
--- a/tr/sv.ini	Tue Jun 13 00:47:24 2017 +0300
+++ b/tr/sv.ini	Tue Jun 20 09:37:43 2017 +0300
@@ -1657,6 +1657,7 @@
 koroinen = Korois
 kuninkoja = Kungsbäcken
 kupittaa = Kuppis
+kupittaanpuisto = Kuppisparken
 kurala (naantali) = Kurala
 kurjenmäki = Tranbacken
 kuuvuori = Månberget
@@ -1689,7 +1690,7 @@
 pääskyvuori = Svalberga
 raisio = Reso
 raision keskusta = Reso centrum
-rautatieasema = 🚉 Järnvägsstation
+rautatieasema = Järnvägsstation
 ruissalo = Runsala
 runosmäki = Runosbacken
 ruskon keskusta = Rusko centrum
@@ -1712,7 +1713,6 @@
 ylioppilaskylä = Studentbyn
 ylioppilaskylä-länsi = Västra Studentbyn
 ylioppilaskylä-itä = Östra Studentbyn
-caribia = Spa Caribia
 lieto as. = Lundo stn.
 kauppakeskus mylly = Mylly
 turku = Åbo
@@ -1722,6 +1722,9 @@
 lieto = Lundo
 koski tl = Koskis
 marttila = S:t Mårtens
+kemiö = Kimito
+kemiönsaari = Kimitoön
+sauvo = Sagu
 
 [headings]
 time = Tid

mercurial