@transportme/load-ptv-gtfs 1.3.4 → 1.3.6

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.
@@ -27,7 +27,7 @@ export class GTFSStop {
27
27
  #isInterstate = false
28
28
  #suburbInFrontMatch
29
29
 
30
- constructor({ stopGTFSID, stopName, stopLat, stopLon, locationType, parentStopGTFSID }, suburbs) {
30
+ constructor({ stopGTFSID, stopName, stopLat, stopLon, locationType, parentStopGTFSID }, suburbs, suburbHook) {
31
31
  this.stopGTFSID = stopGTFSID
32
32
  this.originalName = stopName.replace(/ \(\w+\.\.\. #/, ' #').replace(/ +/g, ' ').trim()
33
33
 
@@ -39,7 +39,7 @@ export class GTFSStop {
39
39
  coordinates: [parseFloat(stopLon), parseFloat(stopLat)]
40
40
  }
41
41
 
42
- this.#setSuburb(suburbs)
42
+ this.#setSuburb(suburbs, suburbHook)
43
43
  this.#setStopNumber()
44
44
 
45
45
  this.fullStopName = this.getFullStopName()
@@ -105,8 +105,11 @@ export class GTFSStop {
105
105
  return this.#expandSuburb(this.originalName.slice(suburbIndex + 1, -1))
106
106
  }
107
107
 
108
- #setSuburb(suburbs) {
109
- if (this.requiresSuburb()) {
108
+ #setSuburb(suburbs, suburbHook) {
109
+ let output
110
+ if (suburbHook && (output = suburbHook(this))) {
111
+ this.suburb = output
112
+ } else if (this.requiresSuburb()) {
110
113
  this.suburb = this.getSuburbFromLocation(suburbs)
111
114
  } else {
112
115
  this.suburb = this.getSuburbFromName()
@@ -206,10 +209,10 @@ export class GTFSStop {
206
209
  return true
207
210
  }
208
211
 
209
- static create(data, suburbs) {
212
+ static create(data, suburbs, suburbHook) {
210
213
  let types = [ GTFSRRBStop, GTFSPlatformStop, GTFSStop ]
211
214
  for (let type of types) {
212
- if (type.canProcess(data)) return new type(data, suburbs)
215
+ if (type.canProcess(data)) return new type(data, suburbs, suburbHook)
213
216
  }
214
217
  }
215
218
  }
@@ -218,8 +221,8 @@ export class GTFSPlatformStop extends GTFSStop {
218
221
 
219
222
  platform
220
223
 
221
- constructor(data, suburbs) {
222
- super(data, suburbs)
224
+ constructor(data, suburbs, suburbHook) {
225
+ super(data, suburbs, suburbHook)
223
226
  this.platform = data.platform
224
227
  }
225
228
 
@@ -238,9 +241,9 @@ export class GTFSPlatformStop extends GTFSStop {
238
241
 
239
242
  export class GTFSRRBStop extends GTFSPlatformStop {
240
243
 
241
- constructor(data, suburbs) {
244
+ constructor(data, suburbs, suburbHook) {
242
245
  data.stopName = data.stopName.replace('Rail Replacement Bus Stop', 'Railway Station')
243
- super(data, suburbs)
246
+ super(data, suburbs, suburbHook)
244
247
  this.platform = 'RRB'
245
248
  }
246
249
 
@@ -4,10 +4,12 @@ import GTFSReader from './GTFSReader.mjs'
4
4
  export default class GTFSStopsReader extends GTFSReader {
5
5
 
6
6
  #suburbData
7
+ #suburbHook
7
8
 
8
- constructor(file, suburbData) {
9
+ constructor(file, suburbData, suburbHook) {
9
10
  super(file)
10
11
  this.#suburbData = suburbData
12
+ this.#suburbHook = suburbHook
11
13
  }
12
14
 
13
15
  /**
@@ -33,6 +35,6 @@ export default class GTFSStopsReader extends GTFSReader {
33
35
  parentStopGTFSID: data.parent_station
34
36
  }
35
37
 
36
- return GTFSStop.create(stopData, this.#suburbData)
38
+ return GTFSStop.create(stopData, this.#suburbData, this.#suburbHook)
37
39
  }
38
40
  }
@@ -19,11 +19,12 @@ export default class StopsLoader {
19
19
  * @param {FeatureCollection} suburbs A GeoJSON FeatureCollection containing a list of all suburbs located within Victoria
20
20
  * @param {string} mode The transit mode being loaded
21
21
  * @param {DatabaseConnection} database A database connection
22
+ * @param {function} [suburbHook] A hook that returns the stop's suburb, or null if unavailable. This function is called before processing from the stop's name or location
22
23
  */
23
- constructor(stopsFile, suburbs, mode, database) {
24
+ constructor(stopsFile, suburbs, mode, database, suburbHook) {
24
25
  this.#stops = database.getCollection('stops')
25
26
  this.#mode = mode
26
- this.#stopsReader = new GTFSStopsReader(stopsFile, suburbs)
27
+ this.#stopsReader = new GTFSStopsReader(stopsFile, suburbs, suburbHook)
27
28
  }
28
29
 
29
30
  getMergeName(stop) {
@@ -158,16 +159,19 @@ export default class StopsLoader {
158
159
  let stopData = this.generateDBStopData(processedData, mergeName)
159
160
  let matchingStop = await this.findMatchingStop(processedData, mergeName)
160
161
 
162
+ let finalStop
161
163
  if (matchingStop) {
162
164
  await this.mergeStops(matchingStop, stopData)
165
+ finalStop = matchingStop
163
166
  } else {
164
167
  await this.#stops.createDocument(stopData)
168
+ finalStop = stopData
165
169
  }
166
170
 
167
171
  if (this.#parentHolding[stop.stopGTFSID]) {
168
172
  for (let childStop of this.#parentHolding[stop.stopGTFSID]) {
169
- let childStopData = this.generateDBStopData(childStop, stopData.mergeName)
170
- await this.mergeStops(stopData, childStopData)
173
+ let childStopData = this.generateDBStopData(childStop, finalStop.mergeName)
174
+ await this.mergeStops(finalStop, childStopData)
171
175
  }
172
176
  delete this.#parentHolding[stop.stopGTFSID]
173
177
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transportme/load-ptv-gtfs",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "",
5
5
  "main": "index.mjs",
6
6
  "scripts": {
@@ -27,6 +27,7 @@ const specialHeader = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'spe
27
27
  const unionWithSpaces = path.join(__dirname, 'sample-data', 'gtfs-splitting', 'union_with_spaces.txt')
28
28
 
29
29
  const parentStopsFile = path.join(__dirname, 'sample-data', 'parent-stop', 'stops.txt')
30
+ const multiParentStopFile = path.join(__dirname, 'sample-data', 'parent-stop', 'multi_stop.txt')
30
31
 
31
32
  describe('The GTFS Stops Loader', () => {
32
33
  it('Should process the stops and add them to the database', async () => {
@@ -196,6 +197,22 @@ describe('The GTFS Stops Loader', () => {
196
197
  expect(gumRd.stopName).to.equal('Gum Road/Main Road West')
197
198
  })
198
199
 
200
+ it('Should allow for a custom suburb hook', async () => {
201
+ let database = new LokiDatabaseConnection('test-db')
202
+ let stops = await database.createCollection('stops')
203
+
204
+ let testSuburbs = ['A', 'B', 'C', null, 'D']
205
+
206
+ let loader = new StopsLoader(stopsFile, suburbs, TRANSIT_MODES.bus, database, () => testSuburbs.shift())
207
+ await loader.loadStops()
208
+
209
+ expect((await stops.findDocument({ 'bays.stopGTFSID': '1000' })).suburb[0]).to.equal('A')
210
+ expect((await stops.findDocument({ 'bays.stopGTFSID': '10001' })).suburb[0]).to.equal('B')
211
+ expect((await stops.findDocument({ 'bays.stopGTFSID': '10002' })).suburb[0]).to.equal('C')
212
+ expect((await stops.findDocument({ 'bays.stopGTFSID': '10009' })).suburb[0]).to.equal('Albanvale') // Null so not used
213
+ expect((await stops.findDocument({ 'bays.stopGTFSID': '1001' })).suburb[0]).to.equal('D')
214
+ })
215
+
199
216
  it('Should allow for individual stops to be loaded in', async () => {
200
217
  let database = new LokiDatabaseConnection('test-db')
201
218
  let stops = await database.createCollection('stops')
@@ -343,6 +360,23 @@ describe('The GTFS Stops Loader', () => {
343
360
  expect(stopData.cleanNames).to.deep.equal(['clifton-hill-railway-station', 'connex'])
344
361
  })
345
362
 
363
+ it('Should handle the parent being part of a merged stop', async () => {
364
+ let database = new LokiDatabaseConnection('test-db')
365
+ let stops = await database.createCollection('stops')
366
+
367
+ await (new StopsLoader(multiParentStopFile, suburbs, TRANSIT_MODES.regionalCoach, database)).loadStops()
368
+
369
+ expect(await stops.countDocuments({})).to.equal(1)
370
+ let stopData = await stops.findDocument({})
371
+ expect(stopData.bays.find(bay => bay.stopGTFSID === '17799').mode).to.equal('regional coach')
372
+ expect(stopData.bays.find(bay => bay.stopGTFSID === '17799').stopType).to.equal('stop')
373
+
374
+ expect(stopData.bays.find(bay => bay.stopGTFSID === 'vic:rail:ART').stopType).to.equal('station')
375
+ expect(stopData.bays.find(bay => bay.stopGTFSID === 'vic:rail:ART').parentStopGTFSID).to.be.null
376
+
377
+ expect(stopData.bays.find(bay => bay.stopGTFSID === '20288').parentStopGTFSID).to.equal('vic:rail:ART')
378
+ })
379
+
346
380
  it('Should use stop and station names and suburbs', async () => {
347
381
  let database = new LokiDatabaseConnection('test-db')
348
382
  let stops = await database.createCollection('stops')
@@ -64,6 +64,15 @@ describe('The GTFSStopReader class', () => {
64
64
  expect(stopData.stopGTFSID).to.equal('14330')
65
65
  expect(stopData.parentStopGTFSID).to.equal('vic:rail:CHL')
66
66
  })
67
+
68
+ it('Should allow a custom stop suburb hook', async () => {
69
+ let stopReader = new GTFSStopsReader(parentStopsFile, suburbs, () => 'Test')
70
+ await stopReader.open()
71
+
72
+ let stopData = await stopReader.getNextEntity()
73
+ expect(stopData.rawStopName).to.equal('Clifton Hill Station')
74
+ expect(stopData.suburb).to.equal('Test')
75
+ })
67
76
  })
68
77
 
69
78
  describe('The getNextEntity function', () => {
@@ -0,0 +1,4 @@
1
+ stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station,wheelchair_boarding,level_id
2
+ "17799","Ararat Railway Station/High St ","-37.28243901","142.93691236","","","0",""
3
+ "20288","Ararat Station","-37.28220485","142.93691370","","vic:rail:ART","1","Level 0"
4
+ "vic:rail:ART","Ararat Railway Station","-37.28224082","142.93691176","1","","1",""