Skip to content

Commit ff1d577

Browse files
committed
[SLD] Represent nodes/buses fictitious injections
Signed-off-by: Samir Romdhani <samir.romdhani_externe@rte-france.com> test remove debugSvgFiles Signed-off-by: Samir Romdhani <samir.romdhani_externe@rte-france.com> review sonar Signed-off-by: Samir Romdhani <samir.romdhani_externe@rte-france.com>
1 parent cb2280b commit ff1d577

5 files changed

Lines changed: 523 additions & 13 deletions

File tree

diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,32 @@ public static Network createDanglingConnectablesNetwork() {
24902490
return network;
24912491
}
24922492

2493+
public static Network createBusbarLoadNetwork() {
2494+
Network network = Network.create("test", "test");
2495+
Substation s = Networks.createSubstation(network, SUBSTATION_ID, "Substation", Country.FR);
2496+
VoltageLevel vl = Networks.createVoltageLevel(s, VOLTAGELEVEL_1_ID, "VoltageLevel", TopologyKind.NODE_BREAKER, 400.0);
2497+
//BBS node1
2498+
vl.getNodeBreakerView().newBusbarSection()
2499+
.setId("BBS1")
2500+
.setNode(1)
2501+
.add();
2502+
//LOAD node2
2503+
vl.newLoad()
2504+
.setId("L1")
2505+
.setNode(2)
2506+
.setP0(10.0)
2507+
.setQ0(2.0)
2508+
.add();
2509+
// broker between node 1 and node 2
2510+
vl.getNodeBreakerView().newBreaker()
2511+
.setId("B1")
2512+
.setNode1(1)
2513+
.setNode2(2)
2514+
.setOpen(false)
2515+
.add();
2516+
return network;
2517+
}
2518+
24932519
public static void createLine(Bus bus1, Bus bus2) {
24942520
String id = String.format("%s - %s",
24952521
bus1.getVoltageLevel().getSubstation().orElseThrow().getId(),

single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/DefaultSVGLegendWriter.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.w3c.dom.Element;
1818
import org.w3c.dom.Text;
1919

20+
import java.util.ArrayList;
2021
import java.util.List;
2122
import java.util.Objects;
2223

@@ -59,11 +60,26 @@ public void drawLegend(VoltageLevelGraph graph, GraphMetadata metadata, StylePro
5960
protected List<BusLegendInfo> getBusLegendInfos(VoltageLevelGraph graph) {
6061
VoltageLevel vl = network.getVoltageLevel(graph.getVoltageLevelInfos().id());
6162
return vl.getBusView().getBusStream()
62-
.map(b -> new BusLegendInfo(b.getId(), List.of(
63-
new BusLegendInfo.Caption(valueFormatter.formatVoltage(b.getV(), "kV"), "v"),
64-
new BusLegendInfo.Caption(valueFormatter.formatAngleInDegrees(b.getAngle()), "angle")
65-
)))
66-
.toList();
63+
.map(bus -> {
64+
List<BusLegendInfo.Caption> captions = new ArrayList<>(4);
65+
captions.add(new BusLegendInfo.Caption(valueFormatter.formatVoltage(bus.getV(), "kV"), "v"));
66+
captions.add(new BusLegendInfo.Caption(valueFormatter.formatAngleInDegrees(bus.getAngle()), "angle"));
67+
if (hasFictitiousInjection(bus.getFictitiousP0())) {
68+
captions.add(new BusLegendInfo.Caption(valueFormatter.formatPower(bus.getFictitiousP0(), withDefaultUnit(svgParameters.getActivePowerUnit(), "MW")), "fictitiousP0"));
69+
}
70+
if (hasFictitiousInjection(bus.getFictitiousQ0())) {
71+
captions.add(new BusLegendInfo.Caption(valueFormatter.formatPower(bus.getFictitiousQ0(), withDefaultUnit(svgParameters.getReactivePowerUnit(), "MVar")), "fictitiousQ0"));
72+
}
73+
return new BusLegendInfo(bus.getId(), captions);
74+
}).toList();
75+
}
76+
77+
private static boolean hasFictitiousInjection(double value) {
78+
return !Double.isNaN(value) && value != 0d;
79+
}
80+
81+
private static String withDefaultUnit(String configuredUnit, String defaultUnit) {
82+
return configuredUnit == null || configuredUnit.isEmpty() ? defaultUnit : configuredUnit;
6783
}
6884

6985
private void drawBusLegendInfo(BusLegendInfo busLegendInfo, double xShift, double yShift,
@@ -81,7 +97,9 @@ private void drawBusLegendInfo(BusLegendInfo busLegendInfo, double xShift, doubl
8197
g.appendChild(circle);
8298

8399
// legend nodes
84-
double padding = 2.5;
100+
boolean isExtendedLegend = busLegendInfo.captions().size() > 2;
101+
double padding = isExtendedLegend ? 2.0 : 2.5;
102+
double paddingStep = isExtendedLegend ? 1.0 : 1.5;
85103
for (BusLegendInfo.Caption caption : busLegendInfo.captions()) {
86104
Element label = g.getOwnerDocument().createElement("text");
87105
writeStyleClasses(label, styleProvider.getBusLegendCaptionStyles(caption), StyleClassConstants.BUS_LEGEND_INFO);
@@ -91,8 +109,7 @@ private void drawBusLegendInfo(BusLegendInfo busLegendInfo, double xShift, doubl
91109
Text textNode = g.getOwnerDocument().createTextNode(caption.label());
92110
label.appendChild(textNode);
93111
g.appendChild(label);
94-
95-
padding += 1.5;
112+
padding += paddingStep;
96113
}
97114
}
98115
}

single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestLegend.java

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
package com.powsybl.sld.iidm;
99

1010
import com.powsybl.diagram.test.Networks;
11-
import com.powsybl.iidm.network.Network;
11+
import com.powsybl.iidm.network.*;
1212
import com.powsybl.sld.builders.NetworkGraphBuilder;
1313
import com.powsybl.sld.model.graphs.VoltageLevelGraph;
14-
import com.powsybl.sld.svg.DefaultSVGLegendWriter;
15-
import com.powsybl.sld.svg.GraphMetadata;
16-
import com.powsybl.sld.svg.SVGLegendWriter;
17-
import com.powsybl.sld.svg.SvgParameters;
14+
import com.powsybl.sld.svg.*;
1815
import com.powsybl.sld.svg.styles.StyleProvider;
1916
import com.powsybl.sld.util.IdUtil;
2017
import org.junit.jupiter.api.BeforeEach;
@@ -24,6 +21,7 @@
2421
import java.io.IOException;
2522

2623
import static org.junit.jupiter.api.Assertions.assertEquals;
24+
import static org.junit.jupiter.api.Assertions.assertTrue;
2725

2826
/**
2927
* @author Slimane Amar {@literal <slimane.amar at rte-france.com>}
@@ -89,6 +87,53 @@ void testSpecificLegend() {
8987
assertEquals(toString("/TestLegendSpecific.svg"), toSVG(g, "/TestLegendSpecific.svg"));
9088
}
9189

90+
@Test
91+
void testLegendDisplaysBusFictitiousInjectionsWhenPresent() {
92+
svgParameters.setBusesLegendAdded(true);
93+
legendWriter = new DefaultSVGLegendWriter(network, svgParameters);
94+
VoltageLevel vl = network.getVoltageLevel("VoltageLevel1"); // BUS_BREAKER
95+
96+
// fictitious injections: Bus1
97+
vl.getBusBreakerView().getBus("Bus1")
98+
.setFictitiousP0(1)
99+
.setFictitiousQ0(-1);
100+
101+
// build graph
102+
VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph("VoltageLevel1");
103+
104+
// Run layout
105+
voltageLevelGraphLayout(g);
106+
107+
String svg = toSVG(g, "/TestLegendFictitiousInjection.svg");
108+
assertEquals(toString("/legend-fictitious-injection-bus-breaker.svg"), svg);
109+
assertTrue(svg.contains("1 MW"));
110+
assertTrue(svg.contains("-1 MVar"));
111+
}
112+
113+
@Test
114+
void testLegendDisplaysNodeFictitiousInjectionsWhenPresent() {
115+
svgParameters.setBusesLegendAdded(true);
116+
network = Networks.createBusbarLoadNetwork(); // NODE_BREAKER
117+
legendWriter = new DefaultSVGLegendWriter(network, svgParameters);
118+
graphBuilder = new NetworkGraphBuilder(network);
119+
VoltageLevel vl = network.getVoltageLevel("VoltageLevel1");
120+
121+
// fictitious injections: node 1
122+
vl.getNodeBreakerView()
123+
.setFictitiousP0(1, 1)
124+
.setFictitiousQ0(1, -1.0);
125+
126+
// build graph
127+
VoltageLevelGraph g = graphBuilder.buildVoltageLevelGraph("VoltageLevel1");
128+
// Run layout
129+
voltageLevelGraphLayout(g);
130+
131+
String svg = toSVG(g, "/TestLegendFictitiousInjection.svg");
132+
assertEquals(toString("/legend-fictitious-injection-node-breaker.svg"), svg);
133+
assertTrue(svg.contains("1 MW"));
134+
assertTrue(svg.contains("-1 MVar"));
135+
}
136+
92137
@Override
93138
protected SVGLegendWriter getDefaultSVGLegendWriter() {
94139
return legendWriter;
Lines changed: 206 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)