Compare commits

...
2 Commits
Author SHA1 Message Date
cjdenio ca0939ee67 oops 2026-09-20 17:19:44 -06:00
cjdenio b7321adbe4 NEW FEATURE: display route when clicking vehicle 2026-09-20 17:15:57 -06:00
3 changed files with 68 additions and 7 deletions

No files matched your search

+32
View File
@@ -257,6 +257,37 @@ func vehicleHandler(mode string) http.HandlerFunc {
} }
} }
func tripHandler(w http.ResponseWriter, r *http.Request) {
rows, err := scheduleDb.Query(`SELECT shapes.shape_pt_lat, shapes.shape_pt_lon FROM shapes INNER JOIN trips ON trips.shape_id = shapes.shape_id WHERE trips.trip_id = ? ORDER BY shapes.shape_pt_sequence ASC`, r.PathValue("trip"))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
var points [][]float64
for rows.Next() {
var lat float64
var lon float64
err = rows.Scan(&lat, &lon)
if err != nil {
break
}
points = append(points, []float64{lat, lon})
}
if len(points) == 0 {
w.WriteHeader(http.StatusNotFound)
return
}
w.Header().Add("Content-Type", "application/json")
response, _ := json.Marshal(map[string]any{"shape": points})
w.Write(response)
}
func main() { func main() {
fmt.Println("Opening database...") fmt.Println("Opening database...")
@@ -275,6 +306,7 @@ func main() {
http.HandleFunc("/api", vehicleHandler("")) http.HandleFunc("/api", vehicleHandler(""))
http.HandleFunc("/api.json", vehicleHandler("json")) http.HandleFunc("/api.json", vehicleHandler("json"))
http.HandleFunc("/api/trips/{trip}", tripHandler)
port := "3000" port := "3000"
if portEnv, ok := os.LookupEnv("PORT"); ok { if portEnv, ok := os.LookupEnv("PORT"); ok {
+1 -1
View File
@@ -300,6 +300,6 @@
</div> </div>
</div> </div>
<script type="module" src="/js/main.js?v=10"></script> <script type="module" src="/js/main.js?v=11"></script>
</body> </body>
</html> </html>
+35 -6
View File
@@ -91,11 +91,15 @@ const brtLayer = L.layerGroup().addTo(map);
const traxLayer = L.layerGroup().addTo(map); const traxLayer = L.layerGroup().addTo(map);
const frontRunnerLayer = L.layerGroup().addTo(map); const frontRunnerLayer = L.layerGroup().addTo(map);
L.polyline(shapes.blueLine, { color: "#004a97", zIndexOffset: 10 }).addTo(map); const railLayer = L.layerGroup().addTo(map);
L.polyline(shapes.redLine, { color: "#be2036", zIndexOffset: 10 }).addTo(map);
L.polyline(shapes.greenLine, { color: "#2eb566", zIndexOffset: 10 }).addTo(map); const currentRouteLayer = L.layerGroup().addTo(map);
L.polyline(shapes.sLine, { color: "#77777a", zIndexOffset: 10 }).addTo(map);
L.polyline(shapes.frontRunner, { color: "#c227b9", zIndexOffset: 10 }).addTo(map); L.polyline(shapes.blueLine, { color: "#004a97", zIndexOffset: 10 }).addTo(railLayer);
L.polyline(shapes.redLine, { color: "#be2036", zIndexOffset: 10 }).addTo(railLayer);
L.polyline(shapes.greenLine, { color: "#2eb566", zIndexOffset: 10 }).addTo(railLayer);
L.polyline(shapes.sLine, { color: "#77777a", zIndexOffset: 10 }).addTo(railLayer);
L.polyline(shapes.frontRunner, { color: "#c227b9", zIndexOffset: 10 }).addTo(railLayer);
// render stations // render stations
for (const station of stations) { for (const station of stations) {
@@ -240,6 +244,18 @@ function vehiclePopupContent(vehicle) {
return content return content
} }
const tripShapeCache = new Map();
async function getTripShape(tripId) {
if (tripShapeCache.has(tripId)) {
return tripShapeCache.get(tripId);
} else {
const data = await fetch(`/api/trips/${tripId}`).then(r => r.json());
tripShapeCache.set(tripId, data.shape);
return data.shape;
}
}
function renderVehicle(vehicle) { function renderVehicle(vehicle) {
return L.marker([vehicle.lat, vehicle.lon], { return L.marker([vehicle.lat, vehicle.lon], {
zIndexOffset: zIndexOffset:
@@ -248,7 +264,20 @@ function renderVehicle(vehicle) {
? 4000 ? 4000
: 3000, : 3000,
icon: renderVehicleIcon(vehicle), icon: renderVehicleIcon(vehicle),
}).bindPopup(vehiclePopupContent(vehicle)); }).bindPopup(vehiclePopupContent(vehicle)).on("popupopen", () => {
getTripShape(vehicle.trip_id).then(shape => {
console.log(shape)
for (const layer of railLayer.getLayers()) {
layer.setStyle({ opacity: 0.2 });
}
L.polyline(shape, { color: `#${vehicle.route.color}`, zIndexOffset: 10 }).addTo(currentRouteLayer);
})
}).on("popupclose", () => {
for (const layer of railLayer.getLayers()) {
layer.setStyle({ opacity: 1.0 });
}
currentRouteLayer.clearLayers();
});
} }
async function reload() { async function reload() {