gtfs 4.15.7 → 4.15.9
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/dist/bin/gtfs-export.js +41 -136
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +85 -156
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +2 -17
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.js +103 -169
- package/dist/index.js.map +1 -1
- package/dist/models/models.d.ts +5 -55
- package/dist/models/models.js +23 -108
- package/dist/models/models.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/gtfs-import.js
CHANGED
|
@@ -360,12 +360,7 @@ var bookingRules = {
|
|
|
360
360
|
},
|
|
361
361
|
{
|
|
362
362
|
name: "prior_notice_last_time",
|
|
363
|
-
type: "
|
|
364
|
-
},
|
|
365
|
-
{
|
|
366
|
-
name: "prior_notice_last_timestamp",
|
|
367
|
-
type: "integer",
|
|
368
|
-
index: true
|
|
363
|
+
type: "time"
|
|
369
364
|
},
|
|
370
365
|
{
|
|
371
366
|
name: "prior_notice_start_day",
|
|
@@ -374,12 +369,7 @@ var bookingRules = {
|
|
|
374
369
|
},
|
|
375
370
|
{
|
|
376
371
|
name: "prior_notice_start_time",
|
|
377
|
-
type: "
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
name: "prior_notice_start_timestamp",
|
|
381
|
-
type: "integer",
|
|
382
|
-
index: true
|
|
372
|
+
type: "time"
|
|
383
373
|
},
|
|
384
374
|
{
|
|
385
375
|
name: "prior_notice_service_id",
|
|
@@ -845,23 +835,15 @@ var frequencies = {
|
|
|
845
835
|
},
|
|
846
836
|
{
|
|
847
837
|
name: "start_time",
|
|
848
|
-
type: "
|
|
838
|
+
type: "time",
|
|
849
839
|
required: true,
|
|
850
840
|
primary: true
|
|
851
841
|
},
|
|
852
|
-
{
|
|
853
|
-
name: "start_timestamp",
|
|
854
|
-
type: "integer"
|
|
855
|
-
},
|
|
856
842
|
{
|
|
857
843
|
name: "end_time",
|
|
858
|
-
type: "
|
|
844
|
+
type: "time",
|
|
859
845
|
required: true
|
|
860
846
|
},
|
|
861
|
-
{
|
|
862
|
-
name: "end_timestamp",
|
|
863
|
-
type: "integer"
|
|
864
|
-
},
|
|
865
847
|
{
|
|
866
848
|
name: "headway_secs",
|
|
867
849
|
type: "integer",
|
|
@@ -1228,21 +1210,11 @@ var stopTimes = {
|
|
|
1228
1210
|
},
|
|
1229
1211
|
{
|
|
1230
1212
|
name: "arrival_time",
|
|
1231
|
-
type: "
|
|
1232
|
-
},
|
|
1233
|
-
{
|
|
1234
|
-
name: "arrival_timestamp",
|
|
1235
|
-
type: "integer",
|
|
1236
|
-
index: true
|
|
1213
|
+
type: "time"
|
|
1237
1214
|
},
|
|
1238
1215
|
{
|
|
1239
1216
|
name: "departure_time",
|
|
1240
|
-
type: "
|
|
1241
|
-
},
|
|
1242
|
-
{
|
|
1243
|
-
name: "departure_timestamp",
|
|
1244
|
-
type: "integer",
|
|
1245
|
-
index: true
|
|
1217
|
+
type: "time"
|
|
1246
1218
|
},
|
|
1247
1219
|
{
|
|
1248
1220
|
name: "location_group_id",
|
|
@@ -1277,12 +1249,7 @@ var stopTimes = {
|
|
|
1277
1249
|
},
|
|
1278
1250
|
{
|
|
1279
1251
|
name: "start_pickup_drop_off_window",
|
|
1280
|
-
type: "
|
|
1281
|
-
},
|
|
1282
|
-
{
|
|
1283
|
-
name: "start_pickup_drop_off_window_timestamp",
|
|
1284
|
-
type: "integer",
|
|
1285
|
-
index: true
|
|
1252
|
+
type: "time"
|
|
1286
1253
|
},
|
|
1287
1254
|
{
|
|
1288
1255
|
name: "pickup_type",
|
|
@@ -1432,12 +1399,12 @@ var timeframes = {
|
|
|
1432
1399
|
},
|
|
1433
1400
|
{
|
|
1434
1401
|
name: "start_time",
|
|
1435
|
-
type: "
|
|
1402
|
+
type: "time",
|
|
1436
1403
|
primary: true
|
|
1437
1404
|
},
|
|
1438
1405
|
{
|
|
1439
1406
|
name: "end_time",
|
|
1440
|
-
type: "
|
|
1407
|
+
type: "time",
|
|
1441
1408
|
primary: true
|
|
1442
1409
|
},
|
|
1443
1410
|
{
|
|
@@ -1710,19 +1677,11 @@ var timetables = {
|
|
|
1710
1677
|
},
|
|
1711
1678
|
{
|
|
1712
1679
|
name: "start_time",
|
|
1713
|
-
type: "
|
|
1714
|
-
},
|
|
1715
|
-
{
|
|
1716
|
-
name: "start_timestamp",
|
|
1717
|
-
type: "integer"
|
|
1680
|
+
type: "time"
|
|
1718
1681
|
},
|
|
1719
1682
|
{
|
|
1720
1683
|
name: "end_time",
|
|
1721
|
-
type: "
|
|
1722
|
-
},
|
|
1723
|
-
{
|
|
1724
|
-
name: "end_timestamp",
|
|
1725
|
-
type: "integer"
|
|
1684
|
+
type: "time"
|
|
1726
1685
|
},
|
|
1727
1686
|
{
|
|
1728
1687
|
name: "timetable_label",
|
|
@@ -2162,21 +2121,11 @@ var boardAlight = {
|
|
|
2162
2121
|
},
|
|
2163
2122
|
{
|
|
2164
2123
|
name: "service_arrival_time",
|
|
2165
|
-
type: "
|
|
2166
|
-
},
|
|
2167
|
-
{
|
|
2168
|
-
name: "service_arrival_timestamp",
|
|
2169
|
-
type: "integer",
|
|
2170
|
-
index: true
|
|
2124
|
+
type: "time"
|
|
2171
2125
|
},
|
|
2172
2126
|
{
|
|
2173
2127
|
name: "service_departure_time",
|
|
2174
|
-
type: "
|
|
2175
|
-
},
|
|
2176
|
-
{
|
|
2177
|
-
name: "service_departure_timestamp",
|
|
2178
|
-
type: "integer",
|
|
2179
|
-
index: true
|
|
2128
|
+
type: "time"
|
|
2180
2129
|
},
|
|
2181
2130
|
{
|
|
2182
2131
|
name: "source",
|
|
@@ -2243,21 +2192,11 @@ var riderTrip = {
|
|
|
2243
2192
|
},
|
|
2244
2193
|
{
|
|
2245
2194
|
name: "boarding_time",
|
|
2246
|
-
type: "
|
|
2247
|
-
},
|
|
2248
|
-
{
|
|
2249
|
-
name: "boarding_timestamp",
|
|
2250
|
-
type: "integer",
|
|
2251
|
-
index: true
|
|
2195
|
+
type: "time"
|
|
2252
2196
|
},
|
|
2253
2197
|
{
|
|
2254
2198
|
name: "alighting_time",
|
|
2255
|
-
type: "
|
|
2256
|
-
},
|
|
2257
|
-
{
|
|
2258
|
-
name: "alighting_timestamp",
|
|
2259
|
-
type: "integer",
|
|
2260
|
-
index: true
|
|
2199
|
+
type: "time"
|
|
2261
2200
|
},
|
|
2262
2201
|
{
|
|
2263
2202
|
name: "rider_type",
|
|
@@ -2331,21 +2270,11 @@ var ridership = {
|
|
|
2331
2270
|
},
|
|
2332
2271
|
{
|
|
2333
2272
|
name: "ridership_start_time",
|
|
2334
|
-
type: "
|
|
2335
|
-
},
|
|
2336
|
-
{
|
|
2337
|
-
name: "ridership_start_timestamp",
|
|
2338
|
-
type: "integer",
|
|
2339
|
-
index: true
|
|
2273
|
+
type: "time"
|
|
2340
2274
|
},
|
|
2341
2275
|
{
|
|
2342
2276
|
name: "ridership_end_time",
|
|
2343
|
-
type: "
|
|
2344
|
-
},
|
|
2345
|
-
{
|
|
2346
|
-
name: "ridership_end_timestamp",
|
|
2347
|
-
type: "integer",
|
|
2348
|
-
index: true
|
|
2277
|
+
type: "time"
|
|
2349
2278
|
},
|
|
2350
2279
|
{
|
|
2351
2280
|
name: "service_id",
|
|
@@ -2524,7 +2453,7 @@ var tripUpdates = {
|
|
|
2524
2453
|
extension: "gtfs-realtime",
|
|
2525
2454
|
schema: [
|
|
2526
2455
|
{
|
|
2527
|
-
name: "
|
|
2456
|
+
name: "id",
|
|
2528
2457
|
type: "text",
|
|
2529
2458
|
required: true,
|
|
2530
2459
|
primary: true,
|
|
@@ -2688,7 +2617,7 @@ var vehiclePositions = {
|
|
|
2688
2617
|
extension: "gtfs-realtime",
|
|
2689
2618
|
schema: [
|
|
2690
2619
|
{
|
|
2691
|
-
name: "
|
|
2620
|
+
name: "id",
|
|
2692
2621
|
type: "text",
|
|
2693
2622
|
required: true,
|
|
2694
2623
|
primary: true,
|
|
@@ -2927,39 +2856,24 @@ var deadheadTimes = {
|
|
|
2927
2856
|
nonstandard: true,
|
|
2928
2857
|
extension: "ods",
|
|
2929
2858
|
schema: [
|
|
2930
|
-
{
|
|
2931
|
-
name: "id",
|
|
2932
|
-
type: "integer",
|
|
2933
|
-
primary: true,
|
|
2934
|
-
prefix: true
|
|
2935
|
-
},
|
|
2936
2859
|
{
|
|
2937
2860
|
name: "deadhead_id",
|
|
2938
2861
|
type: "text",
|
|
2939
2862
|
required: true,
|
|
2940
2863
|
index: true,
|
|
2864
|
+
primary: true,
|
|
2941
2865
|
prefix: true
|
|
2942
2866
|
},
|
|
2943
2867
|
{
|
|
2944
2868
|
name: "arrival_time",
|
|
2945
|
-
type: "
|
|
2869
|
+
type: "time",
|
|
2946
2870
|
required: true
|
|
2947
2871
|
},
|
|
2948
|
-
{
|
|
2949
|
-
name: "arrival_timestamp",
|
|
2950
|
-
type: "integer",
|
|
2951
|
-
index: true
|
|
2952
|
-
},
|
|
2953
2872
|
{
|
|
2954
2873
|
name: "departure_time",
|
|
2955
|
-
type: "
|
|
2874
|
+
type: "time",
|
|
2956
2875
|
required: true
|
|
2957
2876
|
},
|
|
2958
|
-
{
|
|
2959
|
-
name: "departure_timestamp",
|
|
2960
|
-
type: "integer",
|
|
2961
|
-
index: true
|
|
2962
|
-
},
|
|
2963
2877
|
{
|
|
2964
2878
|
name: "ops_location_id",
|
|
2965
2879
|
type: "text",
|
|
@@ -2974,6 +2888,7 @@ var deadheadTimes = {
|
|
|
2974
2888
|
name: "location_sequence",
|
|
2975
2889
|
type: "integer",
|
|
2976
2890
|
required: true,
|
|
2891
|
+
primary: true,
|
|
2977
2892
|
min: 0,
|
|
2978
2893
|
index: true
|
|
2979
2894
|
},
|
|
@@ -3352,6 +3267,9 @@ function padLeadingZeros(time) {
|
|
|
3352
3267
|
}
|
|
3353
3268
|
return split.join(":");
|
|
3354
3269
|
}
|
|
3270
|
+
function getTimestampColumnName(columnName) {
|
|
3271
|
+
return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
|
|
3272
|
+
}
|
|
3355
3273
|
|
|
3356
3274
|
// src/lib/import-gtfs-realtime.ts
|
|
3357
3275
|
function getNestedProperty(obj, defaultValue, path3) {
|
|
@@ -3566,35 +3484,22 @@ async function updateGtfsRealtimeData(task) {
|
|
|
3566
3484
|
}
|
|
3567
3485
|
|
|
3568
3486
|
// src/lib/import-gtfs.ts
|
|
3569
|
-
var
|
|
3570
|
-
var
|
|
3571
|
-
const cached =
|
|
3572
|
-
if (cached
|
|
3487
|
+
var timeCache = {};
|
|
3488
|
+
var formatAndCacheTime = (value) => {
|
|
3489
|
+
const cached = timeCache[value];
|
|
3490
|
+
if (cached !== void 0) {
|
|
3573
3491
|
return cached;
|
|
3574
3492
|
}
|
|
3575
|
-
const
|
|
3576
|
-
const
|
|
3577
|
-
const computed = [
|
|
3578
|
-
|
|
3493
|
+
const timeAsSecondsFromMidnight = calculateSecondsFromMidnight(value);
|
|
3494
|
+
const timeAsString = padLeadingZeros(value);
|
|
3495
|
+
const computed = [timeAsSecondsFromMidnight, timeAsString];
|
|
3496
|
+
timeCache[value] = computed;
|
|
3579
3497
|
return computed;
|
|
3580
3498
|
};
|
|
3581
3499
|
var getTextFiles = async (folderPath) => {
|
|
3582
3500
|
const files = await readdir(folderPath);
|
|
3583
3501
|
return files.filter((filename) => filename.slice(-3) === "txt");
|
|
3584
3502
|
};
|
|
3585
|
-
var TIME_COLUMN_NAMES = [
|
|
3586
|
-
"start_time",
|
|
3587
|
-
"end_time",
|
|
3588
|
-
"arrival_time",
|
|
3589
|
-
"departure_time",
|
|
3590
|
-
"prior_notice_last_time",
|
|
3591
|
-
"prior_notice_start_time",
|
|
3592
|
-
"start_pickup_drop_off_window"
|
|
3593
|
-
];
|
|
3594
|
-
var TIME_COLUMN_PAIRS = TIME_COLUMN_NAMES.map((name) => [
|
|
3595
|
-
name,
|
|
3596
|
-
name.endsWith("time") ? `${name}stamp` : `${name}_timestamp`
|
|
3597
|
-
]);
|
|
3598
3503
|
var downloadGtfsFiles = async (task) => {
|
|
3599
3504
|
if (!task.url) {
|
|
3600
3505
|
throw new Error("No `url` specified in config");
|
|
@@ -3672,7 +3577,8 @@ var createGtfsTables = (db) => {
|
|
|
3672
3577
|
if (!model.schema) {
|
|
3673
3578
|
return;
|
|
3674
3579
|
}
|
|
3675
|
-
const
|
|
3580
|
+
const sqlColumnCreateStatements = [];
|
|
3581
|
+
for (const column of model.schema) {
|
|
3676
3582
|
const checks = [];
|
|
3677
3583
|
if (column.min !== void 0 && column.max) {
|
|
3678
3584
|
checks.push(
|
|
@@ -3687,8 +3593,7 @@ var createGtfsTables = (db) => {
|
|
|
3687
3593
|
checks.push(
|
|
3688
3594
|
`(TYPEOF(${column.name}) = 'integer' OR ${column.name} IS NULL)`
|
|
3689
3595
|
);
|
|
3690
|
-
}
|
|
3691
|
-
if (column.type === "real") {
|
|
3596
|
+
} else if (column.type === "real") {
|
|
3692
3597
|
checks.push(
|
|
3693
3598
|
`(TYPEOF(${column.name}) = 'real' OR ${column.name} IS NULL)`
|
|
3694
3599
|
);
|
|
@@ -3697,17 +3602,24 @@ var createGtfsTables = (db) => {
|
|
|
3697
3602
|
const columnDefault = column.default ? "DEFAULT " + column.default : "";
|
|
3698
3603
|
const columnCollation = column.nocase ? "COLLATE NOCASE" : "";
|
|
3699
3604
|
const checkClause = checks.length > 0 ? `CHECK(${checks.join(" AND ")})` : "";
|
|
3700
|
-
|
|
3701
|
-
|
|
3605
|
+
sqlColumnCreateStatements.push(
|
|
3606
|
+
`${column.name} ${column.type} ${checkClause} ${required} ${columnDefault} ${columnCollation}`
|
|
3607
|
+
);
|
|
3608
|
+
if (column.type === "time") {
|
|
3609
|
+
sqlColumnCreateStatements.push(
|
|
3610
|
+
`${getTimestampColumnName(column.name)} INTEGER`
|
|
3611
|
+
);
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3702
3614
|
const primaryColumns = model.schema.filter((column) => column.primary);
|
|
3703
3615
|
if (primaryColumns.length > 0) {
|
|
3704
|
-
|
|
3705
|
-
`PRIMARY KEY (${primaryColumns.map((
|
|
3616
|
+
sqlColumnCreateStatements.push(
|
|
3617
|
+
`PRIMARY KEY (${primaryColumns.map(({ name }) => name).join(", ")})`
|
|
3706
3618
|
);
|
|
3707
3619
|
}
|
|
3708
3620
|
db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
|
|
3709
3621
|
db.prepare(
|
|
3710
|
-
`CREATE TABLE ${model.filenameBase} (${
|
|
3622
|
+
`CREATE TABLE ${model.filenameBase} (${sqlColumnCreateStatements.join(", ")});`
|
|
3711
3623
|
).run();
|
|
3712
3624
|
}
|
|
3713
3625
|
};
|
|
@@ -3716,10 +3628,18 @@ var createGtfsIndexes = (db) => {
|
|
|
3716
3628
|
if (!model.schema) {
|
|
3717
3629
|
return;
|
|
3718
3630
|
}
|
|
3719
|
-
for (const column of model.schema
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3631
|
+
for (const column of model.schema) {
|
|
3632
|
+
if (column.index) {
|
|
3633
|
+
db.prepare(
|
|
3634
|
+
`CREATE INDEX idx_${model.filenameBase}_${column.name} ON ${model.filenameBase} (${column.name});`
|
|
3635
|
+
).run();
|
|
3636
|
+
}
|
|
3637
|
+
if (column.type === "time") {
|
|
3638
|
+
const timestampColumnName = getTimestampColumnName(column.name);
|
|
3639
|
+
db.prepare(
|
|
3640
|
+
`CREATE INDEX idx_${model.filenameBase}_${timestampColumnName} ON ${model.filenameBase} (${timestampColumnName});`
|
|
3641
|
+
).run();
|
|
3642
|
+
}
|
|
3723
3643
|
}
|
|
3724
3644
|
}
|
|
3725
3645
|
};
|
|
@@ -3728,11 +3648,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
3728
3648
|
const formattedLine = {};
|
|
3729
3649
|
const filenameBase = model.filenameBase;
|
|
3730
3650
|
const filenameExtension = model.filenameExtension;
|
|
3731
|
-
for (const
|
|
3732
|
-
const { name, type, required, min, max } = columnSchema;
|
|
3651
|
+
for (const { name, type, required } of model.schema) {
|
|
3733
3652
|
let value = line[name];
|
|
3734
3653
|
if (value === "" || value === void 0 || value === null) {
|
|
3735
3654
|
formattedLine[name] = null;
|
|
3655
|
+
if (type === "time") {
|
|
3656
|
+
formattedLine[getTimestampColumnName(name)] = null;
|
|
3657
|
+
}
|
|
3736
3658
|
if (required) {
|
|
3737
3659
|
throw new Error(
|
|
3738
3660
|
`Missing required value in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
|
|
@@ -3747,17 +3669,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
3747
3669
|
`Invalid date in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
|
|
3748
3670
|
);
|
|
3749
3671
|
}
|
|
3672
|
+
} else if (type === "time") {
|
|
3673
|
+
const [timeAsSecondsFromMidnight, timeAsString] = formatAndCacheTime(value);
|
|
3674
|
+
value = timeAsString;
|
|
3675
|
+
formattedLine[getTimestampColumnName(name)] = timeAsSecondsFromMidnight ?? null;
|
|
3750
3676
|
}
|
|
3751
3677
|
formattedLine[name] = value;
|
|
3752
3678
|
}
|
|
3753
|
-
for (const [timeColumnName, timestampColumnName] of TIME_COLUMN_PAIRS) {
|
|
3754
|
-
const value = formattedLine[timeColumnName];
|
|
3755
|
-
if (value) {
|
|
3756
|
-
const [seconds, date] = calculateAndCacheDate(value);
|
|
3757
|
-
formattedLine[timestampColumnName] = seconds;
|
|
3758
|
-
formattedLine[timeColumnName] = date;
|
|
3759
|
-
}
|
|
3760
|
-
}
|
|
3761
3679
|
return formattedLine;
|
|
3762
3680
|
};
|
|
3763
3681
|
var BATCH_SIZE = 1e5;
|
|
@@ -3784,12 +3702,23 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3784
3702
|
return;
|
|
3785
3703
|
}
|
|
3786
3704
|
task.log(`Importing - ${filename}\r`);
|
|
3787
|
-
const columns = model.schema.
|
|
3788
|
-
|
|
3705
|
+
const columns = model.schema.flatMap((column) => {
|
|
3706
|
+
if (column.type === "time") {
|
|
3707
|
+
return [
|
|
3708
|
+
column,
|
|
3709
|
+
{
|
|
3710
|
+
name: getTimestampColumnName(column.name),
|
|
3711
|
+
type: "integer",
|
|
3712
|
+
index: true
|
|
3713
|
+
}
|
|
3714
|
+
];
|
|
3715
|
+
}
|
|
3716
|
+
return column;
|
|
3717
|
+
});
|
|
3789
3718
|
const prefixedColumns = new Set(
|
|
3790
|
-
columns.filter((
|
|
3719
|
+
columns.filter((column) => column.prefix).map((column) => column.name)
|
|
3791
3720
|
);
|
|
3792
|
-
const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.map((
|
|
3721
|
+
const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.map(({ name }) => name).join(", ")}) VALUES (${columns.map(({ name }) => `@${name}`).join(", ")})`;
|
|
3793
3722
|
const insert = db.prepare(prepareStatement);
|
|
3794
3723
|
const insertLines = db.transaction((lines) => {
|
|
3795
3724
|
for (const [rowNumber, line] of Object.entries(lines)) {
|
|
@@ -3809,7 +3738,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3809
3738
|
}
|
|
3810
3739
|
} catch (error) {
|
|
3811
3740
|
if (error.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
|
|
3812
|
-
const primaryColumns =
|
|
3741
|
+
const primaryColumns = columns.filter(
|
|
3813
3742
|
(column) => column.primary
|
|
3814
3743
|
);
|
|
3815
3744
|
task.logWarning(
|