@golemio/public-transport 0.1.0-dev.2780201953 → 0.1.0-dev.2780480386
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/db/migrations/postgresql/20260821000000-widen-stop-times-dwell-seconds.js +53 -0
- package/db/migrations/postgresql/sqls/20260821000000-widen-stop-times-dwell-seconds-down.sql +141 -0
- package/db/migrations/postgresql/sqls/20260821000000-widen-stop-times-dwell-seconds-up.sql +151 -0
- package/dist/integration-engine/gtfs/transformations/GtfsTransformation.js +16 -1
- package/dist/integration-engine/gtfs/transformations/GtfsTransformation.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var dbm;
|
|
4
|
+
var type;
|
|
5
|
+
var seed;
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
var Promise;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* We receive the dbmigrate dependency from dbmigrate initially.
|
|
12
|
+
* This enables us to not have to rely on NODE_PATH.
|
|
13
|
+
*/
|
|
14
|
+
exports.setup = function(options, seedLink) {
|
|
15
|
+
dbm = options.dbmigrate;
|
|
16
|
+
type = dbm.dataType;
|
|
17
|
+
seed = seedLink;
|
|
18
|
+
Promise = options.Promise;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
exports.up = function(db) {
|
|
22
|
+
var filePath = path.join(__dirname, 'sqls', '20260821000000-widen-stop-times-dwell-seconds-up.sql');
|
|
23
|
+
return new Promise( function( resolve, reject ) {
|
|
24
|
+
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
|
|
25
|
+
if (err) return reject(err);
|
|
26
|
+
console.log('received data: ' + data);
|
|
27
|
+
|
|
28
|
+
resolve(data);
|
|
29
|
+
});
|
|
30
|
+
})
|
|
31
|
+
.then(function(data) {
|
|
32
|
+
return db.runSql(data);
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
exports.down = function(db) {
|
|
37
|
+
var filePath = path.join(__dirname, 'sqls', '20260821000000-widen-stop-times-dwell-seconds-down.sql');
|
|
38
|
+
return new Promise( function( resolve, reject ) {
|
|
39
|
+
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
|
|
40
|
+
if (err) return reject(err);
|
|
41
|
+
console.log('received data: ' + data);
|
|
42
|
+
|
|
43
|
+
resolve(data);
|
|
44
|
+
});
|
|
45
|
+
})
|
|
46
|
+
.then(function(data) {
|
|
47
|
+
return db.runSql(data);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
exports._meta = {
|
|
52
|
+
"version": 1
|
|
53
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
-- Narrowing back fails if any stored dwell time exceeds smallint -- clear such feeds first.
|
|
2
|
+
DROP VIEW public_transport.v_public_vehiclepositions_combined_stop_times;
|
|
3
|
+
DROP VIEW public_transport.v_public_vehiclepositions_future_stop_times;
|
|
4
|
+
DROP FUNCTION public_transport.predict_delay_seconds(integer, integer, character varying);
|
|
5
|
+
|
|
6
|
+
ALTER TABLE public_transport.gtfs_stop_times ALTER COLUMN computed_dwell_time_seconds TYPE smallint;
|
|
7
|
+
|
|
8
|
+
CREATE FUNCTION public_transport.predict_delay_seconds(position_delay integer, stop_dwell_time_seconds smallint, provider_source_type character varying) RETURNS integer
|
|
9
|
+
LANGUAGE plpgsql
|
|
10
|
+
AS $$
|
|
11
|
+
declare
|
|
12
|
+
result int;
|
|
13
|
+
BEGIN
|
|
14
|
+
select
|
|
15
|
+
position_delay - least(greatest(0, position_delay), greatest(0, stop_dwell_time_seconds - 60))
|
|
16
|
+
into result;
|
|
17
|
+
|
|
18
|
+
if provider_source_type = '1' then -- http
|
|
19
|
+
return greatest(0, result);
|
|
20
|
+
else
|
|
21
|
+
return result;
|
|
22
|
+
end if;
|
|
23
|
+
END;
|
|
24
|
+
$$;
|
|
25
|
+
|
|
26
|
+
COMMENT ON FUNCTION public_transport.predict_delay_seconds(position_delay integer, stop_dwell_time_seconds smallint, provider_source_type character varying) IS '
|
|
27
|
+
Predicts the delay of a vehicle at a stop.
|
|
28
|
+
If the provider source type is HTTP, the predicted delay should never be negative (ahead of schedule).
|
|
29
|
+
';
|
|
30
|
+
|
|
31
|
+
CREATE VIEW public_transport.v_public_vehiclepositions_future_stop_times AS
|
|
32
|
+
WITH RECURSIVE stop_times AS (
|
|
33
|
+
SELECT rst.trip_id,
|
|
34
|
+
vt.id AS trips_id,
|
|
35
|
+
vt.feed_id,
|
|
36
|
+
vt.provider_source_type,
|
|
37
|
+
COALESCE(vp.delay, 0) AS delay,
|
|
38
|
+
COALESCE(vp.last_stop_sequence, 1) AS initial_stop_sequence,
|
|
39
|
+
vp.state_position,
|
|
40
|
+
rst.stop_id,
|
|
41
|
+
rst.stop_sequence,
|
|
42
|
+
rst.computed_dwell_time_seconds,
|
|
43
|
+
rst.arrival_time,
|
|
44
|
+
rst.departure_time,
|
|
45
|
+
CASE
|
|
46
|
+
WHEN ((vp.state_position)::text = 'off_track'::text) THEN COALESCE(vp.delay, 0)
|
|
47
|
+
WHEN (vp.last_stop_sequence IS NULL) THEN COALESCE(vp.delay, 0)
|
|
48
|
+
ELSE COALESCE(vp.delay_stop_arrival, 0)
|
|
49
|
+
END AS arrival_delay_seconds,
|
|
50
|
+
CASE
|
|
51
|
+
WHEN ((vp.state_position)::text = 'off_track'::text) THEN public_transport.predict_delay_seconds(vp.delay, rst.computed_dwell_time_seconds, vt.provider_source_type)
|
|
52
|
+
WHEN (vp.last_stop_sequence IS NULL) THEN public_transport.predict_delay_seconds(vp.delay, rst.computed_dwell_time_seconds, vt.provider_source_type)
|
|
53
|
+
WHEN ((vp.state_position)::text = 'at_stop'::text) THEN
|
|
54
|
+
CASE
|
|
55
|
+
WHEN ((vt.provider_source_type)::text = '1'::text) THEN GREATEST(0, vp.delay)
|
|
56
|
+
ELSE vp.delay
|
|
57
|
+
END
|
|
58
|
+
ELSE vp.delay_stop_departure
|
|
59
|
+
END AS departure_delay_seconds
|
|
60
|
+
FROM ((public_transport.gtfs_stop_times rst
|
|
61
|
+
JOIN public_transport.vehiclepositions_trips vt ON (((vt.gtfs_trip_id)::text = (rst.trip_id)::text) AND (rst.feed_id = vt.feed_id)))
|
|
62
|
+
JOIN public_transport.vehiclepositions_positions vp ON (((vp.id = vt.last_position_id) AND ((vp.valid_to IS NULL) OR (vp.valid_to >= now())) AND ((vp.state_position)::text = ANY (ARRAY[('on_track'::character varying)::text, ('at_stop'::character varying)::text, ('before_track'::character varying)::text, ('before_track_delayed'::character varying)::text, ('off_track'::character varying)::text])))))
|
|
63
|
+
WHERE ((vt.gtfs_trip_id IS NOT NULL) AND (rst.stop_sequence = COALESCE(vp.last_stop_sequence, 1)))
|
|
64
|
+
UNION ALL
|
|
65
|
+
SELECT rst.trip_id,
|
|
66
|
+
previous_row.trips_id,
|
|
67
|
+
previous_row.feed_id,
|
|
68
|
+
previous_row.provider_source_type,
|
|
69
|
+
previous_row.delay,
|
|
70
|
+
previous_row.initial_stop_sequence,
|
|
71
|
+
previous_row.state_position,
|
|
72
|
+
rst.stop_id,
|
|
73
|
+
rst.stop_sequence,
|
|
74
|
+
rst.computed_dwell_time_seconds,
|
|
75
|
+
rst.arrival_time,
|
|
76
|
+
rst.departure_time,
|
|
77
|
+
CASE
|
|
78
|
+
WHEN (((rst.stop_sequence - previous_row.initial_stop_sequence) = 1) AND ((previous_row.state_position)::text <> 'at_stop'::text)) THEN
|
|
79
|
+
CASE
|
|
80
|
+
WHEN (((rst.arrival_time)::interval + ('00:00:01'::interval * (previous_row.delay)::double precision)) < ((previous_row.departure_time)::interval + ('00:00:01'::interval * (previous_row.departure_delay_seconds)::double precision))) THEN NULL::integer
|
|
81
|
+
ELSE previous_row.delay
|
|
82
|
+
END
|
|
83
|
+
ELSE previous_row.departure_delay_seconds
|
|
84
|
+
END AS arrival_delay_seconds,
|
|
85
|
+
public_transport.predict_delay_seconds(
|
|
86
|
+
CASE
|
|
87
|
+
WHEN (((rst.stop_sequence - previous_row.initial_stop_sequence) = 1) AND ((previous_row.state_position)::text <> 'at_stop'::text)) THEN previous_row.delay
|
|
88
|
+
ELSE previous_row.departure_delay_seconds
|
|
89
|
+
END, rst.computed_dwell_time_seconds, previous_row.provider_source_type) AS departure_delay_seconds
|
|
90
|
+
FROM (stop_times previous_row
|
|
91
|
+
JOIN public_transport.gtfs_stop_times rst ON ((((rst.trip_id)::text = (previous_row.trip_id)::text) AND (rst.stop_sequence = (previous_row.stop_sequence + 1)) AND (rst.feed_id = previous_row.feed_id))))
|
|
92
|
+
)
|
|
93
|
+
SELECT trips_id AS rt_trip_id,
|
|
94
|
+
stop_sequence,
|
|
95
|
+
arrival_delay_seconds AS stop_arr_delay,
|
|
96
|
+
CASE
|
|
97
|
+
WHEN (((arrival_time)::interval + ('00:00:01'::interval * (COALESCE(arrival_delay_seconds, 0))::double precision)) > ((departure_time)::interval + ('00:00:01'::interval * (COALESCE(departure_delay_seconds, 0))::double precision))) THEN NULL::integer
|
|
98
|
+
ELSE departure_delay_seconds
|
|
99
|
+
END AS stop_dep_delay,
|
|
100
|
+
stop_id
|
|
101
|
+
FROM stop_times
|
|
102
|
+
ORDER BY trip_id, stop_sequence;
|
|
103
|
+
|
|
104
|
+
CREATE VIEW public_transport.v_public_vehiclepositions_combined_stop_times AS
|
|
105
|
+
SELECT DISTINCT ON (stop_times.rt_trip_id, stop_times.stop_sequence) stop_times.rt_trip_id,
|
|
106
|
+
vt.gtfs_trip_id,
|
|
107
|
+
stop_times.stop_sequence,
|
|
108
|
+
stop_times.stop_arr_delay,
|
|
109
|
+
stop_times.stop_dep_delay,
|
|
110
|
+
vt.gtfs_route_type,
|
|
111
|
+
vt.gtfs_route_short_name,
|
|
112
|
+
vt.run_number,
|
|
113
|
+
vt.internal_run_number,
|
|
114
|
+
vt.provider_source_type,
|
|
115
|
+
vt.cis_trip_number,
|
|
116
|
+
vt.vehicle_registration_number,
|
|
117
|
+
stop_times.stop_id,
|
|
118
|
+
vcs.cis_stop_platform_code,
|
|
119
|
+
rs.platform_code,
|
|
120
|
+
rs.stop_name,
|
|
121
|
+
platform.stop_id AS assigned_stop_id
|
|
122
|
+
FROM ((((((( SELECT prediction.rt_trip_id,
|
|
123
|
+
prediction.stop_sequence,
|
|
124
|
+
prediction.stop_arr_delay,
|
|
125
|
+
prediction.stop_dep_delay,
|
|
126
|
+
prediction.stop_id
|
|
127
|
+
FROM public_transport.v_public_vehiclepositions_future_stop_times prediction
|
|
128
|
+
UNION ALL
|
|
129
|
+
SELECT history.rt_trip_id,
|
|
130
|
+
history.stop_sequence,
|
|
131
|
+
history.stop_arr_delay,
|
|
132
|
+
history.stop_dep_delay,
|
|
133
|
+
history.stop_id
|
|
134
|
+
FROM public_transport.v_public_vehiclepositions_past_stop_times history) stop_times
|
|
135
|
+
JOIN public_transport.vehiclepositions_trips vt ON (((vt.id)::text = (stop_times.rt_trip_id)::text)))
|
|
136
|
+
JOIN public_transport.vehiclepositions_positions vp ON (((vt.last_position_id = vp.id) AND ((vp.valid_to IS NULL) OR (vp.valid_to >= now())) AND ((vp.state_position)::text <> 'after_track'::text))))
|
|
137
|
+
JOIN public_transport.gtfs_stops rs ON (((rs.stop_id)::text = (stop_times.stop_id)::text) AND (rs.feed_id = vt.feed_id)))
|
|
138
|
+
LEFT JOIN public_transport.gtfs_cis_stops rcs ON (((rcs.id)::text = rs.computed_cis_stop_id) AND (rcs.feed_id = vt.feed_id)))
|
|
139
|
+
LEFT JOIN public_transport.vehiclepositions_cis_stops vcs ON ((((vcs.rt_trip_id)::text = (stop_times.rt_trip_id)::text) AND (vcs.cis_stop_group_id = rcs.cis) AND (vcs.feed_id = vt.feed_id))))
|
|
140
|
+
LEFT JOIN public_transport.gtfs_stops platform ON (((rs.parent_station IS NOT NULL) AND ((platform.parent_station)::text = (rs.parent_station)::text) AND ((platform.platform_code)::text = (vcs.cis_stop_platform_code)::text) AND (platform.location_type = 0) AND (platform.feed_id = vt.feed_id))))
|
|
141
|
+
ORDER BY stop_times.rt_trip_id, stop_times.stop_sequence, platform.stop_id;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
-- Widen computed_dwell_time_seconds: ids-jmk stop_times has depot/terminal layovers
|
|
2
|
+
-- (arrival vs departure gap) up to ~17.75h, exceeding smallint range (max 32767s / 9.1h).
|
|
3
|
+
-- ALTER on the partitioned parent cascades to all attached partitions; tmp tables are transient
|
|
4
|
+
-- (recreated per import via LIKE parent).
|
|
5
|
+
-- v_public_vehiclepositions_future_stop_times reads the column, and
|
|
6
|
+
-- v_public_vehiclepositions_combined_stop_times reads that view in turn, so both must be
|
|
7
|
+
-- dropped and recreated around the ALTER (Postgres won't widen a column a view depends on
|
|
8
|
+
-- in place).
|
|
9
|
+
-- predict_delay_seconds(integer, smallint, character varying) takes the column as its 2nd
|
|
10
|
+
-- arg; widening the column leaves no matching overload, so it must be dropped and recreated
|
|
11
|
+
-- with an integer param too (CREATE OR REPLACE can't change an argument type).
|
|
12
|
+
DROP VIEW public_transport.v_public_vehiclepositions_combined_stop_times;
|
|
13
|
+
DROP VIEW public_transport.v_public_vehiclepositions_future_stop_times;
|
|
14
|
+
DROP FUNCTION public_transport.predict_delay_seconds(integer, smallint, character varying);
|
|
15
|
+
|
|
16
|
+
ALTER TABLE public_transport.gtfs_stop_times ALTER COLUMN computed_dwell_time_seconds TYPE integer;
|
|
17
|
+
|
|
18
|
+
CREATE FUNCTION public_transport.predict_delay_seconds(position_delay integer, stop_dwell_time_seconds integer, provider_source_type character varying) RETURNS integer
|
|
19
|
+
LANGUAGE plpgsql
|
|
20
|
+
AS $$
|
|
21
|
+
declare
|
|
22
|
+
result int;
|
|
23
|
+
BEGIN
|
|
24
|
+
select
|
|
25
|
+
position_delay - least(greatest(0, position_delay), greatest(0, stop_dwell_time_seconds - 60))
|
|
26
|
+
into result;
|
|
27
|
+
|
|
28
|
+
if provider_source_type = '1' then -- http
|
|
29
|
+
return greatest(0, result);
|
|
30
|
+
else
|
|
31
|
+
return result;
|
|
32
|
+
end if;
|
|
33
|
+
END;
|
|
34
|
+
$$;
|
|
35
|
+
|
|
36
|
+
COMMENT ON FUNCTION public_transport.predict_delay_seconds(position_delay integer, stop_dwell_time_seconds integer, provider_source_type character varying) IS '
|
|
37
|
+
Predicts the delay of a vehicle at a stop.
|
|
38
|
+
If the provider source type is HTTP, the predicted delay should never be negative (ahead of schedule).
|
|
39
|
+
';
|
|
40
|
+
|
|
41
|
+
CREATE VIEW public_transport.v_public_vehiclepositions_future_stop_times AS
|
|
42
|
+
WITH RECURSIVE stop_times AS (
|
|
43
|
+
SELECT rst.trip_id,
|
|
44
|
+
vt.id AS trips_id,
|
|
45
|
+
vt.feed_id,
|
|
46
|
+
vt.provider_source_type,
|
|
47
|
+
COALESCE(vp.delay, 0) AS delay,
|
|
48
|
+
COALESCE(vp.last_stop_sequence, 1) AS initial_stop_sequence,
|
|
49
|
+
vp.state_position,
|
|
50
|
+
rst.stop_id,
|
|
51
|
+
rst.stop_sequence,
|
|
52
|
+
rst.computed_dwell_time_seconds,
|
|
53
|
+
rst.arrival_time,
|
|
54
|
+
rst.departure_time,
|
|
55
|
+
CASE
|
|
56
|
+
WHEN ((vp.state_position)::text = 'off_track'::text) THEN COALESCE(vp.delay, 0)
|
|
57
|
+
WHEN (vp.last_stop_sequence IS NULL) THEN COALESCE(vp.delay, 0)
|
|
58
|
+
ELSE COALESCE(vp.delay_stop_arrival, 0)
|
|
59
|
+
END AS arrival_delay_seconds,
|
|
60
|
+
CASE
|
|
61
|
+
WHEN ((vp.state_position)::text = 'off_track'::text) THEN public_transport.predict_delay_seconds(vp.delay, rst.computed_dwell_time_seconds, vt.provider_source_type)
|
|
62
|
+
WHEN (vp.last_stop_sequence IS NULL) THEN public_transport.predict_delay_seconds(vp.delay, rst.computed_dwell_time_seconds, vt.provider_source_type)
|
|
63
|
+
WHEN ((vp.state_position)::text = 'at_stop'::text) THEN
|
|
64
|
+
CASE
|
|
65
|
+
WHEN ((vt.provider_source_type)::text = '1'::text) THEN GREATEST(0, vp.delay)
|
|
66
|
+
ELSE vp.delay
|
|
67
|
+
END
|
|
68
|
+
ELSE vp.delay_stop_departure
|
|
69
|
+
END AS departure_delay_seconds
|
|
70
|
+
FROM ((public_transport.gtfs_stop_times rst
|
|
71
|
+
JOIN public_transport.vehiclepositions_trips vt ON (((vt.gtfs_trip_id)::text = (rst.trip_id)::text) AND (rst.feed_id = vt.feed_id)))
|
|
72
|
+
JOIN public_transport.vehiclepositions_positions vp ON (((vp.id = vt.last_position_id) AND ((vp.valid_to IS NULL) OR (vp.valid_to >= now())) AND ((vp.state_position)::text = ANY (ARRAY[('on_track'::character varying)::text, ('at_stop'::character varying)::text, ('before_track'::character varying)::text, ('before_track_delayed'::character varying)::text, ('off_track'::character varying)::text])))))
|
|
73
|
+
WHERE ((vt.gtfs_trip_id IS NOT NULL) AND (rst.stop_sequence = COALESCE(vp.last_stop_sequence, 1)))
|
|
74
|
+
UNION ALL
|
|
75
|
+
SELECT rst.trip_id,
|
|
76
|
+
previous_row.trips_id,
|
|
77
|
+
previous_row.feed_id,
|
|
78
|
+
previous_row.provider_source_type,
|
|
79
|
+
previous_row.delay,
|
|
80
|
+
previous_row.initial_stop_sequence,
|
|
81
|
+
previous_row.state_position,
|
|
82
|
+
rst.stop_id,
|
|
83
|
+
rst.stop_sequence,
|
|
84
|
+
rst.computed_dwell_time_seconds,
|
|
85
|
+
rst.arrival_time,
|
|
86
|
+
rst.departure_time,
|
|
87
|
+
CASE
|
|
88
|
+
WHEN (((rst.stop_sequence - previous_row.initial_stop_sequence) = 1) AND ((previous_row.state_position)::text <> 'at_stop'::text)) THEN
|
|
89
|
+
CASE
|
|
90
|
+
WHEN (((rst.arrival_time)::interval + ('00:00:01'::interval * (previous_row.delay)::double precision)) < ((previous_row.departure_time)::interval + ('00:00:01'::interval * (previous_row.departure_delay_seconds)::double precision))) THEN NULL::integer
|
|
91
|
+
ELSE previous_row.delay
|
|
92
|
+
END
|
|
93
|
+
ELSE previous_row.departure_delay_seconds
|
|
94
|
+
END AS arrival_delay_seconds,
|
|
95
|
+
public_transport.predict_delay_seconds(
|
|
96
|
+
CASE
|
|
97
|
+
WHEN (((rst.stop_sequence - previous_row.initial_stop_sequence) = 1) AND ((previous_row.state_position)::text <> 'at_stop'::text)) THEN previous_row.delay
|
|
98
|
+
ELSE previous_row.departure_delay_seconds
|
|
99
|
+
END, rst.computed_dwell_time_seconds, previous_row.provider_source_type) AS departure_delay_seconds
|
|
100
|
+
FROM (stop_times previous_row
|
|
101
|
+
JOIN public_transport.gtfs_stop_times rst ON ((((rst.trip_id)::text = (previous_row.trip_id)::text) AND (rst.stop_sequence = (previous_row.stop_sequence + 1)) AND (rst.feed_id = previous_row.feed_id))))
|
|
102
|
+
)
|
|
103
|
+
SELECT trips_id AS rt_trip_id,
|
|
104
|
+
stop_sequence,
|
|
105
|
+
arrival_delay_seconds AS stop_arr_delay,
|
|
106
|
+
CASE
|
|
107
|
+
WHEN (((arrival_time)::interval + ('00:00:01'::interval * (COALESCE(arrival_delay_seconds, 0))::double precision)) > ((departure_time)::interval + ('00:00:01'::interval * (COALESCE(departure_delay_seconds, 0))::double precision))) THEN NULL::integer
|
|
108
|
+
ELSE departure_delay_seconds
|
|
109
|
+
END AS stop_dep_delay,
|
|
110
|
+
stop_id
|
|
111
|
+
FROM stop_times
|
|
112
|
+
ORDER BY trip_id, stop_sequence;
|
|
113
|
+
|
|
114
|
+
CREATE VIEW public_transport.v_public_vehiclepositions_combined_stop_times AS
|
|
115
|
+
SELECT DISTINCT ON (stop_times.rt_trip_id, stop_times.stop_sequence) stop_times.rt_trip_id,
|
|
116
|
+
vt.gtfs_trip_id,
|
|
117
|
+
stop_times.stop_sequence,
|
|
118
|
+
stop_times.stop_arr_delay,
|
|
119
|
+
stop_times.stop_dep_delay,
|
|
120
|
+
vt.gtfs_route_type,
|
|
121
|
+
vt.gtfs_route_short_name,
|
|
122
|
+
vt.run_number,
|
|
123
|
+
vt.internal_run_number,
|
|
124
|
+
vt.provider_source_type,
|
|
125
|
+
vt.cis_trip_number,
|
|
126
|
+
vt.vehicle_registration_number,
|
|
127
|
+
stop_times.stop_id,
|
|
128
|
+
vcs.cis_stop_platform_code,
|
|
129
|
+
rs.platform_code,
|
|
130
|
+
rs.stop_name,
|
|
131
|
+
platform.stop_id AS assigned_stop_id
|
|
132
|
+
FROM ((((((( SELECT prediction.rt_trip_id,
|
|
133
|
+
prediction.stop_sequence,
|
|
134
|
+
prediction.stop_arr_delay,
|
|
135
|
+
prediction.stop_dep_delay,
|
|
136
|
+
prediction.stop_id
|
|
137
|
+
FROM public_transport.v_public_vehiclepositions_future_stop_times prediction
|
|
138
|
+
UNION ALL
|
|
139
|
+
SELECT history.rt_trip_id,
|
|
140
|
+
history.stop_sequence,
|
|
141
|
+
history.stop_arr_delay,
|
|
142
|
+
history.stop_dep_delay,
|
|
143
|
+
history.stop_id
|
|
144
|
+
FROM public_transport.v_public_vehiclepositions_past_stop_times history) stop_times
|
|
145
|
+
JOIN public_transport.vehiclepositions_trips vt ON (((vt.id)::text = (stop_times.rt_trip_id)::text)))
|
|
146
|
+
JOIN public_transport.vehiclepositions_positions vp ON (((vt.last_position_id = vp.id) AND ((vp.valid_to IS NULL) OR (vp.valid_to >= now())) AND ((vp.state_position)::text <> 'after_track'::text))))
|
|
147
|
+
JOIN public_transport.gtfs_stops rs ON (((rs.stop_id)::text = (stop_times.stop_id)::text) AND (rs.feed_id = vt.feed_id)))
|
|
148
|
+
LEFT JOIN public_transport.gtfs_cis_stops rcs ON (((rcs.id)::text = rs.computed_cis_stop_id) AND (rcs.feed_id = vt.feed_id)))
|
|
149
|
+
LEFT JOIN public_transport.vehiclepositions_cis_stops vcs ON ((((vcs.rt_trip_id)::text = (stop_times.rt_trip_id)::text) AND (vcs.cis_stop_group_id = rcs.cis) AND (vcs.feed_id = vt.feed_id))))
|
|
150
|
+
LEFT JOIN public_transport.gtfs_stops platform ON (((rs.parent_station IS NOT NULL) AND ((platform.parent_station)::text = (rs.parent_station)::text) AND ((platform.platform_code)::text = (vcs.cis_stop_platform_code)::text) AND (platform.location_type = 0) AND (platform.feed_id = vt.feed_id))))
|
|
151
|
+
ORDER BY stop_times.rt_trip_id, stop_times.stop_sequence, platform.stop_id;
|
|
@@ -32,6 +32,21 @@ let GtfsTransformation = class GtfsTransformation extends AbstractTransformation
|
|
|
32
32
|
return acc;
|
|
33
33
|
}, {});
|
|
34
34
|
const { feedId } = input;
|
|
35
|
+
// some feed exports (e.g. IDS JMK) prepend a UTF-8 BOM to every file; left in place it
|
|
36
|
+
// sticks to the first header name (e.g. "stop_id"), which then fails to match any
|
|
37
|
+
// known column and gets dropped, nulling out the whole first column (often the PK).
|
|
38
|
+
let bomChecked = false;
|
|
39
|
+
const stripBom = new stream_1.Transform({
|
|
40
|
+
transform(chunk, _encoding, callback) {
|
|
41
|
+
if (!bomChecked) {
|
|
42
|
+
bomChecked = true;
|
|
43
|
+
if (chunk.length >= 3 && chunk[0] === 0xef && chunk[1] === 0xbb && chunk[2] === 0xbf) {
|
|
44
|
+
chunk = chunk.subarray(3);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
callback(null, chunk);
|
|
48
|
+
},
|
|
49
|
+
});
|
|
35
50
|
const addColumns = new stream_1.Transform({
|
|
36
51
|
objectMode: true,
|
|
37
52
|
transform(chunk, _encoding, callback) {
|
|
@@ -51,7 +66,7 @@ let GtfsTransformation = class GtfsTransformation extends AbstractTransformation
|
|
|
51
66
|
callback();
|
|
52
67
|
},
|
|
53
68
|
});
|
|
54
|
-
const out = (0, stream_1.pipeline)(input.sourceStream, (0, csv_parser_1.default)(), addColumns, (0, csv_stringify_1.default)({ header: true }), (err) => {
|
|
69
|
+
const out = (0, stream_1.pipeline)(input.sourceStream, stripBom, (0, csv_parser_1.default)(), addColumns, (0, csv_stringify_1.default)({ header: true }), (err) => {
|
|
55
70
|
if (err) {
|
|
56
71
|
integration_engine_1.log.error(`Datasets: transformation error (${input.name}): ${err.toString()}`);
|
|
57
72
|
throw err;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GtfsTransformation.js","sourceRoot":"","sources":["../../../../src/integration-engine/gtfs/transformations/GtfsTransformation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2DAAiC;AAEjC,8EAA4D;AAC5D,6GAA0G;AAC1G,iEAAgE;AAChE,4DAA6B;AAC7B,kEAAsC;AACtC,mCAAuD;AAShD,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,+CAAyD;IAG7F;QACI,KAAK,EAAE,CAAC;QAIF,sBAAiB,GAAG,CAAC,KAA8B,EAAY,EAAE;YACvE,iEAAiE;YACjE,MAAM,4BAA4B,GAAG,MAAM,CAAC,IAAI,CAAC,WAAI,CAAC,KAAK,CAAC,IAAkB,CAAC,CAAC,yBAAyB,CAAC;iBACrG,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;iBACnD,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;gBAClB,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;gBACjB,OAAO,GAAG,CAAC;YACf,CAAC,EAAE,EAA0B,CAAC,CAAC;YAEnC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;YAEzB,MAAM,UAAU,GAAG,IAAI,kBAAS,CAAC;gBAC7B,UAAU,EAAE,IAAI;gBAChB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ;oBAChC,IAAI,CAAC,IAAI,CAAC;wBACN,sEAAsE;wBACtE,GAAG,4BAA4B;wBAC/B,kEAAkE;wBAClE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;6BAChB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,4BAA4B,CAAC;6BACpD,MAAM,CAAC,CAAC,GAAQ,EAAE,GAAG,EAAE,EAAE;4BACtB,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;4BACtB,OAAO,GAAG,CAAC;wBACf,CAAC,EAAE,EAAE,CAAC;wBACV,qEAAqE;wBACrE,OAAO,EAAE,MAAM;qBAClB,CAAC,CAAC;oBACH,QAAQ,EAAE,CAAC;gBACf,CAAC;aACJ,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,IAAA,iBAAQ,EAAC,KAAK,CAAC,YAAY,EAAE,IAAA,oBAAG,GAAE,EAAE,UAAU,EAAE,IAAA,uBAAS,EAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"GtfsTransformation.js","sourceRoot":"","sources":["../../../../src/integration-engine/gtfs/transformations/GtfsTransformation.ts"],"names":[],"mappings":"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"}
|