gtfs 4.15.8 → 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 +21 -128
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +81 -147
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +0 -15
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.js +83 -160
- package/dist/index.js.map +1 -1
- package/dist/models/models.d.ts +0 -42
- package/dist/models/models.js +19 -100
- 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",
|
|
@@ -2937,24 +2866,14 @@ var deadheadTimes = {
|
|
|
2937
2866
|
},
|
|
2938
2867
|
{
|
|
2939
2868
|
name: "arrival_time",
|
|
2940
|
-
type: "
|
|
2869
|
+
type: "time",
|
|
2941
2870
|
required: true
|
|
2942
2871
|
},
|
|
2943
|
-
{
|
|
2944
|
-
name: "arrival_timestamp",
|
|
2945
|
-
type: "integer",
|
|
2946
|
-
index: true
|
|
2947
|
-
},
|
|
2948
2872
|
{
|
|
2949
2873
|
name: "departure_time",
|
|
2950
|
-
type: "
|
|
2874
|
+
type: "time",
|
|
2951
2875
|
required: true
|
|
2952
2876
|
},
|
|
2953
|
-
{
|
|
2954
|
-
name: "departure_timestamp",
|
|
2955
|
-
type: "integer",
|
|
2956
|
-
index: true
|
|
2957
|
-
},
|
|
2958
2877
|
{
|
|
2959
2878
|
name: "ops_location_id",
|
|
2960
2879
|
type: "text",
|
|
@@ -3348,6 +3267,9 @@ function padLeadingZeros(time) {
|
|
|
3348
3267
|
}
|
|
3349
3268
|
return split.join(":");
|
|
3350
3269
|
}
|
|
3270
|
+
function getTimestampColumnName(columnName) {
|
|
3271
|
+
return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
|
|
3272
|
+
}
|
|
3351
3273
|
|
|
3352
3274
|
// src/lib/import-gtfs-realtime.ts
|
|
3353
3275
|
function getNestedProperty(obj, defaultValue, path3) {
|
|
@@ -3562,35 +3484,22 @@ async function updateGtfsRealtimeData(task) {
|
|
|
3562
3484
|
}
|
|
3563
3485
|
|
|
3564
3486
|
// src/lib/import-gtfs.ts
|
|
3565
|
-
var
|
|
3566
|
-
var
|
|
3567
|
-
const cached =
|
|
3568
|
-
if (cached
|
|
3487
|
+
var timeCache = {};
|
|
3488
|
+
var formatAndCacheTime = (value) => {
|
|
3489
|
+
const cached = timeCache[value];
|
|
3490
|
+
if (cached !== void 0) {
|
|
3569
3491
|
return cached;
|
|
3570
3492
|
}
|
|
3571
|
-
const
|
|
3572
|
-
const
|
|
3573
|
-
const computed = [
|
|
3574
|
-
|
|
3493
|
+
const timeAsSecondsFromMidnight = calculateSecondsFromMidnight(value);
|
|
3494
|
+
const timeAsString = padLeadingZeros(value);
|
|
3495
|
+
const computed = [timeAsSecondsFromMidnight, timeAsString];
|
|
3496
|
+
timeCache[value] = computed;
|
|
3575
3497
|
return computed;
|
|
3576
3498
|
};
|
|
3577
3499
|
var getTextFiles = async (folderPath) => {
|
|
3578
3500
|
const files = await readdir(folderPath);
|
|
3579
3501
|
return files.filter((filename) => filename.slice(-3) === "txt");
|
|
3580
3502
|
};
|
|
3581
|
-
var TIME_COLUMN_NAMES = [
|
|
3582
|
-
"start_time",
|
|
3583
|
-
"end_time",
|
|
3584
|
-
"arrival_time",
|
|
3585
|
-
"departure_time",
|
|
3586
|
-
"prior_notice_last_time",
|
|
3587
|
-
"prior_notice_start_time",
|
|
3588
|
-
"start_pickup_drop_off_window"
|
|
3589
|
-
];
|
|
3590
|
-
var TIME_COLUMN_PAIRS = TIME_COLUMN_NAMES.map((name) => [
|
|
3591
|
-
name,
|
|
3592
|
-
name.endsWith("time") ? `${name}stamp` : `${name}_timestamp`
|
|
3593
|
-
]);
|
|
3594
3503
|
var downloadGtfsFiles = async (task) => {
|
|
3595
3504
|
if (!task.url) {
|
|
3596
3505
|
throw new Error("No `url` specified in config");
|
|
@@ -3668,7 +3577,8 @@ var createGtfsTables = (db) => {
|
|
|
3668
3577
|
if (!model.schema) {
|
|
3669
3578
|
return;
|
|
3670
3579
|
}
|
|
3671
|
-
const
|
|
3580
|
+
const sqlColumnCreateStatements = [];
|
|
3581
|
+
for (const column of model.schema) {
|
|
3672
3582
|
const checks = [];
|
|
3673
3583
|
if (column.min !== void 0 && column.max) {
|
|
3674
3584
|
checks.push(
|
|
@@ -3683,8 +3593,7 @@ var createGtfsTables = (db) => {
|
|
|
3683
3593
|
checks.push(
|
|
3684
3594
|
`(TYPEOF(${column.name}) = 'integer' OR ${column.name} IS NULL)`
|
|
3685
3595
|
);
|
|
3686
|
-
}
|
|
3687
|
-
if (column.type === "real") {
|
|
3596
|
+
} else if (column.type === "real") {
|
|
3688
3597
|
checks.push(
|
|
3689
3598
|
`(TYPEOF(${column.name}) = 'real' OR ${column.name} IS NULL)`
|
|
3690
3599
|
);
|
|
@@ -3693,17 +3602,24 @@ var createGtfsTables = (db) => {
|
|
|
3693
3602
|
const columnDefault = column.default ? "DEFAULT " + column.default : "";
|
|
3694
3603
|
const columnCollation = column.nocase ? "COLLATE NOCASE" : "";
|
|
3695
3604
|
const checkClause = checks.length > 0 ? `CHECK(${checks.join(" AND ")})` : "";
|
|
3696
|
-
|
|
3697
|
-
|
|
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
|
+
}
|
|
3698
3614
|
const primaryColumns = model.schema.filter((column) => column.primary);
|
|
3699
3615
|
if (primaryColumns.length > 0) {
|
|
3700
|
-
|
|
3701
|
-
`PRIMARY KEY (${primaryColumns.map((
|
|
3616
|
+
sqlColumnCreateStatements.push(
|
|
3617
|
+
`PRIMARY KEY (${primaryColumns.map(({ name }) => name).join(", ")})`
|
|
3702
3618
|
);
|
|
3703
3619
|
}
|
|
3704
3620
|
db.prepare(`DROP TABLE IF EXISTS ${model.filenameBase};`).run();
|
|
3705
3621
|
db.prepare(
|
|
3706
|
-
`CREATE TABLE ${model.filenameBase} (${
|
|
3622
|
+
`CREATE TABLE ${model.filenameBase} (${sqlColumnCreateStatements.join(", ")});`
|
|
3707
3623
|
).run();
|
|
3708
3624
|
}
|
|
3709
3625
|
};
|
|
@@ -3712,10 +3628,18 @@ var createGtfsIndexes = (db) => {
|
|
|
3712
3628
|
if (!model.schema) {
|
|
3713
3629
|
return;
|
|
3714
3630
|
}
|
|
3715
|
-
for (const column of model.schema
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
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
|
+
}
|
|
3719
3643
|
}
|
|
3720
3644
|
}
|
|
3721
3645
|
};
|
|
@@ -3724,11 +3648,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
3724
3648
|
const formattedLine = {};
|
|
3725
3649
|
const filenameBase = model.filenameBase;
|
|
3726
3650
|
const filenameExtension = model.filenameExtension;
|
|
3727
|
-
for (const
|
|
3728
|
-
const { name, type, required, min, max } = columnSchema;
|
|
3651
|
+
for (const { name, type, required } of model.schema) {
|
|
3729
3652
|
let value = line[name];
|
|
3730
3653
|
if (value === "" || value === void 0 || value === null) {
|
|
3731
3654
|
formattedLine[name] = null;
|
|
3655
|
+
if (type === "time") {
|
|
3656
|
+
formattedLine[getTimestampColumnName(name)] = null;
|
|
3657
|
+
}
|
|
3732
3658
|
if (required) {
|
|
3733
3659
|
throw new Error(
|
|
3734
3660
|
`Missing required value in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
|
|
@@ -3743,17 +3669,13 @@ var formatGtfsLine = (line, model, totalLineCount) => {
|
|
|
3743
3669
|
`Invalid date in ${filenameBase}.${filenameExtension} for ${name} on line ${lineNumber}.`
|
|
3744
3670
|
);
|
|
3745
3671
|
}
|
|
3672
|
+
} else if (type === "time") {
|
|
3673
|
+
const [timeAsSecondsFromMidnight, timeAsString] = formatAndCacheTime(value);
|
|
3674
|
+
value = timeAsString;
|
|
3675
|
+
formattedLine[getTimestampColumnName(name)] = timeAsSecondsFromMidnight ?? null;
|
|
3746
3676
|
}
|
|
3747
3677
|
formattedLine[name] = value;
|
|
3748
3678
|
}
|
|
3749
|
-
for (const [timeColumnName, timestampColumnName] of TIME_COLUMN_PAIRS) {
|
|
3750
|
-
const value = formattedLine[timeColumnName];
|
|
3751
|
-
if (value) {
|
|
3752
|
-
const [seconds, date] = calculateAndCacheDate(value);
|
|
3753
|
-
formattedLine[timestampColumnName] = seconds;
|
|
3754
|
-
formattedLine[timeColumnName] = date;
|
|
3755
|
-
}
|
|
3756
|
-
}
|
|
3757
3679
|
return formattedLine;
|
|
3758
3680
|
};
|
|
3759
3681
|
var BATCH_SIZE = 1e5;
|
|
@@ -3780,11 +3702,23 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3780
3702
|
return;
|
|
3781
3703
|
}
|
|
3782
3704
|
task.log(`Importing - ${filename}\r`);
|
|
3783
|
-
const
|
|
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
|
+
});
|
|
3784
3718
|
const prefixedColumns = new Set(
|
|
3785
|
-
|
|
3719
|
+
columns.filter((column) => column.prefix).map((column) => column.name)
|
|
3786
3720
|
);
|
|
3787
|
-
const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${
|
|
3721
|
+
const prepareStatement = `INSERT ${task.ignoreDuplicates ? "OR IGNORE" : ""} INTO ${model.filenameBase} (${columns.map(({ name }) => name).join(", ")}) VALUES (${columns.map(({ name }) => `@${name}`).join(", ")})`;
|
|
3788
3722
|
const insert = db.prepare(prepareStatement);
|
|
3789
3723
|
const insertLines = db.transaction((lines) => {
|
|
3790
3724
|
for (const [rowNumber, line] of Object.entries(lines)) {
|
|
@@ -3804,7 +3738,7 @@ var importGtfsFiles = (db, task) => mapSeries2(
|
|
|
3804
3738
|
}
|
|
3805
3739
|
} catch (error) {
|
|
3806
3740
|
if (error.code === "SQLITE_CONSTRAINT_PRIMARYKEY") {
|
|
3807
|
-
const primaryColumns =
|
|
3741
|
+
const primaryColumns = columns.filter(
|
|
3808
3742
|
(column) => column.primary
|
|
3809
3743
|
);
|
|
3810
3744
|
task.logWarning(
|