@transportme/load-ptv-gtfs 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/gtfs-parser/GTFSRoute.mjs +6 -6
- package/lib/gtfs-parser/GTFSStop.mjs +8 -0
- package/lib/gtfs-parser/GTFSTrip.mjs +13 -1
- package/package.json +1 -1
- package/test/newer-metro-loader-test.test.mjs +80 -0
- package/test/newer-tram-format.test.mjs +35 -0
- package/test/sample-data/new-metro-2/calendar.txt +13 -0
- package/test/sample-data/new-metro-2/calendar_dates.txt +1 -0
- package/test/sample-data/new-metro-2/routes.txt +2 -0
- package/test/sample-data/new-metro-2/stop_times.txt +5 -0
- package/test/sample-data/new-metro-2/stops.txt +9 -0
- package/test/sample-data/new-metro-2/trips.txt +2 -0
- package/test/sample-data/new-tram-2/routes.txt +25 -0
- package/test/sample-data/new-tram-2/stops.txt +5 -0
|
@@ -57,7 +57,7 @@ export default class GTFSRoute {
|
|
|
57
57
|
*/
|
|
58
58
|
static create(data, mode) {
|
|
59
59
|
let { routeGTFSID } = data
|
|
60
|
-
let routeTypes = [
|
|
60
|
+
let routeTypes = [ RailGTFSRoute, NewGTFSRoute, SmartrakGTFSRoute, GTFSRoute ]
|
|
61
61
|
for (let type of routeTypes) {
|
|
62
62
|
if (type.canProcess(routeGTFSID, mode)) return new type(data)
|
|
63
63
|
}
|
|
@@ -105,20 +105,20 @@ class NewGTFSRoute extends GTFSRoute {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
|
108
|
-
* Used to represent a Metro train route on the new data
|
|
108
|
+
* Used to represent a Metro train route on the new data. Suspect it works on V/Line routes as well
|
|
109
109
|
*
|
|
110
110
|
* Used for a technicality where the route name (eg Pakenham) is stored in the route number instead.
|
|
111
111
|
*/
|
|
112
|
-
class
|
|
112
|
+
class RailGTFSRoute extends NewGTFSRoute {
|
|
113
113
|
|
|
114
114
|
constructor(data) {
|
|
115
115
|
super(data)
|
|
116
|
-
this.routeName = this.routeNumber
|
|
116
|
+
this.routeName = this.routeNumber.replace(' Bus Replacement', '')
|
|
117
117
|
this.routeNumber = null
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
static canProcess(routeGTFSID, mode) {
|
|
121
|
-
return super.canProcess(routeGTFSID, mode) && mode === TRANSIT_MODES.metroTrain
|
|
121
|
+
return super.canProcess(routeGTFSID, mode) && (mode === TRANSIT_MODES.metroTrain || mode === TRANSIT_MODES.regionalTrain)
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
}
|
|
124
|
+
}
|
|
@@ -136,6 +136,14 @@ export class GTFSStop {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
if (stopNumberParts = stopName.match(/^(.*) #(D?\d*[A-Za-z]?)$/)) {
|
|
140
|
+
// Stops in the form ABC Road #123
|
|
141
|
+
return {
|
|
142
|
+
stopNumber: stopNumberParts[2].toUpperCase(),
|
|
143
|
+
stopName: stopNumberParts[1]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
139
147
|
return { stopNumber: null, stopName: stopName }
|
|
140
148
|
}
|
|
141
149
|
|
|
@@ -48,7 +48,7 @@ export default class GTFSTrip {
|
|
|
48
48
|
* @returns {GTFSTrip} A trip instance representing the data being passed in
|
|
49
49
|
*/
|
|
50
50
|
static create(data, mode) {
|
|
51
|
-
let types = [ SmartrakTrip, MetroTrip, GTFSTrip ]
|
|
51
|
+
let types = [ SmartrakTrip, MetroRRBTrip, MetroTrip, GTFSTrip ]
|
|
52
52
|
for (let type of types) {
|
|
53
53
|
if (type.canProcess(data, mode)) return new type(data)
|
|
54
54
|
}
|
|
@@ -176,4 +176,16 @@ export class MetroTrip extends GTFSTrip {
|
|
|
176
176
|
return this.#runID
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export class MetroRRBTrip extends MetroTrip {
|
|
182
|
+
|
|
183
|
+
constructor(data) {
|
|
184
|
+
super(data)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static canProcess(data, mode) {
|
|
188
|
+
return super.canProcess(data, mode) && data.id.match(/^02-\w{3}-R-/)
|
|
189
|
+
}
|
|
190
|
+
|
|
179
191
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LokiDatabaseConnection } from '@transportme/database'
|
|
2
|
+
import StopsLoader from '../lib/loader/StopsLoader.mjs'
|
|
3
|
+
import { TRANSIT_MODES } from '../lib/constants.mjs'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
import url from 'url'
|
|
6
|
+
import { expect } from 'chai'
|
|
7
|
+
import suburbs from './sample-data/suburbs.json' with { type: 'json' }
|
|
8
|
+
import RouteLoader from '../lib/loader/RouteLoader.mjs'
|
|
9
|
+
import TripLoader from '../lib/loader/TripLoader.mjs'
|
|
10
|
+
|
|
11
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
12
|
+
const __dirname = path.dirname(__filename)
|
|
13
|
+
|
|
14
|
+
const agencyFile = path.join(__dirname, 'sample-data', 'routes', 'agency.txt')
|
|
15
|
+
|
|
16
|
+
const calendarFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'calendar.txt')
|
|
17
|
+
const calendarDatesFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'calendar_dates.txt')
|
|
18
|
+
|
|
19
|
+
const routesFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'routes.txt')
|
|
20
|
+
|
|
21
|
+
const stopTimesFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'stop_times.txt')
|
|
22
|
+
const tripsFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'trips.txt')
|
|
23
|
+
const stopsFile = path.join(__dirname, 'sample-data', 'new-metro-2', 'stops.txt')
|
|
24
|
+
|
|
25
|
+
describe('The GTFS Loaders with the new 230525 Metro data', () => {
|
|
26
|
+
describe('The route loader', () => {
|
|
27
|
+
it('Should convert the updated route ID format to the legacy format', async () => {
|
|
28
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
29
|
+
let routes = await database.createCollection('routes')
|
|
30
|
+
|
|
31
|
+
let routeLoader = new RouteLoader(routesFile, agencyFile, TRANSIT_MODES.metroTrain, database)
|
|
32
|
+
await routeLoader.loadRoutes()
|
|
33
|
+
|
|
34
|
+
let williamstown = await routes.findDocument({ routeGTFSID: '2-WIL' })
|
|
35
|
+
|
|
36
|
+
expect(williamstown).to.exist
|
|
37
|
+
expect(williamstown.routeName).to.equal('Williamstown')
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('The trip loader', () => {
|
|
42
|
+
it('It identify a rail replacement bus trip and mark it as such', async () => {
|
|
43
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
44
|
+
let stops = await database.createCollection('stops')
|
|
45
|
+
let routes = await database.createCollection('routes')
|
|
46
|
+
let trips = await database.createCollection('gtfs timetables')
|
|
47
|
+
|
|
48
|
+
let stopLoader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.metroTrain, database)
|
|
49
|
+
await stopLoader.loadStops()
|
|
50
|
+
|
|
51
|
+
let routeLoader = new RouteLoader(routesFile, agencyFile, TRANSIT_MODES.metroTrain, database)
|
|
52
|
+
await routeLoader.loadRoutes()
|
|
53
|
+
|
|
54
|
+
let routeIDMap = routeLoader.getRouteIDMap()
|
|
55
|
+
|
|
56
|
+
let tripLoader = new TripLoader({
|
|
57
|
+
tripsFile, stopTimesFile,
|
|
58
|
+
calendarFile, calendarDatesFile
|
|
59
|
+
}, TRANSIT_MODES.metroTrain, database)
|
|
60
|
+
|
|
61
|
+
await tripLoader.loadTrips({ routeIDMap })
|
|
62
|
+
|
|
63
|
+
let trip = await trips.findDocument({ runID: 'BW000' })
|
|
64
|
+
|
|
65
|
+
expect(trip).to.not.be.null
|
|
66
|
+
expect(trip.tripID).to.equal('02-WIL-R-7-T6-BW000')
|
|
67
|
+
expect(trip.shapeID).to.equal('2-WIL-R-vpt-7.1.R')
|
|
68
|
+
expect(trip.routeGTFSID).to.equal('2-WIL')
|
|
69
|
+
expect(trip.block).to.equal(null)
|
|
70
|
+
expect(trip.isRailReplacementBus).to.be.true
|
|
71
|
+
expect(trip.direction).to.equal('Up')
|
|
72
|
+
|
|
73
|
+
expect(trip.stopTimings[0].stopName).to.equal('Williamstown Railway Station')
|
|
74
|
+
expect(trip.stopTimings[0].platform).to.equal('RRB')
|
|
75
|
+
|
|
76
|
+
expect(trip.stopTimings[3].stopName).to.equal('Newport Railway Station')
|
|
77
|
+
expect(trip.stopTimings[3].platform).to.equal('RRB')
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { LokiDatabaseConnection } from '@transportme/database'
|
|
2
|
+
import StopsLoader from '../lib/loader/StopsLoader.mjs'
|
|
3
|
+
import { TRANSIT_MODES } from '../lib/constants.mjs'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
import url from 'url'
|
|
6
|
+
import { expect } from 'chai'
|
|
7
|
+
import suburbs from './sample-data/suburbs.json' with { type: 'json' }
|
|
8
|
+
import RouteLoader from '../lib/loader/RouteLoader.mjs'
|
|
9
|
+
|
|
10
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
11
|
+
const __dirname = path.dirname(__filename)
|
|
12
|
+
|
|
13
|
+
const agencyFile = path.join(__dirname, 'sample-data', 'routes', 'agency.txt')
|
|
14
|
+
|
|
15
|
+
const routesFile = path.join(__dirname, 'sample-data', 'new-tram-2', 'routes.txt')
|
|
16
|
+
const stopsFile = path.join(__dirname, 'sample-data', 'new-tram-2', 'stops.txt')
|
|
17
|
+
|
|
18
|
+
describe('The GTFS Loaders with the new Tram data', () => {
|
|
19
|
+
describe('The stop loader', () => {
|
|
20
|
+
it('Should process the stops and add them to the database', async () => {
|
|
21
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
22
|
+
let stops = await database.createCollection('stops')
|
|
23
|
+
|
|
24
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.tram, database)
|
|
25
|
+
await loader.loadStops()
|
|
26
|
+
|
|
27
|
+
let stop = await stops.findDocument({
|
|
28
|
+
'stopName': 'Glenferrie Road/Wattletree Road'
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
expect(stop).to.not.be.null
|
|
32
|
+
expect(stop.bays[0].stopNumber).to.equal('45')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date
|
|
2
|
+
"T2","0","0","0","0","0","1","0","20250124","20250128"
|
|
3
|
+
"T5","0","1","1","1","0","0","0","20250121","20250123"
|
|
4
|
+
"T5_1","0","1","0","0","0","0","0","20250124","20250128"
|
|
5
|
+
"T5+v6","0","1","1","0","0","0","0","20250121","20250123"
|
|
6
|
+
"T5+v7","0","0","0","1","0","0","0","20250121","20250123"
|
|
7
|
+
"T5+v8","0","0","1","1","0","0","0","20250121","20250123"
|
|
8
|
+
"T5+v9","0","1","0","0","0","0","0","20250121","20250123"
|
|
9
|
+
"T5+w3","0","1","0","0","0","0","0","20250124","20250128"
|
|
10
|
+
"T5+w4","0","1","0","0","0","0","0","20250124","20250128"
|
|
11
|
+
"T6","0","0","0","0","1","0","0","20250124","20250128"
|
|
12
|
+
"UE","1","0","0","0","0","0","0","20250124","20250128"
|
|
13
|
+
"UH","0","0","0","0","0","0","1","20250124","20250128"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
service_id,date,exception_type
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_type,drop_off_type,shape_dist_traveled
|
|
2
|
+
"02-WIL-R-7-T6-BW000","20:59:00","20:59:00","26315","1","","0","0","0.00"
|
|
3
|
+
"02-WIL-R-7-T6-BW000","21:01:00","21:01:00","26314","2","","0","0","1181.84"
|
|
4
|
+
"02-WIL-R-7-T6-BW000","21:03:00","21:03:00","26247","3","","0","0","1940.26"
|
|
5
|
+
"02-WIL-R-7-T6-BW000","21:19:00","21:19:00","26242","4","","0","0","4445.63"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station,platform_code
|
|
2
|
+
"26242","Newport Rail Replacement Bus Stop","-37.84249141","144.88254956","","Parentvic:rail:NPT","R-Bus"
|
|
3
|
+
"26247","North Williamstown Rail Replacement Bus Stop","-37.85750447","144.89056490","","Parentvic:rail:NWN","R-Bus"
|
|
4
|
+
"26314","Williamstown Beach Rail Replacement Bus Stop","-37.86385491","144.89494197","","Parentvic:rail:WBH","R-Bus"
|
|
5
|
+
"26315","Williamstown Rail Replacement Bus Stop","-37.86756640","144.90547637","","Parentvic:rail:WIL","R-Bus"
|
|
6
|
+
"Parentvic:rail:NPT","Newport Railway Station","-37.84272637","144.88358830","1","",""
|
|
7
|
+
"Parentvic:rail:NWN","North Williamstown Railway Station","-37.85733348","144.88906947","1","",""
|
|
8
|
+
"Parentvic:rail:WBH","Williamstown Beach Railway Station","-37.86398189","144.89448368","1","",""
|
|
9
|
+
"Parentvic:rail:WIL","Williamstown Railway Station","-37.86775292","144.90532331","1","",""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
route_id,agency_id,route_short_name,route_long_name,route_type,route_color,route_text_color
|
|
2
|
+
"aus:vic:vic-03-1:","37","1","South Melbourne Beach - East Coburg","0","B5BD00","000000"
|
|
3
|
+
"aus:vic:vic-03-109:","37","109","Port Melbourne - Box Hill","0","E87722","000000"
|
|
4
|
+
"aus:vic:vic-03-11:","37","11","Victoria Harbour Docklands - West Preston","0","6ECEB2","000000"
|
|
5
|
+
"aus:vic:vic-03-12:","37","12","St Kilda (Fitzroy St) - Victoria Gardens","0","007E92","FFFFFF"
|
|
6
|
+
"aus:vic:vic-03-16:","37","16","Kew - Melbourne University via St Kilda Beach","0","FBD872","000000"
|
|
7
|
+
"aus:vic:vic-03-19:","37","19","Flinders Street Station, City - North Coburg","0","8A1B61","FFFFFF"
|
|
8
|
+
"aus:vic:vic-03-3:","37","3","East Malvern - Melbourne University","0","8DC8E8","000000"
|
|
9
|
+
"aus:vic:vic-03-30:","37","30","Central Pier Docklands - St Vincents Plaza","0","534F96","FFFFFF"
|
|
10
|
+
"aus:vic:vic-03-35:","37","35","Clockwise - Clockwise","0","6B3529","FFFFFF"
|
|
11
|
+
"aus:vic:vic-03-48:","37","48","Victoria Harbour Docklands - North Balwyn","0","333434","FFFFFF"
|
|
12
|
+
"aus:vic:vic-03-5:","37","5","Malvern (Burke Road) - Melbourne University","0","D50032","FFFFFF"
|
|
13
|
+
"aus:vic:vic-03-57:","37","57","Flinders Street Station, City - West Maribyrnong","0","00C1D5","000000"
|
|
14
|
+
"aus:vic:vic-03-58:","37","58","Toorak - West Coburg","0","969696","FFFFFF"
|
|
15
|
+
"aus:vic:vic-03-59:","37","59","Flinders Street Station, City - Airport West","0","00653A","FFFFFF"
|
|
16
|
+
"aus:vic:vic-03-6:","37","6","Glen Iris - Moreland","0","01426A","FFFFFF"
|
|
17
|
+
"aus:vic:vic-03-64:","37","64","East Brighton - Melbourne University","0","00AB8E","FFFFFF"
|
|
18
|
+
"aus:vic:vic-03-67:","37","67","Carnegie - Melbourne University","0","956C58","FFFFFF"
|
|
19
|
+
"aus:vic:vic-03-70:","37","70","Waterfront City Docklands - Wattle Park","0","F59BBB","000000"
|
|
20
|
+
"aus:vic:vic-03-72:","37","72","Camberwell - Melbourne University","0","9ABEAA","000000"
|
|
21
|
+
"aus:vic:vic-03-75:","37","75","Central Pier Docklands - Vermont South","0","00A9E0","000000"
|
|
22
|
+
"aus:vic:vic-03-78:","37","78","Balaclava via Prahran - North Richmond","0","A0A0D6","000000"
|
|
23
|
+
"aus:vic:vic-03-82:","37","82","Moonee Ponds - Footscray","0","D2D755","000000"
|
|
24
|
+
"aus:vic:vic-03-86:","37","86","Waterfront City Docklands - Bundoora RMIT","0","FFB500","000000"
|
|
25
|
+
"aus:vic:vic-03-96:","37","96","St Kilda Beach - East Brunswick","0","C6007E","FFFFFF"
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
stop_id,stop_name,stop_lat,stop_lon
|
|
2
|
+
"10311","Glenferrie Rd/Wattletree Rd #45","-37.86245520","145.02850849"
|
|
3
|
+
"10371","Duncraig Ave/Wattletree Rd #44","-37.86206934","145.02538150"
|
|
4
|
+
"1083","Clyde St/Raleigh Rd #42","-37.76969864","144.89884126"
|
|
5
|
+
"11285","Egerton Rd/Wattletree Rd #43","-37.86170982","145.02275399"
|