feat(transit): add Szczecin buses and trams (ZDiTM, CC0)

Keyless GTFS-Realtime feed published by ZDiTM Szczecin under CC0 1.0.
Speeds are m/s (checked against vehicle movement), the file refreshes about
every 20 s, and the feed carries no route ids, so vehicles take the default
bus mode.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
Itallo BrandãoandClaude Sonnet 5.5 committed 2026-11-06 02:50:42 -03:00
1 parent edd6212793
commit 433b336c2d
6 files changed
+57 -4

No files matched your search

+23
View File
@@ -788,6 +788,29 @@ export const TRANSIT_FEED_REGISTRY = Object.freeze([
defaultMode: 'bus',
routeLabel: rioRouteLabel,
}),
Object.freeze({
id: 'zditm-szczecin',
name: 'Szczecin buses and trams',
operator:
'Zarząd Dróg i Transportu Miejskiego w Szczecinie (ZDiTM), Szczecin',
region: 'Szczecin, Poland',
// Every vehicle in a 2026-11-05 snapshot sat between 53.34–53.55 N and
// 14.44–14.77 E, inside 20 km of this point.
center: Object.freeze({ lat: 53.44, lon: 14.56 }),
loadRadiusKm: 25,
url: 'https://www.zditm.szczecin.pl/storage/gtfs/gtfs-rt-vehicles.pb',
license: 'CC0 1.0',
licenseUrl: 'https://www.zditm.szczecin.pl/en/zditm/for-developers',
attribution:
'Zarząd Dróg i Transportu Miejskiego w Szczecinie (ZDiTM Szczecin)',
defaultEnabled: true,
terms: Object.freeze({
quote:
'The data are provided free of charge under the CC0 1.0 licence, for use in any context, with no prior notification required.',
note: 'CC0 needs no credit; it is given anyway as a courtesy. ZDiTM gives no guarantee of accuracy or completeness. The developer page says the feed updates every minute; measured on 2026-11-05 the file changed about every 20 seconds, with vehicle timestamps up to 50 seconds old. Speeds are m/s: checked against vehicle movement between two snapshots. The feed carries no route id at all, so every vehicle takes the feed default mode even though the city also runs trams.',
}),
defaultMode: 'bus',
}),
]);
/**
+26
View File
@@ -552,3 +552,29 @@ test('Rio feeds are CC BY 4.0 and live', () => {
'Rio has a DATA_SOURCES row',
);
});
test('Szczecin is CC0, live, covers the city and not Berlin', () => {
const feed = getTransitFeed('zditm-szczecin');
assert.equal(feed.defaultEnabled, true);
assert.equal(feed.license, 'CC0 1.0');
assert.equal(
feed.licenseUrl,
'https://www.zditm.szczecin.pl/en/zditm/for-developers',
);
assert.match(feed.terms.quote, /CC0 1\.0 licence/);
assert.match(feed.attribution, /ZDiTM/);
assert.equal(feed.routeLabel, undefined, 'the feed has no route ids');
assert.equal(transitModeFor(feed, null), 'bus');
const ids = (lat, lon) => transitFeedsInRange(lat, lon).map((f) => f.id);
assert.ok(ids(53.4285, 14.5528).includes('zditm-szczecin'), 'city centre');
assert.ok(ids(53.5, 14.7).includes('zditm-szczecin'), 'north-east edge');
assert.ok(!ids(52.52, 13.405).includes('zditm-szczecin'), 'Berlin');
const sources = readFileSync(
new URL('../../DATA_SOURCES.md', import.meta.url),
'utf8',
);
assert.ok(
sources.split('\n').some((l) => l.startsWith('| **ZDiTM Szczecin')),
'Szczecin has a DATA_SOURCES row',
);
});