@transportme/load-ptv-gtfs 1.0.0
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/.github/workflows/unit-test.yml +46 -0
- package/lib/constants.mjs +18 -0
- package/lib/gtfs-package/PTVGTFS.mjs +96 -0
- package/lib/gtfs-parser/GTFSAgency.mjs +15 -0
- package/lib/gtfs-parser/GTFSCalendar.mjs +63 -0
- package/lib/gtfs-parser/GTFSCalendarDate.mjs +15 -0
- package/lib/gtfs-parser/GTFSRoute.mjs +106 -0
- package/lib/gtfs-parser/GTFSShape.mjs +39 -0
- package/lib/gtfs-parser/GTFSStop.mjs +212 -0
- package/lib/gtfs-parser/GTFSStopTime.mjs +30 -0
- package/lib/gtfs-parser/GTFSTrip.mjs +169 -0
- package/lib/gtfs-parser/readers/GTFSAgencyReader.mjs +27 -0
- package/lib/gtfs-parser/readers/GTFSCalendarDatesReader.mjs +25 -0
- package/lib/gtfs-parser/readers/GTFSCalendarReader.mjs +63 -0
- package/lib/gtfs-parser/readers/GTFSReader.mjs +48 -0
- package/lib/gtfs-parser/readers/GTFSRouteReader.mjs +35 -0
- package/lib/gtfs-parser/readers/GTFSShapeReader.mjs +75 -0
- package/lib/gtfs-parser/readers/GTFSStopTimesReader.mjs +85 -0
- package/lib/gtfs-parser/readers/GTFSStopsReader.mjs +36 -0
- package/lib/gtfs-parser/readers/GTFSTripReader.mjs +61 -0
- package/lib/gtfs-parser/readers/line-reader.mjs +112 -0
- package/lib/loader/RouteLoader.mjs +101 -0
- package/lib/loader/ShapeLoader.mjs +86 -0
- package/lib/loader/StopsLoader.mjs +139 -0
- package/lib/loader/TripLoader.mjs +187 -0
- package/lib/post-processing/merge-stops.mjs +85 -0
- package/lib/post-processing/set-route-stops.mjs +73 -0
- package/lib/post-processing/set-stop-services.mjs +64 -0
- package/lib/utils.mjs +16 -0
- package/package.json +27 -0
- package/test/gtfs-calendar.test.mjs +182 -0
- package/test/gtfs-route-loader.test.mjs +190 -0
- package/test/gtfs-routes.test.mjs +77 -0
- package/test/gtfs-shapes-loader.test.mjs +105 -0
- package/test/gtfs-shapes.test.mjs +23 -0
- package/test/gtfs-stop-loader-metro.test.mjs +49 -0
- package/test/gtfs-stop-loader.test.mjs +223 -0
- package/test/gtfs-stop-times.test.mjs +37 -0
- package/test/gtfs-stops.test.mjs +290 -0
- package/test/gtfs-trip-loader.test.mjs +142 -0
- package/test/gtfs-trips.test.mjs +109 -0
- package/test/line-reader.test.mjs +94 -0
- package/test/merge-stops.test.mjs +376 -0
- package/test/ptv-gtfs.test.mjs +106 -0
- package/test/sample-data/calendar/calendar.txt +34 -0
- package/test/sample-data/calendar/calendar_dates.txt +26 -0
- package/test/sample-data/gtfs-splitting/force_unique_stops_bus.txt +7 -0
- package/test/sample-data/gtfs-splitting/force_unique_stops_tram.txt +3 -0
- package/test/sample-data/gtfs-splitting/line_reader_test.txt +8 -0
- package/test/sample-data/gtfs-splitting/name_overrides.txt +4 -0
- package/test/sample-data/gtfs-splitting/nov_2024_train_data.txt +6 -0
- package/test/sample-data/gtfs-splitting/sample_stops.txt +20 -0
- package/test/sample-data/gtfs-splitting/special_chars_stops_csv.txt +6 -0
- package/test/sample-data/gtfs-splitting/stops_without_secondary.txt +6 -0
- package/test/sample-data/gtfs-unzipping/gtfs.zip +0 -0
- package/test/sample-data/one_line.csv +2 -0
- package/test/sample-data/routes/agency.txt +11 -0
- package/test/sample-data/routes/metro_bus_routes.txt +4 -0
- package/test/sample-data/routes/metro_lines.txt +5 -0
- package/test/sample-data/routes/regional_bus_routes.txt +7 -0
- package/test/sample-data/routes/vline.txt +7 -0
- package/test/sample-data/routes/west_gipp_transit.txt +20 -0
- package/test/sample-data/shapes/shapes.txt +89 -0
- package/test/sample-data/shapes/stop_times.txt +9 -0
- package/test/sample-data/shapes/stops.txt +4 -0
- package/test/sample-data/shapes/trips.txt +4 -0
- package/test/sample-data/stop-data/name-overrides.json +25 -0
- package/test/sample-data/stop-data/unique-stops.json +1 -0
- package/test/sample-data/suburbs.json +77 -0
- package/test/sample-data/trips/bus_trips.txt +5 -0
- package/test/sample-data/trips/stop_times.txt +29 -0
- package/test/sample-data/trips/stop_times_new.txt +8 -0
- package/test/sample-data/trips/stops.txt +8 -0
- package/test/sample-data/trips/trips.txt +5 -0
- package/test/sample-data/trips/trips_new.txt +2 -0
- package/test/set-stop-services.test.mjs +69 -0
- package/test/utils-test.mjs +26 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import url from 'url'
|
|
4
|
+
import { LokiDatabaseConnection } from '@transportme/database'
|
|
5
|
+
import StopsLoader from '../lib/loader/StopsLoader.mjs'
|
|
6
|
+
import RouteLoader from '../lib/loader/RouteLoader.mjs'
|
|
7
|
+
import TripLoader from '../lib/loader/TripLoader.mjs'
|
|
8
|
+
import ShapeLoader from '../lib/loader/ShapeLoader.mjs'
|
|
9
|
+
import { TRANSIT_MODES } from '../lib/constants.mjs'
|
|
10
|
+
import suburbs from './sample-data/suburbs.json' with { type: 'json' }
|
|
11
|
+
|
|
12
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
13
|
+
const __dirname = path.dirname(__filename)
|
|
14
|
+
|
|
15
|
+
const routesFile = path.join(__dirname, 'sample-data', 'routes', 'metro_bus_routes.txt')
|
|
16
|
+
const agencyFile = path.join(__dirname, 'sample-data', 'routes', 'agency.txt')
|
|
17
|
+
|
|
18
|
+
const calendarFile = path.join(__dirname, 'sample-data', 'calendar', 'calendar.txt')
|
|
19
|
+
const calendarDatesFile = path.join(__dirname, 'sample-data', 'calendar', 'calendar_dates.txt')
|
|
20
|
+
|
|
21
|
+
const stopsFile = path.join(__dirname, 'sample-data', 'shapes', 'stops.txt')
|
|
22
|
+
const stopTimesFile = path.join(__dirname, 'sample-data', 'shapes', 'stop_times.txt')
|
|
23
|
+
const tripsFile = path.join(__dirname, 'sample-data', 'shapes', 'trips.txt')
|
|
24
|
+
const shapeFile = path.join(__dirname, 'sample-data', 'shapes', 'shapes.txt')
|
|
25
|
+
|
|
26
|
+
describe('The ShapeLoader class', () => {
|
|
27
|
+
it('Should process the shapes and append it to the route data', async () => {
|
|
28
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
29
|
+
let stops = await database.createCollection('stops')
|
|
30
|
+
let routes = await database.createCollection('routes')
|
|
31
|
+
let trips = await database.createCollection('gtfs timetables')
|
|
32
|
+
|
|
33
|
+
let stopLoader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.metroBus, database)
|
|
34
|
+
await stopLoader.loadStops()
|
|
35
|
+
|
|
36
|
+
let routeLoader = new RouteLoader(routesFile, agencyFile, TRANSIT_MODES.metroBus, database)
|
|
37
|
+
await routeLoader.loadRoutes()
|
|
38
|
+
|
|
39
|
+
let routeIDMap = routeLoader.getRouteIDMap()
|
|
40
|
+
|
|
41
|
+
let tripLoader = new TripLoader({
|
|
42
|
+
tripsFile, stopTimesFile,
|
|
43
|
+
calendarFile, calendarDatesFile
|
|
44
|
+
}, TRANSIT_MODES.metroBus, database)
|
|
45
|
+
|
|
46
|
+
await tripLoader.loadTrips({ routeIDMap })
|
|
47
|
+
let shapeIDMap = tripLoader.getShapeIDMap()
|
|
48
|
+
|
|
49
|
+
let shapeLoader = new ShapeLoader(shapeFile, database)
|
|
50
|
+
|
|
51
|
+
await shapeLoader.loadShapes({ shapeIDMap })
|
|
52
|
+
|
|
53
|
+
let route = await routes.findDocument({ routeGTFSID: '4-601' })
|
|
54
|
+
|
|
55
|
+
expect(route).to.exist
|
|
56
|
+
expect(route.routePath.length).to.equal(2)
|
|
57
|
+
|
|
58
|
+
let monashHuntingdale = route.routePath.find(path => path.fullGTFSIDs.includes('49-601-aus-1.3.H'))
|
|
59
|
+
expect(monashHuntingdale).to.exist
|
|
60
|
+
expect(monashHuntingdale.length).to.equal(2848.26)
|
|
61
|
+
expect(monashHuntingdale.path.coordinates.length).to.equal(38)
|
|
62
|
+
|
|
63
|
+
expect(monashHuntingdale.path.coordinates[0]).to.deep.equal([ 145.132081, -37.913926 ])
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('Should merge duplicate shapes with the same length and start/end coordinates', async () => {
|
|
67
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
68
|
+
let stops = await database.createCollection('stops')
|
|
69
|
+
let routes = await database.createCollection('routes')
|
|
70
|
+
let trips = await database.createCollection('gtfs timetables')
|
|
71
|
+
|
|
72
|
+
let stopLoader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.metroBus, database)
|
|
73
|
+
await stopLoader.loadStops()
|
|
74
|
+
|
|
75
|
+
let routeLoader = new RouteLoader(routesFile, agencyFile, TRANSIT_MODES.metroBus, database)
|
|
76
|
+
await routeLoader.loadRoutes()
|
|
77
|
+
|
|
78
|
+
let routeIDMap = routeLoader.getRouteIDMap()
|
|
79
|
+
|
|
80
|
+
let tripLoader = new TripLoader({
|
|
81
|
+
tripsFile, stopTimesFile,
|
|
82
|
+
calendarFile, calendarDatesFile
|
|
83
|
+
}, TRANSIT_MODES.metroBus, database)
|
|
84
|
+
|
|
85
|
+
await tripLoader.loadTrips({ routeIDMap })
|
|
86
|
+
let shapeIDMap = tripLoader.getShapeIDMap()
|
|
87
|
+
|
|
88
|
+
let shapeLoader = new ShapeLoader(shapeFile, database)
|
|
89
|
+
|
|
90
|
+
await shapeLoader.loadShapes({ shapeIDMap })
|
|
91
|
+
|
|
92
|
+
let testTrip = await trips.findDocument({ tripID: '49-601--1-MF10-999' })
|
|
93
|
+
expect(testTrip.shapeID).to.equal('49-601-aus-1.4.H')
|
|
94
|
+
|
|
95
|
+
let route = await routes.findDocument({ routeGTFSID: testTrip.routeGTFSID })
|
|
96
|
+
expect(route.routeNumber).to.equal('601')
|
|
97
|
+
|
|
98
|
+
let tripShape = route.routePath.find(path => path.fullGTFSIDs.includes(testTrip.shapeID))
|
|
99
|
+
expect(tripShape).to.exist
|
|
100
|
+
expect(tripShape.fullGTFSIDs).to.have.members([
|
|
101
|
+
'49-601-aus-1.3.H',
|
|
102
|
+
'49-601-aus-1.4.H'
|
|
103
|
+
])
|
|
104
|
+
})
|
|
105
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import url from 'url'
|
|
4
|
+
import GTFSShapeReader from '../lib/gtfs-parser/readers/GTFSShapeReader.mjs'
|
|
5
|
+
|
|
6
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
7
|
+
const __dirname = path.dirname(__filename)
|
|
8
|
+
|
|
9
|
+
const shapeFile = path.join(__dirname, 'sample-data', 'shapes', 'shapes.txt')
|
|
10
|
+
|
|
11
|
+
describe('The GTFSShapeReader class', () => {
|
|
12
|
+
it('Should read the trips.txt file and return a GTFSTrip object', async () => {
|
|
13
|
+
let reader = new GTFSShapeReader(shapeFile)
|
|
14
|
+
await reader.open()
|
|
15
|
+
|
|
16
|
+
let shape = await reader.getNextEntity()
|
|
17
|
+
|
|
18
|
+
expect(shape.shapeID).to.equal('49-601-aus-1.2.R')
|
|
19
|
+
expect(shape.points.length).to.equal(46)
|
|
20
|
+
expect(shape.shapeLength).to.equal(3069.43)
|
|
21
|
+
expect(shape.hash).to.equal(`3069.43-145.102663,-37.910905-145.131911,-37.913896`)
|
|
22
|
+
})
|
|
23
|
+
})
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
|
|
9
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
10
|
+
const __dirname = path.dirname(__filename)
|
|
11
|
+
|
|
12
|
+
const stopsFile = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'nov_2024_train_data.txt')
|
|
13
|
+
|
|
14
|
+
describe('The GTFS Stops Loader (Testing on the projected Nov 2024 data)', () => {
|
|
15
|
+
it('Should process the stops and add them to the database', async () => {
|
|
16
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
17
|
+
let stops = await database.createCollection('stops')
|
|
18
|
+
|
|
19
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.metroTrain, database)
|
|
20
|
+
await loader.loadStops()
|
|
21
|
+
|
|
22
|
+
let stop = await stops.findDocument({
|
|
23
|
+
'stopName': 'Camberwell Railway Station'
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
expect(stop).to.not.be.null
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('Should label the individual platforms with their platform numbers', async () => {
|
|
30
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
31
|
+
let stops = await database.createCollection('stops')
|
|
32
|
+
|
|
33
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.metroTrain, database)
|
|
34
|
+
await loader.loadStops()
|
|
35
|
+
|
|
36
|
+
let stop = await stops.findDocument({
|
|
37
|
+
'stopName': 'Camberwell Railway Station'
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
let platformIDs = ["11207", "11208", "11209"]
|
|
41
|
+
let platforms = platformIDs.map(id => stop.bays.find(bay => bay.stopGTFSID === id))
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < platformIDs.length; i++) {
|
|
44
|
+
let platform = platforms[i]
|
|
45
|
+
expect(platform).to.not.be.undefined
|
|
46
|
+
expect(platforms[i].platform).to.equal((i + 1).toString())
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
})
|
|
@@ -0,0 +1,223 @@
|
|
|
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
|
+
|
|
9
|
+
import uniqueStops from './sample-data/stop-data/unique-stops.json' with { type: 'json' }
|
|
10
|
+
import nameOverrides from './sample-data/stop-data/name-overrides.json' with { type: 'json' }
|
|
11
|
+
import GTFSStopsReader from '../lib/gtfs-parser/readers/GTFSStopsReader.mjs'
|
|
12
|
+
|
|
13
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
14
|
+
const __dirname = path.dirname(__filename)
|
|
15
|
+
|
|
16
|
+
const stopsFile = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'sample_stops.txt')
|
|
17
|
+
|
|
18
|
+
const uniqueStopsBus = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'force_unique_stops_bus.txt')
|
|
19
|
+
const uniqueStopsTram = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'force_unique_stops_tram.txt')
|
|
20
|
+
|
|
21
|
+
const stopNameOverrides = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'name_overrides.txt')
|
|
22
|
+
|
|
23
|
+
const specialHeader = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'special_chars_stops_csv.txt')
|
|
24
|
+
|
|
25
|
+
describe('The GTFS Stops Loader', () => {
|
|
26
|
+
it('Should process the stops and add them to the database', async () => {
|
|
27
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
28
|
+
let stops = await database.createCollection('stops')
|
|
29
|
+
|
|
30
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database)
|
|
31
|
+
await loader.loadStops()
|
|
32
|
+
|
|
33
|
+
let stop = await stops.findDocument({
|
|
34
|
+
'bays.stopGTFSID': '10011'
|
|
35
|
+
})
|
|
36
|
+
expect(stop).to.not.be.null
|
|
37
|
+
expect(stop.stopName).to.equal('Moffat Street/Main Road West')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('Should merge street-level stops matching with the exact same name', async () => {
|
|
41
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
42
|
+
let stops = await database.createCollection('stops')
|
|
43
|
+
|
|
44
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database)
|
|
45
|
+
await loader.loadStops()
|
|
46
|
+
|
|
47
|
+
let wavWatson = await stops.findDocument({
|
|
48
|
+
'bays.stopGTFSID': '16074'
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
expect(wavWatson).to.not.be.null
|
|
52
|
+
expect(wavWatson.stopName).to.equal('Waverley Road/Watsons Road')
|
|
53
|
+
expect(wavWatson.bays.length).to.equal(2)
|
|
54
|
+
expect(wavWatson.suburb).to.deep.equal(['Glen Waverley'])
|
|
55
|
+
expect(wavWatson.cleanSuburbs).to.deep.equal(['glen-waverley'])
|
|
56
|
+
|
|
57
|
+
let wavWarrigal = await stops.findDocument({
|
|
58
|
+
'bays.stopGTFSID': '9379'
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
expect(wavWarrigal).to.not.be.null
|
|
62
|
+
expect(wavWarrigal.stopName).to.equal('Waverley Road/Warrigal Road')
|
|
63
|
+
expect(wavWarrigal.bays.length).to.equal(2)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('Should merge non street stops, and keep the secondary stop name if they are the same', async () => {
|
|
67
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
68
|
+
let stops = await database.createCollection('stops')
|
|
69
|
+
|
|
70
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database)
|
|
71
|
+
await loader.loadStops()
|
|
72
|
+
|
|
73
|
+
let stop = await stops.findDocument({
|
|
74
|
+
'bays.stopGTFSID': '19580'
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
expect(stop).to.not.be.null
|
|
78
|
+
expect(stop.bays.length).to.equal(3)
|
|
79
|
+
expect(stop.stopName).to.equal('Belgrave Railway Station/Belgrave-Gembrook Road')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('Should merge non street stops, and discard the secondary stop name if they are different', async () => {
|
|
83
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
84
|
+
let stops = await database.createCollection('stops')
|
|
85
|
+
|
|
86
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database)
|
|
87
|
+
await loader.loadStops()
|
|
88
|
+
|
|
89
|
+
let stop = await stops.findDocument({
|
|
90
|
+
'bays.stopGTFSID': '28191'
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
expect(stop).to.not.be.null
|
|
94
|
+
expect(stop.bays.length).to.equal(3)
|
|
95
|
+
expect(stop.stopName).to.equal('Lilydale Railway Station')
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('Should update the suburb list as well', async () => {
|
|
99
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
100
|
+
let stops = await database.createCollection('stops')
|
|
101
|
+
|
|
102
|
+
let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database)
|
|
103
|
+
await loader.loadStops()
|
|
104
|
+
|
|
105
|
+
let stop = await stops.findDocument({
|
|
106
|
+
'bays.stopGTFSID': '51586'
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
expect(stop).to.not.be.null
|
|
110
|
+
expect(stop.bays.length).to.equal(2)
|
|
111
|
+
expect(stop.stopName).to.equal('Huntingdale Railway Station')
|
|
112
|
+
expect(stop.suburb).to.deep.equal(['Huntingdale', 'Oakleigh'])
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('Should not merge stops that are forced to be unique and would otherwise be merged', async () => {
|
|
116
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
117
|
+
let stops = await database.createCollection('stops')
|
|
118
|
+
|
|
119
|
+
function getMergeName(stop) {
|
|
120
|
+
if (uniqueStops.includes(stop.fullStopName)) return stop.fullStopName
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
await (new StopsLoader(uniqueStopsBus, suburbs, TRANSIT_MODES.bus, database)).loadStops({ getMergeName })
|
|
124
|
+
await (new StopsLoader(uniqueStopsTram, suburbs, 'tram', database)).loadStops({ getMergeName })
|
|
125
|
+
|
|
126
|
+
let melbRoyal = await stops.findDocument({
|
|
127
|
+
'bays.stopGTFSID': '16830'
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
expect(melbRoyal).to.not.be.null
|
|
131
|
+
expect(melbRoyal.bays.length).to.equal(1)
|
|
132
|
+
expect(melbRoyal.stopName).to.equal('Melbourne University/Royal Parade')
|
|
133
|
+
|
|
134
|
+
let melbGrattan = await stops.findDocument({
|
|
135
|
+
'bays.stopGTFSID': '28670'
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
expect(melbGrattan).to.not.be.null
|
|
139
|
+
expect(melbGrattan.bays.length).to.equal(4)
|
|
140
|
+
expect(melbGrattan.stopName).to.equal('Melbourne University/Grattan Street')
|
|
141
|
+
|
|
142
|
+
let melbSwanston = await stops.findDocument({
|
|
143
|
+
'bays.stopGTFSID': '87'
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
expect(melbSwanston).to.not.be.null
|
|
147
|
+
expect(melbSwanston.bays.length).to.equal(3)
|
|
148
|
+
expect(melbSwanston.stopName).to.equal('Melbourne University/Swanston Street')
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('Should override stop names if required', async () => {
|
|
152
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
153
|
+
let stops = await database.createCollection('stops')
|
|
154
|
+
|
|
155
|
+
await (new StopsLoader(stopNameOverrides, suburbs, TRANSIT_MODES.bus, database)).loadStops({
|
|
156
|
+
processStop: stop => {
|
|
157
|
+
let updatedName = nameOverrides[stop.fullStopName]
|
|
158
|
+
if (updatedName) stop.fullStopName = updatedName
|
|
159
|
+
|
|
160
|
+
return stop
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
let ballarat = await stops.findDocument({
|
|
165
|
+
'bays.stopGTFSID': '49020'
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
expect(ballarat).to.not.be.null
|
|
169
|
+
expect(ballarat.bays.length).to.equal(3)
|
|
170
|
+
expect(ballarat.stopName).to.equal('Ballarat Railway Station')
|
|
171
|
+
expect(ballarat.bays[0].originalName).to.equal('Ballarat Bus Interchange (Soldiers Hill)')
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
it('Should handle CSV blank spaces and other unicode junk', async () => {
|
|
175
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
176
|
+
let stops = await database.createCollection('stops')
|
|
177
|
+
|
|
178
|
+
await (new StopsLoader(specialHeader, suburbs, TRANSIT_MODES.bus, database)).loadStops()
|
|
179
|
+
|
|
180
|
+
let gumRd = await stops.findDocument({
|
|
181
|
+
'bays.stopGTFSID': '10009'
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
expect(gumRd).to.not.be.null
|
|
185
|
+
expect(gumRd.stopName).to.equal('Gum Road/Main Road West')
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('Should allow for individual stops to be loaded in', async () => {
|
|
189
|
+
let database = new LokiDatabaseConnection('test-db')
|
|
190
|
+
let stops = await database.createCollection('stops')
|
|
191
|
+
|
|
192
|
+
let loader = new StopsLoader(specialHeader, suburbs, TRANSIT_MODES.bus, database)
|
|
193
|
+
let reader = new GTFSStopsReader('')
|
|
194
|
+
|
|
195
|
+
await loader.loadStop(reader.processEntity({
|
|
196
|
+
stop_id: '51586',
|
|
197
|
+
stop_name: 'Huntingdale Station/Haughton Road (Oakleigh)',
|
|
198
|
+
stop_lat: '-37.9111998619901',
|
|
199
|
+
stop_lon: '145.103064853799'
|
|
200
|
+
}))
|
|
201
|
+
|
|
202
|
+
let huntingdale = await stops.findDocument({
|
|
203
|
+
'bays.stopGTFSID': '51586'
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
expect(huntingdale).to.not.be.null
|
|
207
|
+
expect(huntingdale.stopName).to.equal('Huntingdale Railway Station/Haughton Road')
|
|
208
|
+
|
|
209
|
+
await loader.loadStop(reader.processEntity({
|
|
210
|
+
stop_id: '22440',
|
|
211
|
+
stop_name: 'Huntingdale Station/Huntingdale Road (Oakleigh)',
|
|
212
|
+
stop_lat: '-37.911010298723',
|
|
213
|
+
stop_lon: '145.103604328761'
|
|
214
|
+
}))
|
|
215
|
+
|
|
216
|
+
huntingdale = await stops.findDocument({
|
|
217
|
+
'bays.stopGTFSID': '22440'
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
expect(huntingdale).to.not.be.null
|
|
221
|
+
expect(huntingdale.stopName).to.equal('Huntingdale Railway Station')
|
|
222
|
+
})
|
|
223
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import url from 'url'
|
|
4
|
+
import GTFSStopTimesReader from '../lib/gtfs-parser/readers/GTFSStopTimesReader.mjs'
|
|
5
|
+
|
|
6
|
+
const __filename = url.fileURLToPath(import.meta.url)
|
|
7
|
+
const __dirname = path.dirname(__filename)
|
|
8
|
+
|
|
9
|
+
const stopTimesFile = path.join(__dirname, 'sample-data', 'trips', 'stop_times.txt')
|
|
10
|
+
|
|
11
|
+
describe('The GTFSStopTimesReader class', () => {
|
|
12
|
+
it('Should read the stop times one trips worth at a time', async () => {
|
|
13
|
+
let reader = new GTFSStopTimesReader(stopTimesFile)
|
|
14
|
+
|
|
15
|
+
await reader.open()
|
|
16
|
+
|
|
17
|
+
let stopTimes = await reader.getNextEntity()
|
|
18
|
+
expect(stopTimes.tripID).to.equal('1.T2.2-ALM-vpt-1.1.R')
|
|
19
|
+
expect(stopTimes.stops.length).to.equal(7)
|
|
20
|
+
expect(stopTimes.stops[0].stopID).to.equal('19847')
|
|
21
|
+
expect(stopTimes.stops[0].departureTime).to.equal('04:57')
|
|
22
|
+
|
|
23
|
+
expect(stopTimes.stops[6].stopID).to.equal('19853')
|
|
24
|
+
expect(stopTimes.stops[6].departureTime).to.equal('05:08')
|
|
25
|
+
|
|
26
|
+
await reader.getNextEntity()
|
|
27
|
+
await reader.getNextEntity()
|
|
28
|
+
|
|
29
|
+
let lastTrip = await reader.getNextEntity()
|
|
30
|
+
expect(lastTrip.tripID).to.equal('101.T2.2-ALM-vpt-1.2.H')
|
|
31
|
+
expect(lastTrip.stops.length).to.equal(7)
|
|
32
|
+
expect(lastTrip.stops[0].stopID).to.equal('19853')
|
|
33
|
+
expect(lastTrip.stops[0].departureTime).to.equal('23:31')
|
|
34
|
+
|
|
35
|
+
expect(reader.available()).to.be.false
|
|
36
|
+
})
|
|
37
|
+
})
|