From df835c8b2c1eee37fc65d2c2ab2b1f674d411e26 Mon Sep 17 00:00:00 2001 From: r8btx <60275558+r8btx@users.noreply.github.com> Date: Tue, 21 Nov 2023 19:31:23 -0500 Subject: [PATCH 1/6] Initial implementation of transportation query --- front-end/src/utils/transportData.js | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 front-end/src/utils/transportData.js diff --git a/front-end/src/utils/transportData.js b/front-end/src/utils/transportData.js new file mode 100644 index 0000000..9c14e15 --- /dev/null +++ b/front-end/src/utils/transportData.js @@ -0,0 +1,75 @@ +import axios from 'axios'; + +const EXCLUDED_ROUTES_QUERY_DELAY = 600000; // 10 mins +const ALERTS_QUERY_DELAY = 120000; // 2 mins +const MIN_QUERY_DELAY = 60000; // 1 min + +let lastExcludedRoutesQuery = -EXCLUDED_ROUTES_QUERY_DELAY; +let lastAlertsQuery = -ALERTS_QUERY_DELAY; +let lastQuery = -MIN_QUERY_DELAY; +let lastResults = {}; + +// Query transportations (real-time update is done through the websocket) +export async function queryTransportations(refresh) { + // Prevent too frequent requests (rate limiting) + if (performance.now() - lastQuery < MIN_QUERY_DELAY) { + return lastResults; + } + + // JSON payload + const json = { + s0: localStorage.agencyId, + sA: 1, + }; + + const subscribedRoutes = localStorage.subscribedRoutes ? localStorage.subscribedRoutes.split(',') : []; + if (subscribedRoutes.length) { + json.rA = subscribedRoutes.length; + } + subscribedRoutes.forEach((route, index) => { + json['r' + index] = route; + }); + + // Params for URL + const params = { + getBuses: refresh || performance.now() - lastExcludedRoutesQuery > EXCLUDED_ROUTES_QUERY_DELAY ? 1 : 2, + deviceId: localStorage.deviceId, + }; + + // Optional parameters + if (refresh) { + params.speed = '1'; + } + if (performance.now() - lastAlertsQuery > ALERTS_QUERY_DELAY) { + params.alertCRC = localStorage.alertCRC; + lastAlertsQuery = performance.now(); + } + + const urlParams = new URLSearchParams(params); + const url = `${localStorage.serviceEndpointSub}/goServices.php?${urlParams.toString()}`; + + try { + const response = await axios.post(url, json); + const data = response.data; + if (!data) { + throw new Error('empty response'); + } + if (data.excludedRoutes) { + lastExcludedRoutesQuery = performance.now(); + // place routes2 implementation here? + } + if (data && ((data.alertCRC && data.alertCRC != localStorage.alertCRC) || data.lastPushId > 0)) { + // query alerts + } + + const transportations = data.buses && Object.keys(data.buses).length ? data.buses : {}; + + lastResults = transportations; + lastQuery = performance.now(); + + return transportations; + } catch (error) { + console.log('Transportations query error: ' + error.message); + return {}; + } +} From be17715f103d2cbba4fc9ab07d2bc5d7d35166d3 Mon Sep 17 00:00:00 2001 From: r8btx <60275558+r8btx@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:17:24 -0500 Subject: [PATCH 2/6] fixed bug --- front-end/src/utils/transportData.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/front-end/src/utils/transportData.js b/front-end/src/utils/transportData.js index 9c14e15..cf72b72 100644 --- a/front-end/src/utils/transportData.js +++ b/front-end/src/utils/transportData.js @@ -16,7 +16,7 @@ export async function queryTransportations(refresh) { return lastResults; } - // JSON payload + // JSON const json = { s0: localStorage.agencyId, sA: 1, @@ -29,6 +29,8 @@ export async function queryTransportations(refresh) { subscribedRoutes.forEach((route, index) => { json['r' + index] = route; }); + const formData = new URLSearchParams({}); + formData.append('json', JSON.stringify(json)); // Params for URL const params = { @@ -46,10 +48,10 @@ export async function queryTransportations(refresh) { } const urlParams = new URLSearchParams(params); - const url = `${localStorage.serviceEndpointSub}/goServices.php?${urlParams.toString()}`; + const url = `${localStorage.serviceEndpointSub}/mapGetData.php?${urlParams.toString()}`; try { - const response = await axios.post(url, json); + const response = await axios.post(url, formData); const data = response.data; if (!data) { throw new Error('empty response'); @@ -67,6 +69,8 @@ export async function queryTransportations(refresh) { lastResults = transportations; lastQuery = performance.now(); + console.log(transportations); + return transportations; } catch (error) { console.log('Transportations query error: ' + error.message); From 91ef92350071c0c7e18acdf6f22b9e3d0defb407 Mon Sep 17 00:00:00 2001 From: r8btx <60275558+r8btx@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:17:40 -0500 Subject: [PATCH 3/6] replaced proxy version --- front-end/src/components/Map.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/front-end/src/components/Map.js b/front-end/src/components/Map.js index 04c8de0..b64357f 100644 --- a/front-end/src/components/Map.js +++ b/front-end/src/components/Map.js @@ -2,10 +2,10 @@ import '../css/map.css'; import { useEffect, useState, useRef } from 'react'; import RealTimeDataWebSocket from '../utils/websocket'; import { loadGoogleMapsAPI, initializeMap, getCoordinates, generateTwoUniqueRandomInts } from '../utils/mapUtility'; +import { queryTransportations } from '../utils/transportData'; import { updateTransportMarkers } from '../utils/transportMarker'; function Map({ line, lineColor }) { - //const API_KEY = ''; const googleMapRef = useRef(null); const [isApiLoaded, setIsApiLoaded] = useState(false); const [isMapLoaded, setIsMapLoaded] = useState(false); @@ -95,15 +95,8 @@ function Map({ line, lineColor }) { const fetchTransportData = async () => { try { - // console.log('fetching transport data'); - const response = await fetch('/buses'); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } - // console.log('response ok'); - const data = await response.json(); - console.log('Initial transport data fetched'); - setTransportData(data); + const transportations = await queryTransportations(true); + setTransportData(transportations); } catch (error) { console.log('error fetching transport data', error); // Other error handling? message? From b99d86bc67dfcf9902768664c76e9dcdf1dabb00 Mon Sep 17 00:00:00 2001 From: r8btx <60275558+r8btx@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:18:17 -0500 Subject: [PATCH 4/6] removed log messages --- front-end/src/utils/transportData.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/front-end/src/utils/transportData.js b/front-end/src/utils/transportData.js index cf72b72..d0bdf75 100644 --- a/front-end/src/utils/transportData.js +++ b/front-end/src/utils/transportData.js @@ -69,8 +69,6 @@ export async function queryTransportations(refresh) { lastResults = transportations; lastQuery = performance.now(); - console.log(transportations); - return transportations; } catch (error) { console.log('Transportations query error: ' + error.message); From 6c589e118d52fe90500f8db18ab3a2149138d56e Mon Sep 17 00:00:00 2001 From: r8btx <60275558+r8btx@users.noreply.github.com> Date: Tue, 21 Nov 2023 23:46:03 -0500 Subject: [PATCH 5/6] dynamically generate marker icon --- front-end/src/utils/transportMarker.js | 44 ++++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/front-end/src/utils/transportMarker.js b/front-end/src/utils/transportMarker.js index 5ed48f6..baec0ad 100644 --- a/front-end/src/utils/transportMarker.js +++ b/front-end/src/utils/transportMarker.js @@ -1,5 +1,4 @@ const MAX_ANIMATION_DURATION = 7000; -const busIcons = ['A', 'B', 'C', 'E', 'F', 'G', 'W']; export function updateTransportMarkers(transportData, markerRef, map) { if (!transportData) { @@ -16,35 +15,37 @@ export function updateTransportMarkers(transportData, markerRef, map) { // Process new and existing transport data Object.keys(transportData).forEach((transport) => { - let lat = parseFloat(transportData[transport][0].latitude); - let lng = parseFloat(transportData[transport][0].longitude); + const transportInfo = transportData[transport][0]; + const lat = parseFloat(transportInfo.latitude); + const lng = parseFloat(transportInfo.longitude); const newPosition = new window.google.maps.LatLng(lat, lng); + const newIcon = generateTransportMarkerIcon(transportInfo.color, transportInfo.calculatedCourse); if (markerRef.current[transport]) { + // Update the position of the existing marker const currentPosition = markerRef.current[transport].getPosition(); animateMarker(markerRef.current[transport], currentPosition, newPosition, MAX_ANIMATION_DURATION); + + // Update the icon of the existing marker + markerRef.current[transport].setIcon(newIcon); } else { // Create a new marker - let transportMarker = createTransportMarker(newPosition, transportData[transport][0], map); + let transportMarker = createTransportMarker(newPosition, transportInfo, map, newIcon); markerRef.current[transport] = transportMarker; } }); } function createTransportMarker(position, transportInfo, map) { - let icon = busIcons[Math.floor(Math.random() * busIcons.length)] let transportMarker = new window.google.maps.Marker({ position, map, title: String(transportInfo.busId), - icon: { - url: 'busIcons/busIcon_route'+busIcons[Math.floor(Math.random() * busIcons.length)]+'.png', - scaledSize: new window.google.maps.Size(30, 30), - }, + icon: generateTransportMarkerIcon(transportInfo.color || '#000', transportInfo.calculatedCourse || 0), }); let infowindow = new window.google.maps.InfoWindow({ - content: `