Skip to content
Merged
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 @@ -10,6 +10,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.RawValue;
import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.config.BaseVoltageConfig;
import com.powsybl.commons.config.BaseVoltagesConfig;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Substation;
import com.powsybl.iidm.network.VoltageLevel;
Expand All @@ -36,6 +38,7 @@
import com.powsybl.sld.server.repository.NadVoltageLevelConfiguredPositionRepository;
import com.powsybl.sld.server.utils.DiagramUtils;
import com.powsybl.sld.server.utils.CsvFileValidator;
import com.powsybl.sld.server.utils.DiagramConstants;
import com.powsybl.sld.server.utils.NadPositionsGenerationMode;
import com.powsybl.sld.server.utils.ResourceUtils;
import com.powsybl.sld.server.utils.TopologicalStyleProvider;
Expand Down Expand Up @@ -260,7 +263,7 @@ public String generateNetworkAreaDiagramSvg(UUID networkUuid, String variantId,
);

// Build Powsybl parameters
buildGraphicalParameters(nadGenerationContext, nadRequestInfos.getCurrentLimitViolationsInfos());
buildGraphicalParameters(nadGenerationContext, nadRequestInfos.getCurrentLimitViolationsInfos(), nadRequestInfos.getBaseVoltagesConfigInfos());

int nbVoltageLevels = nadGenerationContext.getVoltageLevelIds().size();
if (nbVoltageLevels > maxVoltageLevels) {
Expand All @@ -270,7 +273,7 @@ public String generateNetworkAreaDiagramSvg(UUID networkUuid, String variantId,
return processSvgAndMetadata(drawSvgAndBuildMetadata(nadGenerationContext));
}

private void buildGraphicalParameters(NadGenerationContext nadGenerationContext, List<CurrentLimitViolationInfos> currentLimitViolationInfos) {
private void buildGraphicalParameters(NadGenerationContext nadGenerationContext, List<CurrentLimitViolationInfos> currentLimitViolationInfos, List<BaseVoltageConfig> baseVoltagesConfigInfos) {

if (nadGenerationContext.getVoltageLevelIds().isEmpty()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "no voltage level was found");
Expand All @@ -286,7 +289,17 @@ private void buildGraphicalParameters(NadGenerationContext nadGenerationContext,
nadParameters.setSvgParameters(svgParameters);
nadParameters.setLayoutParameters(layoutParameters);
Map<String, String> limitViolationStyles = DiagramUtils.createLimitViolationStyles(currentLimitViolationInfos, StyleProvider.LINE_OVERLOADED_CLASS);
nadParameters.setStyleProviderFactory(n -> new TopologicalStyleProvider(nadGenerationContext.getNetwork(), limitViolationStyles));

baseVoltagesConfigInfos.forEach(vl -> vl.setProfile(DiagramConstants.BASE_VOLTAGES_DEFAULT_PROFILE));
BaseVoltagesConfig baseVoltagesConfig = new BaseVoltagesConfig();
baseVoltagesConfig.setBaseVoltages(baseVoltagesConfigInfos);
baseVoltagesConfig.setDefaultProfile(DiagramConstants.BASE_VOLTAGES_DEFAULT_PROFILE);

nadParameters.setStyleProviderFactory(n -> new TopologicalStyleProvider(
nadGenerationContext.getNetwork(),
baseVoltagesConfig,
limitViolationStyles
));

// Set style provider factory either with geographical data or with the provided positions (if any)
if (nadGenerationContext.getNadPositionsGenerationMode() == NadPositionsGenerationMode.GEOGRAPHICAL_COORDINATES && nadGenerationContext.getPositions().isEmpty()) {
Expand Down
137 changes: 13 additions & 124 deletions src/main/java/com/powsybl/sld/server/SingleLineDiagramController.java

Large diffs are not rendered by default.

73 changes: 41 additions & 32 deletions src/main/java/com/powsybl/sld/server/SingleLineDiagramService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.powsybl.sld.server;

import com.powsybl.commons.PowsyblException;
import com.powsybl.commons.config.BaseVoltagesConfig;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Substation;
Expand Down Expand Up @@ -65,13 +66,13 @@ public static Network getNetwork(UUID networkUuid, String variantId, NetworkStor

private static SubstationLayoutFactory getSubstationLayoutFactory(String substationLayout) {
return switch (substationLayout) {
case "horizontal" -> new HorizontalSubstationLayoutFactory();
case "vertical" -> new VerticalSubstationLayoutFactory();
case DiagramConstants.SUBSTATION_LAYOUT_HORIZONTAL -> new HorizontalSubstationLayoutFactory();
case DiagramConstants.SUBSTATION_LAYOUT_VERTICAL -> new VerticalSubstationLayoutFactory();
default -> throw new PowsyblException("Substation layout " + substationLayout + " incorrect");
};
}

SvgAndMetadata generateSvgAndMetadata(UUID networkUuid, String variantId, String id, SingleLineDiagramParameters diagParams, SvgGenerationMetadata svgGenerationMetadata) {
SvgAndMetadata generateSvgAndMetadata(UUID networkUuid, String variantId, String id, SldRequestInfos sldRequestInfos) {
Network network = getNetwork(networkUuid, variantId, networkStoreService);
if (network.getVoltageLevel(id) == null && network.getSubstation(id) == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Voltage level or substation " + id + " not found");
Expand All @@ -80,52 +81,60 @@ SvgAndMetadata generateSvgAndMetadata(UUID networkUuid, String variantId, String
try (var svgWriter = new StringWriter();
var metadataWriter = new StringWriter()) {

SldComponentLibrary compLibrary = SldComponentLibrary.find(diagParams.getComponentLibrary())
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Component library '" + diagParams.getComponentLibrary() + "' not found"));
SldComponentLibrary compLibrary = SldComponentLibrary.find(sldRequestInfos.getComponentLibrary())
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Component library '" + sldRequestInfos.getComponentLibrary() + "' not found"));

SvgParameters svgParameters = new SvgParameters(SVG_PARAMETERS);
svgParameters.setLabelCentered(diagParams.isLabelCentered());
svgParameters.setLabelDiagonal(diagParams.isDiagonalLabel());
svgParameters.setUseName(diagParams.isUseName());
svgParameters.setLabelCentered(sldRequestInfos.isCenterLabel());
svgParameters.setLabelDiagonal(sldRequestInfos.isDiagonalLabel());
svgParameters.setUseName(sldRequestInfos.isUseName());
svgParameters.setUndefinedValueSymbol("\u2014");
svgParameters.setLanguageTag(diagParams.getLanguage());
svgParameters.setLanguageTag(sldRequestInfos.getLanguage());
svgParameters.setUnifyVoltageLevelColors(true);
LayoutParameters layoutParameters = new LayoutParameters(LAYOUT_PARAMETERS);

SldParameters sldParameters = new SldParameters();

if (diagParams.getSldDisplayMode() == SldDisplayMode.FEEDER_POSITION) {
svgParameters.setBusesLegendAdded(false);
svgParameters.setLabelDiagonal(true);
sldParameters.setLabelProviderFactory(PositionDiagramLabelProvider.newLabelProviderFactory(id));
} else if (diagParams.getSldDisplayMode() == SldDisplayMode.STATE_VARIABLE) {
svgParameters.setBusesLegendAdded(true);
sldParameters.setLabelProviderFactory(CommonLabelProvider.newCommonLabelProviderFactory(svgGenerationMetadata != null ? svgGenerationMetadata.getBusIdToIccValues() : null));
} else {
throw new PowsyblException(String.format("Given sld display mode %s doesn't exist", diagParams.getSldDisplayMode()));
switch (sldRequestInfos.getSldDisplayMode()) {
case SldDisplayMode.FEEDER_POSITION:
svgParameters.setBusesLegendAdded(false);
svgParameters.setLabelDiagonal(true);
sldParameters.setLabelProviderFactory(PositionDiagramLabelProvider.newLabelProviderFactory(id));
break;
case SldDisplayMode.STATE_VARIABLE:
svgParameters.setBusesLegendAdded(true);
sldParameters.setLabelProviderFactory(CommonLabelProvider.newCommonLabelProviderFactory(sldRequestInfos.getBusIdToIccValues()));
break;
default:
throw new PowsyblException(String.format("Given sld display mode %s doesn't exist", sldRequestInfos.getSldDisplayMode()));
}

var voltageLevelLayoutFactory = CustomVoltageLevelLayoutFactoryCreator.newCustomVoltageLevelLayoutFactoryCreator();
var substationLayoutFactory = getSubstationLayoutFactory(diagParams.getSubstationLayout());
var substationLayoutFactory = getSubstationLayoutFactory(sldRequestInfos.getSubstationLayout());

sldParameters.setSvgParameters(svgParameters);
sldParameters.setSubstationLayoutFactory(substationLayoutFactory);
sldParameters.setVoltageLevelLayoutFactoryCreator(voltageLevelLayoutFactory);
sldParameters.setLayoutParameters(layoutParameters);

Map<String, String> limitViolationStyles = DiagramUtils.createLimitViolationStyles(svgGenerationMetadata != null ? svgGenerationMetadata.getCurrentLimitViolationInfos() : null, OVERLOAD_STYLE_CLASS);

sldParameters.setStyleProviderFactory((net, parameters) ->
diagParams.isTopologicalColoring()
? new StyleProvidersList(new TopologicalStyleProvider(network, parameters),
new HighlightLineStateStyleProvider(network),
new LimitHighlightStyleProvider(network, limitViolationStyles),
new BusLegendStyleProvider())
: new StyleProvidersList(new NominalVoltageStyleProvider(),
new HighlightLineStateStyleProvider(network),
new LimitHighlightStyleProvider(network, limitViolationStyles),
new BusLegendStyleProvider())
);
Map<String, String> limitViolationStyles = DiagramUtils.createLimitViolationStyles(sldRequestInfos.getCurrentLimitViolationsInfos(), OVERLOAD_STYLE_CLASS);

sldParameters.setStyleProviderFactory((net, parameters) -> {
sldRequestInfos.getBaseVoltagesConfigInfos().forEach(vl -> vl.setProfile(DiagramConstants.BASE_VOLTAGES_DEFAULT_PROFILE));
BaseVoltagesConfig baseVoltagesConfig = new BaseVoltagesConfig();
baseVoltagesConfig.setBaseVoltages(sldRequestInfos.getBaseVoltagesConfigInfos());
baseVoltagesConfig.setDefaultProfile(DiagramConstants.BASE_VOLTAGES_DEFAULT_PROFILE);

return new StyleProvidersList(
sldRequestInfos.isTopologicalColoring()
? new TopologicalStyleProvider(baseVoltagesConfig, network, parameters)
: new NominalVoltageStyleProvider(baseVoltagesConfig),
new HighlightLineStateStyleProvider(network),
new LimitHighlightStyleProvider(network, limitViolationStyles),
new BusLegendStyleProvider()
);
});

sldParameters.setComponentLibrary(compLibrary);

SingleLineDiagram.draw(network, id, svgWriter, metadataWriter, sldParameters);
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/com/powsybl/sld/server/dto/SldRequestInfos.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright (c) 2025, 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/.
*/
package com.powsybl.sld.server.dto;

import java.util.List;
import java.util.Map;

import com.powsybl.commons.config.BaseVoltageConfig;
import com.powsybl.sld.server.GridSuiteAndConvergenceComponentLibrary;
import com.powsybl.sld.server.utils.DiagramConstants;
import com.powsybl.sld.server.utils.SldDisplayMode;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* @author Caroline Jeandat <caroline.jeandat at rte-france.com>
*/
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class SldRequestInfos {
private boolean useName = false;
private boolean centerLabel = false;
private boolean diagonalLabel = false;
private boolean topologicalColoring = false;
private String componentLibrary = GridSuiteAndConvergenceComponentLibrary.NAME;
private String substationLayout = DiagramConstants.SUBSTATION_LAYOUT_HORIZONTAL;
private SldDisplayMode sldDisplayMode = SldDisplayMode.STATE_VARIABLE;
private String language = "en";
private List<CurrentLimitViolationInfos> currentLimitViolationsInfos;
private List<BaseVoltageConfig> baseVoltagesConfigInfos;
Map<String, Double> busIdToIccValues;

public void setComponentLibrary(String componentLibrary) {
this.componentLibrary = (componentLibrary == null || componentLibrary.isBlank())
? GridSuiteAndConvergenceComponentLibrary.NAME
: componentLibrary;
}

public void setSubstationLayout(String substationLayout) {
this.substationLayout = (substationLayout == null || substationLayout.isBlank())
? DiagramConstants.SUBSTATION_LAYOUT_HORIZONTAL
: substationLayout;
}

public void setSldDisplayMode(SldDisplayMode sldDisplayMode) {
this.sldDisplayMode = (sldDisplayMode == null)
? SldDisplayMode.STATE_VARIABLE
: sldDisplayMode;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.powsybl.sld.server.dto.nad;

import com.powsybl.commons.config.BaseVoltageConfig;
import com.powsybl.sld.server.dto.CurrentLimitViolationInfos;
import com.powsybl.sld.server.utils.NadPositionsGenerationMode;
import lombok.*;
Expand All @@ -31,4 +32,5 @@ public class NadRequestInfos {
private NadPositionsGenerationMode nadPositionsGenerationMode;
private UUID nadPositionsConfigUuid;
private List<CurrentLimitViolationInfos> currentLimitViolationsInfos;
private List<BaseVoltageConfig> baseVoltagesConfigInfos;
}
19 changes: 19 additions & 0 deletions src/main/java/com/powsybl/sld/server/utils/DiagramConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2025, 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/.
*/
package com.powsybl.sld.server.utils;

/**
* @author Caroline Jeandat <caroline.jeandat at rte-france.com>
*/
public final class DiagramConstants {
private DiagramConstants() {
}

public static final String SUBSTATION_LAYOUT_HORIZONTAL = "horizontal";
public static final String SUBSTATION_LAYOUT_VERTICAL = "vertical";
public static final String BASE_VOLTAGES_DEFAULT_PROFILE = "Default";
}

This file was deleted.

Loading