From d939b2d0c182af2dd73bbd82005c2ff39cd1388a Mon Sep 17 00:00:00 2001 From: Markus Willman <mpewil@utu.fi> Date: Thu, 1 Mar 2018 00:20:04 +0200 Subject: [PATCH] fix commit 883a6b81034e0727cd89ce2e3667d55f0da35cfd - move old images into a separate directory - apiBusInfo uses POST requests from js so that we can include extra parameters from javascript and still use url_for() - fixes for shape drawing --- server/app.py | 27 +++--- server/gtfs.py | 14 +--- server/locator.py | 15 ++++ static/css/stylesheet.css | 2 +- .../application_placeholder.png} | Bin static/img/{ => old}/bus_icon.png | Bin static/img/{ => old}/bus_stop.png | Bin .../foli_placeholder.png} | Bin .../news_placeholder.png} | Bin .../timetables_placeholder.png} | Bin templates/map.html | 78 +++++++++++------- 11 files changed, 79 insertions(+), 57 deletions(-) rename static/img/{application_placeholder_old.png => old/application_placeholder.png} (100%) rename static/img/{ => old}/bus_icon.png (100%) rename static/img/{ => old}/bus_stop.png (100%) rename static/img/{foli_placeholder_old.png => old/foli_placeholder.png} (100%) rename static/img/{news_placeholder_old.png => old/news_placeholder.png} (100%) rename static/img/{timetables_placeholder_old.png => old/timetables_placeholder.png} (100%) diff --git a/server/app.py b/server/app.py index 4d2fa12..05eb97b 100644 --- a/server/app.py +++ b/server/app.py @@ -209,28 +209,25 @@ def apiStopInfo(version): # Get info on a specific bus: used in the map view when a bus is focused # URI: /api/v1/bus/<busId>/ -@app.route('/api/v<int:version>/bus/') +@app.route('/api/v<int:version>/bus/', methods=['POST']) @app.route('/api/v<int:version>/bus/<busId>/') -@app.route('/api/v<int:version>/bus/<busId>/<getShape>/') -def apiBusInfo(version, busId = None, getShape = "false"): - # busId is falsely optional here so that we can easily use url_for() for this endpoint in js - if int(version) == 1 and busId != None: - lastModified, data = locator.getLastResponse() - if not data or data.get('status', None) != 'OK': - return {} +@app.route('/api/v<int:version>/bus/<busId>/<int:getShape>/') +def apiBusInfo(version, busId = None, getShape = None): + if int(version) == 1: + if busId == None: + busId = request.form.get('bus_id', default = None, type = str) + if getShape == None: + getShape = request.form.get('get_shape', default = 0, type = int) - data = data['result'] - vehicles = data.get('vehicles', None) - if not vehicles: - return {} + if not busId: + abort(400) - data = vehicles[busId] + lastModified, data = locator.getVehicle(busId) # add shapes to the data # route_short_name = lineref from data - if (getShape == "true"): + if data and getShape != 0: # FIXME: in theory this can contain shape information for multiple trips, since route_short_name doesn't have to be and isn't unique to one trip in GTFS - # blockref from SIRI VM is the trip_id in GTFS, this is clearly a Föli implementation detail and as such lineref remains as fallback data["shapes"] = gtfs.getTripShapes(data["lineref"], data["blockref"]) if data: diff --git a/server/gtfs.py b/server/gtfs.py index 372ea72..1443a55 100644 --- a/server/gtfs.py +++ b/server/gtfs.py @@ -347,12 +347,12 @@ class GtfsHandler(object): return stop.stop_timezone # predicate function used to filter out trips not currently in service, will only retain trips of particular route or named trip - def _namedInactivePredicate(self, trip, lineref = None, now = None): + def _namedInactivePredicate(self, trip, lineref = None, blockref = None, now = None): # FIXME: not tied to any specifc stop, so server time (ie. UTC most likely under docker) if not now: now = datetime.now(tzlocal()) - if not lineref: + if not lineref and not blockref: return self._inactivePredicate(trip, now) short_name = trip.trip_short_name @@ -360,16 +360,10 @@ class GtfsHandler(object): route = self.schedule.GetRoute(trip.route_id) short_name = route.route_short_name if route.route_short_name else route.route_id - return short_name == lineref and self._inactivePredicate(trip, now) + return (not short_name or short_name == lineref) and (not blockref or blockref == trip.block_id) and self._inactivePredicate(trip, now) def getTripShapes(self, lineref, blockref = None): - # blockref from SIRI VM being trip_id is Föli implementation detail, which is why lineref is retained as fallback - if blockref: - trip = self.schedule.GetTrip(blockref) - if trip: - return [self.schedule.GetShape(trip.shape_id).points] - - shapes = (self.schedule.GetShape(trip.shape_id) for trip in self.schedule.GetTripList() if self._namedInactivePredicate(trip, lineref)) + shapes = (self.schedule.GetShape(trip.shape_id) for trip in self.schedule.GetTripList() if self._namedInactivePredicate(trip, lineref, blockref)) return {s.shape_id:s.points for s in shapes}.values() def setLocator(self, locatorService): diff --git a/server/locator.py b/server/locator.py index dc33b68..e69b315 100644 --- a/server/locator.py +++ b/server/locator.py @@ -72,6 +72,9 @@ class PollingThreadReader(object): def getNearbyVehicles(self, lat, lon, maxDist): pass + def getVehicle(self, vehicleId): + pass + class FoliLocator(PollingThreadReader): def _linePredicate(self, vehicle, lines): line = vehicle['publishedlinename'] @@ -110,3 +113,15 @@ class FoliLocator(PollingThreadReader): return (modified, {}) return (modified, {v['vehicleref']:v for v in vehicles.values() if self._distancePredicate(v, lat, lon, maxDist)}) + + def getVehicle(self, vehicleId): + modified, data = self.getLastResponse() + if not data or data.get('status', None) != 'OK': + return (modified, {}) + + data = data['result'] + vehicles = data.get('vehicles', None) + if not vehicles: + return (modified, {}) + + return (modified, vehicles.get(vehicleId, {})) diff --git a/static/css/stylesheet.css b/static/css/stylesheet.css index 76bc671..a861364 100644 --- a/static/css/stylesheet.css +++ b/static/css/stylesheet.css @@ -120,7 +120,7 @@ body { } .dynamicContentHeader { - background: url("../img/dynamic_content_placeholder.jpg"); + background: url("../img/SBS-logo.png"); background-size: 100% 100%; } diff --git a/static/img/application_placeholder_old.png b/static/img/old/application_placeholder.png similarity index 100% rename from static/img/application_placeholder_old.png rename to static/img/old/application_placeholder.png diff --git a/static/img/bus_icon.png b/static/img/old/bus_icon.png similarity index 100% rename from static/img/bus_icon.png rename to static/img/old/bus_icon.png diff --git a/static/img/bus_stop.png b/static/img/old/bus_stop.png similarity index 100% rename from static/img/bus_stop.png rename to static/img/old/bus_stop.png diff --git a/static/img/foli_placeholder_old.png b/static/img/old/foli_placeholder.png similarity index 100% rename from static/img/foli_placeholder_old.png rename to static/img/old/foli_placeholder.png diff --git a/static/img/news_placeholder_old.png b/static/img/old/news_placeholder.png similarity index 100% rename from static/img/news_placeholder_old.png rename to static/img/old/news_placeholder.png diff --git a/static/img/timetables_placeholder_old.png b/static/img/old/timetables_placeholder.png similarity index 100% rename from static/img/timetables_placeholder_old.png rename to static/img/old/timetables_placeholder.png diff --git a/templates/map.html b/templates/map.html index 8be5119..7310570 100644 --- a/templates/map.html +++ b/templates/map.html @@ -70,7 +70,7 @@ // focusedMarker is the title of the focused marker var focusedMarker = undefined; var focusedBus = undefined; - var focusedShape = undefined; + var mapShapes = []; var focusedBusWindow = undefined; var apiEndpoint = "{{ url_for('apiLocatorService', version = 1, stopId = stop_info.stop_id, type = 'nearby', _external = True) }}"; var trackingLoop = null; @@ -172,10 +172,6 @@ console.log('stopped from double click'); return; } - if (focusedShape !== undefined) { - focusedShape.setMap(null); - focusedShape = undefined; - } } focusedMarker = marker.title; @@ -200,10 +196,13 @@ marker.setMap(null); focusedMarker = undefined; focusedBus = undefined; - if (focusedShape !== undefined) { - focusedShape.setMap(null); - focusedShape = undefined; - } + + $.each(mapShapes, function( key, value ) { + if (value !== undefined) { + value.setMap(null); + } + }); + mapShapes = []; } markers = {}; @@ -271,10 +270,19 @@ } }); + console.log('mapShapes ', mapShapes); + $.each(mapShapes, function( key, value ) { + if (value !== undefined) { + value.setMap(null); + } + }); + mapShapes = []; + // get information about the focused bus var requestFocus = focusedMarker; - $.getJSON( - "{{ url_for('apiBusInfo', version = 1, _external = True) }}" + focusedMarker + '/true', + $.post( + "{{ url_for('apiBusInfo', version = 1, _external = True) }}", + { bus_id: requestFocus, get_shape: 1 }, function (data) { // poor man's locking (the A in Ajax is for Asynchronous :)) if (requestFocus !== focusedMarker) @@ -284,22 +292,24 @@ console.log("found this bus info: ", focusedBus); // draw the shape - var shapeCoordinates = []; $.each(focusedBus.shapes, function (key, value) { + var shapeCoordinates = []; value.map( value => { shapeCoordinates.push(positionToGoogleLatLng(value[0], value[1])); }); - }); - focusedShape = new google.maps.Polyline({ - map: gmap, - path: shapeCoordinates, - strokeColor: "#FF0000", - strokeOpacity: 1.0, - strokeWeight: 2 + mapShapes.push(new google.maps.Polyline({ + map: gmap, + path: shapeCoordinates, + strokeColor: "#FF0000", + strokeOpacity: 1.0, + strokeWeight: 2 + })); }); - updateInfoWindow(); - } + + updateInfoWindow(true); + }, + 'json' ); marker = gmarkers[focusedMarker]; @@ -313,35 +323,38 @@ }; var drawOneBus = function() { - $.getJSON( - "{{ url_for('apiBusInfo', version = 1, _external = True) }}" + focusedMarker + '/false', - function (resultData) { + var requestFocus = focusedMarker; + $.post( + "{{ url_for('apiBusInfo', version = 1, _external = True) }}", + { bus_id: requestFocus, get_shape: 0 }, + function (data) { // poor man's locking - if (trackingLoop === null) + if (trackingLoop === null || requestFocus !== focusedMarker) return; // if the focused bus disappeared from the list, just go back to the 'all' mode - if ($.isEmptyObject(resultData) || gmarkers[focusedMarker] === undefined) { + if ($.isEmptyObject(data) || gmarkers[focusedMarker] === undefined) { console.log('lost track of the bus, going back to normal mode'); mapClicked(); } else { // getting here means that the bus is still active // => update its position marker = gmarkers[focusedMarker]; - focusedBus = resultData; + focusedBus = data; updateInfoWindow(); // get more information about the bus - position = positionToGoogleLatLng(resultData.latitude, resultData.longitude); + position = positionToGoogleLatLng(data.latitude, data.longitude); marker.setPosition(position); gmap.panTo(position); } - } + }, + 'json' ) }; // creates or updates the info window for focused bus - var updateInfoWindow = function() { + var updateInfoWindow = function(recreate = false) { // TODO is there a better way of doing this, this way is pretty ugly var infoWindowContent = ` <h1>` + focusedBus.lineref + `</h1> @@ -350,7 +363,10 @@ Expected Arrival: ` + focusedBus.next_expectedarrivaltime + ` <br> `; - if (focusedBusWindow === undefined) { + if (focusedBusWindow === undefined || recreate) { + if (focusedBusWindow !== undefined) + focusedBusWindow.close(); + focusedBusWindow = new google.maps.InfoWindow({ content: infoWindowContent }); -- GitLab