From 643fc3c2e9465123611cc5f166f2dabe4d5fad14 Mon Sep 17 00:00:00 2001 From: Hubert goEuropa Date: Thu, 1 Jul 2021 22:36:47 +0200 Subject: [PATCH 01/14] Improving translations, adding OSM with configuration, some mysql error fix --- .../org/transitclock/i18n/text.properties | 39 +- .../org/transitclock/i18n/text_pl.properties | 45 ++- .../src/main/webapp/map/javascript/avlMap.js | 2 +- .../src/main/webapp/map/map.jsp | 3 +- .../src/main/webapp/map/testMap.html | 3 +- .../src/main/webapp/reports/avlMap.jsp | 2 +- .../reports/javascript/avlMapJavascript.jsp | 366 ++++++++++++++++++ .../src/main/webapp/reports/lastAvlReport.jsp | 2 +- .../main/webapp/reports/params/vehicle.jsp | 2 +- .../reports/predAccuracyIntervalsChart.jsp | 18 +- .../webapp/reports/predAccuracyRangeChart.jsp | 30 +- .../webapp/reports/schAdhByRouteChart.jsp | 42 +- .../main/webapp/reports/schAdhByStopChart.jsp | 43 +- .../main/webapp/reports/schAdhByTimeChart.jsp | 34 +- .../main/webapp/reports/schAdhByTimeData.jsp | 2 +- .../reports/scheduleHorizStopsReport.jsp | 5 +- 16 files changed, 552 insertions(+), 86 deletions(-) create mode 100644 transitclockWebapp/src/main/webapp/reports/javascript/avlMapJavascript.jsp diff --git a/transitclockWebapp/src/main/resources/org/transitclock/i18n/text.properties b/transitclockWebapp/src/main/resources/org/transitclock/i18n/text.properties index 9b5aaea3e..36e62dc32 100644 --- a/transitclockWebapp/src/main/resources/org/transitclock/i18n/text.properties +++ b/transitclockWebapp/src/main/resources/org/transitclock/i18n/text.properties @@ -200,4 +200,41 @@ div.Adh = Adh: div.Headsign = Headsign div.Start = Start: div.End = End: -div.Service = Service: \ No newline at end of file +div.Service = Service: +PredictionAccuracyRangeFor = Prediction Accuracy Range for +PredictionAccuracyRangeForRoute = route +Predictions = predictions +PlurarDaySuffix = s +DayGenitive = day +Days = days +NoDataForParameters = No data for requested parameters. Hit back button to try other parameters. +PredictionsWithinRange = % of Predictions Within Range +PredictionLengthInMinutes = Prediction Length (minutes) +Error = Error +EarlierThanPredicted_MoreThan = Earlier than predicted (more than +SecsEarly_ = secs early) +WithinBounds_ = Within Bounds ( +SecsEarlyTo = secs early to +SecsLate_ = secs late) +LaterThanPredicted_MoreThan = Later than predicted (more than +PredictionAccuracySecs = Prediction Accuracy (secs) (positive means vehicle later than predicted) +EarlierThanPredicted = Earlier than predicted +SecsEarly = secs early +WithinBounds = Within Bounds +SecsLate = secs late +LaterThanPredicted = Later than predicted +Points = points +TooLate = Too Late +AllVehicles = All Vehicles +AssigmentId = Assigment ID +MinEarlyTo = min early to +To = to +Stops = stops +StopsBig = Stops +ScheduleAdherenceFor = Schedule Adherence for +EarlyLate = Early/Late +StopsUnderEq4ForVehiclesThatAre = stops for vehicles that are +StopsOver4ForVehiclesThatAre = stops for vehicles that are +NumberOfStopsPerTimeInterval = Number of stops per time interval +MinutesVehicleLateNOrEarlyPositive = Minutes vehicle late (negative) or early (positive) +Undefined = undefined \ No newline at end of file diff --git a/transitclockWebapp/src/main/resources/org/transitclock/i18n/text_pl.properties b/transitclockWebapp/src/main/resources/org/transitclock/i18n/text_pl.properties index 47f897370..feb4b60c6 100644 --- a/transitclockWebapp/src/main/resources/org/transitclock/i18n/text_pl.properties +++ b/transitclockWebapp/src/main/resources/org/transitclock/i18n/text_pl.properties @@ -65,8 +65,8 @@ div.veh = Pojazdy div.roude = Szczeg\u00f3\u0142y trasy div.rou = Trasy div.spfpbla = Wybierz parametry dla przeiwdywania lokacji API -div.lat = D\u0142ugo\u015b\u0107 geograficzna: -div.lon = Szeroko\u015b\u0107 geograficzna: +div.lat = D\u0142ugo\u015b\u0107 geograficzna +div.lon = Szeroko\u015b\u0107 geograficzna div.md = Maksymalny dystans: div.mdf = metry ( domy\u015blnie 1500m ) div.np = Prognoza numer\u00f3w: @@ -140,7 +140,7 @@ div.spdavld = Wybierz parametry by wy\u015bwietli\u0107 dane AVL na mapie wed\u0 div.spdavlbv = Wybierz parametry by wy\u015bwietli\u0107 dane AVL na mapie wed\u0142ug pojazdu div.lgpsr = Ostatnie raporty GPS przez ostatnie 24 godziny div.spfsr = Wybierz parametry dla raportu rozk\u0142adu -div.lgps = Last GPS +div.lgps = Data ostatniego odczytu div.selectroute = Wybierz lini\u0119 div.droute = Linia div.dstop = Przystanek @@ -200,4 +200,41 @@ div.Adh = Odch.: div.Headsign = Kierunek div.Start = Start: div.End = Koniec: -div.Service = Kalendarz: \ No newline at end of file +div.Service = Kalendarz: +PredictionAccuracyRangeFor = Wykres zakresu dok\u0142adno\u015Bci prognozy dla linii +PredictionAccuracyRangeForRoute = +Predictions = prognozy +DayGenitive = dnia +Days = dni +NoDataForParameters = Brak danych dla wybranych parametrów. Cofnij i wybierz inne parametry. +PredictionsWithinRange = % prognoz w zakresie +PredictionLengthInMinutes = D\u0142ugo\u015B\u0107 prognozy (w minutach) +Error = B\u0142\u0105d +EarlierThanPredicted_MoreThan = Wcze\u015Bniej ni\u017C prognozowano(> +SecsEarly_ = sekund wcze\u015Bniej) +WithinBounds_ = W zakresie (od +SecsEarlyTo = sekund wcze\u015Bniej do +SecsLate_ = sekund pó\u017Aniej) +LaterThanPredicted_MoreThan = Pó\u017Aniej ni\u017C prognozowano (> +PredictionAccuracySecs = Dok\u0142adno\u015B\u0107 prognozy (sek) (warto\u015B\u0107 pozytywna oznacza pojazd pó\u017Aniej ni\u017C prognozowano) +EarlierThanPredicted = Wcze\u015Bniej ni\u017C prognozowano +SecsEarly = sekund wcze\u015Bniej +WithinBounds = W zakresie +SecsLate = sekund pó\u017Aniej +LaterThanPredicted = Pó\u017Aniej ni\u017C prognozowano +Points = punktów +TooLate = Za pó\u017Ano +AllVehicles = Wszystkie pojazdy +TimeProc = Czas proces. +AssigmentId = Assigment ID +MinEarlyTo = min wcze\u015Bniej do +To = do +Stops = przystanków +StopsBig = Przystanki +ScheduleAdherenceFor = Przestrzeganie rozk\u0142adu dla +EarlyLate = Wcze\u015Bniej/Pó\u017Aniej +StopsUnderEq4ForVehiclesThatAre = przystanki dla pojazdów, które s\u0105 od +StopsOver4ForVehiclesThatAre = przystanków dla pojazdów, które s\u0105 od +NumberOfStopsPerTimeInterval = Liczba przystanków na interwa\u0142 czasowy +MinutesVehicleLateNOrEarlyPositive = Minut pojazd pó\u017Aniej (negatywna) lub wcze\u015Bniej (pozytywna) +Undefined = nieokre\u015Blony \ No newline at end of file diff --git a/transitclockWebapp/src/main/webapp/map/javascript/avlMap.js b/transitclockWebapp/src/main/webapp/map/javascript/avlMap.js index 8e68439fd..616c5e8d8 100644 --- a/transitclockWebapp/src/main/webapp/map/javascript/avlMap.js +++ b/transitclockWebapp/src/main/webapp/map/javascript/avlMap.js @@ -40,7 +40,7 @@ function drawAvlMarker(avl) { // Create popup with detailed info - var labels = ["Vehicle", "GPS Time", "Time Proc", "Lat/Lon", "Speed", "Heading", "Assignment ID"], + var labels = ["Vehicles", "GPS Time", "Time Proc", "Lat/Lon", "Speed", "Heading", "Assignment ID"], keys = ["vehicleId", "time", "timeProcessed", "latlon", "niceSpeed", "heading", "assignmentId"]; // populate missing keys diff --git a/transitclockWebapp/src/main/webapp/map/map.jsp b/transitclockWebapp/src/main/webapp/map/map.jsp index ef0fb955a..e6cd317c4 100644 --- a/transitclockWebapp/src/main/webapp/map/map.jsp +++ b/transitclockWebapp/src/main/webapp/map/map.jsp @@ -800,9 +800,10 @@ if (!agencyId) alert("You must specify agency in URL using a=agencyId parameter"); // Create the map with a scale and specify which map tiles to use +var mapTileUrl = <%=System.getProperty("transitclock.mapTileUrl")%> var map = L.map('map'); L.control.scale({metric: false}).addTo(map); -L.tileLayer('http://api.tiles.mapbox.com/v4/transitime.j1g5bb0j/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoidHJhbnNpdGltZSIsImEiOiJiYnNWMnBvIn0.5qdbXMUT1-d90cv1PAIWOQ', { +L.tileLayer(mapTileUrl, { // Specifying a shorter version of attribution. Original really too long. //attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', attribution: '© OpenStreetMap & CC-BY-SA, Imagery © Mapbox', diff --git a/transitclockWebapp/src/main/webapp/map/testMap.html b/transitclockWebapp/src/main/webapp/map/testMap.html index 4d062764c..b5c8a2487 100644 --- a/transitclockWebapp/src/main/webapp/map/testMap.html +++ b/transitclockWebapp/src/main/webapp/map/testMap.html @@ -48,9 +48,10 @@ - + diff --git a/transitclockWebapp/src/main/webapp/reports/javascript/avlMapJavascript.jsp b/transitclockWebapp/src/main/webapp/reports/javascript/avlMapJavascript.jsp new file mode 100644 index 000000000..c9f6ecddb --- /dev/null +++ b/transitclockWebapp/src/main/webapp/reports/javascript/avlMapJavascript.jsp @@ -0,0 +1,366 @@ +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> + + + + + + diff --git a/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp b/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp index f6e00434c..faeec31b7 100644 --- a/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp +++ b/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp @@ -56,7 +56,7 @@ $( document ).ready(function() { <%@include file="/template/header.jsp" %>
- +
\ No newline at end of file diff --git a/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp b/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp index a36365b2f..8a966b96d 100644 --- a/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp +++ b/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp @@ -22,7 +22,7 @@ $.getJSON(apiUrlPrefix + "/command/vehicleIds", function(vehicles) { // Generate list of routes for the selector - var selectorData = [{id: '', text: 'All Vehicles'}]; + var selectorData = [{id: '', text: ''}]; for (var i in vehicles.ids) { var id = vehicles.ids[i]; selectorData.push({id: id, text: id}) diff --git a/transitclockWebapp/src/main/webapp/reports/predAccuracyIntervalsChart.jsp b/transitclockWebapp/src/main/webapp/reports/predAccuracyIntervalsChart.jsp index 62e44937d..cb22e882a 100644 --- a/transitclockWebapp/src/main/webapp/reports/predAccuracyIntervalsChart.jsp +++ b/transitclockWebapp/src/main/webapp/reports/predAccuracyIntervalsChart.jsp @@ -2,10 +2,13 @@ pageEncoding="UTF-8"%> <%@ page import="org.transitclock.utils.web.WebUtils" %> +<%@page import="java.util.ResourceBundle" %> +<%@page import="java.util.Locale" %> <%@page import="org.transitclock.db.webstructs.WebAgency"%> <% // Determine all the parameters from the query string +ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", request.getLocale()); // Determine agency using "a" param String agencyId = request.getParameter("a"); @@ -15,7 +18,7 @@ String agencyId = request.getParameter("a"); String routeIds[] = request.getParameterValues("r"); String titleRoutes = ""; if (routeIds != null && !routeIds[0].isEmpty()) { - titleRoutes += ", route "; + titleRoutes += ", " + labels.getString("PredictionAccuracyRangeForRoute"); if (routeIds.length > 1) titleRoutes += "s"; titleRoutes += routeIds[0]; @@ -27,7 +30,10 @@ if (routeIds != null && !routeIds[0].isEmpty()) { String sourceParam = request.getParameter("source"); String source = (sourceParam != null && !sourceParam.isEmpty()) ? - ", " + sourceParam + " predictions" : ""; + request.getLocale().toString() == "pl_PL" ? + ", " + labels.getString("Predictions") + " " + sourceParam + : ", " + sourceParam + " " + labels.getString("Predictions") + : ""; String beginDate = request.getParameter("beginDate"); String numDays = request.getParameter("numDays"); String beginTime = request.getParameter("beginTime"); @@ -37,7 +43,7 @@ String chartTitle = "Prediction Accuracy for " + WebAgency.getCachedWebAgency(agencyId).getAgencyName() + titleRoutes + source - + ", " + beginDate + " for " + numDays + " day" + (Integer.parseInt(numDays) > 1 ? "s" : ""); + + ", " + beginDate + " " + labels.getString("div.for") + " " + numDays + " " + (Integer.parseInt(numDays) > 1 ? labels.getString("Days") : labels.getString("DayGenitive")); if ((beginTime != null && !beginTime.isEmpty()) || (endTime != null && !endTime.isEmpty())) { chartTitle += ", " + beginTime + " to " + endTime; @@ -124,7 +130,7 @@ if ((beginTime != null && !beginTime.isEmpty()) || (endTime != null && !endTime. // When there is an AJAX problem alert the user error: function(request, status, error) { console.log(request.responseText) - var msg = $("

").html("
No data for requested parameters. Hit back button to try other parameters.") + var msg = $("

").html("
") $("#errorMessage").append(msg); $("#errorMessage").fadeIn("slow"); }, @@ -155,7 +161,7 @@ if ((beginTime != null && !beginTime.isEmpty()) || (endTime != null && !endTime. // Make chart a bit graay so that it stands out backgroundColor: '#f2f2f2'}, hAxis: { - title: 'Prediction Length (minutes)', + title: '', // So that last column is labeled maxValue: 15, // Want a gridline for every minute, not just the default of 5 gridlines @@ -163,7 +169,7 @@ if ((beginTime != null && !beginTime.isEmpty()) || (endTime != null && !endTime. // Nice to show a faint line for every 30 seconds as well minorGridlines: {count: 1} }, - vAxis: {title: 'Prediction Accuracy (secs) (postive means vehicle later than predicted)', + vAxis: {title: '', // Try to show accuracy on a consistent vertical axis and // divide into minutes. This unfortunately won't work well // if values are greater than 300 because then chart will diff --git a/transitclockWebapp/src/main/webapp/reports/predAccuracyRangeChart.jsp b/transitclockWebapp/src/main/webapp/reports/predAccuracyRangeChart.jsp index cf0a97c52..9c94aa61f 100644 --- a/transitclockWebapp/src/main/webapp/reports/predAccuracyRangeChart.jsp +++ b/transitclockWebapp/src/main/webapp/reports/predAccuracyRangeChart.jsp @@ -1,9 +1,12 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="org.transitclock.utils.web.WebUtils" %> +<%@page import="java.util.ResourceBundle" %> +<%@page import="java.util.Locale" %> <%@page import="org.transitclock.db.webstructs.WebAgency"%> <% // Determine all the parameters from the query string +ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", request.getLocale()); // Determine agency using "a" param String agencyId = request.getParameter("a"); @@ -13,7 +16,7 @@ String agencyId = request.getParameter("a"); String routeIds[] = request.getParameterValues("r"); String titleRoutes = ""; if (routeIds != null && !routeIds[0].isEmpty()) { - titleRoutes += ", route "; + titleRoutes += ", " + labels.getString("PredictionAccuracyRangeForRoute"); if (routeIds.length > 1) titleRoutes += "s"; titleRoutes += routeIds[0]; @@ -25,18 +28,21 @@ if (routeIds != null && !routeIds[0].isEmpty()) { String sourceParam = request.getParameter("source"); String source = (sourceParam != null && !sourceParam.isEmpty()) ? - ", " + sourceParam + " predictions" : ""; + request.getLocale().toString() == "pl_PL" ? + ", " + labels.getString("Predictions") + " " + sourceParam + : ", " + sourceParam + " " + labels.getString("Predictions") + : ""; String beginDate = request.getParameter("beginDate"); String numDays = request.getParameter("numDays"); if (numDays == null) numDays = "1"; String beginTime = request.getParameter("beginTime"); String endTime = request.getParameter("endTime"); -String chartTitle = "Prediction Accuracy Range for " +String chartTitle = labels.getString("PredictionAccuracyRangeFor") + " " + WebAgency.getCachedWebAgency(agencyId).getAgencyName() + titleRoutes + source - + ", " + beginDate + " for " + numDays + " day" + (Integer.parseInt(numDays) > 1 ? "s" : ""); + + ", " + beginDate + " " + labels.getString("div.for") + " " + numDays + " " + (Integer.parseInt(numDays) > 1 ? labels.getString("Days") : labels.getString("DayGenitive")); if ((beginTime != null && !beginTime.isEmpty()) || (endTime != null && !endTime.isEmpty())) { chartTitle += ", " + beginTime + " to " + endTime; @@ -129,7 +135,7 @@ function getDataTable() { // When there is an AJAX problem alert the user error: function(request, status, error) { console.log(request.responseText) - var msg = $("

").html("
No data for requested parameters. Hit back button to try other parameters.") + var msg = $("

").html("
") $("#errorMessage").append(msg); $("#errorMessage").fadeIn("slow"); }, @@ -152,7 +158,7 @@ function drawChart() { // Make chart a bit graay so that it stands out backgroundColor: '#f2f2f2'}, hAxis: { - title: 'Prediction Length (minutes)', + title: '', // So that last column is labeled maxValue: 15, // Want a gridline for every minute, not just the default of 5 gridlines @@ -161,7 +167,7 @@ function drawChart() { minorGridlines: {count: 1} }, vAxis: { - title: '% of Predictions Within Range', + title: '', maxValue: 100, // Specify ticks so that when column adds up to just over 100% the horizontal // part of chart not increased to 120% to accomodate it. @@ -187,10 +193,10 @@ function parseSummary(data) { results.push(d); }); document.getElementById('summary').innerHTML = "Schedule Adherence over " + results[0] + " arrival and departures
" - + "Early: " + results[1] - + "% OnTime: " + results[2] - + "% Late: " + results[3] + "%"; - + + "" + ": " + results[1] + + "% : " + results[2] + + "% : " + results[3] + "%"; + } function formatQueryParams() { @@ -201,7 +207,7 @@ function showSummary() { $("#summary").show(); $.get("data/summaryScheduleAdherence.jsp?"+formatQueryParams(), parseSummary) .fail(function() { - document.getElementById('summary').innerHTML ="Error!"; + document.getElementById('summary').innerHTML =""; }); } diff --git a/transitclockWebapp/src/main/webapp/reports/schAdhByRouteChart.jsp b/transitclockWebapp/src/main/webapp/reports/schAdhByRouteChart.jsp index 2e54b2e92..cf82e2fcf 100644 --- a/transitclockWebapp/src/main/webapp/reports/schAdhByRouteChart.jsp +++ b/transitclockWebapp/src/main/webapp/reports/schAdhByRouteChart.jsp @@ -1,6 +1,8 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="org.transitclock.utils.web.WebUtils" %> +<%@page import="java.util.ResourceBundle" %> +<%@page import="java.util.Locale" %> @@ -50,11 +52,12 @@ <%@include file="/template/header.jsp" %> <% - String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " days)"; - String allowableEarly = request.getParameter("allowableEarly");; - String allowableLate = request.getParameter("allowableLate");; - String chartSubtitle = allowableEarly + " min early to " - + allowableLate + " min late
" + dateRange; + ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", request.getLocale()); + String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " " + labels.getString("Days") + ")"; + String allowableEarly = request.getParameter("allowableEarly"); + String allowableLate = request.getParameter("allowableLate"); + String chartSubtitle = allowableEarly + " " + labels.getString("MinEarlyTo") + " " + + allowableLate + " " + labels.getString("div.minlate") + "
" + dateRange; String beginTime = request.getParameter("beginTime"); String endTime = request.getParameter("endTime"); @@ -63,11 +66,10 @@ beginTime = "00:00"; // default value if (endTime.isEmpty()) endTime = "24:00"; // default value - chartSubtitle += ", " + beginTime + " to " + endTime; + chartSubtitle += ", " + beginTime + " " + labels.getString("To") + " " + endTime; } %> - -

Schedule Adherence by Route
+
<%= chartSubtitle %>
@@ -136,10 +138,10 @@ var globalNumberOfRoutes; function createDataTableAndDrawChart(jsonData) { // Initialize dataArray with the column info var dataArray = [[ - 'Route', - 'Late', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, - 'On Time', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, - 'Early', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'} + '', + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'} ]]; // Add data for each route to the dataArray @@ -155,15 +157,15 @@ var globalNumberOfRoutes; route.name, latePercent, 'opacity: 1.0', - 'Late: ' + route.late + ' out of ' + route.total + ' stops', + '' + ': ' + route.late + ' ' + '' + ' ' + route.total + ' ' + '', route.late > 0 ? latePercent.toFixed(1) + '%' : '', ontimePercent, 'opacity: 1.0', - 'On time: ' + route.ontime + ' out of ' + route.total + ' stops', + '' + ': ' + route.ontime + ' ' + '' + ' ' + route.total + ' ' + '', route.ontime > 0 ? ontimePercent.toFixed(1) + '%' : '', earlyPercent, 'opacity: 1.0', - 'Early: ' + route.early + ' out of ' + route.total + ' stops', + '' + ': ' + route.early + ' ' + '' + ' ' + route.total + ' ' + '', (route.early > 0) ? earlyPercent.toFixed(1) + '%' : '' ]; dataArray.push(dataArrayForRoute); @@ -180,18 +182,18 @@ var globalNumberOfRoutes; var ontimePercent = (100.0 * totalOntime / totalTotal); var latePercent = (100.0 * totalLate / totalTotal); var dataArrayForRoute = [ - 'Combined', + '', latePercent, 'opacity: 1.0', - 'Late: ' + totalLate + ' out of ' + totalTotal + ' stops', + '' + ': ' + totalLate + ' ' + '' + ' ' + totalTotal + ' ' + '', latePercent.toFixed(1) + '%', ontimePercent, 'opacity: 1.0', - 'On time: ' + totalOntime + ' out of ' + totalTotal + ' stops', + '' + ': ' + totalOntime + ' ' + '' + ' ' + totalTotal + ' ' + '', ontimePercent.toFixed(1) + '%', earlyPercent, 'opacity: 1.0', - 'Early: ' + totalEarly + ' out of ' + totalTotal + ' stops', + '' + ': ' + totalEarly + ' ' + '' + ' ' + totalTotal + ' ' + '', earlyPercent.toFixed(1) + '%' ]; dataArray.push(dataArrayForRoute); @@ -221,7 +223,7 @@ var globalNumberOfRoutes; // When there is an AJAX problem alert the user error: function(request, status, error) { console.log(request.responseText) - var msg = $("

").html("
No data for requested parameters. Hit back button to try other parameters.") + var msg = $("

").html("
") $("#errorMessage").append(msg);; $("#errorMessage").fadeIn("fast"); $("#loading").fadeOut("slow"); diff --git a/transitclockWebapp/src/main/webapp/reports/schAdhByStopChart.jsp b/transitclockWebapp/src/main/webapp/reports/schAdhByStopChart.jsp index 7438a7cdf..7b1a98d32 100644 --- a/transitclockWebapp/src/main/webapp/reports/schAdhByStopChart.jsp +++ b/transitclockWebapp/src/main/webapp/reports/schAdhByStopChart.jsp @@ -1,6 +1,8 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="org.transitclock.utils.web.WebUtils" %> +<%@page import="java.util.ResourceBundle" %> +<%@page import="java.util.Locale" %> @@ -53,6 +55,7 @@

+
@@ -66,9 +69,10 @@ var vertSpaceForChart = (numberOfStops + 1) * 22; var chartDivHeight = vertSpaceForTitleAndHAxis + vertSpaceForChart; $("#" + divId).height(chartDivHeight); + var directionTitle = (directionId == 0 || directionId == 1) ? '' + ': ' + directionId : ''; var options = { - title: 'Direction: ' + directionId, + title: directionTitle, titleTextStyle: { fontSize: 22, bold: false @@ -123,11 +127,11 @@ function createDataTableAndDrawChartForDirection(stopsData) { // Initialize dataArray with the column info var dataArray = [[ - 'Stop', - 'Late', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, - 'On Time', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, - 'Early', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'} - ]]; + '', + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'}, + '', {role: 'style'}, { role: 'tooltip'}, { role: 'annotation'} + ]]; // Add data for each route to the dataArray var totalEarly = 0; @@ -142,15 +146,15 @@ stop.stop_name + ' ', latePercent, 'opacity: 1.0', - 'Late: ' + stop.late + ' out of ' + stop.total + ' times', + '' + ': ' + stop.late + ' ' + '' + ' ' + stop.total + ' ' + '', stop.late > 0 ? latePercent.toFixed(1) + '%' : '', ontimePercent, 'opacity: 1.0', - 'On time: ' + stop.ontime + ' out of ' + stop.total + ' times', + '' + ': ' + stop.ontime + ' ' + '' + ' ' + stop.total + ' ' + '', stop.ontime > 0 ? ontimePercent.toFixed(1) + '%' : '', earlyPercent, 'opacity: 1.0', - 'Early: ' + stop.early + ' out of ' + stop.total + ' times', + '' + ': ' + stop.early + ' ' + '' + ' ' + stop.total + ' ' + '', (stop.early > 0) ? earlyPercent.toFixed(1) + '%' : '' ]; dataArray.push(dataArrayForStop); @@ -169,15 +173,15 @@ 'Total: ', latePercent, 'opacity: 1.0', - 'Late: ' + totalLate + ' out of ' + totalTotal + ' times', + '' + ': ' + totalLate + ' ' + '' + ' ' + totalTotal + ' ' + '', latePercent.toFixed(1) + '%', ontimePercent, 'opacity: 1.0', - 'On time: ' + totalOntime + ' out of ' + totalTotal + ' times', + '' + ': ' + totalOntime + ' ' + '' + ' ' + totalTotal + ' ' + '', ontimePercent.toFixed(1) + '%', earlyPercent, 'opacity: 1.0', - 'Early: ' + totalEarly + ' out of ' + totalTotal + ' times', + '' + ': ' + totalEarly + ' ' + '' + ' ' + totalTotal + ' ' + '', earlyPercent.toFixed(1) + '%' ]; dataArray.push(dataArrayForStop); @@ -226,11 +230,12 @@ var routeName = routeData.routes[0].name; <% - String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " days)"; - String allowableEarly = request.getParameter("allowableEarly");; - String allowableLate = request.getParameter("allowableLate");; + ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", request.getLocale()); + String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " " + labels.getString("Days") + ")"; + String allowableEarly = request.getParameter("allowableEarly"); + String allowableLate = request.getParameter("allowableLate"); String chartParams = - allowableEarly + " min early to " + allowableLate + " min late
" + allowableEarly + " " + labels.getString("MinEarlyTo") + " " + allowableLate + " " + labels.getString("div.minlate") + "
" + dateRange; String beginTime = request.getParameter("beginTime"); @@ -240,11 +245,11 @@ beginTime = "00:00"; // default value if (endTime.isEmpty()) endTime = "24:00"; // default value - chartParams += ", " + beginTime + " to " + endTime; + chartParams += ", " + beginTime + " " + labels.getString("To") + " " + endTime; } %> - $("#title").html('Schedule Adherence for ' + routeName); + $("#title").html('' + ' ' + routeName); $("#subtitle").html('<%= chartParams %>'); } @@ -266,7 +271,7 @@ // When there is an AJAX problem alert the user error: function(request, status, error) { console.log(request.responseText) - var msg = $("

").html("
No data for requested parameters. Hit back button to try other parameters.") + var msg = $("

").html("
") $("#errorMessage").append(msg); $("#errorMessage").fadeIn("fast"); $("#loading").fadeOut("slow"); diff --git a/transitclockWebapp/src/main/webapp/reports/schAdhByTimeChart.jsp b/transitclockWebapp/src/main/webapp/reports/schAdhByTimeChart.jsp index 2bfbf8038..c8637f0cc 100644 --- a/transitclockWebapp/src/main/webapp/reports/schAdhByTimeChart.jsp +++ b/transitclockWebapp/src/main/webapp/reports/schAdhByTimeChart.jsp @@ -1,6 +1,8 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="org.transitclock.utils.web.WebUtils" %> +<%@page import="java.util.ResourceBundle" %> +<%@page import="java.util.Locale" %> @@ -50,11 +52,12 @@ <%@include file="/template/header.jsp" %> <% - String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " days)"; - String allowableEarly = request.getParameter("allowableEarly");; - String allowableLate = request.getParameter("allowableLate");; - String chartSubtitle = allowableEarly + " min early to " - + allowableLate + " min late
" + ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", request.getLocale()); + String dateRange = request.getParameter("beginDate") + " (+" + request.getParameter("numDays") + " " + labels.getString("Days") + ")"; + String allowableEarly = request.getParameter("allowableEarly"); + String allowableLate = request.getParameter("allowableLate"); + String chartSubtitle = allowableEarly + " " + labels.getString("MinEarlyTo") + " " + + allowableLate + " " + labels.getString("div.minlate") + "
" + dateRange; String beginTime = request.getParameter("beginTime"); @@ -65,7 +68,7 @@ beginTime = "00:00"; // default value if (endTime.isEmpty()) endTime = "24:00"; // default value - chartSubtitle += ", " + beginTime + " to " + endTime; + chartSubtitle += ", " + beginTime + " " + labels.getString("To") + " " + endTime; } %>

@@ -97,8 +100,8 @@ function drawChart() { function createDataTableAndDrawChart(jsonData) { // Initialize the data array with the header that describes the columns var dataArray = [[ - 'Early/Late', - 'Stops', + '', + '', { role: 'style' }, { role: 'annotation' }, { role: 'tooltip' } @@ -137,13 +140,14 @@ function createDataTableAndDrawChart(jsonData) { var annotation = bucket.counts_per_time_period; - var tooltip = bucket.counts_per_time_period + ' stops for vehicles that are '; + var tooltip = (bucket.counts_per_time_period > 4) ? '' + ' ' : '' + ' ' ; + tooltip = bucket.counts_per_time_period + ' ' + tooltip; if (bucket.time_period < 0) { // vehicle late - tooltip += -(bucket.time_period+30) + 's to ' + (-bucket.time_period) + 's late. '; + tooltip += -(bucket.time_period+30) + 's ' + '' + ' ' + (-bucket.time_period) + ' ' + '' + '. '; } else { // vehicle early - tooltip += bucket.time_period + 's to ' + (bucket.time_period+30) + 's early. '; + tooltip += bucket.time_period + 's ' + '' + ' ' + (bucket.time_period+30) + ' ' + '' + '. '; } var row = [timeFloor, counts, style, annotation, tooltip]; @@ -177,12 +181,12 @@ function createDataTableAndDrawChart(jsonData) { chartArea: {top:10, width: '86%', height: '90%'}, vAxis: { minValue: 0, - title: "Number of stops per time interval", + title: '', textStyle: {fontSize: 12}, }, hAxis: { ticks: ticks, - title: "Minutes vehicle late (negative) or early (positive)", + title: '', // The chart always draws the baseline at value 0 over the chart. // Since the baseline isn't true zero, since using bars and // putting tick marks at the edges of the bars, don't want this @@ -207,7 +211,7 @@ function createDataTableAndDrawChart(jsonData) { function determineChartTitle(routeData) { var agencyName = routeData.agency; var routeName = routeData.routes[0].name; - $("#title").html('Schedule Adherence for ' + routeName); + $("#title").html('' + ' ' + routeName); } function getDataAndDrawChart() { @@ -227,7 +231,7 @@ function getDataAndDrawChart() { // When there is an AJAX problem alert the user error: function(request, status, error) { console.log(request.responseText) - var msg = $("

").html("
No data for requested parameters. Hit back button to try other parameters.") + var msg = $("

").html("
") $("#errorMessage").append(msg); $("#errorMessage").fadeIn("fast"); $("#loading").fadeOut("slow"); diff --git a/transitclockWebapp/src/main/webapp/reports/schAdhByTimeData.jsp b/transitclockWebapp/src/main/webapp/reports/schAdhByTimeData.jsp index 6df4acf15..4be765530 100644 --- a/transitclockWebapp/src/main/webapp/reports/schAdhByTimeData.jsp +++ b/transitclockWebapp/src/main/webapp/reports/schAdhByTimeData.jsp @@ -44,7 +44,7 @@ int BUCKET_TIME = 30; String epochCommandPre = "EXTRACT (EPOCH FROM "; String epochCommandPost = ")"; if (isMysql) { - epochCommandPre = "UNIX_TIMESTAMP"; + epochCommandPre = ""; epochCommandPost = ""; } String sql = diff --git a/transitclockWebapp/src/main/webapp/reports/scheduleHorizStopsReport.jsp b/transitclockWebapp/src/main/webapp/reports/scheduleHorizStopsReport.jsp index b3f933635..a0cd15d4e 100644 --- a/transitclockWebapp/src/main/webapp/reports/scheduleHorizStopsReport.jsp +++ b/transitclockWebapp/src/main/webapp/reports/scheduleHorizStopsReport.jsp @@ -44,11 +44,12 @@ if (agencyId == null || agencyId.isEmpty()) { // Go through all service classes and directions for route for (var i=0; i' : schedule.directionId; // Create title for schedule $('body').append("

" - + ' ' + schedule.directionId - + ", Service: " + schedule.serviceName + + ' ' + directionText + + ", " + '' + " " + schedule.serviceName + "
"); var table = $("
").appendTo('body')[0]; From da83dd0ad83cd87ee58736391e89ac03e22ed919 Mon Sep 17 00:00:00 2001 From: Hubert goEuropa Date: Thu, 1 Jul 2021 22:44:17 +0200 Subject: [PATCH 02/14] Improving translations, some mysql error fix --- .../transitclock/reports/AvlJsonQuery.java | 14 ++++++++-- .../reports/ChartJsonBuilder.java | 2 +- .../reports/PredAccuracyRangeQuery.java | 28 +++++++++++++------ .../reports/PredictionAccuracyQuery.java | 3 ++ .../org/transitclock/reports/SqlUtils.java | 13 +++++++-- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java b/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java index 38cb214d6..2ac0a7540 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java @@ -67,11 +67,18 @@ public static String getAvlJson(String agencyId, String vehicleId, + beginTime + "' AND '" + endTime + "' "; } - String sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " + /*String sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " + "heading, timeProcessed, source " + "FROM avlreports " - + "WHERE time BETWEEN " + " cast(? as timestamp)" - + " AND " + "cast(? as timestamp)" + " + INTERVAL '" + numdays + " day' " + + "WHERE time BETWEEN " + " cast(? as datetime)" + + " AND " + "cast(? as datetime)" + " + INTERVAL '" + numdays + " day' " + + timeSql;*/ + + String sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " + + "heading, timeProcessed, source " + + "FROM avlreports " + + "WHERE time BETWEEN " + " cast(? as datetime)" + + " AND " + "date_add(cast(? as datetime), INTERVAL " + numdays + " day) " + timeSql; @@ -86,6 +93,7 @@ public static String getAvlJson(String agencyId, String vehicleId, // to view too much data at once. sql += "ORDER BY vehicleId, time LIMIT " + MAX_ROWS; + String json=null; try { java.util.Date startdate = Time.parseDate(beginDate); diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/ChartJsonBuilder.java b/transitclockWebapp/src/main/java/org/transitclock/reports/ChartJsonBuilder.java index 5ea0b8336..70898dffe 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/ChartJsonBuilder.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/ChartJsonBuilder.java @@ -79,7 +79,7 @@ public void addRowElement(String value) { * The value of the element to be added to the row */ public void addRowElement(double value) { - String rowElement = "{\"v\": " + StringUtils.oneDigitFormat(value) + String rowElement = "{\"v\": " + StringUtils.oneDigitFormat(value).replace(",", ".") + "}"; rowElementsList.add(rowElement); } diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/PredAccuracyRangeQuery.java b/transitclockWebapp/src/main/java/org/transitclock/reports/PredAccuracyRangeQuery.java index 52303dd6b..a5c69f384 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/PredAccuracyRangeQuery.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/PredAccuracyRangeQuery.java @@ -18,6 +18,8 @@ package org.transitclock.reports; import java.sql.SQLException; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.text.ParseException; import java.util.List; @@ -26,6 +28,8 @@ import org.transitclock.reports.ChartJsonBuilder.RowBuilder; import org.transitclock.utils.StringUtils; import org.transitclock.utils.Time; +import java.util.ResourceBundle; +import java.util.Locale; /** * For generating the JSON data for a Google chart for showing percent of @@ -38,6 +42,8 @@ public class PredAccuracyRangeQuery extends PredictionAccuracyQuery { private static final Logger logger = LoggerFactory .getLogger(PredAccuracyRangeQuery.class); + + ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", Locale.getDefault()); /********************** Member Functions **************************/ @@ -85,15 +91,15 @@ private void addCols(ChartJsonBuilder builder, int maxEarlySec, } builder.addNumberColumn(); - builder.addNumberColumn("Earlier than predicted (more than " + maxEarlySec + " secs early)"); + builder.addNumberColumn(labels.getString("EarlierThanPredicted_MoreThan") + " " + maxEarlySec + " " + labels.getString("SecsEarly_")); builder.addTooltipColumn(); - builder.addNumberColumn("Within Bounds (" + maxEarlySec + " secs early to " - + maxLateSec + " secs late)"); + builder.addNumberColumn(labels.getString("WithinBounds_") + " " + maxEarlySec + " " + labels.getString("SecsEarlyTo") + " " + + maxLateSec + " " + labels.getString("SecsLate_")); builder.addTooltipColumn(); - builder.addNumberColumn("Later than predicted (more than " + maxLateSec + " secs late)"); + builder.addNumberColumn(labels.getString("LaterThanPredicted_MoreThan") + maxLateSec + " " + labels.getString("SecsLate_")); builder.addTooltipColumn(); } - + /** * Adds the row definition in JSON string format so that chart the data * using Google charts. The row definition contains the actual data. @@ -154,17 +160,21 @@ else if (accuracyInSecs < maxLateSec) rowBuilder.addRowElement(predBucketSecs); rowBuilder.addRowElement(tooEarlyPercentage); - rowBuilder.addRowElement("Earlier than predicted: " + tooEarly + " points, " + + + ResourceBundle labels = ResourceBundle.getBundle("org.transitclock.i18n.text", Locale.getDefault()); + + rowBuilder.addRowElement(labels.getString("EarlierThanPredicted") + ": " + tooEarly + " " + labels.getString("Points") + ", " + StringUtils.oneDigitFormat(tooEarlyPercentage) + "%"); rowBuilder.addRowElement(okPercentage); - rowBuilder.addRowElement("Within Bounds: " + ok + " points, " + rowBuilder.addRowElement(labels.getString("WithinBounds") + ": " + ok + " " + labels.getString("Points") + ", " + StringUtils.oneDigitFormat(okPercentage) + "%"); rowBuilder.addRowElement(tooLatePercentage); - rowBuilder.addRowElement("Too Late: " + tooLate + " points, " + rowBuilder.addRowElement(labels.getString("TooLate") + ": " + tooLate + " " + labels.getString("Points") + ", " + StringUtils.oneDigitFormat(tooLatePercentage) + "%"); - rowBuilder.addRowElement("Later than predicted: " + tooLate + " points, " + rowBuilder.addRowElement(labels.getString("LaterThanPredicted") + ": " + tooLate + " " + labels.getString("Points") + ", " + StringUtils.oneDigitFormat(tooLatePercentage) + "%"); } } diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/PredictionAccuracyQuery.java b/transitclockWebapp/src/main/java/org/transitclock/reports/PredictionAccuracyQuery.java index 6c9531b66..b8a033bb1 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/PredictionAccuracyQuery.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/PredictionAccuracyQuery.java @@ -382,6 +382,9 @@ protected void doQuery(String beginDateStr, String numDaysStr, // Set the parameters for the query int i = 1; statement.setTimestamp(i++, beginDate); + if ("mysql".equals(dbType)) { + statement.setTimestamp(i++, beginDate); + } if (beginTime != null) { if ("mysql".equals(dbType)) { diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/SqlUtils.java b/transitclockWebapp/src/main/java/org/transitclock/reports/SqlUtils.java index 38a17083e..4414ef88f 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/SqlUtils.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/SqlUtils.java @@ -17,6 +17,7 @@ package org.transitclock.reports; import java.text.ParseException; +import java.text.SimpleDateFormat; import javax.servlet.http.HttpServletRequest; @@ -215,8 +216,16 @@ public static String timeRangeClause(HttpServletRequest request, numDays = maxNumDays; String sql = null; if (isMysql) { - sql = " AND " + timeColumnName + " BETWEEN '" + beginDate - + "' " + " AND DATE_ADD(STR_TO_DATE('" + beginDate + "', '%Y-%m-%d'), INTERVAL " + String reformattedBeginDate = beginDate; + SimpleDateFormat currentFormat = new SimpleDateFormat("MM-dd-yyyy"); + SimpleDateFormat requiredFormat = new SimpleDateFormat("yyyy-MM-dd"); + try { + reformattedBeginDate = requiredFormat.format(currentFormat.parse(beginDate)); + } catch (ParseException e) { + e.printStackTrace(); + } + sql = " AND " + timeColumnName + " BETWEEN '" + reformattedBeginDate + + "' " + " AND DATE_ADD(STR_TO_DATE('" + reformattedBeginDate + "', '%Y-%m-%d'), INTERVAL " + numDays + " day) " + timeSql + ' '; } else { sql =" AND " + timeColumnName + " BETWEEN '" + beginDate From ff5d6e722c7ce86bfe17cf3cfcd5f078ceecdd99 Mon Sep 17 00:00:00 2001 From: Hubert goEuropa Date: Tue, 13 Jul 2021 07:15:43 +0200 Subject: [PATCH 03/14] Add vehicleName, vehicleSpeed[traccar], popup fix --- .../core/dataCache/VehicleDataCache.java | 11 ++- .../custom/traccar/TraccarAVLModule.java | 10 ++- .../transitclock/db/structs/AvlReport.java | 60 +++++++++++++ .../db/structs/VehicleConfig.java | 51 ++++++++++- .../org/transitclock/ipc/data/IpcVehicle.java | 86 ++++++++++++++++++- .../ipc/data/IpcVehicleConfig.java | 9 +- .../ddl_mysql_org_transitime_db_structs.sql | 1 + .../ddl_oracle_org_transitime_db_structs.sql | 3 +- ...ddl_postgres_org_transitime_db_structs.sql | 3 +- .../api/data/ApiVehicleConfig.java | 6 +- .../api/data/ApiVehicleDetails.java | 6 +- .../transitclock/reports/AvlJsonQuery.java | 24 ++++-- .../src/main/webapp/maps/map.jsp | 12 ++- .../main/webapp/reports/lastAvlJsonData.jsp | 10 ++- .../src/main/webapp/reports/lastAvlReport.jsp | 2 +- .../main/webapp/reports/params/vehicle.jsp | 9 +- 16 files changed, 269 insertions(+), 34 deletions(-) diff --git a/transitclock/src/main/java/org/transitclock/core/dataCache/VehicleDataCache.java b/transitclock/src/main/java/org/transitclock/core/dataCache/VehicleDataCache.java index 82814700f..f5c69dfc5 100644 --- a/transitclock/src/main/java/org/transitclock/core/dataCache/VehicleDataCache.java +++ b/transitclock/src/main/java/org/transitclock/core/dataCache/VehicleDataCache.java @@ -27,6 +27,7 @@ import org.hibernate.HibernateException; import org.hibernate.Session; +import org.hibernate.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.transitclock.applications.Core; @@ -180,7 +181,8 @@ public void cacheVehicleConfig(AvlReport avlReport) { // If new vehicle... String vehicleId = avlReport.getVehicleId(); - VehicleConfig vehicleConfig = new VehicleConfig(vehicleId); + String vehicleName = avlReport.getVehicleName(); + VehicleConfig vehicleConfig = new VehicleConfig(vehicleId, vehicleName); VehicleConfig absent = vehicleConfigsMap.putIfAbsent(vehicleId, vehicleConfig); if (absent == null) { logger.info("Encountered new vehicle where vehicleId={} so " @@ -188,6 +190,13 @@ public void cacheVehicleConfig(AvlReport avlReport) { + "VehicleConfig to database.", vehicleId); // Write the vehicle to the database Core.getInstance().getDbLogger().add(vehicleConfig); + } else if(!vehicleName.equals(absent.getName())){ + Session session = + HibernateUtils.getSession(AgencyConfig.getAgencyId()); + Transaction tx = session.beginTransaction(); + absent.setName(vehicleName); + VehicleConfig.updateVehicleConfig(absent, session); + tx.commit(); } } diff --git a/transitclock/src/main/java/org/transitclock/custom/traccar/TraccarAVLModule.java b/transitclock/src/main/java/org/transitclock/custom/traccar/TraccarAVLModule.java index 0d938c9f3..ba4769802 100644 --- a/transitclock/src/main/java/org/transitclock/custom/traccar/TraccarAVLModule.java +++ b/transitclock/src/main/java/org/transitclock/custom/traccar/TraccarAVLModule.java @@ -27,6 +27,7 @@ import org.transitclock.avl.PollUrlAvlModule; import org.transitclock.config.StringConfigValue; import org.transitclock.db.structs.AvlReport; +import org.transitclock.db.structs.Location; import org.transitclock.db.structs.AvlReport.AssignmentType; import io.swagger.client.ApiClient; import io.swagger.client.api.DefaultApi; @@ -91,18 +92,19 @@ protected void getAndProcessData() throws Exception { Device device=findDeviceById(devices, result.getDeviceId()); AvlReport avlReport = null; + // If have device details use name. - if(device!=null && device.getName()!=null && !device.getName().isEmpty()) + if(device!=null && device.getUniqueId()!=null && !device.getUniqueId().isEmpty()) { - avlReport = new AvlReport(device.getName(), + avlReport = new AvlReport(device.getUniqueId().toString(), device.getName(), result.getDeviceTime().toDate().getTime(), result.getLatitude().doubleValue(), - result.getLongitude().doubleValue(), traccarSource.toString()); + result.getLongitude().doubleValue(), result.getSpeed().floatValue(), result.getCourse().floatValue(), traccarSource.toString()); } else { avlReport = new AvlReport(result.getDeviceId().toString(), result.getDeviceTime().toDate().getTime(), result.getLatitude().doubleValue(), - result.getLongitude().doubleValue(), traccarSource.toString()); + result.getLongitude().doubleValue(), result.getSpeed().floatValue(), result.getCourse().floatValue(), traccarSource.toString()); } if(avlReport!=null) avlReportsReadIn.add(avlReport); diff --git a/transitclock/src/main/java/org/transitclock/db/structs/AvlReport.java b/transitclock/src/main/java/org/transitclock/db/structs/AvlReport.java index e89233c1d..48e848279 100644 --- a/transitclock/src/main/java/org/transitclock/db/structs/AvlReport.java +++ b/transitclock/src/main/java/org/transitclock/db/structs/AvlReport.java @@ -171,6 +171,7 @@ public enum AssignmentType { @Column(length=HibernateUtils.DEFAULT_ID_SIZE) String field1Value; + private String vehicleName; // How long the AvlReport source field can be in db private static final int SOURCE_LENGTH = 10; @@ -212,6 +213,7 @@ protected AvlReport() { passengerFullness = null; field1Name = null; field1Value = null; + vehicleName = null; } /** @@ -259,6 +261,54 @@ public AvlReport(String vehicleId, long time, double lat, double lon, this.timeProcessed = null; } + /** + * Constructor for an AvlReport object that is not yet being processed. + * Since not yet being processed timeProcessed is set to null. + * + * @param vehicleId + * ID of the vehicle + * @param vehicleName + * Name of the vehicle + * @param time + * Epoch time in msec of GPS report (not when processed) + * @param lat + * Latitude in decimal degrees + * @param lon + * Longitude in decimal degrees + * @param speed + * Speed of vehicle in m/s. Should be set to Float.NaN if speed + * not available + * @param heading + * Heading of vehicle in degrees clockwise from north. Should be + * set to Float.NaN if speed not available + * @param source + * Text describing the source of the report + */ + public AvlReport(String vehicleId, String vehicleName, long time, double lat, double lon, + float speed, float heading, String source) { + // Store the values + this.vehicleId = vehicleId; + this.time = new Date(time); + this.location = new Location(lat, lon); + // DB requires null instead of NaN + this.speed = Float.isNaN(speed) ? null : speed; + this.heading = Float.isNaN(heading) ? null : heading; + this.source = sized(source); + this.assignmentId = null; + this.assignmentType = AssignmentType.UNSET; + this.leadVehicleId = null; + this.driverId = null; + this.licensePlate = null; + this.passengerCount = null; + this.passengerFullness = null; + this.field1Name = null; + this.field1Value = null; + this.vehicleName = vehicleName; + + // Don't yet know when processed so set timeProcessed to null + this.timeProcessed = null; + } + /** * Constructor for an AvlReport object that is not yet being processed. * Since not yet being processed timeProcessed is set to null. @@ -1030,6 +1080,16 @@ public String getField1Name() { public String getField1Value() { return field1Value; } + + + + public String getVehicleName() { + return vehicleName; + } + + public void setVehicleName(String vehicleName) { + this.vehicleName = vehicleName; + } /** * Returns true if the AVL report is configured to indicate that it was diff --git a/transitclock/src/main/java/org/transitclock/db/structs/VehicleConfig.java b/transitclock/src/main/java/org/transitclock/db/structs/VehicleConfig.java index 8c80c2c8f..ee7c6609c 100644 --- a/transitclock/src/main/java/org/transitclock/db/structs/VehicleConfig.java +++ b/transitclock/src/main/java/org/transitclock/db/structs/VehicleConfig.java @@ -27,6 +27,7 @@ import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; +import org.hibernate.Transaction; import org.hibernate.annotations.DynamicUpdate; import org.transitclock.db.hibernate.HibernateUtils; @@ -44,6 +45,9 @@ public class VehicleConfig { @Id private final String id; + @Column + private String name; + // Same as vehicle type in GTFS @Column private final Integer type; @@ -87,6 +91,26 @@ public VehicleConfig(String id) { capacity = null; crushCapacity = null; nonPassengerVehicle = null; + name = null; + } + + /** + * Constructor for when new vehicle encountered and automatically adding it + * to the db. + * + * @param id vehicle ID + * @param name vehicle name + * + */ + public VehicleConfig(String id, String name) { + this.id = id; + type = null; + description = null; + trackerId = null; + capacity = null; + crushCapacity = null; + nonPassengerVehicle = null; + this.name = name; } /** @@ -101,6 +125,7 @@ private VehicleConfig() { capacity = null; crushCapacity = null; nonPassengerVehicle = null; + name = null; } /** @@ -118,10 +143,24 @@ public static List getVehicleConfigs(Session session) return query.list(); } + /** + * Reads List of VehicleConfig objects from database + * + * @param VehicleConfig, session + * @throws HibernateException + */ + public static void updateVehicleConfig(VehicleConfig vehicleConfig, Session session) + throws HibernateException { + //Transaction tx = session.beginTransaction(); + session.update(vehicleConfig); + //tx.commit(); + } + @Override public String toString() { return "VehicleConfig [" + "id=" + id + + "name=" + name + ", type=" + type + ", description=" + description + ", trackerId=" + trackerId @@ -192,5 +231,15 @@ public Integer getCrushCapacity() { public Boolean isNonPassengerVehicle() { return nonPassengerVehicle; } - + + /** + * @return the vehicle name + */ + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicle.java b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicle.java index 422da6ca1..a9ea44dc3 100644 --- a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicle.java +++ b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicle.java @@ -52,6 +52,8 @@ public class IpcVehicle implements Serializable { public boolean isAtStop() { return isAtStop; } + + private String vehicleName; private final String blockId; private final BlockAssignmentMethod blockAssignmentMethod; @@ -96,6 +98,7 @@ public boolean isAtStop() { * @param vs */ public IpcVehicle(VehicleState vs) { + this.vehicleName = vs.getVehicleName(); this.blockAssignmentMethod = vs.getAssignmentMethod(); this.avl = new IpcAvl(vs.getAvlReport()); this.heading = vs.getHeading(); @@ -257,6 +260,74 @@ protected IpcVehicle(String blockId, this.predictedLongitude = predictedLongitude; } + + /** + * Constructor used for when deserializing a proxy object. Declared + * protected because only used internally by the proxy class but also for + * sub class. + * + * @param blockId + * @param blockAssignmentMethod + * @param avl + * @param pathHeading + * @param routeId + * @param routeShortName + * @param routeName + * @param tripId + * @param tripPatternId + * @param directionId + * @param headsign + * @param predictable + * @param schedBasedPred + * @param realTimeSchdAdh + * @param isDelayed + * @param isLayover + * @param layoverDepartureTime + * @param nextStopId + * @param nextStopName + * @param vehicleType + * @param freqStartTime + */ + protected IpcVehicle(String blockId, String vehicleName, + BlockAssignmentMethod blockAssignmentMethod, IpcAvl avl, + float heading, String routeId, String routeShortName, + String routeName, String tripId, String tripPatternId, + String directionId, String headsign, boolean predictable, + boolean schedBasedPred, TemporalDifference realTimeSchdAdh, + boolean isDelayed, boolean isLayover, long layoverDepartureTime, + + String nextStopId, String nextStopName, String vehicleType, long freqStartTime, boolean isAtStop, IpcHoldingTime holdingTime, double predictedLatitude, double predictedLongitude) { + + this.vehicleName = vehicleName; + this.blockId = blockId; + this.blockAssignmentMethod = blockAssignmentMethod; + this.avl = avl; + this.heading = heading; + this.routeId = routeId; + this.routeShortName = routeShortName; + this.routeName = routeName; + this.tripId = tripId; + this.tripPatternId = tripPatternId; + this.directionId = directionId; + this.headsign = headsign; + this.predictable = predictable; + this.schedBasedPred = schedBasedPred; + this.realTimeSchedAdh = realTimeSchdAdh; + this.isDelayed = isDelayed; + this.isLayover = isLayover; + this.layoverDepartureTime = layoverDepartureTime; + this.nextStopId = nextStopId; + this.nextStopName = nextStopName; + this.vehicleType = vehicleType; + + this.freqStartTime = freqStartTime; + this.isAtStop = isAtStop; + this.holdingTime = holdingTime; + + this.predictedLatitude = predictedLatitude; + this.predictedLongitude = predictedLongitude; + + } /* * SerializationProxy is used so that this class can be immutable and so @@ -265,6 +336,7 @@ protected IpcVehicle(String blockId, protected static class SerializationProxy implements Serializable { // Exact copy of fields of IpcVehicle enclosing class object protected String blockId; + protected String vehicleName; protected BlockAssignmentMethod blockAssignmentMethod; protected IpcAvl avl; protected float heading; @@ -300,6 +372,7 @@ protected static class SerializationProxy implements Serializable { * Only to be used within this class. */ protected SerializationProxy(IpcVehicle v) { + this.vehicleName = v.vehicleName; this.blockId = v.blockId; this.blockAssignmentMethod = v.blockAssignmentMethod; this.avl = v.avl; @@ -340,6 +413,7 @@ protected void writeObject(java.io.ObjectOutputStream stream) throws IOException { stream.writeShort(currentSerializationVersion); + stream.writeObject(vehicleName); stream.writeObject(blockId); stream.writeObject(blockAssignmentMethod); stream.writeObject(avl); @@ -388,6 +462,7 @@ protected void readObject(java.io.ObjectInputStream stream) // serialization version is OK so read in object blockId = (String) stream.readObject(); + vehicleName = (String) stream.readObject(); blockAssignmentMethod = (BlockAssignmentMethod) stream.readObject(); avl = (IpcAvl) stream.readObject(); heading = stream.readFloat(); @@ -422,7 +497,7 @@ protected void readObject(java.io.ObjectInputStream stream) * object is converted to an enclosing class object. */ private Object readResolve() { - return new IpcVehicle(blockId, blockAssignmentMethod, avl, heading, + return new IpcVehicle(blockId, vehicleName, blockAssignmentMethod, avl, heading, routeId, routeShortName, routeName, tripId, tripPatternId, directionId, headsign, predictable, schedBasedPred, realTimeSchdAdh, isDelayed, isLayover, layoverDepartureTime, @@ -589,11 +664,20 @@ public String getNextStopName() { public String getVehicleType() { return vehicleType; } + + public String getVehicleName() { + return vehicleName; + } + + public void setVehicleName(String vehicleName) { + this.vehicleName = vehicleName; + } @Override public String toString() { return "IpcVehicle [" + "vehicleId=" + avl.getVehicleId() + + ", vehicleName=" + vehicleName + ", blockId=" + blockId + ", blockAssignmentMethod=" + blockAssignmentMethod + ", routeId=" + routeId diff --git a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleConfig.java b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleConfig.java index 5aca83639..1a67a50f0 100644 --- a/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleConfig.java +++ b/transitclock/src/main/java/org/transitclock/ipc/data/IpcVehicleConfig.java @@ -35,7 +35,8 @@ public class IpcVehicleConfig implements Serializable { private final Integer capacity; private final Integer crushCapacity; private final Boolean nonPassengerVehicle; - + private final String name; + private static final long serialVersionUID = 4172266751162647909L; /********************** Member Functions **************************/ @@ -47,6 +48,7 @@ public IpcVehicleConfig(VehicleConfig vc) { this.capacity = vc.getCapacity(); this.crushCapacity = vc.getCrushCapacity(); this.nonPassengerVehicle = vc.isNonPassengerVehicle(); + this.name = vc.getName(); } public String getId() { @@ -73,6 +75,10 @@ public Boolean isNonPassengerVehicle() { return nonPassengerVehicle; } + public String getName() { + return name; + } + @Override public String toString() { return "IpcVehicleConfig [" @@ -82,6 +88,7 @@ public String toString() { + ", capacity=" + capacity + ", crushCapacity=" + crushCapacity + ", nonPassengerVehicle=" + nonPassengerVehicle + + ", name=" + name + "]"; } } diff --git a/transitclock/src/main/resources/ddl_mysql_org_transitime_db_structs.sql b/transitclock/src/main/resources/ddl_mysql_org_transitime_db_structs.sql index 819223bd1..5e0325397 100644 --- a/transitclock/src/main/resources/ddl_mysql_org_transitime_db_structs.sql +++ b/transitclock/src/main/resources/ddl_mysql_org_transitime_db_structs.sql @@ -429,6 +429,7 @@ create table VehicleConfigs ( id varchar(60) not null, + name varchar(255), capacity integer, crushCapacity integer, description varchar(255), diff --git a/transitclock/src/main/resources/ddl_oracle_org_transitime_db_structs.sql b/transitclock/src/main/resources/ddl_oracle_org_transitime_db_structs.sql index 6f0c49cc4..cf7a776c5 100644 --- a/transitclock/src/main/resources/ddl_oracle_org_transitime_db_structs.sql +++ b/transitclock/src/main/resources/ddl_oracle_org_transitime_db_structs.sql @@ -262,7 +262,7 @@ id varchar2(60 char) not null, configRev number(10,0) not null, color varchar2(10 char), - description varchar2(1024 char), + description varchar2(2048 char), maxLat double precision, maxLon double precision, minLat double precision, @@ -429,6 +429,7 @@ create table VehicleConfigs ( id varchar2(60 char) not null, + name varchar2(255 char), capacity number(10,0), crushCapacity number(10,0), description varchar2(255 char), diff --git a/transitclock/src/main/resources/ddl_postgres_org_transitime_db_structs.sql b/transitclock/src/main/resources/ddl_postgres_org_transitime_db_structs.sql index 33cce163c..d3ecb2a29 100644 --- a/transitclock/src/main/resources/ddl_postgres_org_transitime_db_structs.sql +++ b/transitclock/src/main/resources/ddl_postgres_org_transitime_db_structs.sql @@ -262,7 +262,7 @@ id varchar(60) not null, configRev int4 not null, color varchar(10), - description varchar(1024), + description varchar(2048), maxLat float8, maxLon float8, minLat float8, @@ -429,6 +429,7 @@ create table VehicleConfigs ( id varchar(60) not null, + name varchar(255), capacity int4, crushCapacity int4, description varchar(255), diff --git a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleConfig.java b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleConfig.java index 6e75b8ee0..365ff6634 100644 --- a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleConfig.java +++ b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleConfig.java @@ -31,7 +31,7 @@ */ @XmlRootElement(name = "vehicleConfig") @XmlType(propOrder = { "id", "type", "description", "capacity", - "crushCapacity", "nonPassengerVehicle" }) + "crushCapacity", "nonPassengerVehicle", "name" }) public class ApiVehicleConfig { @XmlAttribute @@ -52,6 +52,9 @@ public class ApiVehicleConfig { @XmlAttribute private Boolean nonPassengerVehicle; + @XmlAttribute + private String name; + /********************** Member Functions **************************/ /** @@ -68,6 +71,7 @@ public ApiVehicleConfig(IpcVehicleConfig vehicle) { this.capacity = vehicle.getCapacity(); this.crushCapacity = vehicle.getCrushCapacity(); this.nonPassengerVehicle = vehicle.isNonPassengerVehicle(); + this.name = vehicle.getName(); } } diff --git a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java index 7ca1ed6be..425b8639c 100644 --- a/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java +++ b/transitclockApi/src/main/java/org/transitclock/api/data/ApiVehicleDetails.java @@ -39,7 +39,7 @@ * */ @XmlRootElement -@XmlType(propOrder = { "id", "routeId", "routeShortName", "routeName", "headsign", +@XmlType(propOrder = { "id", "vehicleName", "routeId", "routeShortName", "routeName", "headsign", "directionId", "vehicleType", "uiType", "schedBasedPreds", "loc", "scheduleAdherence", "scheduleAdherenceStr", "blockId", "blockAssignmentMethod", "tripId", "tripPatternId", "isDelayed", @@ -50,6 +50,9 @@ public class ApiVehicleDetails extends ApiVehicleAbstract { @XmlAttribute private String routeName; + @XmlAttribute + private String vehicleName; + // Note: needs to be Integer instead of an int because it can be null // (for vehicles that are not predictable) @XmlAttribute(name = "schAdh") @@ -138,6 +141,7 @@ public ApiVehicleDetails(IpcVehicle vehicle, Time timeForAgency, UiMode... uiTyp super(vehicle, uiType.length > 0 ? uiType[0] : UiMode.NORMAL); routeName = vehicle.getRouteName(); + vehicleName = vehicle.getVehicleName(); scheduleAdherence = vehicle.getRealTimeSchedAdh() != null ? vehicle .getRealTimeSchedAdh().getTemporalDifference() : null; scheduleAdherenceStr = vehicle.getRealTimeSchedAdh() != null ? vehicle diff --git a/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java b/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java index 2ac0a7540..da606814f 100644 --- a/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java +++ b/transitclockWebapp/src/main/java/org/transitclock/reports/AvlJsonQuery.java @@ -18,6 +18,7 @@ import java.text.ParseException; +import org.transitclock.db.webstructs.WebAgency; import org.transitclock.utils.Time; /** @@ -66,21 +67,26 @@ public static String getAvlJson(String agencyId, String vehicleId, timeSql = " AND time(time) BETWEEN '" + beginTime + "' AND '" + endTime + "' "; } - - /*String sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " - + "heading, timeProcessed, source " - + "FROM avlreports " - + "WHERE time BETWEEN " + " cast(? as datetime)" - + " AND " + "cast(? as datetime)" + " + INTERVAL '" + numdays + " day' " - + timeSql;*/ - String sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " + String sql = ""; + WebAgency agency = WebAgency.getCachedWebAgency(agencyId); + + if ("mysql".equals(agency.getDbType())) { + sql = "SELECT vehicleId, name, time, assignmentId, lat, lon, speed, " + "heading, timeProcessed, source " + "FROM avlreports " + + "INNER JOIN vehicleconfigs ON vehicleconfigs.id = avlreports.vehicleId " + "WHERE time BETWEEN " + " cast(? as datetime)" + " AND " + "date_add(cast(? as datetime), INTERVAL " + numdays + " day) " + + timeSql;; + } else { + sql = "SELECT vehicleId, time, assignmentId, lat, lon, speed, " + + "heading, timeProcessed, source " + + "FROM avlreports " + + "WHERE time BETWEEN " + " cast(? as datetime)" + + " AND " + "cast(? as datetime)" + " + INTERVAL '" + numdays + " day' " + timeSql; - + } // If only want data for single vehicle then specify so in SQL if (vehicleId != null && !vehicleId.isEmpty()) diff --git a/transitclockWebapp/src/main/webapp/maps/map.jsp b/transitclockWebapp/src/main/webapp/maps/map.jsp index 0e7f3d46b..916d496e8 100644 --- a/transitclockWebapp/src/main/webapp/maps/map.jsp +++ b/transitclockWebapp/src/main/webapp/maps/map.jsp @@ -23,6 +23,8 @@ <%@include file="/template/includes.jsp" %> + + @@ -398,9 +400,9 @@ function getVehiclePopupContent(vehicleData) { nextStopNameStr += "
Id: " + vehicleData.nextStopId; var driver = vehicleData.driver ? "
: " + vehicleData.driver : ""; - var latLonHeadingStr = verbose ? "
Lat: " + vehicleData.loc.lat + var latLonHeadingStr = verbose ? "
: " + vehicleData.loc.lat + "
: " + vehicleData.loc.lon - + "
: " + vehicleData.loc.heading + + "
: " + vehicleData.loc.heading + "
: " + formatSpeed(vehicleData.loc.speed) : ""; var gpsTimeStr = dateFormat(vehicleData.loc.time); @@ -561,8 +563,10 @@ function createVehicleMarker(vehicleData) { var vehicleMarker = L.marker(vehicleLoc, getVehicleMarkerOptions(vehicleData)) .setIcon(getIconForVehicle(vehicleData)) + .bindLabel(vehicleData.id, {noHide: true, className: "my-label", offset: [12, -14] }) .addTo(map); + // Add the background and the heading arrow markers to // vehicleIcon so they can all be updated when the vehicle moves. vehicleMarker.background = vehicleBackground; @@ -857,8 +861,8 @@ L.control.zoom({position: 'bottomleft'}).addTo(map); var mapTileUrl = '<%= WebConfigParams.getMapTileUrl() %>'; L.tileLayer(mapTileUrl, { // Specifying a shorter version of attribution. Original really too long. - //attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', - attribution: '© OpenStreetMap & CC-BY-SA, Imagery ©<%= WebConfigParams.getMapTileCopyright() %>', + //attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery ďż˝ Mapbox', + attribution: '© OpenStreetMap & CC-BY-SA, Imagery ďż˝<%= WebConfigParams.getMapTileCopyright() %>', maxZoom: 19 }).addTo(map); diff --git a/transitclockWebapp/src/main/webapp/reports/lastAvlJsonData.jsp b/transitclockWebapp/src/main/webapp/reports/lastAvlJsonData.jsp index 0053a38d0..656a99df1 100644 --- a/transitclockWebapp/src/main/webapp/reports/lastAvlJsonData.jsp +++ b/transitclockWebapp/src/main/webapp/reports/lastAvlJsonData.jsp @@ -11,21 +11,23 @@ String dbtype = agency.getDbType(); String sql = null; if(dbtype.equals("mysql")){ sql = - "SELECT a.vehicleId, maxTime, lat, lon " + "SELECT a.vehicleId, vC.name, maxTime, lat, lon " + "FROM " + "(SELECT vehicleId, max(time) AS maxTime " + "FROM AvlReports WHERE time > date_sub(now(), interval 1 day) " + "GROUP BY vehicleId) a " - + "JOIN AvlReports b ON a.vehicleId=b.vehicleId AND a.maxTime = b.time"; + + "JOIN AvlReports b ON a.vehicleId=b.vehicleId AND a.maxTime = b.time " + + "JOIN VehicleConfigs vC ON a.vehicleId=vC.id"; } if(dbtype.equals("postgresql")) { sql = - "select a.vehicleId as \"vehicleId\", a.maxTime as \"maxTime\", lat, lon from ( " + "select a.vehicleId as \"vehicleId\", vC.name as \"name\", a.maxTime as \"maxTime\", lat, lon from ( " + "SELECT vehicleId, max(time) AS maxTime " + "FROM avlreports WHERE time > now() + '-24 hours' " + "GROUP BY vehicleId) a " - + "JOIN AvlReports b ON a.vehicleId=b.vehicleId AND a.maxTime = b.time"; + + "JOIN AvlReports b ON a.vehicleId=b.vehicleId AND a.maxTime = b.time " + + "JOIN VehicleConfigs vC ON a.vehicleId=vC.id"; } diff --git a/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp b/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp index faeec31b7..3152a4fd2 100644 --- a/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp +++ b/transitclockWebapp/src/main/webapp/reports/lastAvlReport.jsp @@ -30,7 +30,7 @@ function dataReadCallback(jsonData) { // Insert row (after the header) var row = table.insertRow(i+1); - row.insertCell(0).innerHTML = vehicleInfo.vehicleId; + row.insertCell(0).innerHTML = (vehicleInfo.name === undefined || vehicleInfo.name == '') ? vehicleInfo.vehicleId : vehicleInfo.name; row.insertCell(1).innerHTML = vehicleInfo.maxTime; row.insertCell(2).innerHTML = vehicleInfo.lat; row.insertCell(3).innerHTML = vehicleInfo.lon; diff --git a/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp b/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp index 8a966b96d..8d985410f 100644 --- a/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp +++ b/transitclockWebapp/src/main/webapp/reports/params/vehicle.jsp @@ -19,13 +19,14 @@