Sat, 10 Jun 2017 22:30:55 +0300
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>