Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ public CustomLabelProvider(Map<String, BranchLabels> branchLabels, Map<String, T
}

@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
public List<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
BranchLabels bl = this.branchLabels.get(edge.getEquipmentId());
String label = null;
EdgeInfo.Direction arrowDirection = null;
if (bl != null) {
label = side == BranchEdge.Side.ONE ? bl.side1 : bl.side2;
arrowDirection = side == BranchEdge.Side.ONE ? bl.arrow1 : bl.arrow2;
}
return Optional.of(new EdgeInfo("Custom", arrowDirection, null, label));
return List.of(new EdgeInfo("Custom", arrowDirection, null, label));
}

@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
public List<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
ThreeWtLabels threeWtLabels1 = threeWtLabels.get(edge.getEquipmentId());
ThreeWtEdge.Side edgeSide = edge.getSide();
String labelSide = null;
Expand All @@ -95,7 +95,7 @@ public Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
}
}
}
return Optional.of(new EdgeInfo("Custom", arrowDirection, null, labelSide));
return List.of(new EdgeInfo("Custom", arrowDirection, null, labelSide));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
import com.powsybl.nad.model.*;

import java.util.List;
import java.util.Optional;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
*/
public interface LabelProvider {
Optional<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side);
List<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side);

Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge);
List<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge);

String getLabel(Edge edge);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class SvgParameters {
private int powerValuePrecision = 0;
private int angleValuePrecision = 1;
private int currentValuePrecision = 0;
private EdgeInfoEnum edgeInfoDisplayed = EdgeInfoEnum.ACTIVE_POWER;
private EdgeInfoEnum[] edgeInfoDisplayed = {EdgeInfoEnum.ACTIVE_POWER};
private double pstArrowHeadSize = 8;
private String undefinedValueSymbol = "";
private boolean highlightGraph;
Expand Down Expand Up @@ -465,11 +465,11 @@ public enum EdgeInfoEnum {
CURRENT;
}

public EdgeInfoEnum getEdgeInfoDisplayed() {
public EdgeInfoEnum[] getEdgeInfoDisplayed() {
return this.edgeInfoDisplayed;
}

public SvgParameters setEdgeInfoDisplayed(EdgeInfoEnum edgeInfoDisplayed) {
public SvgParameters setEdgeInfoDisplayed(EdgeInfoEnum[] edgeInfoDisplayed) {
this.edgeInfoDisplayed = edgeInfoDisplayed;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,24 +283,22 @@ private void drawHalfEdge(Graph graph, XMLStreamWriter writer, BranchEdge edge,
writer.writeAttribute(ID_ATTRIBUTE, getPrefixedId(edge.getDiagramId() + "." + side.getNum()));
writeStyleClasses(writer, styleProvider.getSideEdgeStyleClasses(edge, side));
if (edge.isVisible(side)) {
Optional<EdgeInfo> edgeInfo = labelProvider.getEdgeInfo(graph, edge, side);
List<EdgeInfo> edgeInfo = labelProvider.getEdgeInfo(graph, edge, side);
if (!graph.isLoop(edge)) {
drawHalfEdge(graph, writer, edge, side, edgeInfo.orElse(null));
drawHalfEdge(graph, writer, edge, side, edgeInfo);
} else {
drawLoopEdge(writer, edge, side, edgeInfo.orElse(null));
drawLoopEdge(writer, edge, side, edgeInfo);
}
}
writer.writeEndElement();
}

private void drawHalfEdge(Graph graph, XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, EdgeInfo edgeInfo) throws XMLStreamException {
private void drawHalfEdge(Graph graph, XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, List<EdgeInfo> edgeInfo) throws XMLStreamException {
writer.writeEmptyElement(POLYLINE_ELEMENT_NAME);
writeStyleClasses(writer, StyleProvider.EDGE_PATH_CLASS);
writeStyleAttribute(writer, styleProvider.getSideEdgeStyle(edge, side));
writer.writeAttribute(POINTS_ATTRIBUTE, getPolylinePointsString(edge, side));
if (edgeInfo != null) {
drawBranchEdgeInfo(graph, writer, edge, side, edgeInfo);
}
drawBranchEdgeInfo(graph, writer, edge, side, edgeInfo);
}

private void drawHighlightHalfEdge(Graph graph, XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side) throws XMLStreamException {
Expand All @@ -315,14 +313,12 @@ private void drawHighlightHalfEdge(XMLStreamWriter writer, BranchEdge edge, Bran
writer.writeAttribute(POINTS_ATTRIBUTE, getPolylinePointsString(edge, side));
}

private void drawLoopEdge(XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, EdgeInfo edgeInfo) throws XMLStreamException {
private void drawLoopEdge(XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, List<EdgeInfo> edgeInfo) throws XMLStreamException {
writer.writeEmptyElement(PATH_ELEMENT_NAME);
writer.writeAttribute(CLASS_ATTRIBUTE, StyleProvider.EDGE_PATH_CLASS);
writer.writeAttribute(PATH_D_ATTRIBUTE, getLoopPathString(edge, side));
writeStyleAttribute(writer, styleProvider.getSideEdgeStyle(edge, side));
if (edgeInfo != null) {
drawLoopEdgeInfo(writer, edge, side, edgeInfo);
}
drawLoopEdgeInfo(writer, edge, side, edgeInfo);
}

private String getPolylinePointsString(BranchEdge edge, BranchEdge.Side side) {
Expand Down Expand Up @@ -357,10 +353,8 @@ private void drawThreeWtEdge(Graph graph, XMLStreamWriter writer, ThreeWtEdge ed
writeStyleAttribute(writer, styleProvider.getThreeWtEdgeStyle(edge));
writer.writeAttribute(POINTS_ATTRIBUTE, getPolylinePointsString(edge));

Optional<EdgeInfo> edgeInfo = labelProvider.getEdgeInfo(graph, edge);
if (edgeInfo.isPresent()) {
drawThreeWtEdgeInfo(graph, writer, edge, edgeInfo.get());
}
List<EdgeInfo> edgeInfo = labelProvider.getEdgeInfo(graph, edge);
drawThreeWtEdgeInfo(graph, writer, edge, edgeInfo);
writer.writeEndElement();
}

Expand Down Expand Up @@ -435,83 +429,70 @@ private void drawPstArrow(XMLStreamWriter writer, ThreeWtNode threeWtNode, Three
writeStyleAttribute(writer, styleProvider.getThreeWtEdgeStyle(edge));
}

private void drawLoopEdgeInfo(XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, EdgeInfo edgeInfo) throws XMLStreamException {
private void drawLoopEdgeInfo(XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, List<EdgeInfo> edgeInfo) throws XMLStreamException {
drawEdgeInfo(writer, edgeInfo, edge.getPoints(side).get(1), edge.getEdgeStartAngle(side));
}

private void drawBranchEdgeInfo(Graph graph, XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, EdgeInfo edgeInfo) throws XMLStreamException {
private void drawBranchEdgeInfo(Graph graph, XMLStreamWriter writer, BranchEdge edge, BranchEdge.Side side, List<EdgeInfo> edgeInfo) throws XMLStreamException {
VoltageLevelNode vlNode = graph.getVoltageLevelNode(edge, side);
BusNode busNode = graph.getBusGraphNode(edge, side);
drawEdgeInfo(writer, edgeInfo, getArrowCenter(vlNode, busNode, edge.getPoints(side)), edge.getEdgeEndAngle(side));
drawEdgeInfo(writer, edgeInfo, getArrowCenter(vlNode, busNode, edge.getPoints(side)), edge.getEdgeStartAngle(side));
}

private void drawThreeWtEdgeInfo(Graph graph, XMLStreamWriter writer, ThreeWtEdge edge, EdgeInfo edgeInfo) throws XMLStreamException {
private void drawThreeWtEdgeInfo(Graph graph, XMLStreamWriter writer, ThreeWtEdge edge, List<EdgeInfo> edgeInfo) throws XMLStreamException {
VoltageLevelNode vlNode = graph.getVoltageLevelNode(edge);
BusNode busNode = graph.getBusGraphNode(edge);
drawEdgeInfo(writer, edgeInfo, getArrowCenter(vlNode, busNode, edge.getPoints()), edge.getEdgeAngle());
}

private void drawEdgeInfo(XMLStreamWriter writer, EdgeInfo edgeInfo, Point infoCenter, double edgeAngle) throws XMLStreamException {
private void drawEdgeInfo(XMLStreamWriter writer, List<EdgeInfo> edgeInfo, Point infoCenter, double edgeAngle) throws XMLStreamException {
drawEdgeInfo(writer, Collections.emptyList(), edgeInfo, infoCenter, edgeAngle);
}

private void drawEdgeInfo(XMLStreamWriter writer, List<String> additionalStyles, EdgeInfo edgeInfo, Point infoCenter, double edgeAngle) throws XMLStreamException {
private void drawEdgeInfo(XMLStreamWriter writer, List<String> additionalStyles, List<EdgeInfo> edgeInfo, Point infoCenter, double edgeAngle) throws XMLStreamException {

writer.writeStartElement(GROUP_ELEMENT_NAME);
writeStyleClasses(writer, additionalStyles, StyleProvider.EDGE_INFOS_CLASS);
writer.writeAttribute(TRANSFORM_ATTRIBUTE, getTranslateString(infoCenter));

writer.writeStartElement(GROUP_ELEMENT_NAME);
writeStyleClasses(writer, styleProvider.getEdgeInfoStyleClasses(edgeInfo));
drawInAndOutArrows(writer, edgeAngle);
Optional<String> externalLabel = edgeInfo.getExternalLabel();
if (externalLabel.isPresent()) {
drawLabel(writer, externalLabel.get(), edgeAngle, true);
}
Optional<String> internalLabel = edgeInfo.getInternalLabel();
if (internalLabel.isPresent()) {
drawLabel(writer, internalLabel.get(), edgeAngle, false);
}
writer.writeEndElement();

writer.writeEndElement();
}
for (int i = 0; i < edgeInfo.size(); i++) {
EdgeInfo info = edgeInfo.get(i);
writer.writeStartElement(GROUP_ELEMENT_NAME);
writeStyleClasses(writer, styleProvider.getEdgeInfoStyleClasses(info));

private void drawInAndOutArrows(XMLStreamWriter writer, double edgeAngle) throws XMLStreamException {
double rotationAngle = edgeAngle + (edgeAngle > Math.PI / 2 ? -3 * Math.PI / 2 : Math.PI / 2);
writer.writeStartElement(GROUP_ELEMENT_NAME);
writer.writeAttribute(TRANSFORM_ATTRIBUTE, getRotateString(rotationAngle));
writer.writeEmptyElement(PATH_ELEMENT_NAME);
writer.writeAttribute(CLASS_ATTRIBUTE, StyleProvider.ARROW_IN_CLASS);
writer.writeAttribute(TRANSFORM_ATTRIBUTE, getScaleString(svgParameters.getArrowHeight()));
writer.writeAttribute(PATH_D_ATTRIBUTE, labelProvider.getArrowPathDIn());
writer.writeEmptyElement(PATH_ELEMENT_NAME);
writer.writeAttribute(CLASS_ATTRIBUTE, StyleProvider.ARROW_OUT_CLASS);
writer.writeAttribute(TRANSFORM_ATTRIBUTE, getScaleString(svgParameters.getArrowHeight()));
writer.writeAttribute(PATH_D_ATTRIBUTE, labelProvider.getArrowPathDOut());
Optional<String> externalLabel = info.getExternalLabel();
if (externalLabel.isPresent()) {
drawLabel(writer, i, externalLabel.get(), edgeAngle, true);
}
Optional<String> internalLabel = info.getInternalLabel();
if (internalLabel.isPresent()) {
drawLabel(writer, i, internalLabel.get(), edgeAngle, false);
}
writer.writeEndElement();
}
writer.writeEndElement();
}

private void drawLabel(XMLStreamWriter writer, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
private void drawLabel(XMLStreamWriter writer, int index, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
if (svgParameters.isEdgeInfoAlongEdge()) {
drawLabelAlongEdge(writer, label, edgeAngle, externalLabel);
drawLabelAlongEdge(writer, index, label, edgeAngle, externalLabel);
} else {
drawLabelPerpendicularToEdge(writer, label, edgeAngle, externalLabel);
drawLabelPerpendicularToEdge(writer, index, label, edgeAngle, externalLabel);
}
}

private void drawLabelAlongEdge(XMLStreamWriter writer, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
private void drawLabelAlongEdge(XMLStreamWriter writer, int index, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
boolean textFlipped = Math.cos(edgeAngle) < 0;
String style = externalLabel == textFlipped ? "text-anchor:end" : null;
double textAngle = textFlipped ? edgeAngle - Math.PI : edgeAngle;
double shift = svgParameters.getArrowLabelShift() * (externalLabel ? 1 : -1);
drawLabel(writer, label, textFlipped ? -shift : shift, style, textAngle, X_ATTRIBUTE);
}

private void drawLabelPerpendicularToEdge(XMLStreamWriter writer, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
private void drawLabelPerpendicularToEdge(XMLStreamWriter writer, int index, String label, double edgeAngle, boolean externalLabel) throws XMLStreamException {
boolean textFlipped = Math.sin(edgeAngle) > 0;
double textAngle = textFlipped ? -Math.PI / 2 + edgeAngle : Math.PI / 2 + edgeAngle;
double shift = svgParameters.getArrowLabelShift();
double shift = index * 0.5 * svgParameters.getArrowLabelShift();
double shiftAdjusted = externalLabel == textFlipped ? shift * 1.15 : -shift; // to have a nice compact rendering, shift needs to be adjusted, because of dominant-baseline:middle (text is expected to be a number, hence not below the line)
drawLabel(writer, label, shiftAdjusted, "text-anchor:middle", textAngle, Y_ATTRIBUTE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
import com.powsybl.nad.svg.EdgeInfo;
import com.powsybl.nad.svg.LabelProvider;
import com.powsybl.nad.svg.SvgParameters;
import com.powsybl.nad.svg.SvgParameters.EdgeInfoEnum;
import com.powsybl.nad.utils.iidm.IidmUtils;
import com.powsybl.nad.utils.svg.SvgUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
Expand All @@ -35,13 +35,13 @@ public DefaultLabelProvider(Network network, SvgParameters svgParameters) {
}

@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
public List<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
Terminal terminal = IidmUtils.getTerminalFromEdge(network, edge, side);
return getEdgeInfo(terminal);
}

@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
public List<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
ThreeWindingsTransformer transformer = network.getThreeWindingsTransformer(edge.getEquipmentId());
if (transformer == null) {
throw new PowsyblException("Unknown three windings transformer '" + edge.getEquipmentId() + "'");
Expand All @@ -55,20 +55,28 @@ public String getLabel(Edge edge) {
return svgParameters.isEdgeNameDisplayed() ? edge.getEquipmentId() : null;
}

private Optional<EdgeInfo> getEdgeInfo(Terminal terminal) {
private List<EdgeInfo> getEdgeInfo(Terminal terminal) {
if (terminal == null) {
return Optional.empty();
return List.of();
}
switch (svgParameters.getEdgeInfoDisplayed()) {
case ACTIVE_POWER:
return Optional.of(new EdgeInfo(EdgeInfo.ACTIVE_POWER, terminal.getP(), valueFormatter::formatPower));
case REACTIVE_POWER:
return Optional.of(new EdgeInfo(EdgeInfo.REACTIVE_POWER, terminal.getQ(), valueFormatter::formatPower));
case CURRENT:
return Optional.of(new EdgeInfo(EdgeInfo.CURRENT, terminal.getI(), valueFormatter::formatCurrent));
default:
return Optional.empty();
List<EdgeInfo> edgeInfos = new ArrayList<>();
EdgeInfoEnum[] infos = svgParameters.getEdgeInfoDisplayed();
for (EdgeInfoEnum info : infos) {
switch (info) {
case ACTIVE_POWER:
edgeInfos.add(new EdgeInfo(EdgeInfo.ACTIVE_POWER, terminal.getP(), valueFormatter::formatPower));
break;
case REACTIVE_POWER:
edgeInfos.add(new EdgeInfo(EdgeInfo.REACTIVE_POWER, terminal.getQ(), valueFormatter::formatPower));
break;
case CURRENT:
edgeInfos.add(new EdgeInfo(EdgeInfo.CURRENT, terminal.getI(), valueFormatter::formatCurrent));
break;
default:
break;
}
}
return List.copyOf(edgeInfos);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
import com.powsybl.nad.model.BranchEdge;
import com.powsybl.nad.model.Graph;
import com.powsybl.nad.model.ThreeWtEdge;
import com.powsybl.nad.svg.SvgParameters.EdgeInfoEnum;
import com.powsybl.nad.svg.iidm.DefaultLabelProvider;
import com.powsybl.nad.svg.iidm.NominalVoltageStyleProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Optional;
import java.util.List;

/**
* @author Florian Dupuy {@literal <florian.dupuy at rte-france.com>}
Expand All @@ -46,13 +47,13 @@ protected StyleProvider getStyleProvider(Network network) {
protected LabelProvider getLabelProvider(Network network) {
return new DefaultLabelProvider(network, getSvgParameters()) {
@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
return Optional.of(new EdgeInfo("test", EdgeInfo.Direction.OUT, internalLabel, externalLabel));
public List<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
return List.of(new EdgeInfo("test", EdgeInfo.Direction.OUT, internalLabel, externalLabel));
}

@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
return Optional.of(new EdgeInfo("test", EdgeInfo.Direction.IN, internalLabel, externalLabel));
public List<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
return List.of(new EdgeInfo("test", EdgeInfo.Direction.IN, internalLabel, externalLabel));
}

@Override
Expand Down Expand Up @@ -94,4 +95,17 @@ void testParallelLabels() {
.setArrowLabelShift(20);
assertSvgEquals("/edge_info_double_labels.svg", network);
}

@Test
void testMultiplePerpendicularLabels() {
Network network = Networks.createTwoVoltageLevels();
internalLabel = "int";
externalLabel = null;
EdgeInfoEnum[] infos = {EdgeInfoEnum.CURRENT, EdgeInfoEnum.ACTIVE_POWER, EdgeInfoEnum.REACTIVE_POWER};
getSvgParameters().setEdgeInfoAlongEdge(false)
.setEdgeInfoDisplayed(infos)
.setArrowShift(50)
.setArrowLabelShift(25);
assertSvgEquals("/edge_info_perpendicular_label.svg", network);
}
}
Loading
Loading