Lisätty pysäkkiryhmän aikataulunäkymä

Sat, 10 Jun 2017 22:30:55 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 10 Jun 2017 22:30:55 +0300
changeset 19
16fa9fb20b32
parent 18
1c8ff93fbfac
child 20
3199e289ae62

Lisätty pysäkkiryhmän aikataulunäkymä

buses.py file | annotate | diff | comparison | revisions
geometry.py file | annotate | diff | comparison | revisions
service.py file | annotate | diff | comparison | revisions
static/style.css file | annotate | diff | comparison | revisions
templates/cluster.html file | annotate | diff | comparison | revisions
templates/pysäkki.html file | annotate | diff | comparison | revisions
--- a/buses.py	Sat Jun 10 21:09:11 2017 +0300
+++ b/buses.py	Sat Jun 10 22:30:55 2017 +0300
@@ -120,9 +120,6 @@
 		# Lajittele lopputulos saapumisajan mukaan.
 		result.sort(key = lambda schedule_entry: schedule_entry['time'])
 		return result
-	@property
-	def linkki_karttaan(self):
-		return 'http://www.openstreetmap.org/#map=19/%f/%f' % (self.sijainti.leveys, self.sijainti.pituus)
 
 class Pysähdys:
 	def __init__(self, saapumisaika, lähtöaika, pysäkki, ajo):
@@ -230,6 +227,12 @@
 		self.stops |= other.stops
 		other.stops = set()
 		other._center = None
+	def schedule(self, max_amount = 50):
+		result = []
+		for stop in self.stops:
+			result += stop.schedule(max_amount)
+		result.sort(key = lambda schedule_entry: schedule_entry['time'])
+		return result[:max_amount]
 
 from collections import defaultdict
 bus_stops_by_name = defaultdict(set)
@@ -326,6 +329,11 @@
 cluster_bus_stops()
 name_clusters()
 
+clusters_by_name = {}
+for cluster in all_clusters:
+	assert cluster.name not in clusters_by_name
+	clusters_by_name[cluster.name] = cluster
+
 print('Ladataan aikataulut... ', end = '', flush = True, file = stderr)
 with open('gtfs/stop_times.txt') as file:
 	rivimäärä = sum(line.count('\n') for line in file)
--- a/geometry.py	Sat Jun 10 21:09:11 2017 +0300
+++ b/geometry.py	Sat Jun 10 22:30:55 2017 +0300
@@ -18,6 +18,9 @@
 	@property
 	def y(self):
 		return self.pituus
+	@property
+	def link_to_map(self):
+		return 'http://www.openstreetmap.org/#map=19/%f/%f' % (self.leveys, self.pituus)
 
 class Rengas:
 	def __init__(tämä, säiliö):
--- a/service.py	Sat Jun 10 21:09:11 2017 +0300
+++ b/service.py	Sat Jun 10 22:30:55 2017 +0300
@@ -44,37 +44,73 @@
 		else:
 			return 'fi'
 
+def sign(schedule_entry):
+	from math import ceil
+	sign = supista_reitti(schedule_entry['trip'].suppea_reitti(schedule_entry['stop']))
+	sign = [tr(paikka, 'paikat') for paikka in sign]
+	sign_representation = ' - '.join(sign)
+	if len(sign_representation) > 25:
+		k = ceil(len(sign) / 2)
+		sign_representation = ' - '.join(sign[:k]) + '\n' + ' - '.join(sign[k:])
+	return sign_representation
+
 @app.route('/pysäkki/<tunniste>')
 def pysäkkiaikataulu(tunniste):
 	from buses import pysäkit
-	from math import ceil
 	aikataulu = []
 	try:
 		pysäkki = pysäkit[tunniste]
 	except KeyError:
 		abort(404)
 	for schedule_entry in pysäkki.schedule(100):
-		sign = supista_reitti(schedule_entry['trip'].suppea_reitti(schedule_entry['stop']))
-		sign = [tr(paikka, 'paikat') for paikka in sign]
-		sign_representation = ' - '.join(sign)
-		if len(sign_representation) > 25:
-			k = ceil(len(sign) / 2)
-			sign_representation = ' - '.join(sign[:k]) + '\n' + ' - '.join(sign[k:])
 		aikataulu.append({
 			'aika': time_representation(schedule_entry['time']),
 			'linja': schedule_entry['trip'].linja.viite,
-			'kyltti': sign_representation,
+			'kyltti': sign(schedule_entry),
 			'ajovuoro': schedule_entry['stop'].ajo.nimi,
 			'yö': is_night_time(schedule_entry['time']),
 		})
 	return render_template(
 		'pysäkki.html',
 		aikataulu = aikataulu,
-		viite = tunniste,
-		nimi = tr(pysäkki.nimi, 'pysäkit'),
-		linkki_karttaan = pysäkki.linkki_karttaan,
+		nimi = tunniste + ' ' + tr(pysäkki.nimi, 'pysäkit'),
+		linkki_karttaan = pysäkki.sijainti.link_to_map,
 		alue = pysäkki.alue,
 		sijainti = pysäkki.sijainti,
+		cluster = pysäkki.cluster.name,
+	)
+
+@app.route('/pysäkkiryhmä/<cluster_name>')
+def cluster_schedule(cluster_name):
+	from buses import pysäkit, clusters_by_name
+	aikataulu = []
+	try:
+		cluster = clusters_by_name[cluster_name]
+	except KeyError:
+		abort(404)
+	for schedule_entry in cluster.schedule(100):
+		aikataulu.append({
+			'aika': time_representation(schedule_entry['time']),
+			'linja': schedule_entry['trip'].linja.viite,
+			'kyltti': sign(schedule_entry),
+			'ajovuoro': schedule_entry['stop'].ajo.nimi,
+			'yö': is_night_time(schedule_entry['time']),
+			'stop_id': schedule_entry['stop'].pysäkki.tunniste,
+			'stop_name': tr(schedule_entry['stop'].pysäkki.nimi, 'pysäkit'),
+		})
+	return render_template(
+		'cluster.html',
+		aikataulu = aikataulu,
+		nimi = 'Yhdistetty pysäkkiaikataulu ' + cluster_name,
+		linkki_karttaan = cluster.center.link_to_map,
+		sijainti = cluster.center,
+		stops_in_cluster = sorted(
+			({
+				'id': stop.tunniste,
+				'name': tr(stop.nimi, 'pysäkit'),
+			} for stop in cluster.stops),
+			key = lambda stop: (len(stop['id']), stop['id'])
+		)
 	)
 
 @app.route('/ajovuoro/<numero>')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/static/style.css	Sat Jun 10 22:30:55 2017 +0300
@@ -0,0 +1,113 @@
+body
+{
+	font-family: "Oxygen-Sans", "Latin Modern Sans", Tahoma, FreeSans, Arial, sans-serif;
+	background: white;
+	color: black;
+	margin: 0;
+	padding: 0;
+	font-size: 24pt;
+}
+a
+{
+	color: inherit;
+	text-decoration: none;
+}
+a:hover
+{
+	text-decoration: underline;
+}
+h1
+{
+	padding-top: 10pt;
+	padding-bottom: 10pt;
+	text-align: center;
+	background: #dc9e00;
+	background: linear-gradient(to bottom, #dc9e00 0%,#eaaf19 49%,#dc9e00 92%,#906700 100%);
+	color: white;
+}
+#aikataulu
+{
+	width:100%;
+	margin: auto;
+}
+
+.sarake-aika, .sarake-linja
+{
+	text-align: center;
+}
+
+.sarake-määränpää
+{
+	text-align: left;
+}
+
+td, th, body
+{
+	font-size: 24pt;
+}
+
+.sarake-aika, .sarake-linja
+{
+	width: 25%;
+}
+
+h1
+{
+	font-variant: small-caps;
+}
+
+.sarake-määränpää a
+{
+	white-space: pre-wrap;
+}
+
+#aikataulu tr td
+{
+	padding-bottom: 10px;
+	padding-top: 10px;
+	padding-left: 0px;
+	padding-right: 0px;
+	margin: 0px;
+	border-top: 1px solid gray;
+}
+
+#aikataulu tr:nth-child(even) {
+	background-color: #F8F8F8;
+}
+
+#aikataulu tr.yö td
+{
+	/*
+	background-color: #d8d8ff;
+	color: #008;
+	border-bottom: 1px solid #00A;
+	*/
+	background-color: #004;
+	color: #bef;
+	border-top: 1px solid #008;
+}
+
+#aikataulu tr.yö:nth-child(even) td
+{
+	background-color: #003;
+}
+
+#pysäkki-info
+{
+	text-align: center
+}
+
+.pysäkki-sijainti
+{
+	font-size: smaller;
+}
+
+.sarake-määränpää
+{
+	text-align: center;
+}
+
+.sarake-pysäkki
+{
+	text-align: center;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/cluster.html	Sat Jun 10 22:30:55 2017 +0300
@@ -0,0 +1,46 @@
+<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>{{nimi}}</title>
+	<style>
+	p { text-align: center }
+	</style>
+</head>
+<body>
+	<h1>{{nimi}}</h1>
+	<p id="pysäkki-info">
+	<a class="pysäkki-sijainti" href="{{linkki_karttaan}}" target="_blank">📌 ({{sijainti}})</a>
+	</p>
+	<p>Pysäkit ryhmässä:
+		<ul>
+		{% for stop in stops_in_cluster %}
+			<li><a href="/pysäkki/{{stop['id']}}">{{stop['id']}} {{stop['name']}}</a></li>
+		{% endfor %}
+		</ul>
+	</p>
+	<table id='aikataulu' cellspacing="0">
+		<tr>
+			<th class='sarake-aika'>Aika</th>
+			<th class='sarake-linja'>Linja</th>
+			<th class='sarake-määränpää'>Määränpää</th>
+			<th class='sarake-pysäkki'>Pysäkki</th>
+		</tr>
+		{% for rivi in aikataulu %}
+		<tr class="{% if rivi['yö'] %} yö {% endif %}">
+			<td class='sarake-aika'>{{rivi['aika']}}</td>
+			<td class='sarake-linja linja'>
+				<a href="/ajovuoro/{{rivi['ajovuoro']}}">{{rivi['linja']}}</a>
+			</td>
+			<td class='sarake-määränpää'>
+				<a href="/ajovuoro/{{rivi['ajovuoro']}}">{{rivi['kyltti']}}</a>
+			</td>
+			<td class='sarake-pysäkki'>
+				<a href="/pysäkki/{{rivi['stop_id']}}">{{rivi['stop_id']}}</a>
+			</td>
+		</tr>
+		{% endfor %}
+	</table>
+</body>
+</html>
--- a/templates/pysäkki.html	Sat Jun 10 21:09:11 2017 +0300
+++ b/templates/pysäkki.html	Sat Jun 10 22:30:55 2017 +0300
@@ -1,127 +1,23 @@
 <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>{{nimi}}</title>
 	<style>
-	body
-	{
-		font-family: "Oxygen-Sans", "Latin Modern Sans", Tahoma, FreeSans, Arial, sans-serif;
-		background: white;
-		color: black;
-		margin: 0;
-		padding: 0;
-		font-size: 24pt;
-	}
-	a
-	{
-		color: inherit;
-		text-decoration: none;
-	}
-	a:hover
-	{
-		text-decoration: underline;
-	}
-	h1
-	{
-		padding-top: 10pt;
-		padding-bottom: 10pt;
-		text-align: center;
-		background: #dc9e00;
-		background: linear-gradient(to bottom, #dc9e00 0%,#eaaf19 49%,#dc9e00 92%,#906700 100%);
-		color: white;
-	}
-	#aikataulu
-	{
-		width:100%;
-		margin: auto;
-	}
-	
-	.sarake-aika, .sarake-linja
-	{
-		text-align: center;
-	}
-	
-	.sarake-määränpää
-	{
-		text-align: left;
-	}
-	
-	td, th, body
-	{
-		font-size: 24pt;
-	}
-	
-	.sarake-aika, .sarake-linja
-	{
-		width: 25%;
-	}
-	
-	h1
-	{
-		font-variant: small-caps;
-	}
-	
-	.sarake-määränpää a
-	{
-		white-space: pre-wrap;
-	}
-	
-	#aikataulu tr td
-	{
-		padding-bottom: 10px;
-		padding-top: 10px;
-		padding-left: 0px;
-		padding-right: 0px;
-		margin: 0px;
-		border-top: 1px solid gray;
-	}
-	
-	#aikataulu tr:nth-child(even) {
-		background-color: #F8F8F8;
-	}
-	
-	#aikataulu tr.yö td
-	{
-		/*
-		background-color: #d8d8ff;
-		color: #008;
-		border-bottom: 1px solid #00A;
-		*/
-		background-color: #004;
-		color: #bef;
-		border-top: 1px solid #008;
-	}
-	
-	#aikataulu tr.yö:nth-child(even) td
-	{
-		background-color: #003;
-	}
-	
-	#pysäkki-info
-	{
-		text-align: center
-	}
-	
-	.pysäkki-sijainti
-	{
-		font-size: smaller;
-	}
-	
-	.sarake-määränpää
-	{
-		text-align: center;
-	}
+	p { text-align: center }
 	</style>
-	<title>{{viite}} {{nimi}}</title>
 </head>
 <body>
-	<h1>{{viite}} {{nimi}}</h1>
+	<h1>{{nimi}}</h1>
 	<p id="pysäkki-info">
 	{{alue or ""}}

 	<a class="pysäkki-sijainti" href="{{linkki_karttaan}}" target="_blank">📌 ({{sijainti}})</a>
 	</p>
+	<p>
+	<a href="/pysäkkiryhmä/{{cluster}}">Lähialueen aikataulu</a>
+	</p>
 	<table id='aikataulu' cellspacing="0">
 		<tr>
 			<th class='sarake-aika'>Aika</th>

mercurial