From b3193daa384cc5a1ddc59351aff7c86a4f098d4b Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 24 Sep 2025 11:55:25 +0200 Subject: [PATCH 01/54] models: node: add isCollapsed attribute -first step to transform trainrunSection.nbOfStops, in actual nodes --- src/app/data-structures/business.data.structures.ts | 1 + src/app/models/node.model.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/app/data-structures/business.data.structures.ts b/src/app/data-structures/business.data.structures.ts index 665a51f38..2eb55ba40 100644 --- a/src/app/data-structures/business.data.structures.ts +++ b/src/app/data-structures/business.data.structures.ts @@ -173,6 +173,7 @@ export interface NodeDto { fullName: string; // full name of the trainrun eg. BN => Bern Wankdorf positionX: number; // coordinate X positionY: number; // coordinate Y + isCollapsed: boolean; // flag to collapse the node ports: PortDto[]; // all ports aligned to the node transitions: TransitionDto[]; // all tranisitons aligned to the node diff --git a/src/app/models/node.model.ts b/src/app/models/node.model.ts index 4e1551625..91b950b4c 100644 --- a/src/app/models/node.model.ts +++ b/src/app/models/node.model.ts @@ -38,6 +38,7 @@ export class Node { private warnings: WarningDto[]; private isSelected: boolean; private labelIds: number[]; + private isCollapsed: boolean; constructor( { @@ -56,6 +57,7 @@ export class Node { symmetryAxis, warnings, labelIds, + isCollapsed, }: NodeDto = { id: Node.incrementId(), betriebspunktName: $localize`:@@app.models.node.shortNameDefault:NEW`, @@ -72,6 +74,7 @@ export class Node { symmetryAxis: null, warnings: null, labelIds: [], + isCollapsed: false, }, ) { this.id = id; @@ -93,6 +96,7 @@ export class Node { this.warnings = warnings; this.isSelected = false; this.labelIds = labelIds; + this.isCollapsed = isCollapsed; if (Node.currentId < this.id) { Node.currentId = this.id; @@ -318,6 +322,14 @@ export class Node { return currentMaxIndex; } + getIsCollapsed(): boolean { + return this.isCollapsed; + } + + setIsCollapsed(isCollapsed: boolean) { + this.isCollapsed = isCollapsed; + } + computeTransitionRouting(transition: Transition) { const port1 = this.getPort(transition.getPortId1()); const port2 = this.getPort(transition.getPortId2()); @@ -845,6 +857,7 @@ export class Node { symmetryAxis: this.symmetryAxis, warnings: this.warnings, labelIds: this.labelIds, + isCollapsed: this.isCollapsed, }; } From 84527fb08fdcd93a50115b4524abeb9ed635edd9 Mon Sep 17 00:00:00 2001 From: Louis Greiner Date: Fri, 24 Oct 2025 10:14:23 +0200 Subject: [PATCH 02/54] temp: add feature branch to CI Signed-off-by: Louis Greiner --- .github/workflows/continuous-integration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 8f7896791..2619c259f 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -3,9 +3,11 @@ on: push: branches: - main + - mrd/new-nodes-management-system pull_request: branches: - main + - mrd/new-nodes-management-system concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} From 435f1c66b8ede96870c312fac2dca55ea4fa30f4 Mon Sep 17 00:00:00 2001 From: Valentin Chanas Date: Fri, 14 Nov 2025 17:00:02 +0100 Subject: [PATCH 03/54] import: handle importing old files with numberOfStops --- .../netzgrafik.default.spec.ts | 116 ++++- .../test-data/2-nodes-legacy.json | 330 +++++++++++++ .../test-data/3-nodes-legacy.json | 432 ++++++++++++++++++ .../sample-netzgrafik/test-data/netzgrafik.ts | 13 + src/app/services/data/data.service.ts | 30 +- src/app/services/data/node.service.ts | 14 +- .../services/data/trainrunsection.service.ts | 16 +- 7 files changed, 928 insertions(+), 23 deletions(-) create mode 100644 src/app/sample-netzgrafik/test-data/2-nodes-legacy.json create mode 100644 src/app/sample-netzgrafik/test-data/3-nodes-legacy.json create mode 100644 src/app/sample-netzgrafik/test-data/netzgrafik.ts diff --git a/src/app/sample-netzgrafik/netzgrafik.default.spec.ts b/src/app/sample-netzgrafik/netzgrafik.default.spec.ts index 9c28bb936..deca1e7e0 100644 --- a/src/app/sample-netzgrafik/netzgrafik.default.spec.ts +++ b/src/app/sample-netzgrafik/netzgrafik.default.spec.ts @@ -1,5 +1,6 @@ import netzgrafikDefaultJson from "./netzgrafik_default.json"; import {NetzgrafikDefault} from "./netzgrafik.default"; +import {NetzgrafikTestData} from "./test-data/netzgrafik"; import {DataService} from "../services/data/data.service"; import {LogPublishersService} from "../logger/log.publishers.service"; import {LogService} from "../logger/log.service"; @@ -63,21 +64,116 @@ describe("NetzgrafikDefault", () => { ); }); - it("should load and serialize default netzgrafikDto (no trainruns) without changes", () => { - const inputDto = NetzgrafikDefault.getDefaultNetzgrafik(); + // TODO: broken until the numberOfStops migration is completely done + // need to be replaced with tests importing a graph without any numberOfStops + describe("normal case", () => { + // needs to be updated to new format (no longer numberOfStops but the complete graph nodes + links) + it("should load and serialize default netzgrafikDto (no trainruns) without changes", () => { + const inputDto = NetzgrafikDefault.getDefaultNetzgrafik(); - dataService.loadNetzgrafikDto(inputDto); + dataService.loadNetzgrafikDto(inputDto); - const outputJson = dataService.getNetzgrafikDto(); - expect(JSON.stringify(inputDto, null, 2)).toEqual(JSON.stringify(outputJson, null, 2)); + const outputJson = dataService.getNetzgrafikDto(); + expect(JSON.stringify(inputDto, null, 2)).toEqual(JSON.stringify(outputJson, null, 2)); + }); + + it("should load and serialize demo netzgrafikDto (complete variant) without changes", () => { + const inputDto = NetzgrafikDefault.getNetzgrafikDemoStandaloneGithub(); + + dataService.loadNetzgrafikDto(inputDto); + + const outputJson = dataService.getNetzgrafikDto(); + expect(JSON.stringify(inputDto, null, 2)).toEqual(JSON.stringify(outputJson, null, 2)); + }); }); - it("should load and serialize demo netzgrafikDto (complete variant) without changes", () => { - const inputDto = NetzgrafikDefault.getNetzgrafikDemoStandaloneGithub(); + describe("handling old files with numberOfStops", () => { + describe("2 nodes", () => { + // A -> B has 1 stop + it("should replace the numberOfStops: 1 with an equivalent graph portion", () => { + const inputDto = NetzgrafikTestData.getLegacyNtezgrafik2Nodes(); + + dataService.loadNetzgrafikDto(inputDto); + + const outputJson = dataService.getNetzgrafikDto(); + + // we expect to have a new node between A and B + // the existing trainrunSection A -> B to now be A -> NEW + // and a new trainrunSection NEW -> B + const newNode = outputJson.nodes[2]; + expect(newNode.betriebspunktName).toBe("NEW"); + expect(newNode.positionX).toBe(1488); + expect(newNode.positionY).toBe(512); + expect(outputJson.trainrunSections[0].sourceNodeId).toBe(11); + expect(outputJson.trainrunSections[0].targetNodeId).toBe(newNode.id); + expect(outputJson.trainrunSections[1].sourceNodeId).toBe(newNode.id); + expect(outputJson.trainrunSections[1].targetNodeId).toBe(12); + expect(outputJson.trainrunSections[0].numberOfStops).toBe(0); + expect(outputJson.trainrunSections[1].numberOfStops).toBe(0); + }); + it("should replace the numberOfStops: 3 with an equivalent graph portion", () => { + const inputDto = NetzgrafikTestData.getLegacyNtezgrafik2Nodes(); + inputDto.trainrunSections[0].numberOfStops = 3; + + dataService.loadNetzgrafikDto(inputDto); + // before + // A ------ B + // after + // A ------ C ------ D ------ E ------ B + const outputJson = dataService.getNetzgrafikDto(); + const newNode1 = outputJson.nodes[2]; + expect(newNode1.betriebspunktName).toBe("NEW"); + expect(newNode1.positionX).toBe(1488); + expect(newNode1.positionY).toBe(512); + const newNode2 = outputJson.nodes[3]; + expect(newNode2.betriebspunktName).toBe("NEW"); + expect(newNode2.positionX).toBe(1576); + expect(newNode2.positionY).toBe(512); + const newNode3 = outputJson.nodes[4]; + expect(newNode3.betriebspunktName).toBe("NEW"); + expect(newNode3.positionX).toBe(1620); + expect(newNode3.positionY).toBe(512); + expect(outputJson.trainrunSections[0].sourceNodeId).toBe(11); + expect(outputJson.trainrunSections[0].targetNodeId).toBe(newNode1.id); + expect(outputJson.trainrunSections[1].sourceNodeId).toBe(newNode1.id); + expect(outputJson.trainrunSections[1].targetNodeId).toBe(newNode2.id); + expect(outputJson.trainrunSections[2].sourceNodeId).toBe(newNode2.id); + expect(outputJson.trainrunSections[2].targetNodeId).toBe(newNode3.id); + expect(outputJson.trainrunSections[3].sourceNodeId).toBe(newNode3.id); + expect(outputJson.trainrunSections[3].targetNodeId).toBe(12); + expect(outputJson.trainrunSections[0].numberOfStops).toBe(0); + expect(outputJson.trainrunSections[1].numberOfStops).toBe(0); + expect(outputJson.trainrunSections[2].numberOfStops).toBe(0); + expect(outputJson.trainrunSections[3].numberOfStops).toBe(0); + }); + }); + describe("3 nodes", () => { + // A -> B -> C + // each trainrunSection with 1 stop + it("should replace the numberOfStops: 1 with an equivalent graph portion for each section", () => { + const inputDto = NetzgrafikTestData.getLegacyNtezgrafik3Nodes(); + + dataService.loadNetzgrafikDto(inputDto); - dataService.loadNetzgrafikDto(inputDto); + const outputJson = dataService.getNetzgrafikDto(); - const outputJson = dataService.getNetzgrafikDto(); - expect(JSON.stringify(inputDto, null, 2)).toEqual(JSON.stringify(outputJson, null, 2)); + const newNode1 = outputJson.nodes[3]; + expect(newNode1.betriebspunktName).toBe("NEW"); + expect(newNode1.positionX).toBe(1488); + expect(newNode1.positionY).toBe(512); + const newNode2 = outputJson.nodes[4]; + expect(newNode2.betriebspunktName).toBe("NEW"); + expect(newNode2.positionX).toBe(1808); + expect(newNode2.positionY).toBe(544); + expect(outputJson.trainrunSections[0].sourceNodeId).toBe(11); + expect(outputJson.trainrunSections[0].targetNodeId).toBe(newNode1.id); + expect(outputJson.trainrunSections[2].sourceNodeId).toBe(newNode1.id); + expect(outputJson.trainrunSections[2].targetNodeId).toBe(12); + expect(outputJson.trainrunSections[1].sourceNodeId).toBe(12); + expect(outputJson.trainrunSections[1].targetNodeId).toBe(newNode2.id); + expect(outputJson.trainrunSections[3].sourceNodeId).toBe(newNode2.id); + expect(outputJson.trainrunSections[3].targetNodeId).toBe(13); + }); + }); }); }); diff --git a/src/app/sample-netzgrafik/test-data/2-nodes-legacy.json b/src/app/sample-netzgrafik/test-data/2-nodes-legacy.json new file mode 100644 index 000000000..9b46b529c --- /dev/null +++ b/src/app/sample-netzgrafik/test-data/2-nodes-legacy.json @@ -0,0 +1,330 @@ +{ + "nodes": [ + { + "id": 11, + "betriebspunktName": "A", + "fullName": "", + "positionX": 1312, + "positionY": 512, + "ports": [{"id": 1, "trainrunSectionId": 1, "positionIndex": 0, "positionAlignment": 3}], + "transitions": [], + "connections": [], + "resourceId": 12, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": false + }, + { + "id": 12, + "betriebspunktName": "B", + "fullName": "", + "positionX": 1664, + "positionY": 512, + "ports": [{"id": 2, "trainrunSectionId": 1, "positionIndex": 0, "positionAlignment": 2}], + "transitions": [], + "connections": [], + "resourceId": 13, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": false + } + ], + "trainrunSections": [ + { + "id": 1, + "sourceNodeId": 11, + "sourcePortId": 1, + "targetNodeId": 12, + "targetPortId": 2, + "travelTime": { + "time": 1, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 0, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 59, + "consecutiveTime": 59, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 1, + "consecutiveTime": 1, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 1, + "trainrunId": 1, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 1410, "y": 528}, + {"x": 1474, "y": 528}, + {"x": 1598, "y": 528}, + {"x": 1662, "y": 528} + ], + "textPositions": { + "0": {"x": 1428, "y": 540}, + "1": {"x": 1456, "y": 516}, + "2": {"x": 1644, "y": 516}, + "3": {"x": 1616, "y": 540}, + "4": {"x": 1536, "y": 516}, + "5": {"x": 1536, "y": 516}, + "6": {"x": 1536, "y": 540} + } + }, + "warnings": null + } + ], + "trainruns": [ + { + "id": 1, + "name": "X", + "categoryId": 1, + "frequencyId": 3, + "trainrunTimeCategoryId": 0, + "labelIds": [], + "direction": "round_trip" + } + ], + "resources": [ + {"id": 12, "capacity": 2}, + {"id": 13, "capacity": 2} + ], + "metadata": { + "analyticsSettings": {"originDestinationSettings": {"connectionPenalty": 5}}, + "trainrunCategories": [ + { + "id": 0, + "order": 0, + "shortName": "EC", + "name": "International", + "colorRef": "EC", + "fachCategory": "HaltezeitIPV", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 1, + "order": 1, + "shortName": "IC", + "name": "InterCity", + "colorRef": "IC", + "fachCategory": "HaltezeitA", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 2, + "order": 2, + "shortName": "IR", + "name": "InterRegio", + "colorRef": "IR", + "fachCategory": "HaltezeitB", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 3, + "order": 3, + "shortName": "RE", + "name": "RegioExpress", + "colorRef": "RE", + "fachCategory": "HaltezeitC", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 4, + "order": 4, + "shortName": "S", + "name": "RegioUndSBahnverkehr", + "colorRef": "S", + "fachCategory": "HaltezeitD", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 5, + "order": 5, + "shortName": "GEX", + "name": "GüterExpress", + "colorRef": "GEX", + "fachCategory": "HaltezeitUncategorized", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + }, + { + "id": 6, + "order": 6, + "shortName": "G", + "name": "Güterverkehr", + "colorRef": "G", + "fachCategory": "HaltezeitUncategorized", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + } + ], + "trainrunFrequencies": [ + { + "id": 0, + "order": 0, + "frequency": 15, + "offset": 0, + "shortName": "15", + "name": "verkehrt viertelstündlich", + "linePatternRef": "15" + }, + { + "id": 1, + "order": 0, + "frequency": 20, + "offset": 0, + "shortName": "20", + "name": "verkehrt im 20 Minuten Takt", + "linePatternRef": "20" + }, + { + "id": 2, + "order": 0, + "frequency": 30, + "offset": 0, + "shortName": "30", + "name": "verkehrt halbstündlich", + "linePatternRef": "30" + }, + { + "id": 3, + "order": 0, + "frequency": 60, + "offset": 0, + "shortName": "60", + "name": "verkehrt stündlich", + "linePatternRef": "60" + }, + { + "id": 4, + "order": 0, + "frequency": 120, + "offset": 0, + "shortName": "120", + "name": "verkehrt zweistündlich (gerade)", + "linePatternRef": "120" + }, + { + "id": 5, + "order": 0, + "frequency": 120, + "offset": 60, + "shortName": "120+", + "name": "verkehrt zweistündlich (ungerade)", + "linePatternRef": "120" + } + ], + "trainrunTimeCategories": [ + { + "id": 0, + "order": 0, + "shortName": "7/24", + "name": "verkehrt uneingeschränkt", + "dayTimeInterval": [], + "weekday": [1, 2, 3, 4, 5, 6, 7], + "linePatternRef": "7/24" + }, + { + "id": 1, + "order": 0, + "shortName": "HVZ", + "name": "verkehrt zur Hauptverkehrszeit", + "dayTimeInterval": [ + {"from": 360, "to": 420}, + {"from": 960, "to": 1140} + ], + "weekday": [1, 2, 3, 4, 5, 6, 7], + "linePatternRef": "HVZ" + }, + { + "id": 2, + "order": 0, + "shortName": "zeitweise", + "name": "verkehrt zeitweise", + "dayTimeInterval": [], + "weekday": [], + "linePatternRef": "ZEITWEISE" + } + ], + "netzgrafikColors": [ + { + "id": 2, + "colorRef": "NORMAL", + "color": "#767676", + "colorFocus": "#000000", + "colorMuted": "#DCDCDC", + "colorRelated": "#767676", + "colorDarkMode": "#767676", + "colorDarkModeFocus": "#DCDCDC", + "colorDarkModeMuted": "#000000", + "colorDarkModeRelated": "#767676" + } + ] + }, + "freeFloatingTexts": [], + "labels": [], + "labelGroups": [], + "filterData": {"filterSettings": []} +} diff --git a/src/app/sample-netzgrafik/test-data/3-nodes-legacy.json b/src/app/sample-netzgrafik/test-data/3-nodes-legacy.json new file mode 100644 index 000000000..5543bd679 --- /dev/null +++ b/src/app/sample-netzgrafik/test-data/3-nodes-legacy.json @@ -0,0 +1,432 @@ +{ + "nodes": [ + { + "id": 11, + "betriebspunktName": "A", + "fullName": "", + "positionX": 1312, + "positionY": 512, + "ports": [{"id": 1, "trainrunSectionId": 1, "positionIndex": 0, "positionAlignment": 3}], + "transitions": [], + "connections": [], + "resourceId": 12, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": false + }, + { + "id": 12, + "betriebspunktName": "B", + "fullName": "", + "positionX": 1664, + "positionY": 512, + "ports": [ + {"id": 2, "trainrunSectionId": 1, "positionIndex": 0, "positionAlignment": 2}, + {"id": 3, "trainrunSectionId": 2, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [], + "connections": [], + "resourceId": 13, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": false + }, + { + "id": 13, + "betriebspunktName": "C", + "fullName": "", + "positionX": 1952, + "positionY": 576, + "ports": [{"id": 4, "trainrunSectionId": 2, "positionIndex": 0, "positionAlignment": 2}], + "transitions": [], + "connections": [], + "resourceId": 14, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": false + } + ], + "trainrunSections": [ + { + "id": 1, + "sourceNodeId": 11, + "sourcePortId": 1, + "targetNodeId": 12, + "targetPortId": 2, + "travelTime": { + "time": 1, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 0, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 59, + "consecutiveTime": 59, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 1, + "consecutiveTime": 1, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 1, + "trainrunId": 1, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 1410, "y": 528}, + {"x": 1474, "y": 528}, + {"x": 1598, "y": 528}, + {"x": 1662, "y": 528} + ], + "textPositions": { + "0": {"x": 1428, "y": 540}, + "1": {"x": 1456, "y": 516}, + "2": {"x": 1644, "y": 516}, + "3": {"x": 1616, "y": 540}, + "4": {"x": 1536, "y": 516}, + "5": {"x": 1536, "y": 516}, + "6": {"x": 1536, "y": 540} + } + }, + "warnings": null + }, + { + "id": 2, + "sourceNodeId": 12, + "sourcePortId": 3, + "targetNodeId": 13, + "targetPortId": 4, + "travelTime": { + "time": 1, + "consecutiveTime": 1, + "lock": true, + "warning": null, + "timeFormatter": null + }, + "sourceDeparture": { + "time": 0, + "consecutiveTime": 0, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "sourceArrival": { + "time": 0, + "consecutiveTime": 60, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetDeparture": { + "time": 59, + "consecutiveTime": 59, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "targetArrival": { + "time": 1, + "consecutiveTime": 1, + "lock": false, + "warning": null, + "timeFormatter": null + }, + "numberOfStops": 1, + "trainrunId": 2, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 1762, "y": 528}, + {"x": 1826, "y": 528}, + {"x": 1886, "y": 592}, + {"x": 1950, "y": 592} + ], + "textPositions": { + "0": {"x": 1780, "y": 540}, + "1": {"x": 1808, "y": 516}, + "2": {"x": 1932, "y": 580}, + "3": {"x": 1904, "y": 604}, + "4": {"x": 1856, "y": 548}, + "5": {"x": 1856, "y": 548}, + "6": {"x": 1856, "y": 572} + } + }, + "warnings": null + } + ], + "trainruns": [ + { + "id": 1, + "name": "X", + "categoryId": 1, + "frequencyId": 3, + "trainrunTimeCategoryId": 0, + "labelIds": [], + "direction": "round_trip" + }, + { + "id": 2, + "name": "X", + "categoryId": 1, + "frequencyId": 3, + "trainrunTimeCategoryId": 0, + "labelIds": [], + "direction": "round_trip" + } + ], + "resources": [ + {"id": 12, "capacity": 2}, + {"id": 13, "capacity": 2}, + {"id": 14, "capacity": 2} + ], + "metadata": { + "analyticsSettings": {"originDestinationSettings": {"connectionPenalty": 5}}, + "trainrunCategories": [ + { + "id": 0, + "order": 0, + "shortName": "EC", + "name": "International", + "colorRef": "EC", + "fachCategory": "HaltezeitIPV", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 1, + "order": 1, + "shortName": "IC", + "name": "InterCity", + "colorRef": "IC", + "fachCategory": "HaltezeitA", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 2, + "order": 2, + "shortName": "IR", + "name": "InterRegio", + "colorRef": "IR", + "fachCategory": "HaltezeitB", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 3, + "order": 3, + "shortName": "RE", + "name": "RegioExpress", + "colorRef": "RE", + "fachCategory": "HaltezeitC", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 4, + "order": 4, + "shortName": "S", + "name": "RegioUndSBahnverkehr", + "colorRef": "S", + "fachCategory": "HaltezeitD", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 2, + "nodeHeadwayNonStop": 2, + "sectionHeadway": 2 + }, + { + "id": 5, + "order": 5, + "shortName": "GEX", + "name": "GüterExpress", + "colorRef": "GEX", + "fachCategory": "HaltezeitUncategorized", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + }, + { + "id": 6, + "order": 6, + "shortName": "G", + "name": "Güterverkehr", + "colorRef": "G", + "fachCategory": "HaltezeitUncategorized", + "minimalTurnaroundTime": 4, + "nodeHeadwayStop": 3, + "nodeHeadwayNonStop": 3, + "sectionHeadway": 3 + } + ], + "trainrunFrequencies": [ + { + "id": 0, + "order": 0, + "frequency": 15, + "offset": 0, + "shortName": "15", + "name": "verkehrt viertelstündlich", + "linePatternRef": "15" + }, + { + "id": 1, + "order": 0, + "frequency": 20, + "offset": 0, + "shortName": "20", + "name": "verkehrt im 20 Minuten Takt", + "linePatternRef": "20" + }, + { + "id": 2, + "order": 0, + "frequency": 30, + "offset": 0, + "shortName": "30", + "name": "verkehrt halbstündlich", + "linePatternRef": "30" + }, + { + "id": 3, + "order": 0, + "frequency": 60, + "offset": 0, + "shortName": "60", + "name": "verkehrt stündlich", + "linePatternRef": "60" + }, + { + "id": 4, + "order": 0, + "frequency": 120, + "offset": 0, + "shortName": "120", + "name": "verkehrt zweistündlich (gerade)", + "linePatternRef": "120" + }, + { + "id": 5, + "order": 0, + "frequency": 120, + "offset": 60, + "shortName": "120+", + "name": "verkehrt zweistündlich (ungerade)", + "linePatternRef": "120" + } + ], + "trainrunTimeCategories": [ + { + "id": 0, + "order": 0, + "shortName": "7/24", + "name": "verkehrt uneingeschränkt", + "dayTimeInterval": [], + "weekday": [1, 2, 3, 4, 5, 6, 7], + "linePatternRef": "7/24" + }, + { + "id": 1, + "order": 0, + "shortName": "HVZ", + "name": "verkehrt zur Hauptverkehrszeit", + "dayTimeInterval": [ + {"from": 360, "to": 420}, + {"from": 960, "to": 1140} + ], + "weekday": [1, 2, 3, 4, 5, 6, 7], + "linePatternRef": "HVZ" + }, + { + "id": 2, + "order": 0, + "shortName": "zeitweise", + "name": "verkehrt zeitweise", + "dayTimeInterval": [], + "weekday": [], + "linePatternRef": "ZEITWEISE" + } + ], + "netzgrafikColors": [ + { + "id": 2, + "colorRef": "NORMAL", + "color": "#767676", + "colorFocus": "#000000", + "colorMuted": "#DCDCDC", + "colorRelated": "#767676", + "colorDarkMode": "#767676", + "colorDarkModeFocus": "#DCDCDC", + "colorDarkModeMuted": "#000000", + "colorDarkModeRelated": "#767676" + } + ] + }, + "freeFloatingTexts": [], + "labels": [], + "labelGroups": [], + "filterData": {"filterSettings": []} +} diff --git a/src/app/sample-netzgrafik/test-data/netzgrafik.ts b/src/app/sample-netzgrafik/test-data/netzgrafik.ts new file mode 100644 index 000000000..8ba7e743c --- /dev/null +++ b/src/app/sample-netzgrafik/test-data/netzgrafik.ts @@ -0,0 +1,13 @@ +import {NetzgrafikDto} from "../../data-structures/business.data.structures"; +import netzgrafikLegacy2NodesJson from "./2-nodes-legacy.json"; +import netzgrafikLegacy3NodesJson from "./3-nodes-legacy.json"; + +export class NetzgrafikTestData { + // old exported json data, still using numberOfStops trainrunSections format + static getLegacyNtezgrafik2Nodes(): NetzgrafikDto { + return JSON.parse(JSON.stringify(netzgrafikLegacy2NodesJson)) as NetzgrafikDto; + } + static getLegacyNtezgrafik3Nodes(): NetzgrafikDto { + return JSON.parse(JSON.stringify(netzgrafikLegacy3NodesJson)) as NetzgrafikDto; + } +} diff --git a/src/app/services/data/data.service.ts b/src/app/services/data/data.service.ts index ff6d2df45..d7c756a35 100644 --- a/src/app/services/data/data.service.ts +++ b/src/app/services/data/data.service.ts @@ -22,6 +22,7 @@ import {DataMigration} from "../../utils/data-migration"; import {FilterService} from "../ui/filter.service"; import {NetzgrafikColoringService} from "./netzgrafikColoring.service"; import {Trainrun} from "src/app/models/trainrun.model"; +import {Vec2D} from "src/app/utils/vec2D"; export class NetzgrafikLoadedInfo { constructor( @@ -30,9 +31,7 @@ export class NetzgrafikLoadedInfo { ) {} } -@Injectable({ - providedIn: "root", -}) +@Injectable({providedIn: "root"}) export class DataService implements OnDestroy { private netzgrafikDtoStore: {netzgrafikDto: NetzgrafikDto} = { netzgrafikDto: NetzgrafikDefault.getDefaultNetzgrafik(), @@ -99,6 +98,8 @@ export class DataService implements OnDestroy { this.trainrunSectionService.enforceConsistentSectionDirection(trainrun.getId()); }); + this.replaceLegacyNumberOfStopsWithRealNodes(netzgrafikDto); + // This must be done due of the bug fix - ensure that each resource object // is used in the Netzgrafik // https://github.com/OpenRailAssociation/netzgrafik-editor-frontend/issues/522 @@ -107,6 +108,29 @@ export class DataService implements OnDestroy { this.netzgrafikLoadedInfoSubject.next(new NetzgrafikLoadedInfo(false, preview)); } + replaceLegacyNumberOfStopsWithRealNodes(netzgrafikDto: NetzgrafikDto) { + for (const trainrunSection of netzgrafikDto.trainrunSections) { + let currentSection = trainrunSection; + for (let i = 0; i < trainrunSection.numberOfStops; i++) { + const newNode = this.nodeService.addEmptyNode(); + const {existingTrainRunSection, newTrainRunSection} = + this.trainrunSectionService.replaceIntermediateStopWithNode( + currentSection.id, + 0, + newNode.getId(), + ); + const sourceNode = existingTrainRunSection.getSourceNode(); + const targetNode = newTrainRunSection.getTargetNode(); + const interpolatedPosition = new Vec2D( + sourceNode.getPositionX() + (targetNode.getPositionX() - sourceNode.getPositionX()) * 0.5, + sourceNode.getPositionY() + (targetNode.getPositionY() - sourceNode.getPositionY()) * 0.5, + ); + newNode.setPosition(interpolatedPosition.getX(), interpolatedPosition.getY()); + currentSection = newTrainRunSection.getDto(); + } + } + } + insertCopyNetzgrafikDto(netzgrafikDto: NetzgrafikDto, enforceUpdate = true) { this.nodeService.unselectAllNodes(); const nodeMap = this.nodeService.mergeNodes(netzgrafikDto.nodes); diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index 484d77b83..28c3e3ac9 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -38,9 +38,7 @@ import { TrainrunOperation, } from "../../models/operation.model"; -@Injectable({ - providedIn: "root", -}) +@Injectable({providedIn: "root"}) export class NodeService implements OnDestroy { // Description of observable data service: https://coryrylan.com/blog/angular-observable-data-services nodesSubject = new BehaviorSubject([]); @@ -256,6 +254,16 @@ export class NodeService implements OnDestroy { return node; } + addEmptyNode(): Node { + const node: Node = new Node(); + node.setIsCollapsed(true); + const resource: Resource = this.resourceService.createAndGetResource(); + node.setResourceId(resource.getId()); + this.nodesStore.nodes.push(node); + this.operation.emit(new NodeOperation(OperationType.create, node)); + return node; + } + deleteNode(nodeId: number, enforceUpdate = true) { const node = this.getNodeFromId(nodeId); const deletetLabelIds = this.labelService.clearLabel( diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 3ed3a2453..a1ccc9813 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -21,6 +21,7 @@ import {takeUntil} from "rxjs/operators"; import {FilterService} from "../ui/filter.service"; import {TrainrunSectionNodePair} from "../util/trainrun.iterator"; import {Operation, OperationType, TrainrunOperation} from "../../models/operation.model"; +import {Vec2D} from "../../utils/vec2D"; interface DepartureAndArrivalTimes { nodeFromDepartureTime: number; @@ -34,16 +35,12 @@ export interface InformSelectedTrainrunClick { open: boolean; } -@Injectable({ - providedIn: "root", -}) +@Injectable({providedIn: "root"}) export class TrainrunSectionService implements OnDestroy { // Description of observable data service: https://coryrylan.com/blog/angular-observable-data-services trainrunSectionsSubject = new BehaviorSubject([]); readonly trainrunSections = this.trainrunSectionsSubject.asObservable(); - trainrunSectionsStore: {trainrunSections: TrainrunSection[]} = { - trainrunSections: [], - }; // store the data in memory + trainrunSectionsStore: {trainrunSections: TrainrunSection[]} = {trainrunSections: []}; // store the data in memory readonly operation = new EventEmitter(); @@ -936,13 +933,14 @@ export class TrainrunSectionService implements OnDestroy { }); } + // this function is no longer used for its original purpose (drag a node that only existed inside numberOfStops and create it inside the real graph) replaceIntermediateStopWithNode(trainrunSectionId: number, stopIndex: number, nodeId: number) { const trainrunSection1 = this.getTrainrunSectionFromId(trainrunSectionId); if ( trainrunSection1.getSourceNodeId() === nodeId || trainrunSection1.getTargetNodeId() === nodeId ) { - return; + return {}; } const origTravelTime = trainrunSection1.getTravelTime(); const trainrunSection2 = this.copyTrainrunSection( @@ -1048,6 +1046,10 @@ export class TrainrunSectionService implements OnDestroy { this.nodeService.connectionsUpdated(); this.nodeService.nodesUpdated(); this.trainrunSectionsUpdated(); + return { + existingTrainRunSection: trainrunSection1, + newTrainRunSection: trainrunSection2, + }; } setWarningOnNode( From f2bf75323d6836a105933b8c62efba57b103d6d9 Mon Sep 17 00:00:00 2001 From: Clara Ni Date: Wed, 29 Oct 2025 12:05:59 +0100 Subject: [PATCH 04/54] clean: remove duplicated tests Signed-off-by: Clara Ni --- .../util/trainrunsection.helper.spec.ts | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/app/services/util/trainrunsection.helper.spec.ts b/src/app/services/util/trainrunsection.helper.spec.ts index db2b82656..aef7cf520 100644 --- a/src/app/services/util/trainrunsection.helper.spec.ts +++ b/src/app/services/util/trainrunsection.helper.spec.ts @@ -216,26 +216,6 @@ describe("TrainrunsectionHelper", () => { expect(d.leftArrivalTime).toBe(larts.leftArrivalTime); }); - it("getTravelTime -- 2 -- 001", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, false, 0); - expect(tt).toBe(1); - }); - - it("getTravelTime -- 2 -- 002", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, true, 0); - expect(tt).toBe(12); - }); - - it("getTravelTime -- 2 -- 003", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, false, 0); - expect(tt).toBe(1); - }); - - it("getTravelTime -- 2 -- 004", () => { - const tt = TrainrunsectionHelper.getTravelTime(8, 10, 2, 12, false, 0); - expect(tt).toBe(1); - }); - it("getRightArrivalTime - 001", () => { const larts: LeftAndRightTimeStructure = { leftDepartureTime: 10, From c9bbdcb7de08d2355e6850bbc0e1d1b81c650ef0 Mon Sep 17 00:00:00 2001 From: Clara Ni Date: Wed, 29 Oct 2025 12:06:50 +0100 Subject: [PATCH 05/54] refacto: split TrainrunsectionHelper.getTravelTime() into 2 functions `TrainrunsectionHelper.getTravelTime()` computes the new travel time of a trainrunSection, either by using the `travelTimeFactor` and the current travel time of the section, or by using the total trainrun travel time and the sum of the new travel times computed up to that point. This logic can be split into 2 independent functions, which will be used depending on whether the considered section is the last one to compute or not. Signed-off-by: Clara Ni --- .../services/data/trainrunsection.service.ts | 21 +++++++------ .../util/trainrunsection.helper.spec.ts | 30 ++++++++++++------- .../services/util/trainrunsection.helper.ts | 29 +++++++++--------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index a1ccc9813..72128be2d 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -879,15 +879,18 @@ export class TrainrunSectionService implements OnDestroy { while (iterator.hasNext()) { const nextPair = iterator.next(); - const isRightNodeNonStop = nextPair.node.isNonStop(nextPair.trainrunSection); - trsTimeStructure.travelTime = TrainrunsectionHelper.getTravelTime( - newTotalTravelTime, - summedTravelTime, - travelTimeFactor, - nextPair.trainrunSection.getTravelTime(), - isRightNodeNonStop, - precision, - ); + const isLastNode = !nextPair.node.isNonStop(nextPair.trainrunSection); + trsTimeStructure.travelTime = isLastNode + ? TrainrunsectionHelper.getLastSectionTravelTime( + newTotalTravelTime, + summedTravelTime, + precision, + ) + : TrainrunsectionHelper.getSectionDistributedTravelTime( + nextPair.trainrunSection.getTravelTime(), + travelTimeFactor, + precision, + ); trsTimeStructure.rightArrivalTime = TrainrunsectionHelper.getRightArrivalTime( trsTimeStructure, precision, diff --git a/src/app/services/util/trainrunsection.helper.spec.ts b/src/app/services/util/trainrunsection.helper.spec.ts index aef7cf520..d770b7034 100644 --- a/src/app/services/util/trainrunsection.helper.spec.ts +++ b/src/app/services/util/trainrunsection.helper.spec.ts @@ -98,24 +98,34 @@ describe("TrainrunsectionHelper", () => { expect(d.leftArrivalTime).toBe(larts.leftArrivalTime); }); - it("getTravelTime -- 001", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, false, 0); + it("getLastSectionTravelTime -- 001", () => { + const tt = TrainrunsectionHelper.getLastSectionTravelTime(10, 10, 0); expect(tt).toBe(1); }); - it("getTravelTime -- 002", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, true, 0); - expect(tt).toBe(12); + it("getLastSectionTravelTime -- 002", () => { + const tt = TrainrunsectionHelper.getLastSectionTravelTime(10, 8, 0); + expect(tt).toBe(2); }); - it("getTravelTime -- 003", () => { - const tt = TrainrunsectionHelper.getTravelTime(10, 10, 1, 12, false, 0); + it("getLastSectionTravelTime -- 003", () => { + const tt = TrainrunsectionHelper.getLastSectionTravelTime(8, 10, 0); expect(tt).toBe(1); }); - it("getTravelTime -- 004", () => { - const tt = TrainrunsectionHelper.getTravelTime(8, 10, 2, 12, false, 0); - expect(tt).toBe(1); + it("getLastSectionTravelTime -- 004", () => { + const tt = TrainrunsectionHelper.getLastSectionTravelTime(10, 2, 0); + expect(tt).toBe(8); + }); + + it("getSectionDistributedTravelTime -- 001", () => { + const tt = TrainrunsectionHelper.getSectionDistributedTravelTime(12, 1, 0); + expect(tt).toBe(12); + }); + + it("getSectionDistributedTravelTime -- 002", () => { + const tt = TrainrunsectionHelper.getSectionDistributedTravelTime(12, 2, 0); + expect(tt).toBe(24); }); it("getRightArrivalTime - 001", () => { diff --git a/src/app/services/util/trainrunsection.helper.ts b/src/app/services/util/trainrunsection.helper.ts index 219568a72..5f6476141 100644 --- a/src/app/services/util/trainrunsection.helper.ts +++ b/src/app/services/util/trainrunsection.helper.ts @@ -39,25 +39,26 @@ export class TrainrunsectionHelper { }; } - static getTravelTime( + static getLastSectionTravelTime( totalTravelTime: number, summedTravelTime: number, - travelTimeFactor: number, + precision = TrainrunSectionService.TIME_PRECISION, + ): number { + return Math.max( + MathUtils.round(totalTravelTime - summedTravelTime, precision), + 1.0 / Math.pow(10, precision), + ); + } + + static getSectionDistributedTravelTime( trsTravelTime: number, - isRightNodeNonStopTransit: boolean, + travelTimeFactor: number, precision = TrainrunSectionService.TIME_PRECISION, ): number { - if (isRightNodeNonStopTransit) { - return Math.max( - MathUtils.round(trsTravelTime * travelTimeFactor, precision), - 1.0 / Math.pow(10, precision), - ); - } else { - return Math.max( - MathUtils.round(totalTravelTime - summedTravelTime, precision), - 1.0 / Math.pow(10, precision), - ); - } + return Math.max( + MathUtils.round(trsTravelTime * travelTimeFactor, precision), + 1.0 / Math.pow(10, precision), + ); } static getRightArrivalTime( From f2c04ca5253c12836e21468611b4447d8395d5a9 Mon Sep 17 00:00:00 2001 From: Clara Ni Date: Tue, 4 Nov 2025 12:55:39 +0100 Subject: [PATCH 06/54] feat: add stop time props in LeftAndRightTimeStructure Until now, a time structure has represented one or several trainrun sections without any stops, so it could be described by its departure and arrival times (right and left) and its travel time. Since we are now going to handle several trainrun sections that include stops, we need to add a new property to store the total stop time in the time structure. Signed-off-by: Clara Ni --- .../data/trainrun-section-times.service.ts | 34 ++++++++++++++----- .../util/trainrunsection.helper.spec.ts | 16 +++++++++ .../services/util/trainrunsection.helper.ts | 7 ++++ src/app/utils/math.ts | 5 +++ .../trainrun-section-card.component.ts | 2 +- .../trainrun-section-tab.component.ts | 1 + 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/app/services/data/trainrun-section-times.service.ts b/src/app/services/data/trainrun-section-times.service.ts index 72918035b..7eb4c9df3 100644 --- a/src/app/services/data/trainrun-section-times.service.ts +++ b/src/app/services/data/trainrun-section-times.service.ts @@ -26,6 +26,7 @@ export class TrainrunSectionTimesService { rightDepartureTime: 0, rightArrivalTime: 0, travelTime: 0, + stopTime: 0, }; private nodesOrdered: Node[] = []; @@ -142,15 +143,20 @@ export class TrainrunSectionTimesService { ); if (!this.lockStructure.rightLock) { this.timeStructure.rightArrivalTime = - this.timeStructure.leftDepartureTime + (this.timeStructure.travelTime % 60); + this.timeStructure.leftDepartureTime + + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.rightArrivalTime %= 60; this.timeStructure.rightDepartureTime = TrainrunsectionHelper.getSymmetricTime( this.timeStructure.rightArrivalTime, ); } else if (!this.lockStructure.travelTimeLock && this.lockStructure.rightLock) { - const extraHour = this.timeStructure.travelTime - (this.timeStructure.travelTime % 60); + const extraHour = + this.timeStructure.travelTime - + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.travelTime = - this.timeStructure.rightArrivalTime - this.timeStructure.leftDepartureTime; + this.timeStructure.rightArrivalTime - + this.timeStructure.leftDepartureTime - + this.timeStructure.stopTime; this.timeStructure.travelTime += this.timeStructure.travelTime < 0 ? 60 : 0; this.timeStructure.travelTime += extraHour; } else { @@ -234,15 +240,20 @@ export class TrainrunSectionTimesService { if (!this.lockStructure.leftLock) { this.timeStructure.leftDepartureTime = - this.timeStructure.rightArrivalTime - (this.timeStructure.travelTime % 60); + this.timeStructure.rightArrivalTime - + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.leftDepartureTime += this.timeStructure.leftDepartureTime < 0 ? 60 : 0; this.timeStructure.leftArrivalTime = TrainrunsectionHelper.getSymmetricTime( this.timeStructure.leftDepartureTime, ); } else if (!this.lockStructure.travelTimeLock && this.lockStructure.leftLock) { - const extraHour = this.timeStructure.travelTime - (this.timeStructure.travelTime % 60); + const extraHour = + this.timeStructure.travelTime - + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.travelTime = - this.timeStructure.rightArrivalTime - this.timeStructure.leftDepartureTime; + this.timeStructure.rightArrivalTime - + this.timeStructure.leftDepartureTime - + this.timeStructure.stopTime; this.timeStructure.travelTime += this.timeStructure.travelTime < 0 ? 60 : 0; this.timeStructure.travelTime += extraHour; } else { @@ -280,15 +291,20 @@ export class TrainrunSectionTimesService { ); if (!this.lockStructure.leftLock) { this.timeStructure.leftArrivalTime = - this.timeStructure.rightDepartureTime + (this.timeStructure.travelTime % 60); + this.timeStructure.rightDepartureTime + + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.leftArrivalTime %= 60; this.timeStructure.leftDepartureTime = TrainrunsectionHelper.getSymmetricTime( this.timeStructure.leftArrivalTime, ); } else if (!this.lockStructure.travelTimeLock && this.lockStructure.leftLock) { - const extraHour = this.timeStructure.travelTime - (this.timeStructure.travelTime % 60); + const extraHour = + this.timeStructure.travelTime - + ((this.timeStructure.travelTime + this.timeStructure.stopTime) % 60); this.timeStructure.travelTime = - this.timeStructure.leftArrivalTime - this.timeStructure.rightDepartureTime; + this.timeStructure.leftArrivalTime - + this.timeStructure.rightDepartureTime - + this.timeStructure.stopTime; this.timeStructure.travelTime += this.timeStructure.travelTime < 0 ? 60 : 0; this.timeStructure.travelTime += extraHour; } else { diff --git a/src/app/services/util/trainrunsection.helper.spec.ts b/src/app/services/util/trainrunsection.helper.spec.ts index d770b7034..4e7cc6d7d 100644 --- a/src/app/services/util/trainrunsection.helper.spec.ts +++ b/src/app/services/util/trainrunsection.helper.spec.ts @@ -89,9 +89,11 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); expect(d.travelTime).toBe(0); + expect(d.stopTime).toBe(0); expect(d.rightDepartureTime).toBe(0); expect(d.rightArrivalTime).toBe(0); expect(d.leftDepartureTime).toBe(larts.leftDepartureTime); @@ -135,6 +137,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); const a = TrainrunsectionHelper.getRightArrivalTime(d); @@ -148,6 +151,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.leftArrivalTime = -10; @@ -162,6 +166,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.leftDepartureTime = undefined; @@ -176,6 +181,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); const a = TrainrunsectionHelper.getRightDepartureTime(d); @@ -189,6 +195,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.rightArrivalTime = -10; @@ -203,6 +210,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.rightArrivalTime = undefined; @@ -217,9 +225,11 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); expect(d.travelTime).toBe(0); + expect(d.stopTime).toBe(0); expect(d.rightDepartureTime).toBe(0); expect(d.rightArrivalTime).toBe(0); expect(d.leftDepartureTime).toBe(larts.leftDepartureTime); @@ -233,6 +243,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); const a = TrainrunsectionHelper.getRightArrivalTime(d); @@ -246,6 +257,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.leftArrivalTime = -10; @@ -260,6 +272,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.leftDepartureTime = undefined; @@ -274,6 +287,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); const a = TrainrunsectionHelper.getRightDepartureTime(d); @@ -287,6 +301,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.rightArrivalTime = -10; @@ -301,6 +316,7 @@ describe("TrainrunsectionHelper", () => { rightDepartureTime: 20, rightArrivalTime: 40, travelTime: 10, + stopTime: 0, }; const d = TrainrunsectionHelper.getDefaultTimeStructure(larts); d.rightArrivalTime = undefined; diff --git a/src/app/services/util/trainrunsection.helper.ts b/src/app/services/util/trainrunsection.helper.ts index 5f6476141..94923a198 100644 --- a/src/app/services/util/trainrunsection.helper.ts +++ b/src/app/services/util/trainrunsection.helper.ts @@ -36,6 +36,7 @@ export class TrainrunsectionHelper { rightDepartureTime: 0, rightArrivalTime: 0, travelTime: 0, + stopTime: 0, }; } @@ -260,6 +261,7 @@ export class TrainrunsectionHelper { mappedTimeStructure.rightDepartureTime = timeStructure.leftDepartureTime; mappedTimeStructure.leftDepartureTime = timeStructure.rightDepartureTime; mappedTimeStructure.travelTime = timeStructure.travelTime; + mappedTimeStructure.stopTime = timeStructure.stopTime; return mappedTimeStructure; } return timeStructure; @@ -285,12 +287,17 @@ export class TrainrunsectionHelper { : bothLastNonStopTrainrunSections.lastNonStopTrainrunSection2; const cumulativeTravelTime = this.trainrunService.getCumulativeTravelTime(trainrunSection); + const totalDuration = + lastRightNode.getArrivalTime(rightTrainrunSection) - + lastLeftNode.getDepartureTime(leftTrainrunSection); + return { leftDepartureTime: lastLeftNode.getDepartureTime(leftTrainrunSection), leftArrivalTime: lastLeftNode.getArrivalTime(leftTrainrunSection), rightDepartureTime: lastRightNode.getDepartureTime(rightTrainrunSection), rightArrivalTime: lastRightNode.getArrivalTime(rightTrainrunSection), travelTime: cumulativeTravelTime, + stopTime: MathUtils.mod60(totalDuration - cumulativeTravelTime), }; } diff --git a/src/app/utils/math.ts b/src/app/utils/math.ts index f3a042723..c628714b7 100644 --- a/src/app/utils/math.ts +++ b/src/app/utils/math.ts @@ -7,4 +7,9 @@ export class MathUtils { const multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; } + + /** Computes the positive modulo 60 of a given number */ + static mod60(value: number): number { + return ((value % 60) + 60) % 60; + } } diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts index bca49632d..68d986481 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-card/trainrun-section-card.component.ts @@ -208,7 +208,7 @@ export class TrainrunSectionCardComponent implements OnInit, AfterViewInit, OnDe this.trainrunService.updateDirection(selectedTrainrun, Direction.ONE_WAY); } - getTrainrunTimeStructure(): Omit { + getTrainrunTimeStructure(): Omit { const selectedTrainrun = this.trainrunService.getSelectedTrainrun(); if (!selectedTrainrun) { return undefined; diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.ts b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.ts index 9675cd0a4..200283b7e 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.ts +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.ts @@ -31,6 +31,7 @@ export interface LeftAndRightTimeStructure { rightDepartureTime: number; rightArrivalTime: number; travelTime: number; + stopTime: number; } export interface LeftAndRightLockStructure { From 85d0b394f742f014a5ea9f65553e18c78dacec4e Mon Sep 17 00:00:00 2001 From: Clara Ni Date: Fri, 31 Oct 2025 15:31:24 +0100 Subject: [PATCH 07/54] feat: correctly update arrival/departure/travel times when a node is masked The behavior is pretty much the same as when a node is a non-stop node, except when updating the travel time, because we need to take into account the stop times of the reduced nodes. Signed-off-by: Clara Ni --- .../algorithms/shortest-travel-time-search.ts | 2 +- src/app/services/data/trainrun.service.ts | 24 ++++++++------ .../services/data/trainrunsection.service.ts | 32 ++++++++++++++----- src/app/services/util/trainrun.iterator.ts | 8 +++-- .../trainIterator.test.spec.ts | 4 +-- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/app/services/analytics/algorithms/shortest-travel-time-search.ts b/src/app/services/analytics/algorithms/shortest-travel-time-search.ts index 2414d804e..ed0e2a825 100644 --- a/src/app/services/analytics/algorithms/shortest-travel-time-search.ts +++ b/src/app/services/analytics/algorithms/shortest-travel-time-search.ts @@ -352,7 +352,7 @@ export class ShortestTravelTimeSearch { private getOutgoingEdge(trainrunSection: TrainrunSection, node: Node): ShortestDistanceEdge { const path: TrainrunSection[] = []; - const iterator = this.trainrunService.getNonStopIterator(node, trainrunSection); + const iterator = this.trainrunService.getNextExpandedStopIterator(node, trainrunSection); while (iterator.hasNext()) { iterator.next(); diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index a83f0dce2..93cbf7da2 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -20,7 +20,7 @@ import {GeneralViewFunctions} from "../../view/util/generalViewFunctions"; import { BackwardNonStopTrainrunIterator, BackwardTrainrunIterator, - NonStopTrainrunIterator, + NextExpandedStopIterator, TrainrunIterator, } from "../util/trainrun.iterator"; import {LogService} from "../../logger/log.service"; @@ -663,7 +663,7 @@ export class TrainrunService { } getLastNonStopNode(node: Node, trainrunSection: TrainrunSection): Node { - const iterator = this.getNonStopIterator(node, trainrunSection); + const iterator = this.getNextExpandedStopIterator(node, trainrunSection); while (iterator.hasNext()) { iterator.next(); } @@ -680,7 +680,7 @@ export class TrainrunService { } getLastNonStopTrainrunSection(node: Node, trainrunSection: TrainrunSection): TrainrunSection { - const iterator = this.getNonStopIterator(node, trainrunSection); + const iterator = this.getNextExpandedStopIterator(node, trainrunSection); while (iterator.hasNext()) { iterator.next(); } @@ -725,7 +725,7 @@ export class TrainrunService { sumTravelTimeUpToLastNonStopNode(node: Node, trainrunSection: TrainrunSection): number { let summedTravelTime = 0; - const iterator = this.getNonStopIterator(node, trainrunSection); + const iterator = this.getNextExpandedStopIterator(node, trainrunSection); while (iterator.hasNext()) { const nextPair = iterator.next(); summedTravelTime += nextPair.trainrunSection.getTravelTime(); @@ -734,7 +734,10 @@ export class TrainrunService { } getCumulativeTravelTime(trainrunSection: TrainrunSection) { - const iterator = this.getNonStopIterator(trainrunSection.getSourceNode(), trainrunSection); + const iterator = this.getNextExpandedStopIterator( + trainrunSection.getSourceNode(), + trainrunSection, + ); while (iterator.hasNext()) { iterator.next(); } @@ -753,7 +756,7 @@ export class TrainrunService { }, ]; let summedTravelTime = 0; - const iterator = this.getNonStopIterator(n, ts); + const iterator = this.getNextExpandedStopIterator(n, ts); while (iterator.hasNext()) { const nextPair = iterator.next(); summedTravelTime += nextPair.trainrunSection.getTravelTime(); @@ -767,7 +770,10 @@ export class TrainrunService { } getCumulativeTravelTimeAndNodePath(trainrunSection: TrainrunSection) { - const iterator = this.getNonStopIterator(trainrunSection.getSourceNode(), trainrunSection); + const iterator = this.getNextExpandedStopIterator( + trainrunSection.getSourceNode(), + trainrunSection, + ); while (iterator.hasNext()) { iterator.next(); } @@ -788,8 +794,8 @@ export class TrainrunService { return new TrainrunIterator(this.logService, node, trainrunSection); } - public getNonStopIterator(node: Node, trainrunSection: TrainrunSection) { - return new NonStopTrainrunIterator(this.logService, node, trainrunSection); + public getNextExpandedStopIterator(node: Node, trainrunSection: TrainrunSection) { + return new NextExpandedStopIterator(this.logService, node, trainrunSection); } public getBackwardIterator(node: Node, trainrunSection: TrainrunSection) { diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 72128be2d..ed4c4cfef 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -321,7 +321,7 @@ export class TrainrunSectionService implements OnDestroy { node: Node, stopNodeId: number, ) { - const iterator = this.trainrunService.getNonStopIterator(node, trainrunSection); + const iterator = this.trainrunService.getNextExpandedStopIterator(node, trainrunSection); while (iterator.hasNext()) { iterator.next(); if (iterator.current().node.getId() === stopNodeId) { @@ -875,12 +875,30 @@ export class TrainrunSectionService implements OnDestroy { const trsTimeStructure = TrainrunsectionHelper.getDefaultTimeStructure(timeStructure); let summedTravelTime = 0; - const iterator = this.trainrunService.getNonStopIterator(leftNode, trs); + const iterator = this.trainrunService.getNextExpandedStopIterator(leftNode, trs); + let prevInitialLeftArrival: number = null; + let stopTime: number; while (iterator.hasNext()) { const nextPair = iterator.next(); + const rightIsTarget = + nextPair.node.getId() === nextPair.trainrunSection.getTargetNode().getId(); + + if (prevInitialLeftArrival !== null) { + stopTime = MathUtils.mod60( + (rightIsTarget + ? nextPair.trainrunSection.getSourceDeparture() + : nextPair.trainrunSection.getTargetDeparture()) - prevInitialLeftArrival, + ); + trsTimeStructure.leftDepartureTime = trsTimeStructure.rightArrivalTime + stopTime; + trsTimeStructure.leftArrivalTime = trsTimeStructure.rightDepartureTime - stopTime; + } + prevInitialLeftArrival = rightIsTarget + ? nextPair.trainrunSection.getTargetArrival() + : nextPair.trainrunSection.getSourceArrival(); - const isLastNode = !nextPair.node.isNonStop(nextPair.trainrunSection); - trsTimeStructure.travelTime = isLastNode + const isLastRightNode = + !nextPair.node.isNonStop(nextPair.trainrunSection) && !nextPair.node.getIsCollapsed(); + trsTimeStructure.travelTime = isLastRightNode ? TrainrunsectionHelper.getLastSectionTravelTime( newTotalTravelTime, summedTravelTime, @@ -891,6 +909,7 @@ export class TrainrunSectionService implements OnDestroy { travelTimeFactor, precision, ); + trsTimeStructure.rightArrivalTime = TrainrunsectionHelper.getRightArrivalTime( trsTimeStructure, precision, @@ -899,8 +918,7 @@ export class TrainrunSectionService implements OnDestroy { trsTimeStructure, precision, ); - const rightIsTarget = - nextPair.node.getId() === nextPair.trainrunSection.getTargetNode().getId(); + this.updateTrainrunSectionTime( nextPair.trainrunSection.getId(), rightIsTarget ? trsTimeStructure.leftArrivalTime : trsTimeStructure.rightArrivalTime, @@ -910,8 +928,6 @@ export class TrainrunSectionService implements OnDestroy { trsTimeStructure.travelTime, ); - trsTimeStructure.leftDepartureTime = trsTimeStructure.rightArrivalTime; - trsTimeStructure.leftArrivalTime = trsTimeStructure.rightDepartureTime; summedTravelTime += trsTimeStructure.travelTime; } diff --git a/src/app/services/util/trainrun.iterator.ts b/src/app/services/util/trainrun.iterator.ts index 9018e02ad..f134e4b51 100644 --- a/src/app/services/util/trainrun.iterator.ts +++ b/src/app/services/util/trainrun.iterator.ts @@ -112,9 +112,13 @@ export class BackwardTrainrunIterator extends TrainrunIterator { } } -export class NonStopTrainrunIterator extends TrainrunIterator { +/** Iterate on the trainrun sections until we find a node which is a stop of the trainrun and not collapsed */ +export class NextExpandedStopIterator extends TrainrunIterator { public next(): TrainrunSectionNodePair { - if (!this.pointerElement.node.isNonStop(this.pointerElement.trainrunSection)) { + if ( + !this.pointerElement.node.isNonStop(this.pointerElement.trainrunSection) && + !this.pointerElement.node.getIsCollapsed() + ) { // The trainrun has a stop and break the forward iteration this.currentElement = Object.assign({}, this.pointerElement); this.pointerElement = new TrainrunSectionNodePair(undefined, undefined); diff --git a/src/integration-testing/trainIterator.test.spec.ts b/src/integration-testing/trainIterator.test.spec.ts index f35f3e74b..f767dc835 100644 --- a/src/integration-testing/trainIterator.test.spec.ts +++ b/src/integration-testing/trainIterator.test.spec.ts @@ -7,7 +7,7 @@ import {ResourceService} from "../app/services/data/resource.service"; import {LogService} from "../app/logger/log.service"; import {LogPublishersService} from "../app/logger/log.publishers.service"; import {NetzgrafikUnitTesting} from "./netzgrafik.unit.testing"; -import {NonStopTrainrunIterator, TrainrunIterator} from "../app/services/util/trainrun.iterator"; +import {NextExpandedStopIterator, TrainrunIterator} from "../app/services/util/trainrun.iterator"; import {NoteService} from "../app/services/data/note.service"; import {LabelGroupService} from "../app/services/data/labelgroup.service"; import {LabelService} from "../app/services/data/label.service"; @@ -146,7 +146,7 @@ describe("TrainrunSection Service Test", () => { const iteratorNodeIds = [1, 2]; - const itr = new NonStopTrainrunIterator( + const itr = new NextExpandedStopIterator( logService, node2, node2.getTrainrunSection(startingTrainrunSection.getTrainrun()), From 6e4c9f3c8bd5a29dd113bf9fa16e8366ed330c44 Mon Sep 17 00:00:00 2001 From: Clara Ni Date: Tue, 4 Nov 2025 15:09:12 +0100 Subject: [PATCH 08/54] feat: display total stop duration of the trainrun section on the section tab Signed-off-by: Clara Ni --- .../trainrunsection-tab/trainrun-section-tab.component.html | 3 +++ .../trainrunsection-tab/trainrun-section-tab.component.scss | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html index 4cc193e1a..db1bb74fa 100644 --- a/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html +++ b/src/app/view/dialogs/trainrun-and-section-dialog/trainrunsection-tab/trainrun-section-tab.component.html @@ -266,6 +266,9 @@ - +
+

+ {{ trainrunSectionTimesService.getTimeStructure().stopTime }}' stop

+
Date: Mon, 24 Nov 2025 15:41:05 +0100 Subject: [PATCH 09/54] import: set node position before calling replaceIntermediateStopWithNode() replaceIntermediateStopWithNode() recomputes a bunch of transition position stuff. At import time, tt was working with incorrect node positions, routing everything to the (0, 0) position. This causes transition positions to be mis-rendered. Instead, set the node position at initialization, before calling replaceIntermediateStopWithNode(). That way the function can work with the final node position. As a bonus, the "new node" event is fired with the correct node position. Signed-off-by: Simon Ser Fixes: 435f1c66b8ed ("import: handle importing old files with numberOfStops") --- src/app/services/data/data.service.ts | 24 ++++++++++++++++-------- src/app/services/data/node.service.ts | 3 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/app/services/data/data.service.ts b/src/app/services/data/data.service.ts index d7c756a35..e05fb5dcf 100644 --- a/src/app/services/data/data.service.ts +++ b/src/app/services/data/data.service.ts @@ -112,20 +112,28 @@ export class DataService implements OnDestroy { for (const trainrunSection of netzgrafikDto.trainrunSections) { let currentSection = trainrunSection; for (let i = 0; i < trainrunSection.numberOfStops; i++) { - const newNode = this.nodeService.addEmptyNode(); + const oldTrainrunSection = this.trainrunSectionService.getTrainrunSectionFromId( + currentSection.id, + ); + const sourceNode = oldTrainrunSection.getSourceNode(); + const targetNode = oldTrainrunSection.getTargetNode(); + const interpolatedPosition = new Vec2D( + sourceNode.getPositionX() + (targetNode.getPositionX() - sourceNode.getPositionX()) * 0.5, + sourceNode.getPositionY() + (targetNode.getPositionY() - sourceNode.getPositionY()) * 0.5, + ); + + const newNode = this.nodeService.addEmptyNode( + interpolatedPosition.getX(), + interpolatedPosition.getY(), + ); + const {existingTrainRunSection, newTrainRunSection} = this.trainrunSectionService.replaceIntermediateStopWithNode( currentSection.id, 0, newNode.getId(), ); - const sourceNode = existingTrainRunSection.getSourceNode(); - const targetNode = newTrainRunSection.getTargetNode(); - const interpolatedPosition = new Vec2D( - sourceNode.getPositionX() + (targetNode.getPositionX() - sourceNode.getPositionX()) * 0.5, - sourceNode.getPositionY() + (targetNode.getPositionY() - sourceNode.getPositionY()) * 0.5, - ); - newNode.setPosition(interpolatedPosition.getX(), interpolatedPosition.getY()); + currentSection = newTrainRunSection.getDto(); } } diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index 28c3e3ac9..f53c3ab7f 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -254,8 +254,9 @@ export class NodeService implements OnDestroy { return node; } - addEmptyNode(): Node { + addEmptyNode(positionX: number, positionY: number): Node { const node: Node = new Node(); + node.setPosition(positionX, positionY); node.setIsCollapsed(true); const resource: Resource = this.resourceService.createAndGetResource(); node.setResourceId(resource.getId()); From f8b6a5325c30db58e1f46c0a4cb046db18823c75 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Tue, 7 Oct 2025 11:54:17 +0200 Subject: [PATCH 10/54] nodes: add the iscollapsed param to the node diplay filtering function --- src/app/view/editor-main-view/data-views/nodes.view.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/nodes.view.ts b/src/app/view/editor-main-view/data-views/nodes.view.ts index 960fa7efd..79cb10504 100644 --- a/src/app/view/editor-main-view/data-views/nodes.view.ts +++ b/src/app/view/editor-main-view/data-views/nodes.view.ts @@ -89,7 +89,7 @@ export class NodesView { } filterNodesToDisplay(node: Node): boolean { - return this.editorView.isNodeVisible(node); + return this.editorView.isNodeVisible(node) && !node.getIsCollapsed(); } displayNodes(inputNodes: Node[]) { From 0266b004509a816d068888143d57ba54d657e77c Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Tue, 7 Oct 2025 14:48:47 +0200 Subject: [PATCH 11/54] feat: add grouping function for collapsed nodes in TrainrunSectionService --- .../services/data/trainrunsection.service.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index ed4c4cfef..3de249465 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -1490,4 +1490,72 @@ export class TrainrunSectionService implements OnDestroy { trainrunSection.routeEdgeAndPlaceText(); trainrunSection.convertVec2DToPath(); } + + /** + * Groups consecutive TrainrunSections that have collapsed nodes between them + * into chains with start and end nodes. Each chain starts and ends with a non-collapsed node. + * @param trainrunSections List of TrainrunSections to group + * @returns Array of section groups with start/end nodes + */ + groupTrainrunSectionsIntoChains(trainrunSections: TrainrunSection[]): Array<{ + sections: TrainrunSection[]; + startNode: Node; + endNode: Node; + }> { + const groups: Array<{ + sections: TrainrunSection[]; + startNode: Node; + endNode: Node; + }> = []; + const visitedSections = new Set(); + + trainrunSections.forEach((section) => { + if (visitedSections.has(section.getId())) { + return; + } + + // Start a new group from this section + const chain: TrainrunSection[] = []; + let currentSection = section; + + // Add the first section + chain.push(currentSection); + visitedSections.add(currentSection.getId()); + + // Look for consecutive sections with collapsed intermediate nodes + // eslint-disable-next-line no-constant-condition + while (true) { + const targetNode = this.nodeService.getNodeFromId(currentSection.getTargetNodeId()); + if (!targetNode || !targetNode.getIsCollapsed()) { + break; // End of chain if target node is not collapsed + } + + // Find next section starting from this collapsed node + const nextSection = trainrunSections.find( + (ts) => + ts.getSourceNodeId() === currentSection.getTargetNodeId() && + ts.getTrainrunId() === currentSection.getTrainrunId() && + !visitedSections.has(ts.getId()), + ); + if (!nextSection) { + break; // No further section found, end of chain + } + chain.push(nextSection); + visitedSections.add(nextSection.getId()); + currentSection = nextSection; + } + + // Create group with start and end nodes + const startNode = this.nodeService.getNodeFromId(chain[0].getSourceNodeId()); + const endNode = this.nodeService.getNodeFromId(chain[chain.length - 1].getTargetNodeId()); + + groups.push({ + sections: chain, + startNode: startNode, + endNode: endNode, + }); + }); + + return groups; + } } From 0bf164442e68d98dec726cf719efc1a21da0f205 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Tue, 7 Oct 2025 14:59:52 +0200 Subject: [PATCH 12/54] feat: implement TrainrunSection grouping in view layer for collapsed nodes --- .../data-views/editor.view.ts | 2 +- .../data-views/trainrunsections.view.ts | 68 ++++++++++++++----- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/editor.view.ts b/src/app/view/editor-main-view/data-views/editor.view.ts index 3ec5b1835..867169316 100644 --- a/src/app/view/editor-main-view/data-views/editor.view.ts +++ b/src/app/view/editor-main-view/data-views/editor.view.ts @@ -136,7 +136,7 @@ export class EditorView implements SVGMouseControllerObserver { this.nodesView = new NodesView(this); this.transitionsView = new TransitionsView(this); this.connectionsView = new ConnectionsView(this); - this.trainrunSectionsView = new TrainrunSectionsView(this); + this.trainrunSectionsView = new TrainrunSectionsView(this, trainrunSectionService); this.trainrunSectionPreviewLineView = new TrainrunSectionPreviewLineView( nodeService, filterService, diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 6b09c99b3..547b85d84 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -28,6 +28,7 @@ import {EditorMode} from "../../editor-menu/editor-mode"; import {Transition} from "../../../models/transition.model"; import {InformSelectedTrainrunClick} from "../../../services/data/trainrunsection.service"; import {LevelOfDetail} from "../../../services/ui/level.of.detail.service"; +import {TrainrunSectionService} from "../../../services/data/trainrunsection.service"; import {LinePatternRefs} from "../../../data-structures/business.data.structures"; import {Direction} from "src/app/data-structures/business.data.structures"; import {GeneralViewFunctions} from "../../util/generalViewFunctions"; @@ -36,7 +37,10 @@ import {TrainrunsectionHelper} from "src/app/services/util/trainrunsection.helpe export class TrainrunSectionsView { trainrunSectionGroup; - constructor(private editorView: EditorView) {} + constructor( + private editorView: EditorView, + private trainrunSectionService: TrainrunSectionService, + ) {} static translateAndRotateText( trainrunSection: TrainrunSection, @@ -1656,23 +1660,53 @@ export class TrainrunSectionsView { connectedTrainIds: any, ): TrainrunSectionViewObject[] { const viewTrainrunSectionDataObjects: TrainrunSectionViewObject[] = []; - inputTrainrunSections.forEach((d: TrainrunSection) => { - viewTrainrunSectionDataObjects.push( - new TrainrunSectionViewObject( - editorView, - d, - TrainrunSectionsView.getNode(d, true).isNonStop(d), - TrainrunSectionsView.getNode(d, false).isNonStop(d), - TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.isFilterDirectionArrowsEnabled(), - ), - ); + + // Group sections by collapsed nodes + const sectionGroups = + this.trainrunSectionService.groupTrainrunSectionsIntoChains(inputTrainrunSections); + + sectionGroups.forEach((group) => { + if (group.sections.length === 1) { + // Simple section without collapsed intermediate nodes + const d = group.sections[0]; + viewTrainrunSectionDataObjects.push( + new TrainrunSectionViewObject( + editorView, + d, + TrainrunSectionsView.getNode(d, true).isNonStop(d), + TrainrunSectionsView.getNode(d, false).isNonStop(d), + TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.isFilterDirectionArrowsEnabled(), + ), + ); + } else { + // Chain of sections with collapsed nodes - create single view object + // Use the first section as the primary reference + const primarySection = group.sections[0]; + const lastSection = group.sections[group.sections.length - 1]; + viewTrainrunSectionDataObjects.push( + new TrainrunSectionViewObject( + editorView, + primarySection, + group.startNode.isNonStop(primarySection), + group.endNode.isNonStop(lastSection), + TrainrunSectionsView.isMuted(primarySection, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(primarySection, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(lastSection, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(primarySection, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(primarySection, TrainrunSectionText.TrainrunSectionName), + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.isFilterDirectionArrowsEnabled(), + ), + ); + } }); + return viewTrainrunSectionDataObjects; } From a020164088b94f67eeb72ded6cdf119edead7cf7 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Tue, 7 Oct 2025 15:29:10 +0200 Subject: [PATCH 13/54] fix: implement custom path calculation for collapsed node chains - Add createViewObjectForCollapsedChain() static method to handle path routing between start/end nodes - Replace standard TrainrunSectionViewObject creation with custom method for collapsed chains - Path now correctly goes from first visible node to last visible node instead of using primary section's path --- .../data-views/connections.view.ts | 6 ++ .../data-views/trainrunsections.view.ts | 78 ++++++++++++++++++- .../data-views/transitions.view.ts | 5 ++ 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/connections.view.ts b/src/app/view/editor-main-view/data-views/connections.view.ts index aa823395d..3309e4695 100644 --- a/src/app/view/editor-main-view/data-views/connections.view.ts +++ b/src/app/view/editor-main-view/data-views/connections.view.ts @@ -240,6 +240,12 @@ export class ConnectionsView { } const node: Node = this.editorView.getNodeFromConnection(con); + + // filter if node is collapsed - do not show connections for collapsed nodes + if (node.getIsCollapsed()) { + return false; + } + const trainrunSection1: TrainrunSection = node.getPort(con.getPortId1()).getTrainrunSection(); const trainrunSection2: TrainrunSection = node.getPort(con.getPortId2()).getTrainrunSection(); const filterTrainrun1 = this.editorView.filterTrainrun(trainrunSection1.getTrainrun()); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 547b85d84..93df7f587 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -152,6 +152,79 @@ export class TrainrunSectionsView { return atSource ? trainrunSection.getSourceNode() : trainrunSection.getTargetNode(); } + /** + * Creates a TrainrunSectionViewObject for collapsed node chains where the visual path + * goes directly from startNode to endNode instead of using the primary section's path. + * This is used when intermediate nodes are collapsed and should not be visible. + */ + static createViewObjectForCollapsedChain( + editorView: EditorView, + primarySection: TrainrunSection, + allSections: TrainrunSection[], + startNode: Node, + endNode: Node, + isNonStopAtSource: boolean, + isNonStopAtTarget: boolean, + isMuted: boolean, + hiddenTagSource: boolean, + hiddenTagTarget: boolean, + hiddenTagTraveltime: boolean, + hiddenTagTrainrunName: boolean, + hiddenTagDirectionArrows: boolean, + ): TrainrunSectionViewObject { + // Create a standard view object first + const viewObject = new TrainrunSectionViewObject( + editorView, + primarySection, + isNonStopAtSource, + isNonStopAtTarget, + isMuted, + hiddenTagSource, + hiddenTagTarget, + hiddenTagTraveltime, + hiddenTagTrainrunName, + hiddenTagDirectionArrows, + ); + + // Override the path calculation to use startNode and endNode + // We need to temporarily modify the primary section's nodes for path calculation + const originalSourceNode = primarySection.getSourceNode(); + const originalTargetNode = primarySection.getTargetNode(); + const originalSourcePortId = primarySection.getSourcePortId(); + const originalTargetPortId = primarySection.getTargetPortId(); + + try { + // Set temporary nodes for path calculation + primarySection.setSourceNode(startNode); + primarySection.setTargetNode(endNode); + + // Find appropriate ports using the correct sections from the chain + // Source port: from the first section of the chain + // Target port: from the last section of the chain + const firstSection = allSections[0]; + const lastSection = allSections[allSections.length - 1]; + + const sourcePort = + startNode.getPortOfTrainrunSection(firstSection.getId()) || startNode.getPorts()[0]; + const targetPort = + endNode.getPortOfTrainrunSection(lastSection.getId()) || endNode.getPorts()[0]; + + primarySection.setSourcePortId(sourcePort.getId()); + primarySection.setTargetPortId(targetPort.getId()); + + // Recalculate path with new nodes + primarySection.routeEdgeAndPlaceText(); + } finally { + // Restore original nodes and ports + primarySection.setSourceNode(originalSourceNode); + primarySection.setTargetNode(originalTargetNode); + primarySection.setSourcePortId(originalSourcePortId); + primarySection.setTargetPortId(originalTargetPortId); + } + + return viewObject; + } + static hasWarning(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): boolean { switch (textElement) { case TrainrunSectionText.SourceDeparture: @@ -1690,9 +1763,12 @@ export class TrainrunSectionsView { const primarySection = group.sections[0]; const lastSection = group.sections[group.sections.length - 1]; viewTrainrunSectionDataObjects.push( - new TrainrunSectionViewObject( + TrainrunSectionsView.createViewObjectForCollapsedChain( editorView, primarySection, + group.sections, + group.startNode, + group.endNode, group.startNode.isNonStop(primarySection), group.endNode.isNonStop(lastSection), TrainrunSectionsView.isMuted(primarySection, selectedTrainrun, connectedTrainIds), diff --git a/src/app/view/editor-main-view/data-views/transitions.view.ts b/src/app/view/editor-main-view/data-views/transitions.view.ts index cd3248105..48e451b51 100644 --- a/src/app/view/editor-main-view/data-views/transitions.view.ts +++ b/src/app/view/editor-main-view/data-views/transitions.view.ts @@ -177,6 +177,11 @@ export class TransitionsView { } const node = this.editorView.getNodeFromTransition(transition); + + if (node.getIsCollapsed()) { + return false; + } + if (!this.editorView.checkFilterNonStopNode(node)) { return false; } From c5ed38c9ca35341b7bc66623bd7387e3523f6e2f Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 16 Oct 2025 13:49:22 +0200 Subject: [PATCH 14/54] fix : calc without temporal dto changes + avoid manual handroll --- src/app/services/data/trainrun.service.ts | 5 + .../services/data/trainrunsection.service.ts | 70 +- src/app/services/util/trainrun.iterator.ts | 14 + .../data-views/trainrunSectionViewObject.ts | 6 + .../data-views/trainrunsections.view.ts | 700 ++++++++++++++---- src/app/view/rastering/definitions.ts | 10 + 6 files changed, 611 insertions(+), 194 deletions(-) diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index 93cbf7da2..a8e2f0b15 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -22,6 +22,7 @@ import { BackwardTrainrunIterator, NextExpandedStopIterator, TrainrunIterator, + ExpandedTrainrunIterator, } from "../util/trainrun.iterator"; import {LogService} from "../../logger/log.service"; import {LabelService} from "./label.service"; @@ -805,6 +806,10 @@ export class TrainrunService { public getBackwardNonStopIterator(node: Node, trainrunSection: TrainrunSection) { return new BackwardNonStopTrainrunIterator(this.logService, node, trainrunSection); } + + public getExpandedIterator(node: Node, trainrunSection: TrainrunSection) { + return new ExpandedTrainrunIterator(this.logService, node, trainrunSection); + } // For each trainrun, get iterator from the smallest consecutiveTime. public getRootIterators(): Map { diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index 3de249465..af758b750 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -1493,20 +1493,13 @@ export class TrainrunSectionService implements OnDestroy { /** * Groups consecutive TrainrunSections that have collapsed nodes between them - * into chains with start and end nodes. Each chain starts and ends with a non-collapsed node. + * into chains. Each chain starts and ends with a non-collapsed node. + * Start and end nodes can be accessed via: sections[0].getSourceNode() and sections[sections.length - 1].getTargetNode() * @param trainrunSections List of TrainrunSections to group - * @returns Array of section groups with start/end nodes + * @returns Array of section chains */ - groupTrainrunSectionsIntoChains(trainrunSections: TrainrunSection[]): Array<{ - sections: TrainrunSection[]; - startNode: Node; - endNode: Node; - }> { - const groups: Array<{ - sections: TrainrunSection[]; - startNode: Node; - endNode: Node; - }> = []; + groupTrainrunSectionsIntoChains(trainrunSections: TrainrunSection[]): TrainrunSection[][] { + const groups: TrainrunSection[][] = []; const visitedSections = new Set(); trainrunSections.forEach((section) => { @@ -1514,46 +1507,31 @@ export class TrainrunSectionService implements OnDestroy { return; } - // Start a new group from this section + // Build chain using TrainrunIterator to leverage existing graph traversal const chain: TrainrunSection[] = []; - let currentSection = section; - - // Add the first section - chain.push(currentSection); - visitedSections.add(currentSection.getId()); - - // Look for consecutive sections with collapsed intermediate nodes - // eslint-disable-next-line no-constant-condition - while (true) { - const targetNode = this.nodeService.getNodeFromId(currentSection.getTargetNodeId()); - if (!targetNode || !targetNode.getIsCollapsed()) { - break; // End of chain if target node is not collapsed + const startNode = section.getSourceNode(); + const iterator = this.trainrunService.getIterator(startNode, section); + + // Traverse the trainrun and collect sections with collapsed intermediate nodes + while (iterator.hasNext()) { + const pair = iterator.next(); + + if (visitedSections.has(pair.trainrunSection.getId())) { + break; // Already processed this section } - // Find next section starting from this collapsed node - const nextSection = trainrunSections.find( - (ts) => - ts.getSourceNodeId() === currentSection.getTargetNodeId() && - ts.getTrainrunId() === currentSection.getTrainrunId() && - !visitedSections.has(ts.getId()), - ); - if (!nextSection) { - break; // No further section found, end of chain + chain.push(pair.trainrunSection); + visitedSections.add(pair.trainrunSection.getId()); + + // Stop if we reach a non-collapsed node (end of collapsed chain) + if (!pair.node.getIsCollapsed()) { + break; } - chain.push(nextSection); - visitedSections.add(nextSection.getId()); - currentSection = nextSection; } - // Create group with start and end nodes - const startNode = this.nodeService.getNodeFromId(chain[0].getSourceNodeId()); - const endNode = this.nodeService.getNodeFromId(chain[chain.length - 1].getTargetNodeId()); - - groups.push({ - sections: chain, - startNode: startNode, - endNode: endNode, - }); + if (chain.length > 0) { + groups.push(chain); + } }); return groups; diff --git a/src/app/services/util/trainrun.iterator.ts b/src/app/services/util/trainrun.iterator.ts index f134e4b51..74dcaad3c 100644 --- a/src/app/services/util/trainrun.iterator.ts +++ b/src/app/services/util/trainrun.iterator.ts @@ -139,3 +139,17 @@ export class BackwardNonStopTrainrunIterator extends BackwardTrainrunIterator { return super.next(); } } + +export class ExpandedTrainrunIterator extends TrainrunIterator { + public next(): TrainrunSectionNodePair { + // Continue traversing only if the current node is collapsed + // Stop when we reach an expanded (non-collapsed) node + if (!this.pointerElement.node.getIsCollapsed()) { + // The trainrun has reached an expanded (non-collapsed) node and break the forward iteration + this.currentElement = Object.assign({}, this.pointerElement); + this.pointerElement = new TrainrunSectionNodePair(undefined, undefined); + return this.currentElement; + } + return super.next(); + } +} diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 73e221407..40d5bca31 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -156,6 +156,12 @@ export class TrainrunSectionViewObject { d.getPath().forEach((p) => { key += p.toString(); }); + + key += "_SRC_" + d.getSourceNode().getPositionX() + "_" + d.getSourceNode().getPositionY(); + key += "_TRG_" + d.getTargetNode().getPositionX() + "_" + d.getTargetNode().getPositionY(); + return key; } + + } diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 93df7f587..7411195cc 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1,8 +1,14 @@ import { + ANGLE_UPSIDE_DOWN_THRESHOLD, + DEFAULT_ANGLE_HORIZONTAL, + DEFAULT_ANGLE_VERTICAL, DEFAULT_PIN_RADIUS, DEFAULT_STOP_ICON, + EDGE_CASE_THRESHOLD, + MIN_PATH_LENGTH_FOR_ANGLE, NODE_EDGE_WIDTH, NODE_TEXT_AREA_HEIGHT, + PATH_COMPARISON_TOLERANCE, RASTERING_BASIC_GRID_SIZE, SHOW_MAX_SINGLE_TRAINRUN_SECTIONS_STOPS, TRAINRUN_SECTION_TEXT_AREA_HEIGHT, @@ -18,12 +24,14 @@ import { import {StaticDomTags} from "./static.dom.tags"; import {TrainrunSection} from "../../../models/trainrunsection.model"; import {EditorView} from "./editor.view"; + import {D3Utils} from "./d3.utils"; import {DragIntermediateStopInfo, PreviewLineMode} from "./trainrunsection.previewline.view"; import {MathUtils} from "../../../utils/math"; import {Trainrun} from "../../../models/trainrun.model"; import {TrainrunSectionViewObject} from "./trainrunSectionViewObject"; import {Node} from "../../../models/node.model"; +import {Port} from "../../../models/port.model"; import {EditorMode} from "../../editor-menu/editor-mode"; import {Transition} from "../../../models/transition.model"; import {InformSelectedTrainrunClick} from "../../../services/data/trainrunsection.service"; @@ -33,6 +41,7 @@ import {LinePatternRefs} from "../../../data-structures/business.data.structures import {Direction} from "src/app/data-structures/business.data.structures"; import {GeneralViewFunctions} from "../../util/generalViewFunctions"; import {TrainrunsectionHelper} from "src/app/services/util/trainrunsection.helper"; +import {SimpleTrainrunSectionRouter} from "../../../services/util/trainrunsection.routing"; export class TrainrunSectionsView { trainrunSectionGroup; @@ -54,19 +63,140 @@ export class TrainrunSectionsView { const t1: Vec2D = pathVec2D[2]; const diff: Vec2D = Vec2D.sub(t1, s1); let a: number = (Math.atan2(diff.getY(), diff.getX()) / Math.PI) * 180.0; - if (Math.abs(a) > 90) { + if (Math.abs(a) > ANGLE_UPSIDE_DOWN_THRESHOLD) { a = a + 180; } // Math.atan2 -> edge cases -> correct manually - if (Math.abs(diff.getX()) < 1) { - a = -90; + if (Math.abs(diff.getX()) < EDGE_CASE_THRESHOLD) { + a = DEFAULT_ANGLE_VERTICAL; } - if (Math.abs(diff.getY()) < 1) { - a = 0; + if (Math.abs(diff.getY()) < EDGE_CASE_THRESHOLD) { + a = DEFAULT_ANGLE_HORIZONTAL; } return "translate(" + x + "," + y + ") rotate(" + a + ", 0,0) "; } + /** + * Version that works with TrainrunSectionViewObject to handle custom paths for collapsed chains + * This method needs access to the view instance to get the collapsed path + */ + static translateAndRotateTextForViewObject( + viewObject: TrainrunSectionViewObject, + trainrunSectionText: TrainrunSectionText, + ) { + const trainrunSection = viewObject.trainrunSection; + + const x = trainrunSection.getTextPositionX(trainrunSectionText); + const y = trainrunSection.getTextPositionY(trainrunSectionText); + const originalPath = trainrunSection.getPath(); + + if (originalPath.length >= 4) { + const s1: Vec2D = originalPath[1]; + const t1: Vec2D = originalPath[2]; + const diff: Vec2D = Vec2D.sub(t1, s1); + let a: number = (Math.atan2(diff.getY(), diff.getX()) / Math.PI) * 180.0; + if (Math.abs(a) > ANGLE_UPSIDE_DOWN_THRESHOLD) { + a = a + 180; + } + // Math.atan2 -> edge cases -> correct manually + if (Math.abs(diff.getX()) < EDGE_CASE_THRESHOLD) { + a = DEFAULT_ANGLE_VERTICAL; + } + if (Math.abs(diff.getY()) < EDGE_CASE_THRESHOLD) { + a = DEFAULT_ANGLE_HORIZONTAL; + } + return "translate(" + x + "," + y + ") rotate(" + a + ", 0,0) "; + } + + return "translate(" + x + "," + y + ") rotate(0, 0,0) "; + } + + private getTextPositionsForCollapsedChain( + collapsedChainPath: Vec2D[], + trainrunSection: TrainrunSection, + ): any { + const sourceNode = trainrunSection.getSourceNode(); + const sourcePort = + sourceNode.getPortOfTrainrunSection(trainrunSection.getId()) || sourceNode.getPorts()[0]; + + if (!sourcePort) { + return null; + } + + return SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedChainPath, sourcePort); + } + + + + getAdditionPositioningValueForViewObjectWithCollapsedSupport( + viewObject: TrainrunSectionViewObject, + textElement: TrainrunSectionText, + ) { + switch (textElement) { + case TrainrunSectionText.SourceDeparture: + case TrainrunSectionText.SourceArrival: + case TrainrunSectionText.TargetDeparture: + case TrainrunSectionText.TargetArrival: + return 1.5; + case TrainrunSectionText.TrainrunSectionTravelTime: + case TrainrunSectionText.TrainrunSectionName: + return this.translateAndRotateTextForViewObjectWithCollapsedSupport( + viewObject, + textElement, + ); + default: + return 0; + } + } + + translateAndRotateTextForViewObjectWithCollapsedSupport( + viewObject: TrainrunSectionViewObject, + trainrunSectionText: TrainrunSectionText, + ) { + const trainrunSection = viewObject.trainrunSection; + const collapsedChainPath = this.getCollapsedChainPath(trainrunSection); + + if (collapsedChainPath && collapsedChainPath.length >= MIN_PATH_LENGTH_FOR_ANGLE) { + const textPositions = this.getTextPositionsForCollapsedChain( + collapsedChainPath, + trainrunSection, + ); + const x = + textPositions?.[trainrunSectionText]?.x ?? + trainrunSection.getTextPositionX(trainrunSectionText); + const y = + textPositions?.[trainrunSectionText]?.y ?? + trainrunSection.getTextPositionY(trainrunSectionText); + + // Use existing calculation logic with collapsed path + if (collapsedChainPath.length < MIN_PATH_LENGTH_FOR_ANGLE) { + return `translate(${x},${y}) rotate(0, 0,0) `; + } + + const [s1, t1] = [collapsedChainPath[1], collapsedChainPath[2]]; + const diff = Vec2D.sub(t1, s1); + let angle = (Math.atan2(diff.getY(), diff.getX()) / Math.PI) * 180.0; + + if (Math.abs(angle) > ANGLE_UPSIDE_DOWN_THRESHOLD) { + angle += 180; + } + + if (Math.abs(diff.getX()) < EDGE_CASE_THRESHOLD) { + angle = DEFAULT_ANGLE_VERTICAL; + } + if (Math.abs(diff.getY()) < EDGE_CASE_THRESHOLD) { + angle = DEFAULT_ANGLE_HORIZONTAL; + } + + return `translate(${x},${y}) rotate(${angle}, 0,0) `; + } + + return TrainrunSectionsView.translateAndRotateTextForViewObject( + viewObject, + trainrunSectionText, + ); + } + static isMuted( trainrunSection: TrainrunSection, selectedTrainrun: Trainrun, @@ -153,76 +283,31 @@ export class TrainrunSectionsView { } /** - * Creates a TrainrunSectionViewObject for collapsed node chains where the visual path - * goes directly from startNode to endNode instead of using the primary section's path. - * This is used when intermediate nodes are collapsed and should not be visible. + * Calculate a direct path between start and end nodes for collapsed chain visualization */ - static createViewObjectForCollapsedChain( - editorView: EditorView, - primarySection: TrainrunSection, - allSections: TrainrunSection[], + static calculateDirectPath( startNode: Node, endNode: Node, - isNonStopAtSource: boolean, - isNonStopAtTarget: boolean, - isMuted: boolean, - hiddenTagSource: boolean, - hiddenTagTarget: boolean, - hiddenTagTraveltime: boolean, - hiddenTagTrainrunName: boolean, - hiddenTagDirectionArrows: boolean, - ): TrainrunSectionViewObject { - // Create a standard view object first - const viewObject = new TrainrunSectionViewObject( - editorView, - primarySection, - isNonStopAtSource, - isNonStopAtTarget, - isMuted, - hiddenTagSource, - hiddenTagTarget, - hiddenTagTraveltime, - hiddenTagTrainrunName, - hiddenTagDirectionArrows, - ); - - // Override the path calculation to use startNode and endNode - // We need to temporarily modify the primary section's nodes for path calculation - const originalSourceNode = primarySection.getSourceNode(); - const originalTargetNode = primarySection.getTargetNode(); - const originalSourcePortId = primarySection.getSourcePortId(); - const originalTargetPortId = primarySection.getTargetPortId(); - - try { - // Set temporary nodes for path calculation - primarySection.setSourceNode(startNode); - primarySection.setTargetNode(endNode); - - // Find appropriate ports using the correct sections from the chain - // Source port: from the first section of the chain - // Target port: from the last section of the chain - const firstSection = allSections[0]; - const lastSection = allSections[allSections.length - 1]; - - const sourcePort = - startNode.getPortOfTrainrunSection(firstSection.getId()) || startNode.getPorts()[0]; - const targetPort = - endNode.getPortOfTrainrunSection(lastSection.getId()) || endNode.getPorts()[0]; + allSections: TrainrunSection[], + primarySection: TrainrunSection, + ): Vec2D[] { + const [firstSection, lastSection] = [allSections[0], allSections[allSections.length - 1]]; - primarySection.setSourcePortId(sourcePort.getId()); - primarySection.setTargetPortId(targetPort.getId()); + const sourcePort = + startNode.getPortOfTrainrunSection(firstSection.getId()) ?? startNode.getPorts()[0]; + const targetPort = + endNode.getPortOfTrainrunSection(lastSection.getId()) ?? endNode.getPorts()[0]; - // Recalculate path with new nodes - primarySection.routeEdgeAndPlaceText(); - } finally { - // Restore original nodes and ports - primarySection.setSourceNode(originalSourceNode); - primarySection.setTargetNode(originalTargetNode); - primarySection.setSourcePortId(originalSourcePortId); - primarySection.setTargetPortId(originalTargetPortId); + if (!sourcePort || !targetPort) { + return []; } - return viewObject; + return SimpleTrainrunSectionRouter.routeTrainrunSection( + startNode, + sourcePort, + endNode, + targetPort, + ); } static hasWarning(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): boolean { @@ -376,15 +461,15 @@ export class TrainrunSectionsView { const retPos = "translate(" + pos.getX() + "," + pos.getY() + ") "; if (atSource) { - if (Math.abs(path[0].getX() - path[1].getX()) > 1) { - return retPos + "rotate(0)"; + if (Math.abs(path[0].getX() - path[1].getX()) > EDGE_CASE_THRESHOLD) { + return retPos + `rotate(${DEFAULT_ANGLE_HORIZONTAL})`; } - return retPos + "rotate(-90)"; + return retPos + `rotate(${DEFAULT_ANGLE_VERTICAL})`; } - if (Math.abs(path[3].getX() - path[2].getX()) > 1) { - return retPos + "rotate(0)"; + if (Math.abs(path[3].getX() - path[2].getX()) > EDGE_CASE_THRESHOLD) { + return retPos + `rotate(${DEFAULT_ANGLE_HORIZONTAL})`; } - return retPos + "rotate(-90)"; + return retPos + `rotate(${DEFAULT_ANGLE_VERTICAL})`; } static getPositionX(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): number { @@ -451,6 +536,27 @@ export class TrainrunSectionsView { } } + /** + * Version that works with TrainrunSectionViewObject for collapsed chains + */ + static getAdditionPositioningValueForViewObject( + viewObject: TrainrunSectionViewObject, + textElement: TrainrunSectionText, + ) { + switch (textElement) { + case TrainrunSectionText.SourceDeparture: + case TrainrunSectionText.SourceArrival: + case TrainrunSectionText.TargetDeparture: + case TrainrunSectionText.TargetArrival: + return 1.5; + case TrainrunSectionText.TrainrunSectionTravelTime: + case TrainrunSectionText.TrainrunSectionName: + return TrainrunSectionsView.translateAndRotateTextForViewObject(viewObject, textElement); + default: + return 0; + } + } + static getTrainrunSectionTimeElementOddOffsetTag(time, trainrun): string { if (trainrun.getFrequency() > 60) { if (Math.floor(time / 60) % 2 === 1) { @@ -935,6 +1041,9 @@ export class TrainrunSectionsView { switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: + if (TrainrunSectionsView.getNode(trainrunSection, true).getIsCollapsed()) { + return true; + } if (!this.editorView.isFilterArrivalDepartureTimeEnabled()) { return true; } @@ -951,6 +1060,9 @@ export class TrainrunSectionsView { return TrainrunSectionsView.getNode(trainrunSection, true).isNonStop(trainrunSection); case TrainrunSectionText.TargetDeparture: case TrainrunSectionText.TargetArrival: + if (TrainrunSectionsView.getNode(trainrunSection, false).getIsCollapsed()) { + return true; + } if (!this.editorView.isFilterArrivalDepartureTimeEnabled()) { return true; } @@ -966,6 +1078,10 @@ export class TrainrunSectionsView { } return TrainrunSectionsView.getNode(trainrunSection, false).isNonStop(trainrunSection); case TrainrunSectionText.TrainrunSectionTravelTime: + if (TrainrunSectionsView.isExitingCollapsedChain(trainrunSection)) { + return true; + } + if (!this.editorView.isFilterTravelTimeEnabled()) { return true; } @@ -978,6 +1094,10 @@ export class TrainrunSectionsView { ); case TrainrunSectionText.TrainrunSectionName: { + if (TrainrunSectionsView.isExitingCollapsedChain(trainrunSection)) { + return true; + } + if (!this.editorView.isFilterTrainrunNameEnabled()) { return true; } @@ -1094,9 +1214,10 @@ export class TrainrunSectionsView { // Compute angle let angle: number; if (xDiff === 0) { - angle = yDiff > 0 && isTargetRightOrBottom ? 90 : -90; + angle = + yDiff > 0 && isTargetRightOrBottom ? ANGLE_UPSIDE_DOWN_THRESHOLD : DEFAULT_ANGLE_VERTICAL; } else { - angle = xDiff > 0 && isTargetRightOrBottom ? 0 : 180; + angle = xDiff > 0 && isTargetRightOrBottom ? DEFAULT_ANGLE_HORIZONTAL : 180; } // Set arrow offset values : positions[1] and positions[2] are @@ -1339,6 +1460,7 @@ export class TrainrunSectionsView { if (!this.editorView.trainrunSectionPreviewLineView.getVariantIsWritable()) { return; } + groupEnter .append(StaticDomTags.EDGE_LINE_PIN_SVG) .attr("class", StaticDomTags.EDGE_LINE_PIN_CLASS) @@ -1356,22 +1478,22 @@ export class TrainrunSectionsView { .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => TrainrunSectionsView.getNode(d.trainrunSection, atSource).getId(), ) - .classed( - StaticDomTags.TAG_HIDDEN, - (d: TrainrunSectionViewObject) => - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSection, atSource), - ), - ) - .classed( - StaticDomTags.TAG_EVENT_DISABLED, - (d: TrainrunSectionViewObject) => - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSection, atSource), - ), - ) + .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { + const node = TrainrunSectionsView.getNode(d.trainrunSection, atSource); + return ( + (!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.checkFilterNonStopNode(node)) || + node.getIsCollapsed() + ); + }) + .classed(StaticDomTags.TAG_EVENT_DISABLED, (d: TrainrunSectionViewObject) => { + const node = TrainrunSectionsView.getNode(d.trainrunSection, atSource); + return ( + (!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.checkFilterNonStopNode(node)) || + node.getIsCollapsed() + ); + }) .classed(atSource ? StaticDomTags.EDGE_IS_SOURCE : StaticDomTags.EDGE_IS_TARGET, true) .classed(StaticDomTags.EDGE_IS_END_NODE, (d: TrainrunSectionViewObject) => { let node = d.trainrunSection.getTargetNode(); @@ -1463,16 +1585,42 @@ export class TrainrunSectionsView { d.trainrunSection.getTrainrunId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) - .attr("x", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPositionX(d.trainrunSection, textElement), - ) - .attr("y", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPositionY(d.trainrunSection, textElement), - ) + .attr("x", (d: TrainrunSectionViewObject) => { + const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSection); + if ( + collapsedChainPath && + collapsedChainPath.length >= 4 && + (textElement === TrainrunSectionText.TargetDeparture || + textElement === TrainrunSectionText.TargetArrival) + ) { + const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSection); + if (chainSections.length > 1) { + const lastSection = chainSections[chainSections.length - 1]; + return lastSection.getTextPositionX(textElement); + } + } + return TrainrunSectionsView.getPositionX(d.trainrunSection, textElement); + }) + .attr("y", (d: TrainrunSectionViewObject) => { + const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSection); + if ( + collapsedChainPath && + collapsedChainPath.length >= 4 && + (textElement === TrainrunSectionText.TargetDeparture || + textElement === TrainrunSectionText.TargetArrival) + ) { + const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSection); + if (chainSections.length > 1) { + const lastSection = chainSections[chainSections.length - 1]; + return lastSection.getTextPositionY(textElement); + } + } + return TrainrunSectionsView.getPositionY(d.trainrunSection, textElement); + }) .attr( TrainrunSectionsView.getAdditionPositioningAttr(textElement), (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getAdditionPositioningValue(d.trainrunSection, textElement), + this.getAdditionPositioningValueForViewObjectWithCollapsedSupport(d, textElement), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.trainrunSection.getTrainrun().selected(), @@ -1488,11 +1636,7 @@ export class TrainrunSectionsView { ) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .text((d: TrainrunSectionViewObject) => - TrainrunSectionsView.getTrainrunSectionValueToShow( - d.trainrunSection, - textElement, - this.editorView, - ), + this.getTrainrunSectionValueToShowWithCollapsedSupport(d, textElement, this.editorView), ) .attr("style", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionValueHtmlStyle(d.trainrunSection, textElement), @@ -1734,53 +1878,31 @@ export class TrainrunSectionsView { ): TrainrunSectionViewObject[] { const viewTrainrunSectionDataObjects: TrainrunSectionViewObject[] = []; - // Group sections by collapsed nodes const sectionGroups = this.trainrunSectionService.groupTrainrunSectionsIntoChains(inputTrainrunSections); - sectionGroups.forEach((group) => { - if (group.sections.length === 1) { - // Simple section without collapsed intermediate nodes - const d = group.sections[0]; - viewTrainrunSectionDataObjects.push( - new TrainrunSectionViewObject( - editorView, - d, - TrainrunSectionsView.getNode(d, true).isNonStop(d), - TrainrunSectionsView.getNode(d, false).isNonStop(d), - TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.isFilterDirectionArrowsEnabled(), - ), - ); - } else { - // Chain of sections with collapsed nodes - create single view object - // Use the first section as the primary reference - const primarySection = group.sections[0]; - const lastSection = group.sections[group.sections.length - 1]; - viewTrainrunSectionDataObjects.push( - TrainrunSectionsView.createViewObjectForCollapsedChain( - editorView, - primarySection, - group.sections, - group.startNode, - group.endNode, - group.startNode.isNonStop(primarySection), - group.endNode.isNonStop(lastSection), - TrainrunSectionsView.isMuted(primarySection, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(primarySection, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(lastSection, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(primarySection, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(primarySection, TrainrunSectionText.TrainrunSectionName), - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.isFilterDirectionArrowsEnabled(), - ), - ); - } + sectionGroups.forEach((sections) => { + sections.forEach((d) => { + if (this.shouldDisplayTrainrunSection(d)) { + this.updateTrainrunSectionPathForCollapsedChain(d); + + viewTrainrunSectionDataObjects.push( + new TrainrunSectionViewObject( + editorView, + d, + TrainrunSectionsView.getNode(d, true).isNonStop(d), + TrainrunSectionsView.getNode(d, false).isNonStop(d), + TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.isFilterDirectionArrowsEnabled(), + ), + ); + } + }); }); return viewTrainrunSectionDataObjects; @@ -2224,6 +2346,11 @@ export class TrainrunSectionsView { } private transformPath(ts: TrainrunSection): Vec2D[] { + const collapsedChainPath = this.getCollapsedChainPath(ts); + if (collapsedChainPath) { + return this.applyBasicFiltering(collapsedChainPath, ts); + } + const srcNode = ts.getSourceNode(); const trgNode = ts.getTargetNode(); let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); @@ -2257,6 +2384,147 @@ export class TrainrunSectionsView { return retPath; } + /** + * Detect collapsed node chains and calculate direct visualization path + * + * A collapsed chain occurs when intermediate nodes are hidden from view. + * Example: A-B*-C*-D where B* and C* are collapsed -> create direct path A→D + * + * Algorithm: + * 1. Walk backward from current section to find chain start (non-collapsed node) + * 2. Walk forward from current section to find chain end (non-collapsed node) + * 3. If start != end, calculate direct path using legacy routing system + * + * @param currentSection The section that might be part of a collapsed chain + * @returns Direct path Vec2D[] if chain detected, null otherwise + */ + private getCollapsedChainPath(currentSection: TrainrunSection): Vec2D[] | null { + const trainrunId = currentSection.getTrainrunId(); + + const startSection = this.findChainBoundary(currentSection, trainrunId, "backward"); + const endSection = this.findChainBoundary(currentSection, trainrunId, "forward"); + + if (startSection.getId() !== endSection.getId()) { + const startNode = startSection.getSourceNode(); + const endNode = endSection.getTargetNode(); + + return TrainrunSectionsView.calculateDirectPath( + startNode, + endNode, + [startSection, endSection], + currentSection, + ); + } + + return null; + } + + /** + * Updates the TrainrunSection's path if it's part of a collapsed chain. + * This ensures the visual rendering uses the correct collapsed path instead of the direct path. + */ + private updateTrainrunSectionPathForCollapsedChain(section: TrainrunSection): void { + const collapsedPath = this.getCollapsedChainPath(section); + if (collapsedPath) { + (section as any).pathVec2D = collapsedPath; + + const sourcePort = section.getSourceNode().getPort(section.getSourcePortId()); + if (sourcePort) { + (section as any).path.textPositions = + SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedPath, sourcePort); + } + } + } + + /** + * Find the boundary of a collapsed chain by walking in the specified direction + */ + private findChainBoundary( + startSection: TrainrunSection, + trainrunId: number, + direction: "forward" | "backward", + ): TrainrunSection { + let currentSection = startSection; + + // eslint-disable-next-line no-constant-condition + while (true) { + const node = + direction === "backward" ? currentSection.getSourceNode() : currentSection.getTargetNode(); + + if (!node.getIsCollapsed()) { + break; + } + + const connectedSections = this.getConnectedTrainrunSections(node, trainrunId).filter( + (ts) => ts.getId() !== currentSection.getId(), + ); + + if (connectedSections.length === 1) { + currentSection = connectedSections[0]; + } else { + break; + } + } + + return currentSection; + } + + /** + * Get all trainrun sections connected to a node for a specific trainrun + */ + private getConnectedTrainrunSections(node: Node, trainrunId: number): TrainrunSection[] { + const sections: TrainrunSection[] = []; + const ports = node.getPorts(); + + for (const port of ports) { + const section = port.getTrainrunSection(); + if (section && section.getTrainrunId() === trainrunId) { + sections.push(section); + } + } + + return sections; + } + + /** + * Determine if a trainrun section should be displayed (not an intermediate in a collapsed chain) + */ + private shouldDisplayTrainrunSection(section: TrainrunSection): boolean { + return !section.getSourceNode().getIsCollapsed() || !section.getTargetNode().getIsCollapsed(); + } + + private static isExitingCollapsedChain(trainrunSection: TrainrunSection): boolean { + return ( + TrainrunSectionsView.getNode(trainrunSection, true).getIsCollapsed() && + !TrainrunSectionsView.getNode(trainrunSection, false).getIsCollapsed() + ); + } + + /** + * Apply basic filtering to a path + */ + private applyBasicFiltering(path: Vec2D[], ts: TrainrunSection): Vec2D[] { + const srcNode = ts.getSourceNode(); + const trgNode = ts.getTargetNode(); + let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); + let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); + + if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { + notFilteringSourceNode = true; + notFilteringTargetNode = true; + } + + if (notFilteringSourceNode && notFilteringTargetNode) { + return path.map((p) => p.copy()); + } else if (notFilteringSourceNode) { + return path.slice(0, 2).map((p) => p.copy()); + } else if (notFilteringTargetNode) { + return path.slice(2).map((p) => p.copy()); + } else { + return []; + } + } + private filterOutAllTrainrunSectionWithHiddenNodeConnection( trainrunSection: TrainrunSection, ): boolean { @@ -2683,4 +2951,140 @@ export class TrainrunSectionsView { this.editorView.nodesView.createNewTrainrunSection(startNode, endNode); this.editorView.setTrainrunSectionAsSelected(trainrunSectionFrom); } + + /** + * Get the value to show for collapsed chains (with corrected times) + */ + /** + * Get the node IDs path for a collapsed chain + */ + getCollapsedChainNodePath(trainrunSection: TrainrunSection): number[] | null { + const sourceNodeId = trainrunSection.getSourceNodeId(); + const targetNodeId = trainrunSection.getTargetNodeId(); + const sourceNode = trainrunSection.getSourceNode(); + const targetNode = trainrunSection.getTargetNode(); + + // Check if this section crosses collapsed nodes by looking at the full chain + const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); + + if (chainSections.length > 1) { + return [sourceNodeId, targetNodeId]; + } + + return null; + } + + getTrainrunSectionValueToShowWithCollapsedSupport( + viewObject: TrainrunSectionViewObject, + textElement: TrainrunSectionText, + editorView: EditorView, + ) { + const trainrunSection = viewObject.trainrunSection; + + // Use unified logic for both collapsed chains and regular sections + return this.getCollapsedChainValueToShow(trainrunSection, textElement, editorView); + } + + /** + * Calculate the correct values for collapsed chains + */ + getCollapsedChainValueToShow( + trainrunSection: TrainrunSection, + textElement: TrainrunSectionText, + editorView: EditorView, + ) { + switch (textElement) { + case TrainrunSectionText.SourceDeparture: + case TrainrunSectionText.SourceArrival: + // For source times, use the original section times (should be from non-collapsed node) + return TrainrunSectionsView.getTrainrunSectionValueToShow( + trainrunSection, + textElement, + editorView, + ); + + case TrainrunSectionText.TargetDeparture: + case TrainrunSectionText.TargetArrival: { + // For collapsed chains, use the actual time from the last section in the chain + const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); + const lastSection = chainSections[chainSections.length - 1]; + + // Use the actual time from the last section (which already includes all stops and travel times) + return TrainrunSectionsView.getTrainrunSectionValueToShow( + lastSection, + textElement, + editorView, + ); + } + + case TrainrunSectionText.TrainrunSectionTravelTime: { + // For collapsed chains, calculate total time including stops at collapsed nodes + const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); + const lastSection = chainSections[chainSections.length - 1]; + + // Calculate total time: arrival time at end - departure time at start + const startTime = TrainrunSectionsView.getTime( + trainrunSection, + TrainrunSectionText.SourceDeparture, + ); + const endTime = TrainrunSectionsView.getTime( + lastSection, + TrainrunSectionText.TargetArrival, + ); + const totalTime = endTime - startTime; + + return ( + TrainrunSectionsView.formatTime(totalTime, editorView.getTimeDisplayPrecision()) + "'" + ); + } + + case TrainrunSectionText.TrainrunSectionName: + // For name, use the original trainrun name + return TrainrunSectionsView.extractTrainrunName(trainrunSection); + } + + return undefined; + } + + /** + * Get all sections that are part of the same collapsed chain + */ + getAllSectionsInCollapsedChain(currentSection: TrainrunSection): TrainrunSection[] { + const sections: TrainrunSection[] = []; + let startSection = currentSection; + + // Walk backwards to find start of chain + while (startSection.getSourceNode().getIsCollapsed()) { + const prevSections = this.getConnectedTrainrunSections( + startSection.getSourceNode(), + currentSection.getTrainrunId(), + ).filter((ts) => ts.getId() !== startSection.getId()); + + if (prevSections.length === 1) { + startSection = prevSections[0]; + } else { + break; + } + } + + // Walk forwards to find end of chain and collect all sections + let currentSectionInChain = startSection; + sections.push(currentSectionInChain); + + while (currentSectionInChain.getTargetNode().getIsCollapsed()) { + const nextSections = this.getConnectedTrainrunSections( + currentSectionInChain.getTargetNode(), + currentSection.getTrainrunId(), + ).filter((ts) => ts.getId() !== currentSectionInChain.getId()); + + if (nextSections.length === 1) { + currentSectionInChain = nextSections[0]; + sections.push(currentSectionInChain); + } else { + break; + } + } + + return sections; + } } diff --git a/src/app/view/rastering/definitions.ts b/src/app/view/rastering/definitions.ts index bfa209e40..efa6cf472 100644 --- a/src/app/view/rastering/definitions.ts +++ b/src/app/view/rastering/definitions.ts @@ -59,3 +59,13 @@ export const TRAINRUN_SECTION_TEXT_AREA_HEIGHT = 20; export const EDITOR_MENU_HEIGHT = 60; export const SHOW_MAX_SINGLE_TRAINRUN_SECTIONS_STOPS = 5; + +/* + Text rotation and path constants for trainrun sections + */ +export const MIN_PATH_LENGTH_FOR_ANGLE = 4; +export const ANGLE_UPSIDE_DOWN_THRESHOLD = 90; +export const EDGE_CASE_THRESHOLD = 1; +export const DEFAULT_ANGLE_VERTICAL = -90; +export const DEFAULT_ANGLE_HORIZONTAL = 0; +export const PATH_COMPARISON_TOLERANCE = 0.01; From ca9c7aeb60ce801bd86ad956b1c83169cdbad5a8 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 14:49:49 +0100 Subject: [PATCH 15/54] fixup! fix start node in groupTrainrunSectionsIntoChains() Signed-off-by: Simon Ser --- src/app/services/data/trainrunsection.service.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index af758b750..fcc02fd9c 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -1507,10 +1507,19 @@ export class TrainrunSectionService implements OnDestroy { return; } + const backwardIterator = this.trainrunService.getBackwardIterator( + section.getTargetNode(), + section, + ); + while (backwardIterator.hasNext() && backwardIterator.current().node.getIsCollapsed()) { + backwardIterator.next(); + } + const startNode = backwardIterator.current().node; + const startSection = backwardIterator.current().trainrunSection; + // Build chain using TrainrunIterator to leverage existing graph traversal const chain: TrainrunSection[] = []; - const startNode = section.getSourceNode(); - const iterator = this.trainrunService.getIterator(startNode, section); + const iterator = this.trainrunService.getIterator(startNode, startSection); // Traverse the trainrun and collect sections with collapsed intermediate nodes while (iterator.hasNext()) { From 66a39a0de82e93b20451e25409dd3f6cfffc4299 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 16:35:39 +0100 Subject: [PATCH 16/54] fixup! only create a single TrainrunSectionViewObject per collapsed chain Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 100 ++++++------------ 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 7411195cc..0ed98b951 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -126,8 +126,6 @@ export class TrainrunSectionsView { return SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedChainPath, sourcePort); } - - getAdditionPositioningValueForViewObjectWithCollapsedSupport( viewObject: TrainrunSectionViewObject, textElement: TrainrunSectionText, @@ -1041,9 +1039,6 @@ export class TrainrunSectionsView { switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: - if (TrainrunSectionsView.getNode(trainrunSection, true).getIsCollapsed()) { - return true; - } if (!this.editorView.isFilterArrivalDepartureTimeEnabled()) { return true; } @@ -1060,9 +1055,6 @@ export class TrainrunSectionsView { return TrainrunSectionsView.getNode(trainrunSection, true).isNonStop(trainrunSection); case TrainrunSectionText.TargetDeparture: case TrainrunSectionText.TargetArrival: - if (TrainrunSectionsView.getNode(trainrunSection, false).getIsCollapsed()) { - return true; - } if (!this.editorView.isFilterArrivalDepartureTimeEnabled()) { return true; } @@ -1078,10 +1070,6 @@ export class TrainrunSectionsView { } return TrainrunSectionsView.getNode(trainrunSection, false).isNonStop(trainrunSection); case TrainrunSectionText.TrainrunSectionTravelTime: - if (TrainrunSectionsView.isExitingCollapsedChain(trainrunSection)) { - return true; - } - if (!this.editorView.isFilterTravelTimeEnabled()) { return true; } @@ -1094,10 +1082,6 @@ export class TrainrunSectionsView { ); case TrainrunSectionText.TrainrunSectionName: { - if (TrainrunSectionsView.isExitingCollapsedChain(trainrunSection)) { - return true; - } - if (!this.editorView.isFilterTrainrunNameEnabled()) { return true; } @@ -1478,22 +1462,22 @@ export class TrainrunSectionsView { .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => TrainrunSectionsView.getNode(d.trainrunSection, atSource).getId(), ) - .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { - const node = TrainrunSectionsView.getNode(d.trainrunSection, atSource); - return ( - (!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.checkFilterNonStopNode(node)) || - node.getIsCollapsed() - ); - }) - .classed(StaticDomTags.TAG_EVENT_DISABLED, (d: TrainrunSectionViewObject) => { - const node = TrainrunSectionsView.getNode(d.trainrunSection, atSource); - return ( - (!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.checkFilterNonStopNode(node)) || - node.getIsCollapsed() - ); - }) + .classed( + StaticDomTags.TAG_HIDDEN, + (d: TrainrunSectionViewObject) => + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.checkFilterNonStopNode( + TrainrunSectionsView.getNode(d.trainrunSection, atSource), + ), + ) + .classed( + StaticDomTags.TAG_EVENT_DISABLED, + (d: TrainrunSectionViewObject) => + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.checkFilterNonStopNode( + TrainrunSectionsView.getNode(d.trainrunSection, atSource), + ), + ) .classed(atSource ? StaticDomTags.EDGE_IS_SOURCE : StaticDomTags.EDGE_IS_TARGET, true) .classed(StaticDomTags.EDGE_IS_END_NODE, (d: TrainrunSectionViewObject) => { let node = d.trainrunSection.getTargetNode(); @@ -1882,27 +1866,23 @@ export class TrainrunSectionsView { this.trainrunSectionService.groupTrainrunSectionsIntoChains(inputTrainrunSections); sectionGroups.forEach((sections) => { - sections.forEach((d) => { - if (this.shouldDisplayTrainrunSection(d)) { - this.updateTrainrunSectionPathForCollapsedChain(d); - - viewTrainrunSectionDataObjects.push( - new TrainrunSectionViewObject( - editorView, - d, - TrainrunSectionsView.getNode(d, true).isNonStop(d), - TrainrunSectionsView.getNode(d, false).isNonStop(d), - TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.isFilterDirectionArrowsEnabled(), - ), - ); - } - }); + const d = sections[0]; + this.updateTrainrunSectionPathForCollapsedChain(d); + viewTrainrunSectionDataObjects.push( + new TrainrunSectionViewObject( + editorView, + d, + TrainrunSectionsView.getNode(d, true).isNonStop(d), + TrainrunSectionsView.getNode(d, false).isNonStop(d), + TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.isFilterDirectionArrowsEnabled(), + ), + ); }); return viewTrainrunSectionDataObjects; @@ -2486,20 +2466,6 @@ export class TrainrunSectionsView { return sections; } - /** - * Determine if a trainrun section should be displayed (not an intermediate in a collapsed chain) - */ - private shouldDisplayTrainrunSection(section: TrainrunSection): boolean { - return !section.getSourceNode().getIsCollapsed() || !section.getTargetNode().getIsCollapsed(); - } - - private static isExitingCollapsedChain(trainrunSection: TrainrunSection): boolean { - return ( - TrainrunSectionsView.getNode(trainrunSection, true).getIsCollapsed() && - !TrainrunSectionsView.getNode(trainrunSection, false).getIsCollapsed() - ); - } - /** * Apply basic filtering to a path */ From f62482068b128497503248f9eefcb93284aad48a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 15:29:20 +0100 Subject: [PATCH 17/54] Add TrainrunSectionViewObject.getTrainrun() TrainrunSectionViewObject will represent multiple trainrun sections soon. Add a helper to get the parent trainrun to reduce reliance on a single trainrun. Signed-off-by: Simon Ser --- .../editor-main-view/data-views/d3.utils.ts | 6 +-- .../data-views/trainrunSectionViewObject.ts | 4 ++ .../data-views/trainrunsections.view.ts | 42 +++++++++---------- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/d3.utils.ts b/src/app/view/editor-main-view/data-views/d3.utils.ts index 53f363409..31bf03799 100644 --- a/src/app/view/editor-main-view/data-views/d3.utils.ts +++ b/src/app/view/editor-main-view/data-views/d3.utils.ts @@ -45,21 +45,21 @@ export class D3Utils { d3.selectAll(StaticDomTags.EDGE_LINE_ARROW_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.getTrainrun().getId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, true); d3.selectAll(StaticDomTags.EDGE_LINE_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.getTrainrun().getId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, true); d3.selectAll(StaticDomTags.EDGE_ROOT_CONTAINER_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.getTrainrun().getId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, true); diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 40d5bca31..db315757e 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -30,6 +30,10 @@ export class TrainrunSectionViewObject { ); } + getTrainrun() { + return this.trainrunSection.getTrainrun(); + } + static generateKey( editorView: EditorView, d: TrainrunSection, diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 0ed98b951..85d8e8cb1 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1132,7 +1132,7 @@ export class TrainrunSectionsView { groupEnter .filter((d: TrainrunSectionViewObject) => { - const displayTextBackground = d.trainrunSection.getTrainrun().isRoundTrip() || isOneWayText; + const displayTextBackground = d.getTrainrun().isRoundTrip() || isOneWayText; return ( this.filterTrainrunsectionAtNode(d.trainrunSection, atSource) && this.filterTimeTrainrunsectionNonStop(d.trainrunSection, atSource, isArrival) && @@ -1152,7 +1152,7 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().getId(), + d.getTrainrun().getId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, lineTextElement) .attr( @@ -1239,7 +1239,7 @@ export class TrainrunSectionsView { groupLinesEnter .append(StaticDomTags.EDGE_LINE_ARROW_SVG) .attr("d", (d: TrainrunSectionViewObject) => { - return d.trainrunSection.getTrainrun().isRoundTrip() ? "" : "M-4,-5L2,0L-4,5Z"; + return d.getTrainrun().isRoundTrip() ? "" : "M-4,-5L2,0L-4,5Z"; }) .attr("transform", (d: TrainrunSectionViewObject) => this.translateAndRotateArrow(d.trainrunSection, arrowType), @@ -1266,10 +1266,10 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().getId(), + d.getTrainrun().getId(), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_LINE_ARROW_EDITOR, true) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => @@ -1313,13 +1313,13 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().getId(), + d.getTrainrun().getId(), ) .attr("d", (d: TrainrunSectionViewObject) => D3Utils.getPathAsSVGString(this.transformPath(d.trainrunSection)), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .classed(classRef, true); @@ -1378,7 +1378,7 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrunId(), + d.getTrainrun().getId(), ) .attr("d", (d: TrainrunSectionViewObject) => TrainrunSectionsView.createSemicircle( @@ -1406,7 +1406,7 @@ export class TrainrunSectionsView { TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ); } @@ -1450,7 +1450,7 @@ export class TrainrunSectionsView { .attr("class", StaticDomTags.EDGE_LINE_PIN_CLASS) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrunId(), + d.getTrainrun().getId(), ) .attr("cx", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getPosition(d.trainrunSection, atSource).getX(), @@ -1502,7 +1502,7 @@ export class TrainrunSectionsView { TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .on("mouseover", (d: TrainrunSectionViewObject, i, a) => this.onTrainrunSectionMouseoverPin( @@ -1545,7 +1545,7 @@ export class TrainrunSectionsView { const renderingObjects = groupEnter .filter((d: TrainrunSectionViewObject) => { const displayTextElement = - d.trainrunSection.getTrainrun().isRoundTrip() || isDefaultText || isOneWayText; + d.getTrainrun().isRoundTrip() || isDefaultText || isOneWayText; return ( this.filterTrainrunsectionAtNode(d.trainrunSection, atSource) && @@ -1566,7 +1566,7 @@ export class TrainrunSectionsView { .attr("data-testid", StaticDomTags.EDGE_LINE_TEXT_CLASS) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrunId(), + d.getTrainrun().getId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) .attr("x", (d: TrainrunSectionViewObject) => { @@ -1607,7 +1607,7 @@ export class TrainrunSectionsView { this.getAdditionPositioningValueForViewObjectWithCollapsedSupport(d, textElement), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), @@ -1698,7 +1698,7 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrunId(), + d.getTrainrun().getId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) .attr("x", 0) @@ -1710,7 +1710,7 @@ export class TrainrunSectionsView { ), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), @@ -1919,7 +1919,7 @@ export class TrainrunSectionsView { .attr("class", StaticDomTags.EDGE_ROOT_CONTAINER) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), @@ -1929,7 +1929,7 @@ export class TrainrunSectionsView { .append(StaticDomTags.EDGE_SVG) .attr("class", StaticDomTags.EDGE_CLASS + " Lines") .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr("data-testid", `${StaticDomTags.EDGE_CLASS}-lines`); @@ -1938,7 +1938,7 @@ export class TrainrunSectionsView { .append(StaticDomTags.EDGE_SVG) .attr("class", StaticDomTags.EDGE_CLASS + " Labels") .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => - d.trainrunSection.getTrainrun().selected(), + d.getTrainrun().selected(), ) .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) .attr("data-testid", `${StaticDomTags.EDGE_CLASS}-labels`); @@ -2848,7 +2848,7 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_ID, (t: TrainrunSectionViewObject) => t.trainrunSection.getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (t: TrainrunSectionViewObject) => - t.trainrunSection.getTrainrun().getId(), + t.getTrainrun().getId(), ) .attr("cx", position.getX()) .attr("cy", position.getY()) @@ -2859,7 +2859,7 @@ export class TrainrunSectionsView { TrainrunSectionsView.isMuted(t.trainrunSection, selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (t: TrainrunSectionViewObject) => - t.trainrunSection.getTrainrun().selected(), + t.getTrainrun().selected(), ) .classed(StaticDomTags.EDGE_LINE_STOPS_FILL, () => !collapsedStops) .on("mouseover", (t: TrainrunSectionViewObject, i, a) => From 1c6b220ac65212b3b155ce3e38e6e89855358dc3 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 16:10:58 +0100 Subject: [PATCH 18/54] Store full trainrun section chain in TrainrunSectionViewObject This makes it clear that there isn't a single trainrun section per TrainrunSectionViewObject: a single TrainrunSectionViewObject can hold multiple sections. The full collapsed chain is stored. For now, blindly replace trainrunSection with trainrunSections[0], to be cleaned up in future commits. Signed-off-by: Simon Ser --- .../editor-main-view/data-views/d3.utils.ts | 38 ++-- .../data-views/trainrunSectionViewObject.ts | 11 +- .../data-views/trainrunsections.view.ts | 202 +++++++++--------- 3 files changed, 125 insertions(+), 126 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/d3.utils.ts b/src/app/view/editor-main-view/data-views/d3.utils.ts index 31bf03799..14432fcda 100644 --- a/src/app/view/editor-main-view/data-views/d3.utils.ts +++ b/src/app/view/editor-main-view/data-views/d3.utils.ts @@ -90,20 +90,20 @@ export class D3Utils { d3.selectAll(StaticDomTags.EDGE_LINE_ARROW_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); d3.selectAll(StaticDomTags.EDGE_LINE_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); d3.selectAll(StaticDomTags.EDGE_ROOT_CONTAINER_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSection.getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); @@ -347,7 +347,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, false) .classed(StaticDomTags.TAG_HOVER, false) @@ -359,7 +359,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, false) .classed(StaticDomTags.TAG_HOVER, false) @@ -371,7 +371,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, false) .classed(StaticDomTags.TAG_HOVER, false) @@ -383,7 +383,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, true); @@ -394,8 +394,8 @@ export class D3Utils { return false; } return ( - d.trainrunSection.getId() === trainrunSection.getId() && - d.trainrunSection.getSourceNodeId() === grayoutEdgeLinePinNode.getId() + d.trainrunSections[0].getId() === trainrunSection.getId() && + d.trainrunSections[0].getSourceNodeId() === grayoutEdgeLinePinNode.getId() ); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, true); @@ -405,8 +405,8 @@ export class D3Utils { return false; } return ( - d.trainrunSection.getId() === trainrunSection.getId() && - d.trainrunSection.getTargetNodeId() === grayoutEdgeLinePinNode.getId() + d.trainrunSections[0].getId() === trainrunSection.getId() && + d.trainrunSections[0].getTargetNodeId() === grayoutEdgeLinePinNode.getId() ); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, true); @@ -419,7 +419,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, true) .classed(StaticDomTags.TAG_HOVER, false) @@ -431,7 +431,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, true) .classed(StaticDomTags.TAG_HOVER, false) @@ -443,7 +443,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.TAG_SELECTED, true) .classed(StaticDomTags.TAG_HOVER, false) @@ -455,7 +455,7 @@ export class D3Utils { if (d === undefined) { return false; } - return d.trainrunSection.getId() === trainrunSection.getId(); + return d.trainrunSections[0].getId() === trainrunSection.getId(); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, false); @@ -466,8 +466,8 @@ export class D3Utils { return false; } return ( - d.trainrunSection.getId() === trainrunSection.getId() && - d.trainrunSection.getSourceNodeId() === grayoutEdgeLinePinNode.getId() + d.trainrunSections[0].getId() === trainrunSection.getId() && + d.trainrunSections[0].getSourceNodeId() === grayoutEdgeLinePinNode.getId() ); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, false); @@ -477,8 +477,8 @@ export class D3Utils { return false; } return ( - d.trainrunSection.getId() === trainrunSection.getId() && - d.trainrunSection.getTargetNodeId() === grayoutEdgeLinePinNode.getId() + d.trainrunSections[0].getId() === trainrunSection.getId() && + d.trainrunSections[0].getTargetNodeId() === grayoutEdgeLinePinNode.getId() ); }) .classed(StaticDomTags.EDGE_LINE_GRAYEDOUT, false); diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index db315757e..c28d31a95 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -6,7 +6,7 @@ export class TrainrunSectionViewObject { constructor( private editorView: EditorView, - public trainrunSection: TrainrunSection, + public trainrunSections: TrainrunSection[], isNonStopAtSource: boolean, isNonStopAtTarget: boolean, isMuted: boolean, @@ -18,7 +18,7 @@ export class TrainrunSectionViewObject { ) { this.key = TrainrunSectionViewObject.generateKey( editorView, - trainrunSection, + trainrunSections, isNonStopAtSource, isNonStopAtTarget, isMuted, @@ -31,12 +31,12 @@ export class TrainrunSectionViewObject { } getTrainrun() { - return this.trainrunSection.getTrainrun(); + return this.trainrunSections[0].getTrainrun(); } static generateKey( editorView: EditorView, - d: TrainrunSection, + trainrunSections: TrainrunSection[], isNonStopAtSource: boolean, isNonStopAtTarget: boolean, isMuted: boolean, @@ -46,6 +46,7 @@ export class TrainrunSectionViewObject { hiddenTagTrainrunName: boolean, hiddenTagDirectionArrows: boolean, ): string { + const d = trainrunSections[0]; const cumulativeTravelTimeData = editorView.getCumulativeTravelTimeAndNodePath(d); const cumulativeTravelTime = cumulativeTravelTimeData[cumulativeTravelTimeData.length - 1].sumTravelTime; @@ -166,6 +167,4 @@ export class TrainrunSectionViewObject { return key; } - - } diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 85d8e8cb1..78edc2d2d 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -84,7 +84,7 @@ export class TrainrunSectionsView { viewObject: TrainrunSectionViewObject, trainrunSectionText: TrainrunSectionText, ) { - const trainrunSection = viewObject.trainrunSection; + const trainrunSection = viewObject.trainrunSections[0]; const x = trainrunSection.getTextPositionX(trainrunSectionText); const y = trainrunSection.getTextPositionY(trainrunSectionText); @@ -151,7 +151,7 @@ export class TrainrunSectionsView { viewObject: TrainrunSectionViewObject, trainrunSectionText: TrainrunSectionText, ) { - const trainrunSection = viewObject.trainrunSection; + const trainrunSection = viewObject.trainrunSections[0]; const collapsedChainPath = this.getCollapsedChainPath(trainrunSection); if (collapsedChainPath && collapsedChainPath.length >= MIN_PATH_LENGTH_FOR_ANGLE) { @@ -1134,8 +1134,8 @@ export class TrainrunSectionsView { .filter((d: TrainrunSectionViewObject) => { const displayTextBackground = d.getTrainrun().isRoundTrip() || isOneWayText; return ( - this.filterTrainrunsectionAtNode(d.trainrunSection, atSource) && - this.filterTimeTrainrunsectionNonStop(d.trainrunSection, atSource, isArrival) && + this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource) && + this.filterTimeTrainrunsectionNonStop(d.trainrunSections[0], atSource, isArrival) && displayTextBackground ); }) @@ -1145,12 +1145,12 @@ export class TrainrunSectionsView { (d: TrainrunSectionViewObject) => StaticDomTags.EDGE_LINE_TEXT_BACKGROUND_CLASS + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - d.trainrunSection, + d.trainrunSections[0], selectedTrainrun, connectedTrainIds, ), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) @@ -1158,9 +1158,9 @@ export class TrainrunSectionsView { .attr( "x", (d: TrainrunSectionViewObject) => - d.trainrunSection.getTextPositionX(lineTextElement) - + d.trainrunSections[0].getTextPositionX(lineTextElement) - TrainrunSectionsView.getTrainrunSectionValueTextWidth( - d.trainrunSection, + d.trainrunSections[0], lineTextElement, ) / 2, @@ -1168,19 +1168,19 @@ export class TrainrunSectionsView { .attr( "y", (d: TrainrunSectionViewObject) => - d.trainrunSection.getTextPositionY(lineTextElement) - + d.trainrunSections[0].getTextPositionY(lineTextElement) - TRAINRUN_SECTION_TEXT_AREA_HEIGHT / 2, ) .attr("width", (d: TrainrunSectionViewObject) => { return TrainrunSectionsView.getTrainrunSectionValueTextWidth( - d.trainrunSection, + d.trainrunSections[0], lineTextElement, ); }) .attr("height", TRAINRUN_SECTION_TEXT_AREA_HEIGHT) .classed(TrainrunSectionText[lineTextElement], true) .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - this.getHiddenTagForTime(d.trainrunSection, lineTextElement), + this.getHiddenTagForTime(d.trainrunSections[0], lineTextElement), ); } @@ -1242,14 +1242,14 @@ export class TrainrunSectionsView { return d.getTrainrun().isRoundTrip() ? "" : "M-4,-5L2,0L-4,5Z"; }) .attr("transform", (d: TrainrunSectionViewObject) => - this.translateAndRotateArrow(d.trainrunSection, arrowType), + this.translateAndRotateArrow(d.trainrunSections[0], arrowType), ) .attr( "class", (d: TrainrunSectionViewObject) => StaticDomTags.EDGE_LINE_ARROW_CLASS + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - d.trainrunSection, + d.trainrunSections[0], selectedTrainrun, connectedTrainIds, ), @@ -1260,11 +1260,11 @@ export class TrainrunSectionsView { !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && (!this.editorView.isFilterDirectionArrowsEnabled() || !this.filterTrainrunsectionAtNode( - d.trainrunSection, + d.trainrunSections[0], arrowType === "BEGINNING_ARROW", )), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) @@ -1273,17 +1273,17 @@ export class TrainrunSectionsView { ) .classed(StaticDomTags.TAG_LINE_ARROW_EDITOR, true) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .on("mouseup", (d: TrainrunSectionViewObject, i, a) => { - this.onTrainrunDirectionArrowMouseUp(d.trainrunSection, a[i]); + this.onTrainrunDirectionArrowMouseUp(d.trainrunSections[0], a[i]); }) .on("mouseover", (d: TrainrunSectionViewObject, i, a) => { - this.onTrainrunSectionMouseoverPath(d.trainrunSection, a[i]); + this.onTrainrunSectionMouseoverPath(d.trainrunSections[0], a[i]); }) .on("mouseout", (d: TrainrunSectionViewObject, i, a) => { - this.onTrainrunSectionMouseoutPath(d.trainrunSection, a[i]); + this.onTrainrunSectionMouseoutPath(d.trainrunSections[0], a[i]); }); }); } @@ -1298,7 +1298,7 @@ export class TrainrunSectionsView { ) { const trainrunSectionElements = groupEnter .filter((d: TrainrunSectionViewObject) => { - return !levelFreqFilter.includes(d.trainrunSection.getFrequencyLinePatternRef()); + return !levelFreqFilter.includes(d.trainrunSections[0].getFrequencyLinePatternRef()); }) .append(StaticDomTags.EDGE_LINE_SVG) .attr( @@ -1306,17 +1306,17 @@ export class TrainrunSectionsView { (d: TrainrunSectionViewObject) => StaticDomTags.EDGE_LINE_CLASS + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - d.trainrunSection, + d.trainrunSections[0], selectedTrainrun, connectedTrainIds, ), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) .attr("d", (d: TrainrunSectionViewObject) => - D3Utils.getPathAsSVGString(this.transformPath(d.trainrunSection)), + D3Utils.getPathAsSVGString(this.transformPath(d.trainrunSections[0])), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), @@ -1328,17 +1328,17 @@ export class TrainrunSectionsView { trainrunSectionElements .on("mouseup", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionMouseUp(d.trainrunSection, a[i]); + this.onTrainrunSectionMouseUp(d.trainrunSections[0], a[i]); } }) .on("mouseover", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionMouseoverPath(d.trainrunSection, a[i]); + this.onTrainrunSectionMouseoverPath(d.trainrunSections[0], a[i]); } }) .on("mouseout", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionMouseoutPath(d.trainrunSection, a[i]); + this.onTrainrunSectionMouseoutPath(d.trainrunSections[0], a[i]); } }); } @@ -1352,11 +1352,11 @@ export class TrainrunSectionsView { ) { groupEnter .filter((d: TrainrunSectionViewObject) => - this.filterTrainrunsectionAtNode(d.trainrunSection, atSource), + this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource), ) .filter((d: TrainrunSectionViewObject) => { - const trans = TrainrunSectionsView.getNode(d.trainrunSection, atSource).getTransition( - d.trainrunSection.getId(), + const trans = TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getTransition( + d.trainrunSections[0].getId(), ); if (trans === undefined) { return true; @@ -1371,39 +1371,39 @@ export class TrainrunSectionsView { " " + StaticDomTags.TAG_FILL + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - d.trainrunSection, + d.trainrunSections[0], selectedTrainrun, connectedTrainIds, ), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) .attr("d", (d: TrainrunSectionViewObject) => TrainrunSectionsView.createSemicircle( - d.trainrunSection, - TrainrunSectionsView.getPosition(d.trainrunSection, atSource), + d.trainrunSections[0], + TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource), ), ) .attr( "transform", (d: TrainrunSectionViewObject) => "translate(" + - TrainrunSectionsView.getPosition(d.trainrunSection, atSource).getX() + + TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getX() + "," + - TrainrunSectionsView.getPosition(d.trainrunSection, atSource).getY() + + TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getY() + ")", ) .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSection, atSource).getId(), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getId(), ) .classed(StaticDomTags.EDGE_IS_TARGET, !atSource) .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSection, atSource).isNonStop(d.trainrunSection), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).isNonStop(d.trainrunSections[0]), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), @@ -1448,26 +1448,26 @@ export class TrainrunSectionsView { groupEnter .append(StaticDomTags.EDGE_LINE_PIN_SVG) .attr("class", StaticDomTags.EDGE_LINE_PIN_CLASS) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) .attr("cx", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPosition(d.trainrunSection, atSource).getX(), + TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getX(), ) .attr("cy", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPosition(d.trainrunSection, atSource).getY(), + TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getY(), ) .attr("r", DEFAULT_PIN_RADIUS) .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSection, atSource).getId(), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getId(), ) .classed( StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSection, atSource), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource), ), ) .classed( @@ -1475,48 +1475,48 @@ export class TrainrunSectionsView { (d: TrainrunSectionViewObject) => !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSection, atSource), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource), ), ) .classed(atSource ? StaticDomTags.EDGE_IS_SOURCE : StaticDomTags.EDGE_IS_TARGET, true) .classed(StaticDomTags.EDGE_IS_END_NODE, (d: TrainrunSectionViewObject) => { - let node = d.trainrunSection.getTargetNode(); + let node = d.trainrunSections[0].getTargetNode(); if (atSource) { - node = d.trainrunSection.getSourceNode(); + node = d.trainrunSections[0].getSourceNode(); } - const port = node.getPortOfTrainrunSection(d.trainrunSection.getId()); + const port = node.getPortOfTrainrunSection(d.trainrunSections[0].getId()); const trans = node.getTransitionFromPortId(port.getId()); return trans === undefined; }) .classed(StaticDomTags.EDGE_IS_NOT_END_NODE, (d: TrainrunSectionViewObject) => { - let node = d.trainrunSection.getTargetNode(); + let node = d.trainrunSections[0].getTargetNode(); if (atSource) { - node = d.trainrunSection.getSourceNode(); + node = d.trainrunSections[0].getSourceNode(); } - const port = node.getPortOfTrainrunSection(d.trainrunSection.getId()); + const port = node.getPortOfTrainrunSection(d.trainrunSections[0].getId()); const trans = node.getTransitionFromPortId(port.getId()); return trans !== undefined; }) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), ) .on("mouseover", (d: TrainrunSectionViewObject, i, a) => this.onTrainrunSectionMouseoverPin( - TrainrunSectionsView.getNode(d.trainrunSection, atSource), + TrainrunSectionsView.getNode(d.trainrunSections[0], atSource), a[i], ), ) .on("mouseout", (d: TrainrunSectionViewObject, i, a) => - this.onTrainrunSectionMouseoutPin(d.trainrunSection, a[i], atSource), + this.onTrainrunSectionMouseoutPin(d.trainrunSections[0], a[i], atSource), ) .on("mousedown", () => this.onTrainrunSectionMousedownPin()) .on("mousemove", () => this.onTrainrunSectionMousemovePin()) .on("mouseup", (d: TrainrunSectionViewObject) => - this.onTrainrunSectionMouseupPin(d.trainrunSection, atSource), + this.onTrainrunSectionMouseupPin(d.trainrunSections[0], atSource), ); } @@ -1548,58 +1548,58 @@ export class TrainrunSectionsView { d.getTrainrun().isRoundTrip() || isDefaultText || isOneWayText; return ( - this.filterTrainrunsectionAtNode(d.trainrunSection, atSource) && - this.filterTimeTrainrunsectionNonStop(d.trainrunSection, atSource, isArrival) && - TrainrunSectionsView.hasWarning(d.trainrunSection, textElement) === hasWarning && + this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource) && + this.filterTimeTrainrunsectionNonStop(d.trainrunSections[0], atSource, isArrival) && + TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement) === hasWarning && displayTextElement ); }) .append(StaticDomTags.EDGE_LINE_TEXT_SVG) .attr("class", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionTimeElementClass( - d.trainrunSection, + d.trainrunSections[0], textElement, selectedTrainrun, connectedTrainIds, ), ) .attr("data-testid", StaticDomTags.EDGE_LINE_TEXT_CLASS) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) .attr("x", (d: TrainrunSectionViewObject) => { - const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSection); + const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSections[0]); if ( collapsedChainPath && collapsedChainPath.length >= 4 && (textElement === TrainrunSectionText.TargetDeparture || textElement === TrainrunSectionText.TargetArrival) ) { - const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSection); + const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSections[0]); if (chainSections.length > 1) { const lastSection = chainSections[chainSections.length - 1]; return lastSection.getTextPositionX(textElement); } } - return TrainrunSectionsView.getPositionX(d.trainrunSection, textElement); + return TrainrunSectionsView.getPositionX(d.trainrunSections[0], textElement); }) .attr("y", (d: TrainrunSectionViewObject) => { - const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSection); + const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSections[0]); if ( collapsedChainPath && collapsedChainPath.length >= 4 && (textElement === TrainrunSectionText.TargetDeparture || textElement === TrainrunSectionText.TargetArrival) ) { - const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSection); + const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSections[0]); if (chainSections.length > 1) { const lastSection = chainSections[chainSections.length - 1]; return lastSection.getTextPositionY(textElement); } } - return TrainrunSectionsView.getPositionY(d.trainrunSection, textElement); + return TrainrunSectionsView.getPositionY(d.trainrunSections[0], textElement); }) .attr( TrainrunSectionsView.getAdditionPositioningAttr(textElement), @@ -1610,40 +1610,40 @@ export class TrainrunSectionsView { d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.hasWarning(d.trainrunSection, textElement), + TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement), ) .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - this.getHiddenTagForTime(d.trainrunSection, textElement), + this.getHiddenTagForTime(d.trainrunSections[0], textElement), ) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .text((d: TrainrunSectionViewObject) => this.getTrainrunSectionValueToShowWithCollapsedSupport(d, textElement, this.editorView), ) .attr("style", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getTrainrunSectionValueHtmlStyle(d.trainrunSection, textElement), + TrainrunSectionsView.getTrainrunSectionValueHtmlStyle(d.trainrunSections[0], textElement), ) .on("mouseover", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionTextMouseover(d.trainrunSection, a[i]); + this.onTrainrunSectionTextMouseover(d.trainrunSections[0], a[i]); } }) .on("mouseout", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionTextMouseout(d.trainrunSection, a[i]); + this.onTrainrunSectionTextMouseout(d.trainrunSections[0], a[i]); } }) .on("mouseup", (d: TrainrunSectionViewObject, i, a) => { if (enableEvents) { - this.onTrainrunSectionElementClicked(d.trainrunSection, a[i], textElement); + this.onTrainrunSectionElementClicked(d.trainrunSections[0], a[i], textElement); } }); if (hasWarning) { renderingObjects.append("svg:title").text((d: TrainrunSectionViewObject) => { - return TrainrunSectionsView.getWarning(d.trainrunSection, textElement); + return TrainrunSectionsView.getWarning(d.trainrunSections[0], textElement); }); } } @@ -1685,18 +1685,18 @@ export class TrainrunSectionsView { const textElement = TrainrunSectionText.TrainrunSectionName; groupEnter .filter((d: TrainrunSectionViewObject) => - this.filterTrainrunsectionAtNode(d.trainrunSection, atSource), + this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource), ) .append(StaticDomTags.EDGE_LINE_TEXT_SVG) .attr("class", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionTimeElementClass( - d.trainrunSection, + d.trainrunSections[0], textElement, selectedTrainrun, connectedTrainIds, ), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) @@ -1705,7 +1705,7 @@ export class TrainrunSectionsView { .attr("y", 0) .attr("transform", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue( - d.trainrunSection, + d.trainrunSections[0], atSource, ), ) @@ -1713,18 +1713,18 @@ export class TrainrunSectionsView { d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.hasWarning(d.trainrunSection, textElement), + TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement), ) .classed(StaticDomTags.TAG_EVENT_DISABLED, true) .classed(StaticDomTags.TAG_START_TEXT_ANCHOR, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.enforceStartTextAnchor(d.trainrunSection, atSource), + TrainrunSectionsView.enforceStartTextAnchor(d.trainrunSections[0], atSource), ) .text((d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow( - d.trainrunSection, + d.trainrunSections[0], this.editorView, atSource, ), @@ -1770,7 +1770,7 @@ export class TrainrunSectionsView { ) .classed(StaticDomTags.TAG_SELECTED, () => trainrunSection.getTrainrun().selected()) .on("mouseup", (t: TrainrunSectionViewObject, i, a) => - this.onIntermediateStopMouseUp(t.trainrunSection, a[i]), + this.onIntermediateStopMouseUp(t.trainrunSections[0], a[i]), ); } @@ -1846,7 +1846,7 @@ export class TrainrunSectionsView { .select(a[i]) .append(StaticDomTags.EDGE_LINE_STOPS_GROUP_SVG) .attr("class", StaticDomTags.EDGE_LINE_STOPS_GROUP_CLASS); - this.createIntermediateStops(grp, t.trainrunSection, selectedTrainrun, connectedTrainIds); + this.createIntermediateStops(grp, t.trainrunSections[0], selectedTrainrun, connectedTrainIds); }); } @@ -1871,7 +1871,7 @@ export class TrainrunSectionsView { viewTrainrunSectionDataObjects.push( new TrainrunSectionViewObject( editorView, - d, + sections, TrainrunSectionsView.getNode(d, true).isNonStop(d), TrainrunSectionsView.getNode(d, false).isNonStop(d), TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), @@ -1917,12 +1917,12 @@ export class TrainrunSectionsView { .enter() .append(StaticDomTags.EDGE_SVG) .attr("class", StaticDomTags.EDGE_ROOT_CONTAINER) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), ) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(d.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ); const groupLines = edgeRootContainerEnter @@ -1931,7 +1931,7 @@ export class TrainrunSectionsView { .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr("data-testid", `${StaticDomTags.EDGE_CLASS}-lines`); const groupLabels = edgeRootContainerEnter @@ -1940,7 +1940,7 @@ export class TrainrunSectionsView { .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr("data-testid", `${StaticDomTags.EDGE_CLASS}-labels`); // Default case: Render default trainrunSection @@ -2117,7 +2117,7 @@ export class TrainrunSectionsView { (atSource ? StaticDomTags.EDGE_IS_TARGET : StaticDomTags.EDGE_IS_SOURCE), ) .filter( - (d: TrainrunSectionViewObject) => d.trainrunSection.getId() === trainrunSection.getId(), + (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId() === trainrunSection.getId(), ); const startAT: Vec2D = new Vec2D(+obj.attr("cx"), +obj.attr("cy")); this.editorView.trainrunSectionPreviewLineView.setExistingTrainrunSection(trainrunSection); @@ -2510,7 +2510,7 @@ export class TrainrunSectionsView { ) { const groupLines = inGroupLines.filter( (d: TrainrunSectionViewObject) => - !this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSection), + !this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSections[0]), ); this.make4LayerTrainrunSectionLines( @@ -2524,7 +2524,7 @@ export class TrainrunSectionsView { if (!this.editorView.isElementDragging()) { const groupLabels = inGroupLabels.filter( (d: TrainrunSectionViewObject) => - !this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSection), + !this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSections[0]), ); if (this.editorView.getLevelOfDetail() === LevelOfDetail.FULL) { @@ -2631,7 +2631,7 @@ export class TrainrunSectionsView { inGroupLabels, ) { const groupLines = inGroupLines.filter((d: TrainrunSectionViewObject) => - this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSection), + this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSections[0]), ); this.make4LayerTrainrunSectionLines( @@ -2644,7 +2644,7 @@ export class TrainrunSectionsView { if (!this.editorView.isElementDragging()) { const groupLabels = inGroupLabels.filter((d: TrainrunSectionViewObject) => - this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSection), + this.filterOutAllTrainrunSectionWithHiddenNodeConnection(d.trainrunSections[0]), ); if ( @@ -2841,12 +2841,12 @@ export class TrainrunSectionsView { (t: TrainrunSectionViewObject) => StaticDomTags.EDGE_LINE_STOPS_CLASS + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - t.trainrunSection, + t.trainrunSections[0], selectedTrainrun, connectedTrainIds, ), ) - .attr(StaticDomTags.EDGE_ID, (t: TrainrunSectionViewObject) => t.trainrunSection.getId()) + .attr(StaticDomTags.EDGE_ID, (t: TrainrunSectionViewObject) => t.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (t: TrainrunSectionViewObject) => t.getTrainrun().getId(), ) @@ -2856,23 +2856,23 @@ export class TrainrunSectionsView { .attr(StaticDomTags.EDGE_LINE_STOPS_INDEX, stopIndex) .attr("numberOfStops", numberOfStops) .classed(StaticDomTags.TAG_MUTED, (t: TrainrunSectionViewObject) => - TrainrunSectionsView.isMuted(t.trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted(t.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_SELECTED, (t: TrainrunSectionViewObject) => t.getTrainrun().selected(), ) .classed(StaticDomTags.EDGE_LINE_STOPS_FILL, () => !collapsedStops) .on("mouseover", (t: TrainrunSectionViewObject, i, a) => - this.onIntermediateStopMouseOver(t.trainrunSection, stopIndex, position, a[i]), + this.onIntermediateStopMouseOver(t.trainrunSections[0], stopIndex, position, a[i]), ) .on("mouseout", (t: TrainrunSectionViewObject, i, a) => - this.onIntermediateStopMouseOut(t.trainrunSection, stopIndex, position, a[i]), + this.onIntermediateStopMouseOut(t.trainrunSections[0], stopIndex, position, a[i]), ) .on("mousedown", (t: TrainrunSectionViewObject, i, a) => - this.onIntermediateStopMouseDown(t.trainrunSection, stopIndex, position, a[i]), + this.onIntermediateStopMouseDown(t.trainrunSections[0], stopIndex, position, a[i]), ) .on("mouseup", (t: TrainrunSectionViewObject, i, a) => - this.onIntermediateStopMouseUp(t.trainrunSection, a[i]), + this.onIntermediateStopMouseUp(t.trainrunSections[0], a[i]), ); } @@ -2945,7 +2945,7 @@ export class TrainrunSectionsView { textElement: TrainrunSectionText, editorView: EditorView, ) { - const trainrunSection = viewObject.trainrunSection; + const trainrunSection = viewObject.trainrunSections[0]; // Use unified logic for both collapsed chains and regular sections return this.getCollapsedChainValueToShow(trainrunSection, textElement, editorView); From f4585fdfb2fe6aa904b9400fe8160205e4da4e3a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 17:27:38 +0100 Subject: [PATCH 19/54] fixup! simplify text nodes position computation Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 59 ++++--------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 78edc2d2d..90c0ee579 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1570,36 +1570,20 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) .attr("x", (d: TrainrunSectionViewObject) => { - const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSections[0]); - if ( - collapsedChainPath && - collapsedChainPath.length >= 4 && - (textElement === TrainrunSectionText.TargetDeparture || - textElement === TrainrunSectionText.TargetArrival) - ) { - const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSections[0]); - if (chainSections.length > 1) { - const lastSection = chainSections[chainSections.length - 1]; - return lastSection.getTextPositionX(textElement); - } - } - return TrainrunSectionsView.getPositionX(d.trainrunSections[0], textElement); + const section = + textElement === TrainrunSectionText.TargetDeparture || + textElement === TrainrunSectionText.TargetArrival + ? d.trainrunSections.at(-1) + : d.trainrunSections[0]; + return TrainrunSectionsView.getPositionX(section, textElement); }) .attr("y", (d: TrainrunSectionViewObject) => { - const collapsedChainPath = this.getCollapsedChainPath(d.trainrunSections[0]); - if ( - collapsedChainPath && - collapsedChainPath.length >= 4 && - (textElement === TrainrunSectionText.TargetDeparture || - textElement === TrainrunSectionText.TargetArrival) - ) { - const chainSections = this.getAllSectionsInCollapsedChain(d.trainrunSections[0]); - if (chainSections.length > 1) { - const lastSection = chainSections[chainSections.length - 1]; - return lastSection.getTextPositionY(textElement); - } - } - return TrainrunSectionsView.getPositionY(d.trainrunSections[0], textElement); + const section = + textElement === TrainrunSectionText.TargetDeparture || + textElement === TrainrunSectionText.TargetArrival + ? d.trainrunSections.at(-1) + : d.trainrunSections[0]; + return TrainrunSectionsView.getPositionY(section, textElement); }) .attr( TrainrunSectionsView.getAdditionPositioningAttr(textElement), @@ -2921,25 +2905,6 @@ export class TrainrunSectionsView { /** * Get the value to show for collapsed chains (with corrected times) */ - /** - * Get the node IDs path for a collapsed chain - */ - getCollapsedChainNodePath(trainrunSection: TrainrunSection): number[] | null { - const sourceNodeId = trainrunSection.getSourceNodeId(); - const targetNodeId = trainrunSection.getTargetNodeId(); - const sourceNode = trainrunSection.getSourceNode(); - const targetNode = trainrunSection.getTargetNode(); - - // Check if this section crosses collapsed nodes by looking at the full chain - const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); - - if (chainSections.length > 1) { - return [sourceNodeId, targetNodeId]; - } - - return null; - } - getTrainrunSectionValueToShowWithCollapsedSupport( viewObject: TrainrunSectionViewObject, textElement: TrainrunSectionText, From caf2ae7e2450283c750f2b08c1f5e6168e0acd47 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 17:30:09 +0100 Subject: [PATCH 20/54] fixup! drop unnecessary getCollapsedChainValueToShow() wrapper Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 90c0ee579..ba6faad6d 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -2912,18 +2912,6 @@ export class TrainrunSectionsView { ) { const trainrunSection = viewObject.trainrunSections[0]; - // Use unified logic for both collapsed chains and regular sections - return this.getCollapsedChainValueToShow(trainrunSection, textElement, editorView); - } - - /** - * Calculate the correct values for collapsed chains - */ - getCollapsedChainValueToShow( - trainrunSection: TrainrunSection, - textElement: TrainrunSectionText, - editorView: EditorView, - ) { switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: From da5be4dd0c605fcc414ba92f0e6516b6cbc9d9a4 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 31 Oct 2025 17:33:35 +0100 Subject: [PATCH 21/54] fixup! drop getAllSectionsInCollapsedChain() The TrainrunSectionViewObject already contains the full chain, no need to re-compute it. Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 59 ++----------------- 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index ba6faad6d..126357a5a 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -2910,14 +2910,12 @@ export class TrainrunSectionsView { textElement: TrainrunSectionText, editorView: EditorView, ) { - const trainrunSection = viewObject.trainrunSections[0]; - switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: // For source times, use the original section times (should be from non-collapsed node) return TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSection, + viewObject.trainrunSections[0], textElement, editorView, ); @@ -2925,12 +2923,9 @@ export class TrainrunSectionsView { case TrainrunSectionText.TargetDeparture: case TrainrunSectionText.TargetArrival: { // For collapsed chains, use the actual time from the last section in the chain - const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); - const lastSection = chainSections[chainSections.length - 1]; - // Use the actual time from the last section (which already includes all stops and travel times) return TrainrunSectionsView.getTrainrunSectionValueToShow( - lastSection, + viewObject.trainrunSections.at(-1)!, textElement, editorView, ); @@ -2938,12 +2933,12 @@ export class TrainrunSectionsView { case TrainrunSectionText.TrainrunSectionTravelTime: { // For collapsed chains, calculate total time including stops at collapsed nodes - const chainSections = this.getAllSectionsInCollapsedChain(trainrunSection); - const lastSection = chainSections[chainSections.length - 1]; + const firstSection = viewObject.trainrunSections[0]; + const lastSection = viewObject.trainrunSections.at(-1)!; // Calculate total time: arrival time at end - departure time at start const startTime = TrainrunSectionsView.getTime( - trainrunSection, + firstSection, TrainrunSectionText.SourceDeparture, ); const endTime = TrainrunSectionsView.getTime( @@ -2959,51 +2954,9 @@ export class TrainrunSectionsView { case TrainrunSectionText.TrainrunSectionName: // For name, use the original trainrun name - return TrainrunSectionsView.extractTrainrunName(trainrunSection); + return TrainrunSectionsView.extractTrainrunName(viewObject.trainrunSections[0]); } return undefined; } - - /** - * Get all sections that are part of the same collapsed chain - */ - getAllSectionsInCollapsedChain(currentSection: TrainrunSection): TrainrunSection[] { - const sections: TrainrunSection[] = []; - let startSection = currentSection; - - // Walk backwards to find start of chain - while (startSection.getSourceNode().getIsCollapsed()) { - const prevSections = this.getConnectedTrainrunSections( - startSection.getSourceNode(), - currentSection.getTrainrunId(), - ).filter((ts) => ts.getId() !== startSection.getId()); - - if (prevSections.length === 1) { - startSection = prevSections[0]; - } else { - break; - } - } - - // Walk forwards to find end of chain and collect all sections - let currentSectionInChain = startSection; - sections.push(currentSectionInChain); - - while (currentSectionInChain.getTargetNode().getIsCollapsed()) { - const nextSections = this.getConnectedTrainrunSections( - currentSectionInChain.getTargetNode(), - currentSection.getTrainrunId(), - ).filter((ts) => ts.getId() !== currentSectionInChain.getId()); - - if (nextSections.length === 1) { - currentSectionInChain = nextSections[0]; - sections.push(currentSectionInChain); - } else { - break; - } - } - - return sections; - } } From 084583401a7cb2672c785d675725a442356798ea Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Nov 2025 11:15:56 +0100 Subject: [PATCH 22/54] fixup! fix path target position in TrainrunSectionViewObject.generateKey() We were only using the first trainrun section's path here. Expose a getPath() method to get a view object's path. We need to call it from inside generateKey() so drop the static attribute. While at it, make the generateKey() helper function private because it shouldn't be called from elsewhere. Signed-off-by: Simon Ser --- .../data-views/trainrunSectionViewObject.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index c28d31a95..fc8c344c5 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -1,4 +1,5 @@ import {TrainrunSection} from "../../../models/trainrunsection.model"; +import {Vec2D} from "../../../utils/vec2D"; import {EditorView} from "./editor.view"; export class TrainrunSectionViewObject { @@ -16,7 +17,7 @@ export class TrainrunSectionViewObject { hiddenTagTrainrunName: boolean, hiddenTagDirectionArrows: boolean, ) { - this.key = TrainrunSectionViewObject.generateKey( + this.key = this.generateKey( editorView, trainrunSections, isNonStopAtSource, @@ -34,7 +35,7 @@ export class TrainrunSectionViewObject { return this.trainrunSections[0].getTrainrun(); } - static generateKey( + private generateKey( editorView: EditorView, trainrunSections: TrainrunSection[], isNonStopAtSource: boolean, @@ -158,13 +159,16 @@ export class TrainrunSectionViewObject { key += "_" + editorView.checkFilterNode(data.node); }); - d.getPath().forEach((p) => { + this.getPath().forEach((p) => { key += p.toString(); }); - key += "_SRC_" + d.getSourceNode().getPositionX() + "_" + d.getSourceNode().getPositionY(); - key += "_TRG_" + d.getTargetNode().getPositionX() + "_" + d.getTargetNode().getPositionY(); - return key; } + + getPath(): Vec2D[] { + const sourcePath = this.trainrunSections[0].getPath().slice(0, 2); + const targetPath = this.trainrunSections.at(-1)!.getPath().slice(2, 4); + return [...sourcePath, ...targetPath]; + } } From d6d8973c647ddda82daf1d46d3538ec72d6d49bf Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Nov 2025 11:25:23 +0100 Subject: [PATCH 23/54] Fix missing source arrival in TrainrunSectionViewObject.generateKey() Target arrival was included twice, and source arrival was missing. Signed-off-by: Simon Ser --- .../editor-main-view/data-views/trainrunSectionViewObject.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index fc8c344c5..0f9d3b373 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -74,7 +74,7 @@ export class TrainrunSectionViewObject { "_" + d.getSourceDeparture() + "_" + - d.getTargetArrival() + + d.getSourceArrival() + "_" + d.getTargetDepartureConsecutiveTime() + "_" + From 7819d2acd09668070017c1347cf17371daaed944 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Nov 2025 11:27:47 +0100 Subject: [PATCH 24/54] fixup! use last section in TrainrunSectionViewObject.generateKey() We were only grabbing metadata from the first section, but we need to make the key change when the last section changes. Signed-off-by: Simon Ser --- .../data-views/trainrunSectionViewObject.ts | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 0f9d3b373..2c10c86d1 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -47,72 +47,74 @@ export class TrainrunSectionViewObject { hiddenTagTrainrunName: boolean, hiddenTagDirectionArrows: boolean, ): string { - const d = trainrunSections[0]; - const cumulativeTravelTimeData = editorView.getCumulativeTravelTimeAndNodePath(d); + const trainrun = this.getTrainrun(); + const firstSection = trainrunSections[0]; + const lastSection = trainrunSections.at(-1); + const cumulativeTravelTimeData = editorView.getCumulativeTravelTimeAndNodePath(firstSection); const cumulativeTravelTime = cumulativeTravelTimeData[cumulativeTravelTimeData.length - 1].sumTravelTime; let key = "#" + - d.getId() + + firstSection.getId() + "@" + - d.getTrainrun().getTitle() + + this.getTrainrun().getTitle() + "_" + - d.getTrainrun().selected() + + this.getTrainrun().selected() + "_" + - d.getNumberOfStops() + + firstSection.getNumberOfStops() + "_" + - d.getTravelTime() + + firstSection.getTravelTime() + "_" + cumulativeTravelTime + "_" + editorView.getTimeDisplayPrecision() + "_" + - d.getTargetDeparture() + + lastSection.getTargetDeparture() + "_" + - d.getTargetArrival() + + lastSection.getTargetArrival() + "_" + - d.getSourceDeparture() + + firstSection.getSourceDeparture() + "_" + - d.getSourceArrival() + + firstSection.getSourceArrival() + "_" + - d.getTargetDepartureConsecutiveTime() + + lastSection.getTargetDepartureConsecutiveTime() + "_" + - d.getTargetArrivalConsecutiveTime() + + lastSection.getTargetArrivalConsecutiveTime() + "_" + - d.getSourceDepartureConsecutiveTime() + + firstSection.getSourceDepartureConsecutiveTime() + "_" + - d.getTargetArrivalConsecutiveTime() + + firstSection.getTargetArrivalConsecutiveTime() + "_" + - d.getNumberOfStops() + + firstSection.getNumberOfStops() + "_" + - d.getFrequency() + + firstSection.getFrequency() + "_" + - d.getFrequencyOffset() + + firstSection.getFrequencyOffset() + "_" + - d.getTrainrun().getTrainrunCategory().shortName + + this.getTrainrun().getTrainrunCategory().shortName + "_" + - d.getTrainrun().getTrainrunFrequency().shortName + + this.getTrainrun().getTrainrunFrequency().shortName + "_" + - d.getTrainrun().getTrainrunTimeCategory().shortName + + this.getTrainrun().getTrainrunTimeCategory().shortName + "_" + - d.getTrainrun().getTrainrunCategory().id + + this.getTrainrun().getTrainrunCategory().id + "_" + - d.getTrainrun().getTrainrunFrequency().id + + this.getTrainrun().getTrainrunFrequency().id + "_" + - d.getTrainrun().getTrainrunTimeCategory().id + + this.getTrainrun().getTrainrunTimeCategory().id + "_" + - d.getTrainrun().getTrainrunCategory().colorRef + + this.getTrainrun().getTrainrunCategory().colorRef + "_" + - d.getTrainrun().getTrainrunFrequency().linePatternRef + + this.getTrainrun().getTrainrunFrequency().linePatternRef + "_" + - d.getTrainrun().getTrainrunTimeCategory().linePatternRef + + this.getTrainrun().getTrainrunTimeCategory().linePatternRef + "_" + - d.getTrainrun().getTrainrunFrequency().frequency + + this.getTrainrun().getTrainrunFrequency().frequency + "_" + - d.getTrainrun().getTrainrunFrequency().offset + + this.getTrainrun().getTrainrunFrequency().offset + "_" + - d.getTrainrun().getDirection() + + this.getTrainrun().getDirection() + "_" + isNonStopAtSource + "_" + @@ -134,17 +136,17 @@ export class TrainrunSectionViewObject { "_" + editorView.isFilterShowNonStopTimeEnabled() + "_" + - editorView.checkFilterNonStopNode(d.getSourceNode()) + + editorView.checkFilterNonStopNode(firstSection.getSourceNode()) + "_" + - editorView.checkFilterNonStopNode(d.getTargetNode()) + + editorView.checkFilterNonStopNode(lastSection.getTargetNode()) + "_" + - editorView.isJunctionNode(d.getSourceNode()) + + editorView.isJunctionNode(firstSection.getSourceNode()) + "_" + - editorView.isJunctionNode(d.getTargetNode()) + + editorView.isJunctionNode(lastSection.getTargetNode()) + "_" + - editorView.checkFilterNode(d.getSourceNode()) + + editorView.checkFilterNode(firstSection.getSourceNode()) + "_" + - editorView.checkFilterNode(d.getTargetNode()) + + editorView.checkFilterNode(lastSection.getTargetNode()) + "_" + editorView.isFilterDirectionArrowsEnabled() + "_" + From 0283d32ea0e1d30adf7e6a249dc4e828430b078b Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Nov 2025 11:36:03 +0100 Subject: [PATCH 25/54] fixup! drop TrainrunSectionsView.getCollapsedChainPath() Instead, grab the path from TrainrunSectionViewObject.getPath(). We need to update a few functions to take the veiw object instead of the first trainrun section. Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 161 +++--------------- 1 file changed, 24 insertions(+), 137 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 126357a5a..d6af22b8b 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -152,7 +152,7 @@ export class TrainrunSectionsView { trainrunSectionText: TrainrunSectionText, ) { const trainrunSection = viewObject.trainrunSections[0]; - const collapsedChainPath = this.getCollapsedChainPath(trainrunSection); + const collapsedChainPath = viewObject.getPath(); if (collapsedChainPath && collapsedChainPath.length >= MIN_PATH_LENGTH_FOR_ANGLE) { const textPositions = this.getTextPositionsForCollapsedChain( @@ -280,34 +280,6 @@ export class TrainrunSectionsView { return atSource ? trainrunSection.getSourceNode() : trainrunSection.getTargetNode(); } - /** - * Calculate a direct path between start and end nodes for collapsed chain visualization - */ - static calculateDirectPath( - startNode: Node, - endNode: Node, - allSections: TrainrunSection[], - primarySection: TrainrunSection, - ): Vec2D[] { - const [firstSection, lastSection] = [allSections[0], allSections[allSections.length - 1]]; - - const sourcePort = - startNode.getPortOfTrainrunSection(firstSection.getId()) ?? startNode.getPorts()[0]; - const targetPort = - endNode.getPortOfTrainrunSection(lastSection.getId()) ?? endNode.getPorts()[0]; - - if (!sourcePort || !targetPort) { - return []; - } - - return SimpleTrainrunSectionRouter.routeTrainrunSection( - startNode, - sourcePort, - endNode, - targetPort, - ); - } - static hasWarning(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): boolean { switch (textElement) { case TrainrunSectionText.SourceDeparture: @@ -1316,7 +1288,7 @@ export class TrainrunSectionsView { d.getTrainrun().getId(), ) .attr("d", (d: TrainrunSectionViewObject) => - D3Utils.getPathAsSVGString(this.transformPath(d.trainrunSections[0])), + D3Utils.getPathAsSVGString(this.transformPath(d)), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), @@ -1851,22 +1823,21 @@ export class TrainrunSectionsView { sectionGroups.forEach((sections) => { const d = sections[0]; - this.updateTrainrunSectionPathForCollapsedChain(d); - viewTrainrunSectionDataObjects.push( - new TrainrunSectionViewObject( - editorView, - sections, - TrainrunSectionsView.getNode(d, true).isNonStop(d), - TrainrunSectionsView.getNode(d, false).isNonStop(d), - TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), - !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && - !this.editorView.isFilterDirectionArrowsEnabled(), - ), + const viewObject = new TrainrunSectionViewObject( + editorView, + sections, + TrainrunSectionsView.getNode(d, true).isNonStop(d), + TrainrunSectionsView.getNode(d, false).isNonStop(d), + TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), + !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && + !this.editorView.isFilterDirectionArrowsEnabled(), ); + this.updateTrainrunSectionPathForCollapsedChain(viewObject); + viewTrainrunSectionDataObjects.push(viewObject); }); return viewTrainrunSectionDataObjects; @@ -2309,10 +2280,10 @@ export class TrainrunSectionsView { return transformedPath; } - private transformPath(ts: TrainrunSection): Vec2D[] { - const collapsedChainPath = this.getCollapsedChainPath(ts); - if (collapsedChainPath) { - return this.applyBasicFiltering(collapsedChainPath, ts); + private transformPath(viewObject: TrainrunSectionViewObject): Vec2D[] { + const ts = viewObject.trainrunSections[0]; + if (viewObject.trainrunSections.length > 1) { + return this.applyBasicFiltering(viewObject.getPath(), ts); } const srcNode = ts.getSourceNode(); @@ -2348,48 +2319,14 @@ export class TrainrunSectionsView { return retPath; } - /** - * Detect collapsed node chains and calculate direct visualization path - * - * A collapsed chain occurs when intermediate nodes are hidden from view. - * Example: A-B*-C*-D where B* and C* are collapsed -> create direct path A→D - * - * Algorithm: - * 1. Walk backward from current section to find chain start (non-collapsed node) - * 2. Walk forward from current section to find chain end (non-collapsed node) - * 3. If start != end, calculate direct path using legacy routing system - * - * @param currentSection The section that might be part of a collapsed chain - * @returns Direct path Vec2D[] if chain detected, null otherwise - */ - private getCollapsedChainPath(currentSection: TrainrunSection): Vec2D[] | null { - const trainrunId = currentSection.getTrainrunId(); - - const startSection = this.findChainBoundary(currentSection, trainrunId, "backward"); - const endSection = this.findChainBoundary(currentSection, trainrunId, "forward"); - - if (startSection.getId() !== endSection.getId()) { - const startNode = startSection.getSourceNode(); - const endNode = endSection.getTargetNode(); - - return TrainrunSectionsView.calculateDirectPath( - startNode, - endNode, - [startSection, endSection], - currentSection, - ); - } - - return null; - } - /** * Updates the TrainrunSection's path if it's part of a collapsed chain. * This ensures the visual rendering uses the correct collapsed path instead of the direct path. */ - private updateTrainrunSectionPathForCollapsedChain(section: TrainrunSection): void { - const collapsedPath = this.getCollapsedChainPath(section); - if (collapsedPath) { + private updateTrainrunSectionPathForCollapsedChain(viewObject: TrainrunSectionViewObject): void { + const section = viewObject.trainrunSections[0]; + const collapsedPath = viewObject.getPath(); + if (viewObject.trainrunSections.length > 1) { (section as any).pathVec2D = collapsedPath; const sourcePort = section.getSourceNode().getPort(section.getSourcePortId()); @@ -2400,56 +2337,6 @@ export class TrainrunSectionsView { } } - /** - * Find the boundary of a collapsed chain by walking in the specified direction - */ - private findChainBoundary( - startSection: TrainrunSection, - trainrunId: number, - direction: "forward" | "backward", - ): TrainrunSection { - let currentSection = startSection; - - // eslint-disable-next-line no-constant-condition - while (true) { - const node = - direction === "backward" ? currentSection.getSourceNode() : currentSection.getTargetNode(); - - if (!node.getIsCollapsed()) { - break; - } - - const connectedSections = this.getConnectedTrainrunSections(node, trainrunId).filter( - (ts) => ts.getId() !== currentSection.getId(), - ); - - if (connectedSections.length === 1) { - currentSection = connectedSections[0]; - } else { - break; - } - } - - return currentSection; - } - - /** - * Get all trainrun sections connected to a node for a specific trainrun - */ - private getConnectedTrainrunSections(node: Node, trainrunId: number): TrainrunSection[] { - const sections: TrainrunSection[] = []; - const ports = node.getPorts(); - - for (const port of ports) { - const section = port.getTrainrunSection(); - if (section && section.getTrainrunId() === trainrunId) { - sections.push(section); - } - } - - return sections; - } - /** * Apply basic filtering to a path */ From 1f62b2d541f1b98b50410cc52984d319fcb11ffa Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 5 Nov 2025 15:50:24 +0100 Subject: [PATCH 26/54] fixup! drop updateTrainrunSectionPathForCollapsedChain() This function overwrites a trainrun section's path. Instead, pick the right section (first or last) when computing path-related outputs. Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 250 +++++++++--------- 1 file changed, 120 insertions(+), 130 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index d6af22b8b..5136f2aa1 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -270,7 +270,8 @@ export class TrainrunSectionsView { return arcGenerator(); } - static getPosition(trainrunSection: TrainrunSection, atSource: boolean): Vec2D { + static getPosition(viewObject: TrainrunSectionViewObject, atSource: boolean): Vec2D { + const trainrunSection = viewObject.trainrunSections.at(atSource ? 0 : -1)!; return atSource ? trainrunSection.getPositionAtSourceNode() : trainrunSection.getPositionAtTargetNode(); @@ -280,6 +281,11 @@ export class TrainrunSectionsView { return atSource ? trainrunSection.getSourceNode() : trainrunSection.getTargetNode(); } + static getNodeFromViewObject(viewObject: TrainrunSectionViewObject, atSource: boolean): Node { + const trainrunSection = viewObject.trainrunSections.at(atSource ? 0 : -1)!; + return TrainrunSectionsView.getNode(trainrunSection, atSource); + } + static hasWarning(trainrunSection: TrainrunSection, textElement: TrainrunSectionText): boolean { switch (textElement) { case TrainrunSectionText.SourceDeparture: @@ -397,8 +403,8 @@ export class TrainrunSectionsView { } } - static enforceStartTextAnchor(trainrunSection: TrainrunSection, atSource: boolean): boolean { - const path = trainrunSection.getPath(); + static enforceStartTextAnchor(viewObject: TrainrunSectionViewObject, atSource: boolean): boolean { + const path = viewObject.getPath(); if (atSource) { if (Math.floor(path[1].getX() - path[0].getX()) > 0) { return true; @@ -418,10 +424,10 @@ export class TrainrunSectionsView { } static getAdditionTextCloseToNodePositioningValue( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, atSource: boolean, ): string { - const path = trainrunSection.getPath(); + const path = viewObject.getPath(); let pos: Vec2D; if (atSource) { pos = Vec2D.add(path[1], Vec2D.scale(Vec2D.normalize(Vec2D.sub(path[1], path[0])), 16)); @@ -962,10 +968,11 @@ export class TrainrunSectionsView { } static getTrainrunSectionNextAndDestinationNodeToShow( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, editorView: EditorView, atSource: boolean, ): string { + const trainrunSection = viewObject.trainrunSections.at(atSource ? 0 : -1); let startNode: Node; if (atSource) { startNode = trainrunSection.getSourceNode(); @@ -1106,8 +1113,8 @@ export class TrainrunSectionsView { .filter((d: TrainrunSectionViewObject) => { const displayTextBackground = d.getTrainrun().isRoundTrip() || isOneWayText; return ( - this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource) && - this.filterTimeTrainrunsectionNonStop(d.trainrunSections[0], atSource, isArrival) && + this.filterTrainrunsectionAtNode(d, atSource) && + this.filterTimeTrainrunsectionNonStop(d, atSource, isArrival) && displayTextBackground ); }) @@ -1127,33 +1134,33 @@ export class TrainrunSectionsView { d.getTrainrun().getId(), ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, lineTextElement) - .attr( - "x", - (d: TrainrunSectionViewObject) => - d.trainrunSections[0].getTextPositionX(lineTextElement) - - TrainrunSectionsView.getTrainrunSectionValueTextWidth( - d.trainrunSections[0], - lineTextElement, - ) / - 2, - ) - .attr( - "y", - (d: TrainrunSectionViewObject) => - d.trainrunSections[0].getTextPositionY(lineTextElement) - - TRAINRUN_SECTION_TEXT_AREA_HEIGHT / 2, - ) + .attr("x", (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; + return ( + trainrunSection.getTextPositionX(lineTextElement) - + TrainrunSectionsView.getTrainrunSectionValueTextWidth(trainrunSection, lineTextElement) / + 2 + ); + }) + .attr("y", (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; + return ( + trainrunSection.getTextPositionY(lineTextElement) - TRAINRUN_SECTION_TEXT_AREA_HEIGHT / 2 + ); + }) .attr("width", (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; return TrainrunSectionsView.getTrainrunSectionValueTextWidth( - d.trainrunSections[0], + trainrunSection, lineTextElement, ); }) .attr("height", TRAINRUN_SECTION_TEXT_AREA_HEIGHT) .classed(TrainrunSectionText[lineTextElement], true) - .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - this.getHiddenTagForTime(d.trainrunSections[0], lineTextElement), - ); + .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; + return this.getHiddenTagForTime(trainrunSection, lineTextElement); + }); } translateAndRotateArrow( @@ -1213,9 +1220,10 @@ export class TrainrunSectionsView { .attr("d", (d: TrainrunSectionViewObject) => { return d.getTrainrun().isRoundTrip() ? "" : "M-4,-5L2,0L-4,5Z"; }) - .attr("transform", (d: TrainrunSectionViewObject) => - this.translateAndRotateArrow(d.trainrunSections[0], arrowType), - ) + .attr("transform", (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(arrowType === "BEGINNING_ARROW" ? 0 : -1)!; + return this.translateAndRotateArrow(trainrunSection, arrowType); + }) .attr( "class", (d: TrainrunSectionViewObject) => @@ -1226,17 +1234,17 @@ export class TrainrunSectionsView { connectedTrainIds, ), ) - .classed( - StaticDomTags.TAG_HIDDEN, - (d: TrainrunSectionViewObject) => + .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(arrowType === "BEGINNING_ARROW" ? 0 : -1)!; + return ( !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && (!this.editorView.isFilterDirectionArrowsEnabled() || - !this.filterTrainrunsectionAtNode( - d.trainrunSections[0], - arrowType === "BEGINNING_ARROW", - )), + !this.filterTrainrunsectionAtNode(d, arrowType === "BEGINNING_ARROW")) + ); + }) + .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => + d.trainrunSections[0].getId(), ) - .attr(StaticDomTags.EDGE_ID, (d: TrainrunSectionViewObject) => d.trainrunSections[0].getId()) .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) @@ -1323,12 +1331,11 @@ export class TrainrunSectionsView { atSource: boolean, ) { groupEnter - .filter((d: TrainrunSectionViewObject) => - this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource), - ) + .filter((d: TrainrunSectionViewObject) => this.filterTrainrunsectionAtNode(d, atSource)) .filter((d: TrainrunSectionViewObject) => { - const trans = TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getTransition( - d.trainrunSections[0].getId(), + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; + const trans = TrainrunSectionsView.getNode(trainrunSection, atSource).getTransition( + trainrunSection.getId(), ); if (trans === undefined) { return true; @@ -1352,28 +1359,29 @@ export class TrainrunSectionsView { .attr(StaticDomTags.EDGE_LINE_LINE_ID, (d: TrainrunSectionViewObject) => d.getTrainrun().getId(), ) - .attr("d", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.createSemicircle( - d.trainrunSections[0], - TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource), - ), - ) + .attr("d", (d: TrainrunSectionViewObject) => { + return TrainrunSectionsView.createSemicircle( + d.trainrunSections.at(atSource ? 0 : -1)!, + TrainrunSectionsView.getPosition(d, atSource), + ); + }) .attr( "transform", (d: TrainrunSectionViewObject) => "translate(" + - TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getX() + + TrainrunSectionsView.getPosition(d, atSource).getX() + "," + - TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getY() + + TrainrunSectionsView.getPosition(d, atSource).getY() + ")", ) .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getId(), + TrainrunSectionsView.getNodeFromViewObject(d, atSource).getId(), ) .classed(StaticDomTags.EDGE_IS_TARGET, !atSource) - .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).isNonStop(d.trainrunSections[0]), - ) + .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1)!; + return TrainrunSectionsView.getNode(trainrunSection, atSource).isNonStop(trainrunSection); + }) .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) @@ -1425,21 +1433,21 @@ export class TrainrunSectionsView { d.getTrainrun().getId(), ) .attr("cx", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getX(), + TrainrunSectionsView.getPosition(d, atSource).getX(), ) .attr("cy", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getPosition(d.trainrunSections[0], atSource).getY(), + TrainrunSectionsView.getPosition(d, atSource).getY(), ) .attr("r", DEFAULT_PIN_RADIUS) .attr(StaticDomTags.EDGE_NODE_ID, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getNode(d.trainrunSections[0], atSource).getId(), + TrainrunSectionsView.getNodeFromViewObject(d, atSource).getId(), ) .classed( StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSections[0], atSource), + TrainrunSectionsView.getNodeFromViewObject(d, atSource), ), ) .classed( @@ -1447,25 +1455,29 @@ export class TrainrunSectionsView { (d: TrainrunSectionViewObject) => !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && !this.editorView.checkFilterNonStopNode( - TrainrunSectionsView.getNode(d.trainrunSections[0], atSource), + TrainrunSectionsView.getNodeFromViewObject(d, atSource), ), ) .classed(atSource ? StaticDomTags.EDGE_IS_SOURCE : StaticDomTags.EDGE_IS_TARGET, true) .classed(StaticDomTags.EDGE_IS_END_NODE, (d: TrainrunSectionViewObject) => { - let node = d.trainrunSections[0].getTargetNode(); + let trainrunSection = d.trainrunSections.at(-1)!; + let node = trainrunSection.getTargetNode(); if (atSource) { - node = d.trainrunSections[0].getSourceNode(); + trainrunSection = d.trainrunSections[0]; + node = trainrunSection.getSourceNode(); } - const port = node.getPortOfTrainrunSection(d.trainrunSections[0].getId()); + const port = node.getPortOfTrainrunSection(trainrunSection.getId()); const trans = node.getTransitionFromPortId(port.getId()); return trans === undefined; }) .classed(StaticDomTags.EDGE_IS_NOT_END_NODE, (d: TrainrunSectionViewObject) => { - let node = d.trainrunSections[0].getTargetNode(); + let trainrunSection = d.trainrunSections.at(-1)!; + let node = trainrunSection.getTargetNode(); if (atSource) { - node = d.trainrunSections[0].getSourceNode(); + trainrunSection = d.trainrunSections[0]; + node = trainrunSection.getSourceNode(); } - const port = node.getPortOfTrainrunSection(d.trainrunSections[0].getId()); + const port = node.getPortOfTrainrunSection(trainrunSection.getId()); const trans = node.getTransitionFromPortId(port.getId()); return trans !== undefined; }) @@ -1506,6 +1518,9 @@ export class TrainrunSectionsView { const atSource = textElement === TrainrunSectionText.SourceArrival || textElement === TrainrunSectionText.SourceDeparture; + const atTarget = + textElement === TrainrunSectionText.TargetArrival || + textElement === TrainrunSectionText.TargetDeparture; const isArrival = textElement === TrainrunSectionText.SourceArrival || textElement === TrainrunSectionText.TargetArrival; @@ -1516,13 +1531,13 @@ export class TrainrunSectionsView { const renderingObjects = groupEnter .filter((d: TrainrunSectionViewObject) => { - const displayTextElement = - d.getTrainrun().isRoundTrip() || isDefaultText || isOneWayText; + const trainrunSection = d.trainrunSections.at(atTarget ? -1 : 0)!; + const displayTextElement = d.getTrainrun().isRoundTrip() || isDefaultText || isOneWayText; return ( - this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource) && - this.filterTimeTrainrunsectionNonStop(d.trainrunSections[0], atSource, isArrival) && - TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement) === hasWarning && + this.filterTrainrunsectionAtNode(d, atSource) && + this.filterTimeTrainrunsectionNonStop(d, atSource, isArrival) && + TrainrunSectionsView.hasWarning(trainrunSection, textElement) === hasWarning && displayTextElement ); }) @@ -1542,19 +1557,11 @@ export class TrainrunSectionsView { ) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, textElement) .attr("x", (d: TrainrunSectionViewObject) => { - const section = - textElement === TrainrunSectionText.TargetDeparture || - textElement === TrainrunSectionText.TargetArrival - ? d.trainrunSections.at(-1) - : d.trainrunSections[0]; + const section = d.trainrunSections.at(atTarget ? -1 : 0)!; return TrainrunSectionsView.getPositionX(section, textElement); }) .attr("y", (d: TrainrunSectionViewObject) => { - const section = - textElement === TrainrunSectionText.TargetDeparture || - textElement === TrainrunSectionText.TargetArrival - ? d.trainrunSections.at(-1) - : d.trainrunSections[0]; + const section = d.trainrunSections.at(atTarget ? -1 : 0)!; return TrainrunSectionsView.getPositionY(section, textElement); }) .attr( @@ -1568,12 +1575,14 @@ export class TrainrunSectionsView { .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) - .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement), - ) - .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => - this.getHiddenTagForTime(d.trainrunSections[0], textElement), - ) + .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atTarget ? -1 : 0)!; + return TrainrunSectionsView.hasWarning(trainrunSection, textElement); + }) + .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { + const trainrunSection = d.trainrunSections.at(atTarget ? -1 : 0)!; + return this.getHiddenTagForTime(d.trainrunSections[0], textElement); + }) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .text((d: TrainrunSectionViewObject) => this.getTrainrunSectionValueToShowWithCollapsedSupport(d, textElement, this.editorView), @@ -1599,7 +1608,8 @@ export class TrainrunSectionsView { if (hasWarning) { renderingObjects.append("svg:title").text((d: TrainrunSectionViewObject) => { - return TrainrunSectionsView.getWarning(d.trainrunSections[0], textElement); + const trainrunSection = d.trainrunSections.at(atTarget ? -1 : 0)!; + return TrainrunSectionsView.getWarning(trainrunSection, textElement); }); } } @@ -1640,9 +1650,7 @@ export class TrainrunSectionsView { ) { const textElement = TrainrunSectionText.TrainrunSectionName; groupEnter - .filter((d: TrainrunSectionViewObject) => - this.filterTrainrunsectionAtNode(d.trainrunSections[0], atSource), - ) + .filter((d: TrainrunSectionViewObject) => this.filterTrainrunsectionAtNode(d, atSource)) .append(StaticDomTags.EDGE_LINE_TEXT_SVG) .attr("class", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionTimeElementClass( @@ -1660,10 +1668,7 @@ export class TrainrunSectionsView { .attr("x", 0) .attr("y", 0) .attr("transform", (d: TrainrunSectionViewObject) => - TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue( - d.trainrunSections[0], - atSource, - ), + TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(d, atSource), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), @@ -1671,16 +1676,17 @@ export class TrainrunSectionsView { .classed(StaticDomTags.TAG_MUTED, (d: TrainrunSectionViewObject) => TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) - .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement), - ) + .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => { + const trainrunSections = d.trainrunSections.at(atSource ? 0 : -1); + return TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement); + }) .classed(StaticDomTags.TAG_EVENT_DISABLED, true) .classed(StaticDomTags.TAG_START_TEXT_ANCHOR, (d: TrainrunSectionViewObject) => - TrainrunSectionsView.enforceStartTextAnchor(d.trainrunSections[0], atSource), + TrainrunSectionsView.enforceStartTextAnchor(d, atSource), ) .text((d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow( - d.trainrunSections[0], + d, this.editorView, atSource, ), @@ -1822,21 +1828,21 @@ export class TrainrunSectionsView { this.trainrunSectionService.groupTrainrunSectionsIntoChains(inputTrainrunSections); sectionGroups.forEach((sections) => { - const d = sections[0]; + const firstSection = sections[0]; + const lastSection = sections.at(-1)!; const viewObject = new TrainrunSectionViewObject( editorView, sections, - TrainrunSectionsView.getNode(d, true).isNonStop(d), - TrainrunSectionsView.getNode(d, false).isNonStop(d), - TrainrunSectionsView.isMuted(d, selectedTrainrun, connectedTrainIds), - this.getHiddenTagForTime(d, TrainrunSectionText.SourceDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TargetDeparture), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionTravelTime), - this.getHiddenTagForTime(d, TrainrunSectionText.TrainrunSectionName), + TrainrunSectionsView.getNode(firstSection, true).isNonStop(firstSection), + TrainrunSectionsView.getNode(lastSection, false).isNonStop(lastSection), + TrainrunSectionsView.isMuted(firstSection, selectedTrainrun, connectedTrainIds), + this.getHiddenTagForTime(firstSection, TrainrunSectionText.SourceDeparture), + this.getHiddenTagForTime(lastSection, TrainrunSectionText.TargetDeparture), + this.getHiddenTagForTime(firstSection, TrainrunSectionText.TrainrunSectionTravelTime), + this.getHiddenTagForTime(firstSection, TrainrunSectionText.TrainrunSectionName), !this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled() && !this.editorView.isFilterDirectionArrowsEnabled(), ); - this.updateTrainrunSectionPathForCollapsedChain(viewObject); viewTrainrunSectionDataObjects.push(viewObject); }); @@ -2159,13 +2165,14 @@ export class TrainrunSectionsView { } private filterTimeTrainrunsectionNonStop( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, atSource: boolean, isArrival: boolean, ): boolean { if (!isArrival) { return true; } + const trainrunSection = viewObject.trainrunSections.at(atSource ? 0 : -1); if (atSource) { return !trainrunSection.getSourceNode().isNonStop(trainrunSection); } @@ -2173,12 +2180,13 @@ export class TrainrunSectionsView { } private filterTrainrunsectionAtNode( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, atSource: boolean, ): boolean { if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { return true; } + const trainrunSection = viewObject.trainrunSections.at(atSource ? 0 : -1); return this.editorView.checkFilterNode(TrainrunSectionsView.getNode(trainrunSection, atSource)); } @@ -2319,24 +2327,6 @@ export class TrainrunSectionsView { return retPath; } - /** - * Updates the TrainrunSection's path if it's part of a collapsed chain. - * This ensures the visual rendering uses the correct collapsed path instead of the direct path. - */ - private updateTrainrunSectionPathForCollapsedChain(viewObject: TrainrunSectionViewObject): void { - const section = viewObject.trainrunSections[0]; - const collapsedPath = viewObject.getPath(); - if (viewObject.trainrunSections.length > 1) { - (section as any).pathVec2D = collapsedPath; - - const sourcePort = section.getSourceNode().getPort(section.getSourcePortId()); - if (sourcePort) { - (section as any).path.textPositions = - SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedPath, sourcePort); - } - } - } - /** * Apply basic filtering to a path */ From 1b69663724bd3d7e48d6c80916407deb2e8819c3 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 7 Nov 2025 15:15:24 +0100 Subject: [PATCH 27/54] Drop duplicate frequency in TrainrunSectionViewObject.generateKey() Further down, these two calls return the same values: this.getTrainrun().getTrainrunFrequency().frequency this.getTrainrun().getTrainrunFrequency().offset Signed-off-by: Simon Ser --- .../editor-main-view/data-views/trainrunSectionViewObject.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 2c10c86d1..9f08897aa 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -88,10 +88,6 @@ export class TrainrunSectionViewObject { "_" + firstSection.getNumberOfStops() + "_" + - firstSection.getFrequency() + - "_" + - firstSection.getFrequencyOffset() + - "_" + this.getTrainrun().getTrainrunCategory().shortName + "_" + this.getTrainrun().getTrainrunFrequency().shortName + From a5254dbc57c6f9503a76cf586fc563d7293ff350 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 7 Nov 2025 15:16:44 +0100 Subject: [PATCH 28/54] Fix missing source arrival consecutive time in TrainrunSectionViewObject.generateKey() Only the source matters for the first section, the target is handled by the last section of the chain. Same as this commit, but for the consecutive time: https://github.com/OpenRailAssociation/netzgrafik-editor-frontend/pull/605/commits/96892086ec63d6840a0a512b965ad6fa7200e2f5 Signed-off-by: Simon Ser --- .../editor-main-view/data-views/trainrunSectionViewObject.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 9f08897aa..f110809d8 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -84,7 +84,7 @@ export class TrainrunSectionViewObject { "_" + firstSection.getSourceDepartureConsecutiveTime() + "_" + - firstSection.getTargetArrivalConsecutiveTime() + + firstSection.getSourceArrivalConsecutiveTime() + "_" + firstSection.getNumberOfStops() + "_" + From 0a6ffdfbee72c99fee3b2eae72a3b5028dc94f24 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 13 Nov 2025 14:29:21 +0100 Subject: [PATCH 29/54] Implement new getTravelTime method to compute total travel time to TrainrunSectionViewObject --- .../data-views/trainrunSectionViewObject.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index f110809d8..7cf9a08d2 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -35,6 +35,15 @@ export class TrainrunSectionViewObject { return this.trainrunSections[0].getTrainrun(); } + getTravelTime(): number { + const firstSection = this.trainrunSections[0]; + const lastSection = this.trainrunSections.at(-1); + const startTime = firstSection.getSourceDepartureConsecutiveTime(); + const endTime = lastSection!.getTargetArrivalConsecutiveTime(); + + return endTime - startTime; + } + private generateKey( editorView: EditorView, trainrunSections: TrainrunSection[], @@ -64,7 +73,7 @@ export class TrainrunSectionViewObject { "_" + firstSection.getNumberOfStops() + "_" + - firstSection.getTravelTime() + + this.getTravelTime() + "_" + cumulativeTravelTime + "_" + From 4ef6ce171e0223bf144240092fb89ddf567d6800 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 13 Nov 2025 14:30:49 +0100 Subject: [PATCH 30/54] Merge getTrainrunSectionValueToShow and getTrainrunSectionValueToShowWithCollapsed support to avoid duplication --- .../data-views/trainrunsections.view.ts | 112 ++++++++---------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 5136f2aa1..02d9316f8 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -892,10 +892,60 @@ export class TrainrunSectionsView { } static getTrainrunSectionValueToShow( - trainrunSection: TrainrunSection, + trainrunSectionOrViewObject: TrainrunSection | TrainrunSectionViewObject, textElement: TrainrunSectionText, editorView: EditorView, ) { + // Determine which section to use + let trainrunSection: TrainrunSection; + + if (trainrunSectionOrViewObject instanceof TrainrunSection) { + // Simple case: we have a TrainrunSection directly + trainrunSection = trainrunSectionOrViewObject; + } else { + // ViewObject case: determine which section to use based on textElement + const viewObject = trainrunSectionOrViewObject; + + switch (textElement) { + case TrainrunSectionText.SourceDeparture: + case TrainrunSectionText.SourceArrival: + trainrunSection = viewObject.trainrunSections[0]; + break; + + case TrainrunSectionText.TargetDeparture: + case TrainrunSectionText.TargetArrival: + trainrunSection = viewObject.trainrunSections.at(-1)!; + break; + + case TrainrunSectionText.TrainrunSectionTravelTime: + // Special case for multiple sections: calculate total time + if (viewObject.trainrunSections.length > 1) { + const firstSection = viewObject.trainrunSections[0]; + const lastSection = viewObject.trainrunSections.at(-1)!; + + const startTime = TrainrunSectionsView.getTime( + firstSection, + TrainrunSectionText.SourceDeparture, + ); + const endTime = TrainrunSectionsView.getTime( + lastSection, + TrainrunSectionText.TargetArrival, + ); + const totalTime = endTime - startTime; + + return ( + TrainrunSectionsView.formatTime(totalTime, editorView.getTimeDisplayPrecision()) + "'" + ); + } + trainrunSection = viewObject.trainrunSections[0]; + break; + + default: + trainrunSection = viewObject.trainrunSections[0]; + } + } + + // Existing logic to display the value switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: @@ -1585,7 +1635,7 @@ export class TrainrunSectionsView { }) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .text((d: TrainrunSectionViewObject) => - this.getTrainrunSectionValueToShowWithCollapsedSupport(d, textElement, this.editorView), + TrainrunSectionsView.getTrainrunSectionValueToShow(d, textElement, this.editorView), ) .attr("style", (d: TrainrunSectionViewObject) => TrainrunSectionsView.getTrainrunSectionValueHtmlStyle(d.trainrunSections[0], textElement), @@ -2778,62 +2828,4 @@ export class TrainrunSectionsView { this.editorView.nodesView.createNewTrainrunSection(startNode, endNode); this.editorView.setTrainrunSectionAsSelected(trainrunSectionFrom); } - - /** - * Get the value to show for collapsed chains (with corrected times) - */ - getTrainrunSectionValueToShowWithCollapsedSupport( - viewObject: TrainrunSectionViewObject, - textElement: TrainrunSectionText, - editorView: EditorView, - ) { - switch (textElement) { - case TrainrunSectionText.SourceDeparture: - case TrainrunSectionText.SourceArrival: - // For source times, use the original section times (should be from non-collapsed node) - return TrainrunSectionsView.getTrainrunSectionValueToShow( - viewObject.trainrunSections[0], - textElement, - editorView, - ); - - case TrainrunSectionText.TargetDeparture: - case TrainrunSectionText.TargetArrival: { - // For collapsed chains, use the actual time from the last section in the chain - // Use the actual time from the last section (which already includes all stops and travel times) - return TrainrunSectionsView.getTrainrunSectionValueToShow( - viewObject.trainrunSections.at(-1)!, - textElement, - editorView, - ); - } - - case TrainrunSectionText.TrainrunSectionTravelTime: { - // For collapsed chains, calculate total time including stops at collapsed nodes - const firstSection = viewObject.trainrunSections[0]; - const lastSection = viewObject.trainrunSections.at(-1)!; - - // Calculate total time: arrival time at end - departure time at start - const startTime = TrainrunSectionsView.getTime( - firstSection, - TrainrunSectionText.SourceDeparture, - ); - const endTime = TrainrunSectionsView.getTime( - lastSection, - TrainrunSectionText.TargetArrival, - ); - const totalTime = endTime - startTime; - - return ( - TrainrunSectionsView.formatTime(totalTime, editorView.getTimeDisplayPrecision()) + "'" - ); - } - - case TrainrunSectionText.TrainrunSectionName: - // For name, use the original trainrun name - return TrainrunSectionsView.extractTrainrunName(viewObject.trainrunSections[0]); - } - - return undefined; - } } From bfd19b3b5d065e4bfd5c82526bb1b7ca0460c420 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 13 Nov 2025 14:50:01 +0100 Subject: [PATCH 31/54] Drop applyBasicFiltering after merging the logic in transformPath --- .../data-views/trainrunsections.view.ts | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 02d9316f8..a8fc02472 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -2339,22 +2339,48 @@ export class TrainrunSectionsView { } private transformPath(viewObject: TrainrunSectionViewObject): Vec2D[] { - const ts = viewObject.trainrunSections[0]; + const firstSection = viewObject.trainrunSections[0]; + const lastSection = viewObject.trainrunSections.at(-1)!; + + // Handle multi-section chains (collapsed nodes) if (viewObject.trainrunSections.length > 1) { - return this.applyBasicFiltering(viewObject.getPath(), ts); + const path = viewObject.getPath(); + const srcNode = firstSection.getSourceNode(); + const trgNode = lastSection.getTargetNode(); + + let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); + let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); + + if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { + notFilteringSourceNode = true; + notFilteringTargetNode = true; + } + + if (notFilteringSourceNode && notFilteringTargetNode) { + return path.map((p) => p.copy()); + } else if (notFilteringSourceNode) { + return path.slice(0, 2).map((p) => p.copy()); + } else if (notFilteringTargetNode) { + return path.slice(2).map((p) => p.copy()); + } else { + return []; + } } - const srcNode = ts.getSourceNode(); - const trgNode = ts.getTargetNode(); + // Handle single sections + const srcNode = firstSection.getSourceNode(); + const trgNode = firstSection.getTargetNode(); let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); + if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { notFilteringSourceNode = true; notFilteringTargetNode = true; } - const path = ts.getPath(); + const path = firstSection.getPath(); let retPath: Vec2D[] = []; + if (notFilteringSourceNode) { retPath.push(path[0].copy()); retPath.push(path[1].copy()); @@ -2365,43 +2391,23 @@ export class TrainrunSectionsView { } if (!this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { - if (ts.getSourceNode().isNonStopNode()) { - const node = ts.getSourceNode().getOppositeNode(ts); - retPath = this.transformPathIfSourceNodeFilteredDueNonStopNodesFiltering(ts, retPath); + if (firstSection.getSourceNode().isNonStopNode()) { + retPath = this.transformPathIfSourceNodeFilteredDueNonStopNodesFiltering( + firstSection, + retPath, + ); } - if (ts.getTargetNode().isNonStopNode()) { - retPath = this.transformPathIfTargetNodeFilteredDueNonStopNodesFiltering(ts, retPath); + if (firstSection.getTargetNode().isNonStopNode()) { + retPath = this.transformPathIfTargetNodeFilteredDueNonStopNodesFiltering( + firstSection, + retPath, + ); } } return retPath; } - /** - * Apply basic filtering to a path - */ - private applyBasicFiltering(path: Vec2D[], ts: TrainrunSection): Vec2D[] { - const srcNode = ts.getSourceNode(); - const trgNode = ts.getTargetNode(); - let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); - let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); - - if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { - notFilteringSourceNode = true; - notFilteringTargetNode = true; - } - - if (notFilteringSourceNode && notFilteringTargetNode) { - return path.map((p) => p.copy()); - } else if (notFilteringSourceNode) { - return path.slice(0, 2).map((p) => p.copy()); - } else if (notFilteringTargetNode) { - return path.slice(2).map((p) => p.copy()); - } else { - return []; - } - } - private filterOutAllTrainrunSectionWithHiddenNodeConnection( trainrunSection: TrainrunSection, ): boolean { From 73b6bf8fdae69a1adedde64ec7399af543a18369 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Fri, 14 Nov 2025 10:46:23 +0100 Subject: [PATCH 32/54] refactor: throw error on cycle detection in trainrun section chains --- src/app/services/data/trainrunsection.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/services/data/trainrunsection.service.ts b/src/app/services/data/trainrunsection.service.ts index fcc02fd9c..0375fd746 100644 --- a/src/app/services/data/trainrunsection.service.ts +++ b/src/app/services/data/trainrunsection.service.ts @@ -1526,7 +1526,9 @@ export class TrainrunSectionService implements OnDestroy { const pair = iterator.next(); if (visitedSections.has(pair.trainrunSection.getId())) { - break; // Already processed this section + throw new Error( + `Cycle detected in trainrun section chain: section ${pair.trainrunSection.getId()} already visited for trainrun ${pair.trainrunSection.getTrainrunId()}`, + ); } chain.push(pair.trainrunSection); From a95cecade7b0841a6a82c6e02a97178a17637474 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Mon, 17 Nov 2025 12:02:26 +0100 Subject: [PATCH 33/54] refactor: merge duplicate text positioning functions --- .../data-views/trainrunsections.view.ts | 80 +++++-------------- 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index a8fc02472..f48765fb7 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -54,11 +54,21 @@ export class TrainrunSectionsView { static translateAndRotateText( trainrunSection: TrainrunSection, trainrunSectionText: TrainrunSectionText, + viewObject?: TrainrunSectionViewObject, ) { const x = trainrunSection.getTextPositionX(trainrunSectionText); const y = trainrunSection.getTextPositionY(trainrunSectionText); - const pathVec2D: Vec2D[] = trainrunSection.getPath(); + // Use viewObject path if provided, otherwise use trainrunSection path + const pathVec2D: Vec2D[] = viewObject + ? viewObject.trainrunSections[0].getPath() + : trainrunSection.getPath(); + + // Check if path has enough points + if (pathVec2D.length < 4) { + return "translate(" + x + "," + y + ") rotate(0, 0,0) "; + } + const s1: Vec2D = pathVec2D[1]; const t1: Vec2D = pathVec2D[2]; const diff: Vec2D = Vec2D.sub(t1, s1); @@ -76,41 +86,6 @@ export class TrainrunSectionsView { return "translate(" + x + "," + y + ") rotate(" + a + ", 0,0) "; } - /** - * Version that works with TrainrunSectionViewObject to handle custom paths for collapsed chains - * This method needs access to the view instance to get the collapsed path - */ - static translateAndRotateTextForViewObject( - viewObject: TrainrunSectionViewObject, - trainrunSectionText: TrainrunSectionText, - ) { - const trainrunSection = viewObject.trainrunSections[0]; - - const x = trainrunSection.getTextPositionX(trainrunSectionText); - const y = trainrunSection.getTextPositionY(trainrunSectionText); - const originalPath = trainrunSection.getPath(); - - if (originalPath.length >= 4) { - const s1: Vec2D = originalPath[1]; - const t1: Vec2D = originalPath[2]; - const diff: Vec2D = Vec2D.sub(t1, s1); - let a: number = (Math.atan2(diff.getY(), diff.getX()) / Math.PI) * 180.0; - if (Math.abs(a) > ANGLE_UPSIDE_DOWN_THRESHOLD) { - a = a + 180; - } - // Math.atan2 -> edge cases -> correct manually - if (Math.abs(diff.getX()) < EDGE_CASE_THRESHOLD) { - a = DEFAULT_ANGLE_VERTICAL; - } - if (Math.abs(diff.getY()) < EDGE_CASE_THRESHOLD) { - a = DEFAULT_ANGLE_HORIZONTAL; - } - return "translate(" + x + "," + y + ") rotate(" + a + ", 0,0) "; - } - - return "translate(" + x + "," + y + ") rotate(0, 0,0) "; - } - private getTextPositionsForCollapsedChain( collapsedChainPath: Vec2D[], trainrunSection: TrainrunSection, @@ -189,9 +164,10 @@ export class TrainrunSectionsView { return `translate(${x},${y}) rotate(${angle}, 0,0) `; } - return TrainrunSectionsView.translateAndRotateTextForViewObject( - viewObject, + return TrainrunSectionsView.translateAndRotateText( + trainrunSection, trainrunSectionText, + viewObject, ); } @@ -497,6 +473,7 @@ export class TrainrunSectionsView { static getAdditionPositioningValue( trainrunSection: TrainrunSection, textElement: TrainrunSectionText, + viewObject?: TrainrunSectionViewObject, ) { switch (textElement) { case TrainrunSectionText.SourceDeparture: @@ -506,28 +483,11 @@ export class TrainrunSectionsView { return 1.5; case TrainrunSectionText.TrainrunSectionTravelTime: case TrainrunSectionText.TrainrunSectionName: - return TrainrunSectionsView.translateAndRotateText(trainrunSection, textElement); - default: - return 0; - } - } - - /** - * Version that works with TrainrunSectionViewObject for collapsed chains - */ - static getAdditionPositioningValueForViewObject( - viewObject: TrainrunSectionViewObject, - textElement: TrainrunSectionText, - ) { - switch (textElement) { - case TrainrunSectionText.SourceDeparture: - case TrainrunSectionText.SourceArrival: - case TrainrunSectionText.TargetDeparture: - case TrainrunSectionText.TargetArrival: - return 1.5; - case TrainrunSectionText.TrainrunSectionTravelTime: - case TrainrunSectionText.TrainrunSectionName: - return TrainrunSectionsView.translateAndRotateTextForViewObject(viewObject, textElement); + return TrainrunSectionsView.translateAndRotateText( + trainrunSection, + textElement, + viewObject, + ); default: return 0; } From bcb91f2432a954af5c8bab56cdbcf4a4c529dedd Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Mon, 17 Nov 2025 15:53:11 +0100 Subject: [PATCH 34/54] fix: fix the calculation of collapsedsection total travel time --- .../data-views/trainrunsections.view.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index f48765fb7..47a67cfcd 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -878,20 +878,24 @@ export class TrainrunSectionsView { break; case TrainrunSectionText.TrainrunSectionTravelTime: - // Special case for multiple sections: calculate total time + // Special case for multiple sections: calculate total time including stop times at intermediate nodes if (viewObject.trainrunSections.length > 1) { - const firstSection = viewObject.trainrunSections[0]; - const lastSection = viewObject.trainrunSections.at(-1)!; + const totalTime = viewObject.trainrunSections.reduce((sum, section, index) => { + // Add travel time for this section + let sectionTime = section.getTravelTime(); + + // Add stop time at intermediate nodes (all except the last section) + if (index < viewObject.trainrunSections.length - 1) { + const nextSection = viewObject.trainrunSections[index + 1]; + const stopTime = Math.abs( + nextSection.getSourceDepartureConsecutiveTime() - + section.getTargetArrivalConsecutiveTime(), + ); + sectionTime += stopTime; + } - const startTime = TrainrunSectionsView.getTime( - firstSection, - TrainrunSectionText.SourceDeparture, - ); - const endTime = TrainrunSectionsView.getTime( - lastSection, - TrainrunSectionText.TargetArrival, - ); - const totalTime = endTime - startTime; + return sum + sectionTime; + }, 0); return ( TrainrunSectionsView.formatTime(totalTime, editorView.getTimeDisplayPrecision()) + "'" From d927e759c201529b5fe90a7b629eded851c2cd8c Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 19 Nov 2025 17:08:33 +0100 Subject: [PATCH 35/54] Update trainrunsectionViewObject.gettraveltime to handle stop times --- .../data-views/trainrunSectionViewObject.ts | 23 +++++++++++++++---- .../data-views/trainrunsections.view.ts | 22 ++++-------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 7cf9a08d2..fc36b2416 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -36,12 +36,25 @@ export class TrainrunSectionViewObject { } getTravelTime(): number { - const firstSection = this.trainrunSections[0]; - const lastSection = this.trainrunSections.at(-1); - const startTime = firstSection.getSourceDepartureConsecutiveTime(); - const endTime = lastSection!.getTargetArrivalConsecutiveTime(); + if (this.trainrunSections.length === 1) { + return this.trainrunSections[0].getTravelTime(); + } - return endTime - startTime; + return this.trainrunSections.reduce((sum, section, index) => { + let sectionTime = section.getTravelTime(); + + // Add stop time at intermediate nodes (all except the last section) + if (index < this.trainrunSections.length - 1) { + const nextSection = this.trainrunSections[index + 1]; + const stopTime = Math.abs( + nextSection.getSourceDepartureConsecutiveTime() - + section.getTargetArrivalConsecutiveTime(), + ); + sectionTime += stopTime; + } + + return sum + sectionTime; + }, 0); } private generateKey( diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 47a67cfcd..eb9efd5b2 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -880,25 +880,11 @@ export class TrainrunSectionsView { case TrainrunSectionText.TrainrunSectionTravelTime: // Special case for multiple sections: calculate total time including stop times at intermediate nodes if (viewObject.trainrunSections.length > 1) { - const totalTime = viewObject.trainrunSections.reduce((sum, section, index) => { - // Add travel time for this section - let sectionTime = section.getTravelTime(); - - // Add stop time at intermediate nodes (all except the last section) - if (index < viewObject.trainrunSections.length - 1) { - const nextSection = viewObject.trainrunSections[index + 1]; - const stopTime = Math.abs( - nextSection.getSourceDepartureConsecutiveTime() - - section.getTargetArrivalConsecutiveTime(), - ); - sectionTime += stopTime; - } - - return sum + sectionTime; - }, 0); - return ( - TrainrunSectionsView.formatTime(totalTime, editorView.getTimeDisplayPrecision()) + "'" + TrainrunSectionsView.formatTime( + viewObject.getTravelTime(), + editorView.getTimeDisplayPrecision(), + ) + "'" ); } trainrunSection = viewObject.trainrunSections[0]; From e8ebb8fed6206d11a3970c96be102ab02e387c75 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 19 Nov 2025 17:42:08 +0100 Subject: [PATCH 36/54] refactor : (gettrainrunvaluetoshow) merge switch cases and remove TrainrunSection param -Remove TrainrunSection parameter support (accept only TrainrunSectionViewObject) -Merge duplicate switch statements into single switch -Merge Source/Target and Departure/Arrival into single case --- .../data-views/trainrunsections.view.ts | 86 +++++++------------ 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index eb9efd5b2..9e95e1c9d 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -852,75 +852,55 @@ export class TrainrunSectionsView { } static getTrainrunSectionValueToShow( - trainrunSectionOrViewObject: TrainrunSection | TrainrunSectionViewObject, + viewObject: TrainrunSectionViewObject, textElement: TrainrunSectionText, editorView: EditorView, ) { - // Determine which section to use - let trainrunSection: TrainrunSection; - - if (trainrunSectionOrViewObject instanceof TrainrunSection) { - // Simple case: we have a TrainrunSection directly - trainrunSection = trainrunSectionOrViewObject; - } else { - // ViewObject case: determine which section to use based on textElement - const viewObject = trainrunSectionOrViewObject; - - switch (textElement) { - case TrainrunSectionText.SourceDeparture: - case TrainrunSectionText.SourceArrival: - trainrunSection = viewObject.trainrunSections[0]; - break; - - case TrainrunSectionText.TargetDeparture: - case TrainrunSectionText.TargetArrival: - trainrunSection = viewObject.trainrunSections.at(-1)!; - break; - - case TrainrunSectionText.TrainrunSectionTravelTime: - // Special case for multiple sections: calculate total time including stop times at intermediate nodes - if (viewObject.trainrunSections.length > 1) { - return ( - TrainrunSectionsView.formatTime( - viewObject.getTravelTime(), - editorView.getTimeDisplayPrecision(), - ) + "'" - ); - } - trainrunSection = viewObject.trainrunSections[0]; - break; - - default: - trainrunSection = viewObject.trainrunSections[0]; - } - } - - // Existing logic to display the value switch (textElement) { case TrainrunSectionText.SourceDeparture: case TrainrunSectionText.SourceArrival: case TrainrunSectionText.TargetDeparture: case TrainrunSectionText.TargetArrival: { - const data = TrainrunSectionsView.getFormattedDisplayText(trainrunSection, textElement); - if (data !== undefined) { - return data; - } - return TrainrunSectionsView.formatTime( - TrainrunSectionsView.getTime(trainrunSection, textElement), - editorView.getTimeDisplayPrecision(), + const isTarget = + textElement === TrainrunSectionText.TargetDeparture || + textElement === TrainrunSectionText.TargetArrival; + const trainrunSection = isTarget + ? viewObject.trainrunSections.at(-1)! + : viewObject.trainrunSections[0]; + + return ( + TrainrunSectionsView.getFormattedDisplayText(trainrunSection, textElement) ?? + TrainrunSectionsView.formatTime( + TrainrunSectionsView.getTime(trainrunSection, textElement), + editorView.getTimeDisplayPrecision(), + ) ); } case TrainrunSectionText.TrainrunSectionTravelTime: { - const data = TrainrunSectionsView.getFormattedDisplayText(trainrunSection, textElement); - if (data !== undefined) { - return data; + const trainrunSection = viewObject.trainrunSections[0]; + const formattedData = TrainrunSectionsView.getFormattedDisplayText( + trainrunSection, + textElement, + ); + if (formattedData !== undefined) { + return formattedData; + } + // Special case for multiple sections: calculate total time including stop times at intermediate nodes + if (viewObject.trainrunSections.length > 1) { + return ( + TrainrunSectionsView.formatTime( + viewObject.getTravelTime(), + editorView.getTimeDisplayPrecision(), + ) + "'" + ); } return TrainrunSectionsView.extractTravelTime(trainrunSection, editorView); } case TrainrunSectionText.TrainrunSectionName: - return TrainrunSectionsView.extractTrainrunName(trainrunSection); + return TrainrunSectionsView.extractTrainrunName(viewObject.trainrunSections[0]); + default: + return undefined; } - return undefined; } static getTrainrunSectionValueTextWidth( From 4ada8d9dc9cd391087b56cfdfda3a71635fff55c Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 19 Nov 2025 17:55:46 +0100 Subject: [PATCH 37/54] refactor: remove special case for multi-section paths in transformPath -use complete path for collapsed nodes in text rotation --- .../data-views/trainrunsections.view.ts | 39 +++---------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 9e95e1c9d..7c40e4a79 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -60,9 +60,7 @@ export class TrainrunSectionsView { const y = trainrunSection.getTextPositionY(trainrunSectionText); // Use viewObject path if provided, otherwise use trainrunSection path - const pathVec2D: Vec2D[] = viewObject - ? viewObject.trainrunSections[0].getPath() - : trainrunSection.getPath(); + const pathVec2D: Vec2D[] = viewObject ? viewObject.getPath() : trainrunSection.getPath(); // Check if path has enough points if (pathVec2D.length < 4) { @@ -2272,34 +2270,10 @@ export class TrainrunSectionsView { const firstSection = viewObject.trainrunSections[0]; const lastSection = viewObject.trainrunSections.at(-1)!; - // Handle multi-section chains (collapsed nodes) - if (viewObject.trainrunSections.length > 1) { - const path = viewObject.getPath(); - const srcNode = firstSection.getSourceNode(); - const trgNode = lastSection.getTargetNode(); - - let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); - let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); - - if (this.editorView.isTemporaryDisableFilteringOfItemsInViewEnabled()) { - notFilteringSourceNode = true; - notFilteringTargetNode = true; - } - - if (notFilteringSourceNode && notFilteringTargetNode) { - return path.map((p) => p.copy()); - } else if (notFilteringSourceNode) { - return path.slice(0, 2).map((p) => p.copy()); - } else if (notFilteringTargetNode) { - return path.slice(2).map((p) => p.copy()); - } else { - return []; - } - } - - // Handle single sections const srcNode = firstSection.getSourceNode(); - const trgNode = firstSection.getTargetNode(); + const trgNode = lastSection.getTargetNode(); + const path = viewObject.getPath(); + let notFilteringSourceNode = this.editorView.checkFilterNode(srcNode); let notFilteringTargetNode = this.editorView.checkFilterNode(trgNode); @@ -2308,7 +2282,6 @@ export class TrainrunSectionsView { notFilteringTargetNode = true; } - const path = firstSection.getPath(); let retPath: Vec2D[] = []; if (notFilteringSourceNode) { @@ -2327,9 +2300,9 @@ export class TrainrunSectionsView { retPath, ); } - if (firstSection.getTargetNode().isNonStopNode()) { + if (lastSection.getTargetNode().isNonStopNode()) { retPath = this.transformPathIfTargetNodeFilteredDueNonStopNodesFiltering( - firstSection, + lastSection, retPath, ); } From 5aab87711daec9b2ae47794d761e62bb6e3a9e3e Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 20 Nov 2025 16:22:02 +0100 Subject: [PATCH 38/54] fix copy/paste behaviour to keep node collapsed if they are --- src/app/services/data/node.service.ts | 5 +++++ src/app/view/editor-main-view/data-views/editor.view.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/services/data/node.service.ts b/src/app/services/data/node.service.ts index f53c3ab7f..0a28331eb 100644 --- a/src/app/services/data/node.service.ts +++ b/src/app/services/data/node.service.ts @@ -109,6 +109,7 @@ export class NodeService implements OnDestroy { node.betriebspunktName, node.fullName, node.labelIds, + node.isCollapsed, ); } else { const existingLabels = existingNode.getLabelIds(); @@ -223,6 +224,7 @@ export class NodeService implements OnDestroy { betriebspunktName?: string, fullName?: string, labelIds?: number[], + isCollapsed?: boolean, enforceUpdate = true, ): Node { const alignedPosition = NodeService.alginNodeToRaster(new Vec2D(positionX, positionY)); @@ -246,6 +248,9 @@ export class NodeService implements OnDestroy { if (labelIds !== undefined) { node.setLabelIds(labelIds); } + if (isCollapsed !== undefined) { + node.setIsCollapsed(isCollapsed); + } this.nodesStore.nodes.push(node); if (enforceUpdate) { this.nodesUpdated(); diff --git a/src/app/view/editor-main-view/data-views/editor.view.ts b/src/app/view/editor-main-view/data-views/editor.view.ts index 867169316..cc17f2719 100644 --- a/src/app/view/editor-main-view/data-views/editor.view.ts +++ b/src/app/view/editor-main-view/data-views/editor.view.ts @@ -458,7 +458,7 @@ export class EditorView implements SVGMouseControllerObserver { const allNodesOfInterest = this.nodeService.getNodes().filter((n: Node) => { this.nodeService.unselectNode(n.getId(), false); - if (this.filterService.filterNode(n)) { + if (this.filterService.filterNode(n) && !n.getIsCollapsed()) { if ( topLeft.getX() < n.getPositionX() && n.getPositionX() + n.getNodeWidth() < bottomRight.getX() From db128b1ae3e45bc8b4bd3a16520cfb1d4376fe9a Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 26 Nov 2025 14:56:53 +0100 Subject: [PATCH 39/54] fix trainrunsection suppression using del key --- src/app/view/editor-main-view/data-views/editor.keyEvents.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts index 5d41d9704..eed5ee203 100644 --- a/src/app/view/editor-main-view/data-views/editor.keyEvents.ts +++ b/src/app/view/editor-main-view/data-views/editor.keyEvents.ts @@ -176,8 +176,8 @@ export class EditorKeyEvents { } return false; } - if (tsvo.trainrunSection.getTrainrun().selected()) { - selectedTrainrunSectionId = tsvo.trainrunSection.getTrainrunId(); + if (tsvo.trainrunSections[0].getTrainrun().selected()) { + selectedTrainrunSectionId = tsvo.trainrunSections[0].getTrainrunId(); } return false; }, From 226791ba8e0f3a554847e279fb929e342ad8ec28 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Wed, 19 Nov 2025 10:57:44 +0100 Subject: [PATCH 40/54] fix: update the tests from trainrunsections.view.spec and data.view.spec accordingly to the isCollapsed's model change --- .../netzgrafik.default.spec.ts | 3 + .../netzgrafik_demo_standalone_github.json | 17416 ++++++++++------ .../data-views/data.view.spec.ts | 4 +- .../data-views/trainrunsections.view.spec.ts | 242 +- 4 files changed, 11701 insertions(+), 5964 deletions(-) diff --git a/src/app/sample-netzgrafik/netzgrafik.default.spec.ts b/src/app/sample-netzgrafik/netzgrafik.default.spec.ts index deca1e7e0..3a32b5e97 100644 --- a/src/app/sample-netzgrafik/netzgrafik.default.spec.ts +++ b/src/app/sample-netzgrafik/netzgrafik.default.spec.ts @@ -83,6 +83,9 @@ describe("NetzgrafikDefault", () => { dataService.loadNetzgrafikDto(inputDto); const outputJson = dataService.getNetzgrafikDto(); + + // The demo file should be up-to-date with numberOfStops: 0 and collapsed nodes + // already in place. No expansion should occur. expect(JSON.stringify(inputDto, null, 2)).toEqual(JSON.stringify(outputJson, null, 2)); }); }); diff --git a/src/app/sample-netzgrafik/netzgrafik_demo_standalone_github.json b/src/app/sample-netzgrafik/netzgrafik_demo_standalone_github.json index 4b384c6b5..a25167a6f 100644 --- a/src/app/sample-netzgrafik/netzgrafik_demo_standalone_github.json +++ b/src/app/sample-netzgrafik/netzgrafik_demo_standalone_github.json @@ -10,7 +10,7 @@ {"id": 1207, "trainrunSectionId": 596, "positionIndex": 0, "positionAlignment": 2}, {"id": 1187, "trainrunSectionId": 586, "positionIndex": 1, "positionAlignment": 2}, {"id": 1382, "trainrunSectionId": 683, "positionIndex": 0, "positionAlignment": 3}, - {"id": 1380, "trainrunSectionId": 682, "positionIndex": 1, "positionAlignment": 3} + {"id": 1380, "trainrunSectionId": 766, "positionIndex": 1, "positionAlignment": 3} ], "transitions": [ {"id": 345, "port1Id": 1187, "port2Id": 1380, "isNonStopTransit": false}, @@ -272,10 +272,10 @@ {"id": 1173, "trainrunSectionId": 579, "positionIndex": 3, "positionAlignment": 2}, {"id": 1217, "trainrunSectionId": 601, "positionIndex": 4, "positionAlignment": 2}, {"id": 1233, "trainrunSectionId": 609, "positionIndex": 5, "positionAlignment": 2}, - {"id": 1157, "trainrunSectionId": 571, "positionIndex": 6, "positionAlignment": 2}, + {"id": 1157, "trainrunSectionId": 750, "positionIndex": 6, "positionAlignment": 2}, {"id": 1276, "trainrunSectionId": 630, "positionIndex": 7, "positionAlignment": 2}, {"id": 1300, "trainrunSectionId": 642, "positionIndex": 8, "positionAlignment": 2}, - {"id": 1191, "trainrunSectionId": 588, "positionIndex": 0, "positionAlignment": 3}, + {"id": 1191, "trainrunSectionId": 753, "positionIndex": 0, "positionAlignment": 3}, {"id": 1172, "trainrunSectionId": 578, "positionIndex": 1, "positionAlignment": 3}, {"id": 1213, "trainrunSectionId": 599, "positionIndex": 2, "positionAlignment": 3}, {"id": 1229, "trainrunSectionId": 607, "positionIndex": 3, "positionAlignment": 3}, @@ -321,7 +321,7 @@ {"id": 1058, "trainrunSectionId": 521, "positionIndex": 0, "positionAlignment": 1}, {"id": 1034, "trainrunSectionId": 509, "positionIndex": 1, "positionAlignment": 1}, {"id": 1070, "trainrunSectionId": 527, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1082, "trainrunSectionId": 533, "positionIndex": 1, "positionAlignment": 2} + {"id": 1082, "trainrunSectionId": 724, "positionIndex": 1, "positionAlignment": 2} ], "transitions": [ {"id": 206, "port1Id": 1035, "port2Id": 1034, "isNonStopTransit": false}, @@ -353,9 +353,9 @@ "positionY": 96, "ports": [ {"id": 1145, "trainrunSectionId": 565, "positionIndex": 0, "positionAlignment": 1}, - {"id": 1212, "trainrunSectionId": 598, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1167, "trainrunSectionId": 576, "positionIndex": 1, "positionAlignment": 2}, - {"id": 1144, "trainrunSectionId": 564, "positionIndex": 2, "positionAlignment": 2}, + {"id": 1167, "trainrunSectionId": 576, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1212, "trainrunSectionId": 598, "positionIndex": 1, "positionAlignment": 2}, + {"id": 1144, "trainrunSectionId": 740, "positionIndex": 2, "positionAlignment": 2}, {"id": 1419, "trainrunSectionId": 702, "positionIndex": 0, "positionAlignment": 3} ], "transitions": [ @@ -411,7 +411,7 @@ "fullName": "Konstanz", "positionX": 4256, "positionY": -416, - "ports": [{"id": 1250, "trainrunSectionId": 617, "positionIndex": 0, "positionAlignment": 1}], + "ports": [{"id": 1250, "trainrunSectionId": 759, "positionIndex": 0, "positionAlignment": 1}], "transitions": [], "connections": [], "resourceId": 163, @@ -436,12 +436,12 @@ "positionX": 4640, "positionY": 1184, "ports": [ - {"id": 1146, "trainrunSectionId": 565, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1146, "trainrunSectionId": 745, "positionIndex": 0, "positionAlignment": 0}, {"id": 1151, "trainrunSectionId": 568, "positionIndex": 0, "positionAlignment": 1}, {"id": 1147, "trainrunSectionId": 566, "positionIndex": 1, "positionAlignment": 1}, {"id": 1155, "trainrunSectionId": 570, "positionIndex": 2, "positionAlignment": 1}, {"id": 1362, "trainrunSectionId": 673, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1364, "trainrunSectionId": 674, "positionIndex": 1, "positionAlignment": 2} + {"id": 1364, "trainrunSectionId": 764, "positionIndex": 1, "positionAlignment": 2} ], "transitions": [ {"id": 249, "port1Id": 1146, "port2Id": 1147, "isNonStopTransit": false}, @@ -895,7 +895,7 @@ {"id": 1171, "trainrunSectionId": 578, "positionIndex": 1, "positionAlignment": 2}, {"id": 1214, "trainrunSectionId": 599, "positionIndex": 2, "positionAlignment": 2}, {"id": 1230, "trainrunSectionId": 607, "positionIndex": 3, "positionAlignment": 2}, - {"id": 1140, "trainrunSectionId": 562, "positionIndex": 4, "positionAlignment": 2}, + {"id": 1140, "trainrunSectionId": 736, "positionIndex": 4, "positionAlignment": 2}, {"id": 1246, "trainrunSectionId": 615, "positionIndex": 5, "positionAlignment": 2}, {"id": 1193, "trainrunSectionId": 589, "positionIndex": 0, "positionAlignment": 3}, {"id": 1170, "trainrunSectionId": 577, "positionIndex": 1, "positionAlignment": 3}, @@ -944,9 +944,9 @@ {"id": 1248, "trainrunSectionId": 616, "positionIndex": 5, "positionAlignment": 2}, {"id": 1227, "trainrunSectionId": 606, "positionIndex": 0, "positionAlignment": 3}, {"id": 1243, "trainrunSectionId": 614, "positionIndex": 1, "positionAlignment": 3}, - {"id": 1211, "trainrunSectionId": 598, "positionIndex": 2, "positionAlignment": 3}, - {"id": 1168, "trainrunSectionId": 576, "positionIndex": 3, "positionAlignment": 3}, - {"id": 1143, "trainrunSectionId": 564, "positionIndex": 4, "positionAlignment": 3} + {"id": 1211, "trainrunSectionId": 757, "positionIndex": 2, "positionAlignment": 3}, + {"id": 1143, "trainrunSectionId": 564, "positionIndex": 3, "positionAlignment": 3}, + {"id": 1168, "trainrunSectionId": 576, "positionIndex": 4, "positionAlignment": 3} ], "transitions": [ {"id": 247, "port1Id": 1142, "port2Id": 1143, "isNonStopTransit": false}, @@ -979,9 +979,9 @@ "positionX": 4640, "positionY": 1888, "ports": [ - {"id": 1152, "trainrunSectionId": 568, "positionIndex": 0, "positionAlignment": 0}, - {"id": 1148, "trainrunSectionId": 566, "positionIndex": 1, "positionAlignment": 0}, - {"id": 1156, "trainrunSectionId": 570, "positionIndex": 2, "positionAlignment": 0} + {"id": 1152, "trainrunSectionId": 748, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1148, "trainrunSectionId": 747, "positionIndex": 1, "positionAlignment": 0}, + {"id": 1156, "trainrunSectionId": 749, "positionIndex": 2, "positionAlignment": 0} ], "transitions": [], "connections": [], @@ -1049,8 +1049,8 @@ {"id": 1091, "trainrunSectionId": 538, "positionIndex": 1, "positionAlignment": 0}, {"id": 1064, "trainrunSectionId": 524, "positionIndex": 0, "positionAlignment": 1}, {"id": 1038, "trainrunSectionId": 511, "positionIndex": 1, "positionAlignment": 1}, - {"id": 1078, "trainrunSectionId": 531, "positionIndex": 2, "positionAlignment": 1}, - {"id": 1090, "trainrunSectionId": 537, "positionIndex": 3, "positionAlignment": 1}, + {"id": 1078, "trainrunSectionId": 721, "positionIndex": 2, "positionAlignment": 1}, + {"id": 1090, "trainrunSectionId": 734, "positionIndex": 3, "positionAlignment": 1}, {"id": 1039, "trainrunSectionId": 512, "positionIndex": 0, "positionAlignment": 2}, {"id": 1079, "trainrunSectionId": 532, "positionIndex": 1, "positionAlignment": 2} ], @@ -1089,8 +1089,8 @@ {"id": 1089, "trainrunSectionId": 537, "positionIndex": 3, "positionAlignment": 0}, {"id": 1062, "trainrunSectionId": 523, "positionIndex": 0, "positionAlignment": 1}, {"id": 1055, "trainrunSectionId": 520, "positionIndex": 1, "positionAlignment": 1}, - {"id": 1076, "trainrunSectionId": 530, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1088, "trainrunSectionId": 536, "positionIndex": 1, "positionAlignment": 2} + {"id": 1076, "trainrunSectionId": 718, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1088, "trainrunSectionId": 731, "positionIndex": 1, "positionAlignment": 2} ], "transitions": [ {"id": 214, "port1Id": 1037, "port2Id": 1055, "isNonStopTransit": true}, @@ -1182,7 +1182,7 @@ {"id": 1060, "trainrunSectionId": 522, "positionIndex": 0, "positionAlignment": 1}, {"id": 1036, "trainrunSectionId": 510, "positionIndex": 1, "positionAlignment": 1}, {"id": 1072, "trainrunSectionId": 528, "positionIndex": 2, "positionAlignment": 1}, - {"id": 1084, "trainrunSectionId": 534, "positionIndex": 3, "positionAlignment": 1} + {"id": 1084, "trainrunSectionId": 725, "positionIndex": 3, "positionAlignment": 1} ], "transitions": [ {"id": 215, "port1Id": 1056, "port2Id": 1036, "isNonStopTransit": true}, @@ -1213,8 +1213,8 @@ "positionX": 2272, "positionY": 2240, "ports": [ - {"id": 1074, "trainrunSectionId": 529, "positionIndex": 0, "positionAlignment": 1}, - {"id": 1086, "trainrunSectionId": 535, "positionIndex": 1, "positionAlignment": 1}, + {"id": 1074, "trainrunSectionId": 717, "positionIndex": 0, "positionAlignment": 1}, + {"id": 1086, "trainrunSectionId": 730, "positionIndex": 1, "positionAlignment": 1}, {"id": 1075, "trainrunSectionId": 530, "positionIndex": 0, "positionAlignment": 3}, {"id": 1087, "trainrunSectionId": 536, "positionIndex": 1, "positionAlignment": 3} ], @@ -1250,7 +1250,7 @@ {"id": 1189, "trainrunSectionId": 587, "positionIndex": 2, "positionAlignment": 2}, {"id": 1424, "trainrunSectionId": 704, "positionIndex": 0, "positionAlignment": 3}, {"id": 1426, "trainrunSectionId": 705, "positionIndex": 1, "positionAlignment": 3}, - {"id": 1422, "trainrunSectionId": 703, "positionIndex": 2, "positionAlignment": 3} + {"id": 1422, "trainrunSectionId": 768, "positionIndex": 2, "positionAlignment": 3} ], "transitions": [ {"id": 369, "port1Id": 1189, "port2Id": 1422, "isNonStopTransit": false}, @@ -1592,9 +1592,9 @@ {"id": 1068, "trainrunSectionId": 526, "positionIndex": 0, "positionAlignment": 1}, {"id": 1094, "trainrunSectionId": 539, "positionIndex": 1, "positionAlignment": 1}, {"id": 1102, "trainrunSectionId": 543, "positionIndex": 2, "positionAlignment": 1}, - {"id": 1098, "trainrunSectionId": 541, "positionIndex": 3, "positionAlignment": 1}, - {"id": 1361, "trainrunSectionId": 673, "positionIndex": 0, "positionAlignment": 3}, - {"id": 1363, "trainrunSectionId": 674, "positionIndex": 1, "positionAlignment": 3} + {"id": 1098, "trainrunSectionId": 735, "positionIndex": 3, "positionAlignment": 1}, + {"id": 1363, "trainrunSectionId": 674, "positionIndex": 0, "positionAlignment": 3}, + {"id": 1361, "trainrunSectionId": 673, "positionIndex": 1, "positionAlignment": 3} ], "transitions": [ {"id": 328, "port1Id": 1353, "port2Id": 1098, "isNonStopTransit": false}, @@ -1627,8 +1627,8 @@ "positionX": -2560, "positionY": 288, "ports": [ - {"id": 1381, "trainrunSectionId": 683, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1379, "trainrunSectionId": 682, "positionIndex": 1, "positionAlignment": 2}, + {"id": 1379, "trainrunSectionId": 682, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1381, "trainrunSectionId": 683, "positionIndex": 1, "positionAlignment": 2}, {"id": 1206, "trainrunSectionId": 595, "positionIndex": 0, "positionAlignment": 3}, {"id": 1110, "trainrunSectionId": 547, "positionIndex": 1, "positionAlignment": 3} ], @@ -1733,7 +1733,7 @@ "positionX": -992, "positionY": 352, "ports": [ - {"id": 1399, "trainrunSectionId": 692, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1399, "trainrunSectionId": 767, "positionIndex": 0, "positionAlignment": 2}, {"id": 1386, "trainrunSectionId": 685, "positionIndex": 0, "positionAlignment": 3} ], "transitions": [{"id": 355, "port1Id": 1399, "port2Id": 1386, "isNonStopTransit": false}], @@ -1811,10 +1811,10 @@ "positionX": -3520, "positionY": 544, "ports": [ - {"id": 1423, "trainrunSectionId": 704, "positionIndex": 0, "positionAlignment": 2}, - {"id": 1425, "trainrunSectionId": 705, "positionIndex": 1, "positionAlignment": 2}, - {"id": 1421, "trainrunSectionId": 703, "positionIndex": 2, "positionAlignment": 2}, - {"id": 1184, "trainrunSectionId": 584, "positionIndex": 0, "positionAlignment": 3}, + {"id": 1421, "trainrunSectionId": 703, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1423, "trainrunSectionId": 704, "positionIndex": 1, "positionAlignment": 2}, + {"id": 1425, "trainrunSectionId": 705, "positionIndex": 2, "positionAlignment": 2}, + {"id": 1184, "trainrunSectionId": 752, "positionIndex": 0, "positionAlignment": 3}, {"id": 1208, "trainrunSectionId": 596, "positionIndex": 1, "positionAlignment": 3}, {"id": 1188, "trainrunSectionId": 586, "positionIndex": 2, "positionAlignment": 3} ], @@ -1885,335 +1885,5535 @@ "symmetryAxis": null, "warnings": null, "labelIds": [] + }, + { + "id": 179, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2432, + "positionY": 2464, + "ports": [ + {"id": 1442, "trainrunSectionId": 713, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1441, "trainrunSectionId": 529, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 387, "port1Id": 1441, "port2Id": 1442, "isNonStopTransit": false}], + "connections": [], + "resourceId": 203, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 180, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2352, + "positionY": 2352, + "ports": [ + {"id": 1444, "trainrunSectionId": 714, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1443, "trainrunSectionId": 713, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 388, "port1Id": 1443, "port2Id": 1444, "isNonStopTransit": false}], + "connections": [], + "resourceId": 204, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 181, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2312, + "positionY": 2296, + "ports": [ + {"id": 1446, "trainrunSectionId": 715, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1445, "trainrunSectionId": 714, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 389, "port1Id": 1445, "port2Id": 1446, "isNonStopTransit": false}], + "connections": [], + "resourceId": 205, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 182, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2292, + "positionY": 2268, + "ports": [ + {"id": 1448, "trainrunSectionId": 716, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1447, "trainrunSectionId": 715, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 390, "port1Id": 1447, "port2Id": 1448, "isNonStopTransit": false}], + "connections": [], + "resourceId": 206, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 183, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2282, + "positionY": 2254, + "ports": [ + {"id": 1450, "trainrunSectionId": 717, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1449, "trainrunSectionId": 716, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 391, "port1Id": 1449, "port2Id": 1450, "isNonStopTransit": false}], + "connections": [], + "resourceId": 207, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 184, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2464, + "positionY": 2208, + "ports": [ + {"id": 1451, "trainrunSectionId": 530, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1452, "trainrunSectionId": 718, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 392, "port1Id": 1451, "port2Id": 1452, "isNonStopTransit": false}], + "connections": [], + "resourceId": 208, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 185, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1984, + "ports": [ + {"id": 1454, "trainrunSectionId": 719, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1453, "trainrunSectionId": 531, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 393, "port1Id": 1453, "port2Id": 1454, "isNonStopTransit": false}], + "connections": [], + "resourceId": 209, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 186, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1888, + "ports": [ + {"id": 1456, "trainrunSectionId": 720, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1455, "trainrunSectionId": 719, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 394, "port1Id": 1455, "port2Id": 1456, "isNonStopTransit": false}], + "connections": [], + "resourceId": 210, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 187, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1840, + "ports": [ + {"id": 1458, "trainrunSectionId": 721, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1457, "trainrunSectionId": 720, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 395, "port1Id": 1457, "port2Id": 1458, "isNonStopTransit": false}], + "connections": [], + "resourceId": 211, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 188, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2400, + "positionY": 3232, + "ports": [ + {"id": 1459, "trainrunSectionId": 533, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1460, "trainrunSectionId": 722, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 396, "port1Id": 1459, "port2Id": 1460, "isNonStopTransit": false}], + "connections": [], + "resourceId": 212, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 189, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2496, + "positionY": 3232, + "ports": [ + {"id": 1461, "trainrunSectionId": 722, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1462, "trainrunSectionId": 723, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 397, "port1Id": 1461, "port2Id": 1462, "isNonStopTransit": false}], + "connections": [], + "resourceId": 213, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 190, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2544, + "positionY": 3232, + "ports": [ + {"id": 1463, "trainrunSectionId": 723, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1464, "trainrunSectionId": 724, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 398, "port1Id": 1463, "port2Id": 1464, "isNonStopTransit": false}], + "connections": [], + "resourceId": 214, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 191, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2592, + "positionY": 2960, + "ports": [ + {"id": 1466, "trainrunSectionId": 725, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1465, "trainrunSectionId": 534, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 399, "port1Id": 1465, "port2Id": 1466, "isNonStopTransit": false}], + "connections": [], + "resourceId": 215, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 192, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2432, + "positionY": 2464, + "ports": [ + {"id": 1468, "trainrunSectionId": 726, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1467, "trainrunSectionId": 535, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 400, "port1Id": 1467, "port2Id": 1468, "isNonStopTransit": false}], + "connections": [], + "resourceId": 216, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 193, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2352, + "positionY": 2352, + "ports": [ + {"id": 1470, "trainrunSectionId": 727, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1469, "trainrunSectionId": 726, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 401, "port1Id": 1469, "port2Id": 1470, "isNonStopTransit": false}], + "connections": [], + "resourceId": 217, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 194, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2312, + "positionY": 2296, + "ports": [ + {"id": 1472, "trainrunSectionId": 728, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1471, "trainrunSectionId": 727, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 402, "port1Id": 1471, "port2Id": 1472, "isNonStopTransit": false}], + "connections": [], + "resourceId": 218, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 195, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2292, + "positionY": 2268, + "ports": [ + {"id": 1474, "trainrunSectionId": 729, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1473, "trainrunSectionId": 728, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 403, "port1Id": 1473, "port2Id": 1474, "isNonStopTransit": false}], + "connections": [], + "resourceId": 219, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 196, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2282, + "positionY": 2254, + "ports": [ + {"id": 1476, "trainrunSectionId": 730, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1475, "trainrunSectionId": 729, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 404, "port1Id": 1475, "port2Id": 1476, "isNonStopTransit": false}], + "connections": [], + "resourceId": 220, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 197, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2464, + "positionY": 2208, + "ports": [ + {"id": 1477, "trainrunSectionId": 536, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1478, "trainrunSectionId": 731, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 405, "port1Id": 1477, "port2Id": 1478, "isNonStopTransit": false}], + "connections": [], + "resourceId": 221, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 198, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1984, + "ports": [ + {"id": 1480, "trainrunSectionId": 732, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1479, "trainrunSectionId": 537, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 406, "port1Id": 1479, "port2Id": 1480, "isNonStopTransit": false}], + "connections": [], + "resourceId": 222, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 199, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1888, + "ports": [ + {"id": 1482, "trainrunSectionId": 733, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1481, "trainrunSectionId": 732, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 407, "port1Id": 1481, "port2Id": 1482, "isNonStopTransit": false}], + "connections": [], + "resourceId": 223, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 200, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1840, + "ports": [ + {"id": 1484, "trainrunSectionId": 734, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1483, "trainrunSectionId": 733, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 408, "port1Id": 1483, "port2Id": 1484, "isNonStopTransit": false}], + "connections": [], + "resourceId": 224, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 201, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2656, + "positionY": 1024, + "ports": [ + {"id": 1486, "trainrunSectionId": 735, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1485, "trainrunSectionId": 541, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 409, "port1Id": 1485, "port2Id": 1486, "isNonStopTransit": false}], + "connections": [], + "resourceId": 225, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 202, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2976, + "positionY": 32, + "ports": [ + {"id": 1487, "trainrunSectionId": 562, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1488, "trainrunSectionId": 736, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 410, "port1Id": 1487, "port2Id": 1488, "isNonStopTransit": false}], + "connections": [], + "resourceId": 226, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 203, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4256, + "positionY": 64, + "ports": [ + {"id": 1489, "trainrunSectionId": 564, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1490, "trainrunSectionId": 737, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 411, "port1Id": 1489, "port2Id": 1490, "isNonStopTransit": false}], + "connections": [], + "resourceId": 227, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 204, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4448, + "positionY": 80, + "ports": [ + {"id": 1491, "trainrunSectionId": 737, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1492, "trainrunSectionId": 738, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 412, "port1Id": 1491, "port2Id": 1492, "isNonStopTransit": false}], + "connections": [], + "resourceId": 228, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 205, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4544, + "positionY": 88, + "ports": [ + {"id": 1493, "trainrunSectionId": 738, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1494, "trainrunSectionId": 739, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 413, "port1Id": 1493, "port2Id": 1494, "isNonStopTransit": false}], + "connections": [], + "resourceId": 229, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 206, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4592, + "positionY": 92, + "ports": [ + {"id": 1495, "trainrunSectionId": 739, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1496, "trainrunSectionId": 740, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 414, "port1Id": 1495, "port2Id": 1496, "isNonStopTransit": false}], + "connections": [], + "resourceId": 230, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 207, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 640, + "ports": [ + {"id": 1497, "trainrunSectionId": 565, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1498, "trainrunSectionId": 741, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 415, "port1Id": 1497, "port2Id": 1498, "isNonStopTransit": false}], + "connections": [], + "resourceId": 231, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 208, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 912, + "ports": [ + {"id": 1499, "trainrunSectionId": 741, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1500, "trainrunSectionId": 742, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 416, "port1Id": 1499, "port2Id": 1500, "isNonStopTransit": false}], + "connections": [], + "resourceId": 232, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 209, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1048, + "ports": [ + {"id": 1501, "trainrunSectionId": 742, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1502, "trainrunSectionId": 743, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 417, "port1Id": 1501, "port2Id": 1502, "isNonStopTransit": false}], + "connections": [], + "resourceId": 233, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 210, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1116, + "ports": [ + {"id": 1503, "trainrunSectionId": 743, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1504, "trainrunSectionId": 744, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 418, "port1Id": 1503, "port2Id": 1504, "isNonStopTransit": false}], + "connections": [], + "resourceId": 234, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 211, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1150, + "ports": [ + {"id": 1505, "trainrunSectionId": 744, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1506, "trainrunSectionId": 745, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 419, "port1Id": 1505, "port2Id": 1506, "isNonStopTransit": false}], + "connections": [], + "resourceId": 235, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 212, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1536, + "ports": [ + {"id": 1507, "trainrunSectionId": 566, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1508, "trainrunSectionId": 746, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 420, "port1Id": 1507, "port2Id": 1508, "isNonStopTransit": false}], + "connections": [], + "resourceId": 236, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 213, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1712, + "ports": [ + {"id": 1509, "trainrunSectionId": 746, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1510, "trainrunSectionId": 747, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 421, "port1Id": 1509, "port2Id": 1510, "isNonStopTransit": false}], + "connections": [], + "resourceId": 237, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 214, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1536, + "ports": [ + {"id": 1511, "trainrunSectionId": 568, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1512, "trainrunSectionId": 748, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 422, "port1Id": 1511, "port2Id": 1512, "isNonStopTransit": false}], + "connections": [], + "resourceId": 238, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 215, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4640, + "positionY": 1536, + "ports": [ + {"id": 1513, "trainrunSectionId": 570, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1514, "trainrunSectionId": 749, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 423, "port1Id": 1513, "port2Id": 1514, "isNonStopTransit": false}], + "connections": [], + "resourceId": 239, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 216, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2448, + "positionY": 32, + "ports": [ + {"id": 1515, "trainrunSectionId": 571, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1516, "trainrunSectionId": 750, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 424, "port1Id": 1515, "port2Id": 1516, "isNonStopTransit": false}], + "connections": [], + "resourceId": 240, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 217, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -3024, + "positionY": 256, + "ports": [ + {"id": 1518, "trainrunSectionId": 751, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1517, "trainrunSectionId": 584, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 425, "port1Id": 1517, "port2Id": 1518, "isNonStopTransit": false}], + "connections": [], + "resourceId": 241, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 218, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -3272, + "positionY": 400, + "ports": [ + {"id": 1520, "trainrunSectionId": 752, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1519, "trainrunSectionId": 751, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 426, "port1Id": 1519, "port2Id": 1520, "isNonStopTransit": false}], + "connections": [], + "resourceId": 242, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 219, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 2976, + "positionY": 32, + "ports": [ + {"id": 1522, "trainrunSectionId": 753, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1521, "trainrunSectionId": 588, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 427, "port1Id": 1521, "port2Id": 1522, "isNonStopTransit": false}], + "connections": [], + "resourceId": 243, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 220, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4256, + "positionY": 64, + "ports": [ + {"id": 1524, "trainrunSectionId": 754, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1523, "trainrunSectionId": 598, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 428, "port1Id": 1523, "port2Id": 1524, "isNonStopTransit": false}], + "connections": [], + "resourceId": 244, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 221, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4064, + "positionY": 48, + "ports": [ + {"id": 1526, "trainrunSectionId": 755, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1525, "trainrunSectionId": 754, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 429, "port1Id": 1525, "port2Id": 1526, "isNonStopTransit": false}], + "connections": [], + "resourceId": 245, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 222, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 3968, + "positionY": 40, + "ports": [ + {"id": 1528, "trainrunSectionId": 756, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1527, "trainrunSectionId": 755, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 430, "port1Id": 1527, "port2Id": 1528, "isNonStopTransit": false}], + "connections": [], + "resourceId": 246, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 223, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 3920, + "positionY": 36, + "ports": [ + {"id": 1530, "trainrunSectionId": 757, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1529, "trainrunSectionId": 756, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 431, "port1Id": 1529, "port2Id": 1530, "isNonStopTransit": false}], + "connections": [], + "resourceId": 247, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 224, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4064, + "positionY": -192, + "ports": [ + {"id": 1532, "trainrunSectionId": 758, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1531, "trainrunSectionId": 617, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 432, "port1Id": 1531, "port2Id": 1532, "isNonStopTransit": false}], + "connections": [], + "resourceId": 248, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 225, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4160, + "positionY": -304, + "ports": [ + {"id": 1534, "trainrunSectionId": 759, "positionIndex": 0, "positionAlignment": 0}, + {"id": 1533, "trainrunSectionId": 758, "positionIndex": 0, "positionAlignment": 1} + ], + "transitions": [{"id": 433, "port1Id": 1533, "port2Id": 1534, "isNonStopTransit": false}], + "connections": [], + "resourceId": 249, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 226, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 3648, + "positionY": 960, + "ports": [ + {"id": 1535, "trainrunSectionId": 674, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1536, "trainrunSectionId": 760, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 434, "port1Id": 1535, "port2Id": 1536, "isNonStopTransit": false}], + "connections": [], + "resourceId": 250, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 227, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4144, + "positionY": 1072, + "ports": [ + {"id": 1537, "trainrunSectionId": 760, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1538, "trainrunSectionId": 761, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 435, "port1Id": 1537, "port2Id": 1538, "isNonStopTransit": false}], + "connections": [], + "resourceId": 251, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 228, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4392, + "positionY": 1128, + "ports": [ + {"id": 1539, "trainrunSectionId": 761, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1540, "trainrunSectionId": 762, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 436, "port1Id": 1539, "port2Id": 1540, "isNonStopTransit": false}], + "connections": [], + "resourceId": 252, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 229, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4516, + "positionY": 1156, + "ports": [ + {"id": 1541, "trainrunSectionId": 762, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1542, "trainrunSectionId": 763, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 437, "port1Id": 1541, "port2Id": 1542, "isNonStopTransit": false}], + "connections": [], + "resourceId": 253, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 230, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": 4578, + "positionY": 1170, + "ports": [ + {"id": 1543, "trainrunSectionId": 763, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1544, "trainrunSectionId": 764, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 438, "port1Id": 1543, "port2Id": 1544, "isNonStopTransit": false}], + "connections": [], + "resourceId": 254, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 231, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -2816, + "positionY": 416, + "ports": [ + {"id": 1546, "trainrunSectionId": 765, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1545, "trainrunSectionId": 682, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 439, "port1Id": 1545, "port2Id": 1546, "isNonStopTransit": false}], + "connections": [], + "resourceId": 255, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 232, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -2944, + "positionY": 480, + "ports": [ + {"id": 1548, "trainrunSectionId": 766, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1547, "trainrunSectionId": 765, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 440, "port1Id": 1547, "port2Id": 1548, "isNonStopTransit": false}], + "connections": [], + "resourceId": 256, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 233, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -1168, + "positionY": 352, + "ports": [ + {"id": 1549, "trainrunSectionId": 692, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1550, "trainrunSectionId": 767, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 441, "port1Id": 1549, "port2Id": 1550, "isNonStopTransit": false}], + "connections": [], + "resourceId": 257, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true + }, + { + "id": 234, + "betriebspunktName": "NEW", + "fullName": "Nouveau noeud", + "positionX": -3728, + "positionY": 576, + "ports": [ + {"id": 1552, "trainrunSectionId": 768, "positionIndex": 0, "positionAlignment": 2}, + {"id": 1551, "trainrunSectionId": 703, "positionIndex": 0, "positionAlignment": 3} + ], + "transitions": [{"id": 442, "port1Id": 1551, "port2Id": 1552, "isNonStopTransit": false}], + "connections": [], + "resourceId": 258, + "perronkanten": 5, + "connectionTime": 3, + "trainrunCategoryHaltezeiten": { + "HaltezeitIPV": {"haltezeit": 3, "no_halt": false}, + "HaltezeitA": {"haltezeit": 2, "no_halt": false}, + "HaltezeitB": {"haltezeit": 2, "no_halt": false}, + "HaltezeitC": {"haltezeit": 1, "no_halt": false}, + "HaltezeitD": {"haltezeit": 1, "no_halt": false}, + "HaltezeitUncategorized": {"haltezeit": 0, "no_halt": true} + }, + "symmetryAxis": null, + "warnings": null, + "labelIds": [], + "isCollapsed": true } ], "trainrunSections": [ { - "id": 509, - "sourceNodeId": 156, - "sourcePortId": 1033, - "targetNodeId": 136, - "targetPortId": 1034, + "id": 509, + "sourceNodeId": 156, + "sourcePortId": 1033, + "targetNodeId": 136, + "targetPortId": 1034, + "travelTime": { + "lock": true, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 2, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 182 + }, + "sourceArrival": { + "lock": false, + "time": 58, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 178 + }, + "targetDeparture": { + "lock": false, + "time": 44, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 164 + }, + "targetArrival": { + "lock": false, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 196 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2640, "y": 3710}, + {"x": 2640, "y": 3646}, + {"x": 2640, "y": 3390}, + {"x": 2640, "y": 3326} + ], + "textPositions": { + "0": {"x": 2652, "y": 3692}, + "1": {"x": 2628, "y": 3664}, + "2": {"x": 2628, "y": 3344}, + "3": {"x": 2652, "y": 3372}, + "4": {"x": 2628, "y": 3518}, + "5": {"x": 2628, "y": 3518}, + "6": {"x": 2652, "y": 3518} + } + }, + "warnings": null + }, + { + "id": 510, + "sourceNodeId": 136, + "sourcePortId": 1035, + "targetNodeId": 158, + "targetPortId": 1036, + "travelTime": { + "lock": true, + "time": 6, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 198 + }, + "sourceArrival": { + "lock": true, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 162 + }, + "targetDeparture": { + "lock": false, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 156 + }, + "targetArrival": { + "lock": false, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 204 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2640, "y": 3230}, + {"x": 2640, "y": 3166}, + {"x": 2640, "y": 2818}, + {"x": 2640, "y": 2754} + ], + "textPositions": { + "0": {"x": 2652, "y": 3212}, + "1": {"x": 2628, "y": 3184}, + "2": {"x": 2628, "y": 2772}, + "3": {"x": 2652, "y": 2800}, + "4": {"x": 2628, "y": 2992}, + "5": {"x": 2628, "y": 2992}, + "6": {"x": 2652, "y": 2992} + } + }, + "warnings": null + }, + { + "id": 511, + "sourceNodeId": 155, + "sourcePortId": 1037, + "targetNodeId": 154, + "targetPortId": 1038, + "travelTime": { + "lock": true, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 232 + }, + "sourceArrival": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 128 + }, + "targetDeparture": { + "lock": true, + "time": 49, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 109 + }, + "targetArrival": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 251 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2704, "y": 2174}, + {"x": 2704, "y": 2110}, + {"x": 2704, "y": 1950}, + {"x": 2704, "y": 1886} + ], + "textPositions": { + "0": {"x": 2716, "y": 2156}, + "1": {"x": 2692, "y": 2128}, + "2": {"x": 2692, "y": 1904}, + "3": {"x": 2716, "y": 1932}, + "4": {"x": 2692, "y": 2030}, + "5": {"x": 2692, "y": 2030}, + "6": {"x": 2716, "y": 2030} + } + }, + "warnings": null + }, + { + "id": 512, + "sourceNodeId": 154, + "sourcePortId": 1039, + "targetNodeId": 169, + "targetPortId": 1040, + "travelTime": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 255 + }, + "sourceArrival": { + "lock": true, + "time": 45, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 105 + }, + "targetDeparture": { + "lock": false, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 87 + }, + "targetArrival": { + "lock": false, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 273 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2654, "y": 1808}, + {"x": 2590, "y": 1808}, + {"x": 2018, "y": 1808}, + {"x": 1954, "y": 1808} + ], + "textPositions": { + "0": {"x": 2636, "y": 1796}, + "1": {"x": 2608, "y": 1820}, + "2": {"x": 1972, "y": 1820}, + "3": {"x": 2000, "y": 1796}, + "4": {"x": 2304, "y": 1796}, + "5": {"x": 2304, "y": 1796}, + "6": {"x": 2304, "y": 1820} + } + }, + "warnings": null + }, + { + "id": 513, + "sourceNodeId": 142, + "sourcePortId": 1041, + "targetNodeId": 141, + "targetPortId": 1042, + "travelTime": { + "lock": true, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 55, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 295 + }, + "sourceArrival": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 65 + }, + "targetDeparture": { + "lock": false, + "time": 46, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 46 + }, + "targetArrival": { + "lock": false, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 314 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": 1726}, + {"x": 80, "y": 1662}, + {"x": 80, "y": 1314}, + {"x": 80, "y": 1250} + ], + "textPositions": { + "0": {"x": 92, "y": 1708}, + "1": {"x": 68, "y": 1680}, + "2": {"x": 68, "y": 1268}, + "3": {"x": 92, "y": 1296}, + "4": {"x": 68, "y": 1488}, + "5": {"x": 68, "y": 1488}, + "6": {"x": 92, "y": 1488} + } + }, + "warnings": null + }, + { + "id": 514, + "sourceNodeId": 141, + "sourcePortId": 1043, + "targetNodeId": 143, + "targetPortId": 1044, + "travelTime": { + "lock": true, + "time": 9, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 314 + }, + "sourceArrival": { + "lock": false, + "time": 46, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 46 + }, + "targetDeparture": { + "lock": false, + "time": 37, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 37 + }, + "targetArrival": { + "lock": false, + "time": 23, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 323 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": 1182}, + {"x": 80, "y": 1118}, + {"x": 80, "y": 866}, + {"x": 80, "y": 802} + ], + "textPositions": { + "0": {"x": 92, "y": 1164}, + "1": {"x": 68, "y": 1136}, + "2": {"x": 68, "y": 820}, + "3": {"x": 92, "y": 848}, + "4": {"x": 68, "y": 992}, + "5": {"x": 68, "y": 992}, + "6": {"x": 92, "y": 992} + } + }, + "warnings": null + }, + { + "id": 515, + "sourceNodeId": 143, + "sourcePortId": 1045, + "targetNodeId": 133, + "targetPortId": 1046, + "travelTime": { + "lock": true, + "time": 7, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 23, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 323 + }, + "sourceArrival": { + "lock": false, + "time": 37, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 37 + }, + "targetDeparture": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 30 + }, + "targetArrival": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 330 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": 734}, + {"x": 80, "y": 670}, + {"x": 80, "y": 414}, + {"x": 80, "y": 350} + ], + "textPositions": { + "0": {"x": 92, "y": 716}, + "1": {"x": 68, "y": 688}, + "2": {"x": 68, "y": 368}, + "3": {"x": 92, "y": 396}, + "4": {"x": 68, "y": 542}, + "5": {"x": 68, "y": 542}, + "6": {"x": 92, "y": 542} + } + }, + "warnings": null + }, + { + "id": 516, + "sourceNodeId": 133, + "sourcePortId": 1047, + "targetNodeId": 144, + "targetPortId": 1048, + "travelTime": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 32, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 332 + }, + "sourceArrival": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 28 + }, + "targetDeparture": { + "lock": false, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "targetArrival": { + "lock": false, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 342 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": 94}, + {"x": 80, "y": 30}, + {"x": 80, "y": -290}, + {"x": 80, "y": -354} + ], + "textPositions": { + "0": {"x": 92, "y": 76}, + "1": {"x": 68, "y": 48}, + "2": {"x": 68, "y": -336}, + "3": {"x": 92, "y": -308}, + "4": {"x": 68, "y": -130}, + "5": {"x": 68, "y": -130}, + "6": {"x": 92, "y": -130} + } + }, + "warnings": null + }, + { + "id": 517, + "sourceNodeId": 144, + "sourcePortId": 1049, + "targetNodeId": 145, + "targetPortId": 1050, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 342 + }, + "sourceArrival": { + "lock": false, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "targetDeparture": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetArrival": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 347 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": -450}, + {"x": 80, "y": -514}, + {"x": 80, "y": -798}, + {"x": 80, "y": -862} + ], + "textPositions": { + "0": {"x": 92, "y": -468}, + "1": {"x": 68, "y": -496}, + "2": {"x": 68, "y": -844}, + "3": {"x": 92, "y": -816}, + "4": {"x": 68, "y": -656}, + "5": {"x": 68, "y": -656}, + "6": {"x": 92, "y": -656} + } + }, + "warnings": null + }, + { + "id": 518, + "sourceNodeId": 145, + "sourcePortId": 1051, + "targetNodeId": 146, + "targetPortId": 1052, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 347 + }, + "sourceArrival": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetDeparture": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 8 + }, + "targetArrival": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 352 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": -930}, + {"x": 80, "y": -994}, + {"x": 80, "y": -1278}, + {"x": 80, "y": -1342} + ], + "textPositions": { + "0": {"x": 92, "y": -948}, + "1": {"x": 68, "y": -976}, + "2": {"x": 68, "y": -1324}, + "3": {"x": 92, "y": -1296}, + "4": {"x": 68, "y": -1136}, + "5": {"x": 68, "y": -1136}, + "6": {"x": 92, "y": -1136} + } + }, + "warnings": null + }, + { + "id": 519, + "sourceNodeId": 146, + "sourcePortId": 1053, + "targetNodeId": 134, + "targetPortId": 1054, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 352 + }, + "sourceArrival": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 8 + }, + "targetDeparture": { + "lock": true, + "time": 3, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 3 + }, + "targetArrival": { + "lock": true, + "time": 57, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 357 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 80, "y": -1410}, + {"x": 80, "y": -1474}, + {"x": 80, "y": -1758}, + {"x": 80, "y": -1822} + ], + "textPositions": { + "0": {"x": 92, "y": -1428}, + "1": {"x": 68, "y": -1456}, + "2": {"x": 68, "y": -1804}, + "3": {"x": 92, "y": -1776}, + "4": {"x": 68, "y": -1616}, + "5": {"x": 68, "y": -1616}, + "6": {"x": 92, "y": -1616} + } + }, + "warnings": null + }, + { + "id": 520, + "sourceNodeId": 158, + "sourcePortId": 1056, + "targetNodeId": 155, + "targetPortId": 1055, + "travelTime": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 204 + }, + "sourceArrival": { + "lock": false, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 156 + }, + "targetDeparture": { + "lock": true, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 128 + }, + "targetArrival": { + "lock": true, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 232 + }, + "numberOfStops": 0, + "trainrunId": 75, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2704, "y": 2686}, + {"x": 2704, "y": 2622}, + {"x": 2704, "y": 2334}, + {"x": 2704, "y": 2270} + ], + "textPositions": { + "0": {"x": 2716, "y": 2668}, + "1": {"x": 2692, "y": 2640}, + "2": {"x": 2692, "y": 2288}, + "3": {"x": 2716, "y": 2316}, + "4": {"x": 2692, "y": 2478}, + "5": {"x": 2692, "y": 2478}, + "6": {"x": 2716, "y": 2478} + } + }, + "warnings": null + }, + { + "id": 521, + "sourceNodeId": 156, + "sourcePortId": 1057, + "targetNodeId": 136, + "targetPortId": 1058, + "travelTime": { + "lock": true, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 2, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 2 + }, + "sourceArrival": { + "lock": true, + "time": 58, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 118 + }, + "targetDeparture": { + "lock": false, + "time": 44, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 104 + }, + "targetArrival": { + "lock": false, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 16 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2608, "y": 3710}, + {"x": 2608, "y": 3646}, + {"x": 2608, "y": 3390}, + {"x": 2608, "y": 3326} + ], + "textPositions": { + "0": {"x": 2620, "y": 3692}, + "1": {"x": 2596, "y": 3664}, + "2": {"x": 2596, "y": 3344}, + "3": {"x": 2620, "y": 3372}, + "4": {"x": 2596, "y": 3518}, + "5": {"x": 2596, "y": 3518}, + "6": {"x": 2620, "y": 3518} + } + }, + "warnings": null + }, + { + "id": 522, + "sourceNodeId": 136, + "sourcePortId": 1059, + "targetNodeId": 158, + "targetPortId": 1060, + "travelTime": { + "lock": true, + "time": 6, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "sourceArrival": { + "lock": true, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 102 + }, + "targetDeparture": { + "lock": false, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 96 + }, + "targetArrival": { + "lock": false, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 24 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2608, "y": 3230}, + {"x": 2608, "y": 3166}, + {"x": 2608, "y": 2818}, + {"x": 2608, "y": 2754} + ], + "textPositions": { + "0": {"x": 2620, "y": 3212}, + "1": {"x": 2596, "y": 3184}, + "2": {"x": 2596, "y": 2772}, + "3": {"x": 2620, "y": 2800}, + "4": {"x": 2596, "y": 2992}, + "5": {"x": 2596, "y": 2992}, + "6": {"x": 2620, "y": 2992} + } + }, + "warnings": null + }, + { + "id": 523, + "sourceNodeId": 158, + "sourcePortId": 1061, + "targetNodeId": 155, + "targetPortId": 1062, + "travelTime": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 24 + }, + "sourceArrival": { + "lock": false, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 96 + }, + "targetDeparture": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 68 + }, + "targetArrival": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 52 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2672, "y": 2686}, + {"x": 2672, "y": 2622}, + {"x": 2672, "y": 2334}, + {"x": 2672, "y": 2270} + ], + "textPositions": { + "0": {"x": 2684, "y": 2668}, + "1": {"x": 2660, "y": 2640}, + "2": {"x": 2660, "y": 2288}, + "3": {"x": 2684, "y": 2316}, + "4": {"x": 2660, "y": 2478}, + "5": {"x": 2660, "y": 2478}, + "6": {"x": 2684, "y": 2478} + } + }, + "warnings": null + }, + { + "id": 524, + "sourceNodeId": 155, + "sourcePortId": 1063, + "targetNodeId": 154, + "targetPortId": 1064, + "travelTime": { + "lock": false, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 52 + }, + "sourceArrival": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 68 + }, + "targetDeparture": { + "lock": true, + "time": 49, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 49 + }, + "targetArrival": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 71 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2672, "y": 2174}, + {"x": 2672, "y": 2110}, + {"x": 2672, "y": 1950}, + {"x": 2672, "y": 1886} + ], + "textPositions": { + "0": {"x": 2684, "y": 2156}, + "1": {"x": 2660, "y": 2128}, + "2": {"x": 2660, "y": 1904}, + "3": {"x": 2684, "y": 1932}, + "4": {"x": 2660, "y": 2030}, + "5": {"x": 2660, "y": 2030}, + "6": {"x": 2684, "y": 2030} + } + }, + "warnings": null + }, + { + "id": 525, + "sourceNodeId": 154, + "sourcePortId": 1065, + "targetNodeId": 153, + "targetPortId": 1066, + "travelTime": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 75 + }, + "sourceArrival": { + "lock": true, + "time": 45, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 45 + }, + "targetDeparture": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 30 + }, + "targetArrival": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 90 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2672, "y": 1790}, + {"x": 2672, "y": 1726}, + {"x": 2672, "y": 1470}, + {"x": 2672, "y": 1406} + ], + "textPositions": { + "0": {"x": 2684, "y": 1772}, + "1": {"x": 2660, "y": 1744}, + "2": {"x": 2660, "y": 1424}, + "3": {"x": 2684, "y": 1452}, + "4": {"x": 2660, "y": 1598}, + "5": {"x": 2660, "y": 1598}, + "6": {"x": 2684, "y": 1598} + } + }, + "warnings": null + }, + { + "id": 526, + "sourceNodeId": 153, + "sourcePortId": 1067, + "targetNodeId": 170, + "targetPortId": 1068, + "travelTime": { + "lock": true, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 31, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 91 + }, + "sourceArrival": { + "lock": true, + "time": 29, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 29 + }, + "targetDeparture": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetArrival": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 107 + }, + "numberOfStops": 0, + "trainrunId": 76, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2672, "y": 1310}, + {"x": 2672, "y": 1246}, + {"x": 2672, "y": 894}, + {"x": 2672, "y": 830} + ], + "textPositions": { + "0": {"x": 2684, "y": 1292}, + "1": {"x": 2660, "y": 1264}, + "2": {"x": 2660, "y": 848}, + "3": {"x": 2684, "y": 876}, + "4": {"x": 2660, "y": 1070}, + "5": {"x": 2660, "y": 1070}, + "6": {"x": 2684, "y": 1070} + } + }, + "warnings": null + }, + { + "id": 527, + "sourceNodeId": 157, + "sourcePortId": 1069, + "targetNodeId": 136, + "targetPortId": 1070, + "travelTime": { + "lock": true, + "time": 23, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 273 + }, + "sourceArrival": { + "lock": true, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 327 + }, + "targetDeparture": { + "lock": true, + "time": 4, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 304 + }, + "targetArrival": { + "lock": true, + "time": 56, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 296 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2306, "y": 3248}, + {"x": 2370, "y": 3248}, + {"x": 2526, "y": 3248}, + {"x": 2590, "y": 3248} + ], + "textPositions": { + "0": {"x": 2324, "y": 3260}, + "1": {"x": 2352, "y": 3236}, + "2": {"x": 2572, "y": 3236}, + "3": {"x": 2544, "y": 3260}, + "4": {"x": 2448, "y": 3236}, + "5": {"x": 2448, "y": 3236}, + "6": {"x": 2448, "y": 3260} + } + }, + "warnings": null + }, + { + "id": 528, + "sourceNodeId": 136, + "sourcePortId": 1071, + "targetNodeId": 158, + "targetPortId": 1072, + "travelTime": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 0, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 300 + }, + "sourceArrival": { + "lock": true, + "time": 0, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 300 + }, + "targetDeparture": { + "lock": true, + "time": 45, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 285 + }, + "targetArrival": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 315 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2672, "y": 3230}, + {"x": 2672, "y": 3166}, + {"x": 2672, "y": 2818}, + {"x": 2672, "y": 2754} + ], + "textPositions": { + "0": {"x": 2684, "y": 3212}, + "1": {"x": 2660, "y": 3184}, + "2": {"x": 2660, "y": 2772}, + "3": {"x": 2684, "y": 2800}, + "4": {"x": 2660, "y": 2992}, + "5": {"x": 2660, "y": 2992}, + "6": {"x": 2684, "y": 2992} + } + }, + "warnings": null + }, + { + "id": 529, + "sourceNodeId": 158, + "sourcePortId": 1073, + "targetNodeId": 179, + "targetPortId": 1441, + "travelTime": { + "lock": true, + "time": 26, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 316 + }, + "sourceArrival": { + "lock": true, + "time": 44, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 284 + }, + "targetDeparture": { + "lock": true, + "time": 18, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 258 + }, + "targetArrival": { + "lock": true, + "time": 42, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 342 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2608, "y": 2686}, + {"x": 2608, "y": 2622}, + {"x": 2448, "y": 2594}, + {"x": 2448, "y": 2530} + ], + "textPositions": { + "0": {"x": 2620, "y": 2668}, + "1": {"x": 2596, "y": 2640}, + "2": {"x": 2436, "y": 2548}, + "3": {"x": 2460, "y": 2576}, + "4": {"x": 2540, "y": 2608}, + "5": {"x": 2540, "y": 2608}, + "6": {"x": 2516, "y": 2608} + } + }, + "warnings": null + }, + { + "id": 530, + "sourceNodeId": 159, + "sourcePortId": 1075, + "targetNodeId": 184, + "targetPortId": 1451, + "travelTime": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 370 + }, + "sourceArrival": { + "lock": true, + "time": 50, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 230 + }, + "targetDeparture": { + "lock": false, + "time": 35, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 215 + }, + "targetArrival": { + "lock": false, + "time": 25, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 385 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2370, "y": 2256}, + {"x": 2434, "y": 2256}, + {"x": 2398, "y": 2224}, + {"x": 2462, "y": 2224} + ], + "textPositions": { + "0": {"x": 2388, "y": 2268}, + "1": {"x": 2416, "y": 2244}, + "2": {"x": 2444, "y": 2212}, + "3": {"x": 2416, "y": 2236}, + "4": {"x": 2416, "y": 2228}, + "5": {"x": 2416, "y": 2228}, + "6": {"x": 2416, "y": 2252} + } + }, + "warnings": null + }, + { + "id": 531, + "sourceNodeId": 155, + "sourcePortId": 1077, + "targetNodeId": 185, + "targetPortId": 1453, + "travelTime": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 43, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 403 + }, + "sourceArrival": { + "lock": true, + "time": 17, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 197 + }, + "targetDeparture": { + "lock": true, + "time": 6, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 186 + }, + "targetArrival": { + "lock": true, + "time": 54, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 414 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2736, "y": 2174}, + {"x": 2736, "y": 2110}, + {"x": 2672, "y": 2114}, + {"x": 2672, "y": 2050} + ], + "textPositions": { + "0": {"x": 2748, "y": 2156}, + "1": {"x": 2724, "y": 2128}, + "2": {"x": 2660, "y": 2068}, + "3": {"x": 2684, "y": 2096}, + "4": {"x": 2692, "y": 2112}, + "5": {"x": 2692, "y": 2112}, + "6": {"x": 2716, "y": 2112} + } + }, + "warnings": null + }, + { + "id": 532, + "sourceNodeId": 154, + "sourcePortId": 1079, + "targetNodeId": 169, + "targetPortId": 1080, + "travelTime": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 435 + }, + "sourceArrival": { + "lock": true, + "time": 45, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 165 + }, + "targetDeparture": { + "lock": false, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 147 + }, + "targetArrival": { + "lock": false, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 453 + }, + "numberOfStops": 0, + "trainrunId": 77, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2654, "y": 1840}, + {"x": 2590, "y": 1840}, + {"x": 2018, "y": 1840}, + {"x": 1954, "y": 1840} + ], + "textPositions": { + "0": {"x": 2636, "y": 1828}, + "1": {"x": 2608, "y": 1852}, + "2": {"x": 1972, "y": 1852}, + "3": {"x": 2000, "y": 1828}, + "4": {"x": 2304, "y": 1828}, + "5": {"x": 2304, "y": 1828}, + "6": {"x": 2304, "y": 1852} + } + }, + "warnings": null + }, + { + "id": 533, + "sourceNodeId": 157, + "sourcePortId": 1081, + "targetNodeId": 188, + "targetPortId": 1459, + "travelTime": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 153 + }, + "sourceArrival": { + "lock": true, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 207 + }, + "targetDeparture": { + "lock": true, + "time": 16, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 196 + }, + "targetArrival": { + "lock": true, + "time": 44, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 164 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2306, "y": 3280}, + {"x": 2370, "y": 3280}, + {"x": 2334, "y": 3248}, + {"x": 2398, "y": 3248} + ], + "textPositions": { + "0": {"x": 2324, "y": 3292}, + "1": {"x": 2352, "y": 3268}, + "2": {"x": 2380, "y": 3236}, + "3": {"x": 2352, "y": 3260}, + "4": {"x": 2352, "y": 3252}, + "5": {"x": 2352, "y": 3252}, + "6": {"x": 2352, "y": 3276} + } + }, + "warnings": null + }, + { + "id": 534, + "sourceNodeId": 136, + "sourcePortId": 1083, + "targetNodeId": 191, + "targetPortId": 1465, + "travelTime": { + "lock": true, + "time": 7, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 0, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 180 + }, + "sourceArrival": { + "lock": true, + "time": 0, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 180 + }, + "targetDeparture": { + "lock": true, + "time": 53, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 173 + }, + "targetArrival": { + "lock": true, + "time": 7, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 187 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2704, "y": 3230}, + {"x": 2704, "y": 3166}, + {"x": 2608, "y": 3090}, + {"x": 2608, "y": 3026} + ], + "textPositions": { + "0": {"x": 2716, "y": 3212}, + "1": {"x": 2692, "y": 3184}, + "2": {"x": 2596, "y": 3044}, + "3": {"x": 2620, "y": 3072}, + "4": {"x": 2668, "y": 3128}, + "5": {"x": 2668, "y": 3128}, + "6": {"x": 2644, "y": 3128} + } + }, + "warnings": null + }, + { + "id": 535, + "sourceNodeId": 158, + "sourcePortId": 1085, + "targetNodeId": 192, + "targetPortId": 1467, + "travelTime": { + "lock": true, + "time": 26, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 196 + }, + "sourceArrival": { + "lock": true, + "time": 44, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 164 + }, + "targetDeparture": { + "lock": true, + "time": 18, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 138 + }, + "targetArrival": { + "lock": true, + "time": 42, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 222 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2640, "y": 2686}, + {"x": 2640, "y": 2622}, + {"x": 2448, "y": 2594}, + {"x": 2448, "y": 2530} + ], + "textPositions": { + "0": {"x": 2652, "y": 2668}, + "1": {"x": 2628, "y": 2640}, + "2": {"x": 2436, "y": 2548}, + "3": {"x": 2460, "y": 2576}, + "4": {"x": 2556, "y": 2608}, + "5": {"x": 2556, "y": 2608}, + "6": {"x": 2532, "y": 2608} + } + }, + "warnings": null + }, + { + "id": 536, + "sourceNodeId": 159, + "sourcePortId": 1087, + "targetNodeId": 197, + "targetPortId": 1477, + "travelTime": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 250 + }, + "sourceArrival": { + "lock": true, + "time": 50, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 110 + }, + "targetDeparture": { + "lock": true, + "time": 35, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 95 + }, + "targetArrival": { + "lock": true, + "time": 25, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 265 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2370, "y": 2288}, + {"x": 2434, "y": 2288}, + {"x": 2398, "y": 2224}, + {"x": 2462, "y": 2224} + ], + "textPositions": { + "0": {"x": 2388, "y": 2300}, + "1": {"x": 2416, "y": 2276}, + "2": {"x": 2444, "y": 2212}, + "3": {"x": 2416, "y": 2236}, + "4": {"x": 2416, "y": 2244}, + "5": {"x": 2416, "y": 2244}, + "6": {"x": 2416, "y": 2268} + } + }, + "warnings": null + }, + { + "id": 537, + "sourceNodeId": 155, + "sourcePortId": 1089, + "targetNodeId": 198, + "targetPortId": 1479, + "travelTime": { + "lock": false, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 43, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 283 + }, + "sourceArrival": { + "lock": true, + "time": 17, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 77 + }, + "targetDeparture": { + "lock": true, + "time": 6, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 66 + }, + "targetArrival": { + "lock": true, + "time": 54, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, + "timeFormatter": null, + "consecutiveTime": 294 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2768, "y": 2174}, + {"x": 2768, "y": 2110}, + {"x": 2672, "y": 2114}, + {"x": 2672, "y": 2050} + ], + "textPositions": { + "0": {"x": 2780, "y": 2156}, + "1": {"x": 2756, "y": 2128}, + "2": {"x": 2660, "y": 2068}, + "3": {"x": 2684, "y": 2096}, + "4": {"x": 2708, "y": 2112}, + "5": {"x": 2708, "y": 2112}, + "6": {"x": 2732, "y": 2112} + } + }, + "warnings": null + }, + { + "id": 538, + "sourceNodeId": 154, + "sourcePortId": 1091, + "targetNodeId": 153, + "targetPortId": 1092, + "travelTime": { + "lock": true, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 15, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 315 + }, + "sourceArrival": { + "lock": false, + "time": 45, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 45 + }, + "targetDeparture": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 30 + }, + "targetArrival": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 330 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2704, "y": 1790}, + {"x": 2704, "y": 1726}, + {"x": 2704, "y": 1470}, + {"x": 2704, "y": 1406} + ], + "textPositions": { + "0": {"x": 2716, "y": 1772}, + "1": {"x": 2692, "y": 1744}, + "2": {"x": 2692, "y": 1424}, + "3": {"x": 2716, "y": 1452}, + "4": {"x": 2692, "y": 1598}, + "5": {"x": 2692, "y": 1598}, + "6": {"x": 2716, "y": 1598} + } + }, + "warnings": null + }, + { + "id": 539, + "sourceNodeId": 153, + "sourcePortId": 1093, + "targetNodeId": 170, + "targetPortId": 1094, + "travelTime": { + "lock": true, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 31, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 331 + }, + "sourceArrival": { + "lock": true, + "time": 29, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 29 + }, + "targetDeparture": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetArrival": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 347 + }, + "numberOfStops": 0, + "trainrunId": 78, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2704, "y": 1310}, + {"x": 2704, "y": 1246}, + {"x": 2704, "y": 894}, + {"x": 2704, "y": 830} + ], + "textPositions": { + "0": {"x": 2716, "y": 1292}, + "1": {"x": 2692, "y": 1264}, + "2": {"x": 2692, "y": 848}, + "3": {"x": 2716, "y": 876}, + "4": {"x": 2692, "y": 1070}, + "5": {"x": 2692, "y": 1070}, + "6": {"x": 2716, "y": 1070} + } + }, + "warnings": null + }, + { + "id": 540, + "sourceNodeId": 142, + "sourcePortId": 1095, + "targetNodeId": 169, + "targetPortId": 1096, + "travelTime": { + "lock": false, + "time": 12, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 35, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 35 + }, + "sourceArrival": { + "lock": true, + "time": 25, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 265 + }, + "targetDeparture": { + "lock": true, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 253 + }, + "targetArrival": { + "lock": true, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 47 + }, + "numberOfStops": 0, + "trainrunId": 79, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 226, "y": 1840}, + {"x": 290, "y": 1840}, + {"x": 1790, "y": 1840}, + {"x": 1854, "y": 1840} + ], + "textPositions": { + "0": {"x": 244, "y": 1852}, + "1": {"x": 272, "y": 1828}, + "2": {"x": 1836, "y": 1828}, + "3": {"x": 1808, "y": 1852}, + "4": {"x": 1040, "y": 1828}, + "5": {"x": 1040, "y": 1828}, + "6": {"x": 1040, "y": 1852} + } + }, + "warnings": null + }, + { + "id": 541, + "sourceNodeId": 153, + "sourcePortId": 1097, + "targetNodeId": 201, + "targetPortId": 1485, + "travelTime": { + "lock": false, + "time": 7, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 58, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 58 + }, + "sourceArrival": { + "lock": true, + "time": 2, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 242 + }, + "targetDeparture": { + "lock": true, + "time": 55, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 235 + }, + "targetArrival": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 65 + }, + "numberOfStops": 0, + "trainrunId": 79, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2768, "y": 1310}, + {"x": 2768, "y": 1246}, + {"x": 2672, "y": 1154}, + {"x": 2672, "y": 1090} + ], + "textPositions": { + "0": {"x": 2780, "y": 1292}, + "1": {"x": 2756, "y": 1264}, + "2": {"x": 2660, "y": 1108}, + "3": {"x": 2684, "y": 1136}, + "4": {"x": 2732, "y": 1200}, + "5": {"x": 2732, "y": 1200}, + "6": {"x": 2708, "y": 1200} + } + }, + "warnings": null + }, + { + "id": 542, + "sourceNodeId": 142, + "sourcePortId": 1099, + "targetNodeId": 169, + "targetPortId": 1100, + "travelTime": { + "lock": true, + "time": 9, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 9, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 9 + }, + "sourceArrival": { + "lock": true, + "time": 51, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 51 + }, + "targetDeparture": { + "lock": false, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 42 + }, + "targetArrival": { + "lock": false, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "numberOfStops": 0, + "trainrunId": 80, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 226, "y": 1808}, + {"x": 290, "y": 1808}, + {"x": 1790, "y": 1808}, + {"x": 1854, "y": 1808} + ], + "textPositions": { + "0": {"x": 244, "y": 1820}, + "1": {"x": 272, "y": 1796}, + "2": {"x": 1836, "y": 1796}, + "3": {"x": 1808, "y": 1820}, + "4": {"x": 1040, "y": 1796}, + "5": {"x": 1040, "y": 1796}, + "6": {"x": 1040, "y": 1820} + } + }, + "warnings": null + }, + { + "id": 543, + "sourceNodeId": 153, + "sourcePortId": 1101, + "targetNodeId": 170, + "targetPortId": 1102, + "travelTime": { + "lock": true, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 29, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 29 + }, + "sourceArrival": { + "lock": true, + "time": 31, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 31 + }, + "targetDeparture": { + "lock": false, + "time": 17, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 17 + }, + "targetArrival": { + "lock": false, + "time": 43, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 43 + }, + "numberOfStops": 0, + "trainrunId": 80, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2736, "y": 1310}, + {"x": 2736, "y": 1246}, + {"x": 2736, "y": 894}, + {"x": 2736, "y": 830} + ], + "textPositions": { + "0": {"x": 2748, "y": 1292}, + "1": {"x": 2724, "y": 1264}, + "2": {"x": 2724, "y": 848}, + "3": {"x": 2748, "y": 876}, + "4": {"x": 2724, "y": 1070}, + "5": {"x": 2724, "y": 1070}, + "6": {"x": 2748, "y": 1070} + } + }, + "warnings": null + }, + { + "id": 544, + "sourceNodeId": 142, + "sourcePortId": 1103, + "targetNodeId": 141, + "targetPortId": 1104, + "travelTime": { + "lock": true, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 59, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 299 + }, + "sourceArrival": { + "lock": false, + "time": 1, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 241 + }, + "targetDeparture": { + "lock": true, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 222 + }, + "targetArrival": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 318 + }, + "numberOfStops": 0, + "trainrunId": 81, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 112, "y": 1726}, + {"x": 112, "y": 1662}, + {"x": 112, "y": 1314}, + {"x": 112, "y": 1250} + ], + "textPositions": { + "0": {"x": 124, "y": 1708}, + "1": {"x": 100, "y": 1680}, + "2": {"x": 100, "y": 1268}, + "3": {"x": 124, "y": 1296}, + "4": {"x": 100, "y": 1488}, + "5": {"x": 100, "y": 1488}, + "6": {"x": 124, "y": 1488} + } + }, + "warnings": null + }, + { + "id": 545, + "sourceNodeId": 141, + "sourcePortId": 1105, + "targetNodeId": 143, + "targetPortId": 1106, + "travelTime": { + "lock": true, + "time": 12, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 319 + }, + "sourceArrival": { + "lock": true, + "time": 41, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 221 + }, + "targetDeparture": { + "lock": true, + "time": 29, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 209 + }, + "targetArrival": { + "lock": true, + "time": 31, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 331 + }, + "numberOfStops": 0, + "trainrunId": 81, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 112, "y": 1182}, + {"x": 112, "y": 1118}, + {"x": 112, "y": 866}, + {"x": 112, "y": 802} + ], + "textPositions": { + "0": {"x": 124, "y": 1164}, + "1": {"x": 100, "y": 1136}, + "2": {"x": 100, "y": 820}, + "3": {"x": 124, "y": 848}, + "4": {"x": 100, "y": 992}, + "5": {"x": 100, "y": 992}, + "6": {"x": 124, "y": 992} + } + }, + "warnings": null + }, + { + "id": 546, + "sourceNodeId": 143, + "sourcePortId": 1107, + "targetNodeId": 172, + "targetPortId": 1108, + "travelTime": { + "lock": true, + "time": 7, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 32, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 332 + }, + "sourceArrival": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 208 + }, + "targetDeparture": { + "lock": false, + "time": 21, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 201 + }, + "targetArrival": { + "lock": false, + "time": 39, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 339 + }, + "numberOfStops": 0, + "trainrunId": 81, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 62, "y": 752}, + {"x": -2, "y": 752}, + {"x": -446, "y": 336}, + {"x": -510, "y": 336} + ], + "textPositions": { + "0": {"x": 44, "y": 740}, + "1": {"x": 16, "y": 764}, + "2": {"x": -492, "y": 348}, + "3": {"x": -464, "y": 324}, + "4": {"x": -224, "y": 532}, + "5": {"x": -224, "y": 532}, + "6": {"x": -224, "y": 556} + } + }, + "warnings": null + }, + { + "id": 547, + "sourceNodeId": 129, + "sourcePortId": 1109, + "targetNodeId": 171, + "targetPortId": 1110, + "travelTime": { + "lock": false, + "time": 22, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 4, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 364 + }, + "sourceArrival": { + "lock": true, + "time": 56, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 176 + }, + "targetDeparture": { + "lock": true, + "time": 34, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 154 + }, + "targetArrival": { + "lock": true, + "time": 26, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 386 + }, + "numberOfStops": 0, + "trainrunId": 81, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": -2146, "y": 176}, + {"x": -2210, "y": 176}, + {"x": -2398, "y": 336}, + {"x": -2462, "y": 336} + ], + "textPositions": { + "0": {"x": -2164, "y": 164}, + "1": {"x": -2192, "y": 188}, + "2": {"x": -2444, "y": 348}, + "3": {"x": -2416, "y": 324}, + "4": {"x": -2304, "y": 244}, + "5": {"x": -2304, "y": 244}, + "6": {"x": -2304, "y": 268} + } + }, + "warnings": null + }, + { + "id": 548, + "sourceNodeId": 142, + "sourcePortId": 1111, + "targetNodeId": 141, + "targetPortId": 1112, + "travelTime": { + "lock": true, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 90 + }, + "sourceArrival": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 90 + }, + "targetDeparture": { + "lock": true, + "time": 12, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 72 + }, + "targetArrival": { + "lock": true, + "time": 48, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 108 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 208, "y": 1726}, + {"x": 208, "y": 1662}, + {"x": 208, "y": 1314}, + {"x": 208, "y": 1250} + ], + "textPositions": { + "0": {"x": 220, "y": 1708}, + "1": {"x": 196, "y": 1680}, + "2": {"x": 196, "y": 1268}, + "3": {"x": 220, "y": 1296}, + "4": {"x": 196, "y": 1488}, + "5": {"x": 196, "y": 1488}, + "6": {"x": 220, "y": 1488} + } + }, + "warnings": null + }, + { + "id": 549, + "sourceNodeId": 141, + "sourcePortId": 1113, + "targetNodeId": 143, + "targetPortId": 1114, + "travelTime": { + "lock": true, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 49, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 109 + }, + "sourceArrival": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 71 + }, + "targetDeparture": { + "lock": false, + "time": 58, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 58 + }, + "targetArrival": { + "lock": false, + "time": 2, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 122 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 208, "y": 1182}, + {"x": 208, "y": 1118}, + {"x": 208, "y": 866}, + {"x": 208, "y": 802} + ], + "textPositions": { + "0": {"x": 220, "y": 1164}, + "1": {"x": 196, "y": 1136}, + "2": {"x": 196, "y": 820}, + "3": {"x": 220, "y": 848}, + "4": {"x": 196, "y": 992}, + "5": {"x": 196, "y": 992}, + "6": {"x": 220, "y": 992} + } + }, + "warnings": null + }, + { + "id": 550, + "sourceNodeId": 143, + "sourcePortId": 1115, + "targetNodeId": 133, + "targetPortId": 1116, + "travelTime": { + "lock": true, + "time": 7, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 4, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 124 + }, + "sourceArrival": { + "lock": true, + "time": 56, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 56 + }, + "targetDeparture": { + "lock": true, + "time": 49, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 49 + }, + "targetArrival": { + "lock": true, + "time": 11, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 131 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 176, "y": 734}, + {"x": 176, "y": 670}, + {"x": 176, "y": 414}, + {"x": 176, "y": 350} + ], + "textPositions": { + "0": {"x": 188, "y": 716}, + "1": {"x": 164, "y": 688}, + "2": {"x": 164, "y": 368}, + "3": {"x": 188, "y": 396}, + "4": {"x": 164, "y": 542}, + "5": {"x": 164, "y": 542}, + "6": {"x": 188, "y": 542} + } + }, + "warnings": null + }, + { + "id": 551, + "sourceNodeId": 133, + "sourcePortId": 1117, + "targetNodeId": 144, + "targetPortId": 1118, + "travelTime": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 12, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 132 + }, + "sourceArrival": { + "lock": true, + "time": 48, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 48 + }, + "targetDeparture": { + "lock": true, + "time": 38, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 38 + }, + "targetArrival": { + "lock": true, + "time": 22, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 142 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 240, "y": 94}, + {"x": 240, "y": 30}, + {"x": 240, "y": -290}, + {"x": 240, "y": -354} + ], + "textPositions": { + "0": {"x": 252, "y": 76}, + "1": {"x": 228, "y": 48}, + "2": {"x": 228, "y": -336}, + "3": {"x": 252, "y": -308}, + "4": {"x": 228, "y": -130}, + "5": {"x": 228, "y": -130}, + "6": {"x": 252, "y": -130} + } + }, + "warnings": null + }, + { + "id": 552, + "sourceNodeId": 144, + "sourcePortId": 1119, + "targetNodeId": 145, + "targetPortId": 1120, + "travelTime": { + "lock": true, + "time": 4, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 23, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 143 + }, + "sourceArrival": { + "lock": true, + "time": 37, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 37 + }, + "targetDeparture": { + "lock": true, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 33 + }, + "targetArrival": { + "lock": true, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 147 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 304, "y": -450}, + {"x": 304, "y": -514}, + {"x": 304, "y": -798}, + {"x": 304, "y": -862} + ], + "textPositions": { + "0": {"x": 316, "y": -468}, + "1": {"x": 292, "y": -496}, + "2": {"x": 292, "y": -844}, + "3": {"x": 316, "y": -816}, + "4": {"x": 292, "y": -656}, + "5": {"x": 292, "y": -656}, + "6": {"x": 316, "y": -656} + } + }, + "warnings": null + }, + { + "id": 553, + "sourceNodeId": 145, + "sourcePortId": 1121, + "targetNodeId": 146, + "targetPortId": 1122, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 148 + }, + "sourceArrival": { + "lock": true, + "time": 32, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 32 + }, + "targetDeparture": { + "lock": true, + "time": 27, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 27 + }, + "targetArrival": { + "lock": true, + "time": 33, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 153 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 304, "y": -930}, + {"x": 304, "y": -994}, + {"x": 304, "y": -1278}, + {"x": 304, "y": -1342} + ], + "textPositions": { + "0": {"x": 316, "y": -948}, + "1": {"x": 292, "y": -976}, + "2": {"x": 292, "y": -1324}, + "3": {"x": 316, "y": -1296}, + "4": {"x": 292, "y": -1136}, + "5": {"x": 292, "y": -1136}, + "6": {"x": 316, "y": -1136} + } + }, + "warnings": null + }, + { + "id": 554, + "sourceNodeId": 146, + "sourcePortId": 1123, + "targetNodeId": 134, + "targetPortId": 1124, + "travelTime": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 34, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 154 + }, + "sourceArrival": { + "lock": true, + "time": 26, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 26 + }, + "targetDeparture": { + "lock": true, + "time": 16, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 16 + }, + "targetArrival": { + "lock": true, + "time": 44, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 164 + }, + "numberOfStops": 0, + "trainrunId": 82, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 304, "y": -1410}, + {"x": 304, "y": -1474}, + {"x": 304, "y": -1758}, + {"x": 304, "y": -1822} + ], + "textPositions": { + "0": {"x": 316, "y": -1428}, + "1": {"x": 292, "y": -1456}, + "2": {"x": 292, "y": -1804}, + "3": {"x": 316, "y": -1776}, + "4": {"x": 292, "y": -1616}, + "5": {"x": 292, "y": -1616}, + "6": {"x": 316, "y": -1616} + } + }, + "warnings": null + }, + { + "id": 555, + "sourceNodeId": 142, + "sourcePortId": 1125, + "targetNodeId": 141, + "targetPortId": 1126, + "travelTime": { + "lock": true, + "time": 19, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 55, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 115 + }, + "sourceArrival": { + "lock": false, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 65 + }, + "targetDeparture": { + "lock": false, + "time": 46, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 46 + }, + "targetArrival": { + "lock": false, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 134 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 176, "y": 1726}, + {"x": 176, "y": 1662}, + {"x": 176, "y": 1314}, + {"x": 176, "y": 1250} + ], + "textPositions": { + "0": {"x": 188, "y": 1708}, + "1": {"x": 164, "y": 1680}, + "2": {"x": 164, "y": 1268}, + "3": {"x": 188, "y": 1296}, + "4": {"x": 164, "y": 1488}, + "5": {"x": 164, "y": 1488}, + "6": {"x": 188, "y": 1488} + } + }, + "warnings": null + }, + { + "id": 556, + "sourceNodeId": 141, + "sourcePortId": 1127, + "targetNodeId": 143, + "targetPortId": 1128, + "travelTime": { + "lock": true, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 134 + }, + "sourceArrival": { + "lock": false, + "time": 46, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 46 + }, + "targetDeparture": { + "lock": false, + "time": 38, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 38 + }, + "targetArrival": { + "lock": false, + "time": 22, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 142 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 176, "y": 1182}, + {"x": 176, "y": 1118}, + {"x": 176, "y": 866}, + {"x": 176, "y": 802} + ], + "textPositions": { + "0": {"x": 188, "y": 1164}, + "1": {"x": 164, "y": 1136}, + "2": {"x": 164, "y": 820}, + "3": {"x": 188, "y": 848}, + "4": {"x": 164, "y": 992}, + "5": {"x": 164, "y": 992}, + "6": {"x": 188, "y": 992} + } + }, + "warnings": null + }, + { + "id": 557, + "sourceNodeId": 143, + "sourcePortId": 1129, + "targetNodeId": 133, + "targetPortId": 1130, + "travelTime": { + "lock": true, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 22, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 142 + }, + "sourceArrival": { + "lock": false, + "time": 38, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 38 + }, + "targetDeparture": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 30 + }, + "targetArrival": { + "lock": true, + "time": 30, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 150 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 144, "y": 734}, + {"x": 144, "y": 670}, + {"x": 144, "y": 414}, + {"x": 144, "y": 350} + ], + "textPositions": { + "0": {"x": 156, "y": 716}, + "1": {"x": 132, "y": 688}, + "2": {"x": 132, "y": 368}, + "3": {"x": 156, "y": 396}, + "4": {"x": 132, "y": 542}, + "5": {"x": 132, "y": 542}, + "6": {"x": 156, "y": 542} + } + }, + "warnings": null + }, + { + "id": 558, + "sourceNodeId": 133, + "sourcePortId": 1131, + "targetNodeId": 144, + "targetPortId": 1132, + "travelTime": { + "lock": true, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 32, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 152 + }, + "sourceArrival": { + "lock": true, + "time": 28, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 28 + }, + "targetDeparture": { + "lock": false, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "targetArrival": { + "lock": false, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 162 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 208, "y": 94}, + {"x": 208, "y": 30}, + {"x": 208, "y": -290}, + {"x": 208, "y": -354} + ], + "textPositions": { + "0": {"x": 220, "y": 76}, + "1": {"x": 196, "y": 48}, + "2": {"x": 196, "y": -336}, + "3": {"x": 220, "y": -308}, + "4": {"x": 196, "y": -130}, + "5": {"x": 196, "y": -130}, + "6": {"x": 220, "y": -130} + } + }, + "warnings": null + }, + { + "id": 559, + "sourceNodeId": 144, + "sourcePortId": 1133, + "targetNodeId": 145, + "targetPortId": 1134, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 42, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 162 + }, + "sourceArrival": { + "lock": false, + "time": 18, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 18 + }, + "targetDeparture": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetArrival": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 167 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 272, "y": -450}, + {"x": 272, "y": -514}, + {"x": 272, "y": -798}, + {"x": 272, "y": -862} + ], + "textPositions": { + "0": {"x": 284, "y": -468}, + "1": {"x": 260, "y": -496}, + "2": {"x": 260, "y": -844}, + "3": {"x": 284, "y": -816}, + "4": {"x": 260, "y": -656}, + "5": {"x": 260, "y": -656}, + "6": {"x": 284, "y": -656} + } + }, + "warnings": null + }, + { + "id": 560, + "sourceNodeId": 145, + "sourcePortId": 1135, + "targetNodeId": 146, + "targetPortId": 1136, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 47, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 167 + }, + "sourceArrival": { + "lock": false, + "time": 13, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 13 + }, + "targetDeparture": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 8 + }, + "targetArrival": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 172 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 272, "y": -930}, + {"x": 272, "y": -994}, + {"x": 272, "y": -1278}, + {"x": 272, "y": -1342} + ], + "textPositions": { + "0": {"x": 284, "y": -948}, + "1": {"x": 260, "y": -976}, + "2": {"x": 260, "y": -1324}, + "3": {"x": 284, "y": -1296}, + "4": {"x": 260, "y": -1136}, + "5": {"x": 260, "y": -1136}, + "6": {"x": 284, "y": -1136} + } + }, + "warnings": null + }, + { + "id": 561, + "sourceNodeId": 146, + "sourcePortId": 1137, + "targetNodeId": 134, + "targetPortId": 1138, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 52, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 172 + }, + "sourceArrival": { + "lock": false, + "time": 8, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 8 + }, + "targetDeparture": { + "lock": false, + "time": 3, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 3 + }, + "targetArrival": { + "lock": false, + "time": 57, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 177 + }, + "numberOfStops": 0, + "trainrunId": 83, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 272, "y": -1410}, + {"x": 272, "y": -1474}, + {"x": 272, "y": -1758}, + {"x": 272, "y": -1822} + ], + "textPositions": { + "0": {"x": 284, "y": -1428}, + "1": {"x": 260, "y": -1456}, + "2": {"x": 260, "y": -1804}, + "3": {"x": 284, "y": -1776}, + "4": {"x": 260, "y": -1616}, + "5": {"x": 260, "y": -1616}, + "6": {"x": 284, "y": -1616} + } + }, + "warnings": null + }, + { + "id": 562, + "sourceNodeId": 135, + "sourcePortId": 1139, + "targetNodeId": 202, + "targetPortId": 1487, + "travelTime": { + "lock": true, + "time": 5, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 9, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 9 + }, + "sourceArrival": { + "lock": true, + "time": 51, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 291 + }, + "targetDeparture": { + "lock": true, + "time": 46, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 286 + }, + "targetArrival": { + "lock": true, + "time": 14, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 14 + }, + "numberOfStops": 0, + "trainrunId": 84, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 2850, "y": 176}, + {"x": 2914, "y": 176}, + {"x": 2910, "y": 48}, + {"x": 2974, "y": 48} + ], + "textPositions": { + "0": {"x": 2868, "y": 188}, + "1": {"x": 2896, "y": 164}, + "2": {"x": 2956, "y": 36}, + "3": {"x": 2928, "y": 60}, + "4": {"x": 2912, "y": 100}, + "5": {"x": 2912, "y": 100}, + "6": {"x": 2912, "y": 124} + } + }, + "warnings": null + }, + { + "id": 563, + "sourceNodeId": 150, + "sourcePortId": 1141, + "targetNodeId": 151, + "targetPortId": 1142, "travelTime": { "lock": true, - "time": 14, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 2, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 182 + "consecutiveTime": 23 }, "sourceArrival": { "lock": false, - "time": 58, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 178 + "consecutiveTime": 277 + }, + "targetDeparture": { + "lock": true, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 264 + }, + "targetArrival": { + "lock": true, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 36 + }, + "numberOfStops": 0, + "trainrunId": 84, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 3394, "y": 176}, + {"x": 3458, "y": 176}, + {"x": 3806, "y": 176}, + {"x": 3870, "y": 176} + ], + "textPositions": { + "0": {"x": 3412, "y": 188}, + "1": {"x": 3440, "y": 164}, + "2": {"x": 3852, "y": 164}, + "3": {"x": 3824, "y": 188}, + "4": {"x": 3632, "y": 164}, + "5": {"x": 3632, "y": 164}, + "6": {"x": 3632, "y": 188} + } + }, + "warnings": null + }, + { + "id": 564, + "sourceNodeId": 151, + "sourcePortId": 1143, + "targetNodeId": 203, + "targetPortId": 1489, + "travelTime": { + "lock": true, + "time": 21, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": false, + "time": 38, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 38 + }, + "sourceArrival": { + "lock": false, + "time": 22, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 262 }, "targetDeparture": { "lock": false, - "time": 44, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 164 + "consecutiveTime": 241 }, "targetArrival": { "lock": false, - "time": 16, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 196 + "consecutiveTime": 59 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2640, "y": 3710}, - {"x": 2640, "y": 3646}, - {"x": 2640, "y": 3390}, - {"x": 2640, "y": 3326} + {"x": 3970, "y": 144}, + {"x": 4034, "y": 144}, + {"x": 4190, "y": 80}, + {"x": 4254, "y": 80} ], "textPositions": { - "0": {"x": 2652, "y": 3692}, - "1": {"x": 2628, "y": 3664}, - "2": {"x": 2628, "y": 3344}, - "3": {"x": 2652, "y": 3372}, - "4": {"x": 2628, "y": 3518}, - "5": {"x": 2628, "y": 3518}, - "6": {"x": 2652, "y": 3518} + "0": {"x": 3988, "y": 156}, + "1": {"x": 4016, "y": 132}, + "2": {"x": 4236, "y": 68}, + "3": {"x": 4208, "y": 92}, + "4": {"x": 4112, "y": 100}, + "5": {"x": 4112, "y": 100}, + "6": {"x": 4112, "y": 124} } }, "warnings": null }, { - "id": 510, - "sourceNodeId": 136, - "sourcePortId": 1035, - "targetNodeId": 158, - "targetPortId": 1036, + "id": 565, + "sourceNodeId": 137, + "sourcePortId": 1145, + "targetNodeId": 207, + "targetPortId": 1497, "travelTime": { "lock": true, - "time": 6, + "time": 30, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 18, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 198 + "consecutiveTime": 84 }, "sourceArrival": { - "lock": true, - "time": 42, + "lock": false, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 162 + "consecutiveTime": 216 }, "targetDeparture": { "lock": false, - "time": 36, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 156 + "consecutiveTime": 186 }, "targetArrival": { "lock": false, - "time": 24, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 204 + "consecutiveTime": 114 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2640, "y": 3230}, - {"x": 2640, "y": 3166}, - {"x": 2640, "y": 2818}, - {"x": 2640, "y": 2754} + {"x": 4656, "y": 222}, + {"x": 4656, "y": 286}, + {"x": 4656, "y": 574}, + {"x": 4656, "y": 638} ], "textPositions": { - "0": {"x": 2652, "y": 3212}, - "1": {"x": 2628, "y": 3184}, - "2": {"x": 2628, "y": 2772}, - "3": {"x": 2652, "y": 2800}, - "4": {"x": 2628, "y": 2992}, - "5": {"x": 2628, "y": 2992}, - "6": {"x": 2652, "y": 2992} + "0": {"x": 4644, "y": 240}, + "1": {"x": 4668, "y": 268}, + "2": {"x": 4668, "y": 620}, + "3": {"x": 4644, "y": 592}, + "4": {"x": 4644, "y": 430}, + "5": {"x": 4644, "y": 430}, + "6": {"x": 4668, "y": 430} } }, "warnings": null }, { - "id": 511, - "sourceNodeId": 155, - "sourcePortId": 1037, - "targetNodeId": 154, - "targetPortId": 1038, + "id": 566, + "sourceNodeId": 140, + "sourcePortId": 1147, + "targetNodeId": 212, + "targetPortId": 1507, "travelTime": { "lock": true, - "time": 19, + "time": 10, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 1 + }, + "sourceDeparture": { + "lock": true, + "time": 26, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 146 + }, + "sourceArrival": { + "lock": true, + "time": 34, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 154 + }, + "targetDeparture": { + "lock": true, + "time": 24, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 144 + }, + "targetArrival": { + "lock": true, + "time": 36, + "warning": null, + "timeFormatter": null, + "consecutiveTime": 156 + }, + "numberOfStops": 0, + "trainrunId": 84, + "resourceId": 0, + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 4688, "y": 1278}, + {"x": 4688, "y": 1342}, + {"x": 4656, "y": 1470}, + {"x": 4656, "y": 1534} + ], + "textPositions": { + "0": {"x": 4676, "y": 1296}, + "1": {"x": 4700, "y": 1324}, + "2": {"x": 4668, "y": 1516}, + "3": {"x": 4644, "y": 1488}, + "4": {"x": 4660, "y": 1406}, + "5": {"x": 4660, "y": 1406}, + "6": {"x": 4684, "y": 1406} + } + }, + "warnings": null + }, + { + "id": 567, + "sourceNodeId": 135, + "sourcePortId": 1149, + "targetNodeId": 170, + "targetPortId": 1150, + "travelTime": { + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 52, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 232 + "consecutiveTime": 67 }, "sourceArrival": { - "lock": false, - "time": 8, + "lock": true, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 128 + "consecutiveTime": 293 }, "targetDeparture": { - "lock": true, - "time": 49, + "lock": false, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 109 + "consecutiveTime": 285 }, "targetArrival": { - "lock": true, - "time": 11, + "lock": false, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 251 + "consecutiveTime": 75 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 2174}, - {"x": 2704, "y": 2110}, - {"x": 2704, "y": 1950}, - {"x": 2704, "y": 1886} + {"x": 2704, "y": 350}, + {"x": 2704, "y": 414}, + {"x": 2704, "y": 670}, + {"x": 2704, "y": 734} ], "textPositions": { - "0": {"x": 2716, "y": 2156}, - "1": {"x": 2692, "y": 2128}, - "2": {"x": 2692, "y": 1904}, - "3": {"x": 2716, "y": 1932}, - "4": {"x": 2692, "y": 2030}, - "5": {"x": 2692, "y": 2030}, - "6": {"x": 2716, "y": 2030} + "0": {"x": 2692, "y": 368}, + "1": {"x": 2716, "y": 396}, + "2": {"x": 2716, "y": 716}, + "3": {"x": 2692, "y": 688}, + "4": {"x": 2692, "y": 542}, + "5": {"x": 2692, "y": 542}, + "6": {"x": 2716, "y": 542} } }, "warnings": null }, { - "id": 512, - "sourceNodeId": 154, - "sourcePortId": 1039, - "targetNodeId": 169, - "targetPortId": 1040, + "id": 568, + "sourceNodeId": 140, + "sourcePortId": 1151, + "targetNodeId": 214, + "targetPortId": 1511, "travelTime": { "lock": true, - "time": 18, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 15, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 255 + "consecutiveTime": 123 }, "sourceArrival": { "lock": true, - "time": 45, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 105 + "consecutiveTime": 237 }, "targetDeparture": { - "lock": false, - "time": 27, + "lock": true, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 87 + "consecutiveTime": 228 }, "targetArrival": { - "lock": false, - "time": 33, + "lock": true, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 273 + "consecutiveTime": 132 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2654, "y": 1808}, - {"x": 2590, "y": 1808}, - {"x": 2018, "y": 1808}, - {"x": 1954, "y": 1808} + {"x": 4656, "y": 1278}, + {"x": 4656, "y": 1342}, + {"x": 4656, "y": 1470}, + {"x": 4656, "y": 1534} ], "textPositions": { - "0": {"x": 2636, "y": 1796}, - "1": {"x": 2608, "y": 1820}, - "2": {"x": 1972, "y": 1820}, - "3": {"x": 2000, "y": 1796}, - "4": {"x": 2304, "y": 1796}, - "5": {"x": 2304, "y": 1796}, - "6": {"x": 2304, "y": 1820} + "0": {"x": 4644, "y": 1296}, + "1": {"x": 4668, "y": 1324}, + "2": {"x": 4668, "y": 1516}, + "3": {"x": 4644, "y": 1488}, + "4": {"x": 4644, "y": 1406}, + "5": {"x": 4644, "y": 1406}, + "6": {"x": 4668, "y": 1406} } }, "warnings": null }, { - "id": 513, - "sourceNodeId": 142, - "sourcePortId": 1041, - "targetNodeId": 141, - "targetPortId": 1042, + "id": 569, + "sourceNodeId": 135, + "sourcePortId": 1153, + "targetNodeId": 170, + "targetPortId": 1154, "travelTime": { "lock": true, - "time": 19, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 55, + "lock": false, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 295 + "consecutiveTime": 132 }, "sourceArrival": { - "lock": true, - "time": 5, + "lock": false, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 288 }, "targetDeparture": { - "lock": false, - "time": 46, + "lock": true, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 280 }, "targetArrival": { - "lock": false, - "time": 14, + "lock": true, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 140 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": 1726}, - {"x": 80, "y": 1662}, - {"x": 80, "y": 1314}, - {"x": 80, "y": 1250} + {"x": 2736, "y": 350}, + {"x": 2736, "y": 414}, + {"x": 2736, "y": 670}, + {"x": 2736, "y": 734} ], "textPositions": { - "0": {"x": 92, "y": 1708}, - "1": {"x": 68, "y": 1680}, - "2": {"x": 68, "y": 1268}, - "3": {"x": 92, "y": 1296}, - "4": {"x": 68, "y": 1488}, - "5": {"x": 68, "y": 1488}, - "6": {"x": 92, "y": 1488} + "0": {"x": 2724, "y": 368}, + "1": {"x": 2748, "y": 396}, + "2": {"x": 2748, "y": 716}, + "3": {"x": 2724, "y": 688}, + "4": {"x": 2724, "y": 542}, + "5": {"x": 2724, "y": 542}, + "6": {"x": 2748, "y": 542} } }, "warnings": null }, { - "id": 514, - "sourceNodeId": 141, - "sourcePortId": 1043, - "targetNodeId": 143, - "targetPortId": 1044, + "id": 570, + "sourceNodeId": 140, + "sourcePortId": 1155, + "targetNodeId": 215, + "targetPortId": 1513, "travelTime": { "lock": true, "time": 9, @@ -2222,446 +7422,446 @@ "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 14, + "lock": true, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 203 }, "sourceArrival": { - "lock": false, - "time": 46, + "lock": true, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 217 }, "targetDeparture": { - "lock": false, - "time": 37, + "lock": true, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 37 + "consecutiveTime": 208 }, "targetArrival": { - "lock": false, - "time": 23, + "lock": true, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 323 + "consecutiveTime": 212 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": 1182}, - {"x": 80, "y": 1118}, - {"x": 80, "y": 866}, - {"x": 80, "y": 802} + {"x": 4720, "y": 1278}, + {"x": 4720, "y": 1342}, + {"x": 4656, "y": 1470}, + {"x": 4656, "y": 1534} ], "textPositions": { - "0": {"x": 92, "y": 1164}, - "1": {"x": 68, "y": 1136}, - "2": {"x": 68, "y": 820}, - "3": {"x": 92, "y": 848}, - "4": {"x": 68, "y": 992}, - "5": {"x": 68, "y": 992}, - "6": {"x": 92, "y": 992} + "0": {"x": 4708, "y": 1296}, + "1": {"x": 4732, "y": 1324}, + "2": {"x": 4668, "y": 1516}, + "3": {"x": 4644, "y": 1488}, + "4": {"x": 4676, "y": 1406}, + "5": {"x": 4676, "y": 1406}, + "6": {"x": 4700, "y": 1406} } }, "warnings": null }, { - "id": 515, - "sourceNodeId": 143, - "sourcePortId": 1045, - "targetNodeId": 133, - "targetPortId": 1046, + "id": 571, + "sourceNodeId": 149, + "sourcePortId": 1158, + "targetNodeId": 216, + "targetPortId": 1515, "travelTime": { "lock": true, - "time": 7, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 23, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 323 + "consecutiveTime": 119 }, "sourceArrival": { "lock": false, - "time": 37, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 37 + "consecutiveTime": 301 }, "targetDeparture": { "lock": true, - "time": 30, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 30 + "consecutiveTime": 298 }, "targetArrival": { "lock": true, - "time": 30, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 122 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": 734}, - {"x": 80, "y": 670}, - {"x": 80, "y": 414}, - {"x": 80, "y": 350} + {"x": 2338, "y": 240}, + {"x": 2402, "y": 240}, + {"x": 2382, "y": 48}, + {"x": 2446, "y": 48} ], "textPositions": { - "0": {"x": 92, "y": 716}, - "1": {"x": 68, "y": 688}, - "2": {"x": 68, "y": 368}, - "3": {"x": 92, "y": 396}, - "4": {"x": 68, "y": 542}, - "5": {"x": 68, "y": 542}, - "6": {"x": 92, "y": 542} + "0": {"x": 2356, "y": 252}, + "1": {"x": 2384, "y": 228}, + "2": {"x": 2428, "y": 36}, + "3": {"x": 2400, "y": 60}, + "4": {"x": 2392, "y": 132}, + "5": {"x": 2392, "y": 132}, + "6": {"x": 2392, "y": 156} } - }, - "warnings": null - }, - { - "id": 516, - "sourceNodeId": 133, - "sourcePortId": 1047, - "targetNodeId": 144, - "targetPortId": 1048, + }, + "warnings": null + }, + { + "id": 572, + "sourceNodeId": 166, + "sourcePortId": 1160, + "targetNodeId": 149, + "targetPortId": 1159, "travelTime": { "lock": true, - "time": 10, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 32, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 332 + "consecutiveTime": 112 }, "sourceArrival": { - "lock": true, - "time": 28, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 28 + "consecutiveTime": 308 }, "targetDeparture": { "lock": false, - "time": 18, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 301 }, "targetArrival": { "lock": false, - "time": 42, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 342 + "consecutiveTime": 119 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": 94}, - {"x": 80, "y": 30}, - {"x": 80, "y": -290}, - {"x": 80, "y": -354} + {"x": 1890, "y": 240}, + {"x": 1954, "y": 240}, + {"x": 2174, "y": 240}, + {"x": 2238, "y": 240} ], "textPositions": { - "0": {"x": 92, "y": 76}, - "1": {"x": 68, "y": 48}, - "2": {"x": 68, "y": -336}, - "3": {"x": 92, "y": -308}, - "4": {"x": 68, "y": -130}, - "5": {"x": 68, "y": -130}, - "6": {"x": 92, "y": -130} + "0": {"x": 1908, "y": 252}, + "1": {"x": 1936, "y": 228}, + "2": {"x": 2220, "y": 228}, + "3": {"x": 2192, "y": 252}, + "4": {"x": 2064, "y": 228}, + "5": {"x": 2064, "y": 228}, + "6": {"x": 2064, "y": 252} } }, "warnings": null }, { - "id": 517, - "sourceNodeId": 144, - "sourcePortId": 1049, - "targetNodeId": 145, - "targetPortId": 1050, + "id": 573, + "sourceNodeId": 147, + "sourcePortId": 1162, + "targetNodeId": 148, + "targetPortId": 1161, "travelTime": { "lock": true, - "time": 5, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 42, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 342 + "consecutiveTime": 98 }, "sourceArrival": { "lock": false, - "time": 18, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 322 }, "targetDeparture": { "lock": false, - "time": 13, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 315 }, "targetArrival": { "lock": false, - "time": 47, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 105 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": -450}, - {"x": 80, "y": -514}, - {"x": 80, "y": -798}, - {"x": 80, "y": -862} + {"x": 1058, "y": 240}, + {"x": 1122, "y": 240}, + {"x": 1278, "y": 240}, + {"x": 1342, "y": 240} ], "textPositions": { - "0": {"x": 92, "y": -468}, - "1": {"x": 68, "y": -496}, - "2": {"x": 68, "y": -844}, - "3": {"x": 92, "y": -816}, - "4": {"x": 68, "y": -656}, - "5": {"x": 68, "y": -656}, - "6": {"x": 92, "y": -656} + "0": {"x": 1076, "y": 252}, + "1": {"x": 1104, "y": 228}, + "2": {"x": 1324, "y": 228}, + "3": {"x": 1296, "y": 252}, + "4": {"x": 1200, "y": 228}, + "5": {"x": 1200, "y": 228}, + "6": {"x": 1200, "y": 252} } }, "warnings": null }, { - "id": 518, - "sourceNodeId": 145, - "sourcePortId": 1051, - "targetNodeId": 146, - "targetPortId": 1052, + "id": 574, + "sourceNodeId": 133, + "sourcePortId": 1164, + "targetNodeId": 147, + "targetPortId": 1163, "travelTime": { "lock": true, - "time": 5, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 47, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 90 }, "sourceArrival": { - "lock": false, - "time": 13, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 330 }, "targetDeparture": { "lock": false, - "time": 8, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 8 + "consecutiveTime": 322 }, "targetArrival": { "lock": false, - "time": 52, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 352 + "consecutiveTime": 98 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": -930}, - {"x": 80, "y": -994}, - {"x": 80, "y": -1278}, - {"x": 80, "y": -1342} + {"x": 258, "y": 240}, + {"x": 322, "y": 240}, + {"x": 894, "y": 240}, + {"x": 958, "y": 240} ], "textPositions": { - "0": {"x": 92, "y": -948}, - "1": {"x": 68, "y": -976}, - "2": {"x": 68, "y": -1324}, - "3": {"x": 92, "y": -1296}, - "4": {"x": 68, "y": -1136}, - "5": {"x": 68, "y": -1136}, - "6": {"x": 92, "y": -1136} + "0": {"x": 276, "y": 252}, + "1": {"x": 304, "y": 228}, + "2": {"x": 940, "y": 228}, + "3": {"x": 912, "y": 252}, + "4": {"x": 608, "y": 228}, + "5": {"x": 608, "y": 228}, + "6": {"x": 608, "y": 252} } }, "warnings": null }, { - "id": 519, - "sourceNodeId": 146, - "sourcePortId": 1053, - "targetNodeId": 134, - "targetPortId": 1054, + "id": 575, + "sourceNodeId": 172, + "sourcePortId": 1166, + "targetNodeId": 133, + "targetPortId": 1165, "travelTime": { "lock": true, - "time": 5, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 52, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 352 + "consecutiveTime": 77 }, "sourceArrival": { "lock": false, - "time": 8, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 8 + "consecutiveTime": 343 }, "targetDeparture": { "lock": true, - "time": 3, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 3 + "consecutiveTime": 336 }, "targetArrival": { "lock": true, - "time": 57, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 357 + "consecutiveTime": 84 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 80, "y": -1410}, - {"x": 80, "y": -1474}, - {"x": 80, "y": -1758}, - {"x": 80, "y": -1822} + {"x": -510, "y": 304}, + {"x": -446, "y": 304}, + {"x": -2, "y": 304}, + {"x": 62, "y": 304} ], "textPositions": { - "0": {"x": 92, "y": -1428}, - "1": {"x": 68, "y": -1456}, - "2": {"x": 68, "y": -1804}, - "3": {"x": 92, "y": -1776}, - "4": {"x": 68, "y": -1616}, - "5": {"x": 68, "y": -1616}, - "6": {"x": 92, "y": -1616} + "0": {"x": -492, "y": 316}, + "1": {"x": -464, "y": 292}, + "2": {"x": 44, "y": 292}, + "3": {"x": 16, "y": 316}, + "4": {"x": -224, "y": 292}, + "5": {"x": -224, "y": 292}, + "6": {"x": -224, "y": 316} } }, "warnings": null }, { - "id": 520, - "sourceNodeId": 158, - "sourcePortId": 1056, - "targetNodeId": 155, - "targetPortId": 1055, + "id": 576, + "sourceNodeId": 137, + "sourcePortId": 1167, + "targetNodeId": 151, + "targetPortId": 1168, "travelTime": { "lock": true, - "time": 28, + "time": 33, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 24, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 204 + "consecutiveTime": 298 }, "sourceArrival": { "lock": false, - "time": 36, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 156 + "consecutiveTime": 242 }, "targetDeparture": { - "lock": true, - "time": 8, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 128 + "consecutiveTime": 209 }, "targetArrival": { - "lock": true, - "time": 52, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 232 + "consecutiveTime": 331 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 2686}, - {"x": 2704, "y": 2622}, - {"x": 2704, "y": 2334}, - {"x": 2704, "y": 2270} + {"x": 4638, "y": 112}, + {"x": 4574, "y": 112}, + {"x": 4034, "y": 176}, + {"x": 3970, "y": 176} ], "textPositions": { - "0": {"x": 2716, "y": 2668}, - "1": {"x": 2692, "y": 2640}, - "2": {"x": 2692, "y": 2288}, - "3": {"x": 2716, "y": 2316}, - "4": {"x": 2692, "y": 2478}, - "5": {"x": 2692, "y": 2478}, - "6": {"x": 2716, "y": 2478} + "0": {"x": 4620, "y": 100}, + "1": {"x": 4592, "y": 124}, + "2": {"x": 3988, "y": 188}, + "3": {"x": 4016, "y": 164}, + "4": {"x": 4304, "y": 132}, + "5": {"x": 4304, "y": 132}, + "6": {"x": 4304, "y": 156} } }, "warnings": null }, { - "id": 521, - "sourceNodeId": 156, - "sourcePortId": 1057, - "targetNodeId": 136, - "targetPortId": 1058, + "id": 577, + "sourceNodeId": 151, + "sourcePortId": 1169, + "targetNodeId": 150, + "targetPortId": 1170, "travelTime": { "lock": true, "time": 14, @@ -2670,321 +7870,327 @@ "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 2, + "lock": false, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 2 + "consecutiveTime": 333 }, "sourceArrival": { - "lock": true, - "time": 58, + "lock": false, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 118 + "consecutiveTime": 207 }, "targetDeparture": { - "lock": false, - "time": 44, + "lock": true, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 104 + "consecutiveTime": 193 }, "targetArrival": { - "lock": false, - "time": 16, + "lock": true, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 16 + "consecutiveTime": 347 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2608, "y": 3710}, - {"x": 2608, "y": 3646}, - {"x": 2608, "y": 3390}, - {"x": 2608, "y": 3326} + {"x": 3870, "y": 80}, + {"x": 3806, "y": 80}, + {"x": 3458, "y": 80}, + {"x": 3394, "y": 80} ], "textPositions": { - "0": {"x": 2620, "y": 3692}, - "1": {"x": 2596, "y": 3664}, - "2": {"x": 2596, "y": 3344}, - "3": {"x": 2620, "y": 3372}, - "4": {"x": 2596, "y": 3518}, - "5": {"x": 2596, "y": 3518}, - "6": {"x": 2620, "y": 3518} + "0": {"x": 3852, "y": 68}, + "1": {"x": 3824, "y": 92}, + "2": {"x": 3412, "y": 92}, + "3": {"x": 3440, "y": 68}, + "4": {"x": 3632, "y": 68}, + "5": {"x": 3632, "y": 68}, + "6": {"x": 3632, "y": 92} } }, "warnings": null }, { - "id": 522, - "sourceNodeId": 136, - "sourcePortId": 1059, - "targetNodeId": 158, - "targetPortId": 1060, + "id": 578, + "sourceNodeId": 150, + "sourcePortId": 1171, + "targetNodeId": 135, + "targetPortId": 1172, "travelTime": { "lock": true, - "time": 6, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 18, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 348 }, "sourceArrival": { "lock": true, - "time": 42, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 102 + "consecutiveTime": 192 }, "targetDeparture": { - "lock": false, - "time": 36, + "lock": true, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 96 + "consecutiveTime": 183 }, "targetArrival": { - "lock": false, - "time": 24, + "lock": true, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 24 + "consecutiveTime": 357 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2608, "y": 3230}, - {"x": 2608, "y": 3166}, - {"x": 2608, "y": 2818}, - {"x": 2608, "y": 2754} + {"x": 3294, "y": 80}, + {"x": 3230, "y": 80}, + {"x": 2914, "y": 80}, + {"x": 2850, "y": 80} ], "textPositions": { - "0": {"x": 2620, "y": 3212}, - "1": {"x": 2596, "y": 3184}, - "2": {"x": 2596, "y": 2772}, - "3": {"x": 2620, "y": 2800}, - "4": {"x": 2596, "y": 2992}, - "5": {"x": 2596, "y": 2992}, - "6": {"x": 2620, "y": 2992} + "0": {"x": 3276, "y": 68}, + "1": {"x": 3248, "y": 92}, + "2": {"x": 2868, "y": 92}, + "3": {"x": 2896, "y": 68}, + "4": {"x": 3072, "y": 68}, + "5": {"x": 3072, "y": 68}, + "6": {"x": 3072, "y": 92} } }, "warnings": null }, { - "id": 523, - "sourceNodeId": 158, - "sourcePortId": 1061, - "targetNodeId": 155, - "targetPortId": 1062, + "id": 579, + "sourceNodeId": 135, + "sourcePortId": 1173, + "targetNodeId": 149, + "targetPortId": 1174, "travelTime": { "lock": true, - "time": 28, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 24, + "lock": true, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 24 + "consecutiveTime": 364 }, "sourceArrival": { - "lock": false, - "time": 36, - "warning": null, + "lock": true, + "time": 56, + "warning": { + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 96 + "consecutiveTime": 176 }, "targetDeparture": { "lock": false, - "time": 8, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 170 }, "targetArrival": { "lock": false, - "time": 52, - "warning": null, + "time": 10, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 370 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 2686}, - {"x": 2672, "y": 2622}, - {"x": 2672, "y": 2334}, - {"x": 2672, "y": 2270} + {"x": 2654, "y": 144}, + {"x": 2590, "y": 144}, + {"x": 2402, "y": 144}, + {"x": 2338, "y": 144} ], "textPositions": { - "0": {"x": 2684, "y": 2668}, - "1": {"x": 2660, "y": 2640}, - "2": {"x": 2660, "y": 2288}, - "3": {"x": 2684, "y": 2316}, - "4": {"x": 2660, "y": 2478}, - "5": {"x": 2660, "y": 2478}, - "6": {"x": 2684, "y": 2478} + "0": {"x": 2636, "y": 132}, + "1": {"x": 2608, "y": 156}, + "2": {"x": 2356, "y": 156}, + "3": {"x": 2384, "y": 132}, + "4": {"x": 2496, "y": 132}, + "5": {"x": 2496, "y": 132}, + "6": {"x": 2496, "y": 156} } }, "warnings": null }, { - "id": 524, - "sourceNodeId": 155, - "sourcePortId": 1063, - "targetNodeId": 154, - "targetPortId": 1064, + "id": 580, + "sourceNodeId": 149, + "sourcePortId": 1175, + "targetNodeId": 166, + "targetPortId": 1176, "travelTime": { - "lock": false, - "time": 19, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 52, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 370 }, "sourceArrival": { "lock": false, - "time": 8, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 170 }, "targetDeparture": { - "lock": true, - "time": 49, + "lock": false, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 49 + "consecutiveTime": 163 }, "targetArrival": { - "lock": true, - "time": 11, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 71 + "consecutiveTime": 377 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 2174}, - {"x": 2672, "y": 2110}, - {"x": 2672, "y": 1950}, - {"x": 2672, "y": 1886} + {"x": 2238, "y": 144}, + {"x": 2174, "y": 144}, + {"x": 1954, "y": 144}, + {"x": 1890, "y": 144} ], "textPositions": { - "0": {"x": 2684, "y": 2156}, - "1": {"x": 2660, "y": 2128}, - "2": {"x": 2660, "y": 1904}, - "3": {"x": 2684, "y": 1932}, - "4": {"x": 2660, "y": 2030}, - "5": {"x": 2660, "y": 2030}, - "6": {"x": 2684, "y": 2030} + "0": {"x": 2220, "y": 132}, + "1": {"x": 2192, "y": 156}, + "2": {"x": 1908, "y": 156}, + "3": {"x": 1936, "y": 132}, + "4": {"x": 2064, "y": 132}, + "5": {"x": 2064, "y": 132}, + "6": {"x": 2064, "y": 156} } }, "warnings": null }, { - "id": 525, - "sourceNodeId": 154, - "sourcePortId": 1065, - "targetNodeId": 153, - "targetPortId": 1066, + "id": 581, + "sourceNodeId": 148, + "sourcePortId": 1177, + "targetNodeId": 147, + "targetPortId": 1178, "travelTime": { "lock": true, - "time": 15, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 15, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 75 + "consecutiveTime": 384 }, "sourceArrival": { - "lock": true, - "time": 45, + "lock": false, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 45 + "consecutiveTime": 156 }, "targetDeparture": { "lock": true, - "time": 30, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 30 + "consecutiveTime": 151 }, "targetArrival": { "lock": true, - "time": 30, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 389 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 1790}, - {"x": 2672, "y": 1726}, - {"x": 2672, "y": 1470}, - {"x": 2672, "y": 1406} + {"x": 1342, "y": 144}, + {"x": 1278, "y": 144}, + {"x": 1122, "y": 144}, + {"x": 1058, "y": 144} ], "textPositions": { - "0": {"x": 2684, "y": 1772}, - "1": {"x": 2660, "y": 1744}, - "2": {"x": 2660, "y": 1424}, - "3": {"x": 2684, "y": 1452}, - "4": {"x": 2660, "y": 1598}, - "5": {"x": 2660, "y": 1598}, - "6": {"x": 2684, "y": 1598} + "0": {"x": 1324, "y": 132}, + "1": {"x": 1296, "y": 156}, + "2": {"x": 1076, "y": 156}, + "3": {"x": 1104, "y": 132}, + "4": {"x": 1200, "y": 132}, + "5": {"x": 1200, "y": 132}, + "6": {"x": 1200, "y": 156} } }, "warnings": null }, { - "id": 526, - "sourceNodeId": 153, - "sourcePortId": 1067, - "targetNodeId": 170, - "targetPortId": 1068, + "id": 582, + "sourceNodeId": 147, + "sourcePortId": 1179, + "targetNodeId": 133, + "targetPortId": 1180, "travelTime": { "lock": true, - "time": 16, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 @@ -2994,2780 +8200,2798 @@ "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 91 + "consecutiveTime": 391 }, "sourceArrival": { "lock": true, "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 29 + "consecutiveTime": 149 }, "targetDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 140 }, "targetArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 107 + "consecutiveTime": 400 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 1310}, - {"x": 2672, "y": 1246}, - {"x": 2672, "y": 894}, - {"x": 2672, "y": 830} + {"x": 958, "y": 144}, + {"x": 894, "y": 144}, + {"x": 322, "y": 144}, + {"x": 258, "y": 144} ], "textPositions": { - "0": {"x": 2684, "y": 1292}, - "1": {"x": 2660, "y": 1264}, - "2": {"x": 2660, "y": 848}, - "3": {"x": 2684, "y": 876}, - "4": {"x": 2660, "y": 1070}, - "5": {"x": 2660, "y": 1070}, - "6": {"x": 2684, "y": 1070} + "0": {"x": 940, "y": 132}, + "1": {"x": 912, "y": 156}, + "2": {"x": 276, "y": 156}, + "3": {"x": 304, "y": 132}, + "4": {"x": 608, "y": 132}, + "5": {"x": 608, "y": 132}, + "6": {"x": 608, "y": 156} } }, "warnings": null }, { - "id": 527, - "sourceNodeId": 157, - "sourcePortId": 1069, - "targetNodeId": 136, - "targetPortId": 1070, + "id": 583, + "sourceNodeId": 133, + "sourcePortId": 1181, + "targetNodeId": 175, + "targetPortId": 1182, "travelTime": { "lock": true, - "time": 23, + "time": 17, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 33, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 273 + "consecutiveTime": 402 }, "sourceArrival": { "lock": true, - "time": 27, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 327 + "consecutiveTime": 138 }, "targetDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 304 + "consecutiveTime": 121 }, "targetArrival": { - "lock": true, - "time": 56, + "lock": false, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 296 + "consecutiveTime": 419 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2306, "y": 3248}, - {"x": 2370, "y": 3248}, - {"x": 2526, "y": 3248}, - {"x": 2590, "y": 3248} + {"x": 62, "y": 112}, + {"x": -2, "y": 112}, + {"x": -1534, "y": -16}, + {"x": -1598, "y": -16} ], "textPositions": { - "0": {"x": 2324, "y": 3260}, - "1": {"x": 2352, "y": 3236}, - "2": {"x": 2572, "y": 3236}, - "3": {"x": 2544, "y": 3260}, - "4": {"x": 2448, "y": 3236}, - "5": {"x": 2448, "y": 3236}, - "6": {"x": 2448, "y": 3260} + "0": {"x": 44, "y": 100}, + "1": {"x": 16, "y": 124}, + "2": {"x": -1580, "y": -4}, + "3": {"x": -1552, "y": -28}, + "4": {"x": -768, "y": 36}, + "5": {"x": -768, "y": 36}, + "6": {"x": -768, "y": 60} } }, "warnings": null }, { - "id": 528, - "sourceNodeId": 136, - "sourcePortId": 1071, - "targetNodeId": 158, - "targetPortId": 1072, + "id": 584, + "sourceNodeId": 130, + "sourcePortId": 1183, + "targetNodeId": 217, + "targetPortId": 1517, "travelTime": { - "lock": true, - "time": 15, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 0, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 300 + "consecutiveTime": 437 }, "sourceArrival": { "lock": true, - "time": 0, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 300 + "consecutiveTime": 103 }, "targetDeparture": { "lock": true, - "time": 45, - "warning": null, + "time": 13, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 285 + "consecutiveTime": 73 }, "targetArrival": { "lock": true, - "time": 15, - "warning": null, + "time": 47, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 315 + "consecutiveTime": 467 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 3230}, - {"x": 2672, "y": 3166}, - {"x": 2672, "y": 2818}, - {"x": 2672, "y": 2754} + {"x": -2530, "y": -16}, + {"x": -2594, "y": -16}, + {"x": -2862, "y": 272}, + {"x": -2926, "y": 272} ], "textPositions": { - "0": {"x": 2684, "y": 3212}, - "1": {"x": 2660, "y": 3184}, - "2": {"x": 2660, "y": 2772}, - "3": {"x": 2684, "y": 2800}, - "4": {"x": 2660, "y": 2992}, - "5": {"x": 2660, "y": 2992}, - "6": {"x": 2684, "y": 2992} + "0": {"x": -2548, "y": -28}, + "1": {"x": -2576, "y": -4}, + "2": {"x": -2908, "y": 284}, + "3": {"x": -2880, "y": 260}, + "4": {"x": -2728, "y": 116}, + "5": {"x": -2728, "y": 116}, + "6": {"x": -2728, "y": 140} } }, "warnings": null }, { - "id": 529, - "sourceNodeId": 158, - "sourcePortId": 1073, - "targetNodeId": 159, - "targetPortId": 1074, + "id": 585, + "sourceNodeId": 160, + "sourcePortId": 1185, + "targetNodeId": 161, + "targetPortId": 1186, "travelTime": { "lock": true, - "time": 53, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 16, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 316 + "consecutiveTime": 528 }, "sourceArrival": { "lock": true, - "time": 44, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 284 + "consecutiveTime": 12 }, "targetDeparture": { - "lock": true, - "time": 51, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 231 + "consecutiveTime": 4 }, "targetArrival": { - "lock": true, - "time": 9, + "lock": false, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 369 + "consecutiveTime": 536 }, - "numberOfStops": 5, - "trainrunId": 77, + "numberOfStops": 0, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2608, "y": 2686}, - {"x": 2608, "y": 2622}, - {"x": 2288, "y": 2398}, - {"x": 2288, "y": 2334} - ], - "textPositions": { - "0": {"x": 2620, "y": 2668}, - "1": {"x": 2596, "y": 2640}, - "2": {"x": 2276, "y": 2352}, - "3": {"x": 2300, "y": 2380}, - "4": {"x": 2460, "y": 2510}, - "5": {"x": 2460, "y": 2510}, - "6": {"x": 2436, "y": 2510} + {"x": -3938, "y": 656}, + {"x": -4002, "y": 656}, + {"x": -4190, "y": 656}, + {"x": -4254, "y": 656} + ], + "textPositions": { + "0": {"x": -3956, "y": 644}, + "1": {"x": -3984, "y": 668}, + "2": {"x": -4236, "y": 668}, + "3": {"x": -4208, "y": 644}, + "4": {"x": -4096, "y": 644}, + "5": {"x": -4096, "y": 644}, + "6": {"x": -4096, "y": 668} } }, "warnings": null }, { - "id": 530, - "sourceNodeId": 159, - "sourcePortId": 1075, - "targetNodeId": 155, - "targetPortId": 1076, + "id": 586, + "sourceNodeId": 128, + "sourcePortId": 1187, + "targetNodeId": 177, + "targetPortId": 1188, "travelTime": { - "lock": true, - "time": 32, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 10, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 370 + "consecutiveTime": 439 }, "sourceArrival": { "lock": true, - "time": 50, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 230 + "consecutiveTime": 101 }, "targetDeparture": { - "lock": false, - "time": 18, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 198 + "consecutiveTime": 90 }, "targetArrival": { - "lock": false, - "time": 42, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 402 + "consecutiveTime": 450 }, - "numberOfStops": 1, - "trainrunId": 77, + "numberOfStops": 0, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2370, "y": 2256}, - {"x": 2434, "y": 2256}, - {"x": 2590, "y": 2192}, - {"x": 2654, "y": 2192} + {"x": -3074, "y": 592}, + {"x": -3138, "y": 592}, + {"x": -3358, "y": 624}, + {"x": -3422, "y": 624} ], "textPositions": { - "0": {"x": 2388, "y": 2268}, - "1": {"x": 2416, "y": 2244}, - "2": {"x": 2636, "y": 2180}, - "3": {"x": 2608, "y": 2204}, - "4": {"x": 2512, "y": 2212}, - "5": {"x": 2512, "y": 2212}, - "6": {"x": 2512, "y": 2236} + "0": {"x": -3092, "y": 580}, + "1": {"x": -3120, "y": 604}, + "2": {"x": -3404, "y": 636}, + "3": {"x": -3376, "y": 612}, + "4": {"x": -3248, "y": 596}, + "5": {"x": -3248, "y": 596}, + "6": {"x": -3248, "y": 620} } }, "warnings": null }, { - "id": 531, - "sourceNodeId": 155, - "sourcePortId": 1077, - "targetNodeId": 154, - "targetPortId": 1078, + "id": 587, + "sourceNodeId": 160, + "sourcePortId": 1189, + "targetNodeId": 161, + "targetPortId": 1190, "travelTime": { - "lock": true, - "time": 23, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 43, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 403 + "consecutiveTime": 484 }, "sourceArrival": { "lock": true, - "time": 17, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 197 + "consecutiveTime": 56 }, "targetDeparture": { "lock": true, - "time": 54, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 174 + "consecutiveTime": 48 }, "targetArrival": { "lock": true, - "time": 6, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 426 + "consecutiveTime": 492 }, - "numberOfStops": 3, - "trainrunId": 77, + "numberOfStops": 0, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2736, "y": 2174}, - {"x": 2736, "y": 2110}, - {"x": 2736, "y": 1950}, - {"x": 2736, "y": 1886} + {"x": -3938, "y": 688}, + {"x": -4002, "y": 688}, + {"x": -4190, "y": 688}, + {"x": -4254, "y": 688} ], "textPositions": { - "0": {"x": 2748, "y": 2156}, - "1": {"x": 2724, "y": 2128}, - "2": {"x": 2724, "y": 1904}, - "3": {"x": 2748, "y": 1932}, - "4": {"x": 2724, "y": 2030}, - "5": {"x": 2724, "y": 2030}, - "6": {"x": 2748, "y": 2030} + "0": {"x": -3956, "y": 676}, + "1": {"x": -3984, "y": 700}, + "2": {"x": -4236, "y": 700}, + "3": {"x": -4208, "y": 676}, + "4": {"x": -4096, "y": 676}, + "5": {"x": -4096, "y": 676}, + "6": {"x": -4096, "y": 700} } }, "warnings": null }, { - "id": 532, - "sourceNodeId": 154, - "sourcePortId": 1079, - "targetNodeId": 169, - "targetPortId": 1080, + "id": 588, + "sourceNodeId": 150, + "sourcePortId": 1192, + "targetNodeId": 219, + "targetPortId": 1521, "travelTime": { "lock": true, - "time": 18, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 15, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 435 + "consecutiveTime": 309 }, "sourceArrival": { "lock": true, - "time": 45, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 165 + "consecutiveTime": 231 }, "targetDeparture": { - "lock": false, - "time": 27, - "warning": null, + "lock": true, + "time": 46, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 147 + "consecutiveTime": 226 }, "targetArrival": { - "lock": false, - "time": 33, - "warning": null, + "lock": true, + "time": 14, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 453 + "consecutiveTime": 314 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2654, "y": 1840}, - {"x": 2590, "y": 1840}, - {"x": 2018, "y": 1840}, - {"x": 1954, "y": 1840} + {"x": 3294, "y": 48}, + {"x": 3230, "y": 48}, + {"x": 3138, "y": 48}, + {"x": 3074, "y": 48} ], "textPositions": { - "0": {"x": 2636, "y": 1828}, - "1": {"x": 2608, "y": 1852}, - "2": {"x": 1972, "y": 1852}, - "3": {"x": 2000, "y": 1828}, - "4": {"x": 2304, "y": 1828}, - "5": {"x": 2304, "y": 1828}, - "6": {"x": 2304, "y": 1852} + "0": {"x": 3276, "y": 36}, + "1": {"x": 3248, "y": 60}, + "2": {"x": 3092, "y": 60}, + "3": {"x": 3120, "y": 36}, + "4": {"x": 3184, "y": 36}, + "5": {"x": 3184, "y": 36}, + "6": {"x": 3184, "y": 60} } }, "warnings": null }, { - "id": 533, - "sourceNodeId": 157, - "sourcePortId": 1081, - "targetNodeId": 136, - "targetPortId": 1082, + "id": 589, + "sourceNodeId": 151, + "sourcePortId": 1194, + "targetNodeId": 150, + "targetPortId": 1193, "travelTime": { "lock": true, - "time": 23, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 33, + "lock": false, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 153 + "consecutiveTime": 294 }, "sourceArrival": { - "lock": true, - "time": 27, + "lock": false, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 207 + "consecutiveTime": 246 }, "targetDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 184 + "consecutiveTime": 233 }, "targetArrival": { - "lock": true, - "time": 56, + "lock": false, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 176 + "consecutiveTime": 307 }, - "numberOfStops": 3, - "trainrunId": 78, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2306, "y": 3280}, - {"x": 2370, "y": 3280}, - {"x": 2526, "y": 3280}, - {"x": 2590, "y": 3280} + {"x": 3870, "y": 48}, + {"x": 3806, "y": 48}, + {"x": 3458, "y": 48}, + {"x": 3394, "y": 48} ], "textPositions": { - "0": {"x": 2324, "y": 3292}, - "1": {"x": 2352, "y": 3268}, - "2": {"x": 2572, "y": 3268}, - "3": {"x": 2544, "y": 3292}, - "4": {"x": 2448, "y": 3268}, - "5": {"x": 2448, "y": 3268}, - "6": {"x": 2448, "y": 3292} + "0": {"x": 3852, "y": 36}, + "1": {"x": 3824, "y": 60}, + "2": {"x": 3412, "y": 60}, + "3": {"x": 3440, "y": 36}, + "4": {"x": 3632, "y": 36}, + "5": {"x": 3632, "y": 36}, + "6": {"x": 3632, "y": 60} } }, "warnings": null }, { - "id": 534, - "sourceNodeId": 136, - "sourcePortId": 1083, - "targetNodeId": 158, - "targetPortId": 1084, + "id": 590, + "sourceNodeId": 135, + "sourcePortId": 1195, + "targetNodeId": 149, + "targetPortId": 1196, "travelTime": { "lock": true, - "time": 15, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 0, + "lock": false, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 180 + "consecutiveTime": 346 }, "sourceArrival": { - "lock": true, - "time": 0, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 180 + "consecutiveTime": 194 }, "targetDeparture": { - "lock": true, - "time": 45, + "lock": false, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 165 + "consecutiveTime": 189 }, "targetArrival": { - "lock": true, - "time": 15, + "lock": false, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 195 + "consecutiveTime": 351 }, - "numberOfStops": 1, - "trainrunId": 78, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 3230}, - {"x": 2704, "y": 3166}, - {"x": 2704, "y": 2818}, - {"x": 2704, "y": 2754} + {"x": 2654, "y": 48}, + {"x": 2590, "y": 48}, + {"x": 2402, "y": 48}, + {"x": 2338, "y": 48} ], "textPositions": { - "0": {"x": 2716, "y": 3212}, - "1": {"x": 2692, "y": 3184}, - "2": {"x": 2692, "y": 2772}, - "3": {"x": 2716, "y": 2800}, - "4": {"x": 2692, "y": 2992}, - "5": {"x": 2692, "y": 2992}, - "6": {"x": 2716, "y": 2992} + "0": {"x": 2636, "y": 36}, + "1": {"x": 2608, "y": 60}, + "2": {"x": 2356, "y": 60}, + "3": {"x": 2384, "y": 36}, + "4": {"x": 2496, "y": 36}, + "5": {"x": 2496, "y": 36}, + "6": {"x": 2496, "y": 60} } }, "warnings": null }, { - "id": 535, - "sourceNodeId": 158, - "sourcePortId": 1085, - "targetNodeId": 159, - "targetPortId": 1086, + "id": 591, + "sourceNodeId": 149, + "sourcePortId": 1197, + "targetNodeId": 166, + "targetPortId": 1198, "travelTime": { "lock": true, - "time": 53, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 16, + "lock": false, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 196 + "consecutiveTime": 351 }, "sourceArrival": { - "lock": true, - "time": 44, + "lock": false, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 164 + "consecutiveTime": 189 }, "targetDeparture": { - "lock": true, - "time": 51, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 111 + "consecutiveTime": 184 }, "targetArrival": { - "lock": true, - "time": 9, + "lock": false, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 249 + "consecutiveTime": 356 }, - "numberOfStops": 5, - "trainrunId": 78, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2640, "y": 2686}, - {"x": 2640, "y": 2622}, - {"x": 2320, "y": 2398}, - {"x": 2320, "y": 2334} + {"x": 2238, "y": 48}, + {"x": 2174, "y": 48}, + {"x": 1954, "y": 48}, + {"x": 1890, "y": 48} ], "textPositions": { - "0": {"x": 2652, "y": 2668}, - "1": {"x": 2628, "y": 2640}, - "2": {"x": 2308, "y": 2352}, - "3": {"x": 2332, "y": 2380}, - "4": {"x": 2492, "y": 2510}, - "5": {"x": 2492, "y": 2510}, - "6": {"x": 2468, "y": 2510} + "0": {"x": 2220, "y": 36}, + "1": {"x": 2192, "y": 60}, + "2": {"x": 1908, "y": 60}, + "3": {"x": 1936, "y": 36}, + "4": {"x": 2064, "y": 36}, + "5": {"x": 2064, "y": 36}, + "6": {"x": 2064, "y": 60} } }, "warnings": null }, { - "id": 536, - "sourceNodeId": 159, - "sourcePortId": 1087, - "targetNodeId": 155, - "targetPortId": 1088, + "id": 592, + "sourceNodeId": 148, + "sourcePortId": 1199, + "targetNodeId": 147, + "targetPortId": 1200, "travelTime": { "lock": true, - "time": 32, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 10, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 250 + "consecutiveTime": 361 }, "sourceArrival": { - "lock": true, - "time": 50, + "lock": false, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 110 + "consecutiveTime": 179 }, "targetDeparture": { - "lock": true, - "time": 18, + "lock": false, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 78 + "consecutiveTime": 175 }, "targetArrival": { - "lock": true, - "time": 42, + "lock": false, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 282 + "consecutiveTime": 365 }, - "numberOfStops": 1, - "trainrunId": 78, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2370, "y": 2288}, - {"x": 2434, "y": 2288}, - {"x": 2590, "y": 2224}, - {"x": 2654, "y": 2224} + {"x": 1342, "y": 48}, + {"x": 1278, "y": 48}, + {"x": 1122, "y": 48}, + {"x": 1058, "y": 48} ], "textPositions": { - "0": {"x": 2388, "y": 2300}, - "1": {"x": 2416, "y": 2276}, - "2": {"x": 2636, "y": 2212}, - "3": {"x": 2608, "y": 2236}, - "4": {"x": 2512, "y": 2244}, - "5": {"x": 2512, "y": 2244}, - "6": {"x": 2512, "y": 2268} + "0": {"x": 1324, "y": 36}, + "1": {"x": 1296, "y": 60}, + "2": {"x": 1076, "y": 60}, + "3": {"x": 1104, "y": 36}, + "4": {"x": 1200, "y": 36}, + "5": {"x": 1200, "y": 36}, + "6": {"x": 1200, "y": 60} } }, "warnings": null }, { - "id": 537, - "sourceNodeId": 155, - "sourcePortId": 1089, - "targetNodeId": 154, - "targetPortId": 1090, + "id": 593, + "sourceNodeId": 147, + "sourcePortId": 1201, + "targetNodeId": 133, + "targetPortId": 1202, "travelTime": { - "lock": false, - "time": 23, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 43, + "lock": false, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 283 + "consecutiveTime": 365 }, "sourceArrival": { - "lock": true, - "time": 17, + "lock": false, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 77 + "consecutiveTime": 175 }, "targetDeparture": { - "lock": true, - "time": 54, + "lock": false, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 54 + "consecutiveTime": 170 }, "targetArrival": { - "lock": true, - "time": 6, + "lock": false, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 306 + "consecutiveTime": 370 }, - "numberOfStops": 3, - "trainrunId": 78, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2768, "y": 2174}, - {"x": 2768, "y": 2110}, - {"x": 2768, "y": 1950}, - {"x": 2768, "y": 1886} + {"x": 958, "y": 112}, + {"x": 894, "y": 112}, + {"x": 322, "y": 112}, + {"x": 258, "y": 112} ], "textPositions": { - "0": {"x": 2780, "y": 2156}, - "1": {"x": 2756, "y": 2128}, - "2": {"x": 2756, "y": 1904}, - "3": {"x": 2780, "y": 1932}, - "4": {"x": 2756, "y": 2030}, - "5": {"x": 2756, "y": 2030}, - "6": {"x": 2780, "y": 2030} + "0": {"x": 940, "y": 100}, + "1": {"x": 912, "y": 124}, + "2": {"x": 276, "y": 124}, + "3": {"x": 304, "y": 100}, + "4": {"x": 608, "y": 100}, + "5": {"x": 608, "y": 100}, + "6": {"x": 608, "y": 124} } }, "warnings": null }, { - "id": 538, - "sourceNodeId": 154, - "sourcePortId": 1091, - "targetNodeId": 153, - "targetPortId": 1092, + "id": 594, + "sourceNodeId": 133, + "sourcePortId": 1203, + "targetNodeId": 172, + "targetPortId": 1204, "travelTime": { "lock": true, - "time": 15, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 15, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 315 + "consecutiveTime": 370 }, "sourceArrival": { "lock": false, - "time": 45, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 45 + "consecutiveTime": 170 }, "targetDeparture": { - "lock": true, - "time": 30, + "lock": false, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 30 + "consecutiveTime": 163 }, "targetArrival": { - "lock": true, - "time": 30, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 377 }, "numberOfStops": 0, - "trainrunId": 78, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 1790}, - {"x": 2704, "y": 1726}, - {"x": 2704, "y": 1470}, - {"x": 2704, "y": 1406} - ], - "textPositions": { - "0": {"x": 2716, "y": 1772}, - "1": {"x": 2692, "y": 1744}, - "2": {"x": 2692, "y": 1424}, - "3": {"x": 2716, "y": 1452}, - "4": {"x": 2692, "y": 1598}, - "5": {"x": 2692, "y": 1598}, - "6": {"x": 2716, "y": 1598} + {"x": 62, "y": 144}, + {"x": -2, "y": 144}, + {"x": -446, "y": 144}, + {"x": -510, "y": 144} + ], + "textPositions": { + "0": {"x": 44, "y": 132}, + "1": {"x": 16, "y": 156}, + "2": {"x": -492, "y": 156}, + "3": {"x": -464, "y": 132}, + "4": {"x": -224, "y": 132}, + "5": {"x": -224, "y": 132}, + "6": {"x": -224, "y": 156} } }, "warnings": null }, { - "id": 539, - "sourceNodeId": 153, - "sourcePortId": 1093, - "targetNodeId": 170, - "targetPortId": 1094, + "id": 595, + "sourceNodeId": 129, + "sourcePortId": 1205, + "targetNodeId": 171, + "targetPortId": 1206, "travelTime": { "lock": true, - "time": 16, + "time": 22, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 31, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 331 + "consecutiveTime": 390 }, "sourceArrival": { - "lock": true, - "time": 29, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 29 + "consecutiveTime": 150 }, "targetDeparture": { "lock": false, - "time": 13, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 128 }, "targetArrival": { "lock": false, - "time": 47, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 412 }, "numberOfStops": 0, - "trainrunId": 78, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 1310}, - {"x": 2704, "y": 1246}, - {"x": 2704, "y": 894}, - {"x": 2704, "y": 830} + {"x": -2146, "y": 144}, + {"x": -2210, "y": 144}, + {"x": -2398, "y": 304}, + {"x": -2462, "y": 304} ], "textPositions": { - "0": {"x": 2716, "y": 1292}, - "1": {"x": 2692, "y": 1264}, - "2": {"x": 2692, "y": 848}, - "3": {"x": 2716, "y": 876}, - "4": {"x": 2692, "y": 1070}, - "5": {"x": 2692, "y": 1070}, - "6": {"x": 2716, "y": 1070} + "0": {"x": -2164, "y": 132}, + "1": {"x": -2192, "y": 156}, + "2": {"x": -2444, "y": 316}, + "3": {"x": -2416, "y": 292}, + "4": {"x": -2304, "y": 212}, + "5": {"x": -2304, "y": 212}, + "6": {"x": -2304, "y": 236} } }, "warnings": null }, { - "id": 540, - "sourceNodeId": 142, - "sourcePortId": 1095, - "targetNodeId": 169, - "targetPortId": 1096, + "id": 596, + "sourceNodeId": 128, + "sourcePortId": 1207, + "targetNodeId": 177, + "targetPortId": 1208, "travelTime": { - "lock": false, - "time": 12, + "lock": true, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 35, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 463 }, "sourceArrival": { "lock": true, - "time": 25, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 265 + "consecutiveTime": 77 }, "targetDeparture": { - "lock": true, - "time": 13, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 253 + "consecutiveTime": 68 }, "targetArrival": { - "lock": true, - "time": 47, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 47 + "consecutiveTime": 472 }, "numberOfStops": 0, - "trainrunId": 79, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 226, "y": 1840}, - {"x": 290, "y": 1840}, - {"x": 1790, "y": 1840}, - {"x": 1854, "y": 1840} + {"x": -3074, "y": 560}, + {"x": -3138, "y": 560}, + {"x": -3358, "y": 592}, + {"x": -3422, "y": 592} ], "textPositions": { - "0": {"x": 244, "y": 1852}, - "1": {"x": 272, "y": 1828}, - "2": {"x": 1836, "y": 1828}, - "3": {"x": 1808, "y": 1852}, - "4": {"x": 1040, "y": 1828}, - "5": {"x": 1040, "y": 1828}, - "6": {"x": 1040, "y": 1852} + "0": {"x": -3092, "y": 548}, + "1": {"x": -3120, "y": 572}, + "2": {"x": -3404, "y": 604}, + "3": {"x": -3376, "y": 580}, + "4": {"x": -3248, "y": 564}, + "5": {"x": -3248, "y": 564}, + "6": {"x": -3248, "y": 588} } }, "warnings": null }, { - "id": 541, - "sourceNodeId": 153, - "sourcePortId": 1097, - "targetNodeId": 170, - "targetPortId": 1098, + "id": 597, + "sourceNodeId": 160, + "sourcePortId": 1209, + "targetNodeId": 161, + "targetPortId": 1210, "travelTime": { - "lock": false, - "time": 15, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 58, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 58 + "consecutiveTime": 501 }, "sourceArrival": { "lock": true, - "time": 2, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 242 + "consecutiveTime": 39 }, "targetDeparture": { "lock": true, - "time": 47, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 227 + "consecutiveTime": 32 }, "targetArrival": { "lock": true, - "time": 13, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 73 + "consecutiveTime": 508 }, - "numberOfStops": 1, - "trainrunId": 79, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2768, "y": 1310}, - {"x": 2768, "y": 1246}, - {"x": 2768, "y": 894}, - {"x": 2768, "y": 830} + {"x": -3938, "y": 624}, + {"x": -4002, "y": 624}, + {"x": -4190, "y": 624}, + {"x": -4254, "y": 624} ], "textPositions": { - "0": {"x": 2780, "y": 1292}, - "1": {"x": 2756, "y": 1264}, - "2": {"x": 2756, "y": 848}, - "3": {"x": 2780, "y": 876}, - "4": {"x": 2756, "y": 1070}, - "5": {"x": 2756, "y": 1070}, - "6": {"x": 2780, "y": 1070} + "0": {"x": -3956, "y": 612}, + "1": {"x": -3984, "y": 636}, + "2": {"x": -4236, "y": 636}, + "3": {"x": -4208, "y": 612}, + "4": {"x": -4096, "y": 612}, + "5": {"x": -4096, "y": 612}, + "6": {"x": -4096, "y": 636} } }, "warnings": null }, { - "id": 542, - "sourceNodeId": 142, - "sourcePortId": 1099, - "targetNodeId": 169, - "targetPortId": 1100, + "id": 598, + "sourceNodeId": 137, + "sourcePortId": 1212, + "targetNodeId": 220, + "targetPortId": 1523, "travelTime": { - "lock": true, - "time": 9, + "lock": false, + "time": 22, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 9, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 9 + "consecutiveTime": 248 }, "sourceArrival": { - "lock": true, - "time": 51, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 51 + "consecutiveTime": 292 }, "targetDeparture": { - "lock": false, - "time": 42, - "warning": null, + "lock": true, + "time": 30, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 42 + "consecutiveTime": 270 }, "targetArrival": { - "lock": false, - "time": 18, - "warning": null, + "lock": true, + "time": 30, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 270 }, "numberOfStops": 0, - "trainrunId": 80, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 226, "y": 1808}, - {"x": 290, "y": 1808}, - {"x": 1790, "y": 1808}, - {"x": 1854, "y": 1808} + {"x": 4638, "y": 144}, + {"x": 4574, "y": 144}, + {"x": 4418, "y": 80}, + {"x": 4354, "y": 80} ], "textPositions": { - "0": {"x": 244, "y": 1820}, - "1": {"x": 272, "y": 1796}, - "2": {"x": 1836, "y": 1796}, - "3": {"x": 1808, "y": 1820}, - "4": {"x": 1040, "y": 1796}, - "5": {"x": 1040, "y": 1796}, - "6": {"x": 1040, "y": 1820} + "0": {"x": 4620, "y": 132}, + "1": {"x": 4592, "y": 156}, + "2": {"x": 4372, "y": 92}, + "3": {"x": 4400, "y": 68}, + "4": {"x": 4496, "y": 100}, + "5": {"x": 4496, "y": 100}, + "6": {"x": 4496, "y": 124} } }, "warnings": null }, { - "id": 543, - "sourceNodeId": 153, - "sourcePortId": 1101, - "targetNodeId": 170, - "targetPortId": 1102, + "id": 599, + "sourceNodeId": 135, + "sourcePortId": 1213, + "targetNodeId": 150, + "targetPortId": 1214, "travelTime": { "lock": true, - "time": 14, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 29, + "lock": false, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 29 + "consecutiveTime": 125 }, "sourceArrival": { - "lock": true, - "time": 31, + "lock": false, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 31 + "consecutiveTime": 295 }, "targetDeparture": { "lock": false, - "time": 17, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 17 + "consecutiveTime": 286 }, "targetArrival": { "lock": false, - "time": 43, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 43 + "consecutiveTime": 134 }, "numberOfStops": 0, - "trainrunId": 80, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2736, "y": 1310}, - {"x": 2736, "y": 1246}, - {"x": 2736, "y": 894}, - {"x": 2736, "y": 830} + {"x": 2850, "y": 112}, + {"x": 2914, "y": 112}, + {"x": 3230, "y": 112}, + {"x": 3294, "y": 112} ], "textPositions": { - "0": {"x": 2748, "y": 1292}, - "1": {"x": 2724, "y": 1264}, - "2": {"x": 2724, "y": 848}, - "3": {"x": 2748, "y": 876}, - "4": {"x": 2724, "y": 1070}, - "5": {"x": 2724, "y": 1070}, - "6": {"x": 2748, "y": 1070} + "0": {"x": 2868, "y": 124}, + "1": {"x": 2896, "y": 100}, + "2": {"x": 3276, "y": 100}, + "3": {"x": 3248, "y": 124}, + "4": {"x": 3072, "y": 100}, + "5": {"x": 3072, "y": 100}, + "6": {"x": 3072, "y": 124} } }, "warnings": null }, { - "id": 544, - "sourceNodeId": 142, - "sourcePortId": 1103, - "targetNodeId": 141, - "targetPortId": 1104, + "id": 600, + "sourceNodeId": 150, + "sourcePortId": 1215, + "targetNodeId": 151, + "targetPortId": 1216, "travelTime": { "lock": true, - "time": 19, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 59, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 299 + "consecutiveTime": 136 }, "sourceArrival": { "lock": false, - "time": 1, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 241 + "consecutiveTime": 284 }, "targetDeparture": { - "lock": true, - "time": 42, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 222 + "consecutiveTime": 271 }, "targetArrival": { - "lock": true, - "time": 18, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 318 + "consecutiveTime": 149 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": 1726}, - {"x": 112, "y": 1662}, - {"x": 112, "y": 1314}, - {"x": 112, "y": 1250} + {"x": 3394, "y": 112}, + {"x": 3458, "y": 112}, + {"x": 3806, "y": 112}, + {"x": 3870, "y": 112} ], "textPositions": { - "0": {"x": 124, "y": 1708}, - "1": {"x": 100, "y": 1680}, - "2": {"x": 100, "y": 1268}, - "3": {"x": 124, "y": 1296}, - "4": {"x": 100, "y": 1488}, - "5": {"x": 100, "y": 1488}, - "6": {"x": 124, "y": 1488} + "0": {"x": 3412, "y": 124}, + "1": {"x": 3440, "y": 100}, + "2": {"x": 3852, "y": 100}, + "3": {"x": 3824, "y": 124}, + "4": {"x": 3632, "y": 100}, + "5": {"x": 3632, "y": 100}, + "6": {"x": 3632, "y": 124} } }, "warnings": null }, { - "id": 545, - "sourceNodeId": 141, - "sourcePortId": 1105, - "targetNodeId": 143, - "targetPortId": 1106, + "id": 601, + "sourceNodeId": 149, + "sourcePortId": 1218, + "targetNodeId": 135, + "targetPortId": 1217, "travelTime": { "lock": true, - "time": 12, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 19, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 319 + "consecutiveTime": 112 }, "sourceArrival": { - "lock": true, - "time": 41, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 221 + "consecutiveTime": 308 }, "targetDeparture": { "lock": true, - "time": 29, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 209 + "consecutiveTime": 302 }, "targetArrival": { "lock": true, - "time": 31, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 331 + "consecutiveTime": 118 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": 1182}, - {"x": 112, "y": 1118}, - {"x": 112, "y": 866}, - {"x": 112, "y": 802} + {"x": 2338, "y": 176}, + {"x": 2402, "y": 176}, + {"x": 2590, "y": 176}, + {"x": 2654, "y": 176} ], "textPositions": { - "0": {"x": 124, "y": 1164}, - "1": {"x": 100, "y": 1136}, - "2": {"x": 100, "y": 820}, - "3": {"x": 124, "y": 848}, - "4": {"x": 100, "y": 992}, - "5": {"x": 100, "y": 992}, - "6": {"x": 124, "y": 992} + "0": {"x": 2356, "y": 188}, + "1": {"x": 2384, "y": 164}, + "2": {"x": 2636, "y": 164}, + "3": {"x": 2608, "y": 188}, + "4": {"x": 2496, "y": 164}, + "5": {"x": 2496, "y": 164}, + "6": {"x": 2496, "y": 188} } }, "warnings": null }, { - "id": 546, - "sourceNodeId": 143, - "sourcePortId": 1107, - "targetNodeId": 172, - "targetPortId": 1108, + "id": 602, + "sourceNodeId": 166, + "sourcePortId": 1220, + "targetNodeId": 149, + "targetPortId": 1219, "travelTime": { "lock": true, - "time": 7, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 32, + "lock": false, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 332 + "consecutiveTime": 106 }, "sourceArrival": { - "lock": true, - "time": 28, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 208 + "consecutiveTime": 314 }, "targetDeparture": { "lock": false, - "time": 21, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 201 + "consecutiveTime": 308 }, "targetArrival": { "lock": false, - "time": 39, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 339 + "consecutiveTime": 112 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 62, "y": 752}, - {"x": -2, "y": 752}, - {"x": -446, "y": 336}, - {"x": -510, "y": 336} + {"x": 1890, "y": 176}, + {"x": 1954, "y": 176}, + {"x": 2174, "y": 176}, + {"x": 2238, "y": 176} ], "textPositions": { - "0": {"x": 44, "y": 740}, - "1": {"x": 16, "y": 764}, - "2": {"x": -492, "y": 348}, - "3": {"x": -464, "y": 324}, - "4": {"x": -224, "y": 532}, - "5": {"x": -224, "y": 532}, - "6": {"x": -224, "y": 556} + "0": {"x": 1908, "y": 188}, + "1": {"x": 1936, "y": 164}, + "2": {"x": 2220, "y": 164}, + "3": {"x": 2192, "y": 188}, + "4": {"x": 2064, "y": 164}, + "5": {"x": 2064, "y": 164}, + "6": {"x": 2064, "y": 188} } }, "warnings": null }, { - "id": 547, - "sourceNodeId": 129, - "sourcePortId": 1109, - "targetNodeId": 171, - "targetPortId": 1110, + "id": 603, + "sourceNodeId": 147, + "sourcePortId": 1222, + "targetNodeId": 148, + "targetPortId": 1221, "travelTime": { - "lock": false, - "time": 22, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 364 + "consecutiveTime": 95 }, "sourceArrival": { - "lock": true, - "time": 56, + "lock": false, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 176 + "consecutiveTime": 325 }, "targetDeparture": { - "lock": true, - "time": 34, + "lock": false, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 154 + "consecutiveTime": 320 }, "targetArrival": { - "lock": true, - "time": 26, + "lock": false, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 386 + "consecutiveTime": 100 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2146, "y": 176}, - {"x": -2210, "y": 176}, - {"x": -2398, "y": 336}, - {"x": -2462, "y": 336} - ], - "textPositions": { - "0": {"x": -2164, "y": 164}, - "1": {"x": -2192, "y": 188}, - "2": {"x": -2444, "y": 348}, - "3": {"x": -2416, "y": 324}, - "4": {"x": -2304, "y": 244}, - "5": {"x": -2304, "y": 244}, - "6": {"x": -2304, "y": 268} + {"x": 1058, "y": 176}, + {"x": 1122, "y": 176}, + {"x": 1278, "y": 176}, + {"x": 1342, "y": 176} + ], + "textPositions": { + "0": {"x": 1076, "y": 188}, + "1": {"x": 1104, "y": 164}, + "2": {"x": 1324, "y": 164}, + "3": {"x": 1296, "y": 188}, + "4": {"x": 1200, "y": 164}, + "5": {"x": 1200, "y": 164}, + "6": {"x": 1200, "y": 188} } }, "warnings": null }, { - "id": 548, - "sourceNodeId": 142, - "sourcePortId": 1111, - "targetNodeId": 141, - "targetPortId": 1112, + "id": 604, + "sourceNodeId": 133, + "sourcePortId": 1224, + "targetNodeId": 147, + "targetPortId": 1223, "travelTime": { "lock": true, - "time": 18, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, + "lock": false, "time": 30, "warning": null, "timeFormatter": null, "consecutiveTime": 90 }, "sourceArrival": { - "lock": true, + "lock": false, "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 330 }, "targetDeparture": { - "lock": true, - "time": 12, + "lock": false, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 72 + "consecutiveTime": 325 }, "targetArrival": { - "lock": true, - "time": 48, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 108 + "consecutiveTime": 95 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": 1726}, - {"x": 208, "y": 1662}, - {"x": 208, "y": 1314}, - {"x": 208, "y": 1250} + {"x": 258, "y": 176}, + {"x": 322, "y": 176}, + {"x": 894, "y": 176}, + {"x": 958, "y": 176} ], "textPositions": { - "0": {"x": 220, "y": 1708}, - "1": {"x": 196, "y": 1680}, - "2": {"x": 196, "y": 1268}, - "3": {"x": 220, "y": 1296}, - "4": {"x": 196, "y": 1488}, - "5": {"x": 196, "y": 1488}, - "6": {"x": 220, "y": 1488} + "0": {"x": 276, "y": 188}, + "1": {"x": 304, "y": 164}, + "2": {"x": 940, "y": 164}, + "3": {"x": 912, "y": 188}, + "4": {"x": 608, "y": 164}, + "5": {"x": 608, "y": 164}, + "6": {"x": 608, "y": 188} } }, "warnings": null }, { - "id": 549, - "sourceNodeId": 141, - "sourcePortId": 1113, - "targetNodeId": 143, - "targetPortId": 1114, + "id": 605, + "sourceNodeId": 172, + "sourcePortId": 1226, + "targetNodeId": 133, + "targetPortId": 1225, "travelTime": { "lock": true, - "time": 13, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 49, + "lock": false, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 109 + "consecutiveTime": 83 }, "sourceArrival": { - "lock": true, - "time": 11, + "lock": false, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 71 + "consecutiveTime": 337 }, "targetDeparture": { - "lock": false, - "time": 58, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 58 + "consecutiveTime": 330 }, "targetArrival": { - "lock": false, - "time": 2, + "lock": true, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 122 + "consecutiveTime": 90 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": 1182}, - {"x": 208, "y": 1118}, - {"x": 208, "y": 866}, - {"x": 208, "y": 802} + {"x": -510, "y": 240}, + {"x": -446, "y": 240}, + {"x": -2, "y": 240}, + {"x": 62, "y": 240} ], "textPositions": { - "0": {"x": 220, "y": 1164}, - "1": {"x": 196, "y": 1136}, - "2": {"x": 196, "y": 820}, - "3": {"x": 220, "y": 848}, - "4": {"x": 196, "y": 992}, - "5": {"x": 196, "y": 992}, - "6": {"x": 220, "y": 992} + "0": {"x": -492, "y": 252}, + "1": {"x": -464, "y": 228}, + "2": {"x": 44, "y": 228}, + "3": {"x": 16, "y": 252}, + "4": {"x": -224, "y": 228}, + "5": {"x": -224, "y": 228}, + "6": {"x": -224, "y": 252} } }, "warnings": null }, { - "id": 550, - "sourceNodeId": 143, - "sourcePortId": 1115, - "targetNodeId": 133, - "targetPortId": 1116, + "id": 606, + "sourceNodeId": 151, + "sourcePortId": 1227, + "targetNodeId": 162, + "targetPortId": 1228, "travelTime": { "lock": true, - "time": 7, + "time": 51, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 124 + "consecutiveTime": 151 }, "sourceArrival": { - "lock": true, - "time": 56, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 56 + "consecutiveTime": 269 }, "targetDeparture": { - "lock": true, - "time": 49, + "lock": false, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 49 + "consecutiveTime": 218 }, "targetArrival": { - "lock": true, - "time": 11, + "lock": false, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 131 + "consecutiveTime": 202 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": 734}, - {"x": 176, "y": 670}, - {"x": 176, "y": 414}, - {"x": 176, "y": 350} + {"x": 3970, "y": 48}, + {"x": 4034, "y": 48}, + {"x": 4574, "y": -176}, + {"x": 4638, "y": -176} ], "textPositions": { - "0": {"x": 188, "y": 716}, - "1": {"x": 164, "y": 688}, - "2": {"x": 164, "y": 368}, - "3": {"x": 188, "y": 396}, - "4": {"x": 164, "y": 542}, - "5": {"x": 164, "y": 542}, - "6": {"x": 188, "y": 542} + "0": {"x": 3988, "y": 60}, + "1": {"x": 4016, "y": 36}, + "2": {"x": 4620, "y": -188}, + "3": {"x": 4592, "y": -164}, + "4": {"x": 4304, "y": -76}, + "5": {"x": 4304, "y": -76}, + "6": {"x": 4304, "y": -52} } }, "warnings": null }, { - "id": 551, - "sourceNodeId": 133, - "sourcePortId": 1117, - "targetNodeId": 144, - "targetPortId": 1118, + "id": 607, + "sourceNodeId": 135, + "sourcePortId": 1229, + "targetNodeId": 150, + "targetPortId": 1230, "travelTime": { "lock": true, - "time": 10, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 12, + "lock": false, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 132 + "consecutiveTime": 125 }, "sourceArrival": { - "lock": true, - "time": 48, + "lock": false, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 48 + "consecutiveTime": 295 }, "targetDeparture": { "lock": true, - "time": 38, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 38 + "consecutiveTime": 286 }, "targetArrival": { "lock": true, - "time": 22, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 142 + "consecutiveTime": 134 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 240, "y": 94}, - {"x": 240, "y": 30}, - {"x": 240, "y": -290}, - {"x": 240, "y": -354} + {"x": 2850, "y": 144}, + {"x": 2914, "y": 144}, + {"x": 3230, "y": 144}, + {"x": 3294, "y": 144} ], "textPositions": { - "0": {"x": 252, "y": 76}, - "1": {"x": 228, "y": 48}, - "2": {"x": 228, "y": -336}, - "3": {"x": 252, "y": -308}, - "4": {"x": 228, "y": -130}, - "5": {"x": 228, "y": -130}, - "6": {"x": 252, "y": -130} + "0": {"x": 2868, "y": 156}, + "1": {"x": 2896, "y": 132}, + "2": {"x": 3276, "y": 132}, + "3": {"x": 3248, "y": 156}, + "4": {"x": 3072, "y": 132}, + "5": {"x": 3072, "y": 132}, + "6": {"x": 3072, "y": 156} } }, "warnings": null }, { - "id": 552, - "sourceNodeId": 144, - "sourcePortId": 1119, - "targetNodeId": 145, - "targetPortId": 1120, + "id": 608, + "sourceNodeId": 150, + "sourcePortId": 1231, + "targetNodeId": 151, + "targetPortId": 1232, "travelTime": { "lock": true, - "time": 4, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 23, + "lock": false, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 143 + "consecutiveTime": 136 }, "sourceArrival": { - "lock": true, - "time": 37, + "lock": false, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 37 + "consecutiveTime": 284 }, "targetDeparture": { - "lock": true, - "time": 33, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 33 + "consecutiveTime": 271 }, "targetArrival": { - "lock": true, - "time": 27, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 147 + "consecutiveTime": 149 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 304, "y": -450}, - {"x": 304, "y": -514}, - {"x": 304, "y": -798}, - {"x": 304, "y": -862} + {"x": 3394, "y": 144}, + {"x": 3458, "y": 144}, + {"x": 3806, "y": 144}, + {"x": 3870, "y": 144} ], "textPositions": { - "0": {"x": 316, "y": -468}, - "1": {"x": 292, "y": -496}, - "2": {"x": 292, "y": -844}, - "3": {"x": 316, "y": -816}, - "4": {"x": 292, "y": -656}, - "5": {"x": 292, "y": -656}, - "6": {"x": 316, "y": -656} + "0": {"x": 3412, "y": 156}, + "1": {"x": 3440, "y": 132}, + "2": {"x": 3852, "y": 132}, + "3": {"x": 3824, "y": 156}, + "4": {"x": 3632, "y": 132}, + "5": {"x": 3632, "y": 132}, + "6": {"x": 3632, "y": 156} } }, "warnings": null }, { - "id": 553, - "sourceNodeId": 145, - "sourcePortId": 1121, - "targetNodeId": 146, - "targetPortId": 1122, + "id": 609, + "sourceNodeId": 149, + "sourcePortId": 1234, + "targetNodeId": 135, + "targetPortId": 1233, "travelTime": { "lock": true, - "time": 5, + "time": 15, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 28, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 148 + "consecutiveTime": 103 }, "sourceArrival": { "lock": true, - "time": 32, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 32 + "consecutiveTime": 317 }, "targetDeparture": { "lock": true, - "time": 27, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 27 + "consecutiveTime": 302 }, "targetArrival": { "lock": true, - "time": 33, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 153 + "consecutiveTime": 118 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 304, "y": -930}, - {"x": 304, "y": -994}, - {"x": 304, "y": -1278}, - {"x": 304, "y": -1342} + {"x": 2338, "y": 208}, + {"x": 2402, "y": 208}, + {"x": 2590, "y": 208}, + {"x": 2654, "y": 208} ], "textPositions": { - "0": {"x": 316, "y": -948}, - "1": {"x": 292, "y": -976}, - "2": {"x": 292, "y": -1324}, - "3": {"x": 316, "y": -1296}, - "4": {"x": 292, "y": -1136}, - "5": {"x": 292, "y": -1136}, - "6": {"x": 316, "y": -1136} + "0": {"x": 2356, "y": 220}, + "1": {"x": 2384, "y": 196}, + "2": {"x": 2636, "y": 196}, + "3": {"x": 2608, "y": 220}, + "4": {"x": 2496, "y": 196}, + "5": {"x": 2496, "y": 196}, + "6": {"x": 2496, "y": 220} } }, "warnings": null }, { - "id": 554, - "sourceNodeId": 146, - "sourcePortId": 1123, - "targetNodeId": 134, - "targetPortId": 1124, + "id": 610, + "sourceNodeId": 166, + "sourcePortId": 1236, + "targetNodeId": 149, + "targetPortId": 1235, "travelTime": { "lock": true, - "time": 10, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 34, + "lock": false, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 154 + "consecutiveTime": 97 }, "sourceArrival": { - "lock": true, - "time": 26, + "lock": false, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 26 + "consecutiveTime": 323 }, "targetDeparture": { - "lock": true, - "time": 16, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 16 + "consecutiveTime": 317 }, "targetArrival": { - "lock": true, - "time": 44, + "lock": false, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 164 + "consecutiveTime": 103 }, "numberOfStops": 0, - "trainrunId": 82, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 304, "y": -1410}, - {"x": 304, "y": -1474}, - {"x": 304, "y": -1758}, - {"x": 304, "y": -1822} + {"x": 1890, "y": 208}, + {"x": 1954, "y": 208}, + {"x": 2174, "y": 208}, + {"x": 2238, "y": 208} ], "textPositions": { - "0": {"x": 316, "y": -1428}, - "1": {"x": 292, "y": -1456}, - "2": {"x": 292, "y": -1804}, - "3": {"x": 316, "y": -1776}, - "4": {"x": 292, "y": -1616}, - "5": {"x": 292, "y": -1616}, - "6": {"x": 316, "y": -1616} + "0": {"x": 1908, "y": 220}, + "1": {"x": 1936, "y": 196}, + "2": {"x": 2220, "y": 196}, + "3": {"x": 2192, "y": 220}, + "4": {"x": 2064, "y": 196}, + "5": {"x": 2064, "y": 196}, + "6": {"x": 2064, "y": 220} } }, "warnings": null }, { - "id": 555, - "sourceNodeId": 142, - "sourcePortId": 1125, - "targetNodeId": 141, - "targetPortId": 1126, + "id": 611, + "sourceNodeId": 147, + "sourcePortId": 1238, + "targetNodeId": 148, + "targetPortId": 1237, "travelTime": { "lock": true, - "time": 19, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 55, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 115 + "consecutiveTime": 85 }, "sourceArrival": { "lock": false, - "time": 5, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 335 }, "targetDeparture": { "lock": false, - "time": 46, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 330 }, "targetArrival": { "lock": false, - "time": 14, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 90 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": 1726}, - {"x": 176, "y": 1662}, - {"x": 176, "y": 1314}, - {"x": 176, "y": 1250} + {"x": 1058, "y": 208}, + {"x": 1122, "y": 208}, + {"x": 1278, "y": 208}, + {"x": 1342, "y": 208} ], "textPositions": { - "0": {"x": 188, "y": 1708}, - "1": {"x": 164, "y": 1680}, - "2": {"x": 164, "y": 1268}, - "3": {"x": 188, "y": 1296}, - "4": {"x": 164, "y": 1488}, - "5": {"x": 164, "y": 1488}, - "6": {"x": 188, "y": 1488} + "0": {"x": 1076, "y": 220}, + "1": {"x": 1104, "y": 196}, + "2": {"x": 1324, "y": 196}, + "3": {"x": 1296, "y": 220}, + "4": {"x": 1200, "y": 196}, + "5": {"x": 1200, "y": 196}, + "6": {"x": 1200, "y": 220} } }, "warnings": null }, { - "id": 556, - "sourceNodeId": 141, - "sourcePortId": 1127, - "targetNodeId": 143, - "targetPortId": 1128, + "id": 612, + "sourceNodeId": 133, + "sourcePortId": 1240, + "targetNodeId": 147, + "targetPortId": 1239, "travelTime": { "lock": true, - "time": 8, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 14, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 80 }, "sourceArrival": { "lock": false, - "time": 46, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 340 }, "targetDeparture": { "lock": false, - "time": 38, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 38 + "consecutiveTime": 335 }, "targetArrival": { "lock": false, - "time": 22, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 142 + "consecutiveTime": 85 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": 1182}, - {"x": 176, "y": 1118}, - {"x": 176, "y": 866}, - {"x": 176, "y": 802} + {"x": 258, "y": 208}, + {"x": 322, "y": 208}, + {"x": 894, "y": 208}, + {"x": 958, "y": 208} ], - "textPositions": { - "0": {"x": 188, "y": 1164}, - "1": {"x": 164, "y": 1136}, - "2": {"x": 164, "y": 820}, - "3": {"x": 188, "y": 848}, - "4": {"x": 164, "y": 992}, - "5": {"x": 164, "y": 992}, - "6": {"x": 188, "y": 992} + "textPositions": { + "0": {"x": 276, "y": 220}, + "1": {"x": 304, "y": 196}, + "2": {"x": 940, "y": 196}, + "3": {"x": 912, "y": 220}, + "4": {"x": 608, "y": 196}, + "5": {"x": 608, "y": 196}, + "6": {"x": 608, "y": 220} } }, "warnings": null }, { - "id": 557, - "sourceNodeId": 143, - "sourcePortId": 1129, + "id": 613, + "sourceNodeId": 172, + "sourcePortId": 1242, "targetNodeId": 133, - "targetPortId": 1130, + "targetPortId": 1241, "travelTime": { "lock": true, - "time": 8, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 22, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 142 + "consecutiveTime": 73 }, "sourceArrival": { "lock": false, - "time": 38, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 38 + "consecutiveTime": 347 }, "targetDeparture": { - "lock": true, - "time": 30, + "lock": false, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 30 + "consecutiveTime": 340 }, "targetArrival": { - "lock": true, - "time": 30, + "lock": false, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 150 + "consecutiveTime": 80 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": 734}, - {"x": 144, "y": 670}, - {"x": 144, "y": 414}, - {"x": 144, "y": 350} + {"x": -510, "y": 272}, + {"x": -446, "y": 272}, + {"x": -2, "y": 272}, + {"x": 62, "y": 272} ], "textPositions": { - "0": {"x": 156, "y": 716}, - "1": {"x": 132, "y": 688}, - "2": {"x": 132, "y": 368}, - "3": {"x": 156, "y": 396}, - "4": {"x": 132, "y": 542}, - "5": {"x": 132, "y": 542}, - "6": {"x": 156, "y": 542} + "0": {"x": -492, "y": 284}, + "1": {"x": -464, "y": 260}, + "2": {"x": 44, "y": 260}, + "3": {"x": 16, "y": 284}, + "4": {"x": -224, "y": 260}, + "5": {"x": -224, "y": 260}, + "6": {"x": -224, "y": 284} } }, "warnings": null }, { - "id": 558, - "sourceNodeId": 133, - "sourcePortId": 1131, - "targetNodeId": 144, - "targetPortId": 1132, + "id": 614, + "sourceNodeId": 151, + "sourcePortId": 1243, + "targetNodeId": 162, + "targetPortId": 1244, "travelTime": { "lock": true, - "time": 10, + "time": 41, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 32, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 152 + "consecutiveTime": 151 }, "sourceArrival": { - "lock": true, - "time": 28, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 28 + "consecutiveTime": 269 }, "targetDeparture": { "lock": false, - "time": 18, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 228 }, "targetArrival": { "lock": false, - "time": 42, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 162 + "consecutiveTime": 192 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": 94}, - {"x": 208, "y": 30}, - {"x": 208, "y": -290}, - {"x": 208, "y": -354} + {"x": 3970, "y": 80}, + {"x": 4034, "y": 80}, + {"x": 4574, "y": -144}, + {"x": 4638, "y": -144} ], "textPositions": { - "0": {"x": 220, "y": 76}, - "1": {"x": 196, "y": 48}, - "2": {"x": 196, "y": -336}, - "3": {"x": 220, "y": -308}, - "4": {"x": 196, "y": -130}, - "5": {"x": 196, "y": -130}, - "6": {"x": 220, "y": -130} + "0": {"x": 3988, "y": 92}, + "1": {"x": 4016, "y": 68}, + "2": {"x": 4620, "y": -156}, + "3": {"x": 4592, "y": -132}, + "4": {"x": 4304, "y": -44}, + "5": {"x": 4304, "y": -44}, + "6": {"x": 4304, "y": -20} } }, "warnings": null }, { - "id": 559, - "sourceNodeId": 144, - "sourcePortId": 1133, - "targetNodeId": 145, - "targetPortId": 1134, + "id": 615, + "sourceNodeId": 135, + "sourcePortId": 1245, + "targetNodeId": 150, + "targetPortId": 1246, "travelTime": { "lock": true, - "time": 5, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 42, + "lock": true, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 162 + "consecutiveTime": 95 }, "sourceArrival": { - "lock": false, - "time": 18, + "lock": true, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 205 }, "targetDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 196 }, "targetArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 167 + "consecutiveTime": 104 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 272, "y": -450}, - {"x": 272, "y": -514}, - {"x": 272, "y": -798}, - {"x": 272, "y": -862} + {"x": 2850, "y": 208}, + {"x": 2914, "y": 208}, + {"x": 3230, "y": 208}, + {"x": 3294, "y": 208} ], "textPositions": { - "0": {"x": 284, "y": -468}, - "1": {"x": 260, "y": -496}, - "2": {"x": 260, "y": -844}, - "3": {"x": 284, "y": -816}, - "4": {"x": 260, "y": -656}, - "5": {"x": 260, "y": -656}, - "6": {"x": 284, "y": -656} + "0": {"x": 2868, "y": 220}, + "1": {"x": 2896, "y": 196}, + "2": {"x": 3276, "y": 196}, + "3": {"x": 3248, "y": 220}, + "4": {"x": 3072, "y": 196}, + "5": {"x": 3072, "y": 196}, + "6": {"x": 3072, "y": 220} } }, "warnings": null }, { - "id": 560, - "sourceNodeId": 145, - "sourcePortId": 1135, - "targetNodeId": 146, - "targetPortId": 1136, + "id": 616, + "sourceNodeId": 150, + "sourcePortId": 1247, + "targetNodeId": 151, + "targetPortId": 1248, "travelTime": { - "lock": true, - "time": 5, + "lock": false, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 47, + "lock": true, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 167 + "consecutiveTime": 106 }, "sourceArrival": { - "lock": false, - "time": 13, + "lock": true, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 194 }, "targetDeparture": { - "lock": false, - "time": 8, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 8 + "consecutiveTime": 181 }, "targetArrival": { - "lock": false, - "time": 52, + "lock": true, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 172 + "consecutiveTime": 119 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 272, "y": -930}, - {"x": 272, "y": -994}, - {"x": 272, "y": -1278}, - {"x": 272, "y": -1342} + {"x": 3394, "y": 208}, + {"x": 3458, "y": 208}, + {"x": 3806, "y": 208}, + {"x": 3870, "y": 208} ], "textPositions": { - "0": {"x": 284, "y": -948}, - "1": {"x": 260, "y": -976}, - "2": {"x": 260, "y": -1324}, - "3": {"x": 284, "y": -1296}, - "4": {"x": 260, "y": -1136}, - "5": {"x": 260, "y": -1136}, - "6": {"x": 284, "y": -1136} + "0": {"x": 3412, "y": 220}, + "1": {"x": 3440, "y": 196}, + "2": {"x": 3852, "y": 196}, + "3": {"x": 3824, "y": 220}, + "4": {"x": 3632, "y": 196}, + "5": {"x": 3632, "y": 196}, + "6": {"x": 3632, "y": 220} } }, "warnings": null }, { - "id": 561, - "sourceNodeId": 146, - "sourcePortId": 1137, - "targetNodeId": 134, - "targetPortId": 1138, + "id": 617, + "sourceNodeId": 151, + "sourcePortId": 1249, + "targetNodeId": 224, + "targetPortId": 1531, "travelTime": { - "lock": true, - "time": 5, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 52, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 172 + "consecutiveTime": 121 }, "sourceArrival": { - "lock": false, - "time": 8, + "lock": true, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 8 + "consecutiveTime": 179 }, "targetDeparture": { - "lock": false, - "time": 3, + "lock": true, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 3 + "consecutiveTime": 155 }, "targetArrival": { - "lock": false, - "time": 57, + "lock": true, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 177 + "consecutiveTime": 145 }, "numberOfStops": 0, - "trainrunId": 83, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 272, "y": -1410}, - {"x": 272, "y": -1474}, - {"x": 272, "y": -1758}, - {"x": 272, "y": -1822} + {"x": 3888, "y": 30}, + {"x": 3888, "y": -34}, + {"x": 4080, "y": -62}, + {"x": 4080, "y": -126} ], "textPositions": { - "0": {"x": 284, "y": -1428}, - "1": {"x": 260, "y": -1456}, - "2": {"x": 260, "y": -1804}, - "3": {"x": 284, "y": -1776}, - "4": {"x": 260, "y": -1616}, - "5": {"x": 260, "y": -1616}, - "6": {"x": 284, "y": -1616} + "0": {"x": 3900, "y": 12}, + "1": {"x": 3876, "y": -16}, + "2": {"x": 4068, "y": -108}, + "3": {"x": 4092, "y": -80}, + "4": {"x": 3972, "y": -48}, + "5": {"x": 3972, "y": -48}, + "6": {"x": 3996, "y": -48} } }, "warnings": null }, { - "id": 562, - "sourceNodeId": 135, - "sourcePortId": 1139, - "targetNodeId": 150, - "targetPortId": 1140, + "id": 618, + "sourceNodeId": 138, + "sourcePortId": 1251, + "targetNodeId": 163, + "targetPortId": 1252, "travelTime": { "lock": true, - "time": 12, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 9, + "lock": false, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 9 + "consecutiveTime": 0 }, "sourceArrival": { - "lock": true, - "time": 51, + "lock": false, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 291 + "consecutiveTime": 60 }, "targetDeparture": { - "lock": true, - "time": 39, + "lock": false, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 279 + "consecutiveTime": 59 }, "targetArrival": { - "lock": true, - "time": 21, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 21 + "consecutiveTime": 1 }, - "numberOfStops": 1, - "trainrunId": 84, + "numberOfStops": 0, + "trainrunId": 91, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 176}, - {"x": 2914, "y": 176}, - {"x": 3230, "y": 176}, - {"x": 3294, "y": 176} + {"x": 2672, "y": -1054}, + {"x": 2672, "y": -990}, + {"x": 2800, "y": -610}, + {"x": 2800, "y": -546} ], "textPositions": { - "0": {"x": 2868, "y": 188}, - "1": {"x": 2896, "y": 164}, - "2": {"x": 3276, "y": 164}, - "3": {"x": 3248, "y": 188}, - "4": {"x": 3072, "y": 164}, - "5": {"x": 3072, "y": 164}, - "6": {"x": 3072, "y": 188} + "0": {"x": 2660, "y": -1036}, + "1": {"x": 2684, "y": -1008}, + "2": {"x": 2812, "y": -564}, + "3": {"x": 2788, "y": -592}, + "4": {"x": 2748, "y": -800}, + "5": {"x": 2748, "y": -800}, + "6": {"x": 2724, "y": -800} } }, "warnings": null }, { - "id": 563, - "sourceNodeId": 150, - "sourcePortId": 1141, - "targetNodeId": 151, - "targetPortId": 1142, + "id": 619, + "sourceNodeId": 163, + "sourcePortId": 1253, + "targetNodeId": 135, + "targetPortId": 1254, "travelTime": { "lock": true, - "time": 13, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 23, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 23 + "consecutiveTime": 3 }, "sourceArrival": { "lock": false, - "time": 37, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 277 + "consecutiveTime": 57 }, "targetDeparture": { - "lock": true, - "time": 24, + "lock": false, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 264 + "consecutiveTime": 56 }, "targetArrival": { - "lock": true, - "time": 36, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 36 + "consecutiveTime": 4 }, "numberOfStops": 0, - "trainrunId": 84, + "trainrunId": 91, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3394, "y": 176}, - {"x": 3458, "y": 176}, - {"x": 3806, "y": 176}, - {"x": 3870, "y": 176} + {"x": 2800, "y": -478}, + {"x": 2800, "y": -414}, + {"x": 2704, "y": -34}, + {"x": 2704, "y": 30} ], "textPositions": { - "0": {"x": 3412, "y": 188}, - "1": {"x": 3440, "y": 164}, - "2": {"x": 3852, "y": 164}, - "3": {"x": 3824, "y": 188}, - "4": {"x": 3632, "y": 164}, - "5": {"x": 3632, "y": 164}, - "6": {"x": 3632, "y": 188} + "0": {"x": 2788, "y": -460}, + "1": {"x": 2812, "y": -432}, + "2": {"x": 2716, "y": 12}, + "3": {"x": 2692, "y": -16}, + "4": {"x": 2740, "y": -224}, + "5": {"x": 2740, "y": -224}, + "6": {"x": 2764, "y": -224} } }, "warnings": null }, { - "id": 564, - "sourceNodeId": 151, - "sourcePortId": 1143, - "targetNodeId": 137, - "targetPortId": 1144, + "id": 620, + "sourceNodeId": 135, + "sourcePortId": 1255, + "targetNodeId": 138, + "targetPortId": 1256, "travelTime": { "lock": true, - "time": 44, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 38, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 38 + "consecutiveTime": 120 }, "sourceArrival": { "lock": false, - "time": 22, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 262 + "consecutiveTime": 60 }, "targetDeparture": { "lock": false, - "time": 38, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 218 + "consecutiveTime": 59 }, "targetArrival": { "lock": false, - "time": 22, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 82 + "consecutiveTime": 121 }, - "numberOfStops": 4, - "trainrunId": 84, + "numberOfStops": 0, + "trainrunId": 92, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3970, "y": 176}, - {"x": 4034, "y": 176}, - {"x": 4574, "y": 176}, - {"x": 4638, "y": 176} + {"x": 2672, "y": 30}, + {"x": 2672, "y": -34}, + {"x": 2640, "y": -990}, + {"x": 2640, "y": -1054} ], "textPositions": { - "0": {"x": 3988, "y": 188}, - "1": {"x": 4016, "y": 164}, - "2": {"x": 4620, "y": 164}, - "3": {"x": 4592, "y": 188}, - "4": {"x": 4304, "y": 164}, - "5": {"x": 4304, "y": 164}, - "6": {"x": 4304, "y": 188} + "0": {"x": 2684, "y": 12}, + "1": {"x": 2660, "y": -16}, + "2": {"x": 2628, "y": -1036}, + "3": {"x": 2652, "y": -1008}, + "4": {"x": 2668, "y": -512}, + "5": {"x": 2668, "y": -512}, + "6": {"x": 2644, "y": -512} } }, "warnings": null }, { - "id": 565, - "sourceNodeId": 137, - "sourcePortId": 1145, - "targetNodeId": 140, - "targetPortId": 1146, + "id": 621, + "sourceNodeId": 166, + "sourcePortId": 1257, + "targetNodeId": 148, + "targetPortId": 1258, "travelTime": { "lock": true, - "time": 61, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 24, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 84 + "consecutiveTime": 356 }, "sourceArrival": { "lock": false, - "time": 36, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 216 + "consecutiveTime": 184 }, "targetDeparture": { "lock": false, - "time": 35, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 155 + "consecutiveTime": 179 }, "targetArrival": { "lock": false, - "time": 25, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 145 + "consecutiveTime": 361 }, - "numberOfStops": 5, - "trainrunId": 84, + "numberOfStops": 0, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4656, "y": 222}, - {"x": 4656, "y": 286}, - {"x": 4656, "y": 1118}, - {"x": 4656, "y": 1182} + {"x": 1790, "y": 48}, + {"x": 1726, "y": 48}, + {"x": 1506, "y": 48}, + {"x": 1442, "y": 48} ], "textPositions": { - "0": {"x": 4644, "y": 240}, - "1": {"x": 4668, "y": 268}, - "2": {"x": 4668, "y": 1164}, - "3": {"x": 4644, "y": 1136}, - "4": {"x": 4644, "y": 702}, - "5": {"x": 4644, "y": 702}, - "6": {"x": 4668, "y": 702} + "0": {"x": 1772, "y": 36}, + "1": {"x": 1744, "y": 60}, + "2": {"x": 1460, "y": 60}, + "3": {"x": 1488, "y": 36}, + "4": {"x": 1616, "y": 36}, + "5": {"x": 1616, "y": 36}, + "6": {"x": 1616, "y": 60} } - }, - "warnings": null - }, - { - "id": 566, - "sourceNodeId": 140, - "sourcePortId": 1147, - "targetNodeId": 152, - "targetPortId": 1148, + }, + "warnings": null + }, + { + "id": 622, + "sourceNodeId": 166, + "sourcePortId": 1259, + "targetNodeId": 148, + "targetPortId": 1260, "travelTime": { "lock": true, - "time": 22, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 26, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 146 + "consecutiveTime": 377 }, "sourceArrival": { - "lock": true, - "time": 34, + "lock": false, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 154 + "consecutiveTime": 163 }, "targetDeparture": { - "lock": true, - "time": 12, + "lock": false, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 132 + "consecutiveTime": 156 }, "targetArrival": { - "lock": true, - "time": 48, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 168 + "consecutiveTime": 384 }, - "numberOfStops": 2, - "trainrunId": 84, + "numberOfStops": 0, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4688, "y": 1278}, - {"x": 4688, "y": 1342}, - {"x": 4688, "y": 1822}, - {"x": 4688, "y": 1886} + {"x": 1790, "y": 144}, + {"x": 1726, "y": 144}, + {"x": 1506, "y": 144}, + {"x": 1442, "y": 144} ], "textPositions": { - "0": {"x": 4676, "y": 1296}, - "1": {"x": 4700, "y": 1324}, - "2": {"x": 4700, "y": 1868}, - "3": {"x": 4676, "y": 1840}, - "4": {"x": 4676, "y": 1582}, - "5": {"x": 4676, "y": 1582}, - "6": {"x": 4700, "y": 1582} + "0": {"x": 1772, "y": 132}, + "1": {"x": 1744, "y": 156}, + "2": {"x": 1460, "y": 156}, + "3": {"x": 1488, "y": 132}, + "4": {"x": 1616, "y": 132}, + "5": {"x": 1616, "y": 132}, + "6": {"x": 1616, "y": 156} } }, "warnings": null }, { - "id": 567, - "sourceNodeId": 135, - "sourcePortId": 1149, - "targetNodeId": 170, - "targetPortId": 1150, + "id": 623, + "sourceNodeId": 148, + "sourcePortId": 1262, + "targetNodeId": 166, + "targetPortId": 1261, "travelTime": { - "lock": false, - "time": 8, + "lock": true, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 7, + "lock": false, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 67 + "consecutiveTime": 100 }, "sourceArrival": { - "lock": true, - "time": 53, + "lock": false, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 293 + "consecutiveTime": 320 }, "targetDeparture": { "lock": false, - "time": 45, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 285 + "consecutiveTime": 314 }, "targetArrival": { "lock": false, - "time": 15, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 75 + "consecutiveTime": 106 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2704, "y": 350}, - {"x": 2704, "y": 414}, - {"x": 2704, "y": 670}, - {"x": 2704, "y": 734} + {"x": 1442, "y": 176}, + {"x": 1506, "y": 176}, + {"x": 1726, "y": 176}, + {"x": 1790, "y": 176} ], "textPositions": { - "0": {"x": 2692, "y": 368}, - "1": {"x": 2716, "y": 396}, - "2": {"x": 2716, "y": 716}, - "3": {"x": 2692, "y": 688}, - "4": {"x": 2692, "y": 542}, - "5": {"x": 2692, "y": 542}, - "6": {"x": 2716, "y": 542} + "0": {"x": 1460, "y": 188}, + "1": {"x": 1488, "y": 164}, + "2": {"x": 1772, "y": 164}, + "3": {"x": 1744, "y": 188}, + "4": {"x": 1616, "y": 164}, + "5": {"x": 1616, "y": 164}, + "6": {"x": 1616, "y": 188} } }, "warnings": null }, { - "id": 568, - "sourceNodeId": 140, - "sourcePortId": 1151, - "targetNodeId": 152, - "targetPortId": 1152, + "id": 624, + "sourceNodeId": 148, + "sourcePortId": 1264, + "targetNodeId": 166, + "targetPortId": 1263, "travelTime": { "lock": true, - "time": 19, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 3, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 123 + "consecutiveTime": 90 }, "sourceArrival": { - "lock": true, - "time": 57, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 237 + "consecutiveTime": 330 }, "targetDeparture": { - "lock": true, - "time": 38, + "lock": false, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 218 + "consecutiveTime": 325 }, "targetArrival": { - "lock": true, - "time": 22, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 142 + "consecutiveTime": 95 }, - "numberOfStops": 1, - "trainrunId": 85, + "numberOfStops": 0, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4656, "y": 1278}, - {"x": 4656, "y": 1342}, - {"x": 4656, "y": 1822}, - {"x": 4656, "y": 1886} + {"x": 1442, "y": 208}, + {"x": 1506, "y": 208}, + {"x": 1726, "y": 208}, + {"x": 1790, "y": 208} ], "textPositions": { - "0": {"x": 4644, "y": 1296}, - "1": {"x": 4668, "y": 1324}, - "2": {"x": 4668, "y": 1868}, - "3": {"x": 4644, "y": 1840}, - "4": {"x": 4644, "y": 1582}, - "5": {"x": 4644, "y": 1582}, - "6": {"x": 4668, "y": 1582} + "0": {"x": 1460, "y": 220}, + "1": {"x": 1488, "y": 196}, + "2": {"x": 1772, "y": 196}, + "3": {"x": 1744, "y": 220}, + "4": {"x": 1616, "y": 196}, + "5": {"x": 1616, "y": 196}, + "6": {"x": 1616, "y": 220} } }, "warnings": null }, { - "id": 569, - "sourceNodeId": 135, - "sourcePortId": 1153, - "targetNodeId": 170, - "targetPortId": 1154, + "id": 625, + "sourceNodeId": 148, + "sourcePortId": 1266, + "targetNodeId": 166, + "targetPortId": 1265, "travelTime": { "lock": true, - "time": 8, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 12, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 132 + "consecutiveTime": 105 }, "sourceArrival": { "lock": false, - "time": 48, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 288 + "consecutiveTime": 315 }, "targetDeparture": { - "lock": true, - "time": 40, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 280 + "consecutiveTime": 308 }, "targetArrival": { - "lock": true, - "time": 20, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 140 + "consecutiveTime": 112 }, "numberOfStops": 0, "trainrunId": 86, @@ -5775,221 +10999,221 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2736, "y": 350}, - {"x": 2736, "y": 414}, - {"x": 2736, "y": 670}, - {"x": 2736, "y": 734} + {"x": 1442, "y": 240}, + {"x": 1506, "y": 240}, + {"x": 1726, "y": 240}, + {"x": 1790, "y": 240} ], "textPositions": { - "0": {"x": 2724, "y": 368}, - "1": {"x": 2748, "y": 396}, - "2": {"x": 2748, "y": 716}, - "3": {"x": 2724, "y": 688}, - "4": {"x": 2724, "y": 542}, - "5": {"x": 2724, "y": 542}, - "6": {"x": 2748, "y": 542} + "0": {"x": 1460, "y": 252}, + "1": {"x": 1488, "y": 228}, + "2": {"x": 1772, "y": 228}, + "3": {"x": 1744, "y": 252}, + "4": {"x": 1616, "y": 228}, + "5": {"x": 1616, "y": 228}, + "6": {"x": 1616, "y": 252} } }, "warnings": null }, { - "id": 570, - "sourceNodeId": 140, - "sourcePortId": 1155, - "targetNodeId": 152, - "targetPortId": 1156, + "id": 626, + "sourceNodeId": 134, + "sourcePortId": 1267, + "targetNodeId": 164, + "targetPortId": 1268, "travelTime": { "lock": true, - "time": 20, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 23, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 203 + "consecutiveTime": 11 }, "sourceArrival": { - "lock": true, - "time": 37, + "lock": false, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 217 + "consecutiveTime": 169 }, "targetDeparture": { - "lock": true, - "time": 17, + "lock": false, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 197 + "consecutiveTime": 156 }, "targetArrival": { - "lock": true, - "time": 43, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 223 + "consecutiveTime": 24 }, - "numberOfStops": 1, - "trainrunId": 86, + "numberOfStops": 0, + "trainrunId": 93, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4720, "y": 1278}, - {"x": 4720, "y": 1342}, - {"x": 4720, "y": 1822}, - {"x": 4720, "y": 1886} + {"x": 322, "y": -1872}, + {"x": 386, "y": -1872}, + {"x": 990, "y": -944}, + {"x": 1054, "y": -944} ], "textPositions": { - "0": {"x": 4708, "y": 1296}, - "1": {"x": 4732, "y": 1324}, - "2": {"x": 4732, "y": 1868}, - "3": {"x": 4708, "y": 1840}, - "4": {"x": 4708, "y": 1582}, - "5": {"x": 4708, "y": 1582}, - "6": {"x": 4732, "y": 1582} + "0": {"x": 340, "y": -1860}, + "1": {"x": 368, "y": -1884}, + "2": {"x": 1036, "y": -956}, + "3": {"x": 1008, "y": -932}, + "4": {"x": 688, "y": -1420}, + "5": {"x": 688, "y": -1420}, + "6": {"x": 688, "y": -1396} } }, "warnings": null }, { - "id": 571, - "sourceNodeId": 149, - "sourcePortId": 1158, - "targetNodeId": 135, - "targetPortId": 1157, + "id": 627, + "sourceNodeId": 164, + "sourcePortId": 1269, + "targetNodeId": 165, + "targetPortId": 1270, "travelTime": { "lock": true, - "time": 7, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 59, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 119 + "consecutiveTime": 25 }, "sourceArrival": { "lock": false, - "time": 1, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 301 + "consecutiveTime": 155 }, "targetDeparture": { - "lock": true, - "time": 54, + "lock": false, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 294 + "consecutiveTime": 146 }, "targetArrival": { - "lock": true, - "time": 6, + "lock": false, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 126 + "consecutiveTime": 34 }, - "numberOfStops": 1, - "trainrunId": 86, + "numberOfStops": 0, + "trainrunId": 93, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 240}, - {"x": 2402, "y": 240}, - {"x": 2590, "y": 240}, - {"x": 2654, "y": 240} + {"x": 1154, "y": -944}, + {"x": 1218, "y": -944}, + {"x": 1726, "y": -656}, + {"x": 1790, "y": -656} ], "textPositions": { - "0": {"x": 2356, "y": 252}, - "1": {"x": 2384, "y": 228}, - "2": {"x": 2636, "y": 228}, - "3": {"x": 2608, "y": 252}, - "4": {"x": 2496, "y": 228}, - "5": {"x": 2496, "y": 228}, - "6": {"x": 2496, "y": 252} + "0": {"x": 1172, "y": -932}, + "1": {"x": 1200, "y": -956}, + "2": {"x": 1772, "y": -668}, + "3": {"x": 1744, "y": -644}, + "4": {"x": 1472, "y": -812}, + "5": {"x": 1472, "y": -812}, + "6": {"x": 1472, "y": -788} } }, "warnings": null }, { - "id": 572, - "sourceNodeId": 166, - "sourcePortId": 1160, - "targetNodeId": 149, - "targetPortId": 1159, + "id": 628, + "sourceNodeId": 165, + "sourcePortId": 1271, + "targetNodeId": 166, + "targetPortId": 1272, "travelTime": { "lock": true, - "time": 7, + "time": 22, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 52, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 35 }, "sourceArrival": { "lock": false, - "time": 8, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 145 }, "targetDeparture": { "lock": false, - "time": 1, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 301 + "consecutiveTime": 123 }, "targetArrival": { "lock": false, - "time": 59, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 119 + "consecutiveTime": 57 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 93, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 240}, - {"x": 1954, "y": 240}, - {"x": 2174, "y": 240}, - {"x": 2238, "y": 240} + {"x": 1808, "y": -606}, + {"x": 1808, "y": -542}, + {"x": 1808, "y": -34}, + {"x": 1808, "y": 30} ], "textPositions": { - "0": {"x": 1908, "y": 252}, - "1": {"x": 1936, "y": 228}, - "2": {"x": 2220, "y": 228}, - "3": {"x": 2192, "y": 252}, - "4": {"x": 2064, "y": 228}, - "5": {"x": 2064, "y": 228}, - "6": {"x": 2064, "y": 252} + "0": {"x": 1796, "y": -588}, + "1": {"x": 1820, "y": -560}, + "2": {"x": 1820, "y": 12}, + "3": {"x": 1796, "y": -16}, + "4": {"x": 1796, "y": -288}, + "5": {"x": 1796, "y": -288}, + "6": {"x": 1820, "y": -288} } }, "warnings": null }, { - "id": 573, - "sourceNodeId": 147, - "sourcePortId": 1162, - "targetNodeId": 148, - "targetPortId": 1161, + "id": 629, + "sourceNodeId": 166, + "sourcePortId": 1273, + "targetNodeId": 149, + "targetPortId": 1274, "travelTime": { "lock": true, "time": 7, @@ -5999,2051 +11223,2045 @@ }, "sourceDeparture": { "lock": false, - "time": 38, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 98 + "consecutiveTime": 60 }, "sourceArrival": { "lock": false, - "time": 22, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 322 + "consecutiveTime": 120 }, "targetDeparture": { "lock": false, - "time": 15, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 315 + "consecutiveTime": 113 }, "targetArrival": { "lock": false, - "time": 45, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 105 + "consecutiveTime": 67 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 93, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1058, "y": 240}, - {"x": 1122, "y": 240}, - {"x": 1278, "y": 240}, - {"x": 1342, "y": 240} + {"x": 1890, "y": 272}, + {"x": 1954, "y": 272}, + {"x": 2174, "y": 272}, + {"x": 2238, "y": 272} ], "textPositions": { - "0": {"x": 1076, "y": 252}, - "1": {"x": 1104, "y": 228}, - "2": {"x": 1324, "y": 228}, - "3": {"x": 1296, "y": 252}, - "4": {"x": 1200, "y": 228}, - "5": {"x": 1200, "y": 228}, - "6": {"x": 1200, "y": 252} + "0": {"x": 1908, "y": 284}, + "1": {"x": 1936, "y": 260}, + "2": {"x": 2220, "y": 260}, + "3": {"x": 2192, "y": 284}, + "4": {"x": 2064, "y": 260}, + "5": {"x": 2064, "y": 260}, + "6": {"x": 2064, "y": 284} } }, "warnings": null }, { - "id": 574, - "sourceNodeId": 133, - "sourcePortId": 1164, - "targetNodeId": 147, - "targetPortId": 1163, + "id": 630, + "sourceNodeId": 149, + "sourcePortId": 1275, + "targetNodeId": 135, + "targetPortId": 1276, "travelTime": { "lock": true, - "time": 8, + "time": 16, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 30, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 68 }, "sourceArrival": { - "lock": true, - "time": 30, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 112 }, "targetDeparture": { "lock": false, - "time": 22, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 322 + "consecutiveTime": 96 }, "targetArrival": { "lock": false, - "time": 38, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 98 + "consecutiveTime": 84 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 93, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 258, "y": 240}, - {"x": 322, "y": 240}, - {"x": 894, "y": 240}, - {"x": 958, "y": 240} + {"x": 2338, "y": 272}, + {"x": 2402, "y": 272}, + {"x": 2590, "y": 272}, + {"x": 2654, "y": 272} ], "textPositions": { - "0": {"x": 276, "y": 252}, - "1": {"x": 304, "y": 228}, - "2": {"x": 940, "y": 228}, - "3": {"x": 912, "y": 252}, - "4": {"x": 608, "y": 228}, - "5": {"x": 608, "y": 228}, - "6": {"x": 608, "y": 252} + "0": {"x": 2356, "y": 284}, + "1": {"x": 2384, "y": 260}, + "2": {"x": 2636, "y": 260}, + "3": {"x": 2608, "y": 284}, + "4": {"x": 2496, "y": 260}, + "5": {"x": 2496, "y": 260}, + "6": {"x": 2496, "y": 284} } }, "warnings": null }, { - "id": 575, - "sourceNodeId": 172, - "sourcePortId": 1166, - "targetNodeId": 133, - "targetPortId": 1165, + "id": 631, + "sourceNodeId": 134, + "sourcePortId": 1277, + "targetNodeId": 146, + "targetPortId": 1278, "travelTime": { "lock": true, - "time": 7, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 17, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 77 + "consecutiveTime": 6 }, "sourceArrival": { "lock": false, - "time": 43, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 343 + "consecutiveTime": 174 }, "targetDeparture": { - "lock": true, - "time": 36, + "lock": false, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 336 + "consecutiveTime": 169 }, "targetArrival": { - "lock": true, - "time": 24, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 84 + "consecutiveTime": 11 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -510, "y": 304}, - {"x": -446, "y": 304}, - {"x": -2, "y": 304}, - {"x": 62, "y": 304} + {"x": 144, "y": -1822}, + {"x": 144, "y": -1758}, + {"x": 144, "y": -1474}, + {"x": 144, "y": -1410} ], "textPositions": { - "0": {"x": -492, "y": 316}, - "1": {"x": -464, "y": 292}, - "2": {"x": 44, "y": 292}, - "3": {"x": 16, "y": 316}, - "4": {"x": -224, "y": 292}, - "5": {"x": -224, "y": 292}, - "6": {"x": -224, "y": 316} + "0": {"x": 132, "y": -1804}, + "1": {"x": 156, "y": -1776}, + "2": {"x": 156, "y": -1428}, + "3": {"x": 132, "y": -1456}, + "4": {"x": 132, "y": -1616}, + "5": {"x": 132, "y": -1616}, + "6": {"x": 156, "y": -1616} } }, "warnings": null }, { - "id": 576, - "sourceNodeId": 137, - "sourcePortId": 1167, - "targetNodeId": 151, - "targetPortId": 1168, + "id": 632, + "sourceNodeId": 146, + "sourcePortId": 1279, + "targetNodeId": 145, + "targetPortId": 1280, "travelTime": { "lock": true, - "time": 33, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 58, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 298 + "consecutiveTime": 11 }, "sourceArrival": { "lock": false, - "time": 2, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 242 + "consecutiveTime": 169 }, "targetDeparture": { "lock": false, - "time": 29, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 209 + "consecutiveTime": 163 }, "targetArrival": { "lock": false, - "time": 31, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 331 + "consecutiveTime": 17 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4638, "y": 144}, - {"x": 4574, "y": 144}, - {"x": 4034, "y": 144}, - {"x": 3970, "y": 144} + {"x": 144, "y": -1342}, + {"x": 144, "y": -1278}, + {"x": 144, "y": -994}, + {"x": 144, "y": -930} ], "textPositions": { - "0": {"x": 4620, "y": 132}, - "1": {"x": 4592, "y": 156}, - "2": {"x": 3988, "y": 156}, - "3": {"x": 4016, "y": 132}, - "4": {"x": 4304, "y": 132}, - "5": {"x": 4304, "y": 132}, - "6": {"x": 4304, "y": 156} + "0": {"x": 132, "y": -1324}, + "1": {"x": 156, "y": -1296}, + "2": {"x": 156, "y": -948}, + "3": {"x": 132, "y": -976}, + "4": {"x": 132, "y": -1136}, + "5": {"x": 132, "y": -1136}, + "6": {"x": 156, "y": -1136} } }, "warnings": null }, { - "id": 577, - "sourceNodeId": 151, - "sourcePortId": 1169, - "targetNodeId": 150, - "targetPortId": 1170, + "id": 633, + "sourceNodeId": 145, + "sourcePortId": 1281, + "targetNodeId": 144, + "targetPortId": 1282, "travelTime": { "lock": true, - "time": 14, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 33, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 333 + "consecutiveTime": 17 }, "sourceArrival": { "lock": false, - "time": 27, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 207 + "consecutiveTime": 163 }, "targetDeparture": { - "lock": true, - "time": 13, + "lock": false, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 193 + "consecutiveTime": 157 }, "targetArrival": { - "lock": true, - "time": 47, + "lock": false, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 23 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3870, "y": 80}, - {"x": 3806, "y": 80}, - {"x": 3458, "y": 80}, - {"x": 3394, "y": 80} + {"x": 144, "y": -862}, + {"x": 144, "y": -798}, + {"x": 144, "y": -514}, + {"x": 144, "y": -450} ], "textPositions": { - "0": {"x": 3852, "y": 68}, - "1": {"x": 3824, "y": 92}, - "2": {"x": 3412, "y": 92}, - "3": {"x": 3440, "y": 68}, - "4": {"x": 3632, "y": 68}, - "5": {"x": 3632, "y": 68}, - "6": {"x": 3632, "y": 92} + "0": {"x": 132, "y": -844}, + "1": {"x": 156, "y": -816}, + "2": {"x": 156, "y": -468}, + "3": {"x": 132, "y": -496}, + "4": {"x": 132, "y": -656}, + "5": {"x": 132, "y": -656}, + "6": {"x": 156, "y": -656} } }, "warnings": null }, { - "id": 578, - "sourceNodeId": 150, - "sourcePortId": 1171, - "targetNodeId": 135, - "targetPortId": 1172, + "id": 634, + "sourceNodeId": 144, + "sourcePortId": 1283, + "targetNodeId": 147, + "targetPortId": 1284, "travelTime": { "lock": true, - "time": 9, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 48, + "lock": false, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 348 + "consecutiveTime": 23 }, "sourceArrival": { - "lock": true, - "time": 12, + "lock": false, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 192 + "consecutiveTime": 157 }, "targetDeparture": { - "lock": true, - "time": 3, + "lock": false, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 183 + "consecutiveTime": 147 }, "targetArrival": { - "lock": true, - "time": 57, + "lock": false, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 357 + "consecutiveTime": 33 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3294, "y": 80}, - {"x": 3230, "y": 80}, - {"x": 2914, "y": 80}, - {"x": 2850, "y": 80} + {"x": 322, "y": -400}, + {"x": 386, "y": -400}, + {"x": 894, "y": 80}, + {"x": 958, "y": 80} ], "textPositions": { - "0": {"x": 3276, "y": 68}, - "1": {"x": 3248, "y": 92}, - "2": {"x": 2868, "y": 92}, - "3": {"x": 2896, "y": 68}, - "4": {"x": 3072, "y": 68}, - "5": {"x": 3072, "y": 68}, - "6": {"x": 3072, "y": 92} + "0": {"x": 340, "y": -388}, + "1": {"x": 368, "y": -412}, + "2": {"x": 940, "y": 68}, + "3": {"x": 912, "y": 92}, + "4": {"x": 640, "y": -172}, + "5": {"x": 640, "y": -172}, + "6": {"x": 640, "y": -148} } }, "warnings": null }, { - "id": 579, - "sourceNodeId": 135, - "sourcePortId": 1173, - "targetNodeId": 149, - "targetPortId": 1174, + "id": 635, + "sourceNodeId": 147, + "sourcePortId": 1285, + "targetNodeId": 148, + "targetPortId": 1286, "travelTime": { "lock": true, - "time": 10, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 364 + "consecutiveTime": 33 }, "sourceArrival": { - "lock": true, - "time": 56, - "warning": { - "title": "Avertissement d'arrivée à l'origine", - "description": "L'heure d'arrivée à l'origine ne peut être atteinte" - }, + "lock": false, + "time": 27, + "warning": null, "timeFormatter": null, - "consecutiveTime": 176 + "consecutiveTime": 147 }, "targetDeparture": { "lock": false, - "time": 50, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 170 + "consecutiveTime": 140 }, "targetArrival": { "lock": false, - "time": 10, - "warning": { - "title": "Avertissement d'arrivée à destination", - "description": "L'heure d'arrivée à destination ne peut être atteinte" - }, + "time": 40, + "warning": null, "timeFormatter": null, - "consecutiveTime": 370 + "consecutiveTime": 40 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2654, "y": 144}, - {"x": 2590, "y": 144}, - {"x": 2402, "y": 144}, - {"x": 2338, "y": 144} + {"x": 1058, "y": 112}, + {"x": 1122, "y": 112}, + {"x": 1278, "y": 112}, + {"x": 1342, "y": 112} ], "textPositions": { - "0": {"x": 2636, "y": 132}, - "1": {"x": 2608, "y": 156}, - "2": {"x": 2356, "y": 156}, - "3": {"x": 2384, "y": 132}, - "4": {"x": 2496, "y": 132}, - "5": {"x": 2496, "y": 132}, - "6": {"x": 2496, "y": 156} + "0": {"x": 1076, "y": 124}, + "1": {"x": 1104, "y": 100}, + "2": {"x": 1324, "y": 100}, + "3": {"x": 1296, "y": 124}, + "4": {"x": 1200, "y": 100}, + "5": {"x": 1200, "y": 100}, + "6": {"x": 1200, "y": 124} } }, "warnings": null }, { - "id": 580, - "sourceNodeId": 149, - "sourcePortId": 1175, + "id": 636, + "sourceNodeId": 148, + "sourcePortId": 1287, "targetNodeId": 166, - "targetPortId": 1176, + "targetPortId": 1288, "travelTime": { "lock": true, - "time": 7, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 10, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 370 + "consecutiveTime": 40 }, "sourceArrival": { "lock": false, - "time": 50, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 170 + "consecutiveTime": 140 }, "targetDeparture": { "lock": false, - "time": 43, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 134 }, "targetArrival": { "lock": false, - "time": 17, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 377 + "consecutiveTime": 46 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2238, "y": 144}, - {"x": 2174, "y": 144}, - {"x": 1954, "y": 144}, - {"x": 1890, "y": 144} + {"x": 1442, "y": 112}, + {"x": 1506, "y": 112}, + {"x": 1726, "y": 112}, + {"x": 1790, "y": 112} ], "textPositions": { - "0": {"x": 2220, "y": 132}, - "1": {"x": 2192, "y": 156}, - "2": {"x": 1908, "y": 156}, - "3": {"x": 1936, "y": 132}, - "4": {"x": 2064, "y": 132}, - "5": {"x": 2064, "y": 132}, - "6": {"x": 2064, "y": 156} + "0": {"x": 1460, "y": 124}, + "1": {"x": 1488, "y": 100}, + "2": {"x": 1772, "y": 100}, + "3": {"x": 1744, "y": 124}, + "4": {"x": 1616, "y": 100}, + "5": {"x": 1616, "y": 100}, + "6": {"x": 1616, "y": 124} } }, "warnings": null }, { - "id": 581, - "sourceNodeId": 148, - "sourcePortId": 1177, - "targetNodeId": 147, - "targetPortId": 1178, + "id": 637, + "sourceNodeId": 166, + "sourcePortId": 1289, + "targetNodeId": 149, + "targetPortId": 1290, "travelTime": { "lock": true, - "time": 5, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 24, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 384 + "consecutiveTime": 46 }, "sourceArrival": { "lock": false, - "time": 36, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 156 + "consecutiveTime": 134 }, "targetDeparture": { - "lock": true, - "time": 31, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 151 + "consecutiveTime": 128 }, "targetArrival": { - "lock": true, - "time": 29, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 389 + "consecutiveTime": 52 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1342, "y": 144}, - {"x": 1278, "y": 144}, - {"x": 1122, "y": 144}, - {"x": 1058, "y": 144} + {"x": 1890, "y": 112}, + {"x": 1954, "y": 112}, + {"x": 2174, "y": 112}, + {"x": 2238, "y": 112} ], "textPositions": { - "0": {"x": 1324, "y": 132}, - "1": {"x": 1296, "y": 156}, - "2": {"x": 1076, "y": 156}, - "3": {"x": 1104, "y": 132}, - "4": {"x": 1200, "y": 132}, - "5": {"x": 1200, "y": 132}, - "6": {"x": 1200, "y": 156} + "0": {"x": 1908, "y": 124}, + "1": {"x": 1936, "y": 100}, + "2": {"x": 2220, "y": 100}, + "3": {"x": 2192, "y": 124}, + "4": {"x": 2064, "y": 100}, + "5": {"x": 2064, "y": 100}, + "6": {"x": 2064, "y": 124} } }, "warnings": null }, { - "id": 582, - "sourceNodeId": 147, - "sourcePortId": 1179, - "targetNodeId": 133, - "targetPortId": 1180, + "id": 638, + "sourceNodeId": 149, + "sourcePortId": 1291, + "targetNodeId": 135, + "targetPortId": 1292, "travelTime": { "lock": true, - "time": 9, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 31, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 391 + "consecutiveTime": 52 }, "sourceArrival": { - "lock": true, - "time": 29, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 149 + "consecutiveTime": 128 }, "targetDeparture": { - "lock": true, - "time": 20, + "lock": false, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 140 + "consecutiveTime": 120 }, "targetArrival": { - "lock": true, - "time": 40, + "lock": false, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 400 + "consecutiveTime": 60 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 94, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 958, "y": 144}, - {"x": 894, "y": 144}, - {"x": 322, "y": 144}, - {"x": 258, "y": 144} + {"x": 2338, "y": 112}, + {"x": 2402, "y": 112}, + {"x": 2590, "y": 112}, + {"x": 2654, "y": 112} ], "textPositions": { - "0": {"x": 940, "y": 132}, - "1": {"x": 912, "y": 156}, - "2": {"x": 276, "y": 156}, - "3": {"x": 304, "y": 132}, - "4": {"x": 608, "y": 132}, - "5": {"x": 608, "y": 132}, - "6": {"x": 608, "y": 156} + "0": {"x": 2356, "y": 124}, + "1": {"x": 2384, "y": 100}, + "2": {"x": 2636, "y": 100}, + "3": {"x": 2608, "y": 124}, + "4": {"x": 2496, "y": 100}, + "5": {"x": 2496, "y": 100}, + "6": {"x": 2496, "y": 124} } }, "warnings": null }, { - "id": 583, - "sourceNodeId": 133, - "sourcePortId": 1181, - "targetNodeId": 175, - "targetPortId": 1182, + "id": 639, + "sourceNodeId": 147, + "sourcePortId": 1293, + "targetNodeId": 148, + "targetPortId": 1294, "travelTime": { "lock": true, - "time": 17, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 42, + "lock": false, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 402 + "consecutiveTime": 54 }, "sourceArrival": { - "lock": true, - "time": 18, + "lock": false, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 138 + "consecutiveTime": 126 }, "targetDeparture": { "lock": false, - "time": 1, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 121 + "consecutiveTime": 120 }, "targetArrival": { "lock": false, - "time": 59, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 419 + "consecutiveTime": 60 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 97, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 62, "y": 112}, - {"x": -2, "y": 112}, - {"x": -1534, "y": -16}, - {"x": -1598, "y": -16} + {"x": 1058, "y": 272}, + {"x": 1122, "y": 272}, + {"x": 1278, "y": 272}, + {"x": 1342, "y": 272} ], "textPositions": { - "0": {"x": 44, "y": 100}, - "1": {"x": 16, "y": 124}, - "2": {"x": -1580, "y": -4}, - "3": {"x": -1552, "y": -28}, - "4": {"x": -768, "y": 36}, - "5": {"x": -768, "y": 36}, - "6": {"x": -768, "y": 60} + "0": {"x": 1076, "y": 284}, + "1": {"x": 1104, "y": 260}, + "2": {"x": 1324, "y": 260}, + "3": {"x": 1296, "y": 284}, + "4": {"x": 1200, "y": 260}, + "5": {"x": 1200, "y": 260}, + "6": {"x": 1200, "y": 284} } }, "warnings": null }, { - "id": 584, - "sourceNodeId": 130, - "sourcePortId": 1183, - "targetNodeId": 177, - "targetPortId": 1184, + "id": 640, + "sourceNodeId": 148, + "sourcePortId": 1295, + "targetNodeId": 166, + "targetPortId": 1296, "travelTime": { - "lock": false, - "time": 61, + "lock": true, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 17, + "lock": false, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 437 + "consecutiveTime": 62 }, "sourceArrival": { - "lock": true, - "time": 43, + "lock": false, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 103 + "consecutiveTime": 118 }, "targetDeparture": { - "lock": true, - "time": 42, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 42 + "consecutiveTime": 112 }, "targetArrival": { - "lock": true, - "time": 18, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 498 + "consecutiveTime": 68 }, - "numberOfStops": 2, - "trainrunId": 87, + "numberOfStops": 0, + "trainrunId": 97, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2530, "y": -16}, - {"x": -2594, "y": -16}, - {"x": -3358, "y": 560}, - {"x": -3422, "y": 560} + {"x": 1442, "y": 272}, + {"x": 1506, "y": 272}, + {"x": 1726, "y": 272}, + {"x": 1790, "y": 272} ], "textPositions": { - "0": {"x": -2548, "y": -28}, - "1": {"x": -2576, "y": -4}, - "2": {"x": -3404, "y": 572}, - "3": {"x": -3376, "y": 548}, - "4": {"x": -2976, "y": 260}, - "5": {"x": -2976, "y": 260}, - "6": {"x": -2976, "y": 284} + "0": {"x": 1460, "y": 284}, + "1": {"x": 1488, "y": 260}, + "2": {"x": 1772, "y": 260}, + "3": {"x": 1744, "y": 284}, + "4": {"x": 1616, "y": 260}, + "5": {"x": 1616, "y": 260}, + "6": {"x": 1616, "y": 284} } }, "warnings": null }, { - "id": 585, - "sourceNodeId": 160, - "sourcePortId": 1185, - "targetNodeId": 161, - "targetPortId": 1186, + "id": 641, + "sourceNodeId": 166, + "sourcePortId": 1297, + "targetNodeId": 149, + "targetPortId": 1298, "travelTime": { "lock": true, - "time": 8, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 48, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 528 + "consecutiveTime": 68 }, "sourceArrival": { - "lock": true, - "time": 12, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 12 + "consecutiveTime": 112 }, "targetDeparture": { "lock": false, - "time": 4, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 4 + "consecutiveTime": 105 }, "targetArrival": { "lock": false, - "time": 56, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 536 + "consecutiveTime": 75 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 97, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3938, "y": 656}, - {"x": -4002, "y": 656}, - {"x": -4190, "y": 656}, - {"x": -4254, "y": 656} + {"x": 1890, "y": 304}, + {"x": 1954, "y": 304}, + {"x": 2174, "y": 304}, + {"x": 2238, "y": 304} ], "textPositions": { - "0": {"x": -3956, "y": 644}, - "1": {"x": -3984, "y": 668}, - "2": {"x": -4236, "y": 668}, - "3": {"x": -4208, "y": 644}, - "4": {"x": -4096, "y": 644}, - "5": {"x": -4096, "y": 644}, - "6": {"x": -4096, "y": 668} + "0": {"x": 1908, "y": 316}, + "1": {"x": 1936, "y": 292}, + "2": {"x": 2220, "y": 292}, + "3": {"x": 2192, "y": 316}, + "4": {"x": 2064, "y": 292}, + "5": {"x": 2064, "y": 292}, + "6": {"x": 2064, "y": 316} } }, "warnings": null }, { - "id": 586, - "sourceNodeId": 128, - "sourcePortId": 1187, - "targetNodeId": 177, - "targetPortId": 1188, + "id": 642, + "sourceNodeId": 149, + "sourcePortId": 1299, + "targetNodeId": 135, + "targetPortId": 1300, "travelTime": { - "lock": false, - "time": 11, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 19, + "lock": false, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 439 + "consecutiveTime": 75 }, "sourceArrival": { - "lock": true, - "time": 41, + "lock": false, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 101 + "consecutiveTime": 105 }, "targetDeparture": { - "lock": true, - "time": 30, + "lock": false, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 98 }, "targetArrival": { - "lock": true, - "time": 30, + "lock": false, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 450 + "consecutiveTime": 82 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 97, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3074, "y": 592}, - {"x": -3138, "y": 592}, - {"x": -3358, "y": 624}, - {"x": -3422, "y": 624} + {"x": 2338, "y": 304}, + {"x": 2402, "y": 304}, + {"x": 2590, "y": 304}, + {"x": 2654, "y": 304} ], "textPositions": { - "0": {"x": -3092, "y": 580}, - "1": {"x": -3120, "y": 604}, - "2": {"x": -3404, "y": 636}, - "3": {"x": -3376, "y": 612}, - "4": {"x": -3248, "y": 596}, - "5": {"x": -3248, "y": 596}, - "6": {"x": -3248, "y": 620} + "0": {"x": 2356, "y": 316}, + "1": {"x": 2384, "y": 292}, + "2": {"x": 2636, "y": 292}, + "3": {"x": 2608, "y": 316}, + "4": {"x": 2496, "y": 292}, + "5": {"x": 2496, "y": 292}, + "6": {"x": 2496, "y": 316} } }, "warnings": null }, { - "id": 587, - "sourceNodeId": 160, - "sourcePortId": 1189, - "targetNodeId": 161, - "targetPortId": 1190, + "id": 643, + "sourceNodeId": 134, + "sourcePortId": 1301, + "targetNodeId": 146, + "targetPortId": 1302, "travelTime": { - "lock": false, - "time": 8, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 4, + "lock": false, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 484 + "consecutiveTime": 28 }, "sourceArrival": { - "lock": true, - "time": 56, + "lock": false, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 56 + "consecutiveTime": 272 }, "targetDeparture": { - "lock": true, - "time": 48, + "lock": false, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 48 + "consecutiveTime": 265 }, "targetArrival": { - "lock": true, - "time": 12, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 492 + "consecutiveTime": 35 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3938, "y": 688}, - {"x": -4002, "y": 688}, - {"x": -4190, "y": 688}, - {"x": -4254, "y": 688} + {"x": 208, "y": -1822}, + {"x": 208, "y": -1758}, + {"x": 208, "y": -1474}, + {"x": 208, "y": -1410} ], "textPositions": { - "0": {"x": -3956, "y": 676}, - "1": {"x": -3984, "y": 700}, - "2": {"x": -4236, "y": 700}, - "3": {"x": -4208, "y": 676}, - "4": {"x": -4096, "y": 676}, - "5": {"x": -4096, "y": 676}, - "6": {"x": -4096, "y": 700} + "0": {"x": 196, "y": -1804}, + "1": {"x": 220, "y": -1776}, + "2": {"x": 220, "y": -1428}, + "3": {"x": 196, "y": -1456}, + "4": {"x": 196, "y": -1616}, + "5": {"x": 196, "y": -1616}, + "6": {"x": 220, "y": -1616} } }, "warnings": null }, { - "id": 588, - "sourceNodeId": 150, - "sourcePortId": 1192, - "targetNodeId": 135, - "targetPortId": 1191, + "id": 644, + "sourceNodeId": 146, + "sourcePortId": 1303, + "targetNodeId": 145, + "targetPortId": 1304, "travelTime": { "lock": true, - "time": 12, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 9, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 309 + "consecutiveTime": 35 }, "sourceArrival": { - "lock": true, - "time": 51, + "lock": false, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 231 + "consecutiveTime": 265 }, "targetDeparture": { - "lock": true, - "time": 39, + "lock": false, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 219 + "consecutiveTime": 259 }, "targetArrival": { - "lock": true, - "time": 21, + "lock": false, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 321 + "consecutiveTime": 41 }, - "numberOfStops": 1, - "trainrunId": 88, + "numberOfStops": 0, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3294, "y": 48}, - {"x": 3230, "y": 48}, - {"x": 2914, "y": 48}, - {"x": 2850, "y": 48} + {"x": 208, "y": -1342}, + {"x": 208, "y": -1278}, + {"x": 208, "y": -994}, + {"x": 208, "y": -930} ], "textPositions": { - "0": {"x": 3276, "y": 36}, - "1": {"x": 3248, "y": 60}, - "2": {"x": 2868, "y": 60}, - "3": {"x": 2896, "y": 36}, - "4": {"x": 3072, "y": 36}, - "5": {"x": 3072, "y": 36}, - "6": {"x": 3072, "y": 60} + "0": {"x": 196, "y": -1324}, + "1": {"x": 220, "y": -1296}, + "2": {"x": 220, "y": -948}, + "3": {"x": 196, "y": -976}, + "4": {"x": 196, "y": -1136}, + "5": {"x": 196, "y": -1136}, + "6": {"x": 220, "y": -1136} } }, "warnings": null }, { - "id": 589, - "sourceNodeId": 151, - "sourcePortId": 1194, - "targetNodeId": 150, - "targetPortId": 1193, + "id": 645, + "sourceNodeId": 145, + "sourcePortId": 1305, + "targetNodeId": 144, + "targetPortId": 1306, "travelTime": { "lock": true, - "time": 13, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 54, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 294 + "consecutiveTime": 41 }, "sourceArrival": { "lock": false, - "time": 6, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 246 + "consecutiveTime": 259 }, "targetDeparture": { "lock": false, - "time": 53, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 233 + "consecutiveTime": 253 }, "targetArrival": { "lock": false, - "time": 7, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 307 + "consecutiveTime": 47 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3870, "y": 48}, - {"x": 3806, "y": 48}, - {"x": 3458, "y": 48}, - {"x": 3394, "y": 48} + {"x": 208, "y": -862}, + {"x": 208, "y": -798}, + {"x": 208, "y": -514}, + {"x": 208, "y": -450} ], "textPositions": { - "0": {"x": 3852, "y": 36}, - "1": {"x": 3824, "y": 60}, - "2": {"x": 3412, "y": 60}, - "3": {"x": 3440, "y": 36}, - "4": {"x": 3632, "y": 36}, - "5": {"x": 3632, "y": 36}, - "6": {"x": 3632, "y": 60} + "0": {"x": 196, "y": -844}, + "1": {"x": 220, "y": -816}, + "2": {"x": 220, "y": -468}, + "3": {"x": 196, "y": -496}, + "4": {"x": 196, "y": -656}, + "5": {"x": 196, "y": -656}, + "6": {"x": 220, "y": -656} } }, "warnings": null }, { - "id": 590, - "sourceNodeId": 135, - "sourcePortId": 1195, - "targetNodeId": 149, - "targetPortId": 1196, + "id": 646, + "sourceNodeId": 144, + "sourcePortId": 1307, + "targetNodeId": 133, + "targetPortId": 1308, "travelTime": { "lock": true, - "time": 5, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 46, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 346 + "consecutiveTime": 47 }, "sourceArrival": { "lock": false, - "time": 14, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 194 + "consecutiveTime": 253 }, "targetDeparture": { - "lock": false, - "time": 9, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 189 + "consecutiveTime": 245 }, "targetArrival": { - "lock": false, - "time": 51, + "lock": true, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 351 + "consecutiveTime": 55 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2654, "y": 48}, - {"x": 2590, "y": 48}, - {"x": 2402, "y": 48}, - {"x": 2338, "y": 48} + {"x": 144, "y": -354}, + {"x": 144, "y": -290}, + {"x": 144, "y": 30}, + {"x": 144, "y": 94} ], "textPositions": { - "0": {"x": 2636, "y": 36}, - "1": {"x": 2608, "y": 60}, - "2": {"x": 2356, "y": 60}, - "3": {"x": 2384, "y": 36}, - "4": {"x": 2496, "y": 36}, - "5": {"x": 2496, "y": 36}, - "6": {"x": 2496, "y": 60} + "0": {"x": 132, "y": -336}, + "1": {"x": 156, "y": -308}, + "2": {"x": 156, "y": 76}, + "3": {"x": 132, "y": 48}, + "4": {"x": 132, "y": -130}, + "5": {"x": 132, "y": -130}, + "6": {"x": 156, "y": -130} } }, "warnings": null }, { - "id": 591, - "sourceNodeId": 149, - "sourcePortId": 1197, - "targetNodeId": 166, - "targetPortId": 1198, + "id": 647, + "sourceNodeId": 133, + "sourcePortId": 1309, + "targetNodeId": 172, + "targetPortId": 1310, "travelTime": { "lock": true, - "time": 5, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 51, + "lock": true, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 351 + "consecutiveTime": 58 }, "sourceArrival": { - "lock": false, - "time": 9, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 189 + "consecutiveTime": 242 }, "targetDeparture": { "lock": false, - "time": 4, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 184 + "consecutiveTime": 235 }, "targetArrival": { "lock": false, - "time": 56, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 356 + "consecutiveTime": 65 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2238, "y": 48}, - {"x": 2174, "y": 48}, - {"x": 1954, "y": 48}, - {"x": 1890, "y": 48} + {"x": 62, "y": 208}, + {"x": -2, "y": 208}, + {"x": -446, "y": 208}, + {"x": -510, "y": 208} ], "textPositions": { - "0": {"x": 2220, "y": 36}, - "1": {"x": 2192, "y": 60}, - "2": {"x": 1908, "y": 60}, - "3": {"x": 1936, "y": 36}, - "4": {"x": 2064, "y": 36}, - "5": {"x": 2064, "y": 36}, - "6": {"x": 2064, "y": 60} + "0": {"x": 44, "y": 196}, + "1": {"x": 16, "y": 220}, + "2": {"x": -492, "y": 220}, + "3": {"x": -464, "y": 196}, + "4": {"x": -224, "y": 196}, + "5": {"x": -224, "y": 196}, + "6": {"x": -224, "y": 220} } }, "warnings": null }, { - "id": 592, - "sourceNodeId": 148, - "sourcePortId": 1199, - "targetNodeId": 147, - "targetPortId": 1200, + "id": 648, + "sourceNodeId": 129, + "sourcePortId": 1311, + "targetNodeId": 167, + "targetPortId": 1312, "travelTime": { "lock": true, - "time": 4, + "time": 18, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 1, + "lock": true, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 361 + "consecutiveTime": 94 }, "sourceArrival": { - "lock": false, - "time": 59, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 179 + "consecutiveTime": 206 }, "targetDeparture": { - "lock": false, - "time": 55, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 175 + "consecutiveTime": 188 }, "targetArrival": { - "lock": false, - "time": 5, + "lock": true, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 365 + "consecutiveTime": 112 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1342, "y": 48}, - {"x": 1278, "y": 48}, - {"x": 1122, "y": 48}, - {"x": 1058, "y": 48} + {"x": -2096, "y": 382}, + {"x": -2096, "y": 446}, + {"x": -2096, "y": 574}, + {"x": -2096, "y": 638} ], "textPositions": { - "0": {"x": 1324, "y": 36}, - "1": {"x": 1296, "y": 60}, - "2": {"x": 1076, "y": 60}, - "3": {"x": 1104, "y": 36}, - "4": {"x": 1200, "y": 36}, - "5": {"x": 1200, "y": 36}, - "6": {"x": 1200, "y": 60} + "0": {"x": -2108, "y": 400}, + "1": {"x": -2084, "y": 428}, + "2": {"x": -2084, "y": 620}, + "3": {"x": -2108, "y": 592}, + "4": {"x": -2108, "y": 510}, + "5": {"x": -2108, "y": 510}, + "6": {"x": -2084, "y": 510} } - }, - "warnings": null - }, - { - "id": 593, - "sourceNodeId": 147, - "sourcePortId": 1201, - "targetNodeId": 133, - "targetPortId": 1202, + }, + "warnings": null + }, + { + "id": 649, + "sourceNodeId": 167, + "sourcePortId": 1314, + "targetNodeId": 129, + "targetPortId": 1313, "travelTime": { "lock": true, - "time": 5, + "time": 18, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 5, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 365 + "consecutiveTime": 43 }, "sourceArrival": { "lock": false, - "time": 55, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 175 + "consecutiveTime": 377 }, "targetDeparture": { "lock": false, - "time": 50, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 170 + "consecutiveTime": 359 }, "targetArrival": { "lock": false, - "time": 10, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 370 + "consecutiveTime": 61 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 958, "y": 112}, - {"x": 894, "y": 112}, - {"x": 322, "y": 112}, - {"x": 258, "y": 112} + {"x": -2064, "y": 638}, + {"x": -2064, "y": 574}, + {"x": -2064, "y": 446}, + {"x": -2064, "y": 382} ], "textPositions": { - "0": {"x": 940, "y": 100}, - "1": {"x": 912, "y": 124}, - "2": {"x": 276, "y": 124}, - "3": {"x": 304, "y": 100}, - "4": {"x": 608, "y": 100}, - "5": {"x": 608, "y": 100}, - "6": {"x": 608, "y": 124} + "0": {"x": -2052, "y": 620}, + "1": {"x": -2076, "y": 592}, + "2": {"x": -2076, "y": 400}, + "3": {"x": -2052, "y": 428}, + "4": {"x": -2076, "y": 510}, + "5": {"x": -2076, "y": 510}, + "6": {"x": -2052, "y": 510} } }, "warnings": null }, { - "id": 594, - "sourceNodeId": 133, - "sourcePortId": 1203, - "targetNodeId": 172, - "targetPortId": 1204, + "id": 650, + "sourceNodeId": 167, + "sourcePortId": 1315, + "targetNodeId": 168, + "targetPortId": 1316, "travelTime": { "lock": true, - "time": 7, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 10, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 370 + "consecutiveTime": 114 }, "sourceArrival": { "lock": false, - "time": 50, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 170 + "consecutiveTime": 186 }, "targetDeparture": { "lock": false, - "time": 43, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 178 }, "targetArrival": { "lock": false, - "time": 17, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 377 + "consecutiveTime": 122 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 62, "y": 144}, - {"x": -2, "y": 144}, - {"x": -446, "y": 144}, - {"x": -510, "y": 144} + {"x": -2096, "y": 706}, + {"x": -2096, "y": 770}, + {"x": -2096, "y": 862}, + {"x": -2096, "y": 926} ], "textPositions": { - "0": {"x": 44, "y": 132}, - "1": {"x": 16, "y": 156}, - "2": {"x": -492, "y": 156}, - "3": {"x": -464, "y": 132}, - "4": {"x": -224, "y": 132}, - "5": {"x": -224, "y": 132}, - "6": {"x": -224, "y": 156} + "0": {"x": -2108, "y": 724}, + "1": {"x": -2084, "y": 752}, + "2": {"x": -2084, "y": 908}, + "3": {"x": -2108, "y": 880}, + "4": {"x": -2108, "y": 816}, + "5": {"x": -2108, "y": 816}, + "6": {"x": -2084, "y": 816} } }, "warnings": null }, { - "id": 595, - "sourceNodeId": 129, - "sourcePortId": 1205, - "targetNodeId": 171, - "targetPortId": 1206, + "id": 651, + "sourceNodeId": 168, + "sourcePortId": 1317, + "targetNodeId": 131, + "targetPortId": 1318, "travelTime": { "lock": true, - "time": 22, + "time": 24, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 30, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 390 + "consecutiveTime": 124 }, "sourceArrival": { "lock": false, - "time": 30, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 150 + "consecutiveTime": 176 }, "targetDeparture": { "lock": false, - "time": 8, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 128 + "consecutiveTime": 152 }, "targetArrival": { "lock": false, - "time": 52, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 412 + "consecutiveTime": 148 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2146, "y": 144}, - {"x": -2210, "y": 144}, - {"x": -2398, "y": 304}, - {"x": -2462, "y": 304} + {"x": -2014, "y": 944}, + {"x": -1950, "y": 944}, + {"x": -1154, "y": 944}, + {"x": -1090, "y": 944} ], "textPositions": { - "0": {"x": -2164, "y": 132}, - "1": {"x": -2192, "y": 156}, - "2": {"x": -2444, "y": 316}, - "3": {"x": -2416, "y": 292}, - "4": {"x": -2304, "y": 212}, - "5": {"x": -2304, "y": 212}, - "6": {"x": -2304, "y": 236} + "0": {"x": -1996, "y": 956}, + "1": {"x": -1968, "y": 932}, + "2": {"x": -1108, "y": 932}, + "3": {"x": -1136, "y": 956}, + "4": {"x": -1552, "y": 932}, + "5": {"x": -1552, "y": 932}, + "6": {"x": -1552, "y": 956} } }, "warnings": null }, { - "id": 596, - "sourceNodeId": 128, - "sourcePortId": 1207, - "targetNodeId": 177, - "targetPortId": 1208, + "id": 652, + "sourceNodeId": 168, + "sourcePortId": 1320, + "targetNodeId": 167, + "targetPortId": 1319, "travelTime": { "lock": true, - "time": 9, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 43, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 463 + "consecutiveTime": 31 }, "sourceArrival": { - "lock": true, - "time": 17, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 77 + "consecutiveTime": 389 }, "targetDeparture": { "lock": false, - "time": 8, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 379 }, "targetArrival": { "lock": false, - "time": 52, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 472 + "consecutiveTime": 41 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3074, "y": 560}, - {"x": -3138, "y": 560}, - {"x": -3358, "y": 592}, - {"x": -3422, "y": 592} + {"x": -2064, "y": 926}, + {"x": -2064, "y": 862}, + {"x": -2064, "y": 770}, + {"x": -2064, "y": 706} ], "textPositions": { - "0": {"x": -3092, "y": 548}, - "1": {"x": -3120, "y": 572}, - "2": {"x": -3404, "y": 604}, - "3": {"x": -3376, "y": 580}, - "4": {"x": -3248, "y": 564}, - "5": {"x": -3248, "y": 564}, - "6": {"x": -3248, "y": 588} + "0": {"x": -2052, "y": 908}, + "1": {"x": -2076, "y": 880}, + "2": {"x": -2076, "y": 724}, + "3": {"x": -2052, "y": 752}, + "4": {"x": -2076, "y": 816}, + "5": {"x": -2076, "y": 816}, + "6": {"x": -2052, "y": 816} } }, "warnings": null }, { - "id": 597, - "sourceNodeId": 160, - "sourcePortId": 1209, - "targetNodeId": 161, - "targetPortId": 1210, + "id": 653, + "sourceNodeId": 132, + "sourcePortId": 1322, + "targetNodeId": 168, + "targetPortId": 1321, "travelTime": { "lock": true, - "time": 7, + "time": 25, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 21, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 501 + "consecutiveTime": 4 }, "sourceArrival": { - "lock": true, - "time": 39, + "lock": false, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 39 + "consecutiveTime": 416 }, "targetDeparture": { - "lock": true, - "time": 32, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 32 + "consecutiveTime": 391 }, "targetArrival": { - "lock": true, - "time": 28, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 508 + "consecutiveTime": 29 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 89, "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - {"x": -3938, "y": 624}, - {"x": -4002, "y": 624}, - {"x": -4190, "y": 624}, - {"x": -4254, "y": 624} + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": -2096, "y": 1438}, + {"x": -2096, "y": 1374}, + {"x": -2096, "y": 1086}, + {"x": -2096, "y": 1022} ], "textPositions": { - "0": {"x": -3956, "y": 612}, - "1": {"x": -3984, "y": 636}, - "2": {"x": -4236, "y": 636}, - "3": {"x": -4208, "y": 612}, - "4": {"x": -4096, "y": 612}, - "5": {"x": -4096, "y": 612}, - "6": {"x": -4096, "y": 636} + "0": {"x": -2084, "y": 1420}, + "1": {"x": -2108, "y": 1392}, + "2": {"x": -2108, "y": 1040}, + "3": {"x": -2084, "y": 1068}, + "4": {"x": -2108, "y": 1230}, + "5": {"x": -2108, "y": 1230}, + "6": {"x": -2084, "y": 1230} } }, "warnings": null }, { - "id": 598, - "sourceNodeId": 137, - "sourcePortId": 1212, - "targetNodeId": 151, - "targetPortId": 1211, + "id": 654, + "sourceNodeId": 132, + "sourcePortId": 1323, + "targetNodeId": 168, + "targetPortId": 1324, "travelTime": { - "lock": false, - "time": 44, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 8, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 248 + "consecutiveTime": 149 }, "sourceArrival": { "lock": false, - "time": 52, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 292 + "consecutiveTime": 151 }, "targetDeparture": { - "lock": true, - "time": 8, + "lock": false, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 248 + "consecutiveTime": 125 }, "targetArrival": { - "lock": true, - "time": 52, + "lock": false, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 292 + "consecutiveTime": 175 }, - "numberOfStops": 4, - "trainrunId": 88, + "numberOfStops": 0, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 4638, "y": 112}, - {"x": 4574, "y": 112}, - {"x": 4034, "y": 112}, - {"x": 3970, "y": 112} + {"x": -2128, "y": 1438}, + {"x": -2128, "y": 1374}, + {"x": -2128, "y": 1086}, + {"x": -2128, "y": 1022} ], "textPositions": { - "0": {"x": 4620, "y": 100}, - "1": {"x": 4592, "y": 124}, - "2": {"x": 3988, "y": 124}, - "3": {"x": 4016, "y": 100}, - "4": {"x": 4304, "y": 100}, - "5": {"x": 4304, "y": 100}, - "6": {"x": 4304, "y": 124} + "0": {"x": -2116, "y": 1420}, + "1": {"x": -2140, "y": 1392}, + "2": {"x": -2140, "y": 1040}, + "3": {"x": -2116, "y": 1068}, + "4": {"x": -2140, "y": 1230}, + "5": {"x": -2140, "y": 1230}, + "6": {"x": -2116, "y": 1230} } }, "warnings": null }, { - "id": 599, - "sourceNodeId": 135, - "sourcePortId": 1213, - "targetNodeId": 150, - "targetPortId": 1214, + "id": 655, + "sourceNodeId": 168, + "sourcePortId": 1325, + "targetNodeId": 167, + "targetPortId": 1326, "travelTime": { "lock": true, - "time": 9, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 5, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 125 + "consecutiveTime": 178 }, "sourceArrival": { "lock": false, - "time": 55, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 295 + "consecutiveTime": 122 }, "targetDeparture": { "lock": false, - "time": 46, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 286 + "consecutiveTime": 114 }, "targetArrival": { "lock": false, - "time": 14, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 186 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 112}, - {"x": 2914, "y": 112}, - {"x": 3230, "y": 112}, - {"x": 3294, "y": 112} + {"x": -2128, "y": 926}, + {"x": -2128, "y": 862}, + {"x": -2128, "y": 770}, + {"x": -2128, "y": 706} ], "textPositions": { - "0": {"x": 2868, "y": 124}, - "1": {"x": 2896, "y": 100}, - "2": {"x": 3276, "y": 100}, - "3": {"x": 3248, "y": 124}, - "4": {"x": 3072, "y": 100}, - "5": {"x": 3072, "y": 100}, - "6": {"x": 3072, "y": 124} + "0": {"x": -2116, "y": 908}, + "1": {"x": -2140, "y": 880}, + "2": {"x": -2140, "y": 724}, + "3": {"x": -2116, "y": 752}, + "4": {"x": -2140, "y": 816}, + "5": {"x": -2140, "y": 816}, + "6": {"x": -2116, "y": 816} } }, "warnings": null }, { - "id": 600, - "sourceNodeId": 150, - "sourcePortId": 1215, - "targetNodeId": 151, - "targetPortId": 1216, + "id": 656, + "sourceNodeId": 167, + "sourcePortId": 1327, + "targetNodeId": 129, + "targetPortId": 1328, "travelTime": { "lock": true, - "time": 13, + "time": 18, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 16, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 136 + "consecutiveTime": 188 }, "sourceArrival": { "lock": false, - "time": 44, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 284 + "consecutiveTime": 112 }, "targetDeparture": { - "lock": false, - "time": 31, + "lock": true, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 271 + "consecutiveTime": 94 }, "targetArrival": { - "lock": false, - "time": 29, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 149 + "consecutiveTime": 206 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3394, "y": 112}, - {"x": 3458, "y": 112}, - {"x": 3806, "y": 112}, - {"x": 3870, "y": 112} + {"x": -2128, "y": 638}, + {"x": -2128, "y": 574}, + {"x": -2128, "y": 446}, + {"x": -2128, "y": 382} ], "textPositions": { - "0": {"x": 3412, "y": 124}, - "1": {"x": 3440, "y": 100}, - "2": {"x": 3852, "y": 100}, - "3": {"x": 3824, "y": 124}, - "4": {"x": 3632, "y": 100}, - "5": {"x": 3632, "y": 100}, - "6": {"x": 3632, "y": 124} + "0": {"x": -2116, "y": 620}, + "1": {"x": -2140, "y": 592}, + "2": {"x": -2140, "y": 400}, + "3": {"x": -2116, "y": 428}, + "4": {"x": -2140, "y": 510}, + "5": {"x": -2140, "y": 510}, + "6": {"x": -2116, "y": 510} } }, "warnings": null }, { - "id": 601, - "sourceNodeId": 149, - "sourcePortId": 1218, - "targetNodeId": 135, - "targetPortId": 1217, + "id": 657, + "sourceNodeId": 129, + "sourcePortId": 1329, + "targetNodeId": 178, + "targetPortId": 1330, "travelTime": { "lock": true, - "time": 6, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 52, + "lock": true, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 214 }, "sourceArrival": { - "lock": false, - "time": 8, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 86 }, "targetDeparture": { - "lock": true, - "time": 2, + "lock": false, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 302 + "consecutiveTime": 83 }, "targetArrival": { - "lock": true, - "time": 58, + "lock": false, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 118 + "consecutiveTime": 217 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 176}, - {"x": 2402, "y": 176}, - {"x": 2590, "y": 176}, - {"x": 2654, "y": 176} + {"x": -2014, "y": 176}, + {"x": -1950, "y": 176}, + {"x": -1762, "y": 176}, + {"x": -1698, "y": 176} ], "textPositions": { - "0": {"x": 2356, "y": 188}, - "1": {"x": 2384, "y": 164}, - "2": {"x": 2636, "y": 164}, - "3": {"x": 2608, "y": 188}, - "4": {"x": 2496, "y": 164}, - "5": {"x": 2496, "y": 164}, - "6": {"x": 2496, "y": 188} + "0": {"x": -1996, "y": 188}, + "1": {"x": -1968, "y": 164}, + "2": {"x": -1716, "y": 164}, + "3": {"x": -1744, "y": 188}, + "4": {"x": -1856, "y": 164}, + "5": {"x": -1856, "y": 164}, + "6": {"x": -1856, "y": 188} } }, "warnings": null }, { - "id": 602, - "sourceNodeId": 166, - "sourcePortId": 1220, - "targetNodeId": 149, - "targetPortId": 1219, + "id": 658, + "sourceNodeId": 133, + "sourcePortId": 1331, + "targetNodeId": 144, + "targetPortId": 1332, "travelTime": { "lock": true, - "time": 6, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 46, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 245 }, "sourceArrival": { - "lock": false, - "time": 14, + "lock": true, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 55 }, "targetDeparture": { "lock": false, - "time": 8, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 47 }, "targetArrival": { "lock": false, - "time": 52, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 253 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 176}, - {"x": 1954, "y": 176}, - {"x": 2174, "y": 176}, - {"x": 2238, "y": 176} + {"x": 112, "y": 94}, + {"x": 112, "y": 30}, + {"x": 112, "y": -290}, + {"x": 112, "y": -354} ], "textPositions": { - "0": {"x": 1908, "y": 188}, - "1": {"x": 1936, "y": 164}, - "2": {"x": 2220, "y": 164}, - "3": {"x": 2192, "y": 188}, - "4": {"x": 2064, "y": 164}, - "5": {"x": 2064, "y": 164}, - "6": {"x": 2064, "y": 188} + "0": {"x": 124, "y": 76}, + "1": {"x": 100, "y": 48}, + "2": {"x": 100, "y": -336}, + "3": {"x": 124, "y": -308}, + "4": {"x": 100, "y": -130}, + "5": {"x": 100, "y": -130}, + "6": {"x": 124, "y": -130} } }, "warnings": null }, { - "id": 603, - "sourceNodeId": 147, - "sourcePortId": 1222, - "targetNodeId": 148, - "targetPortId": 1221, + "id": 659, + "sourceNodeId": 144, + "sourcePortId": 1333, + "targetNodeId": 145, + "targetPortId": 1334, "travelTime": { "lock": true, - "time": 5, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 35, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 95 + "consecutiveTime": 253 }, "sourceArrival": { "lock": false, - "time": 25, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 325 + "consecutiveTime": 47 }, "targetDeparture": { "lock": false, - "time": 20, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 320 + "consecutiveTime": 41 }, "targetArrival": { "lock": false, - "time": 40, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 100 + "consecutiveTime": 259 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1058, "y": 176}, - {"x": 1122, "y": 176}, - {"x": 1278, "y": 176}, - {"x": 1342, "y": 176} + {"x": 176, "y": -450}, + {"x": 176, "y": -514}, + {"x": 176, "y": -798}, + {"x": 176, "y": -862} ], "textPositions": { - "0": {"x": 1076, "y": 188}, - "1": {"x": 1104, "y": 164}, - "2": {"x": 1324, "y": 164}, - "3": {"x": 1296, "y": 188}, - "4": {"x": 1200, "y": 164}, - "5": {"x": 1200, "y": 164}, - "6": {"x": 1200, "y": 188} + "0": {"x": 188, "y": -468}, + "1": {"x": 164, "y": -496}, + "2": {"x": 164, "y": -844}, + "3": {"x": 188, "y": -816}, + "4": {"x": 164, "y": -656}, + "5": {"x": 164, "y": -656}, + "6": {"x": 188, "y": -656} } }, "warnings": null }, { - "id": 604, - "sourceNodeId": 133, - "sourcePortId": 1224, - "targetNodeId": 147, - "targetPortId": 1223, + "id": 660, + "sourceNodeId": 145, + "sourcePortId": 1335, + "targetNodeId": 146, + "targetPortId": 1336, "travelTime": { "lock": true, - "time": 5, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 30, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 259 }, "sourceArrival": { "lock": false, - "time": 30, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 41 }, "targetDeparture": { "lock": false, - "time": 25, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 325 + "consecutiveTime": 35 }, "targetArrival": { "lock": false, - "time": 35, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 95 + "consecutiveTime": 265 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 258, "y": 176}, - {"x": 322, "y": 176}, - {"x": 894, "y": 176}, - {"x": 958, "y": 176} + {"x": 176, "y": -930}, + {"x": 176, "y": -994}, + {"x": 176, "y": -1278}, + {"x": 176, "y": -1342} ], "textPositions": { - "0": {"x": 276, "y": 188}, - "1": {"x": 304, "y": 164}, - "2": {"x": 940, "y": 164}, - "3": {"x": 912, "y": 188}, - "4": {"x": 608, "y": 164}, - "5": {"x": 608, "y": 164}, - "6": {"x": 608, "y": 188} + "0": {"x": 188, "y": -948}, + "1": {"x": 164, "y": -976}, + "2": {"x": 164, "y": -1324}, + "3": {"x": 188, "y": -1296}, + "4": {"x": 164, "y": -1136}, + "5": {"x": 164, "y": -1136}, + "6": {"x": 188, "y": -1136} } }, "warnings": null }, { - "id": 605, - "sourceNodeId": 172, - "sourcePortId": 1226, - "targetNodeId": 133, - "targetPortId": 1225, + "id": 661, + "sourceNodeId": 146, + "sourcePortId": 1337, + "targetNodeId": 134, + "targetPortId": 1338, "travelTime": { "lock": true, "time": 7, @@ -8053,159 +13271,159 @@ }, "sourceDeparture": { "lock": false, - "time": 23, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 265 }, "sourceArrival": { "lock": false, - "time": 37, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 337 + "consecutiveTime": 35 }, "targetDeparture": { "lock": true, - "time": 30, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 28 }, "targetArrival": { "lock": true, - "time": 30, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 272 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -510, "y": 240}, - {"x": -446, "y": 240}, - {"x": -2, "y": 240}, - {"x": 62, "y": 240} + {"x": 176, "y": -1410}, + {"x": 176, "y": -1474}, + {"x": 176, "y": -1758}, + {"x": 176, "y": -1822} ], "textPositions": { - "0": {"x": -492, "y": 252}, - "1": {"x": -464, "y": 228}, - "2": {"x": 44, "y": 228}, - "3": {"x": 16, "y": 252}, - "4": {"x": -224, "y": 228}, - "5": {"x": -224, "y": 228}, - "6": {"x": -224, "y": 252} + "0": {"x": 188, "y": -1428}, + "1": {"x": 164, "y": -1456}, + "2": {"x": 164, "y": -1804}, + "3": {"x": 188, "y": -1776}, + "4": {"x": 164, "y": -1616}, + "5": {"x": 164, "y": -1616}, + "6": {"x": 188, "y": -1616} } }, "warnings": null }, { - "id": 606, - "sourceNodeId": 151, - "sourcePortId": 1227, - "targetNodeId": 162, - "targetPortId": 1228, + "id": 662, + "sourceNodeId": 167, + "sourcePortId": 1340, + "targetNodeId": 129, + "targetPortId": 1339, "travelTime": { - "lock": true, - "time": 51, + "lock": false, + "time": 19, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 31, + "lock": true, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 151 + "consecutiveTime": 33 }, "sourceArrival": { - "lock": false, - "time": 29, + "lock": true, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 269 + "consecutiveTime": 387 }, "targetDeparture": { - "lock": false, - "time": 38, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 218 + "consecutiveTime": 368 }, "targetArrival": { - "lock": false, - "time": 22, + "lock": true, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 202 + "consecutiveTime": 52 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3970, "y": 48}, - {"x": 4034, "y": 48}, - {"x": 4574, "y": -176}, - {"x": 4638, "y": -176} + {"x": -2032, "y": 638}, + {"x": -2032, "y": 574}, + {"x": -2032, "y": 446}, + {"x": -2032, "y": 382} ], "textPositions": { - "0": {"x": 3988, "y": 60}, - "1": {"x": 4016, "y": 36}, - "2": {"x": 4620, "y": -188}, - "3": {"x": 4592, "y": -164}, - "4": {"x": 4304, "y": -76}, - "5": {"x": 4304, "y": -76}, - "6": {"x": 4304, "y": -52} + "0": {"x": -2020, "y": 620}, + "1": {"x": -2044, "y": 592}, + "2": {"x": -2044, "y": 400}, + "3": {"x": -2020, "y": 428}, + "4": {"x": -2044, "y": 510}, + "5": {"x": -2044, "y": 510}, + "6": {"x": -2020, "y": 510} } }, "warnings": null }, { - "id": 607, - "sourceNodeId": 135, - "sourcePortId": 1229, - "targetNodeId": 150, - "targetPortId": 1230, + "id": 663, + "sourceNodeId": 168, + "sourcePortId": 1342, + "targetNodeId": 167, + "targetPortId": 1341, "travelTime": { "lock": true, - "time": 9, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 5, + "lock": true, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 125 + "consecutiveTime": 22 }, "sourceArrival": { - "lock": false, - "time": 55, + "lock": true, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 295 + "consecutiveTime": 398 }, "targetDeparture": { - "lock": true, - "time": 46, + "lock": false, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 286 + "consecutiveTime": 388 }, "targetArrival": { - "lock": true, - "time": 14, + "lock": false, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 32 }, "numberOfStops": 0, "trainrunId": 90, @@ -8213,63 +13431,63 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 144}, - {"x": 2914, "y": 144}, - {"x": 3230, "y": 144}, - {"x": 3294, "y": 144} + {"x": -2032, "y": 926}, + {"x": -2032, "y": 862}, + {"x": -2032, "y": 770}, + {"x": -2032, "y": 706} ], "textPositions": { - "0": {"x": 2868, "y": 156}, - "1": {"x": 2896, "y": 132}, - "2": {"x": 3276, "y": 132}, - "3": {"x": 3248, "y": 156}, - "4": {"x": 3072, "y": 132}, - "5": {"x": 3072, "y": 132}, - "6": {"x": 3072, "y": 156} + "0": {"x": -2020, "y": 908}, + "1": {"x": -2044, "y": 880}, + "2": {"x": -2044, "y": 724}, + "3": {"x": -2020, "y": 752}, + "4": {"x": -2044, "y": 816}, + "5": {"x": -2044, "y": 816}, + "6": {"x": -2020, "y": 816} } }, "warnings": null }, { - "id": 608, - "sourceNodeId": 150, - "sourcePortId": 1231, - "targetNodeId": 151, - "targetPortId": 1232, + "id": 664, + "sourceNodeId": 131, + "sourcePortId": 1344, + "targetNodeId": 168, + "targetPortId": 1343, "travelTime": { "lock": true, - "time": 13, + "time": 21, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 16, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 136 + "consecutiveTime": 0 }, "sourceArrival": { "lock": false, - "time": 44, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 284 + "consecutiveTime": 420 }, "targetDeparture": { - "lock": false, - "time": 31, + "lock": true, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 271 + "consecutiveTime": 399 }, "targetArrival": { - "lock": false, - "time": 29, + "lock": true, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 149 + "consecutiveTime": 21 }, "numberOfStops": 0, "trainrunId": 90, @@ -8277,989 +13495,989 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3394, "y": 144}, - {"x": 3458, "y": 144}, - {"x": 3806, "y": 144}, - {"x": 3870, "y": 144} + {"x": -1090, "y": 976}, + {"x": -1154, "y": 976}, + {"x": -1950, "y": 976}, + {"x": -2014, "y": 976} ], "textPositions": { - "0": {"x": 3412, "y": 156}, - "1": {"x": 3440, "y": 132}, - "2": {"x": 3852, "y": 132}, - "3": {"x": 3824, "y": 156}, - "4": {"x": 3632, "y": 132}, - "5": {"x": 3632, "y": 132}, - "6": {"x": 3632, "y": 156} + "0": {"x": -1108, "y": 964}, + "1": {"x": -1136, "y": 988}, + "2": {"x": -1996, "y": 988}, + "3": {"x": -1968, "y": 964}, + "4": {"x": -1552, "y": 964}, + "5": {"x": -1552, "y": 964}, + "6": {"x": -1552, "y": 988} } }, "warnings": null }, { - "id": 609, - "sourceNodeId": 149, - "sourcePortId": 1234, - "targetNodeId": 135, - "targetPortId": 1233, + "id": 665, + "sourceNodeId": 169, + "sourcePortId": 1345, + "targetNodeId": 153, + "targetPortId": 1346, "travelTime": { "lock": true, - "time": 15, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 43, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 103 + "consecutiveTime": 48 }, "sourceArrival": { "lock": true, - "time": 17, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 317 + "consecutiveTime": 252 }, "targetDeparture": { "lock": true, - "time": 2, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 302 + "consecutiveTime": 243 }, "targetArrival": { "lock": true, - "time": 58, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 118 + "consecutiveTime": 57 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 208}, - {"x": 2402, "y": 208}, - {"x": 2590, "y": 208}, - {"x": 2654, "y": 208} + {"x": 1954, "y": 1776}, + {"x": 2018, "y": 1776}, + {"x": 2590, "y": 1360}, + {"x": 2654, "y": 1360} ], "textPositions": { - "0": {"x": 2356, "y": 220}, - "1": {"x": 2384, "y": 196}, - "2": {"x": 2636, "y": 196}, - "3": {"x": 2608, "y": 220}, - "4": {"x": 2496, "y": 196}, - "5": {"x": 2496, "y": 196}, - "6": {"x": 2496, "y": 220} + "0": {"x": 1972, "y": 1788}, + "1": {"x": 2000, "y": 1764}, + "2": {"x": 2636, "y": 1348}, + "3": {"x": 2608, "y": 1372}, + "4": {"x": 2304, "y": 1556}, + "5": {"x": 2304, "y": 1556}, + "6": {"x": 2304, "y": 1580} } }, "warnings": null }, { - "id": 610, - "sourceNodeId": 166, - "sourcePortId": 1236, - "targetNodeId": 149, - "targetPortId": 1235, + "id": 666, + "sourceNodeId": 169, + "sourcePortId": 1347, + "targetNodeId": 153, + "targetPortId": 1348, "travelTime": { "lock": true, - "time": 6, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 37, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 97 + "consecutiveTime": 18 }, "sourceArrival": { "lock": false, - "time": 23, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 323 + "consecutiveTime": 42 }, "targetDeparture": { "lock": false, - "time": 17, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 317 + "consecutiveTime": 32 }, "targetArrival": { "lock": false, - "time": 43, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 103 + "consecutiveTime": 28 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 80, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 208}, - {"x": 1954, "y": 208}, - {"x": 2174, "y": 208}, - {"x": 2238, "y": 208} + {"x": 1954, "y": 1744}, + {"x": 2018, "y": 1744}, + {"x": 2590, "y": 1328}, + {"x": 2654, "y": 1328} ], "textPositions": { - "0": {"x": 1908, "y": 220}, - "1": {"x": 1936, "y": 196}, - "2": {"x": 2220, "y": 196}, - "3": {"x": 2192, "y": 220}, - "4": {"x": 2064, "y": 196}, - "5": {"x": 2064, "y": 196}, - "6": {"x": 2064, "y": 220} + "0": {"x": 1972, "y": 1756}, + "1": {"x": 2000, "y": 1732}, + "2": {"x": 2636, "y": 1316}, + "3": {"x": 2608, "y": 1340}, + "4": {"x": 2304, "y": 1524}, + "5": {"x": 2304, "y": 1524}, + "6": {"x": 2304, "y": 1548} } }, "warnings": null }, { - "id": 611, - "sourceNodeId": 147, - "sourcePortId": 1238, - "targetNodeId": 148, - "targetPortId": 1237, + "id": 667, + "sourceNodeId": 169, + "sourcePortId": 1349, + "targetNodeId": 142, + "targetPortId": 1350, "travelTime": { "lock": true, - "time": 5, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 25, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 85 + "consecutiveTime": 453 }, "sourceArrival": { "lock": false, - "time": 35, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 335 + "consecutiveTime": 147 }, "targetDeparture": { "lock": false, - "time": 30, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 138 }, "targetArrival": { "lock": false, - "time": 30, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 462 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { - "path": [ - {"x": 1058, "y": 208}, - {"x": 1122, "y": 208}, - {"x": 1278, "y": 208}, - {"x": 1342, "y": 208} + "path": [ + {"x": 1854, "y": 1776}, + {"x": 1790, "y": 1776}, + {"x": 290, "y": 1776}, + {"x": 226, "y": 1776} ], "textPositions": { - "0": {"x": 1076, "y": 220}, - "1": {"x": 1104, "y": 196}, - "2": {"x": 1324, "y": 196}, - "3": {"x": 1296, "y": 220}, - "4": {"x": 1200, "y": 196}, - "5": {"x": 1200, "y": 196}, - "6": {"x": 1200, "y": 220} + "0": {"x": 1836, "y": 1764}, + "1": {"x": 1808, "y": 1788}, + "2": {"x": 244, "y": 1788}, + "3": {"x": 272, "y": 1764}, + "4": {"x": 1040, "y": 1764}, + "5": {"x": 1040, "y": 1764}, + "6": {"x": 1040, "y": 1788} } }, "warnings": null }, { - "id": 612, - "sourceNodeId": 133, - "sourcePortId": 1240, - "targetNodeId": 147, - "targetPortId": 1239, + "id": 668, + "sourceNodeId": 169, + "sourcePortId": 1351, + "targetNodeId": 142, + "targetPortId": 1352, "travelTime": { "lock": true, - "time": 5, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 20, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 80 + "consecutiveTime": 273 }, "sourceArrival": { "lock": false, - "time": 40, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 340 + "consecutiveTime": 87 }, "targetDeparture": { - "lock": false, - "time": 35, + "lock": true, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 335 + "consecutiveTime": 78 }, "targetArrival": { - "lock": false, - "time": 25, + "lock": true, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 85 + "consecutiveTime": 282 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 75, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 258, "y": 208}, - {"x": 322, "y": 208}, - {"x": 894, "y": 208}, - {"x": 958, "y": 208} + {"x": 1854, "y": 1744}, + {"x": 1790, "y": 1744}, + {"x": 290, "y": 1744}, + {"x": 226, "y": 1744} ], "textPositions": { - "0": {"x": 276, "y": 220}, - "1": {"x": 304, "y": 196}, - "2": {"x": 940, "y": 196}, - "3": {"x": 912, "y": 220}, - "4": {"x": 608, "y": 196}, - "5": {"x": 608, "y": 196}, - "6": {"x": 608, "y": 220} + "0": {"x": 1836, "y": 1732}, + "1": {"x": 1808, "y": 1756}, + "2": {"x": 244, "y": 1756}, + "3": {"x": 272, "y": 1732}, + "4": {"x": 1040, "y": 1732}, + "5": {"x": 1040, "y": 1732}, + "6": {"x": 1040, "y": 1756} } }, "warnings": null }, { - "id": 613, - "sourceNodeId": 172, - "sourcePortId": 1242, - "targetNodeId": 133, - "targetPortId": 1241, + "id": 669, + "sourceNodeId": 170, + "sourcePortId": 1353, + "targetNodeId": 135, + "targetPortId": 1354, "travelTime": { "lock": true, - "time": 7, + "time": 11, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 73 + "consecutiveTime": 74 }, "sourceArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 226 }, "targetDeparture": { - "lock": false, - "time": 40, + "lock": true, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 340 + "consecutiveTime": 215 }, "targetArrival": { - "lock": false, - "time": 20, + "lock": true, + "time": 25, "warning": null, "timeFormatter": null, - "consecutiveTime": 80 + "consecutiveTime": 85 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -510, "y": 272}, - {"x": -446, "y": 272}, - {"x": -2, "y": 272}, - {"x": 62, "y": 272} + {"x": 2832, "y": 734}, + {"x": 2832, "y": 670}, + {"x": 2832, "y": 414}, + {"x": 2832, "y": 350} ], "textPositions": { - "0": {"x": -492, "y": 284}, - "1": {"x": -464, "y": 260}, - "2": {"x": 44, "y": 260}, - "3": {"x": 16, "y": 284}, - "4": {"x": -224, "y": 260}, - "5": {"x": -224, "y": 260}, - "6": {"x": -224, "y": 284} + "0": {"x": 2844, "y": 716}, + "1": {"x": 2820, "y": 688}, + "2": {"x": 2820, "y": 368}, + "3": {"x": 2844, "y": 396}, + "4": {"x": 2820, "y": 542}, + "5": {"x": 2820, "y": 542}, + "6": {"x": 2844, "y": 542} } }, "warnings": null }, { - "id": 614, - "sourceNodeId": 151, - "sourcePortId": 1243, - "targetNodeId": 162, - "targetPortId": 1244, + "id": 670, + "sourceNodeId": 170, + "sourcePortId": 1355, + "targetNodeId": 135, + "targetPortId": 1356, "travelTime": { "lock": true, - "time": 41, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 31, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 151 + "consecutiveTime": 43 }, "sourceArrival": { "lock": false, - "time": 29, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 269 + "consecutiveTime": 17 }, "targetDeparture": { - "lock": false, - "time": 48, + "lock": true, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 228 + "consecutiveTime": 10 }, "targetArrival": { - "lock": false, - "time": 12, + "lock": true, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 192 + "consecutiveTime": 50 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 80, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3970, "y": 80}, - {"x": 4034, "y": 80}, - {"x": 4574, "y": -144}, - {"x": 4638, "y": -144} + {"x": 2800, "y": 734}, + {"x": 2800, "y": 670}, + {"x": 2800, "y": 414}, + {"x": 2800, "y": 350} ], "textPositions": { - "0": {"x": 3988, "y": 92}, - "1": {"x": 4016, "y": 68}, - "2": {"x": 4620, "y": -156}, - "3": {"x": 4592, "y": -132}, - "4": {"x": 4304, "y": -44}, - "5": {"x": 4304, "y": -44}, - "6": {"x": 4304, "y": -20} + "0": {"x": 2812, "y": 716}, + "1": {"x": 2788, "y": 688}, + "2": {"x": 2788, "y": 368}, + "3": {"x": 2812, "y": 396}, + "4": {"x": 2788, "y": 542}, + "5": {"x": 2788, "y": 542}, + "6": {"x": 2812, "y": 542} } }, "warnings": null }, { - "id": 615, - "sourceNodeId": 135, - "sourcePortId": 1245, - "targetNodeId": 150, - "targetPortId": 1246, + "id": 671, + "sourceNodeId": 170, + "sourcePortId": 1357, + "targetNodeId": 135, + "targetPortId": 1358, "travelTime": { "lock": true, - "time": 9, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 35, + "lock": false, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 95 + "consecutiveTime": 347 }, "sourceArrival": { - "lock": true, - "time": 25, + "lock": false, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 205 + "consecutiveTime": 13 }, "targetDeparture": { "lock": true, - "time": 16, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 196 + "consecutiveTime": 5 }, "targetArrival": { "lock": true, - "time": 44, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 104 + "consecutiveTime": 355 }, "numberOfStops": 0, - "trainrunId": 79, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 208}, - {"x": 2914, "y": 208}, - {"x": 3230, "y": 208}, - {"x": 3294, "y": 208} + {"x": 2768, "y": 734}, + {"x": 2768, "y": 670}, + {"x": 2768, "y": 414}, + {"x": 2768, "y": 350} ], "textPositions": { - "0": {"x": 2868, "y": 220}, - "1": {"x": 2896, "y": 196}, - "2": {"x": 3276, "y": 196}, - "3": {"x": 3248, "y": 220}, - "4": {"x": 3072, "y": 196}, - "5": {"x": 3072, "y": 196}, - "6": {"x": 3072, "y": 220} + "0": {"x": 2780, "y": 716}, + "1": {"x": 2756, "y": 688}, + "2": {"x": 2756, "y": 368}, + "3": {"x": 2780, "y": 396}, + "4": {"x": 2756, "y": 542}, + "5": {"x": 2756, "y": 542}, + "6": {"x": 2780, "y": 542} } }, "warnings": null }, { - "id": 616, - "sourceNodeId": 150, - "sourcePortId": 1247, - "targetNodeId": 151, - "targetPortId": 1248, + "id": 672, + "sourceNodeId": 170, + "sourcePortId": 1359, + "targetNodeId": 135, + "targetPortId": 1360, "travelTime": { - "lock": false, - "time": 13, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 46, + "lock": false, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 107 }, "sourceArrival": { - "lock": true, - "time": 14, + "lock": false, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 194 + "consecutiveTime": 13 }, "targetDeparture": { "lock": true, - "time": 1, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 181 + "consecutiveTime": 5 }, "targetArrival": { "lock": true, - "time": 59, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 119 + "consecutiveTime": 115 }, "numberOfStops": 0, - "trainrunId": 79, + "trainrunId": 76, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3394, "y": 208}, - {"x": 3458, "y": 208}, - {"x": 3806, "y": 208}, - {"x": 3870, "y": 208} + {"x": 2672, "y": 734}, + {"x": 2672, "y": 670}, + {"x": 2672, "y": 414}, + {"x": 2672, "y": 350} ], "textPositions": { - "0": {"x": 3412, "y": 220}, - "1": {"x": 3440, "y": 196}, - "2": {"x": 3852, "y": 196}, - "3": {"x": 3824, "y": 220}, - "4": {"x": 3632, "y": 196}, - "5": {"x": 3632, "y": 196}, - "6": {"x": 3632, "y": 220} + "0": {"x": 2684, "y": 716}, + "1": {"x": 2660, "y": 688}, + "2": {"x": 2660, "y": 368}, + "3": {"x": 2684, "y": 396}, + "4": {"x": 2660, "y": 542}, + "5": {"x": 2660, "y": 542}, + "6": {"x": 2684, "y": 542} } }, "warnings": null }, { - "id": 617, - "sourceNodeId": 151, - "sourcePortId": 1249, - "targetNodeId": 139, - "targetPortId": 1250, + "id": 673, + "sourceNodeId": 170, + "sourcePortId": 1361, + "targetNodeId": 140, + "targetPortId": 1362, "travelTime": { - "lock": false, - "time": 49, + "lock": true, + "time": 47, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 1, + "lock": false, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 121 + "consecutiveTime": 75 }, "sourceArrival": { - "lock": true, - "time": 59, + "lock": false, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 179 + "consecutiveTime": 285 }, "targetDeparture": { "lock": true, - "time": 10, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 130 + "consecutiveTime": 238 }, "targetArrival": { "lock": true, - "time": 50, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 170 + "consecutiveTime": 122 }, - "numberOfStops": 2, - "trainrunId": 79, + "numberOfStops": 0, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 3888, "y": 30}, - {"x": 3888, "y": -34}, - {"x": 4272, "y": -286}, - {"x": 4272, "y": -350} + {"x": 2850, "y": 784}, + {"x": 2914, "y": 784}, + {"x": 4574, "y": 1200}, + {"x": 4638, "y": 1200} ], "textPositions": { - "0": {"x": 3900, "y": 12}, - "1": {"x": 3876, "y": -16}, - "2": {"x": 4260, "y": -332}, - "3": {"x": 4284, "y": -304}, - "4": {"x": 4068, "y": -160}, - "5": {"x": 4068, "y": -160}, - "6": {"x": 4092, "y": -160} + "0": {"x": 2868, "y": 796}, + "1": {"x": 2896, "y": 772}, + "2": {"x": 4620, "y": 1188}, + "3": {"x": 4592, "y": 1212}, + "4": {"x": 3744, "y": 980}, + "5": {"x": 3744, "y": 980}, + "6": {"x": 3744, "y": 1004} } }, "warnings": null }, { - "id": 618, - "sourceNodeId": 138, - "sourcePortId": 1251, - "targetNodeId": 163, - "targetPortId": 1252, + "id": 674, + "sourceNodeId": 170, + "sourcePortId": 1363, + "targetNodeId": 226, + "targetPortId": 1535, "travelTime": { - "lock": true, - "time": 1, + "lock": false, + "time": 30, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 0, + "lock": true, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 0 + "consecutiveTime": 141 }, "sourceArrival": { - "lock": false, - "time": 0, + "lock": true, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 279 }, "targetDeparture": { - "lock": false, - "time": 59, + "lock": true, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 59 + "consecutiveTime": 249 }, "targetArrival": { - "lock": false, - "time": 1, + "lock": true, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 1 + "consecutiveTime": 171 }, "numberOfStops": 0, - "trainrunId": 91, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": -1054}, - {"x": 2672, "y": -990}, - {"x": 2800, "y": -610}, - {"x": 2800, "y": -546} + {"x": 2850, "y": 752}, + {"x": 2914, "y": 752}, + {"x": 3582, "y": 976}, + {"x": 3646, "y": 976} ], "textPositions": { - "0": {"x": 2660, "y": -1036}, - "1": {"x": 2684, "y": -1008}, - "2": {"x": 2812, "y": -564}, - "3": {"x": 2788, "y": -592}, - "4": {"x": 2748, "y": -800}, - "5": {"x": 2748, "y": -800}, - "6": {"x": 2724, "y": -800} + "0": {"x": 2868, "y": 764}, + "1": {"x": 2896, "y": 740}, + "2": {"x": 3628, "y": 964}, + "3": {"x": 3600, "y": 988}, + "4": {"x": 3248, "y": 852}, + "5": {"x": 3248, "y": 852}, + "6": {"x": 3248, "y": 876} } }, "warnings": null }, { - "id": 619, - "sourceNodeId": 163, - "sourcePortId": 1253, - "targetNodeId": 135, - "targetPortId": 1254, + "id": 675, + "sourceNodeId": 142, + "sourcePortId": 1365, + "targetNodeId": 141, + "targetPortId": 1366, "travelTime": { "lock": true, - "time": 1, + "time": 19, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 3, + "lock": true, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 3 + "consecutiveTime": 475 }, "sourceArrival": { - "lock": false, - "time": 57, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 57 + "consecutiveTime": 125 }, "targetDeparture": { "lock": false, - "time": 56, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 56 + "consecutiveTime": 106 }, "targetArrival": { "lock": false, - "time": 4, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 4 + "consecutiveTime": 494 }, "numberOfStops": 0, - "trainrunId": 91, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2800, "y": -478}, - {"x": 2800, "y": -414}, - {"x": 2704, "y": -34}, - {"x": 2704, "y": 30} + {"x": 144, "y": 1726}, + {"x": 144, "y": 1662}, + {"x": 144, "y": 1314}, + {"x": 144, "y": 1250} ], "textPositions": { - "0": {"x": 2788, "y": -460}, - "1": {"x": 2812, "y": -432}, - "2": {"x": 2716, "y": 12}, - "3": {"x": 2692, "y": -16}, - "4": {"x": 2740, "y": -224}, - "5": {"x": 2740, "y": -224}, - "6": {"x": 2764, "y": -224} + "0": {"x": 156, "y": 1708}, + "1": {"x": 132, "y": 1680}, + "2": {"x": 132, "y": 1268}, + "3": {"x": 156, "y": 1296}, + "4": {"x": 132, "y": 1488}, + "5": {"x": 132, "y": 1488}, + "6": {"x": 156, "y": 1488} } }, "warnings": null }, { - "id": 620, - "sourceNodeId": 135, - "sourcePortId": 1255, - "targetNodeId": 138, - "targetPortId": 1256, + "id": 676, + "sourceNodeId": 141, + "sourcePortId": 1367, + "targetNodeId": 143, + "targetPortId": 1368, "travelTime": { "lock": true, - "time": 1, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 0, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 120 + "consecutiveTime": 494 }, "sourceArrival": { "lock": false, - "time": 0, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 106 }, "targetDeparture": { "lock": false, - "time": 59, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 59 + "consecutiveTime": 99 }, "targetArrival": { "lock": false, - "time": 1, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 121 + "consecutiveTime": 501 }, "numberOfStops": 0, - "trainrunId": 92, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 30}, - {"x": 2672, "y": -34}, - {"x": 2640, "y": -990}, - {"x": 2640, "y": -1054} + {"x": 144, "y": 1182}, + {"x": 144, "y": 1118}, + {"x": 144, "y": 866}, + {"x": 144, "y": 802} ], - "textPositions": { - "0": {"x": 2684, "y": 12}, - "1": {"x": 2660, "y": -16}, - "2": {"x": 2628, "y": -1036}, - "3": {"x": 2652, "y": -1008}, - "4": {"x": 2668, "y": -512}, - "5": {"x": 2668, "y": -512}, - "6": {"x": 2644, "y": -512} + "textPositions": { + "0": {"x": 156, "y": 1164}, + "1": {"x": 132, "y": 1136}, + "2": {"x": 132, "y": 820}, + "3": {"x": 156, "y": 848}, + "4": {"x": 132, "y": 992}, + "5": {"x": 132, "y": 992}, + "6": {"x": 156, "y": 992} } }, "warnings": null }, { - "id": 621, - "sourceNodeId": 166, - "sourcePortId": 1257, - "targetNodeId": 148, - "targetPortId": 1258, + "id": 677, + "sourceNodeId": 143, + "sourcePortId": 1369, + "targetNodeId": 133, + "targetPortId": 1370, "travelTime": { "lock": true, - "time": 5, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 56, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 356 + "consecutiveTime": 503 }, "sourceArrival": { "lock": false, - "time": 4, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 184 + "consecutiveTime": 97 }, "targetDeparture": { "lock": false, - "time": 59, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 179 + "consecutiveTime": 90 }, "targetArrival": { "lock": false, - "time": 1, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 361 + "consecutiveTime": 510 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1790, "y": 48}, - {"x": 1726, "y": 48}, - {"x": 1506, "y": 48}, - {"x": 1442, "y": 48} + {"x": 112, "y": 734}, + {"x": 112, "y": 670}, + {"x": 112, "y": 414}, + {"x": 112, "y": 350} ], "textPositions": { - "0": {"x": 1772, "y": 36}, - "1": {"x": 1744, "y": 60}, - "2": {"x": 1460, "y": 60}, - "3": {"x": 1488, "y": 36}, - "4": {"x": 1616, "y": 36}, - "5": {"x": 1616, "y": 36}, - "6": {"x": 1616, "y": 60} + "0": {"x": 124, "y": 716}, + "1": {"x": 100, "y": 688}, + "2": {"x": 100, "y": 368}, + "3": {"x": 124, "y": 396}, + "4": {"x": 100, "y": 542}, + "5": {"x": 100, "y": 542}, + "6": {"x": 124, "y": 542} } }, "warnings": null }, { - "id": 622, - "sourceNodeId": 166, - "sourcePortId": 1259, - "targetNodeId": 148, - "targetPortId": 1260, + "id": 678, + "sourceNodeId": 133, + "sourcePortId": 1371, + "targetNodeId": 144, + "targetPortId": 1372, "travelTime": { "lock": true, - "time": 7, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 17, + "lock": true, + "time": 32, "warning": null, "timeFormatter": null, - "consecutiveTime": 377 + "consecutiveTime": 512 }, "sourceArrival": { - "lock": false, - "time": 43, + "lock": true, + "time": 28, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 88 }, "targetDeparture": { "lock": false, - "time": 36, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 156 + "consecutiveTime": 78 }, "targetArrival": { "lock": false, - "time": 24, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 384 + "consecutiveTime": 522 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1790, "y": 144}, - {"x": 1726, "y": 144}, - {"x": 1506, "y": 144}, - {"x": 1442, "y": 144} + {"x": 176, "y": 94}, + {"x": 176, "y": 30}, + {"x": 176, "y": -290}, + {"x": 176, "y": -354} ], "textPositions": { - "0": {"x": 1772, "y": 132}, - "1": {"x": 1744, "y": 156}, - "2": {"x": 1460, "y": 156}, - "3": {"x": 1488, "y": 132}, - "4": {"x": 1616, "y": 132}, - "5": {"x": 1616, "y": 132}, - "6": {"x": 1616, "y": 156} + "0": {"x": 188, "y": 76}, + "1": {"x": 164, "y": 48}, + "2": {"x": 164, "y": -336}, + "3": {"x": 188, "y": -308}, + "4": {"x": 164, "y": -130}, + "5": {"x": 164, "y": -130}, + "6": {"x": 188, "y": -130} } }, "warnings": null }, { - "id": 623, - "sourceNodeId": 148, - "sourcePortId": 1262, - "targetNodeId": 166, - "targetPortId": 1261, + "id": 679, + "sourceNodeId": 144, + "sourcePortId": 1373, + "targetNodeId": 145, + "targetPortId": 1374, "travelTime": { "lock": true, - "time": 6, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 40, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 100 + "consecutiveTime": 522 }, "sourceArrival": { "lock": false, - "time": 20, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 320 + "consecutiveTime": 78 }, "targetDeparture": { "lock": false, - "time": 14, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 73 }, "targetArrival": { "lock": false, - "time": 46, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 527 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 176}, - {"x": 1506, "y": 176}, - {"x": 1726, "y": 176}, - {"x": 1790, "y": 176} + {"x": 240, "y": -450}, + {"x": 240, "y": -514}, + {"x": 240, "y": -798}, + {"x": 240, "y": -862} ], "textPositions": { - "0": {"x": 1460, "y": 188}, - "1": {"x": 1488, "y": 164}, - "2": {"x": 1772, "y": 164}, - "3": {"x": 1744, "y": 188}, - "4": {"x": 1616, "y": 164}, - "5": {"x": 1616, "y": 164}, - "6": {"x": 1616, "y": 188} + "0": {"x": 252, "y": -468}, + "1": {"x": 228, "y": -496}, + "2": {"x": 228, "y": -844}, + "3": {"x": 252, "y": -816}, + "4": {"x": 228, "y": -656}, + "5": {"x": 228, "y": -656}, + "6": {"x": 252, "y": -656} } }, "warnings": null }, { - "id": 624, - "sourceNodeId": 148, - "sourcePortId": 1264, - "targetNodeId": 166, - "targetPortId": 1263, + "id": 680, + "sourceNodeId": 145, + "sourcePortId": 1375, + "targetNodeId": 146, + "targetPortId": 1376, "travelTime": { "lock": true, "time": 5, @@ -9269,957 +14487,963 @@ }, "sourceDeparture": { "lock": false, - "time": 30, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 527 }, "sourceArrival": { "lock": false, - "time": 30, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 330 + "consecutiveTime": 73 }, "targetDeparture": { "lock": false, - "time": 25, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 325 + "consecutiveTime": 68 }, "targetArrival": { "lock": false, - "time": 35, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 95 + "consecutiveTime": 532 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 208}, - {"x": 1506, "y": 208}, - {"x": 1726, "y": 208}, - {"x": 1790, "y": 208} + {"x": 240, "y": -930}, + {"x": 240, "y": -994}, + {"x": 240, "y": -1278}, + {"x": 240, "y": -1342} ], "textPositions": { - "0": {"x": 1460, "y": 220}, - "1": {"x": 1488, "y": 196}, - "2": {"x": 1772, "y": 196}, - "3": {"x": 1744, "y": 220}, - "4": {"x": 1616, "y": 196}, - "5": {"x": 1616, "y": 196}, - "6": {"x": 1616, "y": 220} + "0": {"x": 252, "y": -948}, + "1": {"x": 228, "y": -976}, + "2": {"x": 228, "y": -1324}, + "3": {"x": 252, "y": -1296}, + "4": {"x": 228, "y": -1136}, + "5": {"x": 228, "y": -1136}, + "6": {"x": 252, "y": -1136} } }, "warnings": null }, { - "id": 625, - "sourceNodeId": 148, - "sourcePortId": 1266, - "targetNodeId": 166, - "targetPortId": 1265, + "id": 681, + "sourceNodeId": 146, + "sourcePortId": 1377, + "targetNodeId": 134, + "targetPortId": 1378, "travelTime": { "lock": true, - "time": 7, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 45, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 105 + "consecutiveTime": 532 }, "sourceArrival": { "lock": false, - "time": 15, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 315 + "consecutiveTime": 68 }, "targetDeparture": { - "lock": false, - "time": 8, + "lock": true, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 63 }, "targetArrival": { - "lock": false, - "time": 52, + "lock": true, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 537 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 240}, - {"x": 1506, "y": 240}, - {"x": 1726, "y": 240}, - {"x": 1790, "y": 240} + {"x": 240, "y": -1410}, + {"x": 240, "y": -1474}, + {"x": 240, "y": -1758}, + {"x": 240, "y": -1822} ], "textPositions": { - "0": {"x": 1460, "y": 252}, - "1": {"x": 1488, "y": 228}, - "2": {"x": 1772, "y": 228}, - "3": {"x": 1744, "y": 252}, - "4": {"x": 1616, "y": 228}, - "5": {"x": 1616, "y": 228}, - "6": {"x": 1616, "y": 252} + "0": {"x": 252, "y": -1428}, + "1": {"x": 228, "y": -1456}, + "2": {"x": 228, "y": -1804}, + "3": {"x": 252, "y": -1776}, + "4": {"x": 228, "y": -1616}, + "5": {"x": 228, "y": -1616}, + "6": {"x": 252, "y": -1616} } }, "warnings": null }, { - "id": 626, - "sourceNodeId": 134, - "sourcePortId": 1267, - "targetNodeId": 164, - "targetPortId": 1268, + "id": 682, + "sourceNodeId": 171, + "sourcePortId": 1379, + "targetNodeId": 231, + "targetPortId": 1545, "travelTime": { - "lock": true, - "time": 13, + "lock": false, + "time": 24, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 11, + "lock": true, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 11 + "consecutiveTime": 387 }, "sourceArrival": { - "lock": false, - "time": 49, + "lock": true, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 169 + "consecutiveTime": 153 }, "targetDeparture": { - "lock": false, - "time": 36, - "warning": null, + "lock": true, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 156 + "consecutiveTime": 129 }, "targetArrival": { - "lock": false, - "time": 24, - "warning": null, + "lock": true, + "time": 51, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 24 + "consecutiveTime": 411 }, "numberOfStops": 0, - "trainrunId": 93, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 322, "y": -1872}, - {"x": 386, "y": -1872}, - {"x": 990, "y": -944}, - {"x": 1054, "y": -944} + {"x": -2562, "y": 304}, + {"x": -2626, "y": 304}, + {"x": -2654, "y": 432}, + {"x": -2718, "y": 432} ], "textPositions": { - "0": {"x": 340, "y": -1860}, - "1": {"x": 368, "y": -1884}, - "2": {"x": 1036, "y": -956}, - "3": {"x": 1008, "y": -932}, - "4": {"x": 688, "y": -1420}, - "5": {"x": 688, "y": -1420}, - "6": {"x": 688, "y": -1396} + "0": {"x": -2580, "y": 292}, + "1": {"x": -2608, "y": 316}, + "2": {"x": -2700, "y": 444}, + "3": {"x": -2672, "y": 420}, + "4": {"x": -2640, "y": 356}, + "5": {"x": -2640, "y": 356}, + "6": {"x": -2640, "y": 380} } }, "warnings": null }, { - "id": 627, - "sourceNodeId": 164, - "sourcePortId": 1269, - "targetNodeId": 165, - "targetPortId": 1270, + "id": 683, + "sourceNodeId": 171, + "sourcePortId": 1381, + "targetNodeId": 128, + "targetPortId": 1382, "travelTime": { "lock": true, - "time": 9, + "time": 44, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 25, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 25 + "consecutiveTime": 414 }, "sourceArrival": { "lock": false, - "time": 35, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 155 + "consecutiveTime": 126 }, "targetDeparture": { "lock": false, - "time": 26, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 146 + "consecutiveTime": 82 }, "targetArrival": { "lock": false, - "time": 34, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 34 + "consecutiveTime": 458 }, "numberOfStops": 0, - "trainrunId": 93, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1154, "y": -944}, - {"x": 1218, "y": -944}, - {"x": 1726, "y": -656}, - {"x": 1790, "y": -656} + {"x": -2562, "y": 336}, + {"x": -2626, "y": 336}, + {"x": -2910, "y": 560}, + {"x": -2974, "y": 560} ], "textPositions": { - "0": {"x": 1172, "y": -932}, - "1": {"x": 1200, "y": -956}, - "2": {"x": 1772, "y": -668}, - "3": {"x": 1744, "y": -644}, - "4": {"x": 1472, "y": -812}, - "5": {"x": 1472, "y": -812}, - "6": {"x": 1472, "y": -788} + "0": {"x": -2580, "y": 324}, + "1": {"x": -2608, "y": 348}, + "2": {"x": -2956, "y": 572}, + "3": {"x": -2928, "y": 548}, + "4": {"x": -2768, "y": 436}, + "5": {"x": -2768, "y": 436}, + "6": {"x": -2768, "y": 460} } }, "warnings": null }, { - "id": 628, - "sourceNodeId": 165, - "sourcePortId": 1271, - "targetNodeId": 166, - "targetPortId": 1272, + "id": 684, + "sourceNodeId": 172, + "sourcePortId": 1383, + "targetNodeId": 178, + "targetPortId": 1384, "travelTime": { "lock": true, - "time": 22, + "time": 16, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 35, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 339 }, "sourceArrival": { "lock": false, - "time": 25, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 145 + "consecutiveTime": 201 }, "targetDeparture": { "lock": false, - "time": 3, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 123 + "consecutiveTime": 185 }, "targetArrival": { "lock": false, - "time": 57, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 57 + "consecutiveTime": 355 }, "numberOfStops": 0, - "trainrunId": 93, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1808, "y": -606}, - {"x": 1808, "y": -542}, - {"x": 1808, "y": -34}, - {"x": 1808, "y": 30} + {"x": -610, "y": 304}, + {"x": -674, "y": 304}, + {"x": -1534, "y": 304}, + {"x": -1598, "y": 304} ], "textPositions": { - "0": {"x": 1796, "y": -588}, - "1": {"x": 1820, "y": -560}, - "2": {"x": 1820, "y": 12}, - "3": {"x": 1796, "y": -16}, - "4": {"x": 1796, "y": -288}, - "5": {"x": 1796, "y": -288}, - "6": {"x": 1820, "y": -288} + "0": {"x": -628, "y": 292}, + "1": {"x": -656, "y": 316}, + "2": {"x": -1580, "y": 316}, + "3": {"x": -1552, "y": 292}, + "4": {"x": -1104, "y": 292}, + "5": {"x": -1104, "y": 292}, + "6": {"x": -1104, "y": 316} } }, "warnings": null }, { - "id": 629, - "sourceNodeId": 166, - "sourcePortId": 1273, - "targetNodeId": 149, - "targetPortId": 1274, + "id": 685, + "sourceNodeId": 174, + "sourcePortId": 1386, + "targetNodeId": 172, + "targetPortId": 1385, "travelTime": { "lock": true, - "time": 7, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 0, + "lock": true, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 69 }, "sourceArrival": { - "lock": false, - "time": 0, + "lock": true, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 120 + "consecutiveTime": 351 }, "targetDeparture": { "lock": false, - "time": 53, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 113 + "consecutiveTime": 343 }, "targetArrival": { "lock": false, - "time": 7, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 67 + "consecutiveTime": 77 }, "numberOfStops": 0, - "trainrunId": 93, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 272}, - {"x": 1954, "y": 272}, - {"x": 2174, "y": 272}, - {"x": 2238, "y": 272} + {"x": -894, "y": 368}, + {"x": -830, "y": 368}, + {"x": -674, "y": 336}, + {"x": -610, "y": 336} ], "textPositions": { - "0": {"x": 1908, "y": 284}, - "1": {"x": 1936, "y": 260}, - "2": {"x": 2220, "y": 260}, - "3": {"x": 2192, "y": 284}, - "4": {"x": 2064, "y": 260}, - "5": {"x": 2064, "y": 260}, - "6": {"x": 2064, "y": 284} + "0": {"x": -876, "y": 380}, + "1": {"x": -848, "y": 356}, + "2": {"x": -628, "y": 324}, + "3": {"x": -656, "y": 348}, + "4": {"x": -752, "y": 340}, + "5": {"x": -752, "y": 340}, + "6": {"x": -752, "y": 364} } }, "warnings": null }, { - "id": 630, - "sourceNodeId": 149, - "sourcePortId": 1275, - "targetNodeId": 135, - "targetPortId": 1276, + "id": 686, + "sourceNodeId": 178, + "sourcePortId": 1388, + "targetNodeId": 172, + "targetPortId": 1387, "travelTime": { "lock": true, - "time": 16, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 8, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 65 }, "sourceArrival": { "lock": false, - "time": 52, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 355 }, "targetDeparture": { "lock": false, - "time": 36, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 96 + "consecutiveTime": 347 }, "targetArrival": { "lock": false, - "time": 24, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 84 + "consecutiveTime": 73 }, "numberOfStops": 0, - "trainrunId": 93, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 272}, - {"x": 2402, "y": 272}, - {"x": 2590, "y": 272}, - {"x": 2654, "y": 272} + {"x": -1598, "y": 272}, + {"x": -1534, "y": 272}, + {"x": -674, "y": 272}, + {"x": -610, "y": 272} ], "textPositions": { - "0": {"x": 2356, "y": 284}, - "1": {"x": 2384, "y": 260}, - "2": {"x": 2636, "y": 260}, - "3": {"x": 2608, "y": 284}, - "4": {"x": 2496, "y": 260}, - "5": {"x": 2496, "y": 260}, - "6": {"x": 2496, "y": 284} + "0": {"x": -1580, "y": 284}, + "1": {"x": -1552, "y": 260}, + "2": {"x": -628, "y": 260}, + "3": {"x": -656, "y": 284}, + "4": {"x": -1104, "y": 260}, + "5": {"x": -1104, "y": 260}, + "6": {"x": -1104, "y": 284} } }, "warnings": null }, { - "id": 631, - "sourceNodeId": 134, - "sourcePortId": 1277, - "targetNodeId": 146, - "targetPortId": 1278, + "id": 687, + "sourceNodeId": 178, + "sourcePortId": 1390, + "targetNodeId": 172, + "targetPortId": 1389, "travelTime": { - "lock": true, - "time": 5, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, + "lock": true, "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 6 + "consecutiveTime": 66 }, "sourceArrival": { - "lock": false, + "lock": true, "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 174 + "consecutiveTime": 354 }, "targetDeparture": { "lock": false, - "time": 49, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 169 + "consecutiveTime": 337 }, "targetArrival": { "lock": false, - "time": 11, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 11 + "consecutiveTime": 83 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 89, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": -1822}, - {"x": 144, "y": -1758}, - {"x": 144, "y": -1474}, - {"x": 144, "y": -1410} + {"x": -1598, "y": 240}, + {"x": -1534, "y": 240}, + {"x": -674, "y": 240}, + {"x": -610, "y": 240} ], "textPositions": { - "0": {"x": 132, "y": -1804}, - "1": {"x": 156, "y": -1776}, - "2": {"x": 156, "y": -1428}, - "3": {"x": 132, "y": -1456}, - "4": {"x": 132, "y": -1616}, - "5": {"x": 132, "y": -1616}, - "6": {"x": 156, "y": -1616} + "0": {"x": -1580, "y": 252}, + "1": {"x": -1552, "y": 228}, + "2": {"x": -628, "y": 228}, + "3": {"x": -656, "y": 252}, + "4": {"x": -1104, "y": 228}, + "5": {"x": -1104, "y": 228}, + "6": {"x": -1104, "y": 252} } }, "warnings": null }, { - "id": 632, - "sourceNodeId": 146, - "sourcePortId": 1279, - "targetNodeId": 145, - "targetPortId": 1280, + "id": 688, + "sourceNodeId": 172, + "sourcePortId": 1391, + "targetNodeId": 178, + "targetPortId": 1392, "travelTime": { "lock": true, - "time": 6, + "time": 18, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 11, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 11 + "consecutiveTime": 65 }, "sourceArrival": { "lock": false, - "time": 49, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 169 + "consecutiveTime": 235 }, "targetDeparture": { "lock": false, - "time": 43, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 217 }, "targetArrival": { "lock": false, - "time": 17, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 17 + "consecutiveTime": 83 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": -1342}, - {"x": 144, "y": -1278}, - {"x": 144, "y": -994}, - {"x": 144, "y": -930} + {"x": -610, "y": 208}, + {"x": -674, "y": 208}, + {"x": -1534, "y": 208}, + {"x": -1598, "y": 208} ], "textPositions": { - "0": {"x": 132, "y": -1324}, - "1": {"x": 156, "y": -1296}, - "2": {"x": 156, "y": -948}, - "3": {"x": 132, "y": -976}, - "4": {"x": 132, "y": -1136}, - "5": {"x": 132, "y": -1136}, - "6": {"x": 156, "y": -1136} + "0": {"x": -628, "y": 196}, + "1": {"x": -656, "y": 220}, + "2": {"x": -1580, "y": 220}, + "3": {"x": -1552, "y": 196}, + "4": {"x": -1104, "y": 196}, + "5": {"x": -1104, "y": 196}, + "6": {"x": -1104, "y": 220} } }, "warnings": null }, { - "id": 633, - "sourceNodeId": 145, - "sourcePortId": 1281, - "targetNodeId": 144, - "targetPortId": 1282, + "id": 689, + "sourceNodeId": 172, + "sourcePortId": 1393, + "targetNodeId": 133, + "targetPortId": 1394, "travelTime": { "lock": true, - "time": 6, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 17, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 17 + "consecutiveTime": 234 }, "sourceArrival": { "lock": false, - "time": 43, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 66 }, "targetDeparture": { - "lock": false, - "time": 37, + "lock": true, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 157 + "consecutiveTime": 58 }, "targetArrival": { - "lock": false, - "time": 23, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 23 + "consecutiveTime": 242 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 96, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": -862}, - {"x": 144, "y": -798}, - {"x": 144, "y": -514}, - {"x": 144, "y": -450} + {"x": -510, "y": 176}, + {"x": -446, "y": 176}, + {"x": -2, "y": 176}, + {"x": 62, "y": 176} ], "textPositions": { - "0": {"x": 132, "y": -844}, - "1": {"x": 156, "y": -816}, - "2": {"x": 156, "y": -468}, - "3": {"x": 132, "y": -496}, - "4": {"x": 132, "y": -656}, - "5": {"x": 132, "y": -656}, - "6": {"x": 156, "y": -656} + "0": {"x": -492, "y": 188}, + "1": {"x": -464, "y": 164}, + "2": {"x": 44, "y": 164}, + "3": {"x": 16, "y": 188}, + "4": {"x": -224, "y": 164}, + "5": {"x": -224, "y": 164}, + "6": {"x": -224, "y": 188} } }, "warnings": null }, { - "id": 634, - "sourceNodeId": 144, - "sourcePortId": 1283, - "targetNodeId": 147, - "targetPortId": 1284, + "id": 690, + "sourceNodeId": 172, + "sourcePortId": 1395, + "targetNodeId": 178, + "targetPortId": 1396, "travelTime": { "lock": true, - "time": 10, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 23, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 23 + "consecutiveTime": 377 }, "sourceArrival": { "lock": false, - "time": 37, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 157 + "consecutiveTime": 163 }, "targetDeparture": { "lock": false, - "time": 27, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 147 + "consecutiveTime": 154 }, "targetArrival": { "lock": false, - "time": 33, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 33 + "consecutiveTime": 386 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 322, "y": -400}, - {"x": 386, "y": -400}, - {"x": 894, "y": 80}, - {"x": 958, "y": 80} + {"x": -610, "y": 144}, + {"x": -674, "y": 144}, + {"x": -1534, "y": 144}, + {"x": -1598, "y": 144} ], "textPositions": { - "0": {"x": 340, "y": -388}, - "1": {"x": 368, "y": -412}, - "2": {"x": 940, "y": 68}, - "3": {"x": 912, "y": 92}, - "4": {"x": 640, "y": -172}, - "5": {"x": 640, "y": -172}, - "6": {"x": 640, "y": -148} + "0": {"x": -628, "y": 132}, + "1": {"x": -656, "y": 156}, + "2": {"x": -1580, "y": 156}, + "3": {"x": -1552, "y": 132}, + "4": {"x": -1104, "y": 132}, + "5": {"x": -1104, "y": 132}, + "6": {"x": -1104, "y": 156} } }, "warnings": null }, { - "id": 635, - "sourceNodeId": 147, - "sourcePortId": 1285, - "targetNodeId": 148, - "targetPortId": 1286, + "id": 691, + "sourceNodeId": 178, + "sourcePortId": 1398, + "targetNodeId": 173, + "targetPortId": 1397, "travelTime": { "lock": true, - "time": 7, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 33, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 33 + "consecutiveTime": 39 }, "sourceArrival": { "lock": false, - "time": 27, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 147 + "consecutiveTime": 381 }, "targetDeparture": { - "lock": false, - "time": 20, + "lock": true, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 140 + "consecutiveTime": 371 }, "targetArrival": { - "lock": false, - "time": 40, + "lock": true, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 40 + "consecutiveTime": 49 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1058, "y": 112}, - {"x": 1122, "y": 112}, - {"x": 1278, "y": 112}, - {"x": 1342, "y": 112} + {"x": -1598, "y": 336}, + {"x": -1534, "y": 336}, + {"x": -1410, "y": 368}, + {"x": -1346, "y": 368} ], "textPositions": { - "0": {"x": 1076, "y": 124}, - "1": {"x": 1104, "y": 100}, - "2": {"x": 1324, "y": 100}, - "3": {"x": 1296, "y": 124}, - "4": {"x": 1200, "y": 100}, - "5": {"x": 1200, "y": 100}, - "6": {"x": 1200, "y": 124} + "0": {"x": -1580, "y": 348}, + "1": {"x": -1552, "y": 324}, + "2": {"x": -1364, "y": 356}, + "3": {"x": -1392, "y": 380}, + "4": {"x": -1472, "y": 340}, + "5": {"x": -1472, "y": 340}, + "6": {"x": -1472, "y": 364} } }, "warnings": null }, { - "id": 636, - "sourceNodeId": 148, - "sourcePortId": 1287, - "targetNodeId": 166, - "targetPortId": 1288, + "id": 692, + "sourceNodeId": 173, + "sourcePortId": 1400, + "targetNodeId": 233, + "targetPortId": 1549, "travelTime": { "lock": true, - "time": 6, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 40, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 40 + "consecutiveTime": 51 }, "sourceArrival": { "lock": false, - "time": 20, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 140 + "consecutiveTime": 369 }, "targetDeparture": { - "lock": false, - "time": 14, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 361 }, "targetArrival": { - "lock": false, - "time": 46, + "lock": true, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 59 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 112}, - {"x": 1506, "y": 112}, - {"x": 1726, "y": 112}, - {"x": 1790, "y": 112} + {"x": -1246, "y": 368}, + {"x": -1182, "y": 368}, + {"x": -1234, "y": 368}, + {"x": -1170, "y": 368} ], "textPositions": { - "0": {"x": 1460, "y": 124}, - "1": {"x": 1488, "y": 100}, - "2": {"x": 1772, "y": 100}, - "3": {"x": 1744, "y": 124}, - "4": {"x": 1616, "y": 100}, - "5": {"x": 1616, "y": 100}, - "6": {"x": 1616, "y": 124} + "0": {"x": -1228, "y": 380}, + "1": {"x": -1200, "y": 356}, + "2": {"x": -1188, "y": 356}, + "3": {"x": -1216, "y": 380}, + "4": {"x": -1208, "y": 356}, + "5": {"x": -1208, "y": 356}, + "6": {"x": -1208, "y": 380} } }, "warnings": null }, { - "id": 637, - "sourceNodeId": 166, - "sourcePortId": 1289, - "targetNodeId": 149, - "targetPortId": 1290, + "id": 693, + "sourceNodeId": 149, + "sourcePortId": 1402, + "targetNodeId": 135, + "targetPortId": 1401, "travelTime": { "lock": true, - "time": 6, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 46, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 52 }, "sourceArrival": { "lock": false, - "time": 14, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 134 + "consecutiveTime": 308 }, "targetDeparture": { - "lock": false, - "time": 8, + "lock": true, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 128 + "consecutiveTime": 300 }, "targetArrival": { - "lock": false, - "time": 52, + "lock": true, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 60 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 112}, - {"x": 1954, "y": 112}, - {"x": 2174, "y": 112}, - {"x": 2238, "y": 112} + {"x": 2338, "y": 80}, + {"x": 2402, "y": 80}, + {"x": 2590, "y": 80}, + {"x": 2654, "y": 80} ], "textPositions": { - "0": {"x": 1908, "y": 124}, - "1": {"x": 1936, "y": 100}, - "2": {"x": 2220, "y": 100}, - "3": {"x": 2192, "y": 124}, - "4": {"x": 2064, "y": 100}, - "5": {"x": 2064, "y": 100}, - "6": {"x": 2064, "y": 124} + "0": {"x": 2356, "y": 92}, + "1": {"x": 2384, "y": 68}, + "2": {"x": 2636, "y": 68}, + "3": {"x": 2608, "y": 92}, + "4": {"x": 2496, "y": 68}, + "5": {"x": 2496, "y": 68}, + "6": {"x": 2496, "y": 92} } }, "warnings": null }, { - "id": 638, - "sourceNodeId": 149, - "sourcePortId": 1291, - "targetNodeId": 135, - "targetPortId": 1292, + "id": 694, + "sourceNodeId": 166, + "sourcePortId": 1404, + "targetNodeId": 149, + "targetPortId": 1403, "travelTime": { "lock": true, - "time": 8, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 52, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 46 }, "sourceArrival": { "lock": false, - "time": 8, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 128 + "consecutiveTime": 314 }, "targetDeparture": { "lock": false, - "time": 0, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 120 + "consecutiveTime": 308 }, "targetArrival": { "lock": false, - "time": 0, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 52 }, "numberOfStops": 0, - "trainrunId": 94, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 112}, - {"x": 2402, "y": 112}, - {"x": 2590, "y": 112}, - {"x": 2654, "y": 112} + {"x": 1890, "y": 80}, + {"x": 1954, "y": 80}, + {"x": 2174, "y": 80}, + {"x": 2238, "y": 80} ], "textPositions": { - "0": {"x": 2356, "y": 124}, - "1": {"x": 2384, "y": 100}, - "2": {"x": 2636, "y": 100}, - "3": {"x": 2608, "y": 124}, - "4": {"x": 2496, "y": 100}, - "5": {"x": 2496, "y": 100}, - "6": {"x": 2496, "y": 124} + "0": {"x": 1908, "y": 92}, + "1": {"x": 1936, "y": 68}, + "2": {"x": 2220, "y": 68}, + "3": {"x": 2192, "y": 92}, + "4": {"x": 2064, "y": 68}, + "5": {"x": 2064, "y": 68}, + "6": {"x": 2064, "y": 92} } }, "warnings": null }, { - "id": 639, - "sourceNodeId": 147, - "sourcePortId": 1293, - "targetNodeId": 148, - "targetPortId": 1294, + "id": 695, + "sourceNodeId": 148, + "sourcePortId": 1406, + "targetNodeId": 166, + "targetPortId": 1405, "travelTime": { "lock": true, "time": 6, @@ -10229,61 +15453,61 @@ }, "sourceDeparture": { "lock": false, - "time": 54, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 54 + "consecutiveTime": 40 }, "sourceArrival": { "lock": false, - "time": 6, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 126 + "consecutiveTime": 320 }, "targetDeparture": { "lock": false, - "time": 0, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 120 + "consecutiveTime": 314 }, "targetArrival": { "lock": false, - "time": 0, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 46 }, "numberOfStops": 0, - "trainrunId": 97, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1058, "y": 272}, - {"x": 1122, "y": 272}, - {"x": 1278, "y": 272}, - {"x": 1342, "y": 272} + {"x": 1442, "y": 80}, + {"x": 1506, "y": 80}, + {"x": 1726, "y": 80}, + {"x": 1790, "y": 80} ], "textPositions": { - "0": {"x": 1076, "y": 284}, - "1": {"x": 1104, "y": 260}, - "2": {"x": 1324, "y": 260}, - "3": {"x": 1296, "y": 284}, - "4": {"x": 1200, "y": 260}, - "5": {"x": 1200, "y": 260}, - "6": {"x": 1200, "y": 284} + "0": {"x": 1460, "y": 92}, + "1": {"x": 1488, "y": 68}, + "2": {"x": 1772, "y": 68}, + "3": {"x": 1744, "y": 92}, + "4": {"x": 1616, "y": 68}, + "5": {"x": 1616, "y": 68}, + "6": {"x": 1616, "y": 92} } - }, - "warnings": null - }, - { - "id": 640, - "sourceNodeId": 148, - "sourcePortId": 1295, - "targetNodeId": 166, - "targetPortId": 1296, + }, + "warnings": null + }, + { + "id": 696, + "sourceNodeId": 147, + "sourcePortId": 1408, + "targetNodeId": 148, + "targetPortId": 1407, "travelTime": { "lock": true, "time": 6, @@ -10293,61 +15517,61 @@ }, "sourceDeparture": { "lock": false, - "time": 2, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 62 + "consecutiveTime": 34 }, "sourceArrival": { "lock": false, - "time": 58, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 118 + "consecutiveTime": 326 }, "targetDeparture": { "lock": false, - "time": 52, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 320 }, "targetArrival": { "lock": false, - "time": 8, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 40 }, "numberOfStops": 0, - "trainrunId": 97, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 272}, - {"x": 1506, "y": 272}, - {"x": 1726, "y": 272}, - {"x": 1790, "y": 272} + {"x": 1058, "y": 80}, + {"x": 1122, "y": 80}, + {"x": 1278, "y": 80}, + {"x": 1342, "y": 80} ], "textPositions": { - "0": {"x": 1460, "y": 284}, - "1": {"x": 1488, "y": 260}, - "2": {"x": 1772, "y": 260}, - "3": {"x": 1744, "y": 284}, - "4": {"x": 1616, "y": 260}, - "5": {"x": 1616, "y": 260}, - "6": {"x": 1616, "y": 284} + "0": {"x": 1076, "y": 92}, + "1": {"x": 1104, "y": 68}, + "2": {"x": 1324, "y": 68}, + "3": {"x": 1296, "y": 92}, + "4": {"x": 1200, "y": 68}, + "5": {"x": 1200, "y": 68}, + "6": {"x": 1200, "y": 92} } }, "warnings": null }, { - "id": 641, - "sourceNodeId": 166, - "sourcePortId": 1297, - "targetNodeId": 149, - "targetPortId": 1298, + "id": 697, + "sourceNodeId": 144, + "sourcePortId": 1410, + "targetNodeId": 147, + "targetPortId": 1409, "travelTime": { "lock": true, "time": 7, @@ -10357,125 +15581,125 @@ }, "sourceDeparture": { "lock": false, - "time": 8, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 27 }, "sourceArrival": { "lock": false, - "time": 52, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 333 }, "targetDeparture": { "lock": false, - "time": 45, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 105 + "consecutiveTime": 326 }, "targetArrival": { "lock": false, - "time": 15, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 75 + "consecutiveTime": 34 }, "numberOfStops": 0, - "trainrunId": 97, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 304}, - {"x": 1954, "y": 304}, - {"x": 2174, "y": 304}, - {"x": 2238, "y": 304} + {"x": 322, "y": -432}, + {"x": 386, "y": -432}, + {"x": 894, "y": 48}, + {"x": 958, "y": 48} ], "textPositions": { - "0": {"x": 1908, "y": 316}, - "1": {"x": 1936, "y": 292}, - "2": {"x": 2220, "y": 292}, - "3": {"x": 2192, "y": 316}, - "4": {"x": 2064, "y": 292}, - "5": {"x": 2064, "y": 292}, - "6": {"x": 2064, "y": 316} + "0": {"x": 340, "y": -420}, + "1": {"x": 368, "y": -444}, + "2": {"x": 940, "y": 36}, + "3": {"x": 912, "y": 60}, + "4": {"x": 640, "y": -204}, + "5": {"x": 640, "y": -204}, + "6": {"x": 640, "y": -180} } }, "warnings": null }, { - "id": 642, - "sourceNodeId": 149, - "sourcePortId": 1299, - "targetNodeId": 135, - "targetPortId": 1300, + "id": 698, + "sourceNodeId": 145, + "sourcePortId": 1412, + "targetNodeId": 144, + "targetPortId": 1411, "travelTime": { "lock": true, - "time": 7, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 15, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 75 + "consecutiveTime": 21 }, "sourceArrival": { "lock": false, - "time": 45, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 105 + "consecutiveTime": 339 }, "targetDeparture": { "lock": false, - "time": 38, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 98 + "consecutiveTime": 333 }, "targetArrival": { "lock": false, - "time": 22, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 82 + "consecutiveTime": 27 }, "numberOfStops": 0, - "trainrunId": 97, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 304}, - {"x": 2402, "y": 304}, - {"x": 2590, "y": 304}, - {"x": 2654, "y": 304} + {"x": 112, "y": -862}, + {"x": 112, "y": -798}, + {"x": 112, "y": -514}, + {"x": 112, "y": -450} ], "textPositions": { - "0": {"x": 2356, "y": 316}, - "1": {"x": 2384, "y": 292}, - "2": {"x": 2636, "y": 292}, - "3": {"x": 2608, "y": 316}, - "4": {"x": 2496, "y": 292}, - "5": {"x": 2496, "y": 292}, - "6": {"x": 2496, "y": 316} + "0": {"x": 100, "y": -844}, + "1": {"x": 124, "y": -816}, + "2": {"x": 124, "y": -468}, + "3": {"x": 100, "y": -496}, + "4": {"x": 100, "y": -656}, + "5": {"x": 100, "y": -656}, + "6": {"x": 124, "y": -656} } }, "warnings": null }, { - "id": 643, - "sourceNodeId": 134, - "sourcePortId": 1301, - "targetNodeId": 146, - "targetPortId": 1302, + "id": 699, + "sourceNodeId": 146, + "sourcePortId": 1414, + "targetNodeId": 145, + "targetPortId": 1413, "travelTime": { "lock": true, "time": 7, @@ -10485,209 +15709,209 @@ }, "sourceDeparture": { "lock": false, - "time": 28, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 28 + "consecutiveTime": 14 }, "sourceArrival": { "lock": false, - "time": 32, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 272 + "consecutiveTime": 346 }, "targetDeparture": { "lock": false, - "time": 25, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 265 + "consecutiveTime": 339 }, "targetArrival": { "lock": false, - "time": 35, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 21 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": -1822}, - {"x": 208, "y": -1758}, - {"x": 208, "y": -1474}, - {"x": 208, "y": -1410} + {"x": 112, "y": -1342}, + {"x": 112, "y": -1278}, + {"x": 112, "y": -994}, + {"x": 112, "y": -930} ], "textPositions": { - "0": {"x": 196, "y": -1804}, - "1": {"x": 220, "y": -1776}, - "2": {"x": 220, "y": -1428}, - "3": {"x": 196, "y": -1456}, - "4": {"x": 196, "y": -1616}, - "5": {"x": 196, "y": -1616}, - "6": {"x": 220, "y": -1616} + "0": {"x": 100, "y": -1324}, + "1": {"x": 124, "y": -1296}, + "2": {"x": 124, "y": -948}, + "3": {"x": 100, "y": -976}, + "4": {"x": 100, "y": -1136}, + "5": {"x": 100, "y": -1136}, + "6": {"x": 124, "y": -1136} } }, "warnings": null }, { - "id": 644, - "sourceNodeId": 146, - "sourcePortId": 1303, - "targetNodeId": 145, - "targetPortId": 1304, + "id": 700, + "sourceNodeId": 134, + "sourcePortId": 1416, + "targetNodeId": 146, + "targetPortId": 1415, "travelTime": { "lock": true, - "time": 6, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 35, + "lock": true, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 6 }, "sourceArrival": { - "lock": false, - "time": 25, + "lock": true, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 265 + "consecutiveTime": 354 }, "targetDeparture": { "lock": false, - "time": 19, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 259 + "consecutiveTime": 346 }, "targetArrival": { "lock": false, - "time": 41, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 14 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": -1342}, - {"x": 208, "y": -1278}, - {"x": 208, "y": -994}, - {"x": 208, "y": -930} + {"x": 112, "y": -1822}, + {"x": 112, "y": -1758}, + {"x": 112, "y": -1474}, + {"x": 112, "y": -1410} ], "textPositions": { - "0": {"x": 196, "y": -1324}, - "1": {"x": 220, "y": -1296}, - "2": {"x": 220, "y": -948}, - "3": {"x": 196, "y": -976}, - "4": {"x": 196, "y": -1136}, - "5": {"x": 196, "y": -1136}, - "6": {"x": 220, "y": -1136} + "0": {"x": 100, "y": -1804}, + "1": {"x": 124, "y": -1776}, + "2": {"x": 124, "y": -1428}, + "3": {"x": 100, "y": -1456}, + "4": {"x": 100, "y": -1616}, + "5": {"x": 100, "y": -1616}, + "6": {"x": 124, "y": -1616} } }, "warnings": null }, { - "id": 645, - "sourceNodeId": 145, - "sourcePortId": 1305, - "targetNodeId": 144, - "targetPortId": 1306, + "id": 701, + "sourceNodeId": 175, + "sourcePortId": 1417, + "targetNodeId": 130, + "targetPortId": 1418, "travelTime": { "lock": true, - "time": 6, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 41, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 421 }, "sourceArrival": { - "lock": false, - "time": 19, + "lock": true, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 259 + "consecutiveTime": 119 }, "targetDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 253 + "consecutiveTime": 106 }, "targetArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 47 + "consecutiveTime": 434 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 208, "y": -862}, - {"x": 208, "y": -798}, - {"x": 208, "y": -514}, - {"x": 208, "y": -450} + {"x": -1698, "y": -16}, + {"x": -1762, "y": -16}, + {"x": -2366, "y": -16}, + {"x": -2430, "y": -16} ], "textPositions": { - "0": {"x": 196, "y": -844}, - "1": {"x": 220, "y": -816}, - "2": {"x": 220, "y": -468}, - "3": {"x": 196, "y": -496}, - "4": {"x": 196, "y": -656}, - "5": {"x": 196, "y": -656}, - "6": {"x": 220, "y": -656} + "0": {"x": -1716, "y": -28}, + "1": {"x": -1744, "y": -4}, + "2": {"x": -2412, "y": -4}, + "3": {"x": -2384, "y": -28}, + "4": {"x": -2064, "y": -28}, + "5": {"x": -2064, "y": -28}, + "6": {"x": -2064, "y": -4} } }, "warnings": null }, { - "id": 646, - "sourceNodeId": 144, - "sourcePortId": 1307, - "targetNodeId": 133, - "targetPortId": 1308, + "id": 702, + "sourceNodeId": 176, + "sourcePortId": 1420, + "targetNodeId": 137, + "targetPortId": 1419, "travelTime": { "lock": true, - "time": 8, + "time": 16, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 47, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 47 + "consecutiveTime": 279 }, "sourceArrival": { "lock": false, - "time": 13, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 253 + "consecutiveTime": 261 }, "targetDeparture": { "lock": true, @@ -10701,455 +15925,467 @@ "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 55 + "consecutiveTime": 295 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": -354}, - {"x": 144, "y": -290}, - {"x": 144, "y": 30}, - {"x": 144, "y": 94} + {"x": 5374, "y": 112}, + {"x": 5310, "y": 112}, + {"x": 4802, "y": 112}, + {"x": 4738, "y": 112} ], "textPositions": { - "0": {"x": 132, "y": -336}, - "1": {"x": 156, "y": -308}, - "2": {"x": 156, "y": 76}, - "3": {"x": 132, "y": 48}, - "4": {"x": 132, "y": -130}, - "5": {"x": 132, "y": -130}, - "6": {"x": 156, "y": -130} + "0": {"x": 5356, "y": 100}, + "1": {"x": 5328, "y": 124}, + "2": {"x": 4756, "y": 124}, + "3": {"x": 4784, "y": 100}, + "4": {"x": 5056, "y": 100}, + "5": {"x": 5056, "y": 100}, + "6": {"x": 5056, "y": 124} } }, "warnings": null }, { - "id": 647, - "sourceNodeId": 133, - "sourcePortId": 1309, - "targetNodeId": 172, - "targetPortId": 1310, + "id": 703, + "sourceNodeId": 177, + "sourcePortId": 1421, + "targetNodeId": 234, + "targetPortId": 1551, "travelTime": { - "lock": true, - "time": 7, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 58, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 58 + "consecutiveTime": 451 }, "sourceArrival": { "lock": true, - "time": 2, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 242 + "consecutiveTime": 89 }, "targetDeparture": { - "lock": false, - "time": 55, - "warning": null, + "lock": true, + "time": 15, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 235 + "consecutiveTime": 75 }, "targetArrival": { - "lock": false, - "time": 5, - "warning": null, + "lock": true, + "time": 45, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 465 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 62, "y": 208}, - {"x": -2, "y": 208}, - {"x": -446, "y": 208}, - {"x": -510, "y": 208} + {"x": -3522, "y": 560}, + {"x": -3586, "y": 560}, + {"x": -3566, "y": 592}, + {"x": -3630, "y": 592} ], "textPositions": { - "0": {"x": 44, "y": 196}, - "1": {"x": 16, "y": 220}, - "2": {"x": -492, "y": 220}, - "3": {"x": -464, "y": 196}, - "4": {"x": -224, "y": 196}, - "5": {"x": -224, "y": 196}, - "6": {"x": -224, "y": 220} + "0": {"x": -3540, "y": 548}, + "1": {"x": -3568, "y": 572}, + "2": {"x": -3612, "y": 604}, + "3": {"x": -3584, "y": 580}, + "4": {"x": -3576, "y": 564}, + "5": {"x": -3576, "y": 564}, + "6": {"x": -3576, "y": 588} } }, "warnings": null }, { - "id": 648, - "sourceNodeId": 129, - "sourcePortId": 1311, - "targetNodeId": 167, - "targetPortId": 1312, + "id": 704, + "sourceNodeId": 177, + "sourcePortId": 1423, + "targetNodeId": 160, + "targetPortId": 1424, "travelTime": { "lock": true, - "time": 18, + "time": 26, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 34, + "lock": false, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 94 + "consecutiveTime": 472 }, "sourceArrival": { - "lock": true, - "time": 26, + "lock": false, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 206 + "consecutiveTime": 68 }, "targetDeparture": { "lock": true, - "time": 8, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 188 + "consecutiveTime": 42 }, "targetArrival": { "lock": true, - "time": 52, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 498 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2096, "y": 382}, - {"x": -2096, "y": 446}, - {"x": -2096, "y": 574}, - {"x": -2096, "y": 638} + {"x": -3522, "y": 592}, + {"x": -3586, "y": 592}, + {"x": -3774, "y": 624}, + {"x": -3838, "y": 624} ], "textPositions": { - "0": {"x": -2108, "y": 400}, - "1": {"x": -2084, "y": 428}, - "2": {"x": -2084, "y": 620}, - "3": {"x": -2108, "y": 592}, - "4": {"x": -2108, "y": 510}, - "5": {"x": -2108, "y": 510}, - "6": {"x": -2084, "y": 510} + "0": {"x": -3540, "y": 580}, + "1": {"x": -3568, "y": 604}, + "2": {"x": -3820, "y": 636}, + "3": {"x": -3792, "y": 612}, + "4": {"x": -3680, "y": 596}, + "5": {"x": -3680, "y": 596}, + "6": {"x": -3680, "y": 620} } }, "warnings": null }, { - "id": 649, - "sourceNodeId": 167, - "sourcePortId": 1314, - "targetNodeId": 129, - "targetPortId": 1313, + "id": 705, + "sourceNodeId": 177, + "sourcePortId": 1425, + "targetNodeId": 160, + "targetPortId": 1426, "travelTime": { - "lock": true, - "time": 18, + "lock": false, + "time": 26, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 43, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 43 + "consecutiveTime": 499 }, "sourceArrival": { "lock": false, - "time": 17, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 377 + "consecutiveTime": 41 }, "targetDeparture": { - "lock": false, - "time": 59, + "lock": true, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 359 + "consecutiveTime": 15 }, "targetArrival": { - "lock": false, - "time": 1, + "lock": true, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 61 + "consecutiveTime": 525 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - {"x": -2064, "y": 638}, - {"x": -2064, "y": 574}, - {"x": -2064, "y": 446}, - {"x": -2064, "y": 382} + "path": { + "path": [ + {"x": -3522, "y": 624}, + {"x": -3586, "y": 624}, + {"x": -3774, "y": 656}, + {"x": -3838, "y": 656} ], "textPositions": { - "0": {"x": -2052, "y": 620}, - "1": {"x": -2076, "y": 592}, - "2": {"x": -2076, "y": 400}, - "3": {"x": -2052, "y": 428}, - "4": {"x": -2076, "y": 510}, - "5": {"x": -2076, "y": 510}, - "6": {"x": -2052, "y": 510} + "0": {"x": -3540, "y": 612}, + "1": {"x": -3568, "y": 636}, + "2": {"x": -3820, "y": 668}, + "3": {"x": -3792, "y": 644}, + "4": {"x": -3680, "y": 628}, + "5": {"x": -3680, "y": 628}, + "6": {"x": -3680, "y": 652} } }, "warnings": null }, { - "id": 650, - "sourceNodeId": 167, - "sourcePortId": 1315, - "targetNodeId": 168, - "targetPortId": 1316, + "id": 706, + "sourceNodeId": 129, + "sourcePortId": 1428, + "targetNodeId": 178, + "targetPortId": 1427, "travelTime": { "lock": true, - "time": 8, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 54, + "lock": true, + "time": 36, "warning": null, "timeFormatter": null, - "consecutiveTime": 114 + "consecutiveTime": 36 }, "sourceArrival": { - "lock": false, - "time": 6, + "lock": true, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 186 + "consecutiveTime": 384 }, "targetDeparture": { "lock": false, - "time": 58, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 178 + "consecutiveTime": 381 }, "targetArrival": { "lock": false, - "time": 2, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 122 + "consecutiveTime": 39 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2096, "y": 706}, - {"x": -2096, "y": 770}, - {"x": -2096, "y": 862}, - {"x": -2096, "y": 926} + {"x": -2014, "y": 336}, + {"x": -1950, "y": 336}, + {"x": -1762, "y": 336}, + {"x": -1698, "y": 336} ], "textPositions": { - "0": {"x": -2108, "y": 724}, - "1": {"x": -2084, "y": 752}, - "2": {"x": -2084, "y": 908}, - "3": {"x": -2108, "y": 880}, - "4": {"x": -2108, "y": 816}, - "5": {"x": -2108, "y": 816}, - "6": {"x": -2084, "y": 816} + "0": {"x": -1996, "y": 348}, + "1": {"x": -1968, "y": 324}, + "2": {"x": -1716, "y": 324}, + "3": {"x": -1744, "y": 348}, + "4": {"x": -1856, "y": 324}, + "5": {"x": -1856, "y": 324}, + "6": {"x": -1856, "y": 348} } }, "warnings": null }, { - "id": 651, - "sourceNodeId": 168, - "sourcePortId": 1317, - "targetNodeId": 131, - "targetPortId": 1318, + "id": 707, + "sourceNodeId": 178, + "sourcePortId": 1429, + "targetNodeId": 129, + "targetPortId": 1430, "travelTime": { "lock": true, - "time": 24, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 4, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 124 + "consecutiveTime": 355 }, "sourceArrival": { "lock": false, - "time": 56, - "warning": null, + "time": 5, + "warning": { + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 176 + "consecutiveTime": 185 }, "targetDeparture": { - "lock": false, - "time": 32, + "lock": true, + "time": 0, "warning": null, "timeFormatter": null, - "consecutiveTime": 152 + "consecutiveTime": 180 }, "targetArrival": { - "lock": false, - "time": 28, - "warning": null, + "lock": true, + "time": 0, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 148 + "consecutiveTime": 360 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2014, "y": 944}, - {"x": -1950, "y": 944}, - {"x": -1154, "y": 944}, - {"x": -1090, "y": 944} + {"x": -1698, "y": 304}, + {"x": -1762, "y": 304}, + {"x": -1950, "y": 304}, + {"x": -2014, "y": 304} ], "textPositions": { - "0": {"x": -1996, "y": 956}, - "1": {"x": -1968, "y": 932}, - "2": {"x": -1108, "y": 932}, - "3": {"x": -1136, "y": 956}, - "4": {"x": -1552, "y": 932}, - "5": {"x": -1552, "y": 932}, - "6": {"x": -1552, "y": 956} + "0": {"x": -1716, "y": 292}, + "1": {"x": -1744, "y": 316}, + "2": {"x": -1996, "y": 316}, + "3": {"x": -1968, "y": 292}, + "4": {"x": -1856, "y": 292}, + "5": {"x": -1856, "y": 292}, + "6": {"x": -1856, "y": 316} } }, "warnings": null }, { - "id": 652, - "sourceNodeId": 168, - "sourcePortId": 1320, - "targetNodeId": 167, - "targetPortId": 1319, + "id": 708, + "sourceNodeId": 129, + "sourcePortId": 1432, + "targetNodeId": 178, + "targetPortId": 1431, "travelTime": { "lock": true, - "time": 10, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 31, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 31 + "consecutiveTime": 62 }, "sourceArrival": { "lock": false, - "time": 29, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 389 + "consecutiveTime": 358 }, "targetDeparture": { "lock": false, - "time": 19, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 379 + "consecutiveTime": 355 }, "targetArrival": { "lock": false, - "time": 41, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 65 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 90, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2064, "y": 926}, - {"x": -2064, "y": 862}, - {"x": -2064, "y": 770}, - {"x": -2064, "y": 706} + {"x": -2014, "y": 272}, + {"x": -1950, "y": 272}, + {"x": -1762, "y": 272}, + {"x": -1698, "y": 272} ], "textPositions": { - "0": {"x": -2052, "y": 908}, - "1": {"x": -2076, "y": 880}, - "2": {"x": -2076, "y": 724}, - "3": {"x": -2052, "y": 752}, - "4": {"x": -2076, "y": 816}, - "5": {"x": -2076, "y": 816}, - "6": {"x": -2052, "y": 816} + "0": {"x": -1996, "y": 284}, + "1": {"x": -1968, "y": 260}, + "2": {"x": -1716, "y": 260}, + "3": {"x": -1744, "y": 284}, + "4": {"x": -1856, "y": 260}, + "5": {"x": -1856, "y": 260}, + "6": {"x": -1856, "y": 284} } }, "warnings": null }, { - "id": 653, - "sourceNodeId": 132, - "sourcePortId": 1322, - "targetNodeId": 168, - "targetPortId": 1321, + "id": 709, + "sourceNodeId": 129, + "sourcePortId": 1434, + "targetNodeId": 178, + "targetPortId": 1433, "travelTime": { "lock": true, - "time": 25, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 4, + "lock": true, + "time": 3, "warning": null, "timeFormatter": null, - "consecutiveTime": 4 + "consecutiveTime": 63 }, "sourceArrival": { - "lock": false, - "time": 56, + "lock": true, + "time": 57, "warning": null, "timeFormatter": null, - "consecutiveTime": 416 + "consecutiveTime": 357 }, "targetDeparture": { "lock": false, - "time": 31, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 391 + "consecutiveTime": 354 }, "targetArrival": { "lock": false, - "time": 29, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 29 + "consecutiveTime": 66 }, "numberOfStops": 0, "trainrunId": 89, @@ -11157,127 +16393,127 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2096, "y": 1438}, - {"x": -2096, "y": 1374}, - {"x": -2096, "y": 1086}, - {"x": -2096, "y": 1022} + {"x": -2014, "y": 240}, + {"x": -1950, "y": 240}, + {"x": -1762, "y": 240}, + {"x": -1698, "y": 240} ], "textPositions": { - "0": {"x": -2084, "y": 1420}, - "1": {"x": -2108, "y": 1392}, - "2": {"x": -2108, "y": 1040}, - "3": {"x": -2084, "y": 1068}, - "4": {"x": -2108, "y": 1230}, - "5": {"x": -2108, "y": 1230}, - "6": {"x": -2084, "y": 1230} + "0": {"x": -1996, "y": 252}, + "1": {"x": -1968, "y": 228}, + "2": {"x": -1716, "y": 228}, + "3": {"x": -1744, "y": 252}, + "4": {"x": -1856, "y": 228}, + "5": {"x": -1856, "y": 228}, + "6": {"x": -1856, "y": 252} } }, "warnings": null }, { - "id": 654, - "sourceNodeId": 132, - "sourcePortId": 1323, - "targetNodeId": 168, - "targetPortId": 1324, + "id": 710, + "sourceNodeId": 178, + "sourcePortId": 1435, + "targetNodeId": 129, + "targetPortId": 1436, "travelTime": { "lock": true, - "time": 26, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 29, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 149 + "consecutiveTime": 83 }, "sourceArrival": { "lock": false, - "time": 31, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 151 + "consecutiveTime": 217 }, "targetDeparture": { - "lock": false, - "time": 5, + "lock": true, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 125 + "consecutiveTime": 214 }, "targetArrival": { - "lock": false, - "time": 55, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 175 + "consecutiveTime": 86 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 95, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2128, "y": 1438}, - {"x": -2128, "y": 1374}, - {"x": -2128, "y": 1086}, - {"x": -2128, "y": 1022} + {"x": -1698, "y": 208}, + {"x": -1762, "y": 208}, + {"x": -1950, "y": 208}, + {"x": -2014, "y": 208} ], "textPositions": { - "0": {"x": -2116, "y": 1420}, - "1": {"x": -2140, "y": 1392}, - "2": {"x": -2140, "y": 1040}, - "3": {"x": -2116, "y": 1068}, - "4": {"x": -2140, "y": 1230}, - "5": {"x": -2140, "y": 1230}, - "6": {"x": -2116, "y": 1230} + "0": {"x": -1716, "y": 196}, + "1": {"x": -1744, "y": 220}, + "2": {"x": -1996, "y": 220}, + "3": {"x": -1968, "y": 196}, + "4": {"x": -1856, "y": 196}, + "5": {"x": -1856, "y": 196}, + "6": {"x": -1856, "y": 220} } }, "warnings": null }, { - "id": 655, - "sourceNodeId": 168, - "sourcePortId": 1325, - "targetNodeId": 167, - "targetPortId": 1326, + "id": 711, + "sourceNodeId": 178, + "sourcePortId": 1437, + "targetNodeId": 172, + "targetPortId": 1438, "travelTime": { "lock": true, - "time": 8, + "time": 17, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 58, + "time": 37, "warning": null, "timeFormatter": null, - "consecutiveTime": 178 + "consecutiveTime": 217 }, "sourceArrival": { "lock": false, - "time": 2, + "time": 23, "warning": null, "timeFormatter": null, - "consecutiveTime": 122 + "consecutiveTime": 83 }, "targetDeparture": { "lock": false, - "time": 54, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 114 + "consecutiveTime": 66 }, "targetArrival": { "lock": false, - "time": 6, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 186 + "consecutiveTime": 234 }, "numberOfStops": 0, "trainrunId": 96, @@ -11285,1023 +16521,1119 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2128, "y": 926}, - {"x": -2128, "y": 862}, - {"x": -2128, "y": 770}, - {"x": -2128, "y": 706} + {"x": -1598, "y": 176}, + {"x": -1534, "y": 176}, + {"x": -674, "y": 176}, + {"x": -610, "y": 176} ], "textPositions": { - "0": {"x": -2116, "y": 908}, - "1": {"x": -2140, "y": 880}, - "2": {"x": -2140, "y": 724}, - "3": {"x": -2116, "y": 752}, - "4": {"x": -2140, "y": 816}, - "5": {"x": -2140, "y": 816}, - "6": {"x": -2116, "y": 816} + "0": {"x": -1580, "y": 188}, + "1": {"x": -1552, "y": 164}, + "2": {"x": -628, "y": 164}, + "3": {"x": -656, "y": 188}, + "4": {"x": -1104, "y": 164}, + "5": {"x": -1104, "y": 164}, + "6": {"x": -1104, "y": 188} } }, "warnings": null }, { - "id": 656, - "sourceNodeId": 167, - "sourcePortId": 1327, + "id": 712, + "sourceNodeId": 178, + "sourcePortId": 1439, "targetNodeId": 129, - "targetPortId": 1328, + "targetPortId": 1440, "travelTime": { "lock": true, - "time": 18, + "time": 3, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 8, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 188 + "consecutiveTime": 386 }, "sourceArrival": { "lock": false, - "time": 52, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 112 + "consecutiveTime": 154 }, "targetDeparture": { - "lock": true, - "time": 34, + "lock": false, + "time": 31, "warning": null, "timeFormatter": null, - "consecutiveTime": 94 + "consecutiveTime": 151 }, "targetArrival": { - "lock": true, - "time": 26, + "lock": false, + "time": 29, "warning": null, "timeFormatter": null, - "consecutiveTime": 206 + "consecutiveTime": 389 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2128, "y": 638}, - {"x": -2128, "y": 574}, - {"x": -2128, "y": 446}, - {"x": -2128, "y": 382} + {"x": -1698, "y": 144}, + {"x": -1762, "y": 144}, + {"x": -1950, "y": 144}, + {"x": -2014, "y": 144} ], "textPositions": { - "0": {"x": -2116, "y": 620}, - "1": {"x": -2140, "y": 592}, - "2": {"x": -2140, "y": 400}, - "3": {"x": -2116, "y": 428}, - "4": {"x": -2140, "y": 510}, - "5": {"x": -2140, "y": 510}, - "6": {"x": -2116, "y": 510} + "0": {"x": -1716, "y": 132}, + "1": {"x": -1744, "y": 156}, + "2": {"x": -1996, "y": 156}, + "3": {"x": -1968, "y": 132}, + "4": {"x": -1856, "y": 132}, + "5": {"x": -1856, "y": 132}, + "6": {"x": -1856, "y": 156} } }, "warnings": null }, { - "id": 657, - "sourceNodeId": 129, - "sourcePortId": 1329, - "targetNodeId": 178, - "targetPortId": 1330, + "id": 713, + "sourceNodeId": 179, + "sourcePortId": 1442, + "targetNodeId": 180, + "targetPortId": 1443, "travelTime": { "lock": true, - "time": 3, + "time": 12, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 34, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 214 + "consecutiveTime": 344 }, "sourceArrival": { "lock": true, - "time": 26, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 86 + "consecutiveTime": 256 }, "targetDeparture": { - "lock": false, - "time": 23, - "warning": null, + "lock": true, + "time": 4, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 244 }, "targetArrival": { - "lock": false, - "time": 37, - "warning": null, + "lock": true, + "time": 56, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 217 + "consecutiveTime": 356 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2014, "y": 176}, - {"x": -1950, "y": 176}, - {"x": -1762, "y": 176}, - {"x": -1698, "y": 176} + {"x": 2448, "y": 2462}, + {"x": 2448, "y": 2398}, + {"x": 2368, "y": 2482}, + {"x": 2368, "y": 2418} ], "textPositions": { - "0": {"x": -1996, "y": 188}, - "1": {"x": -1968, "y": 164}, - "2": {"x": -1716, "y": 164}, - "3": {"x": -1744, "y": 188}, - "4": {"x": -1856, "y": 164}, - "5": {"x": -1856, "y": 164}, - "6": {"x": -1856, "y": 188} + "0": {"x": 2460, "y": 2444}, + "1": {"x": 2436, "y": 2416}, + "2": {"x": 2356, "y": 2436}, + "3": {"x": 2380, "y": 2464}, + "4": {"x": 2396, "y": 2440}, + "5": {"x": 2396, "y": 2440}, + "6": {"x": 2420, "y": 2440} } }, "warnings": null }, { - "id": 658, - "sourceNodeId": 133, - "sourcePortId": 1331, - "targetNodeId": 144, - "targetPortId": 1332, + "id": 714, + "sourceNodeId": 180, + "sourcePortId": 1444, + "targetNodeId": 181, + "targetPortId": 1445, "travelTime": { "lock": true, - "time": 8, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 5, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 245 + "consecutiveTime": 358 }, "sourceArrival": { "lock": true, - "time": 55, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 55 + "consecutiveTime": 242 }, "targetDeparture": { - "lock": false, - "time": 47, - "warning": null, + "lock": true, + "time": 57, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 47 + "consecutiveTime": 237 }, "targetArrival": { - "lock": false, - "time": 13, - "warning": null, + "lock": true, + "time": 3, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 253 + "consecutiveTime": 363 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": 94}, - {"x": 112, "y": 30}, - {"x": 112, "y": -290}, - {"x": 112, "y": -354} + {"x": 2368, "y": 2350}, + {"x": 2368, "y": 2286}, + {"x": 2328, "y": 2426}, + {"x": 2328, "y": 2362} ], "textPositions": { - "0": {"x": 124, "y": 76}, - "1": {"x": 100, "y": 48}, - "2": {"x": 100, "y": -336}, - "3": {"x": 124, "y": -308}, - "4": {"x": 100, "y": -130}, - "5": {"x": 100, "y": -130}, - "6": {"x": 124, "y": -130} + "0": {"x": 2380, "y": 2332}, + "1": {"x": 2356, "y": 2304}, + "2": {"x": 2316, "y": 2380}, + "3": {"x": 2340, "y": 2408}, + "4": {"x": 2336, "y": 2356}, + "5": {"x": 2336, "y": 2356}, + "6": {"x": 2360, "y": 2356} } }, "warnings": null }, { - "id": 659, - "sourceNodeId": 144, - "sourcePortId": 1333, - "targetNodeId": 145, - "targetPortId": 1334, + "id": 715, + "sourceNodeId": 181, + "sourcePortId": 1446, + "targetNodeId": 182, + "targetPortId": 1447, "travelTime": { "lock": true, - "time": 6, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 253 + "consecutiveTime": 365 }, "sourceArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 47 + "consecutiveTime": 235 }, "targetDeparture": { - "lock": false, - "time": 41, - "warning": null, + "lock": true, + "time": 54, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 234 }, "targetArrival": { - "lock": false, - "time": 19, - "warning": null, + "lock": true, + "time": 6, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 259 + "consecutiveTime": 366 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": -450}, - {"x": 176, "y": -514}, - {"x": 176, "y": -798}, - {"x": 176, "y": -862} + {"x": 2328, "y": 2294}, + {"x": 2328, "y": 2230}, + {"x": 2308, "y": 2398}, + {"x": 2308, "y": 2334} ], "textPositions": { - "0": {"x": 188, "y": -468}, - "1": {"x": 164, "y": -496}, - "2": {"x": 164, "y": -844}, - "3": {"x": 188, "y": -816}, - "4": {"x": 164, "y": -656}, - "5": {"x": 164, "y": -656}, - "6": {"x": 188, "y": -656} + "0": {"x": 2340, "y": 2276}, + "1": {"x": 2316, "y": 2248}, + "2": {"x": 2296, "y": 2352}, + "3": {"x": 2320, "y": 2380}, + "4": {"x": 2306, "y": 2314}, + "5": {"x": 2306, "y": 2314}, + "6": {"x": 2330, "y": 2314} } }, "warnings": null }, { - "id": 660, - "sourceNodeId": 145, - "sourcePortId": 1335, - "targetNodeId": 146, - "targetPortId": 1336, + "id": 716, + "sourceNodeId": 182, + "sourcePortId": 1448, + "targetNodeId": 183, + "targetPortId": 1449, "travelTime": { "lock": true, - "time": 6, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 19, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 259 + "consecutiveTime": 368 }, "sourceArrival": { - "lock": false, - "time": 41, - "warning": null, + "lock": true, + "time": 52, + "warning": { + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 232 }, "targetDeparture": { - "lock": false, - "time": 35, - "warning": null, + "lock": true, + "time": 52, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 232 }, "targetArrival": { - "lock": false, - "time": 25, - "warning": null, + "lock": true, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 265 + "consecutiveTime": 369 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": -930}, - {"x": 176, "y": -994}, - {"x": 176, "y": -1278}, - {"x": 176, "y": -1342} + {"x": 2308, "y": 2266}, + {"x": 2308, "y": 2202}, + {"x": 2298, "y": 2384}, + {"x": 2298, "y": 2320} ], "textPositions": { - "0": {"x": 188, "y": -948}, - "1": {"x": 164, "y": -976}, - "2": {"x": 164, "y": -1324}, - "3": {"x": 188, "y": -1296}, - "4": {"x": 164, "y": -1136}, - "5": {"x": 164, "y": -1136}, - "6": {"x": 188, "y": -1136} + "0": {"x": 2320, "y": 2248}, + "1": {"x": 2296, "y": 2220}, + "2": {"x": 2286, "y": 2338}, + "3": {"x": 2310, "y": 2366}, + "4": {"x": 2291, "y": 2293}, + "5": {"x": 2291, "y": 2293}, + "6": {"x": 2315, "y": 2293} } }, "warnings": null }, { - "id": 661, - "sourceNodeId": 146, - "sourcePortId": 1337, - "targetNodeId": 134, - "targetPortId": 1338, + "id": 717, + "sourceNodeId": 183, + "sourcePortId": 1450, + "targetNodeId": 159, + "targetPortId": 1074, "travelTime": { "lock": true, - "time": 7, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 25, - "warning": null, + "lock": true, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 265 + "consecutiveTime": 369 }, "sourceArrival": { - "lock": false, - "time": 35, - "warning": null, + "lock": true, + "time": 52, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 35 + "consecutiveTime": 232 }, "targetDeparture": { "lock": true, - "time": 28, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 28 + "consecutiveTime": 231 }, "targetArrival": { "lock": true, - "time": 32, - "warning": null, + "time": 9, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 272 + "consecutiveTime": 369 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": -1410}, - {"x": 176, "y": -1474}, - {"x": 176, "y": -1758}, - {"x": 176, "y": -1822} + {"x": 2298, "y": 2252}, + {"x": 2298, "y": 2188}, + {"x": 2288, "y": 2398}, + {"x": 2288, "y": 2334} ], "textPositions": { - "0": {"x": 188, "y": -1428}, - "1": {"x": 164, "y": -1456}, - "2": {"x": 164, "y": -1804}, - "3": {"x": 188, "y": -1776}, - "4": {"x": 164, "y": -1616}, - "5": {"x": 164, "y": -1616}, - "6": {"x": 188, "y": -1616} + "0": {"x": 2310, "y": 2234}, + "1": {"x": 2286, "y": 2206}, + "2": {"x": 2276, "y": 2352}, + "3": {"x": 2300, "y": 2380}, + "4": {"x": 2281, "y": 2293}, + "5": {"x": 2281, "y": 2293}, + "6": {"x": 2305, "y": 2293} } }, "warnings": null }, { - "id": 662, - "sourceNodeId": 167, - "sourcePortId": 1340, - "targetNodeId": 129, - "targetPortId": 1339, + "id": 718, + "sourceNodeId": 184, + "sourcePortId": 1452, + "targetNodeId": 155, + "targetPortId": 1076, "travelTime": { - "lock": false, - "time": 19, + "lock": true, + "time": 15, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 33, - "warning": null, + "time": 27, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 33 + "consecutiveTime": 387 }, "sourceArrival": { "lock": true, - "time": 27, - "warning": null, + "time": 33, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 387 + "consecutiveTime": 213 }, "targetDeparture": { - "lock": true, - "time": 8, + "lock": false, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 368 + "consecutiveTime": 198 }, "targetArrival": { - "lock": true, - "time": 52, + "lock": false, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 402 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2032, "y": 638}, - {"x": -2032, "y": 574}, - {"x": -2032, "y": 446}, - {"x": -2032, "y": 382} + {"x": 2562, "y": 2224}, + {"x": 2626, "y": 2224}, + {"x": 2590, "y": 2192}, + {"x": 2654, "y": 2192} ], "textPositions": { - "0": {"x": -2020, "y": 620}, - "1": {"x": -2044, "y": 592}, - "2": {"x": -2044, "y": 400}, - "3": {"x": -2020, "y": 428}, - "4": {"x": -2044, "y": 510}, - "5": {"x": -2044, "y": 510}, - "6": {"x": -2020, "y": 510} + "0": {"x": 2580, "y": 2236}, + "1": {"x": 2608, "y": 2212}, + "2": {"x": 2636, "y": 2180}, + "3": {"x": 2608, "y": 2204}, + "4": {"x": 2608, "y": 2196}, + "5": {"x": 2608, "y": 2196}, + "6": {"x": 2608, "y": 2220} } }, "warnings": null }, { - "id": 663, - "sourceNodeId": 168, - "sourcePortId": 1342, - "targetNodeId": 167, - "targetPortId": 1341, + "id": 719, + "sourceNodeId": 185, + "sourcePortId": 1454, + "targetNodeId": 186, + "targetPortId": 1455, "travelTime": { "lock": true, - "time": 10, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 22, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 22 + "consecutiveTime": 416 }, "sourceArrival": { "lock": true, - "time": 38, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 398 + "consecutiveTime": 184 }, "targetDeparture": { - "lock": false, - "time": 28, - "warning": null, + "lock": true, + "time": 0, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 388 + "consecutiveTime": 180 }, "targetArrival": { - "lock": false, - "time": 32, - "warning": null, + "lock": true, + "time": 0, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 32 + "consecutiveTime": 420 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2032, "y": 926}, - {"x": -2032, "y": 862}, - {"x": -2032, "y": 770}, - {"x": -2032, "y": 706} + {"x": 2672, "y": 1982}, + {"x": 2672, "y": 1918}, + {"x": 2672, "y": 2018}, + {"x": 2672, "y": 1954} ], "textPositions": { - "0": {"x": -2020, "y": 908}, - "1": {"x": -2044, "y": 880}, - "2": {"x": -2044, "y": 724}, - "3": {"x": -2020, "y": 752}, - "4": {"x": -2044, "y": 816}, - "5": {"x": -2044, "y": 816}, - "6": {"x": -2020, "y": 816} + "0": {"x": 2684, "y": 1964}, + "1": {"x": 2660, "y": 1936}, + "2": {"x": 2660, "y": 1972}, + "3": {"x": 2684, "y": 2000}, + "4": {"x": 2660, "y": 1968}, + "5": {"x": 2660, "y": 1968}, + "6": {"x": 2684, "y": 1968} } }, "warnings": null }, { - "id": 664, - "sourceNodeId": 131, - "sourcePortId": 1344, - "targetNodeId": 168, - "targetPortId": 1343, + "id": 720, + "sourceNodeId": 186, + "sourcePortId": 1456, + "targetNodeId": 187, + "targetPortId": 1457, "travelTime": { "lock": true, - "time": 21, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 0, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 0 + "consecutiveTime": 422 }, "sourceArrival": { - "lock": false, - "time": 0, + "lock": true, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 420 + "consecutiveTime": 178 }, "targetDeparture": { "lock": true, - "time": 39, - "warning": null, + "time": 57, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 399 + "consecutiveTime": 177 }, "targetArrival": { "lock": true, - "time": 21, - "warning": null, + "time": 3, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 21 + "consecutiveTime": 423 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1090, "y": 976}, - {"x": -1154, "y": 976}, - {"x": -1950, "y": 976}, - {"x": -2014, "y": 976} + {"x": 2672, "y": 1886}, + {"x": 2672, "y": 1822}, + {"x": 2672, "y": 1970}, + {"x": 2672, "y": 1906} ], "textPositions": { - "0": {"x": -1108, "y": 964}, - "1": {"x": -1136, "y": 988}, - "2": {"x": -1996, "y": 988}, - "3": {"x": -1968, "y": 964}, - "4": {"x": -1552, "y": 964}, - "5": {"x": -1552, "y": 964}, - "6": {"x": -1552, "y": 988} + "0": {"x": 2684, "y": 1868}, + "1": {"x": 2660, "y": 1840}, + "2": {"x": 2660, "y": 1924}, + "3": {"x": 2684, "y": 1952}, + "4": {"x": 2660, "y": 1896}, + "5": {"x": 2660, "y": 1896}, + "6": {"x": 2684, "y": 1896} } }, "warnings": null }, { - "id": 665, - "sourceNodeId": 169, - "sourcePortId": 1345, - "targetNodeId": 153, - "targetPortId": 1346, + "id": 721, + "sourceNodeId": 187, + "sourcePortId": 1458, + "targetNodeId": 154, + "targetPortId": 1078, "travelTime": { "lock": true, - "time": 9, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 48, - "warning": null, + "time": 5, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 48 + "consecutiveTime": 425 }, "sourceArrival": { "lock": true, - "time": 12, - "warning": null, + "time": 55, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 252 + "consecutiveTime": 175 }, "targetDeparture": { "lock": true, - "time": 3, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 243 + "consecutiveTime": 174 }, "targetArrival": { "lock": true, - "time": 57, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 57 + "consecutiveTime": 426 }, "numberOfStops": 0, - "trainrunId": 79, + "trainrunId": 77, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1954, "y": 1776}, - {"x": 2018, "y": 1776}, - {"x": 2590, "y": 1360}, - {"x": 2654, "y": 1360} + {"x": 2672, "y": 1838}, + {"x": 2672, "y": 1774}, + {"x": 2736, "y": 1950}, + {"x": 2736, "y": 1886} ], "textPositions": { - "0": {"x": 1972, "y": 1788}, - "1": {"x": 2000, "y": 1764}, - "2": {"x": 2636, "y": 1348}, - "3": {"x": 2608, "y": 1372}, - "4": {"x": 2304, "y": 1556}, - "5": {"x": 2304, "y": 1556}, - "6": {"x": 2304, "y": 1580} + "0": {"x": 2684, "y": 1820}, + "1": {"x": 2660, "y": 1792}, + "2": {"x": 2724, "y": 1904}, + "3": {"x": 2748, "y": 1932}, + "4": {"x": 2716, "y": 1862}, + "5": {"x": 2716, "y": 1862}, + "6": {"x": 2692, "y": 1862} } }, "warnings": null }, { - "id": 666, - "sourceNodeId": 169, - "sourcePortId": 1347, - "targetNodeId": 153, - "targetPortId": 1348, + "id": 722, + "sourceNodeId": 188, + "sourcePortId": 1460, + "targetNodeId": 189, + "targetPortId": 1461, "travelTime": { "lock": true, - "time": 10, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 18, + "lock": true, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 18 + "consecutiveTime": 166 }, "sourceArrival": { - "lock": false, - "time": 42, + "lock": true, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 42 + "consecutiveTime": 194 }, "targetDeparture": { - "lock": false, - "time": 32, - "warning": null, + "lock": true, + "time": 10, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 32 + "consecutiveTime": 190 }, "targetArrival": { - "lock": false, - "time": 28, - "warning": null, + "lock": true, + "time": 50, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 28 + "consecutiveTime": 170 }, "numberOfStops": 0, - "trainrunId": 80, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1954, "y": 1744}, - {"x": 2018, "y": 1744}, - {"x": 2590, "y": 1328}, - {"x": 2654, "y": 1328} + {"x": 2498, "y": 3248}, + {"x": 2562, "y": 3248}, + {"x": 2430, "y": 3248}, + {"x": 2494, "y": 3248} ], "textPositions": { - "0": {"x": 1972, "y": 1756}, - "1": {"x": 2000, "y": 1732}, - "2": {"x": 2636, "y": 1316}, - "3": {"x": 2608, "y": 1340}, - "4": {"x": 2304, "y": 1524}, - "5": {"x": 2304, "y": 1524}, - "6": {"x": 2304, "y": 1548} + "0": {"x": 2516, "y": 3260}, + "1": {"x": 2544, "y": 3236}, + "2": {"x": 2476, "y": 3236}, + "3": {"x": 2448, "y": 3260}, + "4": {"x": 2496, "y": 3236}, + "5": {"x": 2496, "y": 3236}, + "6": {"x": 2496, "y": 3260} } }, "warnings": null }, { - "id": 667, - "sourceNodeId": 169, - "sourcePortId": 1349, - "targetNodeId": 142, - "targetPortId": 1350, + "id": 723, + "sourceNodeId": 189, + "sourcePortId": 1462, + "targetNodeId": 190, + "targetPortId": 1463, "travelTime": { "lock": true, - "time": 9, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 33, + "lock": true, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 453 + "consecutiveTime": 172 }, "sourceArrival": { - "lock": false, - "time": 27, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 147 + "consecutiveTime": 188 }, "targetDeparture": { - "lock": false, - "time": 18, - "warning": null, + "lock": true, + "time": 7, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 138 + "consecutiveTime": 187 }, "targetArrival": { - "lock": false, - "time": 42, - "warning": null, + "lock": true, + "time": 53, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 462 + "consecutiveTime": 173 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1854, "y": 1776}, - {"x": 1790, "y": 1776}, - {"x": 290, "y": 1776}, - {"x": 226, "y": 1776} + {"x": 2594, "y": 3248}, + {"x": 2658, "y": 3248}, + {"x": 2478, "y": 3248}, + {"x": 2542, "y": 3248} ], "textPositions": { - "0": {"x": 1836, "y": 1764}, - "1": {"x": 1808, "y": 1788}, - "2": {"x": 244, "y": 1788}, - "3": {"x": 272, "y": 1764}, - "4": {"x": 1040, "y": 1764}, - "5": {"x": 1040, "y": 1764}, - "6": {"x": 1040, "y": 1788} + "0": {"x": 2612, "y": 3260}, + "1": {"x": 2640, "y": 3236}, + "2": {"x": 2524, "y": 3236}, + "3": {"x": 2496, "y": 3260}, + "4": {"x": 2568, "y": 3236}, + "5": {"x": 2568, "y": 3236}, + "6": {"x": 2568, "y": 3260} } }, "warnings": null }, { - "id": 668, - "sourceNodeId": 169, - "sourcePortId": 1351, - "targetNodeId": 142, - "targetPortId": 1352, + "id": 724, + "sourceNodeId": 190, + "sourcePortId": 1464, + "targetNodeId": 136, + "targetPortId": 1082, "travelTime": { "lock": true, - "time": 9, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 33, - "warning": null, + "lock": true, + "time": 55, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 273 + "consecutiveTime": 175 }, "sourceArrival": { - "lock": false, - "time": 27, - "warning": null, + "lock": true, + "time": 5, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 87 + "consecutiveTime": 185 }, "targetDeparture": { "lock": true, - "time": 18, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 78 + "consecutiveTime": 184 }, "targetArrival": { "lock": true, - "time": 42, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 282 + "consecutiveTime": 176 }, "numberOfStops": 0, - "trainrunId": 75, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1854, "y": 1744}, - {"x": 1790, "y": 1744}, - {"x": 290, "y": 1744}, - {"x": 226, "y": 1744} + {"x": 2642, "y": 3248}, + {"x": 2706, "y": 3248}, + {"x": 2526, "y": 3280}, + {"x": 2590, "y": 3280} ], "textPositions": { - "0": {"x": 1836, "y": 1732}, - "1": {"x": 1808, "y": 1756}, - "2": {"x": 244, "y": 1756}, - "3": {"x": 272, "y": 1732}, - "4": {"x": 1040, "y": 1732}, - "5": {"x": 1040, "y": 1732}, - "6": {"x": 1040, "y": 1756} + "0": {"x": 2660, "y": 3260}, + "1": {"x": 2688, "y": 3236}, + "2": {"x": 2572, "y": 3268}, + "3": {"x": 2544, "y": 3292}, + "4": {"x": 2616, "y": 3252}, + "5": {"x": 2616, "y": 3252}, + "6": {"x": 2616, "y": 3276} } }, "warnings": null }, { - "id": 669, - "sourceNodeId": 170, - "sourcePortId": 1353, - "targetNodeId": 135, - "targetPortId": 1354, + "id": 725, + "sourceNodeId": 191, + "sourcePortId": 1466, + "targetNodeId": 158, + "targetPortId": 1084, "travelTime": { "lock": true, - "time": 11, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 14, - "warning": null, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 74 + "consecutiveTime": 189 }, "sourceArrival": { "lock": true, - "time": 46, - "warning": null, + "time": 51, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 226 + "consecutiveTime": 171 }, "targetDeparture": { "lock": true, - "time": 35, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 215 + "consecutiveTime": 165 }, "targetArrival": { "lock": true, - "time": 25, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 85 + "consecutiveTime": 195 }, "numberOfStops": 0, - "trainrunId": 79, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2832, "y": 734}, - {"x": 2832, "y": 670}, - {"x": 2832, "y": 414}, - {"x": 2832, "y": 350} + {"x": 2608, "y": 2958}, + {"x": 2608, "y": 2894}, + {"x": 2704, "y": 2818}, + {"x": 2704, "y": 2754} ], "textPositions": { - "0": {"x": 2844, "y": 716}, - "1": {"x": 2820, "y": 688}, - "2": {"x": 2820, "y": 368}, - "3": {"x": 2844, "y": 396}, - "4": {"x": 2820, "y": 542}, - "5": {"x": 2820, "y": 542}, - "6": {"x": 2844, "y": 542} + "0": {"x": 2620, "y": 2940}, + "1": {"x": 2596, "y": 2912}, + "2": {"x": 2692, "y": 2772}, + "3": {"x": 2716, "y": 2800}, + "4": {"x": 2644, "y": 2856}, + "5": {"x": 2644, "y": 2856}, + "6": {"x": 2668, "y": 2856} } }, "warnings": null }, { - "id": 670, - "sourceNodeId": 170, - "sourcePortId": 1355, - "targetNodeId": 135, - "targetPortId": 1356, + "id": 726, + "sourceNodeId": 192, + "sourcePortId": 1468, + "targetNodeId": 193, + "targetPortId": 1469, "travelTime": { "lock": true, - "time": 7, + "time": 12, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 43, + "lock": true, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 43 + "consecutiveTime": 224 }, "sourceArrival": { - "lock": false, - "time": 17, + "lock": true, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 17 + "consecutiveTime": 136 }, "targetDeparture": { "lock": true, - "time": 10, - "warning": null, + "time": 4, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 10 + "consecutiveTime": 124 }, "targetArrival": { "lock": true, - "time": 50, - "warning": null, + "time": 56, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 50 + "consecutiveTime": 236 }, "numberOfStops": 0, - "trainrunId": 80, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2800, "y": 734}, - {"x": 2800, "y": 670}, - {"x": 2800, "y": 414}, - {"x": 2800, "y": 350} + {"x": 2448, "y": 2462}, + {"x": 2448, "y": 2398}, + {"x": 2368, "y": 2482}, + {"x": 2368, "y": 2418} ], "textPositions": { - "0": {"x": 2812, "y": 716}, - "1": {"x": 2788, "y": 688}, - "2": {"x": 2788, "y": 368}, - "3": {"x": 2812, "y": 396}, - "4": {"x": 2788, "y": 542}, - "5": {"x": 2788, "y": 542}, - "6": {"x": 2812, "y": 542} + "0": {"x": 2460, "y": 2444}, + "1": {"x": 2436, "y": 2416}, + "2": {"x": 2356, "y": 2436}, + "3": {"x": 2380, "y": 2464}, + "4": {"x": 2396, "y": 2440}, + "5": {"x": 2396, "y": 2440}, + "6": {"x": 2420, "y": 2440} } }, "warnings": null }, { - "id": 671, - "sourceNodeId": 170, - "sourcePortId": 1357, - "targetNodeId": 135, - "targetPortId": 1358, + "id": 727, + "sourceNodeId": 193, + "sourcePortId": 1470, + "targetNodeId": 194, + "targetPortId": 1471, "travelTime": { "lock": true, - "time": 8, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 47, + "lock": true, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 238 }, "sourceArrival": { - "lock": false, - "time": 13, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 122 }, "targetDeparture": { "lock": true, - "time": 5, - "warning": null, + "time": 57, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 5 + "consecutiveTime": 117 }, "targetArrival": { "lock": true, - "time": 55, - "warning": null, + "time": 3, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 355 + "consecutiveTime": 243 }, "numberOfStops": 0, "trainrunId": 78, @@ -12309,541 +17641,589 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2768, "y": 734}, - {"x": 2768, "y": 670}, - {"x": 2768, "y": 414}, - {"x": 2768, "y": 350} + {"x": 2368, "y": 2350}, + {"x": 2368, "y": 2286}, + {"x": 2328, "y": 2426}, + {"x": 2328, "y": 2362} ], "textPositions": { - "0": {"x": 2780, "y": 716}, - "1": {"x": 2756, "y": 688}, - "2": {"x": 2756, "y": 368}, - "3": {"x": 2780, "y": 396}, - "4": {"x": 2756, "y": 542}, - "5": {"x": 2756, "y": 542}, - "6": {"x": 2780, "y": 542} + "0": {"x": 2380, "y": 2332}, + "1": {"x": 2356, "y": 2304}, + "2": {"x": 2316, "y": 2380}, + "3": {"x": 2340, "y": 2408}, + "4": {"x": 2336, "y": 2356}, + "5": {"x": 2336, "y": 2356}, + "6": {"x": 2360, "y": 2356} } }, "warnings": null }, { - "id": 672, - "sourceNodeId": 170, - "sourcePortId": 1359, - "targetNodeId": 135, - "targetPortId": 1360, + "id": 728, + "sourceNodeId": 194, + "sourcePortId": 1472, + "targetNodeId": 195, + "targetPortId": 1473, "travelTime": { "lock": true, - "time": 8, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 47, + "lock": true, + "time": 5, "warning": null, "timeFormatter": null, - "consecutiveTime": 107 + "consecutiveTime": 245 }, "sourceArrival": { - "lock": false, - "time": 13, + "lock": true, + "time": 55, "warning": null, "timeFormatter": null, - "consecutiveTime": 13 + "consecutiveTime": 115 }, "targetDeparture": { "lock": true, - "time": 5, - "warning": null, + "time": 54, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 5 + "consecutiveTime": 114 }, "targetArrival": { "lock": true, - "time": 55, - "warning": null, + "time": 6, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 115 + "consecutiveTime": 246 }, "numberOfStops": 0, - "trainrunId": 76, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2672, "y": 734}, - {"x": 2672, "y": 670}, - {"x": 2672, "y": 414}, - {"x": 2672, "y": 350} + {"x": 2328, "y": 2294}, + {"x": 2328, "y": 2230}, + {"x": 2308, "y": 2398}, + {"x": 2308, "y": 2334} ], "textPositions": { - "0": {"x": 2684, "y": 716}, - "1": {"x": 2660, "y": 688}, - "2": {"x": 2660, "y": 368}, - "3": {"x": 2684, "y": 396}, - "4": {"x": 2660, "y": 542}, - "5": {"x": 2660, "y": 542}, - "6": {"x": 2684, "y": 542} + "0": {"x": 2340, "y": 2276}, + "1": {"x": 2316, "y": 2248}, + "2": {"x": 2296, "y": 2352}, + "3": {"x": 2320, "y": 2380}, + "4": {"x": 2306, "y": 2314}, + "5": {"x": 2306, "y": 2314}, + "6": {"x": 2330, "y": 2314} } }, "warnings": null }, { - "id": 673, - "sourceNodeId": 170, - "sourcePortId": 1361, - "targetNodeId": 140, - "targetPortId": 1362, + "id": 729, + "sourceNodeId": 195, + "sourcePortId": 1474, + "targetNodeId": 196, + "targetPortId": 1475, "travelTime": { "lock": true, - "time": 47, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 15, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 75 + "consecutiveTime": 248 }, "sourceArrival": { - "lock": false, - "time": 45, - "warning": null, + "lock": true, + "time": 52, + "warning": { + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 285 + "consecutiveTime": 112 }, "targetDeparture": { "lock": true, - "time": 58, - "warning": null, + "time": 52, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 238 + "consecutiveTime": 112 }, "targetArrival": { "lock": true, - "time": 2, - "warning": null, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 122 + "consecutiveTime": 249 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 752}, - {"x": 2914, "y": 752}, - {"x": 4574, "y": 1200}, - {"x": 4638, "y": 1200} + {"x": 2308, "y": 2266}, + {"x": 2308, "y": 2202}, + {"x": 2298, "y": 2384}, + {"x": 2298, "y": 2320} ], "textPositions": { - "0": {"x": 2868, "y": 764}, - "1": {"x": 2896, "y": 740}, - "2": {"x": 4620, "y": 1188}, - "3": {"x": 4592, "y": 1212}, - "4": {"x": 3744, "y": 964}, - "5": {"x": 3744, "y": 964}, - "6": {"x": 3744, "y": 988} + "0": {"x": 2320, "y": 2248}, + "1": {"x": 2296, "y": 2220}, + "2": {"x": 2286, "y": 2338}, + "3": {"x": 2310, "y": 2366}, + "4": {"x": 2291, "y": 2293}, + "5": {"x": 2291, "y": 2293}, + "6": {"x": 2315, "y": 2293} } }, "warnings": null }, { - "id": 674, - "sourceNodeId": 170, - "sourcePortId": 1363, - "targetNodeId": 140, - "targetPortId": 1364, + "id": 730, + "sourceNodeId": 196, + "sourcePortId": 1476, + "targetNodeId": 159, + "targetPortId": 1086, "travelTime": { - "lock": false, - "time": 61, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 21, - "warning": null, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 141 + "consecutiveTime": 249 }, "sourceArrival": { "lock": true, - "time": 39, - "warning": null, + "time": 52, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 279 + "consecutiveTime": 112 }, "targetDeparture": { "lock": true, - "time": 38, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 218 + "consecutiveTime": 111 }, "targetArrival": { "lock": true, - "time": 22, - "warning": null, + "time": 9, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 202 + "consecutiveTime": 249 }, - "numberOfStops": 5, - "trainrunId": 86, + "numberOfStops": 0, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2850, "y": 784}, - {"x": 2914, "y": 784}, - {"x": 4574, "y": 1232}, - {"x": 4638, "y": 1232} + {"x": 2298, "y": 2252}, + {"x": 2298, "y": 2188}, + {"x": 2320, "y": 2398}, + {"x": 2320, "y": 2334} ], "textPositions": { - "0": {"x": 2868, "y": 796}, - "1": {"x": 2896, "y": 772}, - "2": {"x": 4620, "y": 1220}, - "3": {"x": 4592, "y": 1244}, - "4": {"x": 3744, "y": 996}, - "5": {"x": 3744, "y": 996}, - "6": {"x": 3744, "y": 1020} + "0": {"x": 2310, "y": 2234}, + "1": {"x": 2286, "y": 2206}, + "2": {"x": 2308, "y": 2352}, + "3": {"x": 2332, "y": 2380}, + "4": {"x": 2321, "y": 2293}, + "5": {"x": 2321, "y": 2293}, + "6": {"x": 2297, "y": 2293} } }, "warnings": null }, { - "id": 675, - "sourceNodeId": 142, - "sourcePortId": 1365, - "targetNodeId": 141, - "targetPortId": 1366, + "id": 731, + "sourceNodeId": 197, + "sourcePortId": 1478, + "targetNodeId": 155, + "targetPortId": 1088, "travelTime": { "lock": true, - "time": 19, + "time": 15, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 55, - "warning": null, + "time": 27, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 475 + "consecutiveTime": 267 }, "sourceArrival": { "lock": true, - "time": 5, - "warning": null, + "time": 33, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 125 + "consecutiveTime": 93 }, "targetDeparture": { - "lock": false, - "time": 46, + "lock": true, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 78 }, "targetArrival": { - "lock": false, - "time": 14, + "lock": true, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 494 + "consecutiveTime": 282 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": 1726}, - {"x": 144, "y": 1662}, - {"x": 144, "y": 1314}, - {"x": 144, "y": 1250} + {"x": 2562, "y": 2224}, + {"x": 2626, "y": 2224}, + {"x": 2590, "y": 2224}, + {"x": 2654, "y": 2224} ], "textPositions": { - "0": {"x": 156, "y": 1708}, - "1": {"x": 132, "y": 1680}, - "2": {"x": 132, "y": 1268}, - "3": {"x": 156, "y": 1296}, - "4": {"x": 132, "y": 1488}, - "5": {"x": 132, "y": 1488}, - "6": {"x": 156, "y": 1488} + "0": {"x": 2580, "y": 2236}, + "1": {"x": 2608, "y": 2212}, + "2": {"x": 2636, "y": 2212}, + "3": {"x": 2608, "y": 2236}, + "4": {"x": 2608, "y": 2212}, + "5": {"x": 2608, "y": 2212}, + "6": {"x": 2608, "y": 2236} } }, "warnings": null }, { - "id": 676, - "sourceNodeId": 141, - "sourcePortId": 1367, - "targetNodeId": 143, - "targetPortId": 1368, + "id": 732, + "sourceNodeId": 198, + "sourcePortId": 1480, + "targetNodeId": 199, + "targetPortId": 1481, "travelTime": { - "lock": true, - "time": 7, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 14, + "lock": true, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 494 + "consecutiveTime": 296 }, "sourceArrival": { - "lock": false, - "time": 46, + "lock": true, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 64 }, "targetDeparture": { - "lock": false, - "time": 39, - "warning": null, + "lock": true, + "time": 0, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 99 + "consecutiveTime": 60 }, "targetArrival": { - "lock": false, - "time": 21, - "warning": null, + "lock": true, + "time": 0, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 501 + "consecutiveTime": 300 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 144, "y": 1182}, - {"x": 144, "y": 1118}, - {"x": 144, "y": 866}, - {"x": 144, "y": 802} + {"x": 2672, "y": 1982}, + {"x": 2672, "y": 1918}, + {"x": 2672, "y": 2018}, + {"x": 2672, "y": 1954} ], "textPositions": { - "0": {"x": 156, "y": 1164}, - "1": {"x": 132, "y": 1136}, - "2": {"x": 132, "y": 820}, - "3": {"x": 156, "y": 848}, - "4": {"x": 132, "y": 992}, - "5": {"x": 132, "y": 992}, - "6": {"x": 156, "y": 992} + "0": {"x": 2684, "y": 1964}, + "1": {"x": 2660, "y": 1936}, + "2": {"x": 2660, "y": 1972}, + "3": {"x": 2684, "y": 2000}, + "4": {"x": 2660, "y": 1968}, + "5": {"x": 2660, "y": 1968}, + "6": {"x": 2684, "y": 1968} } }, "warnings": null }, { - "id": 677, - "sourceNodeId": 143, - "sourcePortId": 1369, - "targetNodeId": 133, - "targetPortId": 1370, + "id": 733, + "sourceNodeId": 199, + "sourcePortId": 1482, + "targetNodeId": 200, + "targetPortId": 1483, "travelTime": { - "lock": true, - "time": 7, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 23, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, - "consecutiveTime": 503 + "consecutiveTime": 302 }, "sourceArrival": { - "lock": false, - "time": 37, + "lock": true, + "time": 58, "warning": null, "timeFormatter": null, - "consecutiveTime": 97 + "consecutiveTime": 58 }, "targetDeparture": { - "lock": false, - "time": 30, - "warning": null, + "lock": true, + "time": 57, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 90 + "consecutiveTime": 57 }, "targetArrival": { - "lock": false, - "time": 30, - "warning": null, + "lock": true, + "time": 3, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 510 + "consecutiveTime": 303 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": 734}, - {"x": 112, "y": 670}, - {"x": 112, "y": 414}, - {"x": 112, "y": 350} + {"x": 2672, "y": 1886}, + {"x": 2672, "y": 1822}, + {"x": 2672, "y": 1970}, + {"x": 2672, "y": 1906} ], "textPositions": { - "0": {"x": 124, "y": 716}, - "1": {"x": 100, "y": 688}, - "2": {"x": 100, "y": 368}, - "3": {"x": 124, "y": 396}, - "4": {"x": 100, "y": 542}, - "5": {"x": 100, "y": 542}, - "6": {"x": 124, "y": 542} + "0": {"x": 2684, "y": 1868}, + "1": {"x": 2660, "y": 1840}, + "2": {"x": 2660, "y": 1924}, + "3": {"x": 2684, "y": 1952}, + "4": {"x": 2660, "y": 1896}, + "5": {"x": 2660, "y": 1896}, + "6": {"x": 2684, "y": 1896} } }, "warnings": null }, { - "id": 678, - "sourceNodeId": 133, - "sourcePortId": 1371, - "targetNodeId": 144, - "targetPortId": 1372, + "id": 734, + "sourceNodeId": 200, + "sourcePortId": 1484, + "targetNodeId": 154, + "targetPortId": 1090, "travelTime": { - "lock": true, - "time": 10, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 32, - "warning": null, + "time": 5, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 512 + "consecutiveTime": 305 }, "sourceArrival": { "lock": true, - "time": 28, - "warning": null, + "time": 55, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 88 + "consecutiveTime": 55 }, "targetDeparture": { - "lock": false, - "time": 18, + "lock": true, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 78 + "consecutiveTime": 54 }, "targetArrival": { - "lock": false, - "time": 42, + "lock": true, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 522 + "consecutiveTime": 306 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 78, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 176, "y": 94}, - {"x": 176, "y": 30}, - {"x": 176, "y": -290}, - {"x": 176, "y": -354} + {"x": 2672, "y": 1838}, + {"x": 2672, "y": 1774}, + {"x": 2768, "y": 1950}, + {"x": 2768, "y": 1886} ], "textPositions": { - "0": {"x": 188, "y": 76}, - "1": {"x": 164, "y": 48}, - "2": {"x": 164, "y": -336}, - "3": {"x": 188, "y": -308}, - "4": {"x": 164, "y": -130}, - "5": {"x": 164, "y": -130}, - "6": {"x": 188, "y": -130} + "0": {"x": 2684, "y": 1820}, + "1": {"x": 2660, "y": 1792}, + "2": {"x": 2756, "y": 1904}, + "3": {"x": 2780, "y": 1932}, + "4": {"x": 2732, "y": 1862}, + "5": {"x": 2732, "y": 1862}, + "6": {"x": 2708, "y": 1862} } }, "warnings": null }, { - "id": 679, - "sourceNodeId": 144, - "sourcePortId": 1373, - "targetNodeId": 145, - "targetPortId": 1374, + "id": 735, + "sourceNodeId": 201, + "sourcePortId": 1486, + "targetNodeId": 170, + "targetPortId": 1098, "travelTime": { - "lock": true, - "time": 5, + "lock": false, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 42, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 522 + "consecutiveTime": 67 }, "sourceArrival": { - "lock": false, - "time": 18, + "lock": true, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 78 + "consecutiveTime": 233 }, "targetDeparture": { - "lock": false, - "time": 13, + "lock": true, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 73 + "consecutiveTime": 227 }, "targetArrival": { - "lock": false, - "time": 47, + "lock": true, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 527 + "consecutiveTime": 73 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 240, "y": -450}, - {"x": 240, "y": -514}, - {"x": 240, "y": -798}, - {"x": 240, "y": -862} + {"x": 2672, "y": 1022}, + {"x": 2672, "y": 958}, + {"x": 2768, "y": 894}, + {"x": 2768, "y": 830} ], "textPositions": { - "0": {"x": 252, "y": -468}, - "1": {"x": 228, "y": -496}, - "2": {"x": 228, "y": -844}, - "3": {"x": 252, "y": -816}, - "4": {"x": 228, "y": -656}, - "5": {"x": 228, "y": -656}, - "6": {"x": 252, "y": -656} + "0": {"x": 2684, "y": 1004}, + "1": {"x": 2660, "y": 976}, + "2": {"x": 2756, "y": 848}, + "3": {"x": 2780, "y": 876}, + "4": {"x": 2708, "y": 926}, + "5": {"x": 2708, "y": 926}, + "6": {"x": 2732, "y": 926} } }, "warnings": null - }, - { - "id": 680, - "sourceNodeId": 145, - "sourcePortId": 1375, - "targetNodeId": 146, - "targetPortId": 1376, + }, + { + "id": 736, + "sourceNodeId": 202, + "sourcePortId": 1488, + "targetNodeId": 150, + "targetPortId": 1140, "travelTime": { "lock": true, "time": 5, @@ -12852,1696 +18232,1768 @@ "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 47, + "lock": true, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 527 + "consecutiveTime": 16 }, "sourceArrival": { - "lock": false, - "time": 13, + "lock": true, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 73 + "consecutiveTime": 284 }, "targetDeparture": { - "lock": false, - "time": 8, + "lock": true, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 279 }, "targetArrival": { - "lock": false, - "time": 52, + "lock": true, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 532 + "consecutiveTime": 21 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 240, "y": -930}, - {"x": 240, "y": -994}, - {"x": 240, "y": -1278}, - {"x": 240, "y": -1342} + {"x": 3074, "y": 48}, + {"x": 3138, "y": 48}, + {"x": 3230, "y": 176}, + {"x": 3294, "y": 176} ], "textPositions": { - "0": {"x": 252, "y": -948}, - "1": {"x": 228, "y": -976}, - "2": {"x": 228, "y": -1324}, - "3": {"x": 252, "y": -1296}, - "4": {"x": 228, "y": -1136}, - "5": {"x": 228, "y": -1136}, - "6": {"x": 252, "y": -1136} + "0": {"x": 3092, "y": 60}, + "1": {"x": 3120, "y": 36}, + "2": {"x": 3276, "y": 164}, + "3": {"x": 3248, "y": 188}, + "4": {"x": 3184, "y": 100}, + "5": {"x": 3184, "y": 100}, + "6": {"x": 3184, "y": 124} } }, "warnings": null }, { - "id": 681, - "sourceNodeId": 146, - "sourcePortId": 1377, - "targetNodeId": 134, - "targetPortId": 1378, + "id": 737, + "sourceNodeId": 203, + "sourcePortId": 1490, + "targetNodeId": 204, + "targetPortId": 1491, "travelTime": { "lock": true, - "time": 5, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 52, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 532 + "consecutiveTime": 61 }, "sourceArrival": { "lock": false, - "time": 8, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 239 }, "targetDeparture": { - "lock": true, - "time": 3, + "lock": false, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 63 + "consecutiveTime": 229 }, "targetArrival": { - "lock": true, - "time": 57, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 537 + "consecutiveTime": 71 }, "numberOfStops": 0, - "trainrunId": 77, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 240, "y": -1410}, - {"x": 240, "y": -1474}, - {"x": 240, "y": -1758}, - {"x": 240, "y": -1822} + {"x": 4354, "y": 80}, + {"x": 4418, "y": 80}, + {"x": 4382, "y": 96}, + {"x": 4446, "y": 96} ], "textPositions": { - "0": {"x": 252, "y": -1428}, - "1": {"x": 228, "y": -1456}, - "2": {"x": 228, "y": -1804}, - "3": {"x": 252, "y": -1776}, - "4": {"x": 228, "y": -1616}, - "5": {"x": 228, "y": -1616}, - "6": {"x": 252, "y": -1616} + "0": {"x": 4372, "y": 92}, + "1": {"x": 4400, "y": 68}, + "2": {"x": 4428, "y": 84}, + "3": {"x": 4400, "y": 108}, + "4": {"x": 4400, "y": 76}, + "5": {"x": 4400, "y": 76}, + "6": {"x": 4400, "y": 100} } }, "warnings": null }, { - "id": 682, - "sourceNodeId": 171, - "sourcePortId": 1379, - "targetNodeId": 128, - "targetPortId": 1380, + "id": 738, + "sourceNodeId": 204, + "sourcePortId": 1492, + "targetNodeId": 205, + "targetPortId": 1493, "travelTime": { - "lock": false, - "time": 49, + "lock": true, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 27, + "lock": false, + "time": 13, "warning": null, "timeFormatter": null, - "consecutiveTime": 387 + "consecutiveTime": 73 }, "sourceArrival": { - "lock": true, - "time": 33, + "lock": false, + "time": 47, "warning": null, "timeFormatter": null, - "consecutiveTime": 153 + "consecutiveTime": 227 }, "targetDeparture": { - "lock": true, - "time": 44, + "lock": false, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 104 + "consecutiveTime": 223 }, "targetArrival": { - "lock": true, - "time": 16, + "lock": false, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 436 + "consecutiveTime": 77 }, - "numberOfStops": 2, - "trainrunId": 81, + "numberOfStops": 0, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2562, "y": 336}, - {"x": -2626, "y": 336}, - {"x": -2910, "y": 592}, - {"x": -2974, "y": 592} + {"x": 4546, "y": 96}, + {"x": 4610, "y": 96}, + {"x": 4478, "y": 104}, + {"x": 4542, "y": 104} ], "textPositions": { - "0": {"x": -2580, "y": 324}, - "1": {"x": -2608, "y": 348}, - "2": {"x": -2956, "y": 604}, - "3": {"x": -2928, "y": 580}, - "4": {"x": -2768, "y": 452}, - "5": {"x": -2768, "y": 452}, - "6": {"x": -2768, "y": 476} + "0": {"x": 4564, "y": 108}, + "1": {"x": 4592, "y": 84}, + "2": {"x": 4524, "y": 92}, + "3": {"x": 4496, "y": 116}, + "4": {"x": 4544, "y": 88}, + "5": {"x": 4544, "y": 88}, + "6": {"x": 4544, "y": 112} } }, "warnings": null }, { - "id": 683, - "sourceNodeId": 171, - "sourcePortId": 1381, - "targetNodeId": 128, - "targetPortId": 1382, + "id": 739, + "sourceNodeId": 205, + "sourcePortId": 1494, + "targetNodeId": 206, + "targetPortId": 1495, "travelTime": { "lock": true, - "time": 44, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 54, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 414 + "consecutiveTime": 79 }, "sourceArrival": { "lock": false, - "time": 6, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 126 + "consecutiveTime": 221 }, "targetDeparture": { "lock": false, - "time": 22, - "warning": null, + "time": 40, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 82 + "consecutiveTime": 220 }, "targetArrival": { "lock": false, - "time": 38, - "warning": null, + "time": 20, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 458 + "consecutiveTime": 80 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2562, "y": 304}, - {"x": -2626, "y": 304}, - {"x": -2910, "y": 560}, - {"x": -2974, "y": 560} + {"x": 4642, "y": 104}, + {"x": 4706, "y": 104}, + {"x": 4526, "y": 108}, + {"x": 4590, "y": 108} ], "textPositions": { - "0": {"x": -2580, "y": 292}, - "1": {"x": -2608, "y": 316}, - "2": {"x": -2956, "y": 572}, - "3": {"x": -2928, "y": 548}, - "4": {"x": -2768, "y": 420}, - "5": {"x": -2768, "y": 420}, - "6": {"x": -2768, "y": 444} + "0": {"x": 4660, "y": 116}, + "1": {"x": 4688, "y": 92}, + "2": {"x": 4572, "y": 96}, + "3": {"x": 4544, "y": 120}, + "4": {"x": 4616, "y": 94}, + "5": {"x": 4616, "y": 94}, + "6": {"x": 4616, "y": 118} } }, "warnings": null }, { - "id": 684, - "sourceNodeId": 172, - "sourcePortId": 1383, - "targetNodeId": 178, - "targetPortId": 1384, + "id": 740, + "sourceNodeId": 206, + "sourcePortId": 1496, + "targetNodeId": 137, + "targetPortId": 1144, "travelTime": { "lock": true, - "time": 16, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 39, - "warning": null, + "time": 21, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 339 + "consecutiveTime": 81 }, "sourceArrival": { "lock": false, - "time": 21, - "warning": null, + "time": 39, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 201 + "consecutiveTime": 219 }, "targetDeparture": { "lock": false, - "time": 5, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 185 + "consecutiveTime": 218 }, "targetArrival": { "lock": false, - "time": 55, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 355 + "consecutiveTime": 82 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -610, "y": 304}, - {"x": -674, "y": 304}, - {"x": -1534, "y": 304}, - {"x": -1598, "y": 304} + {"x": 4690, "y": 108}, + {"x": 4754, "y": 108}, + {"x": 4574, "y": 176}, + {"x": 4638, "y": 176} ], "textPositions": { - "0": {"x": -628, "y": 292}, - "1": {"x": -656, "y": 316}, - "2": {"x": -1580, "y": 316}, - "3": {"x": -1552, "y": 292}, - "4": {"x": -1104, "y": 292}, - "5": {"x": -1104, "y": 292}, - "6": {"x": -1104, "y": 316} + "0": {"x": 4708, "y": 120}, + "1": {"x": 4736, "y": 96}, + "2": {"x": 4620, "y": 164}, + "3": {"x": 4592, "y": 188}, + "4": {"x": 4664, "y": 130}, + "5": {"x": 4664, "y": 130}, + "6": {"x": 4664, "y": 154} } }, "warnings": null }, { - "id": 685, - "sourceNodeId": 174, - "sourcePortId": 1386, - "targetNodeId": 172, - "targetPortId": 1385, + "id": 741, + "sourceNodeId": 207, + "sourcePortId": 1498, + "targetNodeId": 208, + "targetPortId": 1499, "travelTime": { "lock": true, - "time": 8, + "time": 14, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 9, + "lock": false, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 69 + "consecutiveTime": 116 }, "sourceArrival": { - "lock": true, - "time": 51, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 351 + "consecutiveTime": 184 }, "targetDeparture": { "lock": false, - "time": 43, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 343 + "consecutiveTime": 170 }, "targetArrival": { "lock": false, - "time": 17, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 77 + "consecutiveTime": 130 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -894, "y": 368}, - {"x": -830, "y": 368}, - {"x": -674, "y": 336}, - {"x": -610, "y": 336} + {"x": 4656, "y": 706}, + {"x": 4656, "y": 770}, + {"x": 4656, "y": 846}, + {"x": 4656, "y": 910} ], "textPositions": { - "0": {"x": -876, "y": 380}, - "1": {"x": -848, "y": 356}, - "2": {"x": -628, "y": 324}, - "3": {"x": -656, "y": 348}, - "4": {"x": -752, "y": 340}, - "5": {"x": -752, "y": 340}, - "6": {"x": -752, "y": 364} + "0": {"x": 4644, "y": 724}, + "1": {"x": 4668, "y": 752}, + "2": {"x": 4668, "y": 892}, + "3": {"x": 4644, "y": 864}, + "4": {"x": 4644, "y": 808}, + "5": {"x": 4644, "y": 808}, + "6": {"x": 4668, "y": 808} } }, "warnings": null }, - { - "id": 686, - "sourceNodeId": 178, - "sourcePortId": 1388, - "targetNodeId": 172, - "targetPortId": 1387, + { + "id": 742, + "sourceNodeId": 208, + "sourcePortId": 1500, + "targetNodeId": 209, + "targetPortId": 1501, "travelTime": { "lock": true, - "time": 8, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 5, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 132 }, "sourceArrival": { "lock": false, - "time": 55, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 355 + "consecutiveTime": 168 }, "targetDeparture": { "lock": false, - "time": 47, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 347 + "consecutiveTime": 162 }, "targetArrival": { "lock": false, - "time": 13, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 73 + "consecutiveTime": 138 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1598, "y": 272}, - {"x": -1534, "y": 272}, - {"x": -674, "y": 272}, - {"x": -610, "y": 272} + {"x": 4656, "y": 978}, + {"x": 4656, "y": 1042}, + {"x": 4656, "y": 982}, + {"x": 4656, "y": 1046} ], "textPositions": { - "0": {"x": -1580, "y": 284}, - "1": {"x": -1552, "y": 260}, - "2": {"x": -628, "y": 260}, - "3": {"x": -656, "y": 284}, - "4": {"x": -1104, "y": 260}, - "5": {"x": -1104, "y": 260}, - "6": {"x": -1104, "y": 284} + "0": {"x": 4644, "y": 996}, + "1": {"x": 4668, "y": 1024}, + "2": {"x": 4668, "y": 1028}, + "3": {"x": 4644, "y": 1000}, + "4": {"x": 4644, "y": 1012}, + "5": {"x": 4644, "y": 1012}, + "6": {"x": 4668, "y": 1012} } }, "warnings": null }, { - "id": 687, - "sourceNodeId": 178, - "sourcePortId": 1390, - "targetNodeId": 172, - "targetPortId": 1389, + "id": 743, + "sourceNodeId": 209, + "sourcePortId": 1502, + "targetNodeId": 210, + "targetPortId": 1503, "travelTime": { - "lock": false, - "time": 17, + "lock": true, + "time": 2, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 6, + "lock": false, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 66 + "consecutiveTime": 140 }, "sourceArrival": { - "lock": true, - "time": 54, + "lock": false, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 354 + "consecutiveTime": 160 }, "targetDeparture": { "lock": false, - "time": 37, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 337 + "consecutiveTime": 158 }, "targetArrival": { "lock": false, - "time": 23, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 142 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1598, "y": 240}, - {"x": -1534, "y": 240}, - {"x": -674, "y": 240}, - {"x": -610, "y": 240} + {"x": 4656, "y": 1114}, + {"x": 4656, "y": 1178}, + {"x": 4656, "y": 1050}, + {"x": 4656, "y": 1114} ], "textPositions": { - "0": {"x": -1580, "y": 252}, - "1": {"x": -1552, "y": 228}, - "2": {"x": -628, "y": 228}, - "3": {"x": -656, "y": 252}, - "4": {"x": -1104, "y": 228}, - "5": {"x": -1104, "y": 228}, - "6": {"x": -1104, "y": 252} + "0": {"x": 4644, "y": 1132}, + "1": {"x": 4668, "y": 1160}, + "2": {"x": 4668, "y": 1096}, + "3": {"x": 4644, "y": 1068}, + "4": {"x": 4644, "y": 1114}, + "5": {"x": 4644, "y": 1114}, + "6": {"x": 4668, "y": 1114} } }, "warnings": null }, { - "id": 688, - "sourceNodeId": 172, - "sourcePortId": 1391, - "targetNodeId": 178, - "targetPortId": 1392, + "id": 744, + "sourceNodeId": 210, + "sourcePortId": 1504, + "targetNodeId": 211, + "targetPortId": 1505, "travelTime": { "lock": true, - "time": 18, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 5, + "time": 24, "warning": null, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 144 }, "sourceArrival": { "lock": false, - "time": 55, - "warning": null, + "time": 36, + "warning": { + "title": "Avertissement d'arrivée à l'origine", + "description": "L'heure d'arrivée à l'origine ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 235 + "consecutiveTime": 156 }, "targetDeparture": { "lock": false, - "time": 37, - "warning": null, + "time": 36, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 217 + "consecutiveTime": 156 }, "targetArrival": { "lock": false, - "time": 23, - "warning": null, + "time": 25, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 145 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -610, "y": 208}, - {"x": -674, "y": 208}, - {"x": -1534, "y": 208}, - {"x": -1598, "y": 208} + {"x": 4656, "y": 1182}, + {"x": 4656, "y": 1246}, + {"x": 4656, "y": 1084}, + {"x": 4656, "y": 1148} ], "textPositions": { - "0": {"x": -628, "y": 196}, - "1": {"x": -656, "y": 220}, - "2": {"x": -1580, "y": 220}, - "3": {"x": -1552, "y": 196}, - "4": {"x": -1104, "y": 196}, - "5": {"x": -1104, "y": 196}, - "6": {"x": -1104, "y": 220} + "0": {"x": 4644, "y": 1200}, + "1": {"x": 4668, "y": 1228}, + "2": {"x": 4668, "y": 1130}, + "3": {"x": 4644, "y": 1102}, + "4": {"x": 4644, "y": 1165}, + "5": {"x": 4644, "y": 1165}, + "6": {"x": 4668, "y": 1165} } }, "warnings": null }, { - "id": 689, - "sourceNodeId": 172, - "sourcePortId": 1393, - "targetNodeId": 133, - "targetPortId": 1394, + "id": 745, + "sourceNodeId": 211, + "sourcePortId": 1506, + "targetNodeId": 140, + "targetPortId": 1146, "travelTime": { "lock": true, - "time": 8, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 54, - "warning": null, + "time": 25, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 234 + "consecutiveTime": 145 }, "sourceArrival": { "lock": false, - "time": 6, - "warning": null, + "time": 36, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 66 + "consecutiveTime": 156 }, "targetDeparture": { - "lock": true, - "time": 58, + "lock": false, + "time": 35, "warning": null, "timeFormatter": null, - "consecutiveTime": 58 + "consecutiveTime": 155 }, "targetArrival": { - "lock": true, - "time": 2, - "warning": null, + "lock": false, + "time": 25, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 242 + "consecutiveTime": 145 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -510, "y": 176}, - {"x": -446, "y": 176}, - {"x": -2, "y": 176}, - {"x": 62, "y": 176} + {"x": 4656, "y": 1216}, + {"x": 4656, "y": 1280}, + {"x": 4656, "y": 1118}, + {"x": 4656, "y": 1182} ], "textPositions": { - "0": {"x": -492, "y": 188}, - "1": {"x": -464, "y": 164}, - "2": {"x": 44, "y": 164}, - "3": {"x": 16, "y": 188}, - "4": {"x": -224, "y": 164}, - "5": {"x": -224, "y": 164}, - "6": {"x": -224, "y": 188} + "0": {"x": 4644, "y": 1234}, + "1": {"x": 4668, "y": 1262}, + "2": {"x": 4668, "y": 1164}, + "3": {"x": 4644, "y": 1136}, + "4": {"x": 4644, "y": 1199}, + "5": {"x": 4644, "y": 1199}, + "6": {"x": 4668, "y": 1199} } }, "warnings": null }, { - "id": 690, - "sourceNodeId": 172, - "sourcePortId": 1395, - "targetNodeId": 178, - "targetPortId": 1396, + "id": 746, + "sourceNodeId": 212, + "sourcePortId": 1508, + "targetNodeId": 213, + "targetPortId": 1509, "travelTime": { "lock": true, - "time": 9, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 17, + "lock": true, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 377 + "consecutiveTime": 158 }, "sourceArrival": { - "lock": false, - "time": 43, + "lock": true, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 163 + "consecutiveTime": 142 }, "targetDeparture": { - "lock": false, - "time": 34, + "lock": true, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 154 + "consecutiveTime": 138 }, "targetArrival": { - "lock": false, - "time": 26, + "lock": true, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 386 + "consecutiveTime": 162 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 84, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -610, "y": 144}, - {"x": -674, "y": 144}, - {"x": -1534, "y": 144}, - {"x": -1598, "y": 144} + {"x": 4656, "y": 1602}, + {"x": 4656, "y": 1666}, + {"x": 4656, "y": 1646}, + {"x": 4656, "y": 1710} ], "textPositions": { - "0": {"x": -628, "y": 132}, - "1": {"x": -656, "y": 156}, - "2": {"x": -1580, "y": 156}, - "3": {"x": -1552, "y": 132}, - "4": {"x": -1104, "y": 132}, - "5": {"x": -1104, "y": 132}, - "6": {"x": -1104, "y": 156} + "0": {"x": 4644, "y": 1620}, + "1": {"x": 4668, "y": 1648}, + "2": {"x": 4668, "y": 1692}, + "3": {"x": 4644, "y": 1664}, + "4": {"x": 4644, "y": 1656}, + "5": {"x": 4644, "y": 1656}, + "6": {"x": 4668, "y": 1656} } }, "warnings": null }, { - "id": 691, - "sourceNodeId": 178, - "sourcePortId": 1398, - "targetNodeId": 173, - "targetPortId": 1397, + "id": 747, + "sourceNodeId": 213, + "sourcePortId": 1510, + "targetNodeId": 152, + "targetPortId": 1148, "travelTime": { "lock": true, - "time": 10, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 39, + "lock": true, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 39 + "consecutiveTime": 164 }, "sourceArrival": { - "lock": false, - "time": 21, + "lock": true, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 381 + "consecutiveTime": 136 }, "targetDeparture": { "lock": true, - "time": 11, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 371 + "consecutiveTime": 132 }, "targetArrival": { "lock": true, - "time": 49, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 49 + "consecutiveTime": 168 }, "numberOfStops": 0, - "trainrunId": 86, + "trainrunId": 84, "resourceId": 0, - "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - {"x": -1598, "y": 336}, - {"x": -1534, "y": 336}, - {"x": -1410, "y": 368}, - {"x": -1346, "y": 368} + "specificTrainrunSectionFrequencyId": null, + "path": { + "path": [ + {"x": 4656, "y": 1778}, + {"x": 4656, "y": 1842}, + {"x": 4688, "y": 1822}, + {"x": 4688, "y": 1886} ], "textPositions": { - "0": {"x": -1580, "y": 348}, - "1": {"x": -1552, "y": 324}, - "2": {"x": -1364, "y": 356}, - "3": {"x": -1392, "y": 380}, - "4": {"x": -1472, "y": 340}, - "5": {"x": -1472, "y": 340}, - "6": {"x": -1472, "y": 364} + "0": {"x": 4644, "y": 1796}, + "1": {"x": 4668, "y": 1824}, + "2": {"x": 4700, "y": 1868}, + "3": {"x": 4676, "y": 1840}, + "4": {"x": 4660, "y": 1832}, + "5": {"x": 4660, "y": 1832}, + "6": {"x": 4684, "y": 1832} } }, "warnings": null }, { - "id": 692, - "sourceNodeId": 173, - "sourcePortId": 1400, - "targetNodeId": 174, - "targetPortId": 1399, + "id": 748, + "sourceNodeId": 214, + "sourcePortId": 1512, + "targetNodeId": 152, + "targetPortId": 1152, "travelTime": { "lock": true, - "time": 17, + "time": 8, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 51, + "lock": true, + "time": 14, "warning": null, "timeFormatter": null, - "consecutiveTime": 51 + "consecutiveTime": 134 }, "sourceArrival": { - "lock": false, - "time": 9, + "lock": true, + "time": 46, "warning": null, "timeFormatter": null, - "consecutiveTime": 369 + "consecutiveTime": 226 }, "targetDeparture": { "lock": true, - "time": 52, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 352 + "consecutiveTime": 218 }, "targetArrival": { "lock": true, - "time": 8, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 142 }, - "numberOfStops": 1, - "trainrunId": 86, + "numberOfStops": 0, + "trainrunId": 85, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1246, "y": 368}, - {"x": -1182, "y": 368}, - {"x": -1058, "y": 368}, - {"x": -994, "y": 368} + {"x": 4656, "y": 1602}, + {"x": 4656, "y": 1666}, + {"x": 4656, "y": 1822}, + {"x": 4656, "y": 1886} ], "textPositions": { - "0": {"x": -1228, "y": 380}, - "1": {"x": -1200, "y": 356}, - "2": {"x": -1012, "y": 356}, - "3": {"x": -1040, "y": 380}, - "4": {"x": -1120, "y": 356}, - "5": {"x": -1120, "y": 356}, - "6": {"x": -1120, "y": 380} + "0": {"x": 4644, "y": 1620}, + "1": {"x": 4668, "y": 1648}, + "2": {"x": 4668, "y": 1868}, + "3": {"x": 4644, "y": 1840}, + "4": {"x": 4644, "y": 1744}, + "5": {"x": 4644, "y": 1744}, + "6": {"x": 4668, "y": 1744} } }, "warnings": null }, { - "id": 693, - "sourceNodeId": 149, - "sourcePortId": 1402, - "targetNodeId": 135, - "targetPortId": 1401, + "id": 749, + "sourceNodeId": 215, + "sourcePortId": 1514, + "targetNodeId": 152, + "targetPortId": 1156, "travelTime": { "lock": true, - "time": 8, + "time": 9, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 52, + "lock": true, + "time": 34, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 214 }, "sourceArrival": { - "lock": false, - "time": 8, + "lock": true, + "time": 26, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 206 }, "targetDeparture": { "lock": true, - "time": 0, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 300 + "consecutiveTime": 197 }, "targetArrival": { "lock": true, - "time": 0, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 60 + "consecutiveTime": 223 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 2338, "y": 80}, - {"x": 2402, "y": 80}, - {"x": 2590, "y": 80}, - {"x": 2654, "y": 80} + {"x": 4656, "y": 1602}, + {"x": 4656, "y": 1666}, + {"x": 4720, "y": 1822}, + {"x": 4720, "y": 1886} ], "textPositions": { - "0": {"x": 2356, "y": 92}, - "1": {"x": 2384, "y": 68}, - "2": {"x": 2636, "y": 68}, - "3": {"x": 2608, "y": 92}, - "4": {"x": 2496, "y": 68}, - "5": {"x": 2496, "y": 68}, - "6": {"x": 2496, "y": 92} + "0": {"x": 4644, "y": 1620}, + "1": {"x": 4668, "y": 1648}, + "2": {"x": 4732, "y": 1868}, + "3": {"x": 4708, "y": 1840}, + "4": {"x": 4700, "y": 1744}, + "5": {"x": 4700, "y": 1744}, + "6": {"x": 4676, "y": 1744} } }, "warnings": null }, { - "id": 694, - "sourceNodeId": 166, - "sourcePortId": 1404, - "targetNodeId": 149, - "targetPortId": 1403, + "id": 750, + "sourceNodeId": 216, + "sourcePortId": 1516, + "targetNodeId": 135, + "targetPortId": 1157, "travelTime": { "lock": true, - "time": 6, + "time": 2, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 46, + "time": 4, "warning": null, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 124 }, "sourceArrival": { "lock": false, - "time": 14, + "time": 56, "warning": null, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 296 }, "targetDeparture": { - "lock": false, - "time": 8, + "lock": true, + "time": 54, "warning": null, "timeFormatter": null, - "consecutiveTime": 308 + "consecutiveTime": 294 }, "targetArrival": { - "lock": false, - "time": 52, + "lock": true, + "time": 6, "warning": null, "timeFormatter": null, - "consecutiveTime": 52 + "consecutiveTime": 126 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1890, "y": 80}, - {"x": 1954, "y": 80}, - {"x": 2174, "y": 80}, - {"x": 2238, "y": 80} + {"x": 2546, "y": 48}, + {"x": 2610, "y": 48}, + {"x": 2590, "y": 240}, + {"x": 2654, "y": 240} ], "textPositions": { - "0": {"x": 1908, "y": 92}, - "1": {"x": 1936, "y": 68}, - "2": {"x": 2220, "y": 68}, - "3": {"x": 2192, "y": 92}, - "4": {"x": 2064, "y": 68}, - "5": {"x": 2064, "y": 68}, - "6": {"x": 2064, "y": 92} + "0": {"x": 2564, "y": 60}, + "1": {"x": 2592, "y": 36}, + "2": {"x": 2636, "y": 228}, + "3": {"x": 2608, "y": 252}, + "4": {"x": 2600, "y": 132}, + "5": {"x": 2600, "y": 132}, + "6": {"x": 2600, "y": 156} } }, "warnings": null }, { - "id": 695, - "sourceNodeId": 148, - "sourcePortId": 1406, - "targetNodeId": 166, - "targetPortId": 1405, + "id": 751, + "sourceNodeId": 217, + "sourcePortId": 1518, + "targetNodeId": 218, + "targetPortId": 1519, "travelTime": { - "lock": true, - "time": 6, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 40, + "lock": true, + "time": 49, "warning": null, "timeFormatter": null, - "consecutiveTime": 40 + "consecutiveTime": 469 }, "sourceArrival": { - "lock": false, - "time": 20, + "lock": true, + "time": 11, "warning": null, "timeFormatter": null, - "consecutiveTime": 320 + "consecutiveTime": 71 }, "targetDeparture": { - "lock": false, - "time": 14, - "warning": null, + "lock": true, + "time": 57, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 314 + "consecutiveTime": 57 }, "targetArrival": { - "lock": false, - "time": 46, - "warning": null, + "lock": true, + "time": 3, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 46 + "consecutiveTime": 483 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1442, "y": 80}, - {"x": 1506, "y": 80}, - {"x": 1726, "y": 80}, - {"x": 1790, "y": 80} + {"x": -3026, "y": 272}, + {"x": -3090, "y": 272}, + {"x": -3110, "y": 416}, + {"x": -3174, "y": 416} ], "textPositions": { - "0": {"x": 1460, "y": 92}, - "1": {"x": 1488, "y": 68}, - "2": {"x": 1772, "y": 68}, - "3": {"x": 1744, "y": 92}, - "4": {"x": 1616, "y": 68}, - "5": {"x": 1616, "y": 68}, - "6": {"x": 1616, "y": 92} + "0": {"x": -3044, "y": 260}, + "1": {"x": -3072, "y": 284}, + "2": {"x": -3156, "y": 428}, + "3": {"x": -3128, "y": 404}, + "4": {"x": -3100, "y": 332}, + "5": {"x": -3100, "y": 332}, + "6": {"x": -3100, "y": 356} } }, "warnings": null }, { - "id": 696, - "sourceNodeId": 147, - "sourcePortId": 1408, - "targetNodeId": 148, - "targetPortId": 1407, + "id": 752, + "sourceNodeId": 218, + "sourcePortId": 1520, + "targetNodeId": 177, + "targetPortId": 1184, "travelTime": { - "lock": true, - "time": 6, + "lock": false, + "time": 13, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 34, - "warning": null, + "lock": true, + "time": 5, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 34 + "consecutiveTime": 485 }, "sourceArrival": { - "lock": false, - "time": 26, - "warning": null, + "lock": true, + "time": 55, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 326 + "consecutiveTime": 55 }, "targetDeparture": { - "lock": false, - "time": 20, + "lock": true, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 320 + "consecutiveTime": 42 }, "targetArrival": { - "lock": false, - "time": 40, + "lock": true, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 40 + "consecutiveTime": 498 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 87, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 1058, "y": 80}, - {"x": 1122, "y": 80}, - {"x": 1278, "y": 80}, - {"x": 1342, "y": 80} - ], - "textPositions": { - "0": {"x": 1076, "y": 92}, - "1": {"x": 1104, "y": 68}, - "2": {"x": 1324, "y": 68}, - "3": {"x": 1296, "y": 92}, - "4": {"x": 1200, "y": 68}, - "5": {"x": 1200, "y": 68}, - "6": {"x": 1200, "y": 92} + {"x": -3274, "y": 416}, + {"x": -3338, "y": 416}, + {"x": -3358, "y": 560}, + {"x": -3422, "y": 560} + ], + "textPositions": { + "0": {"x": -3292, "y": 404}, + "1": {"x": -3320, "y": 428}, + "2": {"x": -3404, "y": 572}, + "3": {"x": -3376, "y": 548}, + "4": {"x": -3348, "y": 476}, + "5": {"x": -3348, "y": 476}, + "6": {"x": -3348, "y": 500} } }, "warnings": null }, { - "id": 697, - "sourceNodeId": 144, - "sourcePortId": 1410, - "targetNodeId": 147, - "targetPortId": 1409, + "id": 753, + "sourceNodeId": 219, + "sourcePortId": 1522, + "targetNodeId": 135, + "targetPortId": 1191, "travelTime": { "lock": true, - "time": 7, + "time": 5, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 27, - "warning": null, + "lock": true, + "time": 16, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 27 + "consecutiveTime": 316 }, "sourceArrival": { - "lock": false, - "time": 33, - "warning": null, + "lock": true, + "time": 44, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 333 + "consecutiveTime": 224 }, "targetDeparture": { - "lock": false, - "time": 26, + "lock": true, + "time": 39, "warning": null, "timeFormatter": null, - "consecutiveTime": 326 + "consecutiveTime": 219 }, "targetArrival": { - "lock": false, - "time": 34, + "lock": true, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 34 + "consecutiveTime": 321 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 322, "y": -432}, - {"x": 386, "y": -432}, - {"x": 894, "y": 48}, - {"x": 958, "y": 48} + {"x": 2974, "y": 48}, + {"x": 2910, "y": 48}, + {"x": 2914, "y": 48}, + {"x": 2850, "y": 48} ], "textPositions": { - "0": {"x": 340, "y": -420}, - "1": {"x": 368, "y": -444}, - "2": {"x": 940, "y": 36}, - "3": {"x": 912, "y": 60}, - "4": {"x": 640, "y": -204}, - "5": {"x": 640, "y": -204}, - "6": {"x": 640, "y": -180} + "0": {"x": 2956, "y": 36}, + "1": {"x": 2928, "y": 60}, + "2": {"x": 2868, "y": 60}, + "3": {"x": 2896, "y": 36}, + "4": {"x": 2912, "y": 36}, + "5": {"x": 2912, "y": 36}, + "6": {"x": 2912, "y": 60} } }, "warnings": null }, { - "id": 698, - "sourceNodeId": 145, - "sourcePortId": 1412, - "targetNodeId": 144, - "targetPortId": 1411, + "id": 754, + "sourceNodeId": 220, + "sourcePortId": 1524, + "targetNodeId": 221, + "targetPortId": 1525, "travelTime": { - "lock": true, - "time": 6, + "lock": false, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 21, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 21 + "consecutiveTime": 270 }, "sourceArrival": { "lock": false, - "time": 39, + "time": 30, "warning": null, "timeFormatter": null, - "consecutiveTime": 339 + "consecutiveTime": 270 }, "targetDeparture": { - "lock": false, - "time": 33, - "warning": null, + "lock": true, + "time": 20, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 333 + "consecutiveTime": 260 }, "targetArrival": { - "lock": false, - "time": 27, - "warning": null, + "lock": true, + "time": 40, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 27 + "consecutiveTime": 280 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": -862}, - {"x": 112, "y": -798}, - {"x": 112, "y": -514}, - {"x": 112, "y": -450} + {"x": 4254, "y": 80}, + {"x": 4190, "y": 80}, + {"x": 4226, "y": 64}, + {"x": 4162, "y": 64} ], "textPositions": { - "0": {"x": 100, "y": -844}, - "1": {"x": 124, "y": -816}, - "2": {"x": 124, "y": -468}, - "3": {"x": 100, "y": -496}, - "4": {"x": 100, "y": -656}, - "5": {"x": 100, "y": -656}, - "6": {"x": 124, "y": -656} + "0": {"x": 4236, "y": 68}, + "1": {"x": 4208, "y": 92}, + "2": {"x": 4180, "y": 76}, + "3": {"x": 4208, "y": 52}, + "4": {"x": 4208, "y": 60}, + "5": {"x": 4208, "y": 60}, + "6": {"x": 4208, "y": 84} } }, "warnings": null }, { - "id": 699, - "sourceNodeId": 146, - "sourcePortId": 1414, - "targetNodeId": 145, - "targetPortId": 1413, + "id": 755, + "sourceNodeId": 221, + "sourcePortId": 1526, + "targetNodeId": 222, + "targetPortId": 1527, "travelTime": { - "lock": true, - "time": 7, + "lock": false, + "time": 4, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 14, + "time": 42, "warning": null, "timeFormatter": null, - "consecutiveTime": 14 + "consecutiveTime": 282 }, "sourceArrival": { "lock": false, - "time": 46, + "time": 18, "warning": null, "timeFormatter": null, - "consecutiveTime": 346 + "consecutiveTime": 258 }, "targetDeparture": { - "lock": false, - "time": 39, - "warning": null, + "lock": true, + "time": 14, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 339 + "consecutiveTime": 254 }, "targetArrival": { - "lock": false, - "time": 21, - "warning": null, + "lock": true, + "time": 46, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 21 + "consecutiveTime": 286 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": -1342}, - {"x": 112, "y": -1278}, - {"x": 112, "y": -994}, - {"x": 112, "y": -930} + {"x": 4062, "y": 64}, + {"x": 3998, "y": 64}, + {"x": 4130, "y": 56}, + {"x": 4066, "y": 56} ], "textPositions": { - "0": {"x": 100, "y": -1324}, - "1": {"x": 124, "y": -1296}, - "2": {"x": 124, "y": -948}, - "3": {"x": 100, "y": -976}, - "4": {"x": 100, "y": -1136}, - "5": {"x": 100, "y": -1136}, - "6": {"x": 124, "y": -1136} + "0": {"x": 4044, "y": 52}, + "1": {"x": 4016, "y": 76}, + "2": {"x": 4084, "y": 68}, + "3": {"x": 4112, "y": 44}, + "4": {"x": 4064, "y": 48}, + "5": {"x": 4064, "y": 48}, + "6": {"x": 4064, "y": 72} } }, "warnings": null }, { - "id": 700, - "sourceNodeId": 134, - "sourcePortId": 1416, - "targetNodeId": 146, - "targetPortId": 1415, + "id": 756, + "sourceNodeId": 222, + "sourcePortId": 1528, + "targetNodeId": 223, + "targetPortId": 1529, "travelTime": { - "lock": true, - "time": 8, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 6, + "lock": false, + "time": 48, "warning": null, "timeFormatter": null, - "consecutiveTime": 6 + "consecutiveTime": 288 }, "sourceArrival": { - "lock": true, - "time": 54, + "lock": false, + "time": 12, "warning": null, "timeFormatter": null, - "consecutiveTime": 354 + "consecutiveTime": 252 }, "targetDeparture": { - "lock": false, - "time": 46, - "warning": null, + "lock": true, + "time": 11, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 346 + "consecutiveTime": 251 }, "targetArrival": { - "lock": false, - "time": 14, - "warning": null, + "lock": true, + "time": 49, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 14 + "consecutiveTime": 289 }, "numberOfStops": 0, - "trainrunId": 85, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 112, "y": -1822}, - {"x": 112, "y": -1758}, - {"x": 112, "y": -1474}, - {"x": 112, "y": -1410} + {"x": 3966, "y": 56}, + {"x": 3902, "y": 56}, + {"x": 4082, "y": 52}, + {"x": 4018, "y": 52} ], "textPositions": { - "0": {"x": 100, "y": -1804}, - "1": {"x": 124, "y": -1776}, - "2": {"x": 124, "y": -1428}, - "3": {"x": 100, "y": -1456}, - "4": {"x": 100, "y": -1616}, - "5": {"x": 100, "y": -1616}, - "6": {"x": 124, "y": -1616} + "0": {"x": 3948, "y": 44}, + "1": {"x": 3920, "y": 68}, + "2": {"x": 4036, "y": 64}, + "3": {"x": 4064, "y": 40}, + "4": {"x": 3992, "y": 42}, + "5": {"x": 3992, "y": 42}, + "6": {"x": 3992, "y": 66} } }, "warnings": null }, { - "id": 701, - "sourceNodeId": 175, - "sourcePortId": 1417, - "targetNodeId": 130, - "targetPortId": 1418, + "id": 757, + "sourceNodeId": 223, + "sourcePortId": 1530, + "targetNodeId": 151, + "targetPortId": 1211, "travelTime": { - "lock": true, - "time": 13, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": true, - "time": 1, - "warning": null, + "lock": false, + "time": 51, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 421 + "consecutiveTime": 291 }, "sourceArrival": { - "lock": true, - "time": 59, - "warning": null, + "lock": false, + "time": 9, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 119 + "consecutiveTime": 249 }, "targetDeparture": { "lock": true, - "time": 46, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 106 + "consecutiveTime": 248 }, "targetArrival": { "lock": true, - "time": 14, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 434 + "consecutiveTime": 292 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 88, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, - "path": { - "path": [ - {"x": -1698, "y": -16}, - {"x": -1762, "y": -16}, - {"x": -2366, "y": -16}, - {"x": -2430, "y": -16} - ], - "textPositions": { - "0": {"x": -1716, "y": -28}, - "1": {"x": -1744, "y": -4}, - "2": {"x": -2412, "y": -4}, - "3": {"x": -2384, "y": -28}, - "4": {"x": -2064, "y": -28}, - "5": {"x": -2064, "y": -28}, - "6": {"x": -2064, "y": -4} + "path": { + "path": [ + {"x": 3918, "y": 52}, + {"x": 3854, "y": 52}, + {"x": 4034, "y": 112}, + {"x": 3970, "y": 112} + ], + "textPositions": { + "0": {"x": 3900, "y": 40}, + "1": {"x": 3872, "y": 64}, + "2": {"x": 3988, "y": 124}, + "3": {"x": 4016, "y": 100}, + "4": {"x": 3944, "y": 70}, + "5": {"x": 3944, "y": 70}, + "6": {"x": 3944, "y": 94} } }, "warnings": null }, { - "id": 702, - "sourceNodeId": 176, - "sourcePortId": 1420, - "targetNodeId": 137, - "targetPortId": 1419, + "id": 758, + "sourceNodeId": 224, + "sourcePortId": 1532, + "targetNodeId": 225, + "targetPortId": 1533, "travelTime": { - "lock": true, - "time": 16, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 39, + "lock": true, + "time": 27, "warning": null, "timeFormatter": null, - "consecutiveTime": 279 + "consecutiveTime": 147 }, "sourceArrival": { - "lock": false, - "time": 21, + "lock": true, + "time": 33, "warning": null, "timeFormatter": null, - "consecutiveTime": 261 + "consecutiveTime": 153 }, "targetDeparture": { "lock": true, - "time": 5, + "time": 22, "warning": null, "timeFormatter": null, - "consecutiveTime": 245 + "consecutiveTime": 142 }, "targetArrival": { "lock": true, - "time": 55, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 295 + "consecutiveTime": 158 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": 5374, "y": 112}, - {"x": 5310, "y": 112}, - {"x": 4802, "y": 112}, - {"x": 4738, "y": 112} + {"x": 4080, "y": -194}, + {"x": 4080, "y": -258}, + {"x": 4176, "y": -174}, + {"x": 4176, "y": -238} ], "textPositions": { - "0": {"x": 5356, "y": 100}, - "1": {"x": 5328, "y": 124}, - "2": {"x": 4756, "y": 124}, - "3": {"x": 4784, "y": 100}, - "4": {"x": 5056, "y": 100}, - "5": {"x": 5056, "y": 100}, - "6": {"x": 5056, "y": 124} + "0": {"x": 4092, "y": -212}, + "1": {"x": 4068, "y": -240}, + "2": {"x": 4164, "y": -220}, + "3": {"x": 4188, "y": -192}, + "4": {"x": 4140, "y": -216}, + "5": {"x": 4140, "y": -216}, + "6": {"x": 4116, "y": -216} } }, "warnings": null }, { - "id": 703, - "sourceNodeId": 177, - "sourcePortId": 1421, - "targetNodeId": 160, - "targetPortId": 1422, + "id": 759, + "sourceNodeId": 225, + "sourcePortId": 1534, + "targetNodeId": 139, + "targetPortId": 1250, "travelTime": { "lock": false, - "time": 30, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 31, + "time": 40, "warning": null, "timeFormatter": null, - "consecutiveTime": 451 + "consecutiveTime": 160 }, "sourceArrival": { "lock": true, - "time": 29, + "time": 20, "warning": null, "timeFormatter": null, - "consecutiveTime": 89 + "consecutiveTime": 140 }, "targetDeparture": { "lock": true, - "time": 59, + "time": 10, "warning": null, "timeFormatter": null, - "consecutiveTime": 59 + "consecutiveTime": 130 }, "targetArrival": { "lock": true, - "time": 1, + "time": 50, "warning": null, "timeFormatter": null, - "consecutiveTime": 481 + "consecutiveTime": 170 }, - "numberOfStops": 1, - "trainrunId": 81, + "numberOfStops": 0, + "trainrunId": 79, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3522, "y": 624}, - {"x": -3586, "y": 624}, - {"x": -3774, "y": 688}, - {"x": -3838, "y": 688} + {"x": 4176, "y": -306}, + {"x": 4176, "y": -370}, + {"x": 4272, "y": -286}, + {"x": 4272, "y": -350} ], "textPositions": { - "0": {"x": -3540, "y": 612}, - "1": {"x": -3568, "y": 636}, - "2": {"x": -3820, "y": 700}, - "3": {"x": -3792, "y": 676}, - "4": {"x": -3680, "y": 644}, - "5": {"x": -3680, "y": 644}, - "6": {"x": -3680, "y": 668} + "0": {"x": 4188, "y": -324}, + "1": {"x": 4164, "y": -352}, + "2": {"x": 4260, "y": -332}, + "3": {"x": 4284, "y": -304}, + "4": {"x": 4236, "y": -328}, + "5": {"x": 4236, "y": -328}, + "6": {"x": 4212, "y": -328} } }, "warnings": null }, { - "id": 704, - "sourceNodeId": 177, - "sourcePortId": 1423, - "targetNodeId": 160, - "targetPortId": 1424, + "id": 760, + "sourceNodeId": 226, + "sourcePortId": 1536, + "targetNodeId": 227, + "targetPortId": 1537, "travelTime": { - "lock": true, - "time": 26, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 52, + "lock": true, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 472 + "consecutiveTime": 173 }, "sourceArrival": { - "lock": false, - "time": 8, + "lock": true, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 68 + "consecutiveTime": 247 }, "targetDeparture": { "lock": true, - "time": 42, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 42 + "consecutiveTime": 233 }, "targetArrival": { "lock": true, - "time": 18, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 498 + "consecutiveTime": 187 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3522, "y": 560}, - {"x": -3586, "y": 560}, - {"x": -3774, "y": 624}, - {"x": -3838, "y": 624} + {"x": 3746, "y": 976}, + {"x": 3810, "y": 976}, + {"x": 4078, "y": 1088}, + {"x": 4142, "y": 1088} ], "textPositions": { - "0": {"x": -3540, "y": 548}, - "1": {"x": -3568, "y": 572}, - "2": {"x": -3820, "y": 636}, - "3": {"x": -3792, "y": 612}, - "4": {"x": -3680, "y": 580}, - "5": {"x": -3680, "y": 580}, - "6": {"x": -3680, "y": 604} + "0": {"x": 3764, "y": 988}, + "1": {"x": 3792, "y": 964}, + "2": {"x": 4124, "y": 1076}, + "3": {"x": 4096, "y": 1100}, + "4": {"x": 3944, "y": 1020}, + "5": {"x": 3944, "y": 1020}, + "6": {"x": 3944, "y": 1044} } }, "warnings": null }, { - "id": 705, - "sourceNodeId": 177, - "sourcePortId": 1425, - "targetNodeId": 160, - "targetPortId": 1426, + "id": 761, + "sourceNodeId": 227, + "sourcePortId": 1538, + "targetNodeId": 228, + "targetPortId": 1539, "travelTime": { "lock": false, - "time": 26, + "time": 6, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 19, + "lock": true, + "time": 9, "warning": null, "timeFormatter": null, - "consecutiveTime": 499 + "consecutiveTime": 189 }, "sourceArrival": { - "lock": false, - "time": 41, + "lock": true, + "time": 51, "warning": null, "timeFormatter": null, - "consecutiveTime": 41 + "consecutiveTime": 231 }, "targetDeparture": { "lock": true, - "time": 15, + "time": 45, "warning": null, "timeFormatter": null, - "consecutiveTime": 15 + "consecutiveTime": 225 }, "targetArrival": { "lock": true, - "time": 45, + "time": 15, "warning": null, "timeFormatter": null, - "consecutiveTime": 525 + "consecutiveTime": 195 }, "numberOfStops": 0, - "trainrunId": 87, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -3522, "y": 592}, - {"x": -3586, "y": 592}, - {"x": -3774, "y": 656}, - {"x": -3838, "y": 656} + {"x": 4242, "y": 1088}, + {"x": 4306, "y": 1088}, + {"x": 4326, "y": 1144}, + {"x": 4390, "y": 1144} ], "textPositions": { - "0": {"x": -3540, "y": 580}, - "1": {"x": -3568, "y": 604}, - "2": {"x": -3820, "y": 668}, - "3": {"x": -3792, "y": 644}, - "4": {"x": -3680, "y": 612}, - "5": {"x": -3680, "y": 612}, - "6": {"x": -3680, "y": 636} + "0": {"x": 4260, "y": 1100}, + "1": {"x": 4288, "y": 1076}, + "2": {"x": 4372, "y": 1132}, + "3": {"x": 4344, "y": 1156}, + "4": {"x": 4316, "y": 1104}, + "5": {"x": 4316, "y": 1104}, + "6": {"x": 4316, "y": 1128} } }, "warnings": null }, { - "id": 706, - "sourceNodeId": 129, - "sourcePortId": 1428, - "targetNodeId": 178, - "targetPortId": 1427, + "id": 762, + "sourceNodeId": 228, + "sourcePortId": 1540, + "targetNodeId": 229, + "targetPortId": 1541, "travelTime": { - "lock": true, - "time": 3, + "lock": false, + "time": 2, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 36, + "time": 17, "warning": null, "timeFormatter": null, - "consecutiveTime": 36 + "consecutiveTime": 197 }, "sourceArrival": { "lock": true, - "time": 24, + "time": 43, "warning": null, "timeFormatter": null, - "consecutiveTime": 384 + "consecutiveTime": 223 }, "targetDeparture": { - "lock": false, - "time": 21, + "lock": true, + "time": 41, "warning": null, "timeFormatter": null, - "consecutiveTime": 381 + "consecutiveTime": 221 }, "targetArrival": { - "lock": false, - "time": 39, + "lock": true, + "time": 19, "warning": null, "timeFormatter": null, - "consecutiveTime": 39 + "consecutiveTime": 199 }, "numberOfStops": 0, "trainrunId": 86, @@ -14549,409 +20001,439 @@ "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2014, "y": 336}, - {"x": -1950, "y": 336}, - {"x": -1762, "y": 336}, - {"x": -1698, "y": 336} + {"x": 4490, "y": 1144}, + {"x": 4554, "y": 1144}, + {"x": 4450, "y": 1172}, + {"x": 4514, "y": 1172} ], "textPositions": { - "0": {"x": -1996, "y": 348}, - "1": {"x": -1968, "y": 324}, - "2": {"x": -1716, "y": 324}, - "3": {"x": -1744, "y": 348}, - "4": {"x": -1856, "y": 324}, - "5": {"x": -1856, "y": 324}, - "6": {"x": -1856, "y": 348} + "0": {"x": 4508, "y": 1156}, + "1": {"x": 4536, "y": 1132}, + "2": {"x": 4496, "y": 1160}, + "3": {"x": 4468, "y": 1184}, + "4": {"x": 4502, "y": 1146}, + "5": {"x": 4502, "y": 1146}, + "6": {"x": 4502, "y": 1170} } }, "warnings": null }, { - "id": 707, - "sourceNodeId": 178, - "sourcePortId": 1429, - "targetNodeId": 129, - "targetPortId": 1430, + "id": 763, + "sourceNodeId": 229, + "sourcePortId": 1542, + "targetNodeId": 230, + "targetPortId": 1543, "travelTime": { - "lock": true, - "time": 4, + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 55, + "lock": true, + "time": 21, "warning": null, "timeFormatter": null, - "consecutiveTime": 355 + "consecutiveTime": 201 }, "sourceArrival": { - "lock": false, - "time": 5, + "lock": true, + "time": 39, "warning": { "title": "Avertissement d'arrivée à l'origine", "description": "L'heure d'arrivée à l'origine ne peut être atteinte" }, "timeFormatter": null, - "consecutiveTime": 185 + "consecutiveTime": 219 }, "targetDeparture": { "lock": true, - "time": 0, - "warning": null, + "time": 39, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 180 + "consecutiveTime": 219 }, "targetArrival": { "lock": true, - "time": 0, + "time": 22, "warning": { - "title": "Avertissement d'arrivée à destination", - "description": "L'heure d'arrivée à destination ne peut être atteinte" + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" }, "timeFormatter": null, - "consecutiveTime": 360 + "consecutiveTime": 202 }, "numberOfStops": 0, - "trainrunId": 81, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1698, "y": 304}, - {"x": -1762, "y": 304}, - {"x": -1950, "y": 304}, - {"x": -2014, "y": 304} + {"x": 4614, "y": 1172}, + {"x": 4678, "y": 1172}, + {"x": 4512, "y": 1186}, + {"x": 4576, "y": 1186} ], "textPositions": { - "0": {"x": -1716, "y": 292}, - "1": {"x": -1744, "y": 316}, - "2": {"x": -1996, "y": 316}, - "3": {"x": -1968, "y": 292}, - "4": {"x": -1856, "y": 292}, - "5": {"x": -1856, "y": 292}, - "6": {"x": -1856, "y": 316} + "0": {"x": 4632, "y": 1184}, + "1": {"x": 4660, "y": 1160}, + "2": {"x": 4558, "y": 1174}, + "3": {"x": 4530, "y": 1198}, + "4": {"x": 4595, "y": 1167}, + "5": {"x": 4595, "y": 1167}, + "6": {"x": 4595, "y": 1191} } }, "warnings": null }, { - "id": 708, - "sourceNodeId": 129, - "sourcePortId": 1432, - "targetNodeId": 178, - "targetPortId": 1431, - "travelTime": { - "lock": true, - "time": 3, + "id": 764, + "sourceNodeId": 230, + "sourcePortId": 1544, + "targetNodeId": 140, + "targetPortId": 1364, + "travelTime": { + "lock": false, + "time": 1, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 2, - "warning": null, + "lock": true, + "time": 22, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 62 + "consecutiveTime": 202 }, "sourceArrival": { - "lock": false, - "time": 58, - "warning": null, + "lock": true, + "time": 39, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 358 + "consecutiveTime": 219 }, "targetDeparture": { - "lock": false, - "time": 55, + "lock": true, + "time": 38, "warning": null, "timeFormatter": null, - "consecutiveTime": 355 + "consecutiveTime": 218 }, "targetArrival": { - "lock": false, - "time": 5, - "warning": null, + "lock": true, + "time": 22, + "warning": { + "title": "Avertissement d'arrivée à destination", + "description": "L'heure d'arrivée à destination ne peut être atteinte" + }, "timeFormatter": null, - "consecutiveTime": 65 + "consecutiveTime": 202 }, "numberOfStops": 0, - "trainrunId": 90, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2014, "y": 272}, - {"x": -1950, "y": 272}, - {"x": -1762, "y": 272}, - {"x": -1698, "y": 272} + {"x": 4676, "y": 1186}, + {"x": 4740, "y": 1186}, + {"x": 4574, "y": 1232}, + {"x": 4638, "y": 1232} ], "textPositions": { - "0": {"x": -1996, "y": 284}, - "1": {"x": -1968, "y": 260}, - "2": {"x": -1716, "y": 260}, - "3": {"x": -1744, "y": 284}, - "4": {"x": -1856, "y": 260}, - "5": {"x": -1856, "y": 260}, - "6": {"x": -1856, "y": 284} + "0": {"x": 4694, "y": 1198}, + "1": {"x": 4722, "y": 1174}, + "2": {"x": 4620, "y": 1220}, + "3": {"x": 4592, "y": 1244}, + "4": {"x": 4657, "y": 1197}, + "5": {"x": 4657, "y": 1197}, + "6": {"x": 4657, "y": 1221} } }, "warnings": null }, { - "id": 709, - "sourceNodeId": 129, - "sourcePortId": 1434, - "targetNodeId": 178, - "targetPortId": 1433, + "id": 765, + "sourceNodeId": 231, + "sourcePortId": 1546, + "targetNodeId": 232, + "targetPortId": 1547, "travelTime": { - "lock": true, - "time": 3, + "lock": false, + "time": 11, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": true, - "time": 3, + "time": 53, "warning": null, "timeFormatter": null, - "consecutiveTime": 63 + "consecutiveTime": 413 }, "sourceArrival": { "lock": true, - "time": 57, + "time": 7, "warning": null, "timeFormatter": null, - "consecutiveTime": 357 + "consecutiveTime": 127 }, "targetDeparture": { - "lock": false, - "time": 54, - "warning": null, + "lock": true, + "time": 56, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 354 + "consecutiveTime": 116 }, "targetArrival": { - "lock": false, - "time": 6, - "warning": null, + "lock": true, + "time": 4, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 66 + "consecutiveTime": 424 }, "numberOfStops": 0, - "trainrunId": 89, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -2014, "y": 240}, - {"x": -1950, "y": 240}, - {"x": -1762, "y": 240}, - {"x": -1698, "y": 240} + {"x": -2818, "y": 432}, + {"x": -2882, "y": 432}, + {"x": -2782, "y": 496}, + {"x": -2846, "y": 496} ], "textPositions": { - "0": {"x": -1996, "y": 252}, - "1": {"x": -1968, "y": 228}, - "2": {"x": -1716, "y": 228}, - "3": {"x": -1744, "y": 252}, - "4": {"x": -1856, "y": 228}, - "5": {"x": -1856, "y": 228}, - "6": {"x": -1856, "y": 252} + "0": {"x": -2836, "y": 420}, + "1": {"x": -2864, "y": 444}, + "2": {"x": -2828, "y": 508}, + "3": {"x": -2800, "y": 484}, + "4": {"x": -2832, "y": 452}, + "5": {"x": -2832, "y": 452}, + "6": {"x": -2832, "y": 476} } }, "warnings": null }, { - "id": 710, - "sourceNodeId": 178, - "sourcePortId": 1435, - "targetNodeId": 129, - "targetPortId": 1436, + "id": 766, + "sourceNodeId": 232, + "sourcePortId": 1548, + "targetNodeId": 128, + "targetPortId": 1380, "travelTime": { - "lock": true, - "time": 3, + "lock": false, + "time": 10, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 23, - "warning": null, + "lock": true, + "time": 6, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 426 }, "sourceArrival": { - "lock": false, - "time": 37, - "warning": null, + "lock": true, + "time": 54, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 217 + "consecutiveTime": 114 }, "targetDeparture": { "lock": true, - "time": 34, + "time": 44, "warning": null, "timeFormatter": null, - "consecutiveTime": 214 + "consecutiveTime": 104 }, "targetArrival": { "lock": true, - "time": 26, + "time": 16, "warning": null, "timeFormatter": null, - "consecutiveTime": 86 + "consecutiveTime": 436 }, "numberOfStops": 0, - "trainrunId": 95, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1698, "y": 208}, - {"x": -1762, "y": 208}, - {"x": -1950, "y": 208}, - {"x": -2014, "y": 208} + {"x": -2946, "y": 496}, + {"x": -3010, "y": 496}, + {"x": -2910, "y": 592}, + {"x": -2974, "y": 592} ], "textPositions": { - "0": {"x": -1716, "y": 196}, - "1": {"x": -1744, "y": 220}, - "2": {"x": -1996, "y": 220}, - "3": {"x": -1968, "y": 196}, - "4": {"x": -1856, "y": 196}, - "5": {"x": -1856, "y": 196}, - "6": {"x": -1856, "y": 220} + "0": {"x": -2964, "y": 484}, + "1": {"x": -2992, "y": 508}, + "2": {"x": -2956, "y": 604}, + "3": {"x": -2928, "y": 580}, + "4": {"x": -2960, "y": 532}, + "5": {"x": -2960, "y": 532}, + "6": {"x": -2960, "y": 556} } }, "warnings": null }, { - "id": 711, - "sourceNodeId": 178, - "sourcePortId": 1437, - "targetNodeId": 172, - "targetPortId": 1438, + "id": 767, + "sourceNodeId": 233, + "sourcePortId": 1550, + "targetNodeId": 174, + "targetPortId": 1399, "travelTime": { "lock": true, - "time": 17, + "time": 7, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { "lock": false, - "time": 37, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 217 + "consecutiveTime": 61 }, "sourceArrival": { "lock": false, - "time": 23, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 83 + "consecutiveTime": 359 }, "targetDeparture": { - "lock": false, - "time": 6, + "lock": true, + "time": 52, "warning": null, "timeFormatter": null, - "consecutiveTime": 66 + "consecutiveTime": 352 }, "targetArrival": { - "lock": false, - "time": 54, + "lock": true, + "time": 8, "warning": null, "timeFormatter": null, - "consecutiveTime": 234 + "consecutiveTime": 68 }, "numberOfStops": 0, - "trainrunId": 96, + "trainrunId": 86, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1598, "y": 176}, - {"x": -1534, "y": 176}, - {"x": -674, "y": 176}, - {"x": -610, "y": 176} + {"x": -1070, "y": 368}, + {"x": -1006, "y": 368}, + {"x": -1058, "y": 368}, + {"x": -994, "y": 368} ], "textPositions": { - "0": {"x": -1580, "y": 188}, - "1": {"x": -1552, "y": 164}, - "2": {"x": -628, "y": 164}, - "3": {"x": -656, "y": 188}, - "4": {"x": -1104, "y": 164}, - "5": {"x": -1104, "y": 164}, - "6": {"x": -1104, "y": 188} + "0": {"x": -1052, "y": 380}, + "1": {"x": -1024, "y": 356}, + "2": {"x": -1012, "y": 356}, + "3": {"x": -1040, "y": 380}, + "4": {"x": -1032, "y": 356}, + "5": {"x": -1032, "y": 356}, + "6": {"x": -1032, "y": 380} } }, "warnings": null }, { - "id": 712, - "sourceNodeId": 178, - "sourcePortId": 1439, - "targetNodeId": 129, - "targetPortId": 1440, + "id": 768, + "sourceNodeId": 234, + "sourcePortId": 1552, + "targetNodeId": 160, + "targetPortId": 1422, "travelTime": { - "lock": true, - "time": 3, + "lock": false, + "time": 14, "warning": null, "timeFormatter": null, "consecutiveTime": 1 }, "sourceDeparture": { - "lock": false, - "time": 26, - "warning": null, + "lock": true, + "time": 47, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 386 + "consecutiveTime": 467 }, "sourceArrival": { - "lock": false, - "time": 34, - "warning": null, + "lock": true, + "time": 13, + "warning": { + "title": "Remplacement des arrêts intermédiaires", + "description": "Le remplacement des arrêts intermédiaires a entraîné des incohérences dans l'attribution des temps !" + }, "timeFormatter": null, - "consecutiveTime": 154 + "consecutiveTime": 73 }, "targetDeparture": { - "lock": false, - "time": 31, + "lock": true, + "time": 59, "warning": null, "timeFormatter": null, - "consecutiveTime": 151 + "consecutiveTime": 59 }, "targetArrival": { - "lock": false, - "time": 29, + "lock": true, + "time": 1, "warning": null, "timeFormatter": null, - "consecutiveTime": 389 + "consecutiveTime": 481 }, "numberOfStops": 0, - "trainrunId": 88, + "trainrunId": 81, "resourceId": 0, "specificTrainrunSectionFrequencyId": null, "path": { "path": [ - {"x": -1698, "y": 144}, - {"x": -1762, "y": 144}, - {"x": -1950, "y": 144}, - {"x": -2014, "y": 144} + {"x": -3730, "y": 592}, + {"x": -3794, "y": 592}, + {"x": -3774, "y": 688}, + {"x": -3838, "y": 688} ], "textPositions": { - "0": {"x": -1716, "y": 132}, - "1": {"x": -1744, "y": 156}, - "2": {"x": -1996, "y": 156}, - "3": {"x": -1968, "y": 132}, - "4": {"x": -1856, "y": 132}, - "5": {"x": -1856, "y": 132}, - "6": {"x": -1856, "y": 156} + "0": {"x": -3748, "y": 580}, + "1": {"x": -3776, "y": 604}, + "2": {"x": -3820, "y": 700}, + "3": {"x": -3792, "y": 676}, + "4": {"x": -3784, "y": 628}, + "5": {"x": -3784, "y": 628}, + "6": {"x": -3784, "y": 652} } }, "warnings": null @@ -15217,7 +20699,63 @@ {"id": 199, "capacity": 2}, {"id": 200, "capacity": 2}, {"id": 201, "capacity": 2}, - {"id": 202, "capacity": 2} + {"id": 202, "capacity": 2}, + {"id": 203, "capacity": 2}, + {"id": 204, "capacity": 2}, + {"id": 205, "capacity": 2}, + {"id": 206, "capacity": 2}, + {"id": 207, "capacity": 2}, + {"id": 208, "capacity": 2}, + {"id": 209, "capacity": 2}, + {"id": 210, "capacity": 2}, + {"id": 211, "capacity": 2}, + {"id": 212, "capacity": 2}, + {"id": 213, "capacity": 2}, + {"id": 214, "capacity": 2}, + {"id": 215, "capacity": 2}, + {"id": 216, "capacity": 2}, + {"id": 217, "capacity": 2}, + {"id": 218, "capacity": 2}, + {"id": 219, "capacity": 2}, + {"id": 220, "capacity": 2}, + {"id": 221, "capacity": 2}, + {"id": 222, "capacity": 2}, + {"id": 223, "capacity": 2}, + {"id": 224, "capacity": 2}, + {"id": 225, "capacity": 2}, + {"id": 226, "capacity": 2}, + {"id": 227, "capacity": 2}, + {"id": 228, "capacity": 2}, + {"id": 229, "capacity": 2}, + {"id": 230, "capacity": 2}, + {"id": 231, "capacity": 2}, + {"id": 232, "capacity": 2}, + {"id": 233, "capacity": 2}, + {"id": 234, "capacity": 2}, + {"id": 235, "capacity": 2}, + {"id": 236, "capacity": 2}, + {"id": 237, "capacity": 2}, + {"id": 238, "capacity": 2}, + {"id": 239, "capacity": 2}, + {"id": 240, "capacity": 2}, + {"id": 241, "capacity": 2}, + {"id": 242, "capacity": 2}, + {"id": 243, "capacity": 2}, + {"id": 244, "capacity": 2}, + {"id": 245, "capacity": 2}, + {"id": 246, "capacity": 2}, + {"id": 247, "capacity": 2}, + {"id": 248, "capacity": 2}, + {"id": 249, "capacity": 2}, + {"id": 250, "capacity": 2}, + {"id": 251, "capacity": 2}, + {"id": 252, "capacity": 2}, + {"id": 253, "capacity": 2}, + {"id": 254, "capacity": 2}, + {"id": 255, "capacity": 2}, + {"id": 256, "capacity": 2}, + {"id": 257, "capacity": 2}, + {"id": 258, "capacity": 2} ], "metadata": { "analyticsSettings": {"originDestinationSettings": {"connectionPenalty": 5}}, diff --git a/src/app/view/editor-main-view/data-views/data.view.spec.ts b/src/app/view/editor-main-view/data-views/data.view.spec.ts index 4d3579884..dea28aac0 100644 --- a/src/app/view/editor-main-view/data-views/data.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/data.view.spec.ts @@ -217,7 +217,7 @@ describe("Editor-DataView", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(3); const cvo1 = new TrainrunSectionViewObject( editorView, - ts, + [ts], false, false, false, @@ -228,7 +228,7 @@ describe("Editor-DataView", () => { false, ); expect(cvo1.key).toBe( - "#3@1234_false_0_39_49_1_21_39_0_39_141_39_0_39_0_20_0_S_20_7/24_4_1_0_S_20_7/24_20_0_round_trip_false_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_true_0_false_2_true_true_true_1_false_true_true_0_false_true_true(130,80)(194,80)(254,80)(318,80)", + "#3@1234_false_0_39_49_1_21_39_0_0_141_39_0_180_0_S_20_7/24_4_1_0_S_20_7/24_20_0_round_trip_false_false_false_false_false_false_false_false_false_true_true_true_false_false_true_true_true_0_false_2_true_true_true_1_false_true_true_0_false_true_true(130,80)(194,80)(254,80)(318,80)", ); }); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts index b55dc3409..4bade13de 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts @@ -26,6 +26,7 @@ import {Vec2D} from "../../../utils/vec2D"; import {LevelOfDetailService} from "../../../services/ui/level.of.detail.service"; import {ViewportCullService} from "../../../services/ui/viewport.cull.service"; import {PositionTransformationService} from "../../../services/util/position.transformation.service"; +import {TrainrunSectionViewObject} from "./trainrunSectionViewObject"; describe("TrainrunSection-View", () => { let dataService: DataService; @@ -321,7 +322,19 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getPosition - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const v = TrainrunSectionsView.getPosition(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v = TrainrunSectionsView.getPosition(viewObject, false); expect(v.getX()).toBe(734); expect(v.getY()).toBe(144); }); @@ -329,7 +342,19 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getPosition - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const v = TrainrunSectionsView.getPosition(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v = TrainrunSectionsView.getPosition(viewObject, true); expect(v.getX()).toBe(418); expect(v.getY()).toBe(112); }); @@ -964,42 +989,114 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(false); }); it("TrainrunSectionsView.enforceStartTextAnchor - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); it("TrainrunSectionsView.enforceStartTextAnchor - 003", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(false); }); it("TrainrunSectionsView.enforceStartTextAnchor - 004", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); it("TrainrunSectionsView.enforceStartTextAnchor - 005", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(6); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(false); }); it("TrainrunSectionsView.enforceStartTextAnchor - 006", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(6); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(true); }); @@ -1007,7 +1104,19 @@ describe("TrainrunSection-View", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(7); ts.getPath()[1].setY(-1); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); @@ -1016,21 +1125,57 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(7); ts.getPath()[3].setX(ts.getPath()[2].getX()); ts.getPath()[3].setY(ts.getPath()[2].getY() + 1000); - const v1 = TrainrunSectionsView.enforceStartTextAnchor(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(true); }); it("TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, true); expect(v1).toBe("translate(498,80) rotate(0)"); }); it("TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, false); expect(v1).toBe("translate(654,112) rotate(0)"); }); @@ -1039,7 +1184,19 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(6); ts.getPath()[3].setX(ts.getPath()[2].getX()); ts.getPath()[3].setY(ts.getPath()[2].getY() + 1000); - const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(ts, false); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, false); expect(v1).toBe("translate(898,96) rotate(-90)"); }); @@ -1048,7 +1205,19 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(6); ts.getPath()[1].setX(ts.getPath()[0].getX()); ts.getPath()[1].setY(ts.getPath()[0].getY()); - const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(ts, true); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, true); expect(v1).toBe("translate(1054,272) rotate(-90)"); }); @@ -1389,50 +1558,64 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getTrainrunSectionValueToShow - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); + const trainrunSection = trainrunSectionService.getTrainrunSectionFromId(0); + const viewObject = new TrainrunSectionViewObject( + editorView, + [trainrunSection], + false, + false, + false, + false, + false, + false, + false, + false, + ); + const v0 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.TrainrunSectionNumberOfStops, editorView, ); expect(v0).toBe(undefined); const v1 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.TrainrunSectionName, editorView, ); expect(v1).toBe("IC1"); const v2 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.TargetDeparture, editorView, ); expect(v2).toBe(50); const v3 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.TargetArrival, editorView, ); expect(v3).toBe(10); const v4 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.SourceDeparture, editorView, ); expect(v4).toBe(0); const v5 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.SourceArrival, editorView, ); expect(v5).toBe(0); const v6 = TrainrunSectionsView.getTrainrunSectionValueToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, TrainrunSectionText.TrainrunSectionTravelTime, editorView, ); @@ -1523,14 +1706,27 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); + const ts = trainrunSectionService.getTrainrunSectionFromId(0); + const viewObject = new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); const v0 = TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, editorView, false, ); expect(v0).toBe("BN"); const v1 = TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow( - trainrunSectionService.getTrainrunSectionFromId(0), + viewObject, editorView, true, ); From edf788c5d62721d616896cd25919f438cb559334 Mon Sep 17 00:00:00 2001 From: Math_R_ Date: Thu, 27 Nov 2025 15:21:16 +0100 Subject: [PATCH 41/54] format --- src/app/services/data/trainrun.service.ts | 2 +- src/app/view/editor-main-view/data-views/d3.utils.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/app/services/data/trainrun.service.ts b/src/app/services/data/trainrun.service.ts index a8e2f0b15..1c288bd1a 100644 --- a/src/app/services/data/trainrun.service.ts +++ b/src/app/services/data/trainrun.service.ts @@ -806,7 +806,7 @@ export class TrainrunService { public getBackwardNonStopIterator(node: Node, trainrunSection: TrainrunSection) { return new BackwardNonStopTrainrunIterator(this.logService, node, trainrunSection); } - + public getExpandedIterator(node: Node, trainrunSection: TrainrunSection) { return new ExpandedTrainrunIterator(this.logService, node, trainrunSection); } diff --git a/src/app/view/editor-main-view/data-views/d3.utils.ts b/src/app/view/editor-main-view/data-views/d3.utils.ts index 14432fcda..5e3329b31 100644 --- a/src/app/view/editor-main-view/data-views/d3.utils.ts +++ b/src/app/view/editor-main-view/data-views/d3.utils.ts @@ -90,20 +90,23 @@ export class D3Utils { d3.selectAll(StaticDomTags.EDGE_LINE_ARROW_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && + d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); d3.selectAll(StaticDomTags.EDGE_LINE_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && + d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); d3.selectAll(StaticDomTags.EDGE_ROOT_CONTAINER_DOM_REF) .filter( (d: TrainrunSectionViewObject) => - d !== undefined && d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), + d !== undefined && + d.trainrunSections[0].getTrainrunId() === trainrunSection.getTrainrunId(), ) .classed(StaticDomTags.TAG_HOVER, false); From 967ad99a4d42a829f94658fdd6add4af984027ba Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 10:33:59 +0100 Subject: [PATCH 42/54] fixup! fixup! drop updateTrainrunSectionPathForCollapsedChain() Signed-off-by: Simon Ser --- .../view/editor-main-view/data-views/trainrunsections.view.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 7c40e4a79..f35fbbb52 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1655,8 +1655,8 @@ export class TrainrunSectionsView { TrainrunSectionsView.isMuted(d.trainrunSections[0], selectedTrainrun, connectedTrainIds), ) .classed(StaticDomTags.TAG_WARNING, (d: TrainrunSectionViewObject) => { - const trainrunSections = d.trainrunSections.at(atSource ? 0 : -1); - return TrainrunSectionsView.hasWarning(d.trainrunSections[0], textElement); + const trainrunSection = d.trainrunSections.at(atSource ? 0 : -1); + return TrainrunSectionsView.hasWarning(trainrunSection, textElement); }) .classed(StaticDomTags.TAG_EVENT_DISABLED, true) .classed(StaticDomTags.TAG_START_TEXT_ANCHOR, (d: TrainrunSectionViewObject) => From 5422f1abc62fa9e0a0ef16e832878af79a8f3a95 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 10:39:40 +0100 Subject: [PATCH 43/54] fixup! fixup! drop updateTrainrunSectionPathForCollapsedChain() Signed-off-by: Simon Ser --- .../view/editor-main-view/data-views/trainrunsections.view.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index f35fbbb52..1b2c75767 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1559,7 +1559,7 @@ export class TrainrunSectionsView { }) .classed(StaticDomTags.TAG_HIDDEN, (d: TrainrunSectionViewObject) => { const trainrunSection = d.trainrunSections.at(atTarget ? -1 : 0)!; - return this.getHiddenTagForTime(d.trainrunSections[0], textElement); + return this.getHiddenTagForTime(trainrunSection, textElement); }) .classed(StaticDomTags.TAG_EVENT_DISABLED, !enableEvents) .text((d: TrainrunSectionViewObject) => From 6ac86fd08178ecebd060108e915c3e84b9bf460e Mon Sep 17 00:00:00 2001 From: Alexis Jacomy Date: Thu, 6 Nov 2025 14:14:52 +0100 Subject: [PATCH 44/54] front: adds global nodes management panel This commit addresses issue: https://github.com/OpenRailAssociation/osrd/issues/13292 Details: - Adds new component GlobalNodesManagementComponent in app/view/editor-edit-tools-view-component - The new component controls the isCollapsed state of the nodes - Adds EN and FR translations for the new component - Adds the new component to the existing EditorEditToolsViewComponent panel --- src/app/app.module.ts | 2 + .../editor-edit-tools-view.component.html | 7 ++ .../global-nodes-management.component.html | 56 +++++++++ .../global-nodes-management.component.scss | 60 ++++++++++ .../global-nodes-management.component.ts | 106 ++++++++++++++++++ src/assets/i18n/en.json | 10 +- src/assets/i18n/fr.json | 10 +- 7 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.html create mode 100644 src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.scss create mode 100644 src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index aae6d957c..c1f4c46aa 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -107,6 +107,7 @@ import {I18nModule} from "./core/i18n/i18n.module"; import {OriginDestinationComponent} from "./services/analytics/origin-destination/components/origin-destination.component"; import {SbbToggleModule} from "@sbb-esta/angular/toggle"; import {ToggleSwitchButtonComponent} from "./view/toggle-switch-button/toggle-switch-button.component"; +import {GlobalNodesManagementComponent} from "./view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component"; @NgModule({ declarations: [ @@ -152,6 +153,7 @@ import {ToggleSwitchButtonComponent} from "./view/toggle-switch-button/toggle-sw NavigationBarComponent, EditorPropertiesViewComponent, EditorEditToolsViewComponent, + GlobalNodesManagementComponent, FilterableLabelDialogComponent, FilterableLabelFormComponent, NoteDialogComponent, diff --git a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html index b69a0ab74..2eff04cda 100644 --- a/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html +++ b/src/app/view/editor-edit-tools-view-component/editor-edit-tools-view.component.html @@ -29,6 +29,13 @@

{{ "app.view.editor-edit-tools-view-component.edit" | t + + {{ + "app.view.editor-edit-tools-view-component.nodes" | translate + }} + + + + +
+ @if (matchingNodes.length) { + + + + @for (column of ["nodes-expanded", "nodes"]; track column) { + + } + + @if (matchingNodes.length > 1) { + + + + } + + + @for (node of matchingNodes; track node.getId()) { + + + + + + } + +
+ {{ "app.view.editor-edit-tools-view-component." + column | translate }} +
+ +
+ + {{ node.getBetriebspunktName() }}{{ node.getFullName() }}
+ } @else { +

{{ "app.view.editor-edit-tools-view-component.nodes-no-result" | translate }}

+ } +
+ diff --git a/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.scss b/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.scss new file mode 100644 index 000000000..202cd1940 --- /dev/null +++ b/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.scss @@ -0,0 +1,60 @@ +.global-nodes-management { + width: 100%; + display: flex; + flex-direction: column; + gap: 0.5rem; + align-items: stretch; + + .search { + position: relative; + + input { + width: 100%; + } + .sbb-icon { + position: absolute; + right: 5px; + top: 50%; + transform: translateY(-50%); + } + } + + .nodes-list { + overflow-x: auto; + + table { + width: 100%; + border-collapse: collapse; + + th, + td { + font-family: var(--sbb-font-light); + font-weight: var(--sbb-font-weight-normal); + padding: 8px 0; + white-space: nowrap; + vertical-align: middle; + } + + th { + text-align: start; + } + tbody tr { + border-top: var(--sbb-border-width-thin) solid var(--sbb-expansion-panel-border-color-open); + } + td.offset { + padding-left: 10px; + } + tbody td:last-child { + width: 99%; + } + thead th:not(:last-child), + tbody td:not(:last-child) { + padding-right: 13px; + } + + .sbb-checkbox { + display: block; + } + } + } +} diff --git a/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.ts b/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.ts new file mode 100644 index 000000000..72e01f8b2 --- /dev/null +++ b/src/app/view/editor-edit-tools-view-component/global-nodes-management/global-nodes-management.component.ts @@ -0,0 +1,106 @@ +import {Component} from "@angular/core"; + +import {NodeService} from "../../../services/data/node.service"; +import {Node} from "../../../models/node.model"; +import {DataService} from "../../../services/data/data.service"; +import {UiInteractionService} from "../../../services/ui/ui.interaction.service"; +import {ConfirmationDialogParameter} from "../../dialogs/confirmation-dialog/confirmation-dialog.component"; + +function normalizeStr(str: string): string { + return str + .toLowerCase() + .trim() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, ""); +} + +@Component({ + selector: "sbb-global-nodes-management", + templateUrl: "./global-nodes-management.component.html", + styleUrl: "./global-nodes-management.component.scss", +}) +export class GlobalNodesManagementComponent { + query: string; + allNodes: Node[]; + matchingNodes: Node[]; + + constructor( + private dataService: DataService, + private nodeService: NodeService, + private uiInteractionService: UiInteractionService, + ) { + this.query = ""; + this.allNodes = this.nodeService.getNodes(); + this.nodeService.nodes.subscribe((nodes) => this.updateState({nodes})); + } + + updateState({nodes = this.allNodes, query = this.query}: {nodes?: Node[]; query?: string}) { + // Save state locally + this.query = query; + this.allNodes = nodes; + + const normalizedQuery = normalizeStr(this.query); + + this.matchingNodes = normalizedQuery + ? this.allNodes.filter( + (node) => + normalizeStr(node.getFullName()).includes(normalizedQuery) || + normalizeStr(node.getBetriebspunktName()).includes(normalizedQuery), + ) + : this.allNodes; + } + + getGlobalCheckboxStatus(): boolean | undefined { + let allCollapsed = true; + let noneCollapsed = true; + this.matchingNodes.every((node) => { + const isCollapsed = node.getIsCollapsed(); + allCollapsed = allCollapsed && isCollapsed; + noneCollapsed = noneCollapsed && !isCollapsed; + + // If both allCollapsed and noneCollapsed fail, stop iterating + return allCollapsed || noneCollapsed; + }); + + if (allCollapsed) return false; + if (noneCollapsed) return true; + return undefined; + } + + toggleIsCollapsed(node: Node, isCollapsed: boolean) { + node.setIsCollapsed(isCollapsed); + this.dataService.triggerViewUpdate(); + } + onClickGlobalCheckbox(event: MouseEvent) { + event.preventDefault(); + event.stopPropagation(); + + const currentGlobalCheckboxStatus = this.getGlobalCheckboxStatus(); + const newCheckboxStatus = !currentGlobalCheckboxStatus; + const newIsCollapsed = !newCheckboxStatus; + + const allNodesImpacted = this.allNodes.length === this.matchingNodes.length; + const impactedNodesCount = this.matchingNodes.length; + + const dialogTitle = $localize`:@@app.view.editor-edit-tools-view-component.global-nodes-management:Global nodes management`; + const dialogContent = newIsCollapsed + ? allNodesImpacted + ? $localize`:@@app.view.editor-edit-tools-view-component.confirm-collapse-all:Are you sure you want to collapse all nodes?` + : $localize`:@@app.view.editor-edit-tools-view-component.confirm-collapse-matching:Are you sure you want to collapse the ${impactedNodesCount}:count: nodes matching "${this.query}:query:"?` + : allNodesImpacted + ? $localize`:@@app.view.editor-edit-tools-view-component.confirm-expand-all:Are you sure you want to expand all nodes?` + : $localize`:@@app.view.editor-edit-tools-view-component.confirm-expand-matching:Are you sure you want to expand the ${impactedNodesCount}:count: nodes matching "${this.query}:query:"?`; + const confirmationDialogParameter = new ConfirmationDialogParameter(dialogTitle, dialogContent); + + this.uiInteractionService + .showConfirmationDiagramDialog(confirmationDialogParameter) + .subscribe((confirmed: boolean) => { + if (confirmed) { + this.matchingNodes.forEach((node) => { + node.setIsCollapsed(newIsCollapsed); + }); + this.dataService.triggerViewUpdate(); + } + }); + } +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 12223bbc5..63fd0221b 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -337,7 +337,15 @@ "trainruns": "Trainruns", "notes": "Notes", "nodes": "Nodes" - } + }, + "nodes-search-placeholder": "Search for names or short names", + "nodes-expanded": "Expanded", + "nodes-no-result": "There is no node matching the query.", + "global-nodes-management": "Global nodes management", + "confirm-expand-all": "Are you sure you want to expand all nodes?", + "confirm-expand-matching": "Are you sure you want to expand the {$count} nodes matching \"{$query}\"?", + "confirm-collapse-all": "Are you sure you want to collapse all nodes?", + "confirm-collapse-matching": "Are you sure you want to collapse the {$count} nodes matching \"{$query}\"?" }, "editor-filter-view": { "filter": "Filter", diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index b6d1979be..4b5fb98fb 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -336,7 +336,15 @@ "trainruns": "Trajets de train", "notes": "Notes", "nodes": "Noeuds" - } + }, + "nodes-search-placeholder": "Rechercher par nom ou trigramme", + "nodes-expanded": "Développés", + "nodes-no-result": "Aucun noeud ne correspond à cette recherche.", + "global-nodes-management": "Gestion globale des noeuds", + "confirm-expand-all": "Êtes-vous sûr(e) de vouloir développer tous les noeuds ?", + "confirm-expand-matching": "Êtes-vous sûr(e) de vouloir développer les {$count} noeuds qui contiennent «{$query}» ?", + "confirm-collapse-all": "Êtes-vous sûr(e) de vouloir réduire tous les noeuds ?", + "confirm-collapse-matching": "Êtes-vous sûr(e) de vouloir réduire les {$count} noeuds qui contiennent «{$query}» ?" }, "editor-filter-view": { "filter": "Filtres", From 1d8f18076e1fbafd1921de5cee1291309844747a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 11:25:46 +0100 Subject: [PATCH 45/54] Drop PATH_COMPARISON_TOLERANCE This is unused. Signed-off-by: Simon Ser --- .../view/editor-main-view/data-views/trainrunsections.view.ts | 1 - src/app/view/rastering/definitions.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 1b2c75767..df7e062cf 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -8,7 +8,6 @@ import { MIN_PATH_LENGTH_FOR_ANGLE, NODE_EDGE_WIDTH, NODE_TEXT_AREA_HEIGHT, - PATH_COMPARISON_TOLERANCE, RASTERING_BASIC_GRID_SIZE, SHOW_MAX_SINGLE_TRAINRUN_SECTIONS_STOPS, TRAINRUN_SECTION_TEXT_AREA_HEIGHT, diff --git a/src/app/view/rastering/definitions.ts b/src/app/view/rastering/definitions.ts index efa6cf472..08f5bb824 100644 --- a/src/app/view/rastering/definitions.ts +++ b/src/app/view/rastering/definitions.ts @@ -68,4 +68,3 @@ export const ANGLE_UPSIDE_DOWN_THRESHOLD = 90; export const EDGE_CASE_THRESHOLD = 1; export const DEFAULT_ANGLE_VERTICAL = -90; export const DEFAULT_ANGLE_HORIZONTAL = 0; -export const PATH_COMPARISON_TOLERANCE = 0.01; From 7559de5db75bd2e42d5f0df2473a6af701aaa979 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 10:33:43 +0100 Subject: [PATCH 46/54] Pass view object in TrainrunSectionsView.createIntermediateStops() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index df7e062cf..126f01b7a 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1715,12 +1715,12 @@ export class TrainrunSectionsView { createIntermediateStops( groupEnter: d3.Selector, - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, selectedTrainrun: Trainrun, connectedTrainIds: any, ) { - const numberOfStops = trainrunSection.getNumberOfStops(); - const path = trainrunSection.getPath(); + const numberOfStops = viewObject.trainrunSections.length - 1; + const path = viewObject.getPath(); let startPosition = path[1]; let lineOrientationVector = Vec2D.sub(path[2], startPosition); const maxNumberOfStops = Math.min( @@ -1767,7 +1767,7 @@ export class TrainrunSectionsView { ); this.createNumberOfStopsTextElement( groupEnter, - trainrunSection, + viewObject.trainrunSections[0], selectedTrainrun, connectedTrainIds, numberOfStops, @@ -1785,7 +1785,7 @@ export class TrainrunSectionsView { .select(a[i]) .append(StaticDomTags.EDGE_LINE_STOPS_GROUP_SVG) .attr("class", StaticDomTags.EDGE_LINE_STOPS_GROUP_CLASS); - this.createIntermediateStops(grp, t.trainrunSections[0], selectedTrainrun, connectedTrainIds); + this.createIntermediateStops(grp, t, selectedTrainrun, connectedTrainIds); }); } From 814c3cf9b6b1e7f0d82ee99f0d3deefee67dc675 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 11:06:15 +0100 Subject: [PATCH 47/54] Pass view object in TrainrunSectionsView.createNumberOfStopsTextElement() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 126f01b7a..3860d4ab2 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -1672,7 +1672,7 @@ export class TrainrunSectionsView { createNumberOfStopsTextElement( groupEnter: d3.Selector, - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, selectedTrainrun: Trainrun, connectedTrainIds: any, numberOfStops: number, @@ -1684,30 +1684,34 @@ export class TrainrunSectionsView { StaticDomTags.EDGE_LINE_TEXT_CLASS + " " + TrainrunSectionsView.createTrainrunSectionFrequencyClassAttribute( - trainrunSection, + viewObject.trainrunSections[0], selectedTrainrun, connectedTrainIds, ) + " " + TrainrunSectionText[TrainrunSectionText.TrainrunSectionNumberOfStops], ) - .attr(StaticDomTags.EDGE_ID, () => trainrunSection.getId()) - .attr(StaticDomTags.EDGE_LINE_LINE_ID, () => trainrunSection.getTrainrunId()) + .attr(StaticDomTags.EDGE_ID, () => viewObject.trainrunSections[0].getId()) + .attr(StaticDomTags.EDGE_LINE_LINE_ID, () => viewObject.getTrainrun().getId()) .attr(StaticDomTags.EDGE_LINE_TEXT_INDEX, TrainrunSectionText.TrainrunSectionNumberOfStops) .attr("numberOfStops", numberOfStops) .attr("x", 0.0) .attr("y", 0.0) .attr("transform", () => TrainrunSectionsView.translateAndRotateText( - trainrunSection, + viewObject.trainrunSections[0], TrainrunSectionText.TrainrunSectionNumberOfStops, ), ) .text(numberOfStops) .classed(StaticDomTags.TAG_MUTED, () => - TrainrunSectionsView.isMuted(trainrunSection, selectedTrainrun, connectedTrainIds), + TrainrunSectionsView.isMuted( + viewObject.trainrunSections[0], + selectedTrainrun, + connectedTrainIds, + ), ) - .classed(StaticDomTags.TAG_SELECTED, () => trainrunSection.getTrainrun().selected()) + .classed(StaticDomTags.TAG_SELECTED, () => viewObject.getTrainrun().selected()) .on("mouseup", (t: TrainrunSectionViewObject, i, a) => this.onIntermediateStopMouseUp(t.trainrunSections[0], a[i]), ); @@ -1767,7 +1771,7 @@ export class TrainrunSectionsView { ); this.createNumberOfStopsTextElement( groupEnter, - viewObject.trainrunSections[0], + viewObject, selectedTrainrun, connectedTrainIds, numberOfStops, From 21fc1f3337f5869989ea2bd110b254a7dfec4056 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 10:58:28 +0100 Subject: [PATCH 48/54] Introduce helper to create view object for TrainrunSectionsView tests Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.spec.ts | 222 +++--------------- 1 file changed, 30 insertions(+), 192 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts index 4bade13de..e0bd72084 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts @@ -179,6 +179,20 @@ describe("TrainrunSection-View", () => { editorView = controller.editorView; }); + const createTrainrunSectionViewObject = (ts: TrainrunSection) => + new TrainrunSectionViewObject( + editorView, + [ts], + false, + false, + false, + false, + false, + false, + false, + false, + ); + it("TrainrunSectionsView.translateAndRotateText - TrainrunSectionName", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); @@ -322,18 +336,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getPosition - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v = TrainrunSectionsView.getPosition(viewObject, false); expect(v.getX()).toBe(734); expect(v.getY()).toBe(144); @@ -342,18 +345,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getPosition - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v = TrainrunSectionsView.getPosition(viewObject, true); expect(v.getX()).toBe(418); expect(v.getY()).toBe(112); @@ -989,18 +981,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(false); }); @@ -1008,18 +989,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); @@ -1027,18 +997,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 003", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(false); }); @@ -1046,18 +1005,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 004", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); @@ -1065,18 +1013,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 005", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(6); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(false); }); @@ -1084,18 +1021,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.enforceStartTextAnchor - 006", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(6); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(true); }); @@ -1104,18 +1030,7 @@ describe("TrainrunSection-View", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(7); ts.getPath()[1].setY(-1); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, true); expect(v1).toBe(true); }); @@ -1125,18 +1040,7 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(7); ts.getPath()[3].setX(ts.getPath()[2].getX()); ts.getPath()[3].setY(ts.getPath()[2].getY() + 1000); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.enforceStartTextAnchor(viewObject, false); expect(v1).toBe(true); }); @@ -1144,18 +1048,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, true); expect(v1).toBe("translate(498,80) rotate(0)"); }); @@ -1163,18 +1056,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue - 002", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, false); expect(v1).toBe("translate(654,112) rotate(0)"); }); @@ -1184,18 +1066,7 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(6); ts.getPath()[3].setX(ts.getPath()[2].getX()); ts.getPath()[3].setY(ts.getPath()[2].getY() + 1000); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, false); expect(v1).toBe("translate(898,96) rotate(-90)"); }); @@ -1205,18 +1076,7 @@ describe("TrainrunSection-View", () => { const ts = trainrunSectionService.getTrainrunSectionFromId(6); ts.getPath()[1].setX(ts.getPath()[0].getX()); ts.getPath()[1].setY(ts.getPath()[0].getY()); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionTextCloseToNodePositioningValue(viewObject, true); expect(v1).toBe("translate(1054,272) rotate(-90)"); }); @@ -1559,18 +1419,7 @@ describe("TrainrunSection-View", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const trainrunSection = trainrunSectionService.getTrainrunSectionFromId(0); - const viewObject = new TrainrunSectionViewObject( - editorView, - [trainrunSection], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(trainrunSection); const v0 = TrainrunSectionsView.getTrainrunSectionValueToShow( viewObject, @@ -1707,18 +1556,7 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow - 001", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(0); - const viewObject = new TrainrunSectionViewObject( - editorView, - [ts], - false, - false, - false, - false, - false, - false, - false, - false, - ); + const viewObject = createTrainrunSectionViewObject(ts); const v0 = TrainrunSectionsView.getTrainrunSectionNextAndDestinationNodeToShow( viewObject, editorView, From ff6410ac828baf84309924ade56e6223ada45ef4 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 11:16:51 +0100 Subject: [PATCH 49/54] Introduce TrainrunSectionViewObject.textPositions Supersedes TrainrunSection.path.textPositions because it takes into account collapsed nodes. Signed-off-by: Simon Ser --- .../data-views/trainrunSectionViewObject.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index fc36b2416..8e1752275 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -1,9 +1,12 @@ +import {TrainrunSectionTextPositions} from "../../../data-structures/technical.data.structures"; import {TrainrunSection} from "../../../models/trainrunsection.model"; +import {SimpleTrainrunSectionRouter} from "../../../services/util/trainrunsection.routing"; import {Vec2D} from "../../../utils/vec2D"; import {EditorView} from "./editor.view"; export class TrainrunSectionViewObject { key: string; + textPositions: TrainrunSectionTextPositions; constructor( private editorView: EditorView, @@ -29,6 +32,11 @@ export class TrainrunSectionViewObject { hiddenTagTrainrunName, hiddenTagDirectionArrows, ); + + this.textPositions = SimpleTrainrunSectionRouter.placeTextOnTrainrunSection( + this.getPath(), + trainrunSections[0].getSourceNode().getPort(trainrunSections[0].getSourcePortId()), + ); } getTrainrun() { From 5ed01abac15cd08b4363fda3fb03c3018e112cfa Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 11:53:59 +0100 Subject: [PATCH 50/54] Pass view object in TrainrunSectionsView.translateAndRotateText() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.spec.ts | 30 ++++++++++++++----- .../data-views/trainrunsections.view.ts | 24 ++++----------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts index e0bd72084..1c96f0c58 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts @@ -196,8 +196,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - TrainrunSectionName", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.TrainrunSectionName, ); expect(text).toBe("translate(576,116) rotate(9.659893078442336, 0,0) "); @@ -206,8 +207,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - TrainrunSectionTravelTime", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.TrainrunSectionTravelTime, ); expect(text).toBe("translate(576,116) rotate(9.659893078442336, 0,0) "); @@ -216,8 +218,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - TrainrunSectionNumberOfStops", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.TrainrunSectionNumberOfStops, ); expect(text).toBe("translate(576,140) rotate(9.659893078442336, 0,0) "); @@ -226,8 +229,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - TrainrunSectionName", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.TrainrunSectionName, ); expect(text).toBe("translate(576,116) rotate(9.659893078442336, 0,0) "); @@ -236,22 +240,31 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - SourceArrival", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const text = TrainrunSectionsView.translateAndRotateText(ts, TrainrunSectionText.SourceArrival); + const viewObject = createTrainrunSectionViewObject(ts); + const text = TrainrunSectionsView.translateAndRotateText( + viewObject, + TrainrunSectionText.SourceArrival, + ); expect(text).toBe("translate(436,124) rotate(9.659893078442336, 0,0) "); }); it("TrainrunSectionsView.translateAndRotateText - TargetArrival", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); - const text = TrainrunSectionsView.translateAndRotateText(ts, TrainrunSectionText.TargetArrival); + const viewObject = createTrainrunSectionViewObject(ts); + const text = TrainrunSectionsView.translateAndRotateText( + viewObject, + TrainrunSectionText.TargetArrival, + ); expect(text).toBe("translate(716,132) rotate(9.659893078442336, 0,0) "); }); it("TrainrunSectionsView.translateAndRotateText - SourceDeparture", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.SourceDeparture, ); expect(text).toBe("translate(464,100) rotate(9.659893078442336, 0,0) "); @@ -260,8 +273,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.translateAndRotateText - TargetDeparture", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(4); + const viewObject = createTrainrunSectionViewObject(ts); const text = TrainrunSectionsView.translateAndRotateText( - ts, + viewObject, TrainrunSectionText.TargetDeparture, ); expect(text).toBe("translate(688,156) rotate(9.659893078442336, 0,0) "); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 3860d4ab2..515174b64 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -51,15 +51,11 @@ export class TrainrunSectionsView { ) {} static translateAndRotateText( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, trainrunSectionText: TrainrunSectionText, - viewObject?: TrainrunSectionViewObject, ) { - const x = trainrunSection.getTextPositionX(trainrunSectionText); - const y = trainrunSection.getTextPositionY(trainrunSectionText); - - // Use viewObject path if provided, otherwise use trainrunSection path - const pathVec2D: Vec2D[] = viewObject ? viewObject.getPath() : trainrunSection.getPath(); + const {x, y} = viewObject.textPositions[trainrunSectionText]; + const pathVec2D = viewObject.getPath(); // Check if path has enough points if (pathVec2D.length < 4) { @@ -161,11 +157,7 @@ export class TrainrunSectionsView { return `translate(${x},${y}) rotate(${angle}, 0,0) `; } - return TrainrunSectionsView.translateAndRotateText( - trainrunSection, - trainrunSectionText, - viewObject, - ); + return TrainrunSectionsView.translateAndRotateText(viewObject, trainrunSectionText); } static isMuted( @@ -480,11 +472,7 @@ export class TrainrunSectionsView { return 1.5; case TrainrunSectionText.TrainrunSectionTravelTime: case TrainrunSectionText.TrainrunSectionName: - return TrainrunSectionsView.translateAndRotateText( - trainrunSection, - textElement, - viewObject, - ); + return TrainrunSectionsView.translateAndRotateText(viewObject, textElement); default: return 0; } @@ -1699,7 +1687,7 @@ export class TrainrunSectionsView { .attr("y", 0.0) .attr("transform", () => TrainrunSectionsView.translateAndRotateText( - viewObject.trainrunSections[0], + viewObject, TrainrunSectionText.TrainrunSectionNumberOfStops, ), ) From 889d4f5cab5a662cd89886f74a0e7ad9c743d80a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 11:55:02 +0100 Subject: [PATCH 51/54] Drop TrainrunSectionsView.translateAndRotateTextForViewObjectWithCollapsedSupport() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 51 +------------------ src/app/view/rastering/definitions.ts | 1 - 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index 515174b64..d3534d12f 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -5,7 +5,6 @@ import { DEFAULT_PIN_RADIUS, DEFAULT_STOP_ICON, EDGE_CASE_THRESHOLD, - MIN_PATH_LENGTH_FOR_ANGLE, NODE_EDGE_WIDTH, NODE_TEXT_AREA_HEIGHT, RASTERING_BASIC_GRID_SIZE, @@ -106,60 +105,12 @@ export class TrainrunSectionsView { return 1.5; case TrainrunSectionText.TrainrunSectionTravelTime: case TrainrunSectionText.TrainrunSectionName: - return this.translateAndRotateTextForViewObjectWithCollapsedSupport( - viewObject, - textElement, - ); + return TrainrunSectionsView.translateAndRotateText(viewObject, textElement); default: return 0; } } - translateAndRotateTextForViewObjectWithCollapsedSupport( - viewObject: TrainrunSectionViewObject, - trainrunSectionText: TrainrunSectionText, - ) { - const trainrunSection = viewObject.trainrunSections[0]; - const collapsedChainPath = viewObject.getPath(); - - if (collapsedChainPath && collapsedChainPath.length >= MIN_PATH_LENGTH_FOR_ANGLE) { - const textPositions = this.getTextPositionsForCollapsedChain( - collapsedChainPath, - trainrunSection, - ); - const x = - textPositions?.[trainrunSectionText]?.x ?? - trainrunSection.getTextPositionX(trainrunSectionText); - const y = - textPositions?.[trainrunSectionText]?.y ?? - trainrunSection.getTextPositionY(trainrunSectionText); - - // Use existing calculation logic with collapsed path - if (collapsedChainPath.length < MIN_PATH_LENGTH_FOR_ANGLE) { - return `translate(${x},${y}) rotate(0, 0,0) `; - } - - const [s1, t1] = [collapsedChainPath[1], collapsedChainPath[2]]; - const diff = Vec2D.sub(t1, s1); - let angle = (Math.atan2(diff.getY(), diff.getX()) / Math.PI) * 180.0; - - if (Math.abs(angle) > ANGLE_UPSIDE_DOWN_THRESHOLD) { - angle += 180; - } - - if (Math.abs(diff.getX()) < EDGE_CASE_THRESHOLD) { - angle = DEFAULT_ANGLE_VERTICAL; - } - if (Math.abs(diff.getY()) < EDGE_CASE_THRESHOLD) { - angle = DEFAULT_ANGLE_HORIZONTAL; - } - - return `translate(${x},${y}) rotate(${angle}, 0,0) `; - } - - return TrainrunSectionsView.translateAndRotateText(viewObject, trainrunSectionText); - } - static isMuted( trainrunSection: TrainrunSection, selectedTrainrun: Trainrun, diff --git a/src/app/view/rastering/definitions.ts b/src/app/view/rastering/definitions.ts index 08f5bb824..800ea3f60 100644 --- a/src/app/view/rastering/definitions.ts +++ b/src/app/view/rastering/definitions.ts @@ -63,7 +63,6 @@ export const SHOW_MAX_SINGLE_TRAINRUN_SECTIONS_STOPS = 5; /* Text rotation and path constants for trainrun sections */ -export const MIN_PATH_LENGTH_FOR_ANGLE = 4; export const ANGLE_UPSIDE_DOWN_THRESHOLD = 90; export const EDGE_CASE_THRESHOLD = 1; export const DEFAULT_ANGLE_VERTICAL = -90; From 48ff1cb1625d96abbd25f2bf9086eb60ef4a511c Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 12:03:09 +0100 Subject: [PATCH 52/54] Drop TrainrunSectionsView.getAdditionPositioningValueForViewObjectWithCollapsedSupport() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.spec.ts | 9 +++++--- .../data-views/trainrunsections.view.ts | 23 ++----------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts index 1c96f0c58..c7acb832c 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.spec.ts @@ -1189,8 +1189,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getAdditionPositioningValue - TrainrunSectionTravelTime", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionPositioningValue( - ts, + viewObject, TrainrunSectionText.TrainrunSectionTravelTime, ); expect(v1).toBe("translate(576,84) rotate(9.659893078442336, 0,0) "); @@ -1199,8 +1200,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getAdditionPositioningValue - TargetDeparture", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionPositioningValue( - ts, + viewObject, TrainrunSectionText.TargetDeparture, ); expect(v1).toBe(1.5); @@ -1209,8 +1211,9 @@ describe("TrainrunSection-View", () => { it("TrainrunSectionsView.getAdditionPositioningValue - TrainrunSectionNumberOfStops", () => { dataService.loadNetzgrafikDto(NetzgrafikUnitTesting.getUnitTestNetzgrafik()); const ts = trainrunSectionService.getTrainrunSectionFromId(2); + const viewObject = createTrainrunSectionViewObject(ts); const v1 = TrainrunSectionsView.getAdditionPositioningValue( - ts, + viewObject, TrainrunSectionText.TrainrunSectionNumberOfStops, ); expect(v1).toBe(0); diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index d3534d12f..a62441b6b 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -93,24 +93,6 @@ export class TrainrunSectionsView { return SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedChainPath, sourcePort); } - getAdditionPositioningValueForViewObjectWithCollapsedSupport( - viewObject: TrainrunSectionViewObject, - textElement: TrainrunSectionText, - ) { - switch (textElement) { - case TrainrunSectionText.SourceDeparture: - case TrainrunSectionText.SourceArrival: - case TrainrunSectionText.TargetDeparture: - case TrainrunSectionText.TargetArrival: - return 1.5; - case TrainrunSectionText.TrainrunSectionTravelTime: - case TrainrunSectionText.TrainrunSectionName: - return TrainrunSectionsView.translateAndRotateText(viewObject, textElement); - default: - return 0; - } - } - static isMuted( trainrunSection: TrainrunSection, selectedTrainrun: Trainrun, @@ -411,9 +393,8 @@ export class TrainrunSectionsView { } static getAdditionPositioningValue( - trainrunSection: TrainrunSection, + viewObject: TrainrunSectionViewObject, textElement: TrainrunSectionText, - viewObject?: TrainrunSectionViewObject, ) { switch (textElement) { case TrainrunSectionText.SourceDeparture: @@ -1483,7 +1464,7 @@ export class TrainrunSectionsView { .attr( TrainrunSectionsView.getAdditionPositioningAttr(textElement), (d: TrainrunSectionViewObject) => - this.getAdditionPositioningValueForViewObjectWithCollapsedSupport(d, textElement), + TrainrunSectionsView.getAdditionPositioningValue(d, textElement), ) .classed(StaticDomTags.TAG_SELECTED, (d: TrainrunSectionViewObject) => d.getTrainrun().selected(), From c8592c33dd55a41a99d5cb2122f5a01f4dcfdae8 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Dec 2025 12:04:26 +0100 Subject: [PATCH 53/54] Drop TrainrunSectionsView.getTextPositionsForCollapsedChain() Signed-off-by: Simon Ser --- .../data-views/trainrunsections.view.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts index a62441b6b..c6244b5bc 100644 --- a/src/app/view/editor-main-view/data-views/trainrunsections.view.ts +++ b/src/app/view/editor-main-view/data-views/trainrunsections.view.ts @@ -39,7 +39,6 @@ import {LinePatternRefs} from "../../../data-structures/business.data.structures import {Direction} from "src/app/data-structures/business.data.structures"; import {GeneralViewFunctions} from "../../util/generalViewFunctions"; import {TrainrunsectionHelper} from "src/app/services/util/trainrunsection.helper"; -import {SimpleTrainrunSectionRouter} from "../../../services/util/trainrunsection.routing"; export class TrainrunSectionsView { trainrunSectionGroup; @@ -78,21 +77,6 @@ export class TrainrunSectionsView { return "translate(" + x + "," + y + ") rotate(" + a + ", 0,0) "; } - private getTextPositionsForCollapsedChain( - collapsedChainPath: Vec2D[], - trainrunSection: TrainrunSection, - ): any { - const sourceNode = trainrunSection.getSourceNode(); - const sourcePort = - sourceNode.getPortOfTrainrunSection(trainrunSection.getId()) || sourceNode.getPorts()[0]; - - if (!sourcePort) { - return null; - } - - return SimpleTrainrunSectionRouter.placeTextOnTrainrunSection(collapsedChainPath, sourcePort); - } - static isMuted( trainrunSection: TrainrunSection, selectedTrainrun: Trainrun, From 7f08f5d01632860e5cbe0a3dbb59a0f947bc3670 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 5 Dec 2025 11:28:00 +0100 Subject: [PATCH 54/54] Mark immutable TrainrunSectionViewObject fields as readonly This prevents callers from mutating these fields. Signed-off-by: Simon Ser --- .../editor-main-view/data-views/trainrunSectionViewObject.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts index 8e1752275..99b599b59 100644 --- a/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts +++ b/src/app/view/editor-main-view/data-views/trainrunSectionViewObject.ts @@ -5,8 +5,8 @@ import {Vec2D} from "../../../utils/vec2D"; import {EditorView} from "./editor.view"; export class TrainrunSectionViewObject { - key: string; - textPositions: TrainrunSectionTextPositions; + readonly key: string; + readonly textPositions: TrainrunSectionTextPositions; constructor( private editorView: EditorView,