Merge branch 'main' into feat/bikeshare-toronto-and-failure-fix

# Conflicts:
#	CHANGELOG.md
#	DATA_SOURCES.md
#	docs/CURRENT-STATE.md
This commit is contained in:
Sameh Khamis committed 2026-10-15 12:35:18 -07:00
commit c9f43e8517
274 files changed
+32719 -1707

No files matched your search

+149 -3
View File
@@ -23,6 +23,47 @@ function bcycleEntry({
...buildBcycleUrls(systemId),
};
}
function urbanSharingEntry({
id,
city,
centerLat,
centerLon,
systemId,
provider,
loadRadiusKm = 100,
}) {
return {
id,
city,
centerLat,
centerLon,
loadRadiusKm,
provider,
stationInformationUrl: `https://gbfs.urbansharing.com/${systemId}/station_information.json`,
stationStatusUrl: `https://gbfs.urbansharing.com/${systemId}/station_status.json`,
};
}
function enturEntry({
id,
city,
centerLat,
centerLon,
systemId,
provider,
loadRadiusKm = 100,
}) {
const base = `https://api.entur.io/mobility/v2/gbfs/v2/${systemId}`;
return {
id,
city,
centerLat,
centerLon,
loadRadiusKm,
provider,
stationInformationUrl: `${base}/station_information`,
stationStatusUrl: `${base}/station_status`,
};
}
const RAW_GBFS_CITY_REGISTRY = [
{
id: 'nyc-citibike',
@@ -48,6 +89,56 @@ const RAW_GBFS_CITY_REGISTRY = [
'https://gbfs.lyft.com/gbfs/2.3/chi/en/station_status.json',
provider: 'Divvy',
},
{
id: 'detroit-mogo',
city: 'Detroit, MI',
centerLat: 42.3314,
centerLon: -83.0458,
loadRadiusKm: 90,
stationInformationUrl:
'https://detroit.publicbikesystem.net/customer/gbfs/v2/en/station_information.json',
stationStatusUrl:
'https://detroit.publicbikesystem.net/customer/gbfs/v2/en/station_status.json',
provider: 'MoGo',
},
{
id: 'pittsburgh-pogoh',
city: 'Pittsburgh, PA',
centerLat: 40.4406,
centerLon: -79.9959,
loadRadiusKm: 90,
stationInformationUrl:
'https://pittsburgh.publicbikesystem.net/customer/gbfs/v2/en/station_information.json',
stationStatusUrl:
'https://pittsburgh.publicbikesystem.net/customer/gbfs/v2/en/station_status.json',
provider: 'POGOH',
},
{
id: 'aspen-we-cycle',
city: 'Aspen, CO',
centerLat: 39.1911,
centerLon: -106.8175,
loadRadiusKm: 90,
stationInformationUrl:
'https://aspen.publicbikesystem.net/customer/gbfs/v2/en/station_information.json',
stationStatusUrl:
'https://aspen.publicbikesystem.net/customer/gbfs/v2/en/station_status.json',
provider: 'WE-cycle',
},
// HIBike serves both Kailua-Kona and Hilo, about 95 km apart; the centre sits
// between them so a camera over either town loads the whole system.
{
id: 'hawaii-island-hibike',
city: 'Kona & Hilo, HI',
centerLat: 19.68,
centerLon: -155.54,
loadRadiusKm: 90,
stationInformationUrl:
'https://kona.publicbikesystem.net/customer/gbfs/v2/en/station_information.json',
stationStatusUrl:
'https://kona.publicbikesystem.net/customer/gbfs/v2/en/station_status.json',
provider: 'HIBike',
},
{
id: 'dc-capital-bikeshare',
city: 'Washington, DC',
@@ -326,6 +417,59 @@ const RAW_GBFS_CITY_REGISTRY = [
centerLon: -119.6982,
systemId: 'bcycle_santabarbara',
}),
urbanSharingEntry({
id: 'oslo-bysykkel',
city: 'Oslo, Norway',
centerLat: 59.9139,
centerLon: 10.7522,
systemId: 'oslobysykkel.no',
provider: 'Oslo Bysykkel',
}),
urbanSharingEntry({
id: 'bergen-bysykkel',
city: 'Bergen, Norway',
centerLat: 60.3913,
centerLon: 5.3221,
systemId: 'bergenbysykkel.no',
provider: 'Bergen Bysykkel',
}),
urbanSharingEntry({
id: 'trondheim-bysykkel',
city: 'Trondheim, Norway',
centerLat: 63.4305,
centerLon: 10.3951,
systemId: 'trondheimbysykkel.no',
provider: 'Trondheim Bysykkel',
}),
enturEntry({
id: 'stavanger-kolumbus',
city: 'Stavanger, Norway',
centerLat: 58.9,
centerLon: 5.72,
systemId: 'kolumbusbysykkel',
provider: 'Kolumbus Bysykkel',
}),
enturEntry({
id: 'skien-farte',
city: 'Skien/Porsgrunn, Norway',
centerLat: 59.16,
centerLon: 9.64,
systemId: 'fartebysykkel',
provider: 'Farte Bysykkel',
loadRadiusKm: 40,
}),
{
id: 'lillestrom-bysykkel',
city: 'Lillestrøm, Norway',
centerLat: 59.9556,
centerLon: 11.0492,
loadRadiusKm: 40,
stationInformationUrl:
'https://api.cyclocity.fr/contracts/lillestrom/gbfs/station_information.json',
stationStatusUrl:
'https://api.cyclocity.fr/contracts/lillestrom/gbfs/station_status.json',
provider: 'Bysykkel Lillestrøm',
},
];
function normalizeRegistryEntry(entry) {
const id = String(entry?.id || '')
@@ -354,11 +498,13 @@ function normalizeRegistryEntry(entry) {
) {
throw new Error(`GBFS entry "${id}" must use https URLs`);
}
// Validate that URLs end with expected GBFS endpoint filenames
if (!/\/station_information\.json$/i.test(stationInformationUrl.pathname)) {
// Validate that URLs end with expected GBFS endpoint names (Entur omits .json)
if (
!/\/station_information(\.json)?$/i.test(stationInformationUrl.pathname)
) {
throw new Error(`GBFS entry "${id}" station_information URL is invalid`);
}
if (!/\/station_status\.json$/i.test(stationStatusUrl.pathname)) {
if (!/\/station_status(\.json)?$/i.test(stationStatusUrl.pathname)) {
throw new Error(`GBFS entry "${id}" station_status URL is invalid`);
}