@golemio/pid 6.4.1-dev.3053867815 → 6.4.1-dev.3054859807
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/example/00_clear_test_data.sql +1 -0
- package/db/example/24_jis_delayed_segments.sql +142 -0
- package/db/migrations/postgresql/20261027100000-jis-delayed-segments.js +16 -0
- package/db/migrations/postgresql/sqls/20250127134438-departure-additional-indexes-down.sql +20 -2
- package/db/migrations/postgresql/sqls/20261027100000-jis-delayed-segments-down.sql +17 -0
- package/db/migrations/postgresql/sqls/20261027100000-jis-delayed-segments-up.sql +42 -0
- package/dist/integration-engine/jis/datasources/JISDelayedSegmentsDataSourceFactory.d.ts +9 -0
- package/dist/integration-engine/jis/datasources/JISDelayedSegmentsDataSourceFactory.js +54 -0
- package/dist/integration-engine/jis/datasources/JISDelayedSegmentsDataSourceFactory.js.map +1 -0
- package/dist/integration-engine/jis/ioc/Di.js +10 -0
- package/dist/integration-engine/jis/ioc/Di.js.map +1 -1
- package/dist/integration-engine/jis/ioc/JISContainerToken.d.ts +5 -0
- package/dist/integration-engine/jis/ioc/JISContainerToken.js +5 -0
- package/dist/integration-engine/jis/ioc/JISContainerToken.js.map +1 -1
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentEnrichmentRepository.d.ts +14 -0
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentEnrichmentRepository.js +69 -0
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentEnrichmentRepository.js.map +1 -0
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentsRepository.d.ts +23 -0
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentsRepository.js +73 -0
- package/dist/integration-engine/jis/repositories/JISDelayedSegmentsRepository.js.map +1 -0
- package/dist/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.d.ts +13 -0
- package/dist/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.js +266 -0
- package/dist/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.js.map +1 -0
- package/dist/integration-engine/jis/repositories/interfaces/IJISDelayedSegmentEnrichmentParams.d.ts +23 -0
- package/dist/integration-engine/jis/repositories/interfaces/IJISDelayedSegmentEnrichmentParams.js +2 -0
- package/dist/integration-engine/jis/repositories/interfaces/IJISDelayedSegmentEnrichmentParams.js.map +1 -0
- package/dist/integration-engine/jis/services/JISDelayedSegmentsDataService.d.ts +38 -0
- package/dist/integration-engine/jis/services/JISDelayedSegmentsDataService.js +174 -0
- package/dist/integration-engine/jis/services/JISDelayedSegmentsDataService.js.map +1 -0
- package/dist/integration-engine/jis/workers/JISWorker.js +1 -0
- package/dist/integration-engine/jis/workers/JISWorker.js.map +1 -1
- package/dist/integration-engine/jis/workers/tasks/RefreshDelayedSegmentsTask.d.ts +15 -0
- package/dist/integration-engine/jis/workers/tasks/RefreshDelayedSegmentsTask.js +55 -0
- package/dist/integration-engine/jis/workers/tasks/RefreshDelayedSegmentsTask.js.map +1 -0
- package/dist/output-gateway/jis/controllers/v1/V1DelayedSegmentsController.d.ts +9 -0
- package/dist/output-gateway/jis/controllers/v1/V1DelayedSegmentsController.js +54 -0
- package/dist/output-gateway/jis/controllers/v1/V1DelayedSegmentsController.js.map +1 -0
- package/dist/output-gateway/jis/data-access/JISDelayedSegmentsRepository.d.ts +14 -0
- package/dist/output-gateway/jis/data-access/JISDelayedSegmentsRepository.js +56 -0
- package/dist/output-gateway/jis/data-access/JISDelayedSegmentsRepository.js.map +1 -0
- package/dist/output-gateway/jis/domain/IJISDelayedSegmentDto.d.ts +12 -0
- package/dist/output-gateway/jis/domain/IJISDelayedSegmentDto.js +2 -0
- package/dist/output-gateway/jis/domain/IJISDelayedSegmentDto.js.map +1 -0
- package/dist/output-gateway/jis/dto/interfaces/IDelayedSegmentsQueryDto.d.ts +5 -0
- package/dist/output-gateway/jis/dto/interfaces/IDelayedSegmentsQueryDto.js +2 -0
- package/dist/output-gateway/jis/dto/interfaces/IDelayedSegmentsQueryDto.js.map +1 -0
- package/dist/output-gateway/jis/helpers/JISDelayedSegmentInfoPanelStopsFilter.d.ts +8 -0
- package/dist/output-gateway/jis/helpers/JISDelayedSegmentInfoPanelStopsFilter.js +13 -0
- package/dist/output-gateway/jis/helpers/JISDelayedSegmentInfoPanelStopsFilter.js.map +1 -0
- package/dist/output-gateway/jis/ioc/Di.js +6 -0
- package/dist/output-gateway/jis/ioc/Di.js.map +1 -1
- package/dist/output-gateway/jis/ioc/OgJisToken.d.ts +3 -0
- package/dist/output-gateway/jis/ioc/OgJisToken.js +3 -0
- package/dist/output-gateway/jis/ioc/OgJisToken.js.map +1 -1
- package/dist/output-gateway/jis/routers/v1/V1JISRouter.d.ts +2 -0
- package/dist/output-gateway/jis/routers/v1/V1JISRouter.js +9 -0
- package/dist/output-gateway/jis/routers/v1/V1JISRouter.js.map +1 -1
- package/dist/output-gateway/jis/transformations/JISDelayedSegmentsTransformation.d.ts +7 -0
- package/dist/output-gateway/jis/transformations/JISDelayedSegmentsTransformation.js +32 -0
- package/dist/output-gateway/jis/transformations/JISDelayedSegmentsTransformation.js.map +1 -0
- package/dist/schema-definitions/jis/datasources/MapaPidDelayShapesJsonSchema.d.ts +3 -0
- package/dist/schema-definitions/jis/datasources/MapaPidDelayShapesJsonSchema.js +16 -0
- package/dist/schema-definitions/jis/datasources/MapaPidDelayShapesJsonSchema.js.map +1 -0
- package/dist/schema-definitions/jis/datasources/interfaces/IMapaPidDelayShape.d.ts +10 -0
- package/dist/schema-definitions/jis/datasources/interfaces/IMapaPidDelayShape.js +2 -0
- package/dist/schema-definitions/jis/datasources/interfaces/IMapaPidDelayShape.js.map +1 -0
- package/dist/schema-definitions/jis/datasources/interfaces/index.d.ts +1 -0
- package/dist/schema-definitions/jis/datasources/interfaces/index.js +1 -0
- package/dist/schema-definitions/jis/datasources/interfaces/index.js.map +1 -1
- package/dist/schema-definitions/jis/models/JISDelayedSegmentsModel.d.ts +24 -0
- package/dist/schema-definitions/jis/models/JISDelayedSegmentsModel.js +138 -0
- package/dist/schema-definitions/jis/models/JISDelayedSegmentsModel.js.map +1 -0
- package/dist/schema-definitions/jis/models/interfaces/IJISDelayedSegment.d.ts +44 -0
- package/dist/schema-definitions/jis/models/interfaces/IJISDelayedSegment.js +2 -0
- package/dist/schema-definitions/jis/models/interfaces/IJISDelayedSegment.js.map +1 -0
- package/dist/schema-definitions/jis/models/interfaces/index.d.ts +1 -0
- package/dist/schema-definitions/jis/models/interfaces/index.js +1 -0
- package/dist/schema-definitions/jis/models/interfaces/index.js.map +1 -1
- package/docs/assets/pid_jis_erd.png +0 -0
- package/docs/asyncapi.yaml +15 -0
- package/docs/implementation_documentation.md +56 -0
- package/docs/index.md +1 -0
- package/docs/jis/delayed-segments.md +241 -0
- package/docs/jis/index.md +9 -0
- package/docs/openapi-output.yaml +176 -0
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import SequelizeCore from "@golemio/core/dist/shared/sequelize.js";
|
|
2
|
+
const { DataTypes, Model } = SequelizeCore;
|
|
3
|
+
const stopJsonSchema = {
|
|
4
|
+
type: "object",
|
|
5
|
+
properties: {
|
|
6
|
+
id: { type: "string" },
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
},
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
required: ["id", "name"],
|
|
11
|
+
};
|
|
12
|
+
export class JISDelayedSegmentsModel extends Model {
|
|
13
|
+
}
|
|
14
|
+
JISDelayedSegmentsModel.tableName = "jis_delayed_segments";
|
|
15
|
+
JISDelayedSegmentsModel.attributeModel = {
|
|
16
|
+
id: {
|
|
17
|
+
primaryKey: true,
|
|
18
|
+
type: DataTypes.TEXT,
|
|
19
|
+
allowNull: false,
|
|
20
|
+
},
|
|
21
|
+
external_from_stop_id: {
|
|
22
|
+
type: DataTypes.STRING(50),
|
|
23
|
+
allowNull: false,
|
|
24
|
+
},
|
|
25
|
+
external_to_stop_id: {
|
|
26
|
+
type: DataTypes.STRING(50),
|
|
27
|
+
allowNull: false,
|
|
28
|
+
},
|
|
29
|
+
from_stop_id: {
|
|
30
|
+
type: DataTypes.STRING(50),
|
|
31
|
+
allowNull: false,
|
|
32
|
+
},
|
|
33
|
+
from_stop_name: {
|
|
34
|
+
type: DataTypes.TEXT,
|
|
35
|
+
allowNull: false,
|
|
36
|
+
},
|
|
37
|
+
to_stop_id: {
|
|
38
|
+
type: DataTypes.STRING(50),
|
|
39
|
+
allowNull: false,
|
|
40
|
+
},
|
|
41
|
+
to_stop_name: {
|
|
42
|
+
type: DataTypes.TEXT,
|
|
43
|
+
allowNull: false,
|
|
44
|
+
},
|
|
45
|
+
expected_delay_seconds: {
|
|
46
|
+
type: DataTypes.INTEGER,
|
|
47
|
+
allowNull: false,
|
|
48
|
+
},
|
|
49
|
+
stops: {
|
|
50
|
+
type: DataTypes.JSONB,
|
|
51
|
+
allowNull: false,
|
|
52
|
+
},
|
|
53
|
+
routes: {
|
|
54
|
+
type: DataTypes.JSONB,
|
|
55
|
+
allowNull: false,
|
|
56
|
+
},
|
|
57
|
+
info_panel_stops: {
|
|
58
|
+
type: DataTypes.JSONB,
|
|
59
|
+
allowNull: false,
|
|
60
|
+
},
|
|
61
|
+
created_at: {
|
|
62
|
+
type: DataTypes.DATE,
|
|
63
|
+
allowNull: false,
|
|
64
|
+
},
|
|
65
|
+
updated_at: {
|
|
66
|
+
type: DataTypes.DATE,
|
|
67
|
+
allowNull: false,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
JISDelayedSegmentsModel.jsonSchema = {
|
|
71
|
+
type: "array",
|
|
72
|
+
items: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {
|
|
75
|
+
id: { type: "string" },
|
|
76
|
+
external_from_stop_id: { type: "string" },
|
|
77
|
+
external_to_stop_id: { type: "string" },
|
|
78
|
+
from_stop_id: { type: "string" },
|
|
79
|
+
from_stop_name: { type: "string" },
|
|
80
|
+
to_stop_id: { type: "string" },
|
|
81
|
+
to_stop_name: { type: "string" },
|
|
82
|
+
expected_delay_seconds: { type: "integer" },
|
|
83
|
+
stops: { type: "array", items: stopJsonSchema },
|
|
84
|
+
routes: {
|
|
85
|
+
type: "array",
|
|
86
|
+
items: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
id: { type: "string" },
|
|
90
|
+
short_name: { type: "string" },
|
|
91
|
+
type: { type: "integer" },
|
|
92
|
+
},
|
|
93
|
+
additionalProperties: false,
|
|
94
|
+
required: ["id", "short_name", "type"],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
info_panel_stops: {
|
|
98
|
+
type: "array",
|
|
99
|
+
items: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
stop: stopJsonSchema,
|
|
103
|
+
preset_route_names: { type: "array", items: { type: "string" } },
|
|
104
|
+
routes: {
|
|
105
|
+
type: "array",
|
|
106
|
+
items: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
id: { type: "string" },
|
|
110
|
+
distance_stops: { type: "integer" },
|
|
111
|
+
},
|
|
112
|
+
additionalProperties: false,
|
|
113
|
+
required: ["id", "distance_stops"],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
required: ["stop", "preset_route_names", "routes"],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
required: [
|
|
124
|
+
"id",
|
|
125
|
+
"external_from_stop_id",
|
|
126
|
+
"external_to_stop_id",
|
|
127
|
+
"from_stop_id",
|
|
128
|
+
"from_stop_name",
|
|
129
|
+
"to_stop_id",
|
|
130
|
+
"to_stop_name",
|
|
131
|
+
"expected_delay_seconds",
|
|
132
|
+
"stops",
|
|
133
|
+
"routes",
|
|
134
|
+
"info_panel_stops",
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=JISDelayedSegmentsModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JISDelayedSegmentsModel.js","sourceRoot":"","sources":["../../../../src/schema-definitions/jis/models/JISDelayedSegmentsModel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface IJISDelayedSegmentStop {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export interface IJISDelayedSegmentRoute {
|
|
6
|
+
id: string;
|
|
7
|
+
short_name: string;
|
|
8
|
+
type: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Route passing an info panel stop, with the signed distance of the stop from the segment
|
|
12
|
+
* (negative before the segment, 0 inside, positive after it, in stops along the route)
|
|
13
|
+
*/
|
|
14
|
+
export interface IJISDelayedSegmentInfoPanelRoute {
|
|
15
|
+
id: string;
|
|
16
|
+
distance_stops: number;
|
|
17
|
+
}
|
|
18
|
+
export interface IJISDelayedSegmentInfoPanelStop {
|
|
19
|
+
stop: IJISDelayedSegmentStop;
|
|
20
|
+
preset_route_names: string[];
|
|
21
|
+
routes: IJISDelayedSegmentInfoPanelRoute[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Stops, routes and info panels of a delayed segment derived from GTFS
|
|
25
|
+
*/
|
|
26
|
+
export interface IJISDelayedSegmentEnrichment extends Pick<IJISDelayedSegment, "stops" | "routes" | "info_panel_stops"> {
|
|
27
|
+
/** Whether both endpoints exist in GTFS; endpoints without stops then mean that no trip runs the whole segment */
|
|
28
|
+
has_endpoint_stops: boolean;
|
|
29
|
+
from_stop: IJISDelayedSegmentStop | null;
|
|
30
|
+
to_stop: IJISDelayedSegmentStop | null;
|
|
31
|
+
}
|
|
32
|
+
export interface IJISDelayedSegment {
|
|
33
|
+
id: string;
|
|
34
|
+
external_from_stop_id: string;
|
|
35
|
+
external_to_stop_id: string;
|
|
36
|
+
from_stop_id: string;
|
|
37
|
+
from_stop_name: string;
|
|
38
|
+
to_stop_id: string;
|
|
39
|
+
to_stop_name: string;
|
|
40
|
+
expected_delay_seconds: number;
|
|
41
|
+
stops: IJISDelayedSegmentStop[];
|
|
42
|
+
routes: IJISDelayedSegmentRoute[];
|
|
43
|
+
info_panel_stops: IJISDelayedSegmentInfoPanelStop[];
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IJISDelayedSegment.js","sourceRoot":"","sources":["../../../../../src/schema-definitions/jis/models/interfaces/IJISDelayedSegment.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/schema-definitions/jis/models/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/schema-definitions/jis/models/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC"}
|
|
Binary file
|
package/docs/asyncapi.yaml
CHANGED
|
@@ -84,6 +84,17 @@ channels:
|
|
|
84
84
|
messages:
|
|
85
85
|
data:
|
|
86
86
|
$ref: "#/components/messages/JISEvents"
|
|
87
|
+
jis.refreshDelayedSegments:
|
|
88
|
+
address: vehicle-positions.jis.refreshDelayedSegments
|
|
89
|
+
description: Fetch delayed segments from Mapa PID, enrich them with GTFS data and refresh them in database
|
|
90
|
+
bindings:
|
|
91
|
+
amqp:
|
|
92
|
+
is: queue
|
|
93
|
+
queue:
|
|
94
|
+
durable: true
|
|
95
|
+
messages:
|
|
96
|
+
empty:
|
|
97
|
+
$ref: "#/components/messages/emptyMessage"
|
|
87
98
|
ropidgtfs.refreshPublicGtfsDepartureCache:
|
|
88
99
|
address: vehicle-positions.ropidgtfs.refreshPublicGtfsDepartureCache
|
|
89
100
|
description: Refresh PublicGtfsDepartureCache
|
|
@@ -382,6 +393,10 @@ operations:
|
|
|
382
393
|
action: "send"
|
|
383
394
|
channel:
|
|
384
395
|
$ref: "#/channels/jis.updateEventWebhook"
|
|
396
|
+
jis.refreshDelayedSegments:
|
|
397
|
+
action: "send"
|
|
398
|
+
channel:
|
|
399
|
+
$ref: "#/channels/jis.refreshDelayedSegments"
|
|
385
400
|
ropidgtfs.refreshPublicGtfsDepartureCache:
|
|
386
401
|
action: "send"
|
|
387
402
|
channel:
|
|
@@ -241,6 +241,26 @@ _:warning: Původním záměrem bylo využití OIS číselníku během zpracová
|
|
|
241
241
|
- název rabbitmq fronty
|
|
242
242
|
- vehicle-positions.jis.fetchJISInfotexts
|
|
243
243
|
|
|
244
|
+
#### _Mapa PID – zpožděné úseky_
|
|
245
|
+
|
|
246
|
+
- zdroj dat
|
|
247
|
+
- url: module.pid.jis.delayedSegments.url
|
|
248
|
+
- interní endpoint webové [Mapy PID](https://mapa.pid.cz/), POST požadavek bez vozidel a tvarů úseků (prázdné `bounds`, `show_delay_sections: false`); zpožděné úseky vrací vždy pro celou síť
|
|
249
|
+
- formát dat
|
|
250
|
+
- protokol: http
|
|
251
|
+
- datový typ: json
|
|
252
|
+
- validační schéma: [MapaPidDelayShapesJsonSchema](../src/schema-definitions/jis/datasources/MapaPidDelayShapesJsonSchema.ts)
|
|
253
|
+
- příklad vstupních dat: [JISDelayedSegmentsDataSourceFactory.unit.test.ts](../test/integration-engine/jis/datasources/JISDelayedSegmentsDataSourceFactory.unit.test.ts)
|
|
254
|
+
- frekvence stahování
|
|
255
|
+
- cron definice:
|
|
256
|
+
- cron.vehicle-positions.jis.refreshDelayedSegments
|
|
257
|
+
- rabin `0 */5 * * * *`
|
|
258
|
+
- prod `0 */5 * * * *`
|
|
259
|
+
- název rabbitmq fronty
|
|
260
|
+
- vehicle-positions.jis.refreshDelayedSegments
|
|
261
|
+
- omezení
|
|
262
|
+
- odpověď neobsahuje čas výpočtu úseků; pokud Mapa PID přestane úseky přepočítávat, vrací poslední známý stav (až 24 hodin) a ten se u nás dál jeví jako aktuální
|
|
263
|
+
|
|
244
264
|
### _Ropid staticka data_
|
|
245
265
|
|
|
246
266
|
- zdroj dat
|
|
@@ -1313,6 +1333,30 @@ Worker má na starost stahování VYMI (JIS) událostí a infotextů, jejich tra
|
|
|
1313
1333
|
- data modely
|
|
1314
1334
|
- žádné
|
|
1315
1335
|
|
|
1336
|
+
#### _task: RefreshDelayedSegmentsTask_
|
|
1337
|
+
|
|
1338
|
+
Záměr, architekturu a algoritmus podrobně popisuje [jis/delayed-segments.md](./jis/delayed-segments.md).
|
|
1339
|
+
|
|
1340
|
+
- vstupní rabbitmq fronta
|
|
1341
|
+
- název: vehicle-positions.jis.refreshDelayedSegments
|
|
1342
|
+
- TTL: 4 minuty
|
|
1343
|
+
- parametry: žádné
|
|
1344
|
+
- závislé fronty (do kterých jsou odesílány zprávy z metody workeru)
|
|
1345
|
+
- žádné
|
|
1346
|
+
- datové zdroje
|
|
1347
|
+
- Mapa PID (zpožděné úseky)
|
|
1348
|
+
- `ropidgtfs_precomputed_departures`, `ropidgtfs_trips`, `ropidgtfs_stops`, `ropid_departures_presets`, `ropid_departures_presets_ropidgtfs_stops`
|
|
1349
|
+
- transformace
|
|
1350
|
+
- úseky se zpožděním pod `module.pid.jis.delayedSegments.minDelaySeconds` (výchozí 300 s) se zahazují
|
|
1351
|
+
- krajní zastávky se převádí na ASW id (`uzel/sloupek`), z nichž se skládá id úseku; úseky bez ASW id (např. železniční body `T…`) se zahazují
|
|
1352
|
+
- úseky se obohatí o GTFS data, všechny jedním dotazem ([JISDelayedSegmentEnrichmentQuery](../src/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.ts)); uvažují se pouze odjezdy v okně ± `module.pid.jis.delayedSegments.routeTimeWindowMinutes` (výchozí 120 min) od stažení a pravidelné spoje (`exceptional = 0`):
|
|
1353
|
+
- zastávky úseku – zastávky mezi krajními zastávkami na spojích projíždějících celý úsek, sloučené podle ASW id (reprezentované abecedně prvním stop id ze všech variant v GTFS, aby se neměnilo mezi běhy), seřazené podél úseku
|
|
1354
|
+
- dotčené linky – linky se spojem, který projede alespoň jeden mezizastávkový úsek ve směru úseku
|
|
1355
|
+
- zastávky s panely – zastávky s presetem odjezdové tabule (párované podle ASW id) do vzdálenosti `module.pid.jis.delayedSegments.maxInfoPanelDistanceStops` (výchozí 5) zastávek od úseku podél dotčených spojů; pro každou linku se uvádí vzdálenost se znaménkem (záporná před úsekem, 0 v úseku, kladná za úsekem), nejbližší k úseku; vzdálenost se počítá jako rozdíl `stop_sequence`, což předpokládá souvislé číslování zastávek spoje (platí pro všechny spoje PID); mezera v číslování by vzdálenost zvětšila o svou délku
|
|
1356
|
+
- zahazují se úseky, jejichž krajní zastávky nejsou v GTFS, úseky, které v časovém okně celé neprojíždí žádný spoj (Mapa PID slučuje navazující úseky různých linek), a úseky bez dotčených linek; počty vyřazených úseků podle důvodu se logují při každém běhu
|
|
1357
|
+
- data modely
|
|
1358
|
+
- Model `jis_delayed_segments` – při každém úspěšném stažení se nahradí celý obsah; `created_at` je začátek aktuální nepřerušené detekce úseku (úsek chybějící v úspěšném stažení se smaže a při dalším výskytu začíná znovu), `updated_at` čas poslední; při chybě stažení zůstávají data beze změny
|
|
1359
|
+
|
|
1316
1360
|
## Uložení dat
|
|
1317
1361
|
|
|
1318
1362
|
- typ databáze
|
|
@@ -1344,6 +1388,7 @@ Worker má na starost stahování VYMI (JIS) událostí a infotextů, jejich tra
|
|
|
1344
1388
|
- popis vozidel se nepromazává – přetrvávají do přepsání novými daty (fixní TTL bylo odstraněno)
|
|
1345
1389
|
- preset logy si uchováváme 8 hodin
|
|
1346
1390
|
- JIS události si uchováváme neomezeně; JIS infotexty jen dokud jsou v posledním přijatém seznamu z VYMI (chybějící se při každém přenačtení mažou)
|
|
1391
|
+
- zpožděné úseky jen dokud jsou v posledním úspěšně staženém seznamu z Mapy PID
|
|
1347
1392
|
|
|
1348
1393
|
## Input API
|
|
1349
1394
|
|
|
@@ -1622,3 +1667,14 @@ Worker má na starost stahování VYMI (JIS) událostí a infotextů, jejich tra
|
|
|
1622
1667
|
- zdrojové tabulky: `jis_events`, `jis_events_ropidgtfs_routes`
|
|
1623
1668
|
- formát odpovědi: viz schéma `EventCustomFormat` v [openapi-output.yaml](./openapi-output.yaml)
|
|
1624
1669
|
- trasy v `informed_entity.routes` jsou snapshot-first (`jis_events_ropidgtfs_routes.route_details`), s GTFS fallbackem (`ropidgtfs_routes`) jen pro starší řádky bez snímku; podrobněji viz [jis/index.md](./jis/index.md#informed_entityroutesroute_details-snímek-gtfs-atributů-trasy)
|
|
1670
|
+
|
|
1671
|
+
#### _/v1/jis/delayed-segments_
|
|
1672
|
+
|
|
1673
|
+
- interní endpoint pro VYMI, vrací aktuální zpožděné úseky obohacené o GTFS data (viz [RefreshDelayedSegmentsTask](#task-refreshdelayedsegmentstask) a [jis/delayed-segments.md](./jis/delayed-segments.md#kontrakt-api))
|
|
1674
|
+
- úseky v čase rostou a zmenšují se, `id` (odvozené od krajních zastávek) proto není stabilní identifikace úseku; úseky se mají párovat podle zastávek
|
|
1675
|
+
- při chybě stažení se úseky nemažou a jejich `last_detected_at` se přestane posouvat, aktuálnost je proto třeba posuzovat podle něj; zaseknutý výpočet na straně Mapy PID tím rozpoznat nelze (viz omezení zdroje)
|
|
1676
|
+
- parametry (volitelné, jen zužují uložená data):
|
|
1677
|
+
- `minDelaySeconds` – minimální `expected_delay_seconds` úseku
|
|
1678
|
+
- `minDistanceStops`, `maxDistanceStops` – rozsah `distance_stops` linek zastávek s panely včetně; zastávky bez linky v rozsahu se vynechají
|
|
1679
|
+
- zdrojové tabulky: `jis_delayed_segments`
|
|
1680
|
+
- formát odpovědi: viz schéma `JISDelayedSegment` v [openapi-output.yaml](./openapi-output.yaml)
|
package/docs/index.md
CHANGED
|
@@ -28,6 +28,7 @@ PID Polohy je soubor služeb datové platformy [Golemio](https://golemio.cz/) na
|
|
|
28
28
|
- [Upřesňující popis architektury platformy Golemio]
|
|
29
29
|
- Podrobná dokumentace:
|
|
30
30
|
- [Dokumentace propisu VYMI dat do datové platformy Golemio]
|
|
31
|
+
- [Zpožděné úseky – podklad pro automatické infotexty](./jis/delayed-segments.md)
|
|
31
32
|
- [Dokumentace zpracování RT dat](./processing/index.md)
|
|
32
33
|
- [Vstupní data HTTP MPVnet (autobusy mimo DPP, přívozy, vlaky)](./processing/input_realtime_data/http_mpvnet.md)
|
|
33
34
|
- [Vstupní data TCP DPP tramvaje](./processing/input_realtime_data/tcp_dpp_tram.md)
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Zpožděné úseky – podklad pro automatické infotexty
|
|
2
|
+
|
|
3
|
+
Stránka popisuje, jak datová platforma Golemio připravuje pro VYMI podklad pro automatické infotexty o zpožděných úsecích sítě PID ([vymi-general#365](https://gitlab.com/operator-ict/golemio/jis/vymi-alerts/vymi-general/-/work_items/365)): záměr, architekturu řešení, algoritmus zpracování, datový model, výstupní API, výkon, konfiguraci, provoz, známá omezení a klíčová rozhodnutí. Stručný přehled pro odběratele je v [index.md](./index.md#zpožděné-úseky--podklad-pro-automatické-infotexty-get-v1jisdelayed-segments), technické údaje workeru a endpointu v [implementační dokumentaci](../implementation_documentation.md#task-refreshdelayedsegmentstask).
|
|
4
|
+
|
|
5
|
+
## Záměr
|
|
6
|
+
|
|
7
|
+
Při velkém zpoždění na úseku sítě (typicky kolona nebo nehoda) mají cestující na odjezdových tabulích dostat informaci, že spoje určitých linek v daném místě nabírají zpoždění. Dispečeři ROPID takové infotexty dnes zadávají ručně. Cílem je, aby je VYMI navrhovalo nebo zakládalo automaticky.
|
|
8
|
+
|
|
9
|
+
Zpožděné úseky již počítá webová [Mapa PID](https://mapa.pid.cz/) z poloh vozidel Golemia, samotná informace o úseku ale pro infotext nestačí. Je třeba vědět, které linky úsekem jezdí a na kterých zastávkách s odjezdovými tabulemi má smysl infotext zobrazit. Odpovědnosti jsou proto rozděleny takto:
|
|
10
|
+
|
|
11
|
+
| Kdo | Odpovědnost |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| Mapa PID | detekce zpožděných úseků a odhad zpoždění |
|
|
14
|
+
| Golemio (modul pid) | pravidelné stažení úseků, obohacení o GTFS data (zastávky úseku, dotčené linky, zastávky s tabulemi a jejich vzdálenost od úseku), uložení a poskytnutí přes interní API |
|
|
15
|
+
| VYMI | párování úseků v čase, rozhodnutí o vzniku, úpravě a ukončení události a infotextů, jejich text a výběr tabulí |
|
|
16
|
+
|
|
17
|
+
Golemio tedy nerozhoduje o infotextech, poskytuje jen fakta potřebná k rozhodnutí. VYMI si úseky stahuje každých 5 minut a zakládá z nich interní události s infotexty jménem uživatele `OICT_Robot`; ve zkušebním provozu jen u úseků poblíž testovacích zastávek (Vozovna Střešovice B 876/2, U Památníku B 789/2) a za přepínačem v konfiguraci, podrobně viz [dokumentace VYMI](https://gitlab.com/operator-ict/golemio/jis/vymi-alerts/vymi-alerts-backend/-/blob/master/docs/delayed-segments.md). Rozhraní je navrženo nezávisle na zdroji úseků (viz [Kontrakt API](#kontrakt-api)), aby šlo zdroj v budoucnu vyměnit nebo doplnit bez změny pro VYMI.
|
|
18
|
+
|
|
19
|
+
## Architektura
|
|
20
|
+
|
|
21
|
+
```mermaid
|
|
22
|
+
flowchart LR
|
|
23
|
+
mapa["Mapa PID<br/>(detekce zpožděných úseků)"]
|
|
24
|
+
cron["Cron Tasks<br/>(každých 5 minut)"]
|
|
25
|
+
rabbit[("RabbitMQ<br/>vehicle-positions.jis.refreshDelayedSegments")]
|
|
26
|
+
ie["VP Integration Engine<br/>RefreshDelayedSegmentsTask"]
|
|
27
|
+
pg[("PostgreSQL<br/>jis_delayed_segments<br/>+ GTFS tabulky")]
|
|
28
|
+
og["VP Output Gateway<br/>GET /v1/jis/delayed-segments"]
|
|
29
|
+
proxy["Access Proxy<br/>(interní role)"]
|
|
30
|
+
vymi["VYMI<br/>(automatické infotexty)"]
|
|
31
|
+
|
|
32
|
+
cron --> rabbit --> ie
|
|
33
|
+
mapa -. "HTTP JSON" .-> ie
|
|
34
|
+
ie <--> pg
|
|
35
|
+
pg -. "čtení" .-> og
|
|
36
|
+
vymi -. "HTTP JSON" .-> proxy -.-> og
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Plná šipka znamená aktivní posílání, přerušovaná stahování příjemcem. Integration Engine si úseky z Mapy PID stahuje, obohacuje je dotazem nad GTFS daty ve stejné databázi a výsledek ukládá do tabulky `jis_delayed_segments`. Output Gateway tabulku jen čte. VYMI si data stahuje z interního endpointu, přístup je omezen rolí v Access Proxy.
|
|
40
|
+
|
|
41
|
+
Průběh jednoho běhu:
|
|
42
|
+
|
|
43
|
+
```mermaid
|
|
44
|
+
sequenceDiagram
|
|
45
|
+
participant cron as Cron Tasks
|
|
46
|
+
participant task as RefreshDelayedSegmentsTask
|
|
47
|
+
participant db as PostgreSQL
|
|
48
|
+
participant mapa as Mapa PID
|
|
49
|
+
|
|
50
|
+
cron->>task: zpráva do fronty (každých 5 minut)
|
|
51
|
+
task->>task: detectedAt = čas stažení
|
|
52
|
+
task->>mapa: POST bez vozidel a tvarů úseků
|
|
53
|
+
mapa-->>task: zpožděné úseky celé sítě
|
|
54
|
+
task->>task: filtr podle zpoždění, převod krajních zastávek na ASW id
|
|
55
|
+
task->>db: úseky s obohacením mladším než TTL
|
|
56
|
+
db-->>task: znovupoužitelná obohacení
|
|
57
|
+
task->>db: obohacení ostatních úseků (jeden dotaz pro všechny)
|
|
58
|
+
db-->>task: zastávky, linky, zastávky s tabulemi
|
|
59
|
+
task->>db: v transakci upsert všech úseků a smazání nedetekovaných
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Zdroj dat: Mapa PID
|
|
63
|
+
|
|
64
|
+
Mapa PID počítá zpožděné úseky průběžně z poloh vozidel. Úsek vzniká sloučením navazujících zpožděných mezizastávkových úseků, jeho odhadované zpoždění (`expected_delay`, v sekundách) je součtem zpoždění sloučených částí. Úseky se proto v čase prodlužují, zkracují a štěpí.
|
|
65
|
+
|
|
66
|
+
Golemio volá interní endpoint webové Mapy PID (adresa je jen v konfiguraci, `module.pid.jis.delayedSegments.url`). Endpoint vrací zpožděné úseky vždy pro celou síť bez ohledu na zobrazenou oblast mapy. Požadavek proto posílá prázdnou oblast (`bounds`) a vypnuté tvary úseků (`show_delay_sections: false`), aby odpověď neobsahovala vozidla ani geometrie a byla co nejmenší. Z odpovědi se používá jen pole `delay_shapes`, validované schématem [MapaPidDelayShapesJsonSchema](../../src/schema-definitions/jis/datasources/MapaPidDelayShapesJsonSchema.ts). Krajní zastávky úseku jsou v něm identifikované stop id ve formátu Mapy PID (např. `U1347Z2`, železniční body `T…`).
|
|
67
|
+
|
|
68
|
+
Endpoint není veřejné API. Úpravy na straně Mapy PID nejsou v naší moci, řešení proto pracuje s jeho současným chováním (viz [Známá omezení](#známá-omezení-a-rizika)).
|
|
69
|
+
|
|
70
|
+
## Zpracování
|
|
71
|
+
|
|
72
|
+
Zpracování obstarává [RefreshDelayedSegmentsTask](../../src/integration-engine/jis/workers/tasks/RefreshDelayedSegmentsTask.ts) a [JISDelayedSegmentsDataService](../../src/integration-engine/jis/services/JISDelayedSegmentsDataService.ts):
|
|
73
|
+
|
|
74
|
+
1. **Čas detekce.** Před stažením se zaznamená `detectedAt`. Všechny úseky jednoho běhu mají stejný čas poslední detekce a od něj se počítá i časové okno obohacení.
|
|
75
|
+
2. **Stažení.** Chyba stažení nebo neplatná odpověď ukončí běh chybou a uložené úseky zůstanou beze změny. Prázdný seznam úseků je platná odpověď a uložené úseky smaže.
|
|
76
|
+
3. **Filtr podle zpoždění.** Úseky se zpožděním pod `minDelaySeconds` (výchozí 300 s) se zahodí. VYMI si minimum zvyšuje parametrem `minDelaySeconds` endpointu (viz [Kontrakt API](#kontrakt-api)).
|
|
77
|
+
4. **Krajní zastávky na ASW id.** Stop id Mapy PID se převede na ASW id (`uzel/sloupek`, např. `U1347Z2` → `1347/2`). Z ASW id krajních zastávek se skládá `id` úseku `{uzel}/{sloupek}-{uzel}/{sloupek}`. Úseky, jejichž krajní zastávky ASW id nemají (železniční body `T…`), se zahodí.
|
|
78
|
+
5. **Obohacení.** Všechny úseky se v každém běhu obohatí jedním dotazem (viz [Obohacení](#obohacení)), každé `id` jen jednou. Obohacené úseky by šly pro optimalizaci cachovat, ale v prvotní implementaci to bylo prozatím vynecháno (bude-li v budoucnu potřeba, lze najít hotovou implementaci v Git historii).
|
|
79
|
+
6. **Vyřazení a duplicity.** Úsek se zahodí, pokud jeho krajní zastávky v GTFS neexistují, pokud ho v časovém okně žádný spoj neprojíždí celý (viz [Známá omezení](#známá-omezení-a-rizika)) nebo pokud nemá dotčené linky. Vyřazené úseky se počítají podle důvodu. Varianty stop id jedné fyzické zastávky mohou vést na stejné `id`; z duplicit se ponechá úsek s největším zpožděním.
|
|
80
|
+
7. **Uložení.** V jedné transakci se všechny úseky upsertují (`updated_at = detectedAt`, `created_at` zůstává z první detekce) a úseky, které v běhu nebyly, se smažou. Úsek, který se později znovu objeví, začíná s novým `created_at`, stejně jako úsek se změněným `id`; `first_detected_at` je proto začátek aktuální nepřerušené detekce.
|
|
81
|
+
|
|
82
|
+
## Obohacení
|
|
83
|
+
|
|
84
|
+
Obohacení odvozuje z GTFS dat (předpočítané odjezdy `ropidgtfs_precomputed_departures`, spoje, zastávky a presety odjezdových tabulí) tři údaje. Počítá je dotaz [JISDelayedSegmentEnrichmentQuery](../../src/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.ts) najednou pro všechny úseky běhu. Uvažují se jen odjezdy v okně ± `routeTimeWindowMinutes` (výchozí 120 min) od `detectedAt` a jen pravidelné spoje (`exceptional = 0`; výjimečné spoje jsou jednorázové spoje na konkrétní den, např. náhradní doprava). Okno zasahuje i do minulosti, protože zpožděný spoj s odjezdem plánovaným dříve může být v úseku ještě teď (spoj plánovaný na 13:00 může úsekem projíždět ve 13:45).
|
|
85
|
+
|
|
86
|
+
**Párování podle ASW id.** Jedna fyzická zastávka může mít v GTFS více stop id (zónové a dočasné varianty, např. `U9904Z1P` a `U9904Z1`), presety tabulí přitom bývají přiřazené jen k jedné z nich. Zastávky se proto všude párují podle ASW id, nikoli podle GTFS stop id.
|
|
87
|
+
|
|
88
|
+
### Zastávky úseku
|
|
89
|
+
|
|
90
|
+
Zastávky mezi krajními zastávkami (včetně nich) na spojích, které v časovém okně projíždějí celý úsek, sloučené podle ASW id a seřazené podél úseku. Pořadí určuje relativní poloha zastávky na spoji (0 na začátku úseku, 1 na konci), nejmenší ze všech spojů, aby se spoje vynechávající některé zastávky (např. rychlík A→D a zastávkový spoj A→B→C→D) shodly na krajních zastávkách. Pokud dvě větve úseku řadí společnou zastávku různě daleko od začátku, může být pořadí zastávek mezi větvemi přeházené; párování ve VYMI pořadí nepoužívá. Úsek, kterým v okně žádný spoj celý neprojíždí, nemá zastávky ani dotčené linky a zahodí se. Zastávku úseku reprezentuje abecedně první GTFS stop id ze všech jejích variant, nejen z těch, které obsluhují spoje v okně, aby se id mezi běhy neměnilo (VYMI podle něj páruje úseky). Zastávky bez ASW id (např. železniční body `T…`) mezi zastávky úseku nepatří.
|
|
91
|
+
|
|
92
|
+
### Dotčené linky
|
|
93
|
+
|
|
94
|
+
Linky, jejichž spoj v časovém okně projede alespoň jeden mezizastávkový úsek mezi dvěma zastávkami úseku, a to ve směru úseku. Směr se neurčuje z pořadí zastávek úseku, ale z dvojic zastávek, které některý spoj jedoucí celým úsekem navštíví v tomto pořadí; platí tak i pro větve, které společnou zastávku řadí různě. Spoj tedy nemusí jet celým úsekem. Linka, která úseku jen dotkne krajní zastávkou nebo jede opačným směrem, dotčená není.
|
|
95
|
+
|
|
96
|
+
### Zastávky s tabulemi a jejich vzdálenost
|
|
97
|
+
|
|
98
|
+
Zastávky s presetem odjezdové tabule na dotčených spojích do vzdálenosti `maxInfoPanelDistanceStops` (výchozí 5) zastávek od úseku. Pro každou zastávku se uvádí seznam presetů a pro každou dotčenou linku vzdálenost od úseku ve stanicích se znaménkem:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
spoj linky X: P0 ─ P1 ─ P2 ─ [A ─ B ─ C ─ D] ─ N1
|
|
102
|
+
vzdálenost: -3 -2 -1 0 0 0 0 +1
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Záporná vzdálenost je před úsekem (tabule, kde cestující nastupují do spojů, které teprve úsekem pojedou), nula v úseku, kladná za úsekem. Pokud spoje jedné linky dávají různé vzdálenosti (např. různé trasy), ponechá se ta nejbližší k úseku. Které tabule dostanou infotext, rozhoduje VYMI: rozsah vzdáleností (výchozí −2 až +2 zastávky) posílá v parametrech `minDistanceStops` a `maxDistanceStops` endpointu a dostane jen tabule v něm.
|
|
106
|
+
|
|
107
|
+
**Vzdálenost jako rozdíl `stop_sequence`.** Vzdálenost se počítá jako rozdíl pořadí zastávky ve spoji (`stop_sequence`) od první, resp. poslední zastávky spoje na úseku. To předpokládá souvislé číslování zastávek spoje, což platí pro všechny spoje PID (ověřeno na všech 127 635 spojodnech produkčních dat v říjnu 2026). Pokud by číslování mezeru mělo, vzdálenost se zvětší o její délku a tabule může vypadnout z limitu. Přesné pořadí by vyžadovalo seřadit všechny zastávky všech dotčených spojů, což byla nejdražší část dotazu (viz [Výkon](#výkon)).
|
|
108
|
+
|
|
109
|
+
## Datový model
|
|
110
|
+
|
|
111
|
+
Tabulka `jis_delayed_segments` (migrace `20261027100000-jis-delayed-segments`), jeden řádek na aktuálně detekovaný úsek:
|
|
112
|
+
|
|
113
|
+
| Sloupec | Typ | Popis |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| `id` | `text` | složené z ASW id krajních zastávek `{uzel}/{sloupek}-{uzel}/{sloupek}` |
|
|
116
|
+
| `external_from_stop_id`, `external_to_stop_id` | `varchar(50)` | krajní zastávky ve formátu zdroje, pro dohledání problémů |
|
|
117
|
+
| `from_stop_id`, `from_stop_name`, `to_stop_id`, `to_stop_name` | `varchar(50)`, `text` | krajní zastávky jako GTFS zastávky |
|
|
118
|
+
| `expected_delay_seconds` | `integer` | odhadované zpoždění úseku |
|
|
119
|
+
| `stops`, `routes`, `info_panel_stops` | `jsonb` | obohacení, struktura odpovídá API |
|
|
120
|
+
| `created_at`, `updated_at` | `timestamptz` | začátek aktuální nepřerušené detekce úseku a poslední detekce |
|
|
121
|
+
|
|
122
|
+
Databázové schéma záměrně nezmiňuje Mapu PID, zdroj je v komentářích sloupců popsán obecně. Úseky se uchovávají jen dokud jsou v posledním úspěšně staženém seznamu.
|
|
123
|
+
|
|
124
|
+
Pro obohacení byl index `ropidgtfs_precomputed_departures (stop_id)` nahrazen indexem `(stop_id, departure_datetime)`, který stejně dobře slouží dotazům jen podle zastávky (např. odjezdové tabule). Tabulka předpočítaných odjezdů se při každém importu GTFS vytváří znovu jako `LIKE … including all`, index se tedy přenáší automaticky. Názvy indexů se ale při importech mění, migrace proto index hledá podle sloupců, ne podle názvu, a skončí chybou, pokud takový index není právě jeden. Migrace nový index nejdříve vytvoří a starý smaže až na konci: smazání drží výhradní zámek tabulky až do konce migrace a při opačném pořadí by odjezdové tabule čekaly po celou dobu stavby indexu (na produkčních datech ~3 s).
|
|
125
|
+
|
|
126
|
+
## Kontrakt API
|
|
127
|
+
|
|
128
|
+
`GET /v1/jis/delayed-segments` (Output Gateway, tag `⚠ JIS (v1) - internal`) vrací uložené úseky seřazené od největšího zpoždění. Volitelné parametry je zužují:
|
|
129
|
+
|
|
130
|
+
- `minDelaySeconds` – jen úseky se zpožděním alespoň takovým,
|
|
131
|
+
- `minDistanceStops`, `maxDistanceStops` – u zastávek s tabulemi jen linky se vzdáleností (`distance_stops`) v tomto rozsahu včetně; zastávky bez takové linky se vynechají.
|
|
132
|
+
|
|
133
|
+
Parametry mohou data jen zúžit: úseky se zpožděním pod `minDelaySeconds` a tabule dál než `maxInfoPanelDistanceStops` z konfigurace Integration Engine se vůbec neukládají. Filtrovat v Output Gateway místo ve VYMI znamená, že VYMI nestahuje data, která by zahodilo, a nastavení filtrů zůstává na jednom místě ve VYMI. Schéma je v [openapi-output.yaml](../openapi-output.yaml) (`JISDelayedSegment`). Odpověď je cachovaná 5 s (`s-maxage=5, stale-while-revalidate=5`).
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"id": "9903/1-9906/1",
|
|
138
|
+
"from_stop": { "id": "U9903Z1P", "name": "Zastávka A" },
|
|
139
|
+
"to_stop": { "id": "U9906Z1P", "name": "Zastávka D" },
|
|
140
|
+
"expected_delay_seconds": 900,
|
|
141
|
+
"first_detected_at": "2026-10-27T08:50:00.000Z",
|
|
142
|
+
"last_detected_at": "2026-10-27T09:00:00.000Z",
|
|
143
|
+
"stops": [{ "id": "U9903Z1P", "name": "Zastávka A" }, "…"],
|
|
144
|
+
"routes": [{ "id": "L9901", "short_name": "9901", "type": 3 }],
|
|
145
|
+
"info_panel_stops": [
|
|
146
|
+
{
|
|
147
|
+
"stop": { "id": "U9901Z1P", "name": "Zastávka P1" },
|
|
148
|
+
"preset_route_names": ["preset-p1"],
|
|
149
|
+
"routes": [{ "id": "L9901", "distance_stops": -2 }]
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Zásady kontraktu:
|
|
156
|
+
|
|
157
|
+
- **Nezávislost na zdroji.** API neobsahuje nic specifického pro Mapu PID (ani její stop id), všechny zastávky a linky jsou GTFS entity. Zdroj úseků lze vyměnit bez změny kontraktu.
|
|
158
|
+
- **`id` není stabilní identifikace.** Úseky v čase rostou, zkracují se a štěpí, `id` se tím mění. VYMI páruje úseky mezi běhy podle `stops`: úsek pokračuje sledovanou kongesci, pokud s ní sdílí alespoň dvě zastávky (dvojice 1:1, větší překryv dřív). Zastávky jsou GTFS stop id abecedně první ze všech variant zastávky v GTFS, nezávisle na tom, které varianty obsluhují spoje v časovém okně; id se tak změní jen se změnou zastávek v GTFS (např. přibude varianta řazená dřív), a i pak jedna změněná zastávka párování podle dvou společných zastávek nerozbije.
|
|
159
|
+
- **Id zastávky s tabulí je id varianty s presetem.** `info_panel_stops[].stop.id` je varianta, ke které je přiřazen preset, a může se lišit od id stejné zastávky ve `stops`. Tabuli v úseku poznáte podle `distance_stops` = 0, ne podle shody id se `stops`.
|
|
160
|
+
- **Aktuálnost podle `last_detected_at`.** Při výpadku zdroje se úseky nemažou. VYMI drží událost platnou do `last_detected_at` + 15 minut (nastavitelné) a při každé další detekci ji prodlouží; když se `last_detected_at` přestane posouvat, událost sama vyprší.
|
|
161
|
+
|
|
162
|
+
## Výkon
|
|
163
|
+
|
|
164
|
+
Obohacení byla věnována pozornost, protože běží každých 5 minut nad produkční databází. Měřeno v říjnu 2026 na snímku produkčních dat (2,5 mil. předpočítaných odjezdů), čas dotazu včetně plánování:
|
|
165
|
+
|
|
166
|
+
| Varianta | 13 úseků | 40 úseků |
|
|
167
|
+
| --- | --- | --- |
|
|
168
|
+
| první verze, dotaz pro každý úsek | až 13 s na úsek | – |
|
|
169
|
+
| dotaz pro každý úsek po optimalizacích | 0,45 s | 1,2 s |
|
|
170
|
+
| jeden dotaz pro všechny úseky | 0,12 s | 0,25 s |
|
|
171
|
+
| současný stav | 0,06–0,08 s | 0,11–0,13 s |
|
|
172
|
+
|
|
173
|
+
Kontrola směru přes dvojice zastávek přidala ~5–8 %: na stejném snímku 93 → 99 ms pro 13 úseků a 184 → 199 ms pro 40 úseků (medián 7 běhů).
|
|
174
|
+
|
|
175
|
+
Hlavní kroky:
|
|
176
|
+
|
|
177
|
+
- **Párování presetů přes malou množinu.** ASW id zastávek nejsou indexovaná, párování všech zastávek dotčených spojů proti všem GTFS zastávkám trvalo sekundy. Dotaz páruje jen proti zastávkám s presetem a jejich variantám.
|
|
178
|
+
- **Jeden dotaz pro všechny úseky.** Plánování (~10 ms) a sdílené části (presety, zastávky) se platí jednou za běh, ne za úsek.
|
|
179
|
+
- **Odolnost vůči odhadům plánovače.** Plánovač u mezivýsledků (CTE) podhodnocuje počty řádků o dva až tři řády a volí vnořené smyčky. Spojení, kde to vedlo k milionům porovnání, nahrazuje vyhledání v malých mapách (`jsonb`) zastávek úseku a dvojic zastávek ve směru úseku.
|
|
180
|
+
- **Vzdálenost z `stop_sequence`** místo řazení všech zastávek všech dotčených spojů (viz výše).
|
|
181
|
+
- **Index `(stop_id, departure_datetime)`** zrychlí hledání odjezdů ze zastávek v časovém okně.
|
|
182
|
+
|
|
183
|
+
JIT kompilace PostgreSQL by dotaz jen zpomalila: samotná kompilace plánu trvá ~3 s. Odhadovaná cena dotazu (~7 000) je sice hluboko pod výchozím `jit_above_cost` (100 000, nastaveno na rabínu i produkci v říjnu 2026), na rozdíl od prototypu, kterému vypnutí JIT na produkci zrychlilo dotaz zhruba desetkrát. Dotaz přesto běží v transakci s `SET LOCAL jit = off`, aby změna odhadu nebo nastavení nemohla běh zpomalit o sekundy. Nastavení platí jen pro tuto transakci.
|
|
184
|
+
|
|
185
|
+
## Konfigurace
|
|
186
|
+
|
|
187
|
+
Klíče modulu pid v konfiguraci Integration Engine:
|
|
188
|
+
|
|
189
|
+
| Klíč | Výchozí hodnota | Význam |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `module.pid.jis.delayedSegments.url` | – (povinný) | adresa endpointu Mapy PID; záměrně jen v konfiguraci nasazení |
|
|
192
|
+
| `module.pid.jis.delayedSegments.minDelaySeconds` | `300` | minimální zpoždění úseku |
|
|
193
|
+
| `module.pid.jis.delayedSegments.routeTimeWindowMinutes` | `120` | časové okno odjezdů pro obohacení (± od detekce) |
|
|
194
|
+
| `module.pid.jis.delayedSegments.maxInfoPanelDistanceStops` | `5` | maximální vzdálenost zastávky s tabulí od úseku |
|
|
195
|
+
|
|
196
|
+
## Provoz
|
|
197
|
+
|
|
198
|
+
- **Spouštění:** cron `cron.vehicle-positions.jis.refreshDelayedSegments`, `0 */5 * * * *` (rabín i produkce), fronta `vehicle-positions.jis.refreshDelayedSegments` s TTL 4 minuty (zprávy starší než další běh propadnou). VYMI si úseky stahuje o dvě minuty později (minuta 2, 7, 12, …), aby četl data právě dokončeného běhu; při změně času spouštění je třeba posunout i VYMI.
|
|
199
|
+
- **Předpoklady nasazení:** nastavený `module.pid.jis.delayedSegments.url`, záznam v Cron Tasks a role v Access Proxy pro přístup VYMI k endpointu.
|
|
200
|
+
- **Logování:** každý běh loguje (úroveň info) počet převzatých a nově spočítaných obohacení, počet uložených úseků a počty vyřazených úseků podle důvodu (pod minimálním zpožděním, bez ASW id, krajní zastávky mimo GTFS, úsek neprojíždí celý žádný spoj, bez dotčených linek). Jednotlivé vyřazené úseky se logují jen na úrovni debug, protože se opakují každých 5 minut po celou dobu zpoždění.
|
|
201
|
+
- **Chyby:** chyba stažení, validace nebo databáze ukončí běh chybou a uložená data zůstanou beze změny. Další běh proběhne normálně.
|
|
202
|
+
- **Chybějící jízdní řády:** pokud běh vyřadí všechny úseky s důvodem `no trip runs the whole segment`, pravděpodobně chybí předpočítané odjezdy pro aktuální čas (`ropidgtfs_precomputed_departures`, např. po neúspěšném importu GTFS). Úseky se pak neuloží a VYMI je nedostane.
|
|
203
|
+
|
|
204
|
+
## Známá omezení a rizika
|
|
205
|
+
|
|
206
|
+
- **Zaseknutý výpočet Mapy PID nelze rozpoznat.** Odpověď neobsahuje čas výpočtu úseků. Pokud Mapa PID přestane úseky přepočítávat, vrací poslední stav (až 24 hodin) a ten se jeví jako aktuální. Změnu na straně Mapy PID nelze zajistit, riziko je pro zkušební provoz přijaté.
|
|
207
|
+
- **Úseky sloučené přes různé linky se zahodí.** Mapa PID slučuje navazující zpožděné mezizastávkové úseky podle zastávek bez ohledu na linku (úsek A→B jedné linky s úsekem B→C jiné linky). Pokud takový sloučený úsek celý neprojíždí žádný spoj, nelze určit jeho zastávky ani linky a úsek se zahodí. Zpoždění tak může zůstat bez infotextu. Počet těchto úseků je v logu každého běhu (`no trip runs the whole segment`). Řešením by bylo rozdělit úsek na části projížděné jednotlivými spoji; zda je to potřeba, ukáže zkušební provoz.
|
|
208
|
+
- **Mezery v `stop_sequence`** by zvětšily vzdálenosti tabulí (viz [Obohacení](#zastávky-s-tabulemi-a-jejich-vzdálenost)).
|
|
209
|
+
- **Úseky přes železniční body** (krajní zastávka `T…` bez ASW id) se nezpracují.
|
|
210
|
+
- **Chybějící název zastávky nebo linky** v GTFS datech by neprošel validací a běh by skončil chybou; data zůstanou z předchozího běhu.
|
|
211
|
+
- **Souběžné běhy** (např. při zdržení fronty) mohou v krajním případě přepsat novější data staršími, další běh je opraví.
|
|
212
|
+
|
|
213
|
+
## Klíčová rozhodnutí
|
|
214
|
+
|
|
215
|
+
| Rozhodnutí | Důvod |
|
|
216
|
+
| --- | --- |
|
|
217
|
+
| Golemio úseky jen obohacuje, o infotextech rozhoduje VYMI | oddělení faktů od pravidel provozu; VYMI vlastní infotexty i jejich životní cyklus |
|
|
218
|
+
| `id` z ASW id krajních zastávek, ale bez stability; párování podle `stops` | Mapa PID úseky slučuje a štěpí, stabilní identita úseku neexistuje |
|
|
219
|
+
| API nezávislé na zdroji, data zdroje jen v DB (`external_*`) | algoritmus Mapy PID se může změnit, zdroj může být vyměněn |
|
|
220
|
+
| Bez nových časových sloupců pro detekci, `created_at` / `updated_at` | první a poslední detekce přirozeně odpovídají vložení a aktualizaci řádku |
|
|
221
|
+
| Neúspěšný běh nemění data, platnost řeší VYMI podle `last_detected_at` | výpadek zdroje nemá smazat informaci o probíhajícím zpoždění |
|
|
222
|
+
| Minimální zpoždění a rozsah vzdáleností tabulí určuje VYMI parametry endpointu, filtruje Output Gateway | jde o provozní rozhodnutí VYMI, Golemio ale posílá jen relevantní data; konfigurace Integration Engine jen omezuje, co se obohacuje a ukládá; testovací zastávky zůstávají filtrem ve VYMI |
|
|
223
|
+
| Vzdálenost tabulí se znaménkem, nejbližší za linku | VYMI rozliší tabule před úsekem, v úseku a za ním |
|
|
224
|
+
| Jedna tabulka s `jsonb` sloupci | data se vždy čtou celá a vyměňují celá, normalizace by nic nepřinesla |
|
|
225
|
+
| Vzdálenost z `stop_sequence` | výkon (viz [Výkon](#výkon)); kompromis je zdokumentovaný výše |
|
|
226
|
+
| Obohacení v každém běhu, bez cache | znovupoužití obohacení přetrvávajících úseků šetřilo jen desetiny sekundy za běh (v listopadu 2026 ~0,1–0,3 s na snímku produkčních dat, ~0,3–0,9 s na rabínu pro 13–40 úseků), za cenu až 30 minut starých zastávek, linek a tabulí po změně jízdních řádů, presetů nebo přechodu mezi denním a nočním provozem |
|
|
227
|
+
| Adresa Mapy PID jen v konfiguraci | endpoint je veřejně dostupný, ale není určen k širokému použití |
|
|
228
|
+
|
|
229
|
+
## Zdrojový kód a testy
|
|
230
|
+
|
|
231
|
+
| Část | Soubor |
|
|
232
|
+
| --- | --- |
|
|
233
|
+
| datový zdroj | [JISDelayedSegmentsDataSourceFactory](../../src/integration-engine/jis/datasources/JISDelayedSegmentsDataSourceFactory.ts) |
|
|
234
|
+
| task | [RefreshDelayedSegmentsTask](../../src/integration-engine/jis/workers/tasks/RefreshDelayedSegmentsTask.ts) |
|
|
235
|
+
| zpracování | [JISDelayedSegmentsDataService](../../src/integration-engine/jis/services/JISDelayedSegmentsDataService.ts) |
|
|
236
|
+
| obohacení | [JISDelayedSegmentEnrichmentRepository](../../src/integration-engine/jis/repositories/JISDelayedSegmentEnrichmentRepository.ts), [JISDelayedSegmentEnrichmentQuery](../../src/integration-engine/jis/repositories/helpers/JISDelayedSegmentEnrichmentQuery.ts) |
|
|
237
|
+
| uložení | [JISDelayedSegmentsRepository (IE)](../../src/integration-engine/jis/repositories/JISDelayedSegmentsRepository.ts), [JISDelayedSegmentsModel](../../src/schema-definitions/jis/models/JISDelayedSegmentsModel.ts) |
|
|
238
|
+
| výstup | [V1DelayedSegmentsController](../../src/output-gateway/jis/controllers/v1/V1DelayedSegmentsController.ts), [JISDelayedSegmentsTransformation](../../src/output-gateway/jis/transformations/JISDelayedSegmentsTransformation.ts) |
|
|
239
|
+
| migrace | [20261027100000-jis-delayed-segments](../../db/migrations/postgresql/sqls/20261027100000-jis-delayed-segments-up.sql) |
|
|
240
|
+
| testovací data | [24_jis_delayed_segments.sql](../../db/example/24_jis_delayed_segments.sql) – syntetický koridor s linkami, které úsek projíždějí celý, částečně, jen se ho dotknou, jsou výjimečné, jedou mimo časové okno nebo mají mezeru v `stop_sequence` |
|
|
241
|
+
| testy | `test/integration-engine/jis/**/*DelayedSegment*`, `test/output-gateway/jis/**/*DelayedSegments*` |
|
package/docs/jis/index.md
CHANGED
|
@@ -306,3 +306,12 @@ Experimentální feed pro e-paper displeje, generovaný stejným taskem. Obsahuj
|
|
|
306
306
|
|
|
307
307
|
- `/v2/pid/departureboards`, `/v3/pid/transferboards` a `/v3/pid/infotexts` čtou infotexty z PostgreSQL; u odjezdových tabulí s parametrem `preset` se vrací jen infotexty navázané na daný preset (`jis_infotexts_presets.route_name`);
|
|
308
308
|
- `/v4/pid/transferboards` čte infotexty z Redis cache `jisCache:*`.
|
|
309
|
+
|
|
310
|
+
### Zpožděné úseky — podklad pro automatické infotexty (`GET /v1/jis/delayed-segments`)
|
|
311
|
+
|
|
312
|
+
Endpoint je interní a slouží VYMI k automatickému vytváření interních událostí a infotextů o zpožděných úsecích ([vymi-general#365](https://gitlab.com/operator-ict/golemio/jis/vymi-alerts/vymi-general/-/work_items/365)). Úseky detekuje Mapa PID, Golemio je stahuje, obohacuje a poskytuje, VYMI rozhoduje, zda a jak vytvořit událost/infotext. Záměr, architekturu, algoritmus, výkon a rozhodnutí podrobně popisuje stránka [Zpožděné úseky](./delayed-segments.md).
|
|
313
|
+
|
|
314
|
+
Úseky každých 5 minut stahuje `RefreshDelayedSegmentsTask` z Mapy PID a obohacuje je o zastávky úseku, dotčené linky a zastávky s panely včetně jejich vzdálenosti od úseku (viz [Zpracování](./delayed-segments.md#zpracování) a [implementační dokumentace](../implementation_documentation.md#task-refreshdelayedsegmentstask)). Pro VYMI platí:
|
|
315
|
+
- úseky v čase rostou a zmenšují se (Mapa PID slučuje navazující zpožděné mezizastávkové úseky), `id` proto není stabilní identifikace; VYMI úseky páruje podle `stops` (alespoň dvě společné zastávky);
|
|
316
|
+
- při chybě stažení zůstávají uložené úseky beze změny a nemažou se; VYMI proto drží událost platnou do `last_detected_at` + 15 minut a nechá ji vypršet, když se `last_detected_at` přestane posouvat; Mapa PID navíc neposílá čas výpočtu úseků, takže zaseknutý výpočet na její straně nelze rozpoznat;
|
|
317
|
+
- minimální zpoždění úseku (`minDelaySeconds`) a rozsah vzdáleností zastávek s panely od úseku (`minDistanceStops`, `maxDistanceStops`) si VYMI určuje parametry endpointu.
|