From 04c26f7e9b0633426ce372f1f1e25a9f1c08f7b1 Mon Sep 17 00:00:00 2001 From: Thomas ADAM Date: Tue, 26 Sep 2023 11:49:01 +0200 Subject: [PATCH 01/34] First try Signed-off-by: Thomas ADAM --- .../powsybl/sld/layout/MatrixZoneLayout.java | 140 +++ .../sld/layout/MatrixZoneLayoutFactory.java | 22 + .../powsybl/sld/iidm/TestCase13ZoneGraph.java | 17 + .../TestCase13ZoneGraphMatrix2x3.svg | 1096 +++++++++++++++++ 4 files changed, 1275 insertions(+) create mode 100644 single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java create mode 100644 single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java create mode 100644 single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java new file mode 100644 index 000000000..9b50dec80 --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2023, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.sld.layout; + +import com.powsybl.sld.model.coordinate.*; +import com.powsybl.sld.model.graphs.*; +import com.powsybl.sld.model.nodes.*; +import org.jgrapht.alg.util.*; + +import java.util.*; + +/** + * @author Thomas Adam + */ +public class MatrixZoneLayout extends AbstractZoneLayout { + + private final String[][] matrix; + + protected MatrixZoneLayout(ZoneGraph graph, String[][] matrix, SubstationLayoutFactory sLayoutFactory, VoltageLevelLayoutFactory vLayoutFactory) { + super(graph, sLayoutFactory, vLayoutFactory); + this.matrix = matrix; + } + + /** + * Calculate relative coordinate of substations in the zone + */ + @Override + protected void calculateCoordSubstations(LayoutParameters layoutParameters) { + // Height by rows + List rowsHeight = new ArrayList<>(); + // Width by col + List colsWidth = new ArrayList<>(); + + for (String[] strings : matrix) { + double rowHeight = 0; + double colWidth = 0; + for (String id : strings) { + Optional subGraph = getGraph().getSubstations().stream().filter(s -> s.getSubstationId().equals(id)).findFirst(); + if (subGraph.isPresent()) { + SubstationGraph graph = subGraph.get(); + // Display substations + Layout sLayout = sLayoutFactory.create(graph, vLayoutFactory); + sLayout.run(layoutParameters); + + rowHeight = Math.max(rowHeight, graph.getHeight()); + colWidth = Math.max(colWidth, graph.getWidth()); + } + colsWidth.add(colWidth); + } + rowsHeight.add(rowHeight); + } + + double zoneWidth = 0.0; + double zoneHeight = 0.0; + double dy = 0.0; + + for (int row = 0; row < matrix.length; row++) { + double maxColWidth = 0.0; + for (int col = 0; col < matrix[row].length; col++) { + String id = matrix[row][col]; + + Optional subGraph = getGraph().getSubstations().stream().filter(s -> s.getSubstationId().equals(id)).findFirst(); + if (subGraph.isPresent()) { + SubstationGraph graph = subGraph.get(); + double dx = colsWidth.get(col); + move(graph, col * dx, row * dy); + } + maxColWidth += colsWidth.get(col); + } + dy = rowsHeight.get(row); + zoneWidth = Math.max(maxColWidth, zoneWidth); + zoneHeight += rowsHeight.get(row); + } + + getGraph().setSize(zoneWidth, zoneHeight); + maxVoltageLevelWidth = zoneWidth; + } + + @Override + protected List calculatePolylineSnakeLine(LayoutParameters layoutParam, Pair nodes, + boolean increment) { + // FIXME: need to be implemented + Node node1 = nodes.getFirst(); + Node node2 = nodes.getSecond(); + List pol = new ArrayList<>(); + pol.add(getGraph().getShiftedPoint(node1)); + pol.add(getGraph().getShiftedPoint(node2)); + return pol; + } + + @Override + public void manageSnakeLines(LayoutParameters layoutParameters) { + // Draw snakelines for each Substations + getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); + // Draw snakelines between all Substations + //manageSnakeLines(getGraph(), layoutParameters); + /* + // Change Voltagelevels coordinates in function of snakelines drawn + adaptPaddingToSnakeLines(layoutParameters); + // Redraw all snakelines + getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); + manageSnakeLines(getGraph(), layoutParameters); + */ + } +/* + private void adaptPaddingToSnakeLines(LayoutParameters layoutParameters) { + double widthSnakeLinesLeft = Math.max(infosNbSnakeLines.getNbSnakeLinesLeftRight().get(Side.LEFT) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); + + LayoutParameters.Padding diagramPadding = layoutParameters.getDiagramPadding(); + LayoutParameters.Padding voltageLevelPadding = layoutParameters.getVoltageLevelPadding(); + + double y = diagramPadding.getTop() + + getGraph().getVoltageLevelStream().findFirst().map(vlg -> getHeightHorizontalSnakeLines(vlg.getId(), TOP, layoutParameters)).orElse(0.); + + for (SubstationGraph subGraph : getGraph().getSubstations()) { + move(subGraph, widthSnakeLinesLeft, y + voltageLevelPadding.getTop()); + } + + for (VoltageLevelGraph vlGraph : getGraph().getVoltageLevels()) { + y += vlGraph.getHeight() + getHeightHorizontalSnakeLines(vlGraph.getId(), BOTTOM, layoutParameters); + } + + double widthSnakeLinesRight = Math.max(infosNbSnakeLines.getNbSnakeLinesLeftRight().get(Side.RIGHT) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); + double substationWidth = getGraph().getWidth() + widthSnakeLinesLeft + widthSnakeLinesRight; + double substationHeight = y - diagramPadding.getTop(); + getGraph().setSize(substationWidth, substationHeight); + + infosNbSnakeLines.reset(); + } + + private double getHeightHorizontalSnakeLines(String vlGraphId, Direction direction, LayoutParameters layoutParameters) { + return Math.max(infosNbSnakeLines.getNbSnakeLinesHorizontalBetween(vlGraphId, direction) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); + } + */ +} diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java new file mode 100644 index 000000000..5f3171ed7 --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2023, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.sld.layout; + +import com.powsybl.sld.model.graphs.*; + +/** + * @author Thomas Adam + */ +public class MatrixZoneLayoutFactory/* implements ZoneLayoutFactory*/ { + + // FIXME : ZoneLayoutFactory need to be refactored + //@Override + public Layout create(ZoneGraph graph, String[][] matrix, SubstationLayoutFactory sLayoutFactory, VoltageLevelLayoutFactory vLayoutFactory) { + return new MatrixZoneLayout(graph, matrix, sLayoutFactory, vLayoutFactory); + } +} diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java index 31768275c..f9a3410a3 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java @@ -111,4 +111,21 @@ void testZoneGraphHWithSubstationV() { assertEquals(toString("/TestCase13ZoneGraphHV.svg"), toSVG(g, "/TestCase13ZoneGraphHV.svg")); } + + @Test + void testZoneGraphMatrix2rows3cols() { + // build zone graph + network = Networks.createNetworkWithManySubstations(); + List zone = Arrays.asList("A", "B", "C", "D", "E"); + ZoneGraph g = new NetworkGraphBuilder(network).buildZoneGraph(zone); + + layoutParameters.setDiagrammPadding(1.0, 1.0, 1.0, 1.0); + + // Run vertical zone layout + String[][] substationsIds = {{"A", "B", "C"}, + {"D", "", "E"}}; + new MatrixZoneLayoutFactory().create(g, substationsIds, new VerticalSubstationLayoutFactory(), new PositionVoltageLevelLayoutFactory()).run(layoutParameters); + + assertEquals(toString("/TestCase13ZoneGraphMatrix2x3.svg"), toSVG(g, "/TestCase13ZoneGraphMatrix2x3.svg")); + } } diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg new file mode 100644 index 000000000..2531bd271 --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg @@ -0,0 +1,1096 @@ + + + + + + + A 400 + + + + A 400 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 400 230 + + + + A 230 + + + + A 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 400 230 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A - B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AC / DC - VSC + Converter1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A230_B230 + + + + + + + + + + + + + + B 230 + + + + B 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A - B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AC / DC - VSC + Converter2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A230_B230 + + + + C 230 + + + + C 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + C 66 + + + + C 66 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C66 - D + + + + C 20 + + + + C 20 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + D 66 + + + + D 66 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D 66 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D66 - D + + + + D 10 + + + + D 10 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D 66 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D - E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + H - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K - D + + + + + + + + + + + + + + E 10 + + + + E 10 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D - E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E - F + + + + + + + + + + + + + + + + + + + + + + From c283b71f7b04e48c284303a7bfb68c4ea16be5de Mon Sep 17 00:00:00 2001 From: Thomas ADAM Date: Tue, 26 Sep 2023 12:42:41 +0200 Subject: [PATCH 02/34] Add default matrix behaviour Signed-off-by: Thomas ADAM --- .../powsybl/sld/layout/MatrixZoneLayout.java | 56 +- .../sld/layout/MatrixZoneLayoutFactory.java | 16 +- .../powsybl/sld/iidm/TestCase13ZoneGraph.java | 17 +- .../TestCase13ZoneGraphMatrix1x5.svg | 1096 +++++++++++++++++ 4 files changed, 1133 insertions(+), 52 deletions(-) create mode 100644 single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java index 9b50dec80..2281eeb6d 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java @@ -32,9 +32,9 @@ protected MatrixZoneLayout(ZoneGraph graph, String[][] matrix, SubstationLayoutF @Override protected void calculateCoordSubstations(LayoutParameters layoutParameters) { // Height by rows - List rowsHeight = new ArrayList<>(); + List maxHeightByRow = new ArrayList<>(); // Width by col - List colsWidth = new ArrayList<>(); + List maxWidthByCol = new ArrayList<>(); for (String[] strings : matrix) { double rowHeight = 0; @@ -50,9 +50,9 @@ protected void calculateCoordSubstations(LayoutParameters layoutParameters) { rowHeight = Math.max(rowHeight, graph.getHeight()); colWidth = Math.max(colWidth, graph.getWidth()); } - colsWidth.add(colWidth); + maxWidthByCol.add(colWidth); } - rowsHeight.add(rowHeight); + maxHeightByRow.add(rowHeight); } double zoneWidth = 0.0; @@ -63,18 +63,17 @@ protected void calculateCoordSubstations(LayoutParameters layoutParameters) { double maxColWidth = 0.0; for (int col = 0; col < matrix[row].length; col++) { String id = matrix[row][col]; - + double dx = maxWidthByCol.get(col); Optional subGraph = getGraph().getSubstations().stream().filter(s -> s.getSubstationId().equals(id)).findFirst(); if (subGraph.isPresent()) { SubstationGraph graph = subGraph.get(); - double dx = colsWidth.get(col); move(graph, col * dx, row * dy); } - maxColWidth += colsWidth.get(col); + maxColWidth += dx; } - dy = rowsHeight.get(row); + dy = maxHeightByRow.get(row); zoneWidth = Math.max(maxColWidth, zoneWidth); - zoneHeight += rowsHeight.get(row); + zoneHeight += dy; } getGraph().setSize(zoneWidth, zoneHeight); @@ -97,44 +96,5 @@ protected List calculatePolylineSnakeLine(LayoutParameters layoutParam, P public void manageSnakeLines(LayoutParameters layoutParameters) { // Draw snakelines for each Substations getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); - // Draw snakelines between all Substations - //manageSnakeLines(getGraph(), layoutParameters); - /* - // Change Voltagelevels coordinates in function of snakelines drawn - adaptPaddingToSnakeLines(layoutParameters); - // Redraw all snakelines - getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); - manageSnakeLines(getGraph(), layoutParameters); - */ - } -/* - private void adaptPaddingToSnakeLines(LayoutParameters layoutParameters) { - double widthSnakeLinesLeft = Math.max(infosNbSnakeLines.getNbSnakeLinesLeftRight().get(Side.LEFT) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); - - LayoutParameters.Padding diagramPadding = layoutParameters.getDiagramPadding(); - LayoutParameters.Padding voltageLevelPadding = layoutParameters.getVoltageLevelPadding(); - - double y = diagramPadding.getTop() - + getGraph().getVoltageLevelStream().findFirst().map(vlg -> getHeightHorizontalSnakeLines(vlg.getId(), TOP, layoutParameters)).orElse(0.); - - for (SubstationGraph subGraph : getGraph().getSubstations()) { - move(subGraph, widthSnakeLinesLeft, y + voltageLevelPadding.getTop()); - } - - for (VoltageLevelGraph vlGraph : getGraph().getVoltageLevels()) { - y += vlGraph.getHeight() + getHeightHorizontalSnakeLines(vlGraph.getId(), BOTTOM, layoutParameters); - } - - double widthSnakeLinesRight = Math.max(infosNbSnakeLines.getNbSnakeLinesLeftRight().get(Side.RIGHT) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); - double substationWidth = getGraph().getWidth() + widthSnakeLinesLeft + widthSnakeLinesRight; - double substationHeight = y - diagramPadding.getTop(); - getGraph().setSize(substationWidth, substationHeight); - - infosNbSnakeLines.reset(); } - - private double getHeightHorizontalSnakeLines(String vlGraphId, Direction direction, LayoutParameters layoutParameters) { - return Math.max(infosNbSnakeLines.getNbSnakeLinesHorizontalBetween(vlGraphId, direction) - 1, 0) * layoutParameters.getHorizontalSnakeLinePadding(); - } - */ } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java index 5f3171ed7..34165f0da 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayoutFactory.java @@ -9,14 +9,24 @@ import com.powsybl.sld.model.graphs.*; +import java.util.*; + /** * @author Thomas Adam */ -public class MatrixZoneLayoutFactory/* implements ZoneLayoutFactory*/ { +public class MatrixZoneLayoutFactory implements ZoneLayoutFactory { - // FIXME : ZoneLayoutFactory need to be refactored - //@Override public Layout create(ZoneGraph graph, String[][] matrix, SubstationLayoutFactory sLayoutFactory, VoltageLevelLayoutFactory vLayoutFactory) { return new MatrixZoneLayout(graph, matrix, sLayoutFactory, vLayoutFactory); } + + @Override + public Layout create(ZoneGraph graph, SubstationLayoutFactory sLayoutFactory, VoltageLevelLayoutFactory vLayoutFactory) { + // By default work as Horizontal layout + List substations = graph.getSubstations().stream().map(SubstationGraph::getId).toList(); + String[] array = new String[substations.size()]; + String[][] matrix = new String[1][]; + matrix[0] = substations.toArray(array); + return new MatrixZoneLayout(graph, matrix, sLayoutFactory, vLayoutFactory); + } } diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java index f9a3410a3..04d07a11c 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java @@ -121,11 +121,26 @@ void testZoneGraphMatrix2rows3cols() { layoutParameters.setDiagrammPadding(1.0, 1.0, 1.0, 1.0); - // Run vertical zone layout + // Run matrix zone layout String[][] substationsIds = {{"A", "B", "C"}, {"D", "", "E"}}; new MatrixZoneLayoutFactory().create(g, substationsIds, new VerticalSubstationLayoutFactory(), new PositionVoltageLevelLayoutFactory()).run(layoutParameters); assertEquals(toString("/TestCase13ZoneGraphMatrix2x3.svg"), toSVG(g, "/TestCase13ZoneGraphMatrix2x3.svg")); } + + @Test + void testZoneGraphMatrix1row5cols() { + // build zone graph + network = Networks.createNetworkWithManySubstations(); + List zone = Arrays.asList("A", "B", "C", "D", "E"); + ZoneGraph g = new NetworkGraphBuilder(network).buildZoneGraph(zone); + + layoutParameters.setDiagrammPadding(1.0, 1.0, 1.0, 1.0); + + // Run default matrix zone layout + new MatrixZoneLayoutFactory().create(g, new VerticalSubstationLayoutFactory(), new PositionVoltageLevelLayoutFactory()).run(layoutParameters); + + assertEquals(toString("/TestCase13ZoneGraphMatrix1x5.svg"), toSVG(g, "/TestCase13ZoneGraphMatrix1x5.svg")); + } } diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg new file mode 100644 index 000000000..d8bcff748 --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg @@ -0,0 +1,1096 @@ + + + + + + + A 400 + + + + A 400 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 400 230 + + + + A 230 + + + + A 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A 400 230 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A - B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AC / DC - VSC + Converter1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A230_B230 + + + + + + + + + + + + + + B 230 + + + + B 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A - B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AC / DC - VSC + Converter2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A230_B230 + + + + C 230 + + + + C 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + C 66 + + + + C 66 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C66 - D + + + + C 20 + + + + C 20 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + D 66 + + + + D 66 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D 66 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D66 - D + + + + D 10 + + + + D 10 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D 66 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D - E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + H - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K - D + + + + + + + + + + + + + + E 10 + + + + E 10 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D - E + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E - F + + + + + + + + + + + + + + + + + + + + + + From 9cc4dc96215019fa8b35f11e17e839420f7f0101 Mon Sep 17 00:00:00 2001 From: Thomas ADAM Date: Thu, 28 Sep 2023 10:16:02 +0200 Subject: [PATCH 03/34] Display Substation with Snakelines draw from Substation Layout Signed-off-by: Thomas ADAM --- .../sld/layout/AbstractZoneLayout.java | 8 +- .../sld/layout/HorizontalZoneLayout.java | 4 +- .../powsybl/sld/layout/MatrixZoneLayout.java | 61 +- .../sld/layout/VerticalZoneLayout.java | 3 +- .../powsybl/sld/model/graphs/ZoneGraph.java | 8 +- .../powsybl/sld/iidm/TestCase13ZoneGraph.java | 2 +- .../TestCase13ZoneGraphMatrix1x5.svg | 510 ++++++++--------- .../TestCase13ZoneGraphMatrix2x3.svg | 528 +++++++++--------- 8 files changed, 574 insertions(+), 550 deletions(-) diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/AbstractZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/AbstractZoneLayout.java index 3d7f2bd5d..98092a82f 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/AbstractZoneLayout.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/AbstractZoneLayout.java @@ -11,7 +11,7 @@ import com.powsybl.sld.model.graphs.VoltageLevelGraph; import com.powsybl.sld.model.graphs.ZoneGraph; -import java.util.Objects; +import java.util.*; /** * @author Thomas Adam {@literal } @@ -19,11 +19,17 @@ public abstract class AbstractZoneLayout extends AbstractBaseLayout { protected SubstationLayoutFactory sLayoutFactory; protected VoltageLevelLayoutFactory vLayoutFactory; + protected Map> layoutBySubstation; protected AbstractZoneLayout(ZoneGraph graph, SubstationLayoutFactory sLayoutFactory, VoltageLevelLayoutFactory vLayoutFactory) { super(graph); this.sLayoutFactory = Objects.requireNonNull(sLayoutFactory); this.vLayoutFactory = Objects.requireNonNull(vLayoutFactory); + this.layoutBySubstation = new HashMap<>(); + for (SubstationGraph subGraph : getGraph().getSubstations()) { + Layout sLayout = sLayoutFactory.create(subGraph, vLayoutFactory); + layoutBySubstation.put(subGraph, (AbstractLayout) sLayout); + } } @Override diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/HorizontalZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/HorizontalZoneLayout.java index 6ee49a57d..0e5296399 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/HorizontalZoneLayout.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/HorizontalZoneLayout.java @@ -48,9 +48,7 @@ protected void calculateCoordSubstations(LayoutParameters layoutParameters) { double zoneHeight = 0.0; for (SubstationGraph subGraph : getGraph().getSubstations()) { - // Calculate the objects coordinates inside the zone graph - Layout sLayout = sLayoutFactory.create(subGraph, vLayoutFactory); - sLayout.run(layoutParameters); + layoutBySubstation.get(subGraph).run(layoutParameters); move(subGraph, zoneWidth, 0); diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java index 2281eeb6d..09e28319c 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/MatrixZoneLayout.java @@ -32,48 +32,41 @@ protected MatrixZoneLayout(ZoneGraph graph, String[][] matrix, SubstationLayoutF @Override protected void calculateCoordSubstations(LayoutParameters layoutParameters) { // Height by rows - List maxHeightByRow = new ArrayList<>(); + double maxHeightRow = 0.0; // Width by col - List maxWidthByCol = new ArrayList<>(); + double maxWidthCol = 0.0; for (String[] strings : matrix) { - double rowHeight = 0; - double colWidth = 0; for (String id : strings) { Optional subGraph = getGraph().getSubstations().stream().filter(s -> s.getSubstationId().equals(id)).findFirst(); if (subGraph.isPresent()) { SubstationGraph graph = subGraph.get(); // Display substations - Layout sLayout = sLayoutFactory.create(graph, vLayoutFactory); - sLayout.run(layoutParameters); + layoutBySubstation.get(graph).run(layoutParameters); - rowHeight = Math.max(rowHeight, graph.getHeight()); - colWidth = Math.max(colWidth, graph.getWidth()); + maxHeightRow = Math.max(maxHeightRow, graph.getHeight()); + maxWidthCol = Math.max(maxWidthCol, graph.getWidth()); } - maxWidthByCol.add(colWidth); } - maxHeightByRow.add(rowHeight); } + LayoutParameters.Padding diagramPadding = layoutParameters.getDiagramPadding(); double zoneWidth = 0.0; double zoneHeight = 0.0; - double dy = 0.0; for (int row = 0; row < matrix.length; row++) { double maxColWidth = 0.0; for (int col = 0; col < matrix[row].length; col++) { String id = matrix[row][col]; - double dx = maxWidthByCol.get(col); Optional subGraph = getGraph().getSubstations().stream().filter(s -> s.getSubstationId().equals(id)).findFirst(); if (subGraph.isPresent()) { SubstationGraph graph = subGraph.get(); - move(graph, col * dx, row * dy); + move(graph, col * maxWidthCol + diagramPadding.getLeft(), row * maxHeightRow + diagramPadding.getTop()); } - maxColWidth += dx; + maxColWidth += maxWidthCol; } - dy = maxHeightByRow.get(row); zoneWidth = Math.max(maxColWidth, zoneWidth); - zoneHeight += dy; + zoneHeight += maxHeightRow; } getGraph().setSize(zoneWidth, zoneHeight); @@ -83,18 +76,42 @@ protected void calculateCoordSubstations(LayoutParameters layoutParameters) { @Override protected List calculatePolylineSnakeLine(LayoutParameters layoutParam, Pair nodes, boolean increment) { - // FIXME: need to be implemented + List polyline; Node node1 = nodes.getFirst(); Node node2 = nodes.getSecond(); - List pol = new ArrayList<>(); - pol.add(getGraph().getShiftedPoint(node1)); - pol.add(getGraph().getShiftedPoint(node2)); - return pol; + VoltageLevelGraph vl1Graph = getGraph().getVoltageLevelGraph(node1); + VoltageLevelGraph vl2Graph = getGraph().getVoltageLevelGraph(node2); + SubstationGraph ss1Graph = getGraph().getSubstationGraph(node1).orElse(null); + SubstationGraph ss2Graph = getGraph().getSubstationGraph(node2).orElse(null); + if (vl1Graph == vl2Graph) { // in the same VL (so far always horizontal layout) + throw new UnsupportedOperationException(); + } else if (ss1Graph != null && ss1Graph == ss2Graph) { // in the same SS + polyline = layoutBySubstation.get(ss1Graph).calculatePolylineSnakeLine(layoutParam, nodes, increment); + } else { // in the same Zone + // FIXME: need to be improved + polyline = new ArrayList<>(); + //polyline.add(getGraph().getShiftedPoint(node1)); + //polyline.add(getGraph().getShiftedPoint(node2)); + } + return polyline; } @Override public void manageSnakeLines(LayoutParameters layoutParameters) { - // Draw snakelines for each Substations + // Draw snakelines between VoltageLevel for each Substations getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); + // Draw snakelines between Substations + manageSnakeLines(getGraph(), layoutParameters); + // Move each substation taking into account snakelines + adaptPaddingToSnakeLines(layoutParameters); + } + + private void adaptPaddingToSnakeLines(LayoutParameters layoutParameters) { + // FIXME: need to be implemented + + // Re-draw snakelines between VoltageLevel for each Substations + // getGraph().getSubstations().forEach(g -> manageSnakeLines(g, layoutParameters)); + // Re-draw snakelines between Substations + // manageSnakeLines(getGraph(), layoutParameters); } } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/VerticalZoneLayout.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/VerticalZoneLayout.java index d3f6aa21f..88b3a0ffb 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/VerticalZoneLayout.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/layout/VerticalZoneLayout.java @@ -71,8 +71,7 @@ protected void calculateCoordSubstations(LayoutParameters layoutParameters) { for (SubstationGraph subGraph : getGraph().getSubstations()) { // Calculate the objects coordinates inside the substation graph - Layout sLayout = sLayoutFactory.create(subGraph, vLayoutFactory); - sLayout.run(layoutParameters); + layoutBySubstation.get(subGraph).run(layoutParameters); move(subGraph, 0, zoneHeight); diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/ZoneGraph.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/ZoneGraph.java index 5507effdf..94c42b896 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/ZoneGraph.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/model/graphs/ZoneGraph.java @@ -12,7 +12,6 @@ import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -59,6 +58,11 @@ public List getSubstations() { return substations; } + public Optional getSubstationGraph(Node node) { + VoltageLevelGraph vlGraph = getVoltageLevelGraph(node); + return getSubstations().stream().filter(s -> s.getVoltageLevels().contains(vlGraph)).findFirst(); + } + @Override public VoltageLevelGraph getVoltageLevel(String voltageLevelId) { Objects.requireNonNull(voltageLevelId); @@ -72,7 +76,7 @@ public Stream getVoltageLevelStream() { @Override public List getVoltageLevels() { - return getVoltageLevelStream().collect(Collectors.toList()); + return getVoltageLevelStream().toList(); } @Override diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java index 04d07a11c..481001515 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestCase13ZoneGraph.java @@ -124,7 +124,7 @@ void testZoneGraphMatrix2rows3cols() { // Run matrix zone layout String[][] substationsIds = {{"A", "B", "C"}, {"D", "", "E"}}; - new MatrixZoneLayoutFactory().create(g, substationsIds, new VerticalSubstationLayoutFactory(), new PositionVoltageLevelLayoutFactory()).run(layoutParameters); + new MatrixZoneLayoutFactory().create(g, substationsIds, new HorizontalSubstationLayoutFactory(), new PositionVoltageLevelLayoutFactory()).run(layoutParameters); assertEquals(toString("/TestCase13ZoneGraphMatrix2x3.svg"), toSVG(g, "/TestCase13ZoneGraphMatrix2x3.svg")); } diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg index d8bcff748..368f59d56 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg @@ -145,932 +145,932 @@ - A 400 + A 400 - + A 400 Bus - + - + - + - + - + - + - + - + - + A 400 230 - A 230 + A 230 - + A 230 Bus - + - + - + - + - + - + - + - + - + A 400 230 - + - + - + - + - + - + - + - + - + A - B - + - + - + - + - + - + - + - + - + AC / DC - VSC Converter1 - + - + - + - + - + - + - + - + - + A230_B230 - + - + - + - B 230 + B 230 - + B 230 Bus - + - + - + - + - + - + - + - + - + A - B - + - + - + - + - + - + - + - + - + B - C - + - + - + - + - + - + - + - + - + AC / DC - VSC Converter2 - + - + - + - + - + - + - + - + - + A230_B230 - C 230 + C 230 - + C 230 Bus - + - + - + - + - + - + - + - + - + C 230 66 - + - + - + - + - + - + - + - + - + B - C - C 66 + C 66 - + C 66 Bus - + - + - + - + - + - + - + - + - + C 230 66 - + - + - + - + - + - + - + - + - + C 66 20 - + - + - + - + - + - + - + - + - + C - D - + - + - + - + - + - + - + - + - + C66 - D - C 20 + C 20 - + C 20 Bus - + - + - + - + - + - + - + - + - + C 66 20 - + - + - + - + - + - + - D 66 + D 66 - + D 66 Bus - + - + - + - + - + - + - + - + - + D 66 10 - + - + - + - + - + - + - + - + - + C - D - + - + - + - + - + - + - + - + - + D66 - D - D 10 + D 10 - + D 10 Bus - + - + - + - + - + - + - + - + - + D 66 10 - + - + - + - + - + - + - + - + - + D - E - + - + - + - + - + - + - + - + - + H - D - + - + - + - + - + - + - + - + - + K - D - + - + - + - E 10 + E 10 - + E 10 Bus - + - + - + - + - + - + - + - + - + D - E - + - + - + - + - + - + - + - + - + E - F diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg index 2531bd271..696cc130d 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix2x3.svg @@ -1,5 +1,5 @@ - + + + + + B 230 + + + + B 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A - B + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AC / DC - VSC + Converter2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A230_B230 + + + + C 230 + + + + C 230 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + B - C + + + + C 66 + + + + C 66 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 230 66 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C - D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C66 - D + + + + C 20 + + + + C 20 Bus + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C 66 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg index 5544f3720..cae58851f 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/TestCase13ZoneGraphMatrix1x5.svg @@ -1,5 +1,5 @@ - +