Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CGMES GL import #2992

Merged
merged 11 commits into from
May 2, 2024
5 changes: 5 additions & 0 deletions cgmes/cgmes-gl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<artifactId>powsybl-config-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>powsybl-triple-store-impl-rdf4j</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ private void addModel(ExportContext context) {
private void addCoordinateSystem(ExportContext context) {
PropertyBag coordinateSystemProperties = new PropertyBag(Arrays.asList(IDENTIFIED_OBJECT_NAME, "crsUrn"), true);
coordinateSystemProperties.setClassPropertyNames(Collections.singletonList(IDENTIFIED_OBJECT_NAME));
coordinateSystemProperties.put(IDENTIFIED_OBJECT_NAME, CgmesGLUtils.COORDINATE_SYSTEM_NAME);
coordinateSystemProperties.put("crsUrn", CgmesGLUtils.COORDINATE_SYSTEM_URN);
context.setCoordinateSystemId(tripleStore.add(context.getGlContext(), CgmesNamespace.CIM_16_NAMESPACE, "CoordinateSystem", coordinateSystemProperties));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
*/
public final class CgmesGLUtils {

public static final String COORDINATE_SYSTEM_NAME = "WGS84";
/**
* Coordinate system URN for WGS84
*/
public static final String COORDINATE_SYSTEM_URN = "urn:ogc:def:crs:EPSG::4326";

private CgmesGLUtils() {
}

public static boolean checkCoordinateSystem(String crsName, String crsUrn) {
return COORDINATE_SYSTEM_NAME.equals(crsName) && COORDINATE_SYSTEM_URN.equals(crsUrn);
public static boolean checkCoordinateSystem(String crsUrn) {
return COORDINATE_SYSTEM_URN.equals(crsUrn);
}

public static String contextNameFor(CgmesSubset subset, TripleStore tripleStore, String modelId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
package com.powsybl.cgmes.gl;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.DanglingLine;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Network;
import com.powsybl.triplestore.api.PropertyBag;
import com.powsybl.iidm.network.extensions.Coordinate;
import com.powsybl.iidm.network.extensions.LinePositionAdder;
import com.powsybl.triplestore.api.PropertyBag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,46 +37,36 @@ public LinePositionImporter(Network network, CgmesGLModel cgmesGLModel) {
}

public void importPosition() {
Map<Line, SortedMap<Integer, Coordinate>> lineCoordinates = new HashMap<>();
Map<DanglingLine, SortedMap<Integer, Coordinate>> danglingLineCoordinates = new HashMap<>();

cgmesGLModel.getLinesPositions().forEach(propertyBag -> importPosition(propertyBag, lineCoordinates, danglingLineCoordinates));
Map<Identifiable<?>, SortedMap<Integer, Coordinate>> lineOrDanglingLineCoordinates = new HashMap<>();

for (Map.Entry<Line, SortedMap<Integer, Coordinate>> e : lineCoordinates.entrySet()) {
Line line = e.getKey();
SortedMap<Integer, Coordinate> coordinates = e.getValue();
line.newExtension(LinePositionAdder.class).withCoordinates(new ArrayList<>(coordinates.values())).add();
}
cgmesGLModel.getLinesPositions().forEach(propertyBag -> importPosition(propertyBag, lineOrDanglingLineCoordinates));

for (Map.Entry<DanglingLine, SortedMap<Integer, Coordinate>> e : danglingLineCoordinates.entrySet()) {
DanglingLine danglingLine = e.getKey();
SortedMap<Integer, Coordinate> coordinates = e.getValue();
danglingLine.newExtension(LinePositionAdder.class).withCoordinates(new ArrayList<>(coordinates.values())).add();
}
lineOrDanglingLineCoordinates.forEach((lOrDl, coordinates) ->
lOrDl.newExtension(LinePositionAdder.class).withCoordinates(coordinates.values().stream().toList()).add());
}

private void importPosition(PropertyBag linePositionData, Map<Line, SortedMap<Integer, Coordinate>> lineCoordinates,
Map<DanglingLine, SortedMap<Integer, Coordinate>> danglingLineCoordinates) {
private void importPosition(PropertyBag linePositionData, Map<Identifiable<?>, SortedMap<Integer, Coordinate>> lineOrDanglingLineCoordinates) {
Objects.requireNonNull(linePositionData);
if (!CgmesGLUtils.checkCoordinateSystem(linePositionData.getId("crsName"), linePositionData.getId("crsUrn"))) {
throw new PowsyblException("Unsupported coodinates system: " + linePositionData.getId("crsName"));
String crsUrn = linePositionData.getId("crsUrn");
if (!CgmesGLUtils.checkCoordinateSystem(crsUrn)) {
throw new PowsyblException("Unsupported coordinates system: " + crsUrn);
}
String lineId = linePositionData.getId("powerSystemResource");
Line line = network.getLine(lineId);
if (line != null) {
lineCoordinates.computeIfAbsent(line, k -> new TreeMap<>())
Identifiable<?> lineOrDanglingLine = getLineOrDanglingLine(lineId);
if (lineOrDanglingLine != null) {
lineOrDanglingLineCoordinates.computeIfAbsent(lineOrDanglingLine, k -> new TreeMap<>())
.put(linePositionData.asInt("seq"), new Coordinate(linePositionData.asDouble("y"), linePositionData.asDouble("x")));
// y <=> lat, x <=> lon
// y <=> lat, x <=> lon
} else {
DanglingLine danglingLine = network.getDanglingLine(lineId);
if (danglingLine != null) {
danglingLineCoordinates.computeIfAbsent(danglingLine, k -> new TreeMap<>())
.put(linePositionData.asInt("seq"), new Coordinate(linePositionData.asDouble("y"), linePositionData.asDouble("x")));
// y <=> lat, x <=> lon
} else {
LOG.warn("Cannot find line/dangling {}, name {} in network {}: skipping line position", lineId, linePositionData.get("name"), network.getId());
}
LOG.warn("Cannot find line/dangling {}, name {} in network {}: skipping line position", lineId, linePositionData.get("name"), network.getId());
}
}

private Identifiable<?> getLineOrDanglingLine(String lineId) {
Line line = network.getLine(lineId);
if (line != null) {
return line;
}
return network.getDanglingLine(lineId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ public class SubstationPositionImporter {

private static final Logger LOG = LoggerFactory.getLogger(SubstationPositionImporter.class);

private Network network;
private final Network network;

public SubstationPositionImporter(Network network) {
this.network = Objects.requireNonNull(network);
}

public void importPosition(PropertyBag substationPositionData) {
Objects.requireNonNull(substationPositionData);
if (!CgmesGLUtils.checkCoordinateSystem(substationPositionData.getId("crsName"), substationPositionData.getId("crsUrn"))) {
throw new PowsyblException("Unsupported coodinates system: " + substationPositionData.getId("crsName"));
String crsUrn = substationPositionData.getId("crsUrn");
if (!CgmesGLUtils.checkCoordinateSystem(crsUrn)) {
throw new PowsyblException("Unsupported coordinates system: " + crsUrn);
}
String substationId = substationPositionData.getId("powerSystemResource");
Substation substation = network.getSubstation(substationId);
Expand Down
2 changes: 0 additions & 2 deletions cgmes/cgmes-gl/src/main/resources/CGMES-GL.sparql
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ SELECT ?powerSystemResource ?name ?crsName ?crsUrn ?x ?y ?seq
cim:IdentifiedObject.name ?name .
?coordinateSystem
a cim:CoordinateSystem ;
cim:IdentifiedObject.name ?crsName ;
cim:CoordinateSystem.crsUrn ?crsUrn .
?positionPoint
a cim:PositionPoint ;
Expand All @@ -38,7 +37,6 @@ SELECT ?powerSystemResource ?name ?crsName ?crsUrn ?x ?y ?seq
cim:IdentifiedObject.name ?name .
?coordinateSystem
a cim:CoordinateSystem ;
cim:IdentifiedObject.name ?crsName ;
cim:CoordinateSystem.crsUrn ?crsUrn .
?positionPoint
a cim:PositionPoint ;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,25 @@
import com.powsybl.cgmes.model.CgmesNamespace;
import com.powsybl.cgmes.model.CgmesSubset;
import com.powsybl.commons.datasource.DataSource;
import com.powsybl.iidm.network.Line;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Substation;
import com.powsybl.triplestore.api.PropertyBag;
import com.powsybl.triplestore.api.TripleStore;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.Coordinate;
import com.powsybl.iidm.network.extensions.LinePosition;
import com.powsybl.iidm.network.extensions.SubstationPosition;
import com.powsybl.iidm.network.impl.extensions.SubstationPositionImpl;
import com.powsybl.iidm.network.impl.extensions.LinePositionImpl;
import com.powsybl.iidm.network.impl.extensions.SubstationPositionImpl;
import com.powsybl.triplestore.api.PropertyBag;
import com.powsybl.triplestore.api.TripleStore;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;

import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.powsybl.cgmes.gl.GLTestUtils.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand All @@ -40,9 +39,60 @@
*/
class CgmesGLExporterTest {

private static final Coordinate SUBSTATION_1 = new Coordinate(51.380348205566406, 0.5492960214614868);
private static final Coordinate SUBSTATION_2 = new Coordinate(52.00010299682617, 0.30759671330451965);
private static final Coordinate LINE_1 = new Coordinate(51.529258728027344, 0.5132722854614258);
private static final Coordinate LINE_2 = new Coordinate(51.944923400878906, 0.4120868146419525);

private Network network;

@BeforeEach
void setUp() {
network = Network.create("Network", "test");
network.setCaseDate(ZonedDateTime.parse("2018-01-01T00:30:00.000+01:00"));
Substation substation1 = network.newSubstation()
.setId("Substation1")
.setCountry(Country.FR)
.add();
VoltageLevel voltageLevel1 = substation1.newVoltageLevel()
.setId("VoltageLevel1")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
voltageLevel1.getBusBreakerView().newBus()
.setId("Bus1")
.add();
Substation substation2 = network.newSubstation()
.setId("Substation2")
.setCountry(Country.FR)
.add();
VoltageLevel voltageLevel2 = substation2.newVoltageLevel()
.setId("VoltageLevel2")
.setNominalV(400)
.setTopologyKind(TopologyKind.BUS_BREAKER)
.add();
voltageLevel2.getBusBreakerView().newBus()
.setId("Bus2")
.add();
network.newLine()
.setId("Line")
.setVoltageLevel1(voltageLevel1.getId())
.setBus1("Bus1")
.setConnectableBus1("Bus1")
.setVoltageLevel2(voltageLevel2.getId())
.setBus2("Bus2")
.setConnectableBus2("Bus2")
.setR(3.0)
.setX(33.0)
.setG1(0.0)
.setB1(386E-6 / 2)
.setG2(0.0)
.setB2(386E-6 / 2)
.add();
}

@Test
void test() {
Network network = GLTestUtils.getNetwork();
Substation substation1 = network.getSubstation("Substation1");
SubstationPosition substationPosition1 = new SubstationPositionImpl(substation1, SUBSTATION_1);
substation1.addExtension(SubstationPosition.class, substationPosition1);
Expand Down Expand Up @@ -95,7 +145,7 @@ void test() {
checkPositionPoint(contextCaptor.getAllValues().get(8), nsCaptor.getAllValues().get(8), typeCaptor.getAllValues().get(8),
propertiesCaptor.getAllValues().get(8), network.getId().toLowerCase(), LINE_1, 2);
checkPositionPoint(contextCaptor.getAllValues().get(9), nsCaptor.getAllValues().get(9), typeCaptor.getAllValues().get(9),
propertiesCaptor.getAllValues().get(9), network.getId().toLowerCase(), GLTestUtils.LINE_2, 3);
propertiesCaptor.getAllValues().get(9), network.getId().toLowerCase(), LINE_2, 3);
checkPositionPoint(contextCaptor.getAllValues().get(10), nsCaptor.getAllValues().get(10), typeCaptor.getAllValues().get(10),
propertiesCaptor.getAllValues().get(10), network.getId().toLowerCase(), SUBSTATION_2, 4);
}
Expand All @@ -120,18 +170,17 @@ private void checkProperties(String context, String namespace, String type, Prop

private void checkCoordinateSystem(String context, String namespace, String type, PropertyBag properties, String basename) {
checkProperties(context, namespace, type, properties, basename, "CoordinateSystem",
Arrays.asList("IdentifiedObject.name", "crsUrn"), Collections.emptyList(),
Arrays.asList("IdentifiedObject.name"));
assertEquals(CgmesGLUtils.COORDINATE_SYSTEM_NAME, properties.get("IdentifiedObject.name"));
Arrays.asList("IdentifiedObject.name", "crsUrn"), Collections.emptyList(),
List.of("IdentifiedObject.name"));
assertEquals(CgmesGLUtils.COORDINATE_SYSTEM_URN, properties.get("crsUrn"));
}

private void checkLocation(String context, String namespace, String type, PropertyBag properties, String basename,
String expectedName, String expectedPowerSystemResource) {
checkProperties(context, namespace, type, properties, basename, "Location",
Arrays.asList("IdentifiedObject.name", "CoordinateSystem", "PowerSystemResources"),
Arrays.asList("CoordinateSystem", "PowerSystemResources"),
Arrays.asList("IdentifiedObject.name"));
Arrays.asList("IdentifiedObject.name", "CoordinateSystem", "PowerSystemResources"),
Arrays.asList("CoordinateSystem", "PowerSystemResources"),
List.of("IdentifiedObject.name"));
assertEquals(expectedName, properties.get("IdentifiedObject.name"));
assertEquals("CoordinateSystemId", properties.get("CoordinateSystem"));
assertEquals(expectedPowerSystemResource, properties.get("PowerSystemResources"));
Expand All @@ -140,8 +189,8 @@ private void checkLocation(String context, String namespace, String type, Proper
private void checkPositionPoint(String context, String namespace, String type, PropertyBag properties, String basename,
Coordinate expectedCoordinate, int expectedSeq) {
checkProperties(context, namespace, type, properties, basename, "PositionPoint",
expectedSeq == -1 ? Arrays.asList("xPosition", "yPosition", "Location") : Arrays.asList("xPosition", "yPosition", "sequenceNumber", "Location"),
Arrays.asList("Location"), Collections.emptyList());
expectedSeq == -1 ? Arrays.asList("xPosition", "yPosition", "Location") : Arrays.asList("xPosition", "yPosition", "sequenceNumber", "Location"),
List.of("Location"), Collections.emptyList());
assertEquals(expectedCoordinate.getLongitude(), properties.asDouble("xPosition"), 0);
assertEquals(expectedCoordinate.getLatitude(), properties.asDouble("yPosition"), 0);
if (expectedSeq != -1) {
Expand Down
Loading