gtfs 4.17.0 → 4.17.1
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 +37 -21
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +141 -129
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +135 -127
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.js +145 -132
- package/dist/index.js.map +1 -1
- package/dist/models/models.d.ts +42 -1
- package/dist/models/models.js +32 -16
- package/dist/models/models.js.map +1 -1
- package/package.json +1 -1
|
@@ -122,21 +122,24 @@ var tripUpdates = {
|
|
|
122
122
|
required: true,
|
|
123
123
|
primary: true,
|
|
124
124
|
index: true,
|
|
125
|
-
source: "id"
|
|
125
|
+
source: "id",
|
|
126
|
+
prefix: true
|
|
126
127
|
},
|
|
127
128
|
{
|
|
128
129
|
name: "vehicle_id",
|
|
129
130
|
type: "text",
|
|
130
131
|
index: true,
|
|
131
132
|
source: "tripUpdate.vehicle.id",
|
|
132
|
-
default: null
|
|
133
|
+
default: null,
|
|
134
|
+
prefix: true
|
|
133
135
|
},
|
|
134
136
|
{
|
|
135
137
|
name: "trip_id",
|
|
136
138
|
type: "text",
|
|
137
139
|
index: true,
|
|
138
140
|
source: "tripUpdate.trip.tripId",
|
|
139
|
-
default: null
|
|
141
|
+
default: null,
|
|
142
|
+
prefix: true
|
|
140
143
|
},
|
|
141
144
|
{
|
|
142
145
|
name: "trip_start_time",
|
|
@@ -155,7 +158,8 @@ var tripUpdates = {
|
|
|
155
158
|
type: "text",
|
|
156
159
|
index: true,
|
|
157
160
|
source: "tripUpdate.trip.routeId",
|
|
158
|
-
default: null
|
|
161
|
+
default: null,
|
|
162
|
+
prefix: true
|
|
159
163
|
},
|
|
160
164
|
{
|
|
161
165
|
name: "start_date",
|
|
@@ -198,7 +202,8 @@ var stopTimeUpdates = {
|
|
|
198
202
|
type: "text",
|
|
199
203
|
index: true,
|
|
200
204
|
source: "parent.tripUpdate.trip.tripId",
|
|
201
|
-
default: null
|
|
205
|
+
default: null,
|
|
206
|
+
prefix: true
|
|
202
207
|
},
|
|
203
208
|
{
|
|
204
209
|
name: "trip_start_time",
|
|
@@ -217,14 +222,16 @@ var stopTimeUpdates = {
|
|
|
217
222
|
type: "text",
|
|
218
223
|
index: true,
|
|
219
224
|
source: "parent.tripUpdate.trip.routeId",
|
|
220
|
-
default: null
|
|
225
|
+
default: null,
|
|
226
|
+
prefix: true
|
|
221
227
|
},
|
|
222
228
|
{
|
|
223
229
|
name: "stop_id",
|
|
224
230
|
type: "text",
|
|
225
231
|
index: true,
|
|
226
232
|
source: "stopId",
|
|
227
|
-
default: null
|
|
233
|
+
default: null,
|
|
234
|
+
prefix: true
|
|
228
235
|
},
|
|
229
236
|
{
|
|
230
237
|
name: "stop_sequence",
|
|
@@ -286,7 +293,8 @@ var vehiclePositions = {
|
|
|
286
293
|
required: true,
|
|
287
294
|
primary: true,
|
|
288
295
|
index: true,
|
|
289
|
-
source: "id"
|
|
296
|
+
source: "id",
|
|
297
|
+
prefix: true
|
|
290
298
|
},
|
|
291
299
|
{
|
|
292
300
|
name: "bearing",
|
|
@@ -328,7 +336,8 @@ var vehiclePositions = {
|
|
|
328
336
|
type: "text",
|
|
329
337
|
index: true,
|
|
330
338
|
source: "vehicle.trip.tripId",
|
|
331
|
-
default: null
|
|
339
|
+
default: null,
|
|
340
|
+
prefix: true
|
|
332
341
|
},
|
|
333
342
|
{
|
|
334
343
|
name: "trip_start_date",
|
|
@@ -373,7 +382,8 @@ var vehiclePositions = {
|
|
|
373
382
|
type: "text",
|
|
374
383
|
index: true,
|
|
375
384
|
source: "vehicle.vehicle.id",
|
|
376
|
-
default: null
|
|
385
|
+
default: null,
|
|
386
|
+
prefix: true
|
|
377
387
|
},
|
|
378
388
|
{
|
|
379
389
|
name: "vehicle_label",
|
|
@@ -423,7 +433,8 @@ var serviceAlerts = {
|
|
|
423
433
|
required: true,
|
|
424
434
|
primary: true,
|
|
425
435
|
index: true,
|
|
426
|
-
source: "id"
|
|
436
|
+
source: "id",
|
|
437
|
+
prefix: true
|
|
427
438
|
},
|
|
428
439
|
{
|
|
429
440
|
name: "active_period",
|
|
@@ -512,21 +523,24 @@ var serviceAlertInformedEntities = {
|
|
|
512
523
|
type: "text",
|
|
513
524
|
required: true,
|
|
514
525
|
primary: true,
|
|
515
|
-
source: "parent.id"
|
|
526
|
+
source: "parent.id",
|
|
527
|
+
prefix: true
|
|
516
528
|
},
|
|
517
529
|
{
|
|
518
530
|
name: "stop_id",
|
|
519
531
|
type: "text",
|
|
520
532
|
index: true,
|
|
521
533
|
source: "stopId",
|
|
522
|
-
default: null
|
|
534
|
+
default: null,
|
|
535
|
+
prefix: true
|
|
523
536
|
},
|
|
524
537
|
{
|
|
525
538
|
name: "route_id",
|
|
526
539
|
type: "text",
|
|
527
540
|
index: true,
|
|
528
541
|
source: "routeId",
|
|
529
|
-
default: null
|
|
542
|
+
default: null,
|
|
543
|
+
prefix: true
|
|
530
544
|
},
|
|
531
545
|
{
|
|
532
546
|
name: "route_type",
|
|
@@ -540,7 +554,8 @@ var serviceAlertInformedEntities = {
|
|
|
540
554
|
type: "text",
|
|
541
555
|
index: true,
|
|
542
556
|
source: "trip.tripId",
|
|
543
|
-
default: null
|
|
557
|
+
default: null,
|
|
558
|
+
prefix: true
|
|
544
559
|
},
|
|
545
560
|
{
|
|
546
561
|
name: "direction_id",
|
|
@@ -616,8 +631,8 @@ import { feature, featureCollection } from "@turf/helpers";
|
|
|
616
631
|
// src/lib/import-gtfs-realtime.ts
|
|
617
632
|
import pluralize from "pluralize";
|
|
618
633
|
import GtfsRealtimeBindings from "gtfs-realtime-bindings";
|
|
619
|
-
import sqlString2 from "sqlstring-sqlite";
|
|
620
634
|
import mapSeries from "promise-map-series";
|
|
635
|
+
import { get } from "lodash-es";
|
|
621
636
|
|
|
622
637
|
// src/lib/utils.ts
|
|
623
638
|
import sqlString from "sqlstring-sqlite";
|
|
@@ -654,39 +669,14 @@ function convertLongTimeToDate(longDate) {
|
|
|
654
669
|
Long.fromBits(low, high, unsigned).toNumber() * 1e3
|
|
655
670
|
).toISOString();
|
|
656
671
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
if (path2 === void 0) return defaultValue;
|
|
661
|
-
const arr = path2.split(".");
|
|
662
|
-
while (arr.length) {
|
|
663
|
-
const nextKey = arr.shift();
|
|
664
|
-
if (nextKey === void 0) {
|
|
665
|
-
return defaultValue;
|
|
666
|
-
} else if (obj == null) {
|
|
667
|
-
return defaultValue;
|
|
668
|
-
} else if (nextKey?.includes("[")) {
|
|
669
|
-
const arrayKey = nextKey.match(/(\w*)\[(\d+)\]/);
|
|
670
|
-
if (arrayKey === null) {
|
|
671
|
-
return defaultValue;
|
|
672
|
-
}
|
|
673
|
-
if (obj[arrayKey[1]] === void 0) {
|
|
674
|
-
return defaultValue;
|
|
675
|
-
}
|
|
676
|
-
if (obj[arrayKey[1]][arrayKey[2]] === void 0) {
|
|
677
|
-
return defaultValue;
|
|
678
|
-
}
|
|
679
|
-
obj = obj[arrayKey[1]][arrayKey[2]];
|
|
680
|
-
} else {
|
|
681
|
-
if (obj[nextKey] === void 0) {
|
|
682
|
-
return defaultValue;
|
|
683
|
-
}
|
|
684
|
-
obj = obj[nextKey];
|
|
685
|
-
}
|
|
672
|
+
function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
|
|
673
|
+
if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
|
|
674
|
+
return value;
|
|
686
675
|
}
|
|
687
|
-
|
|
688
|
-
return obj;
|
|
676
|
+
return `${prefix}${value}`;
|
|
689
677
|
}
|
|
678
|
+
|
|
679
|
+
// src/lib/import-gtfs-realtime.ts
|
|
690
680
|
async function fetchGtfsRealtimeData(urlConfig, task) {
|
|
691
681
|
task.log(`Downloading GTFS-Realtime from ${urlConfig.url}`);
|
|
692
682
|
const response = await fetch(urlConfig.url, {
|
|
@@ -744,100 +734,117 @@ function prepareRealtimeFieldValue(entity, column, task) {
|
|
|
744
734
|
if (column.name === "expiration_timestamp") {
|
|
745
735
|
return task.currentTimestamp + task.gtfsRealtimeExpirationSeconds;
|
|
746
736
|
}
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
737
|
+
const baseValue = column.source === void 0 ? column.default : get(entity, column.source, column.default);
|
|
738
|
+
const timeAdjustedValue = baseValue?.__isLong__ ? convertLongTimeToDate(baseValue) : baseValue;
|
|
739
|
+
const prefixedValue = applyPrefixToValue(
|
|
740
|
+
timeAdjustedValue,
|
|
741
|
+
column.prefix,
|
|
742
|
+
task.prefix
|
|
743
|
+
);
|
|
744
|
+
return column.type === "json" ? JSON.stringify(prefixedValue) : prefixedValue;
|
|
752
745
|
}
|
|
753
746
|
async function processRealtimeAlerts(db, gtfsRealtimeData, task) {
|
|
754
|
-
|
|
747
|
+
const alertStmt = db.prepare(
|
|
748
|
+
`REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(
|
|
749
|
+
", "
|
|
750
|
+
)}) VALUES (${serviceAlerts.schema.map(() => "?").join(", ")})`
|
|
751
|
+
);
|
|
752
|
+
const informedEntityStmt = db.prepare(
|
|
753
|
+
`REPLACE INTO ${serviceAlertInformedEntities.filenameBase} (${serviceAlertInformedEntities.schema.map((column) => column.name).join(
|
|
754
|
+
", "
|
|
755
|
+
)}) VALUES (${serviceAlertInformedEntities.schema.map(() => "?").join(", ")})`
|
|
756
|
+
);
|
|
755
757
|
let totalLineCount = 0;
|
|
756
|
-
|
|
757
|
-
const
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
try {
|
|
761
|
-
db.prepare(
|
|
762
|
-
`REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
|
|
763
|
-
).run();
|
|
764
|
-
} catch (error) {
|
|
765
|
-
task.logWarning(`Import error: ${error.message}`);
|
|
766
|
-
}
|
|
767
|
-
if (!entity.alert.informedEntity || entity.alert.informedEntity.length === 0) {
|
|
768
|
-
task.logWarning(
|
|
769
|
-
`Import error: No informed entities found for alert id=${entity.id}`
|
|
758
|
+
db.transaction(() => {
|
|
759
|
+
for (const entity of gtfsRealtimeData.entity) {
|
|
760
|
+
const fieldValues = serviceAlerts.schema.map(
|
|
761
|
+
(column) => prepareRealtimeFieldValue(entity, column, task)
|
|
770
762
|
);
|
|
771
|
-
} else {
|
|
772
|
-
const informedEntities = [];
|
|
773
|
-
for (const informedEntity of entity.alert.informedEntity) {
|
|
774
|
-
informedEntity.parent = entity;
|
|
775
|
-
const subValues = serviceAlertInformedEntities.schema.map(
|
|
776
|
-
(column) => prepareRealtimeFieldValue(informedEntity, column, task)
|
|
777
|
-
);
|
|
778
|
-
informedEntities.push(`(${subValues.join(", ")})`);
|
|
779
|
-
totalLineCount++;
|
|
780
|
-
}
|
|
781
763
|
try {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
764
|
+
alertStmt.run(fieldValues);
|
|
765
|
+
if (entity.alert.informedEntity?.length) {
|
|
766
|
+
const informedEntities = entity.alert.informedEntity.map(
|
|
767
|
+
(informedEntity) => {
|
|
768
|
+
informedEntity.parent = entity;
|
|
769
|
+
return serviceAlertInformedEntities.schema.map(
|
|
770
|
+
(column) => prepareRealtimeFieldValue(informedEntity, column, task)
|
|
771
|
+
);
|
|
772
|
+
}
|
|
773
|
+
);
|
|
774
|
+
for (const values of informedEntities) {
|
|
775
|
+
informedEntityStmt.run(values);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
totalLineCount++;
|
|
785
779
|
} catch (error) {
|
|
786
780
|
task.logWarning(`Import error: ${error.message}`);
|
|
787
781
|
}
|
|
788
782
|
}
|
|
789
|
-
task.log(
|
|
790
|
-
|
|
783
|
+
task.log(
|
|
784
|
+
`Importing - GTFS-Realtime service alerts - ${totalLineCount} entries imported\r`,
|
|
785
|
+
true
|
|
786
|
+
);
|
|
787
|
+
})();
|
|
791
788
|
}
|
|
792
789
|
async function processRealtimeTripUpdates(db, gtfsRealtimeData, task) {
|
|
793
|
-
task.log(`Download successful`);
|
|
794
790
|
let totalLineCount = 0;
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
)
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
791
|
+
const tripUpdateStmt = db.prepare(
|
|
792
|
+
`REPLACE INTO ${tripUpdates.filenameBase} (${tripUpdates.schema.map((column) => column.name).join(
|
|
793
|
+
", "
|
|
794
|
+
)}) VALUES (${tripUpdates.schema.map(() => "?").join(", ")})`
|
|
795
|
+
);
|
|
796
|
+
const stopTimeStmt = db.prepare(
|
|
797
|
+
`REPLACE INTO ${stopTimeUpdates.filenameBase} (${stopTimeUpdates.schema.map((column) => column.name).join(
|
|
798
|
+
", "
|
|
799
|
+
)}) VALUES (${stopTimeUpdates.schema.map(() => "?").join(", ")})`
|
|
800
|
+
);
|
|
801
|
+
db.transaction(() => {
|
|
802
|
+
for (const entity of gtfsRealtimeData.entity) {
|
|
803
|
+
try {
|
|
804
|
+
const fieldValues = tripUpdates.schema.map(
|
|
805
|
+
(column) => prepareRealtimeFieldValue(entity, column, task)
|
|
806
|
+
);
|
|
807
|
+
tripUpdateStmt.run(fieldValues);
|
|
808
|
+
for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
|
|
809
|
+
stopTimeUpdate.parent = entity;
|
|
810
|
+
const values = stopTimeUpdates.schema.map(
|
|
811
|
+
(column) => prepareRealtimeFieldValue(stopTimeUpdate, column, task)
|
|
812
|
+
);
|
|
813
|
+
stopTimeStmt.run(values);
|
|
814
|
+
}
|
|
815
|
+
totalLineCount++;
|
|
816
|
+
} catch (error) {
|
|
817
|
+
task.logWarning(`Import error: ${error.message}`);
|
|
818
|
+
}
|
|
821
819
|
}
|
|
822
|
-
task.log(
|
|
823
|
-
|
|
820
|
+
task.log(
|
|
821
|
+
`Importing - GTFS-Realtime trip updates - ${totalLineCount} entries imported\r`,
|
|
822
|
+
true
|
|
823
|
+
);
|
|
824
|
+
})();
|
|
824
825
|
}
|
|
825
826
|
async function processRealtimeVehiclePositions(db, gtfsRealtimeData, task) {
|
|
826
|
-
task.log(`Download successful`);
|
|
827
827
|
let totalLineCount = 0;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
)
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
828
|
+
const vehiclePositionStmt = db.prepare(
|
|
829
|
+
`REPLACE INTO ${vehiclePositions.filenameBase} (${vehiclePositions.schema.map((column) => column.name).join(
|
|
830
|
+
", "
|
|
831
|
+
)}) VALUES (${vehiclePositions.schema.map(() => "?").join(", ")})`
|
|
832
|
+
);
|
|
833
|
+
db.transaction(() => {
|
|
834
|
+
for (const entity of gtfsRealtimeData.entity) {
|
|
835
|
+
try {
|
|
836
|
+
const fieldValues = vehiclePositions.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
|
|
837
|
+
vehiclePositionStmt.run(fieldValues);
|
|
838
|
+
totalLineCount++;
|
|
839
|
+
} catch (error) {
|
|
840
|
+
task.logWarning(`Import error: ${error.message}`);
|
|
841
|
+
}
|
|
838
842
|
}
|
|
839
|
-
task.log(
|
|
840
|
-
|
|
843
|
+
task.log(
|
|
844
|
+
`Importing - GTFS-Realtime vehicle positions - ${totalLineCount} entries imported\r`,
|
|
845
|
+
true
|
|
846
|
+
);
|
|
847
|
+
})();
|
|
841
848
|
}
|
|
842
849
|
async function updateGtfsRealtimeData(task) {
|
|
843
850
|
if (task.realtimeAlerts === void 0 && task.realtimeTripUpdates === void 0 && task.realtimeVehiclePositions === void 0) {
|
|
@@ -918,6 +925,7 @@ async function updateGtfsRealtime(initialConfig) {
|
|
|
918
925
|
gtfsRealtimeExpirationSeconds: config.gtfsRealtimeExpirationSeconds,
|
|
919
926
|
ignoreErrors: config.ignoreErrors,
|
|
920
927
|
sqlitePath: config.sqlitePath,
|
|
928
|
+
prefix: agency2.prefix,
|
|
921
929
|
currentTimestamp: Math.floor(Date.now() / 1e3),
|
|
922
930
|
log: log(config),
|
|
923
931
|
logWarning: logWarning(config),
|
|
@@ -954,12 +962,12 @@ async function updateGtfsRealtime(initialConfig) {
|
|
|
954
962
|
import { without, compact as compact2 } from "lodash-es";
|
|
955
963
|
import pluralize3 from "pluralize";
|
|
956
964
|
import { stringify } from "csv-stringify";
|
|
957
|
-
import
|
|
965
|
+
import sqlString2 from "sqlstring-sqlite";
|
|
958
966
|
import mapSeries3 from "promise-map-series";
|
|
959
967
|
import untildify4 from "untildify";
|
|
960
968
|
|
|
961
969
|
// src/lib/advancedQuery.ts
|
|
962
|
-
import
|
|
970
|
+
import sqlString3 from "sqlstring-sqlite";
|
|
963
971
|
|
|
964
972
|
// src/lib/gtfs/routes.ts
|
|
965
973
|
import { omit as omit3, pick } from "lodash-es";
|
|
@@ -973,7 +981,7 @@ import { omit as omit5, orderBy, pick as pick3 } from "lodash-es";
|
|
|
973
981
|
|
|
974
982
|
// src/lib/gtfs/stop-times.ts
|
|
975
983
|
import { omit as omit6 } from "lodash-es";
|
|
976
|
-
import
|
|
984
|
+
import sqlString4 from "sqlstring-sqlite";
|
|
977
985
|
|
|
978
986
|
// src/bin/gtfsrealtime-update.ts
|
|
979
987
|
var pe = new PrettyError();
|