diff --git a/static/js/main.js b/static/js/main.js
index fe77cdc..3ce6288 100644
--- a/static/js/main.js
+++ b/static/js/main.js
@@ -1,4 +1,3 @@
-import protobuf from "https://cdn.jsdelivr.net/npm/protobufjs@8.0.0/dist/protobuf.js/+esm";
import * as L from "https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet-src.esm.js";
import Alpine from "https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/module.esm.min.js";
@@ -14,6 +13,13 @@ function displayLastUpdated() {
setInterval(displayLastUpdated, 1000)
+const RouteType = {
+ TRAM: 1,
+ SUBWAY: 2,
+ RAIL: 3,
+ BUS: 4,
+}
+
const ICONS = {
bus: ``,
tram: ``,
@@ -79,163 +85,155 @@ function clearMap() {
frontRunnerLayer.clearLayers();
}
-protobuf.load("/schema.proto").then((root) => {
- const RouteType = root.VehicleFeed.Route.RouteType;
+function routeDesignator(route) {
+ if (route.id == "92235") {
+ return "OGX";
+ } else if (route.id == "3686") {
+ return "UVX";
+ } else if (route.id == "87711") {
+ return "MVX";
+ } else if (route.type == RouteType.BUS) {
+ return "#" + route.short_name;
+ } else {
+ return route.long_name;
+ }
+}
- function routeDesignator(route) {
- if (route.id == "92235") {
- return "OGX";
- } else if (route.id == "3686") {
- return "UVX";
- } else if (route.id == "87711") {
- return "MVX";
- } else if (route.type == RouteType.BUS) {
- return "#" + route.shortName;
- } else {
- return route.longName;
+function populateTotals(vehicles) {
+ const totals = {
+ bus: 0,
+ trax: 0,
+ frontrunner: 0,
+ }
+
+ for (const vehicle of vehicles) {
+ switch(vehicle.route.type) {
+ case RouteType.BUS:
+ totals.bus++;
+ break;
+ case RouteType.TRAM:
+ totals.trax++;
+ break;
+ case RouteType.RAIL:
+ totals.frontrunner++;
+ break;
}
}
- function populateTotals(vehicles) {
- const totals = {
- bus: 0,
- trax: 0,
- frontrunner: 0,
- }
+ document.getElementById("count-bus").innerText = totals.bus.toString()
+ document.getElementById("count-trax").innerText = totals.trax.toString()
+ document.getElementById("count-frontrunner").innerText = totals.frontrunner.toString()
+}
- for (const vehicle of vehicles) {
- switch(vehicle.route.type) {
- case RouteType.BUS:
- totals.bus++;
- break;
- case RouteType.TRAM:
- totals.trax++;
- break;
- case RouteType.RAIL:
- totals.frontrunner++;
- break;
- }
- }
+let bannerVisible = false
- document.getElementById("count-bus").innerText = totals.bus.toString()
- document.getElementById("count-trax").innerText = totals.trax.toString()
- document.getElementById("count-frontrunner").innerText = totals.frontrunner.toString()
- }
+let currentVehicles = new Map()
- let bannerVisible = false
+function renderVehicleIcon(vehicle) {
+ return L.divIcon({
+ className: "",
+ html: `
+
+ ${
+ vehicle.route.type == RouteType.BUS
+ ? ICONS.bus
+ : vehicle.route.type == RouteType.TRAM
+ ? ICONS.tram
+ : vehicle.route.type == RouteType.RAIL
+ ? ICONS.train
+ : ""
+ }
+
`,
+ })
+}
- let currentVehicles = new Map()
-
- function renderVehicleIcon(vehicle) {
- return L.divIcon({
- className: "",
- html: `
-
- ${
- vehicle.route.type == RouteType.BUS
- ? ICONS.bus
- : vehicle.route.type == RouteType.TRAM
- ? ICONS.tram
- : vehicle.route.type == RouteType.RAIL
- ? ICONS.train
- : ""
- }
-
`,
- })
- }
-
- function renderVehicle(vehicle) {
- return L.marker([vehicle.lat, vehicle.lon], {
- zIndexOffset:
- vehicle.route.type == RouteType.TRAM ||
- vehicle.route.type == RouteType.RAIL
- ? 4000
- : 3000,
- icon: renderVehicleIcon(vehicle),
- })
- .bindPopup(
- `${routeDesignator(vehicle.route)} to ${vehicle.headsign.replace(
- /^to /i,
- ""
- )}${vehicle.nearestStation ? `
@ ${vehicle.nearestStation?.name}` : ""}
vehicle #: ${vehicle.id}`
- );
- }
-
- async function reload() {
- const bin = await fetch("/api").then((r) => r.arrayBuffer());
- const { vehicles, info } = root
- .lookupType("VehicleFeed")
- .decode(new Uint8Array(bin));
-
- lastUpdated = info.lastUpdate
- displayLastUpdated()
-
- populateTotals(vehicles)
- if (vehicles.length == 0) {
- if (!bannerVisible) {
- document.getElementById("banner").classList.remove("hidden")
- bannerVisible = true
- map.invalidateSize()
- }
- } else {
- if (bannerVisible) {
- document.getElementById("banner").classList.add("hidden")
- bannerVisible = false
- map.invalidateSize()
- }
- }
-
- const seenVehicleIds = new Set()
-
- vehicles.forEach((vehicle) => {
- seenVehicleIds.add(vehicle.id)
-
- if (currentVehicles.has(vehicle.id)) { // if this vehicle is already on the map, update its location
- currentVehicles.get(vehicle.id).marker.setLatLng([vehicle.lat, vehicle.lon])
- currentVehicles.get(vehicle.id).marker.setIcon(renderVehicleIcon(vehicle))
- } else {
- const marker = renderVehicle(vehicle)
- marker.addTo(
- ["92235", "3686", "87711"].includes(vehicle.route.id)
- ? brtLayer
- : vehicle.route.type == RouteType.TRAM
- ? traxLayer
- : vehicle.route.type == RouteType.RAIL
- ? frontRunnerLayer
- : busLayer
- );
- currentVehicles.set(vehicle.id, {
- vehicle,
- marker,
+function renderVehicle(vehicle) {
+ return L.marker([vehicle.lat, vehicle.lon], {
+ zIndexOffset:
+ vehicle.route.type == RouteType.TRAM ||
+ vehicle.route.type == RouteType.RAIL
+ ? 4000
+ : 3000,
+ icon: renderVehicleIcon(vehicle),
})
- }
- });
+ .bindPopup(
+ `${routeDesignator(vehicle.route)} to ${vehicle.headsign.replace(
+ /^to /i,
+ ""
+ )}${vehicle.nearest_station ? `
@ ${vehicle.nearest_station?.name}` : ""}
vehicle #: ${vehicle.id}`
+ );
+}
- // remove any vehicles that should be removed
- for (const key of currentVehicles.keys()) {
- if (!seenVehicleIds.has(key)) {
- console.log(`removing vehicle from route ${currentVehicles.get(key).vehicle.route.shortName}`)
- currentVehicles.get(key).marker.remove()
- currentVehicles.delete(key)
- }
+async function reload() {
+ const { vehicles, info } = await fetch("/api", { headers: { Accept: "application/json" } }).then((r) => r.json());
+
+ lastUpdated = info.last_update
+ displayLastUpdated()
+
+ populateTotals(vehicles)
+ if (vehicles.length == 0) {
+ if (!bannerVisible) {
+ document.getElementById("banner").classList.remove("hidden")
+ bannerVisible = true
+ map.invalidateSize()
+ }
+ } else {
+ if (bannerVisible) {
+ document.getElementById("banner").classList.add("hidden")
+ bannerVisible = false
+ map.invalidateSize()
}
}
- reload();
+ const seenVehicleIds = new Set()
- setInterval(reload, 5000);
-});
+ vehicles.forEach((vehicle) => {
+ seenVehicleIds.add(vehicle.id)
+
+ if (currentVehicles.has(vehicle.id)) { // if this vehicle is already on the map, update its location
+ currentVehicles.get(vehicle.id).marker.setLatLng([vehicle.lat, vehicle.lon])
+ currentVehicles.get(vehicle.id).marker.setIcon(renderVehicleIcon(vehicle))
+ } else {
+ const marker = renderVehicle(vehicle)
+ marker.addTo(
+ ["92235", "3686", "87711"].includes(vehicle.route.id)
+ ? brtLayer
+ : vehicle.route.type == RouteType.TRAM
+ ? traxLayer
+ : vehicle.route.type == RouteType.RAIL
+ ? frontRunnerLayer
+ : busLayer
+ );
+ currentVehicles.set(vehicle.id, {
+ vehicle,
+ marker,
+ })
+ }
+ });
+
+ // remove any vehicles that should be removed
+ for (const key of currentVehicles.keys()) {
+ if (!seenVehicleIds.has(key)) {
+ currentVehicles.get(key).marker.remove()
+ currentVehicles.delete(key)
+ }
+ }
+}
+
+reload();
+
+setInterval(reload, 5000);
Alpine.data('app', () => ({
busLayer: true,