From 0065c7f4f5a6c51e0390d7a3afad2fe31e8cb537 Mon Sep 17 00:00:00 2001 From: Chandler Swift Date: Sat, 3 Feb 2024 00:28:31 -0600 Subject: [PATCH] Add amtrak train live location layer --- layers/amtrak-live/layer.js | 39 ++++++++++++++++++++ layers/amtrak-live/pin.svg | 22 +++++++++++ layers/{amtrak => amtrak-routes}/README.md | 0 layers/{amtrak => amtrak-routes}/get_data.sh | 0 layers/{amtrak => amtrak-routes}/layer.js | 0 layers/index.js | 9 ++++- 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 layers/amtrak-live/layer.js create mode 100644 layers/amtrak-live/pin.svg rename layers/{amtrak => amtrak-routes}/README.md (100%) rename layers/{amtrak => amtrak-routes}/get_data.sh (100%) rename layers/{amtrak => amtrak-routes}/layer.js (100%) diff --git a/layers/amtrak-live/layer.js b/layers/amtrak-live/layer.js new file mode 100644 index 0000000..266d8e7 --- /dev/null +++ b/layers/amtrak-live/layer.js @@ -0,0 +1,39 @@ +import VectorLayer from 'ol/layer/Vector'; +import {Vector as VectorSource} from 'ol/source.js'; + +import {Style} from 'ol/style.js'; +import Icon from 'ol/style/Icon.js'; + +import pinURL from './pin.svg?url'; +import { Feature } from 'ol'; +import { Point } from 'ol/geom'; +import { fromLonLat } from 'ol/proj'; + +const vectorLayer = new VectorLayer({ + source: new VectorSource({ + loader: async function() { + const res = await fetch("https://api-v3.amtraker.com/v3/trains"); + const trainsByRoute = await res.json(); + + for (let [_route, trains] of Object.entries(trainsByRoute)) { + for (let train of trains) { + const {stations: _, ...trainWithoutStations} = train; + this.addFeature(new Feature({ + geometry: new Point(fromLonLat([train.lon, train.lat])), + ...trainWithoutStations, + })) + } + } + }, + }), + style: new Style({ + image: new Icon({ + anchor: [0.5, .9], + src: pinURL, + }), + }), +}); + +setInterval(() => vectorLayer.getSource().refresh(), 30000); + +export default vectorLayer; diff --git a/layers/amtrak-live/pin.svg b/layers/amtrak-live/pin.svg new file mode 100644 index 0000000..633f210 --- /dev/null +++ b/layers/amtrak-live/pin.svg @@ -0,0 +1,22 @@ + + + + + diff --git a/layers/amtrak/README.md b/layers/amtrak-routes/README.md similarity index 100% rename from layers/amtrak/README.md rename to layers/amtrak-routes/README.md diff --git a/layers/amtrak/get_data.sh b/layers/amtrak-routes/get_data.sh similarity index 100% rename from layers/amtrak/get_data.sh rename to layers/amtrak-routes/get_data.sh diff --git a/layers/amtrak/layer.js b/layers/amtrak-routes/layer.js similarity index 100% rename from layers/amtrak/layer.js rename to layers/amtrak-routes/layer.js diff --git a/layers/index.js b/layers/index.js index 0855b45..bcf6fa9 100644 --- a/layers/index.js +++ b/layers/index.js @@ -3,7 +3,8 @@ import OSM from 'ol/source/OSM'; import StadiaMaps from 'ol/source/StadiaMaps.js'; import chandlerLayer from './chandler/layer.js'; -import amtrakLayer from './amtrak/layer.js'; +import amtrakRoutesLayer from './amtrak-routes/layer.js'; +import amtrakLiveLayer from './amtrak-live/layer'; import viarailLayer from './viarail/layer.js'; import arenasLayer from './nhl-arenas/layer.js'; import bikepackingLayer from './bikepacking/layer.js'; @@ -67,7 +68,11 @@ const layerCategories = [ }, { name: "Amtrak Routes", - layer: amtrakLayer, + layer: amtrakRoutesLayer, + }, + { + name: "Amtrak Trains (live-ish)", + layer: amtrakLiveLayer, }, { name: "Via Rail Routes",