gtfs 4.0.0 → 4.0.2
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/@types/index.d.ts +97 -79
- package/@types/tests.ts +1 -1
- package/CHANGELOG.md +18 -0
- package/README.md +13 -12
- package/config-sample-rtupdates.json +6 -18
- package/lib/db.js +6 -0
- package/lib/gtfs/stops.js +5 -2
- package/lib/import.js +83 -136
- package/package.json +6 -5
package/@types/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import CsvParse = require('csv-parse');
|
|
2
2
|
|
|
3
|
+
import Database = require('better-sqlite3');
|
|
4
|
+
|
|
3
5
|
import { FeatureCollection, Geometry } from '@turf/helpers';
|
|
4
6
|
|
|
5
7
|
export {}; // disable implicit exporting of types
|
|
@@ -19,7 +21,7 @@ export type SqlSelect = string[];
|
|
|
19
21
|
|
|
20
22
|
export type SqlOrderBy = Array<[string, 'ASC' | 'DESC']>;
|
|
21
23
|
|
|
22
|
-
export type JoinTables =
|
|
24
|
+
export type JoinTables = JoinOptions[];
|
|
23
25
|
|
|
24
26
|
export type SqlResults = Array<Record<string, any>>;
|
|
25
27
|
|
|
@@ -29,25 +31,26 @@ export type SqlTableName = string;
|
|
|
29
31
|
|
|
30
32
|
export type Config = ExportConfig & ImportConfig;
|
|
31
33
|
|
|
32
|
-
export
|
|
34
|
+
export interface AdvancedQueryOptions {
|
|
33
35
|
/**
|
|
34
|
-
*
|
|
36
|
+
* Queries the database with support for table joins and custom tables and returns an array of data.
|
|
35
37
|
*/
|
|
36
38
|
query?: SqlWhere;
|
|
37
39
|
fields?: SqlSelect;
|
|
38
40
|
orderBy?: SqlOrderBy;
|
|
39
|
-
join?:
|
|
41
|
+
join?: JoinOptions[];
|
|
40
42
|
options?: QueryOptions;
|
|
41
|
-
}
|
|
43
|
+
}
|
|
42
44
|
|
|
43
|
-
export
|
|
45
|
+
export interface JoinOptions {
|
|
44
46
|
/**
|
|
45
47
|
* Options for joining, type
|
|
46
48
|
*/
|
|
47
49
|
type?: 'LEFT OUTER' | 'INNER';
|
|
48
50
|
table: string;
|
|
49
51
|
on: string;
|
|
50
|
-
}
|
|
52
|
+
}
|
|
53
|
+
|
|
51
54
|
interface VerboseConfig {
|
|
52
55
|
/**
|
|
53
56
|
* Whether or not to print output to the console. Defaults to true.
|
|
@@ -57,7 +60,7 @@ interface VerboseConfig {
|
|
|
57
60
|
|
|
58
61
|
export interface DbConfig {
|
|
59
62
|
/**
|
|
60
|
-
* A path to
|
|
63
|
+
* A path to a SQLite database. Defaults to using an in-memory database.
|
|
61
64
|
*/
|
|
62
65
|
sqlitePath?: string;
|
|
63
66
|
}
|
|
@@ -71,7 +74,7 @@ export interface ExportConfig extends DbConfig, VerboseConfig {
|
|
|
71
74
|
|
|
72
75
|
export interface ImportConfig extends DbConfig, VerboseConfig {
|
|
73
76
|
/**
|
|
74
|
-
* An array of GTFS files to be imported.
|
|
77
|
+
* An array of agencies with GTFS files to be imported.
|
|
75
78
|
*/
|
|
76
79
|
agencies: Array<{
|
|
77
80
|
/**
|
|
@@ -114,11 +117,11 @@ export interface ImportConfig extends DbConfig, VerboseConfig {
|
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
export interface QueryOptions {
|
|
117
|
-
db?:
|
|
120
|
+
db?: Database.Database;
|
|
118
121
|
}
|
|
119
122
|
|
|
120
123
|
/**
|
|
121
|
-
* Use exportGtfs() in your code to run an export of a GTFS
|
|
124
|
+
* Use exportGtfs() in your code to run an export of a GTFS from SQLite specified in a config.json file.
|
|
122
125
|
*/
|
|
123
126
|
export function exportGtfs(config: ExportConfig): Promise<void>;
|
|
124
127
|
|
|
@@ -133,17 +136,17 @@ export function importGtfs(config: ImportConfig): Promise<void>;
|
|
|
133
136
|
export function updateGtfsRealtime(config: ImportConfig): Promise<void>;
|
|
134
137
|
|
|
135
138
|
/**
|
|
136
|
-
*
|
|
139
|
+
* Opens the database specified in the config object.
|
|
137
140
|
*/
|
|
138
|
-
export function openDb(config: DbConfig):
|
|
141
|
+
export function openDb(config: DbConfig): Database.Database;
|
|
139
142
|
|
|
140
143
|
/**
|
|
141
|
-
* Closes
|
|
144
|
+
* Closes the specified database.
|
|
142
145
|
*/
|
|
143
|
-
export function closeDb(db?:
|
|
146
|
+
export function closeDb(db?: Database.Database): void;
|
|
144
147
|
|
|
145
148
|
/**
|
|
146
|
-
*
|
|
149
|
+
* Returns an array of agencies that match query parameters.
|
|
147
150
|
*/
|
|
148
151
|
export function getAgencies(
|
|
149
152
|
query?: SqlWhere,
|
|
@@ -153,7 +156,17 @@ export function getAgencies(
|
|
|
153
156
|
): SqlResults;
|
|
154
157
|
|
|
155
158
|
/**
|
|
156
|
-
*
|
|
159
|
+
* Returns an array of areas that match query parameters.
|
|
160
|
+
*/
|
|
161
|
+
export function getAreas(
|
|
162
|
+
query?: SqlWhere,
|
|
163
|
+
fields?: SqlSelect,
|
|
164
|
+
sortBy?: SqlOrderBy,
|
|
165
|
+
options?: QueryOptions
|
|
166
|
+
): SqlResults;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Returns an array of attributions that match query parameters.
|
|
157
170
|
*/
|
|
158
171
|
export function getAttributions(
|
|
159
172
|
query?: SqlWhere,
|
|
@@ -163,7 +176,7 @@ export function getAttributions(
|
|
|
163
176
|
): SqlResults;
|
|
164
177
|
|
|
165
178
|
/**
|
|
166
|
-
*
|
|
179
|
+
* Returns an array of routes that match query parameters.
|
|
167
180
|
*/
|
|
168
181
|
export function getRoutes(
|
|
169
182
|
query?: SqlWhere,
|
|
@@ -173,7 +186,7 @@ export function getRoutes(
|
|
|
173
186
|
): SqlResults;
|
|
174
187
|
|
|
175
188
|
/**
|
|
176
|
-
*
|
|
189
|
+
* Returns an array of stops that match query parameters.
|
|
177
190
|
*/
|
|
178
191
|
export function getStops(
|
|
179
192
|
query?: SqlWhere,
|
|
@@ -183,7 +196,7 @@ export function getStops(
|
|
|
183
196
|
): SqlResults;
|
|
184
197
|
|
|
185
198
|
/**
|
|
186
|
-
*
|
|
199
|
+
* Returns geoJSON object of stops that match query parameters.
|
|
187
200
|
* All valid queries for `getStops()` work for `getStopsAsGeoJSON()`.
|
|
188
201
|
*/
|
|
189
202
|
export function getStopsAsGeoJSON(
|
|
@@ -192,7 +205,7 @@ export function getStopsAsGeoJSON(
|
|
|
192
205
|
): Promise<FeatureCollection<Geometry, { [name: string]: any }>>;
|
|
193
206
|
|
|
194
207
|
/**
|
|
195
|
-
*
|
|
208
|
+
* Returns an array of stop_times that match query parameters.
|
|
196
209
|
*/
|
|
197
210
|
export function getStoptimes(
|
|
198
211
|
query?: SqlWhere,
|
|
@@ -202,7 +215,7 @@ export function getStoptimes(
|
|
|
202
215
|
): SqlResults;
|
|
203
216
|
|
|
204
217
|
/**
|
|
205
|
-
*
|
|
218
|
+
* Returns an array of trips that match query parameters.
|
|
206
219
|
*/
|
|
207
220
|
export function getTrips(
|
|
208
221
|
query?: SqlWhere,
|
|
@@ -212,7 +225,7 @@ export function getTrips(
|
|
|
212
225
|
): SqlResults;
|
|
213
226
|
|
|
214
227
|
/**
|
|
215
|
-
*
|
|
228
|
+
* Returns an array of shapes that match query parameters.
|
|
216
229
|
*/
|
|
217
230
|
export function getShapes(
|
|
218
231
|
query?: SqlWhere,
|
|
@@ -222,16 +235,16 @@ export function getShapes(
|
|
|
222
235
|
): SqlResults;
|
|
223
236
|
|
|
224
237
|
/**
|
|
225
|
-
*
|
|
238
|
+
* Returns a geoJSON object of shapes that match query parameters.
|
|
226
239
|
* All valid queries for `getShapes()` work for `getShapesAsGeoJSON()`.
|
|
227
240
|
*/
|
|
228
241
|
export function getShapesAsGeoJSON(
|
|
229
242
|
query?: SqlWhere,
|
|
230
243
|
options?: QueryOptions
|
|
231
|
-
):
|
|
244
|
+
): FeatureCollection<Geometry, { [name: string]: any }>;
|
|
232
245
|
|
|
233
246
|
/**
|
|
234
|
-
*
|
|
247
|
+
* Returns an array of calendars that match query parameters.
|
|
235
248
|
*/
|
|
236
249
|
export function getCalendars(
|
|
237
250
|
query?: SqlWhere,
|
|
@@ -241,7 +254,7 @@ export function getCalendars(
|
|
|
241
254
|
): SqlResults;
|
|
242
255
|
|
|
243
256
|
/**
|
|
244
|
-
*
|
|
257
|
+
* Returns an array of calendar_dates that match query parameters.
|
|
245
258
|
*/
|
|
246
259
|
export function getCalendarDates(
|
|
247
260
|
query?: SqlWhere,
|
|
@@ -251,7 +264,7 @@ export function getCalendarDates(
|
|
|
251
264
|
): SqlResults;
|
|
252
265
|
|
|
253
266
|
/**
|
|
254
|
-
*
|
|
267
|
+
* Returns an array of fare_attributes that match query parameters.
|
|
255
268
|
*/
|
|
256
269
|
export function getFareAttributes(
|
|
257
270
|
query?: SqlWhere,
|
|
@@ -261,9 +274,9 @@ export function getFareAttributes(
|
|
|
261
274
|
): SqlResults;
|
|
262
275
|
|
|
263
276
|
/**
|
|
264
|
-
*
|
|
277
|
+
* Returns an array of fare_leg_rules that match query parameters.
|
|
265
278
|
*/
|
|
266
|
-
export function
|
|
279
|
+
export function getFareLegRules(
|
|
267
280
|
query?: SqlWhere,
|
|
268
281
|
fields?: SqlSelect,
|
|
269
282
|
sortBy?: SqlOrderBy,
|
|
@@ -271,9 +284,9 @@ export function getFareRules(
|
|
|
271
284
|
): SqlResults;
|
|
272
285
|
|
|
273
286
|
/**
|
|
274
|
-
*
|
|
287
|
+
* Returns an array of fare_products that match query parameters.
|
|
275
288
|
*/
|
|
276
|
-
export function
|
|
289
|
+
export function getFareProducts(
|
|
277
290
|
query?: SqlWhere,
|
|
278
291
|
fields?: SqlSelect,
|
|
279
292
|
sortBy?: SqlOrderBy,
|
|
@@ -281,9 +294,9 @@ export function getFeedInfo(
|
|
|
281
294
|
): SqlResults;
|
|
282
295
|
|
|
283
296
|
/**
|
|
284
|
-
*
|
|
297
|
+
* Returns an array of fare_rules that match query parameters.
|
|
285
298
|
*/
|
|
286
|
-
export function
|
|
299
|
+
export function getFareRules(
|
|
287
300
|
query?: SqlWhere,
|
|
288
301
|
fields?: SqlSelect,
|
|
289
302
|
sortBy?: SqlOrderBy,
|
|
@@ -291,9 +304,9 @@ export function getFrequencies(
|
|
|
291
304
|
): SqlResults;
|
|
292
305
|
|
|
293
306
|
/**
|
|
294
|
-
*
|
|
307
|
+
* Returns an array of fare_transfer_rules that match query parameters.
|
|
295
308
|
*/
|
|
296
|
-
export function
|
|
309
|
+
export function getFareTransferRules(
|
|
297
310
|
query?: SqlWhere,
|
|
298
311
|
fields?: SqlSelect,
|
|
299
312
|
sortBy?: SqlOrderBy,
|
|
@@ -301,9 +314,9 @@ export function getLevels(
|
|
|
301
314
|
): SqlResults;
|
|
302
315
|
|
|
303
316
|
/**
|
|
304
|
-
*
|
|
317
|
+
* Returns an array of feed_info that match query parameters.
|
|
305
318
|
*/
|
|
306
|
-
export function
|
|
319
|
+
export function getFeedInfo(
|
|
307
320
|
query?: SqlWhere,
|
|
308
321
|
fields?: SqlSelect,
|
|
309
322
|
sortBy?: SqlOrderBy,
|
|
@@ -311,9 +324,9 @@ export function getPathways(
|
|
|
311
324
|
): SqlResults;
|
|
312
325
|
|
|
313
326
|
/**
|
|
314
|
-
*
|
|
327
|
+
* Returns an array of frequencies that match query parameters.
|
|
315
328
|
*/
|
|
316
|
-
export function
|
|
329
|
+
export function getFrequencies(
|
|
317
330
|
query?: SqlWhere,
|
|
318
331
|
fields?: SqlSelect,
|
|
319
332
|
sortBy?: SqlOrderBy,
|
|
@@ -321,9 +334,9 @@ export function getTransfers(
|
|
|
321
334
|
): SqlResults;
|
|
322
335
|
|
|
323
336
|
/**
|
|
324
|
-
*
|
|
337
|
+
* Returns an array of levels that match query parameters.
|
|
325
338
|
*/
|
|
326
|
-
export function
|
|
339
|
+
export function getLevels(
|
|
327
340
|
query?: SqlWhere,
|
|
328
341
|
fields?: SqlSelect,
|
|
329
342
|
sortBy?: SqlOrderBy,
|
|
@@ -331,10 +344,9 @@ export function getTranslations(
|
|
|
331
344
|
): SqlResults;
|
|
332
345
|
|
|
333
346
|
/**
|
|
334
|
-
*
|
|
335
|
-
* These are from the non-standard `directions.txt` file.
|
|
347
|
+
* Returns an array of pathways that match query parameters.
|
|
336
348
|
*/
|
|
337
|
-
export function
|
|
349
|
+
export function getPathways(
|
|
338
350
|
query?: SqlWhere,
|
|
339
351
|
fields?: SqlSelect,
|
|
340
352
|
sortBy?: SqlOrderBy,
|
|
@@ -342,10 +354,9 @@ export function getDirections(
|
|
|
342
354
|
): SqlResults;
|
|
343
355
|
|
|
344
356
|
/**
|
|
345
|
-
*
|
|
346
|
-
* These are from the non-standard `stop_attributes.txt` file.
|
|
357
|
+
* Returns an array of transfers that match query parameters.
|
|
347
358
|
*/
|
|
348
|
-
export function
|
|
359
|
+
export function getTransfers(
|
|
349
360
|
query?: SqlWhere,
|
|
350
361
|
fields?: SqlSelect,
|
|
351
362
|
sortBy?: SqlOrderBy,
|
|
@@ -353,10 +364,9 @@ export function getStopAttributes(
|
|
|
353
364
|
): SqlResults;
|
|
354
365
|
|
|
355
366
|
/**
|
|
356
|
-
*
|
|
357
|
-
* These are from the non-standard `timetables.txt` file.
|
|
367
|
+
* Returns an array of translations that match query parameters.
|
|
358
368
|
*/
|
|
359
|
-
export function
|
|
369
|
+
export function getTranslations(
|
|
360
370
|
query?: SqlWhere,
|
|
361
371
|
fields?: SqlSelect,
|
|
362
372
|
sortBy?: SqlOrderBy,
|
|
@@ -364,10 +374,9 @@ export function getTimetables(
|
|
|
364
374
|
): SqlResults;
|
|
365
375
|
|
|
366
376
|
/**
|
|
367
|
-
*
|
|
368
|
-
* These are from the non-standard `timetable_stop_order.txt` file.
|
|
377
|
+
* Returns an array of stop_areas that match query parameters.
|
|
369
378
|
*/
|
|
370
|
-
export function
|
|
379
|
+
export function getStopAreas(
|
|
371
380
|
query?: SqlWhere,
|
|
372
381
|
fields?: SqlSelect,
|
|
373
382
|
sortBy?: SqlOrderBy,
|
|
@@ -375,10 +384,10 @@ export function getTimetableStopOrders(
|
|
|
375
384
|
): SqlResults;
|
|
376
385
|
|
|
377
386
|
/**
|
|
378
|
-
*
|
|
379
|
-
*
|
|
387
|
+
* Returns an array of directions that match query parameters.
|
|
388
|
+
* This is for the non-standard `directions.txt` file.
|
|
380
389
|
*/
|
|
381
|
-
export function
|
|
390
|
+
export function getDirections(
|
|
382
391
|
query?: SqlWhere,
|
|
383
392
|
fields?: SqlSelect,
|
|
384
393
|
sortBy?: SqlOrderBy,
|
|
@@ -386,10 +395,10 @@ export function getTimetablePages(
|
|
|
386
395
|
): SqlResults;
|
|
387
396
|
|
|
388
397
|
/**
|
|
389
|
-
*
|
|
390
|
-
*
|
|
398
|
+
* Returns an array of stop_attributes that match query parameters.
|
|
399
|
+
* This is for the non-standard `stop_attributes.txt` file.
|
|
391
400
|
*/
|
|
392
|
-
export function
|
|
401
|
+
export function getStopAttributes(
|
|
393
402
|
query?: SqlWhere,
|
|
394
403
|
fields?: SqlSelect,
|
|
395
404
|
sortBy?: SqlOrderBy,
|
|
@@ -397,10 +406,10 @@ export function getTimetableNotes(
|
|
|
397
406
|
): SqlResults;
|
|
398
407
|
|
|
399
408
|
/**
|
|
400
|
-
*
|
|
401
|
-
*
|
|
409
|
+
* Returns an array of timetables that match query parameters.
|
|
410
|
+
* This is for the non-standard `timetables.txt` file used in GTFS-to-HTML.
|
|
402
411
|
*/
|
|
403
|
-
export function
|
|
412
|
+
export function getTimetables(
|
|
404
413
|
query?: SqlWhere,
|
|
405
414
|
fields?: SqlSelect,
|
|
406
415
|
sortBy?: SqlOrderBy,
|
|
@@ -408,9 +417,10 @@ export function getTimetableNotesReferences(
|
|
|
408
417
|
): SqlResults;
|
|
409
418
|
|
|
410
419
|
/**
|
|
411
|
-
*
|
|
420
|
+
* Returns an array of timetable_stop_orders that match query parameters.
|
|
421
|
+
* This is for the non-standard `timetable_stop_order.txt` file used in GTFS-to-HTML.
|
|
412
422
|
*/
|
|
413
|
-
export function
|
|
423
|
+
export function getTimetableStopOrders(
|
|
414
424
|
query?: SqlWhere,
|
|
415
425
|
fields?: SqlSelect,
|
|
416
426
|
sortBy?: SqlOrderBy,
|
|
@@ -418,9 +428,10 @@ export function getBoardAlights(
|
|
|
418
428
|
): SqlResults;
|
|
419
429
|
|
|
420
430
|
/**
|
|
421
|
-
*
|
|
431
|
+
* Returns an array of timetable_pages that match query parameters.
|
|
432
|
+
* This is for the non-standard `timetable_pages.txt` file used in GTFS-to-HTML.
|
|
422
433
|
*/
|
|
423
|
-
export function
|
|
434
|
+
export function getTimetablePages(
|
|
424
435
|
query?: SqlWhere,
|
|
425
436
|
fields?: SqlSelect,
|
|
426
437
|
sortBy?: SqlOrderBy,
|
|
@@ -428,9 +439,10 @@ export function getRideFeedInfos(
|
|
|
428
439
|
): SqlResults;
|
|
429
440
|
|
|
430
441
|
/**
|
|
431
|
-
*
|
|
442
|
+
* Returns an array of timetable_notes that match query parameters.
|
|
443
|
+
* This is for the non-standard `timetable_notes.txt` file used in GTFS-to-HTML.
|
|
432
444
|
*/
|
|
433
|
-
export function
|
|
445
|
+
export function getTimetableNotes(
|
|
434
446
|
query?: SqlWhere,
|
|
435
447
|
fields?: SqlSelect,
|
|
436
448
|
sortBy?: SqlOrderBy,
|
|
@@ -438,9 +450,10 @@ export function getRiderTrips(
|
|
|
438
450
|
): SqlResults;
|
|
439
451
|
|
|
440
452
|
/**
|
|
441
|
-
*
|
|
453
|
+
* Returns an array of timetable_notes_references that match query parameters.
|
|
454
|
+
* This is for the non-standard `timetable_notes_references.txt` file used in GTFS-to-HTML.
|
|
442
455
|
*/
|
|
443
|
-
export function
|
|
456
|
+
export function getTimetableNotesReferences(
|
|
444
457
|
query?: SqlWhere,
|
|
445
458
|
fields?: SqlSelect,
|
|
446
459
|
sortBy?: SqlOrderBy,
|
|
@@ -448,9 +461,10 @@ export function getRiderships(
|
|
|
448
461
|
): SqlResults;
|
|
449
462
|
|
|
450
463
|
/**
|
|
451
|
-
*
|
|
464
|
+
* Returns an array of trips_dated_vehicle_journey that match query parameters.
|
|
465
|
+
* This is for the non-standard `trips_dated_vehicle_journey.txt` file.
|
|
452
466
|
*/
|
|
453
|
-
export function
|
|
467
|
+
export function getTripsDatedVehicleJourneys(
|
|
454
468
|
query?: SqlWhere,
|
|
455
469
|
fields?: SqlSelect,
|
|
456
470
|
sortBy?: SqlOrderBy,
|
|
@@ -458,7 +472,8 @@ export function getTripCapacities(
|
|
|
458
472
|
): SqlResults;
|
|
459
473
|
|
|
460
474
|
/**
|
|
461
|
-
*
|
|
475
|
+
* Returns an array of GTFS Realtime service alerts that match query parameters.
|
|
476
|
+
* This only works if you configure GTFS Realtime import in node-gtfs.
|
|
462
477
|
*/
|
|
463
478
|
export function getServiceAlerts(
|
|
464
479
|
query?: SqlWhere,
|
|
@@ -468,7 +483,8 @@ export function getServiceAlerts(
|
|
|
468
483
|
): SqlResults;
|
|
469
484
|
|
|
470
485
|
/**
|
|
471
|
-
*
|
|
486
|
+
* Returns an array of GTFS Realtime trip updates that match query parameters.
|
|
487
|
+
* This only works if you configure GTFS Realtime import in node-gtfs.
|
|
472
488
|
*/
|
|
473
489
|
export function getTripUpdates(
|
|
474
490
|
query?: SqlWhere,
|
|
@@ -478,9 +494,10 @@ export function getTripUpdates(
|
|
|
478
494
|
): SqlResults;
|
|
479
495
|
|
|
480
496
|
/**
|
|
481
|
-
*
|
|
497
|
+
* Returns an array of GTFS Realtime stop time updates that match query parameters.
|
|
498
|
+
* This only works if you configure GTFS Realtime import in node-gtfs.
|
|
482
499
|
*/
|
|
483
|
-
export function
|
|
500
|
+
export function getStopTimesUpdates(
|
|
484
501
|
query?: SqlWhere,
|
|
485
502
|
fields?: SqlSelect,
|
|
486
503
|
sortBy?: SqlOrderBy,
|
|
@@ -488,9 +505,10 @@ export function getVehiclePositions(
|
|
|
488
505
|
): SqlResults;
|
|
489
506
|
|
|
490
507
|
/**
|
|
491
|
-
*
|
|
508
|
+
* Returns an array of GTFS Realtime vehicle positions that match query parameters.
|
|
509
|
+
* This only works if you configure GTFS Realtime import in node-gtfs.
|
|
492
510
|
*/
|
|
493
|
-
export function
|
|
511
|
+
export function getVehiclePositions(
|
|
494
512
|
query?: SqlWhere,
|
|
495
513
|
fields?: SqlSelect,
|
|
496
514
|
sortBy?: SqlOrderBy,
|
package/@types/tests.ts
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.0.2] - 2023-01-15
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- In getStopsAsGeoJSON only return stops that are part of a route.
|
|
13
|
+
|
|
14
|
+
### Updated
|
|
15
|
+
|
|
16
|
+
- Dependency updates
|
|
17
|
+
|
|
18
|
+
## [4.0.1] - 2022-12-31
|
|
19
|
+
|
|
20
|
+
### Updated
|
|
21
|
+
|
|
22
|
+
- Update types info
|
|
23
|
+
- Improved readme
|
|
24
|
+
- Improved queries
|
|
25
|
+
|
|
8
26
|
## [4.0.0] - 2022-12-30
|
|
9
27
|
|
|
10
28
|
### Changed
|
package/README.md
CHANGED
|
@@ -688,7 +688,7 @@ const stops = getStops({
|
|
|
688
688
|
});
|
|
689
689
|
```
|
|
690
690
|
|
|
691
|
-
### getStopsAsGeoJSON(query)
|
|
691
|
+
### getStopsAsGeoJSON(query, options)
|
|
692
692
|
|
|
693
693
|
Returns geoJSON object of stops that match query parameters. All valid queries for `getStops()` work for `getStopsAsGeoJSON()`.
|
|
694
694
|
|
|
@@ -800,7 +800,7 @@ const shapes = getShapes({
|
|
|
800
800
|
});
|
|
801
801
|
```
|
|
802
802
|
|
|
803
|
-
### getShapesAsGeoJSON(query)
|
|
803
|
+
### getShapesAsGeoJSON(query, options)
|
|
804
804
|
|
|
805
805
|
Returns a geoJSON object of shapes that match query parameters. All valid queries for `getShapes()` work for `getShapesAsGeoJSON()`.
|
|
806
806
|
|
|
@@ -1237,23 +1237,24 @@ import { openDb } from 'gtfs';
|
|
|
1237
1237
|
const db = openDb(config);
|
|
1238
1238
|
|
|
1239
1239
|
// Get a specific trip
|
|
1240
|
-
const
|
|
1241
|
-
const trip = statement.get('123');
|
|
1240
|
+
const trip = db.prepare('SELECT * FROM trips WHERE trip_id = ?').get('123');
|
|
1242
1241
|
|
|
1243
1242
|
// Get all stops
|
|
1244
1243
|
const stops = db.prepare('SELECT * from stops').all();
|
|
1245
1244
|
|
|
1246
1245
|
// Get all calendar_ids for specific date
|
|
1247
|
-
const
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1246
|
+
const calendarIds = db
|
|
1247
|
+
.prepare(
|
|
1248
|
+
'SELECT service_id from calendar WHERE start_date <= $date AND end_date >= $date'
|
|
1249
|
+
)
|
|
1250
|
+
.all({ date: 20150101 });
|
|
1251
1251
|
|
|
1252
1252
|
// Find all stops for route_id=18 by joining tables
|
|
1253
|
-
const
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1253
|
+
const stopIds = db
|
|
1254
|
+
.prepare(
|
|
1255
|
+
'SELECT DISTINCT stops.stop_id from stops INNER JOIN stop_times ON stops.stop_id = stop_times.stop_id INNER JOIN trips on trips.trip_id = stop_times.trip_id WHERE trips.route_id = ?'
|
|
1256
|
+
)
|
|
1257
|
+
.all('18');
|
|
1257
1258
|
|
|
1258
1259
|
// Execute raw SQL
|
|
1259
1260
|
const sql = "DELETE FROM trips where trip_id = '329'";
|
|
@@ -1,28 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"agencies": [
|
|
3
3
|
{
|
|
4
|
-
"url": "
|
|
5
|
-
"exclude": ["shapes"],
|
|
4
|
+
"url": "https://marintransit.org/data/google_transit.zip",
|
|
6
5
|
"realtimeUrls": [
|
|
7
|
-
"https://
|
|
8
|
-
"https://
|
|
9
|
-
"https://
|
|
10
|
-
]
|
|
11
|
-
"realtimeHeaders": {
|
|
12
|
-
"X-CustomHeader": "MyCustomHeader"
|
|
13
|
-
},
|
|
14
|
-
"headers": {
|
|
15
|
-
"X-CustomHeader": "MyCustomHeader"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"path": "/path/to/gtfs.zip",
|
|
20
|
-
"exclude": ["stop_times", "shapes"]
|
|
6
|
+
"https://marintransit.net/gtfs-rt/alerts",
|
|
7
|
+
"https://marintransit.net/gtfs-rt/tripupdates",
|
|
8
|
+
"https://marintransit.net/gtfs-rt/vehiclepositions"
|
|
9
|
+
]
|
|
21
10
|
}
|
|
22
11
|
],
|
|
23
12
|
"csvOptions": {
|
|
24
13
|
"skip_lines_with_error": true
|
|
25
14
|
},
|
|
26
|
-
"sqlitePath": "/tmp/gtfs"
|
|
27
|
-
"exportPath": "~/path/to/export/gtfs"
|
|
15
|
+
"sqlitePath": "/tmp/gtfs"
|
|
28
16
|
}
|
package/lib/db.js
CHANGED
|
@@ -27,6 +27,12 @@ export function openDb(config) {
|
|
|
27
27
|
return dbs[filename];
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
if (Object.keys(dbs).length > 1) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
'Multiple databases open, please specify which one to use.'
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
throw new Error('Unable to find database connection.');
|
|
31
37
|
}
|
|
32
38
|
|
package/lib/gtfs/stops.js
CHANGED
|
@@ -87,7 +87,7 @@ export function getStopsAsGeoJSON(query = {}, options = {}) {
|
|
|
87
87
|
'SELECT DISTINCT route_id FROM trips WHERE trip_id IN (SELECT DISTINCT trip_id FROM stop_times WHERE stop_id = ?)';
|
|
88
88
|
const routes = db
|
|
89
89
|
.prepare(`SELECT * FROM routes WHERE route_id IN (${routeSubquery})`)
|
|
90
|
-
.
|
|
90
|
+
.all(stop.stop_id);
|
|
91
91
|
|
|
92
92
|
stop.routes = orderBy(routes, (route) =>
|
|
93
93
|
Number.parseInt(route.route_short_name, 10)
|
|
@@ -97,5 +97,8 @@ export function getStopsAsGeoJSON(query = {}, options = {}) {
|
|
|
97
97
|
return stop;
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
// Exclude stops not part of any route
|
|
101
|
+
const filteredStops = preparedStops.filter((stop) => stop.routes.length > 0);
|
|
102
|
+
|
|
103
|
+
return stopsToGeoJSON(filteredStops);
|
|
101
104
|
}
|
package/lib/import.js
CHANGED
|
@@ -82,76 +82,33 @@ function getDescendantProp(obj, desc, defaultvalue) {
|
|
|
82
82
|
return obj;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
const markRealtimeDataStale = (
|
|
86
|
-
const
|
|
87
|
-
(x) => x.filenameBase === 'vehicle_positions'
|
|
88
|
-
);
|
|
89
|
-
const tripUpdatesModel = models.find(
|
|
90
|
-
(x) => x.filenameBase === 'trip_updates'
|
|
91
|
-
);
|
|
92
|
-
const stopTimesUpdatesModel = models.find(
|
|
93
|
-
(x) => x.filenameBase === 'stop_times_updates'
|
|
94
|
-
);
|
|
95
|
-
const serviceAlertsModel = models.find(
|
|
96
|
-
(x) => x.filenameBase === 'service_alerts'
|
|
97
|
-
);
|
|
98
|
-
const serviceAlertTargetsModel = models.find(
|
|
99
|
-
(x) => x.filenameBase === 'service_alert_targets'
|
|
100
|
-
);
|
|
85
|
+
const markRealtimeDataStale = (config, log) => {
|
|
86
|
+
const db = openDb(config);
|
|
101
87
|
|
|
102
|
-
// Mark all data as stale
|
|
103
88
|
log(`Marking GTFS-Realtime data as stale..`);
|
|
104
|
-
db.prepare(
|
|
105
|
-
|
|
106
|
-
).run();
|
|
107
|
-
db.prepare(`UPDATE
|
|
108
|
-
db.prepare(
|
|
109
|
-
`UPDATE ${stopTimesUpdatesModel.filenameBase} SET isUpdated=0`
|
|
110
|
-
).run();
|
|
111
|
-
db.prepare(`UPDATE ${serviceAlertsModel.filenameBase} SET isUpdated=0`).run();
|
|
112
|
-
db.prepare(
|
|
113
|
-
`UPDATE ${serviceAlertTargetsModel.filenameBase} SET isUpdated=0`
|
|
114
|
-
).run();
|
|
89
|
+
db.prepare(`UPDATE vehicle_positions SET isUpdated=0`).run();
|
|
90
|
+
db.prepare(`UPDATE trip_updates SET isUpdated=0`).run();
|
|
91
|
+
db.prepare(`UPDATE stop_times_updates SET isUpdated=0`).run();
|
|
92
|
+
db.prepare(`UPDATE service_alerts SET isUpdated=0`).run();
|
|
93
|
+
db.prepare(`UPDATE service_alert_targets SET isUpdated=0`).run();
|
|
115
94
|
log(`Marked GTFS-Realtime data as stale\r`, true);
|
|
116
95
|
};
|
|
117
96
|
|
|
118
|
-
const cleanStaleRealtimeData = (
|
|
119
|
-
const
|
|
120
|
-
(x) => x.filenameBase === 'vehicle_positions'
|
|
121
|
-
);
|
|
122
|
-
const tripUpdatesModel = models.find(
|
|
123
|
-
(x) => x.filenameBase === 'trip_updates'
|
|
124
|
-
);
|
|
125
|
-
const stopTimesUpdatesModel = models.find(
|
|
126
|
-
(x) => x.filenameBase === 'stop_times_updates'
|
|
127
|
-
);
|
|
128
|
-
const serviceAlertsModel = models.find(
|
|
129
|
-
(x) => x.filenameBase === 'service_alerts'
|
|
130
|
-
);
|
|
131
|
-
const serviceAlertTargetsModel = models.find(
|
|
132
|
-
(x) => x.filenameBase === 'service_alert_targets'
|
|
133
|
-
);
|
|
97
|
+
const cleanStaleRealtimeData = (config, log) => {
|
|
98
|
+
const db = openDb(config);
|
|
134
99
|
|
|
135
100
|
log(`Cleaning stale GTFS-RT data..`);
|
|
136
|
-
db.prepare(
|
|
137
|
-
|
|
138
|
-
).run();
|
|
139
|
-
db.prepare(
|
|
140
|
-
|
|
141
|
-
).run();
|
|
142
|
-
db.prepare(
|
|
143
|
-
`DELETE FROM ${stopTimesUpdatesModel.filenameBase} WHERE isUpdated=0`
|
|
144
|
-
).run();
|
|
145
|
-
db.prepare(
|
|
146
|
-
`DELETE FROM ${serviceAlertsModel.filenameBase} WHERE isUpdated=0`
|
|
147
|
-
).run();
|
|
148
|
-
db.prepare(
|
|
149
|
-
`DELETE FROM ${serviceAlertTargetsModel.filenameBase} WHERE isUpdated=0`
|
|
150
|
-
).run();
|
|
101
|
+
db.prepare(`DELETE FROM vehicle_positions WHERE isUpdated=0`).run();
|
|
102
|
+
db.prepare(`DELETE FROM trip_updates WHERE isUpdated=0`).run();
|
|
103
|
+
db.prepare(`DELETE FROM stop_times_updates WHERE isUpdated=0`).run();
|
|
104
|
+
db.prepare(`DELETE FROM service_alerts WHERE isUpdated=0`).run();
|
|
105
|
+
db.prepare(`DELETE FROM service_alert_targets WHERE isUpdated=0`).run();
|
|
151
106
|
log(`Cleaned stale GTFS-Realtime data\r`, true);
|
|
152
107
|
};
|
|
153
108
|
|
|
154
109
|
const updateRealtimeData = async (task) => {
|
|
110
|
+
const db = openDb(task);
|
|
111
|
+
|
|
155
112
|
const model = {
|
|
156
113
|
vehicle_positions: models.find(
|
|
157
114
|
(x) => x.filenameBase === 'vehicle_positions'
|
|
@@ -225,13 +182,11 @@ const updateRealtimeData = async (task) => {
|
|
|
225
182
|
);
|
|
226
183
|
|
|
227
184
|
try {
|
|
228
|
-
|
|
229
|
-
.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
)
|
|
234
|
-
.run();
|
|
185
|
+
db.prepare(
|
|
186
|
+
`REPLACE INTO ${model[gtfsRealtimeType].filenameBase} (${
|
|
187
|
+
fields[gtfsRealtimeType]
|
|
188
|
+
}) VALUES (${fieldValues.join(', ')})`
|
|
189
|
+
).run();
|
|
235
190
|
} catch (error) {
|
|
236
191
|
task.warn('Import error: ' + error.message);
|
|
237
192
|
}
|
|
@@ -251,13 +206,11 @@ const updateRealtimeData = async (task) => {
|
|
|
251
206
|
}
|
|
252
207
|
|
|
253
208
|
try {
|
|
254
|
-
|
|
255
|
-
.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
)
|
|
260
|
-
.run();
|
|
209
|
+
db.prepare(
|
|
210
|
+
`REPLACE INTO ${model.stop_times_updates.filenameBase} (${
|
|
211
|
+
fields.stop_times_updates
|
|
212
|
+
}) VALUES ${stopUpdateArray.join(', ')}`
|
|
213
|
+
).run();
|
|
261
214
|
} catch (error) {
|
|
262
215
|
task.warn('Import error: ' + error.message);
|
|
263
216
|
}
|
|
@@ -278,13 +231,11 @@ const updateRealtimeData = async (task) => {
|
|
|
278
231
|
}
|
|
279
232
|
|
|
280
233
|
try {
|
|
281
|
-
|
|
282
|
-
.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
)
|
|
287
|
-
.run();
|
|
234
|
+
db.prepare(
|
|
235
|
+
`REPLACE INTO ${model.service_alert_targets.filenameBase} (${
|
|
236
|
+
fields.service_alert_targets
|
|
237
|
+
}) VALUES ${alertTargetArray.join(', ')}`
|
|
238
|
+
).run();
|
|
288
239
|
} catch (error) {
|
|
289
240
|
task.warn('Import error: ' + error.message);
|
|
290
241
|
}
|
|
@@ -478,6 +429,8 @@ const formatLine = (line, model, totalLineCount) => {
|
|
|
478
429
|
};
|
|
479
430
|
|
|
480
431
|
const importLines = (task, lines, model, totalLineCount) => {
|
|
432
|
+
const db = openDb(task);
|
|
433
|
+
|
|
481
434
|
if (lines.length === 0) {
|
|
482
435
|
return;
|
|
483
436
|
}
|
|
@@ -496,12 +449,11 @@ const importLines = (task, lines, model, totalLineCount) => {
|
|
|
496
449
|
}
|
|
497
450
|
|
|
498
451
|
try {
|
|
499
|
-
|
|
452
|
+
db.prepare(
|
|
500
453
|
`INSERT ${task.ignoreDuplicates ? 'OR IGNORE' : ''} INTO ${
|
|
501
454
|
model.filenameBase
|
|
502
455
|
} (${fieldNames.join(', ')}) VALUES ${placeholders.join(',')}`
|
|
503
|
-
);
|
|
504
|
-
insert.run(...values);
|
|
456
|
+
).run(...values);
|
|
505
457
|
} catch (error) {
|
|
506
458
|
task.warn(
|
|
507
459
|
`Check ${model.filenameBase}.txt for invalid data between lines ${
|
|
@@ -625,16 +577,10 @@ export async function importGtfs(initialConfig) {
|
|
|
625
577
|
path: agency.path,
|
|
626
578
|
csvOptions: config.csvOptions || {},
|
|
627
579
|
ignoreDuplicates: config.ignoreDuplicates,
|
|
628
|
-
|
|
629
|
-
log
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
warn(message) {
|
|
633
|
-
logWarning(message);
|
|
634
|
-
},
|
|
635
|
-
error(message) {
|
|
636
|
-
logError(message);
|
|
637
|
-
},
|
|
580
|
+
sqlitePath: config.sqlitePath,
|
|
581
|
+
log,
|
|
582
|
+
warn: logWarning,
|
|
583
|
+
error: logError,
|
|
638
584
|
};
|
|
639
585
|
|
|
640
586
|
if (task.agency_url) {
|
|
@@ -671,7 +617,49 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
671
617
|
const log = _log(config);
|
|
672
618
|
const logError = _logError(config);
|
|
673
619
|
const logWarning = _logWarning(config);
|
|
674
|
-
|
|
620
|
+
|
|
621
|
+
try {
|
|
622
|
+
openDb(config);
|
|
623
|
+
|
|
624
|
+
const agencyCount = config.agencies.length;
|
|
625
|
+
log(
|
|
626
|
+
`Starting GTFS-Realtime refresh for ${pluralize(
|
|
627
|
+
'agencies',
|
|
628
|
+
agencyCount,
|
|
629
|
+
true
|
|
630
|
+
)} using SQLite database at ${config.sqlitePath}`
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
markRealtimeDataStale(config, log);
|
|
634
|
+
|
|
635
|
+
await Promise.all(
|
|
636
|
+
config.agencies.map(async (agency) => {
|
|
637
|
+
if (!agency.realtimeUrls) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const task = {
|
|
642
|
+
realtime_headers: agency.realtimeHeaders || false,
|
|
643
|
+
realtime_urls: agency.realtimeUrls || false,
|
|
644
|
+
sqlitePath: config.sqlitePath,
|
|
645
|
+
log,
|
|
646
|
+
warn: logWarning,
|
|
647
|
+
error: logError,
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
await updateRealtimeData(task);
|
|
651
|
+
})
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
cleanStaleRealtimeData(config, log);
|
|
655
|
+
log(
|
|
656
|
+
`Completed GTFS-Realtime refresh for ${pluralize(
|
|
657
|
+
'agencies',
|
|
658
|
+
agencyCount,
|
|
659
|
+
true
|
|
660
|
+
)}\n`
|
|
661
|
+
);
|
|
662
|
+
} catch (error) {
|
|
675
663
|
if (error instanceof Error && error.code === 'SQLITE_CANTOPEN') {
|
|
676
664
|
logError(
|
|
677
665
|
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`
|
|
@@ -679,46 +667,5 @@ export async function updateGtfsRealtime(initialConfig) {
|
|
|
679
667
|
}
|
|
680
668
|
|
|
681
669
|
throw error;
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
const agencyCount = config.agencies.length;
|
|
685
|
-
log(
|
|
686
|
-
`Starting GTFS-Realtime refresh for ${pluralize(
|
|
687
|
-
'agencies',
|
|
688
|
-
agencyCount,
|
|
689
|
-
true
|
|
690
|
-
)} using SQLite database at ${config.sqlitePath}`
|
|
691
|
-
);
|
|
692
|
-
|
|
693
|
-
await markRealtimeDataStale(db, log);
|
|
694
|
-
|
|
695
|
-
await mapSeries(config.agencies, async (agency) => {
|
|
696
|
-
const task = {
|
|
697
|
-
realtime_headers: agency.realtimeHeaders || false,
|
|
698
|
-
realtime_urls: agency.realtimeUrls || false,
|
|
699
|
-
db,
|
|
700
|
-
log(message, overwrite) {
|
|
701
|
-
log(message, overwrite);
|
|
702
|
-
},
|
|
703
|
-
warn(message) {
|
|
704
|
-
logWarning(message);
|
|
705
|
-
},
|
|
706
|
-
error(message) {
|
|
707
|
-
logError(message);
|
|
708
|
-
},
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
if (task.realtime_urls) {
|
|
712
|
-
await updateRealtimeData(task);
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
await cleanStaleRealtimeData(db, log);
|
|
717
|
-
log(
|
|
718
|
-
`Completed GTFS-Realtime refresh for ${pluralize(
|
|
719
|
-
'agencies',
|
|
720
|
-
agencyCount,
|
|
721
|
-
true
|
|
722
|
-
)}\n`
|
|
723
|
-
);
|
|
670
|
+
}
|
|
724
671
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Import GTFS transit data into SQLite and query routes, stops, times, fares and more",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"transit",
|
|
@@ -95,13 +95,14 @@
|
|
|
95
95
|
"yoctocolors": "^1.0.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
+
"@types/better-sqlite3": "^7.6.3",
|
|
98
99
|
"dtslint": "^4.2.1",
|
|
99
|
-
"eslint": "^8.
|
|
100
|
-
"eslint-config-prettier": "^8.
|
|
100
|
+
"eslint": "^8.32.0",
|
|
101
|
+
"eslint-config-prettier": "^8.6.0",
|
|
101
102
|
"eslint-config-xo": "^0.43.1",
|
|
102
|
-
"husky": "^8.0.
|
|
103
|
+
"husky": "^8.0.3",
|
|
103
104
|
"mocha": "^10.2.0",
|
|
104
|
-
"prettier": "^2.8.
|
|
105
|
+
"prettier": "^2.8.3",
|
|
105
106
|
"pretty-quick": "^3.1.3",
|
|
106
107
|
"should": "^13.2.3"
|
|
107
108
|
},
|