Asioita

Mon, 25 Sep 2017 10:46:23 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 25 Sep 2017 10:46:23 +0300
changeset 68
382dd85b83a2
parent 67
336c750b7b5d
child 69
d42bf38fbf9d

Asioita

busroute.py file | annotate | diff | comparison | revisions
service.py file | annotate | diff | comparison | revisions
static/style.css file | annotate | diff | comparison | revisions
templates/stop_display.html file | annotate | diff | comparison | revisions
--- a/busroute.py	Sat Sep 23 01:23:55 2017 +0300
+++ b/busroute.py	Mon Sep 25 10:46:23 2017 +0300
@@ -45,7 +45,7 @@
 	name = abbreviations.get(name, name)
 	return name
 
-def reduce_schedule(reitti, trip_length, whole = False):
+def reduce_schedule(reitti, trip_length, whole = False, long = False):
 	length = ((trip_length / 600) * 3 + len(reitti) * 2) / 5
 	if not reitti:
 		return ''
@@ -62,12 +62,12 @@
 	priorities = {
 		'ihala': 150,
 		'kauppakeskus mylly': 200,
-		'kuninkoja': 80,
+		'kuninkoja': 150,
 		'moikoinen': 80,
 		'raision keskusta': 150,
 		'kukola': 50,
 		'kaistarniemi': 50,
-		'papinsaari': 50,
+		'papinsaari': 80,
 		'oriniemi': 50,
 		'pikisaari': 50,
 		'häppilä': 20,
@@ -76,8 +76,8 @@
 		'halinen': 70,
 		'kakskerta': 200,
 		'pansio': 50,
-		'räntämäki': 10,
-		'verkahovi': 20,
+		'räntämäki': 25,
+		'verkahovi': 25,
 		'skanssi': 200,
 		'vaala': 20,
 		'varissuo': 60,
@@ -110,7 +110,7 @@
 		'marttila': 100,
 		'koski tl': 100,
 		'katariina': 50,
-		'länsikeskus': 50,
+		'länsikeskus': 30,
 		'kaanaa': 100,
 		'satava': 50,
 		'suikkila': 50,
@@ -118,7 +118,6 @@
 		'räntämäki': 50,
 		'moisio': 25,
 		'pääskyvuori': 100,
-		#'rautatieasema': 50,
 		'logomo': 100,
 		'rymättylä': 50,
 		"sauvo": 500,
@@ -132,8 +131,35 @@
 		'merimasku': 50,
 		'turkuhalli': 100,
 		'messukeskus': 100,
-		'naantalin pikatie': 150,
-		'helsingin valtatie': 500,
+		'naantalin pikatie': 25,
+		'helsingin valtatie': 25,
+		'lauste': 25,
+		'pompo': 25,
+		'loukinainen': 25,
+		'tuorla': 25,
+		'satakunnantie': 25,
+		'hepokulta': 25,
+		'nättinummi': 25,
+		'nummenmäki': 25,
+		'kurala': 25,
+		'itäharju': 25,
+		'vasaramäki': 25,
+		'pohjola': 25,
+		'iso-heikkilä': 25,
+		'patterinhaka': 25,
+		'illoinen': 50,
+		'luolavuori': 25,
+		'mäntymäki': 25,
+		'kurjenmäki': 25,
+		'kuusisto': 25,
+		'rautatieasema': 25,
+		'majakkaranta': 25,
+		'itäranta': 25,
+		'martti': 25,
+		'vähä-heikkilä': 25,
+		'särkilahti': 25,
+		'urusvuori': 25,
+		'port arthur': 25,
 	}
 
 	if 'kauppatori' not in reitti:
@@ -164,19 +190,22 @@
 		for i, stop in enumerate(reitti) \
 		if reitti_arvot[stop] >= 1
 		], key = lambda stop: -stop[1])
-	# enintään neljä tulee kylttiin
-	weights = weights[:3]
-	# jos kolmas kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan se pois
-	try:
-		if weights[2][0] != destination and weights[2][1] < (725 / length ** 0.8):
-			del weights[2]
-	except IndexError:
-		pass
-	try:
-		if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15):
-			del weights[1]
-	except IndexError:
-		pass
+	if long:
+		weights = weights[:4]
+	else:
+		# enintään neljä tulee kylttiin
+		weights = weights[:3]
+		# jos kolmas kylttiarvo ei ole tarpeeksi merkittävä suhteessa reitin pituuteen niin otetaan se pois
+		try:
+			if weights[2][0] != destination and weights[2][1] < (725 / length ** 0.8):
+				del weights[2]
+		except IndexError:
+			pass
+		try:
+			if weights[1][0] != destination and weights[1][1] < (500 / length ** 1.15):
+				del weights[1]
+		except IndexError:
+			pass
 	# lajitellaan painoarvot uudestaan reittijärjestykseen jotta sign tulee oikeinpäin
 	weights = sorted(weights, key = lambda weight_data: weight_data[2])
 	# muodostetaan sign..
--- a/service.py	Sat Sep 23 01:23:55 2017 +0300
+++ b/service.py	Mon Sep 25 10:46:23 2017 +0300
@@ -61,23 +61,37 @@
 		else:
 			return request.accept_languages.best_match(tr.languages)
 
-def sign(schedule_entry):
+def sign(schedule_entry, long = False):
 	from math import ceil
 	trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance
-	sign = reduce_schedule(schedule_entry['trip'].concise_schedule(schedule_entry['stop']), trip_length = trip_length)
+	sign = reduce_schedule(schedule_entry['trip'].concise_schedule(schedule_entry['stop']), trip_length = trip_length, long = long)
 	if sign:
 		sign_representation = ' - '.join(tr(place, 'paikat') for place in sign if place not in suffix_regions)
 		sign_representation += ''.join(' ' + tr(place, 'suffix-places') for place in sign if place in suffix_regions)
-		#if len(sign_representation) > 25:
-		#	k = ceil(len(sign) / 2)
-		#	sign_representation = ' - '.join(sign[:k]) + '\n' + ' - '.join(sign[k:])
 		return sign_representation
 	else:
 		return schedule_entry['trip'].schedule[-1].stop.name
 
+def long_form_sign(schedule_entry):
+	from math import ceil
+	trip_length = schedule_entry['trip'].length - schedule_entry['stop'].traveled_distance
+	sign = reduce_schedule(schedule_entry['trip'].concise_schedule(schedule_entry['stop']), trip_length = trip_length, long = True)
+	if sign:
+		return {
+			'destination': tr(sign[-1], 'paikat'),
+			'via': [tr(place, 'paikat') for place in sign[:-1]],
+		}
+	else:
+		return {
+			'destination': schedule_entry['trip'].schedule[-1].stop.name,
+			'via': [],
+		}
+	
+
 def imminent(schedule_entry):
 	return (schedule_entry['time'] - now()) <= timedelta(minutes = 3)
 
+
 @app.route('/stop/<reference>')
 def bus_stop_schedule(reference):
 	from buses import bus_stops
@@ -106,6 +120,104 @@
 		tr = tr,
 	)
 
+@app.route('/stop_display/<reference>')
+def stop_display(reference):
+	from buses import bus_stops
+	schedule = []
+	try:
+		bus_stop = bus_stops[reference]
+	except KeyError:
+		abort(404)
+	for i, schedule_entry in enumerate(bus_stop.schedule(max_amount = 6, arrivals = False)):
+		schedule.append({
+			'time_data': schedule_entry['time'],
+			'time': time_representation(schedule_entry['time']),
+			'route': schedule_entry['trip'].route.reference,
+			'sign': long_form_sign(schedule_entry),
+			'trip': schedule_entry['stop'].trip.name,
+			'night': is_night_time(schedule_entry['time']),
+			'imminent': imminent(schedule_entry),
+			'index': i,
+		})
+	from pprint import pprint
+	pprint(schedule)
+	if schedule:
+		num_imminent_leaves = max(1, len([schedule_entry for schedule_entry in schedule if schedule_entry['time_data'] - schedule[0]['time_data'] < timedelta(minutes = 3)]))
+	else:
+		num_imminent_leaves = 1
+	return render_template(
+		'stop_display.html',
+		schedule = schedule,
+		ref = bus_stop.code,
+		name = tr(bus_stop.name, 'bus-stops'),
+		link_to_map = bus_stop.location.link_to_map,
+		region = bus_stop.region,
+		location = bus_stop.location,
+		cluster = bus_stop.cluster.url_name if len(bus_stop.cluster.stops) > 1 else None,
+		num_imminent_leaves = num_imminent_leaves,
+		tr = tr,
+	)
+
+@app.route('/test')
+def test():
+	from buses import bus_stops
+	bus_stop = bus_stops['16']
+	schedule = [{'imminent': True,
+		'index': 0,
+		'night': False,
+		'route': '2A',
+		'sign': {'destination': 'Kohmo', 'via': ['Nummenmäki', 'Kurala']},
+		'time': '1m',
+		'trip': '00012501__3798generatedBlock'},
+		{'imminent': True,
+		'index': 1,
+		'night': False,
+		'route': '54',
+		'sign': {'destination': 'Ylioppilaskylä', 'via': []},
+		'time': '2m',
+		'trip': '00014359__5656generatedBlock'},
+		{'imminent': True,
+		'index': 2,
+		'night': False,
+		'route': '1',
+		'sign': {'destination': 'Lentoasema ✈', 'via': ['Urusvuori']},
+		'time': '3m',
+		'trip': '00010281__1281generatedBlock'},
+		{'imminent': False,
+		'index': 3,
+		'night': False,
+		'route': '56',
+		'sign': {'destination': 'Räntämäki', 'via': ['Nummenmäki', 'Halinen']},
+		'time': '8m',
+		'trip': '00014686__5983generatedBlock'},
+		{'imminent': False,
+		'index': 4,
+		'night': False,
+		'route': '42',
+		'sign': {'destination': 'Varissuo', 'via': ['Kupittaa as', 'Itäharju']},
+		'time': '18:30',
+		'trip': '00014010__5307generatedBlock'},
+		{'imminent': False,
+		'index': 5,
+		'night': False,
+		'route': '2B',
+		'sign': {'destination': 'Littoinen',
+				'via': ['Nummenmäki', 'Kurala', 'Kohmo']},
+		'time': '18:35',
+		'trip': '00012629__3926generatedBlock'}]
+	return render_template(
+		'stop_display.html',
+		schedule = schedule,
+		ref = bus_stop.code,
+		name = tr(bus_stop.name, 'bus-stops'),
+		link_to_map = bus_stop.location.link_to_map,
+		region = bus_stop.region,
+		location = bus_stop.location,
+		cluster = bus_stop.cluster.url_name if len(bus_stop.cluster.stops) > 1 else None,
+		num_imminent_leaves = max(1, sum(schedule_entry['imminent'] for schedule_entry in schedule)),
+		tr = tr,
+	)
+
 def time_representation(time, relative = True):
 	time_difference = time - now()
 	if relative and timedelta(minutes = -1) < time_difference < timedelta(minutes = 1):
--- a/static/style.css	Sat Sep 23 01:23:55 2017 +0300
+++ b/static/style.css	Mon Sep 25 10:46:23 2017 +0300
@@ -159,7 +159,6 @@
 {
 	color: #C0660B;
 	vertical-align: middle;
-	animation: blinker steps(1) 500ms infinite alternate;
 	opacity: 0;
 	animation: blinking 2s linear infinite;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/stop_display.html	Mon Sep 25 10:46:23 2017 +0300
@@ -0,0 +1,265 @@
+<html>
+<head>
+	<link rel="icon" type="image/png" href="../static/favicon.png" />
+	<link rel="stylesheet" type="text/css" href="../static/style.css" />
+	<meta charset='UTF-8' />
+	<title>{{name}}</title>
+	<meta http-equiv='refresh' content='30'>
+	<style>
+	.sarake-määränpää
+	{
+		text-align: left;
+	}
+	
+	.next-leave
+	{
+		margin-left: 1vw;
+		margin-right: 1vw;
+	}
+	
+	.next-leave td
+	{
+		height: 30vh;
+		vertical-align: middle;
+	}
+	
+	.next-leave-table
+	{
+		width: 100%;
+	}
+	
+	.next-leave-time, .next-leave-destination, .next-leave-route
+	{
+		font-weight: bold;
+		font-size: 10vmin;
+	}
+	
+	.next-leave-time
+	{
+		width: 25%;
+		text-align: left
+	}
+	
+	.next-leave-route
+	{
+		width: 25%;
+	}
+	
+	.next-leave-destination
+	{
+		width: 50%;
+	}
+	
+	.via
+	{
+		list-style: none;
+		font-size: 6vmin;
+		padding-top: 1vw;
+		font-weight: normal;
+	}
+	
+	.next-leave-table
+	{
+		text-align: center;
+	}
+	
+	#other-leaves
+	{
+		width: 100%;
+		position: absolute;
+		bottom: 0;
+		background: #ccc;
+		box-shadow: 0 0 1vw rgba(0, 0, 0, 0.5), inset 0 0 2vw rgba(0, 0, 0, 0.5);
+	}
+	
+	#other-leaves table
+	{
+		width: 80%;
+		margin: auto;
+		margin-bottom: 10pt;
+		margin-top: 10pt;
+	}
+	
+	#other-leaves table td
+	{
+		font-size: 4vh;
+		height: 5vh;
+		text-align: center;
+	}
+	
+	.other-leave-time
+	{
+		width: 30%;
+	}
+	
+	.other-leave-route
+	{
+		width: 30%;
+	}
+	
+	.other-leave-destination
+	{
+		width: 40%;
+	}
+
+	#stop-name
+	{
+		width: 100%;
+		text-align: center;
+	}
+	
+	h1
+	{
+		background-color: #ffd90f;
+		margin: 0;
+		padding-top: 10pt;
+		background: #dc9e00;
+		background: linear-gradient(to bottom, #ffd90f 0%, #ffd90f 95%, #AA7700 100%);
+		color: black;
+		vertical-align: middle;
+		box-shadow: 0px 0px 1vw rgba(0, 0, 0, 0.5);
+	}
+	
+	h1, h1 span
+	{
+		font-size: 5vw;
+		text-align: center;
+		font-weight: bold;
+	}
+	
+	h1 span, h1 img
+	{
+		vertical-align: middle;
+	}
+	
+	@media screen and (orientation:landscape)
+	{
+		h1
+		{
+			height: 12vh;
+		}
+		
+		h1 img
+		{
+			height: 10vh;
+			float: left;
+			margin-left: 1%;
+		}
+		
+		#stop-name
+		{
+			margin-top: 5pt;
+			font-size: 8vh;
+		}
+	}
+	
+	@media screen and (orientation:portrait)
+	{
+		h1 img
+		{
+			height: 10vh;
+			display: block;
+			margin-left: auto;
+			margin-right: auto;
+		}
+		
+		#stop-name
+		{
+			font-size: 6vw;
+		}
+	}
+	</style>
+	
+	<script>
+	num_visible_leaves = 3;
+	num_imminent_leaves = {{num_imminent_leaves}};
+	var imminent_leave_cycle = [];
+	var other_leave_cycle = [];
+	var max_leaves;
+	var current_imminent_leave = 0;
+	var current_other_leave = 0;
+	var initialized = false;
+	function cycle_leaves()
+	{
+		if (initialized == false)
+		{
+			for (max_leaves = 0;; max_leaves += 1)
+			{
+				var i = max_leaves;
+				var tr = document.getElementById('leave-' + i);
+				if (tr)
+				{
+					if (i == 0 || i == num_imminent_leaves)
+						tr.style.display = 'table-row-group';
+					else if (i < num_imminent_leaves)
+						imminent_leave_cycle.push(tr);
+					else if (i >= num_imminent_leaves + 1)
+						other_leave_cycle.push(tr);
+				}
+				else
+					break;
+			}
+			initialized = true;
+			current_imminent_leave = imminent_leave_cycle.length - 1;
+			current_other_leave = other_leave_cycle.length - 1;
+		}
+		if (imminent_leave_cycle)
+		{
+			current_imminent_leave = (current_imminent_leave + 1) % imminent_leave_cycle.length;
+			for (var i = 0; i < imminent_leave_cycle.length; i += 1)
+				imminent_leave_cycle[i].style.display = (i == current_imminent_leave) ? 'table-row-group' : 'none';
+		}
+		if (other_leave_cycle)
+		{
+			current_other_leave = (current_other_leave + 1) % other_leave_cycle.length;
+			for (var i = 0; i < other_leave_cycle.length; i += 1)
+				other_leave_cycle[i].style.display = (i == current_other_leave) ? 'table-row-group' : 'none';
+		}
+		setTimeout(cycle_leaves, 6000);
+	}
+	</script>
+</head>
+<body onload='cycle_leaves()'>
+	<h1><img src="../static/pysäkki.png" height="128" /><span id='stop-name'>{{ref}} {{name}}</span></h1>
+	<div class='next-leave'>
+	<table class='next-leave-table'>
+	{% for schedule_entry in schedule[:num_imminent_leaves] %}
+	<tbody id="leave-{{schedule_entry['index']}}">
+	<tr>
+	<td class='next-leave-time'>
+	{% if schedule_entry['imminent'] %}
+	<span class='imminent-leave'>{{schedule_entry['time']}}</span>&#8203;
+	{% else %}
+	{{schedule_entry['time']}}&#8203;
+	{% endif %}
+	</td>
+	<td class='next-leave-route'>{{schedule_entry['route']}}</td>
+	<td class='next-leave-destination'>{{schedule_entry['sign']['destination']}}
+	<span class='via'><br />
+	{% if num_imminent_leaves > 1 and schedule_entry['sign']['via'][0] and schedule_entry['sign']['via'][1] %}
+	{{schedule_entry['sign']['via'][0]}} - {{schedule_entry['sign']['via'][1]}}
+	{% for entry in schedule_entry['sign']['via'][2:] %}<br />{{entry}}{% endfor %}</span>
+	{% else %}
+	{% for entry in schedule_entry['sign']['via'] %}{{entry}}<br />{% endfor %}</span>
+	{% endif %}
+	</th>
+	</tr>
+	</tbody>
+	{% endfor %}
+	</table>
+	</div>
+	{% if schedule[num_imminent_leaves] %}
+	<div id='other-leaves'>
+	<table cellspacing="0">
+		{% for halt in schedule[num_imminent_leaves:] %}
+		<tr id="leave-{{halt['index']}}" style='display: none'>
+			<td class='other-leave-time'>{{halt['time']}}</td>
+			<td class='other-leave-route'>{{halt['route']}}</td>
+			<td class='other-leave-destination'>{{halt['sign']['destination']}}</td>
+		</tr>
+		{% endfor %}
+	</table>
+	</div>
+	{% endif %}
+</body>
+</html>

mercurial