diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataController.java b/src/main/java/org/gridsuite/geodata/server/GeoDataController.java index 36373ae4..2378c28f 100644 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataController.java +++ b/src/main/java/org/gridsuite/geodata/server/GeoDataController.java @@ -58,7 +58,10 @@ public ResponseEntity> getSubstations(@Parameter(descrip @Parameter(description = "Countries") @RequestParam(name = "country", required = false) List countries, @RequestBody(required = false) List substationIds) { Set countrySet = toCountrySet(countries); - Network network = networkStoreService.getNetwork(networkUuid, substationIds != null ? PreloadingStrategy.NONE : PreloadingStrategy.COLLECTION); + PreloadingStrategy preloadingStrategy = geoDataService.preferPreload(substationIds) ? + PreloadingStrategy.COLLECTION : + PreloadingStrategy.NONE; + Network network = networkStoreService.getNetwork(networkUuid, preloadingStrategy); if (variantId != null) { network.getVariantManager().setWorkingVariant(variantId); } @@ -74,7 +77,10 @@ public ResponseEntity> getLines(@Parameter(description = "Netw @Parameter(description = "Countries") @RequestParam(name = "country", required = false) List countries, @RequestBody(required = false) List lineIds) { Set countrySet = toCountrySet(countries); - Network network = networkStoreService.getNetwork(networkUuid, lineIds != null ? PreloadingStrategy.NONE : PreloadingStrategy.COLLECTION); + PreloadingStrategy preloadingStrategy = geoDataService.preferPreload(lineIds) ? + PreloadingStrategy.COLLECTION : + PreloadingStrategy.NONE; + Network network = networkStoreService.getNetwork(networkUuid, preloadingStrategy); if (variantId != null) { network.getVariantManager().setWorkingVariant(variantId); } diff --git a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java index b7ca4460..ca24eb19 100644 --- a/src/main/java/org/gridsuite/geodata/server/GeoDataService.java +++ b/src/main/java/org/gridsuite/geodata/server/GeoDataService.java @@ -385,12 +385,11 @@ private static Map> getNeighbours(List substatio for (Substation s : substations) { for (VoltageLevel vl : s.getVoltageLevels()) { for (Line line : vl.getConnectables(Line.class)) { - Substation s1 = line.getTerminal1().getVoltageLevel().getSubstation().orElseThrow(); // TODO - Substation s2 = line.getTerminal2().getVoltageLevel().getSubstation().orElseThrow(); // TODO - if (s1 != s) { - neighbours.get(s.getId()).add(s1.getId()); - } else if (s2 != s) { - neighbours.get(s.getId()).add(s2.getId()); + Substation s1 = line.getTerminal1().getVoltageLevel().getSubstation().orElse(null); + Substation s2 = line.getTerminal2().getVoltageLevel().getSubstation().orElse(null); + Substation otherSide = s1 == s ? s2 : s1; + if (otherSide != null) { + neighbours.get(s.getId()).add(otherSide.getId()); } } } @@ -445,7 +444,8 @@ boolean emptyOrEquals(String emptyable, String s) { *

* returns null when the substations at the end of the line are missing. */ - private LineGeoData getLineGeoDataWithEndSubstations(Map linesGeoDataDb, Map substationGeoDataDb, String lineId, Substation substation1, Substation substation2) { + private LineGeoData getLineGeoDataWithEndSubstations(Map linesGeoDataDb, + Map substationGeoDataDb, String lineId, Substation substation1, Substation substation2) { LineGeoData geoData = linesGeoDataDb.get(lineId); SubstationGeoData substation1GeoData = substationGeoDataDb.get(substation1.getId()); SubstationGeoData substation2GeoData = substationGeoDataDb.get(substation2.getId()); @@ -515,17 +515,25 @@ List getLinesByCountries(Network network, Set countries) { // we also want the destination substation (so we add the neighbouring country) Set countryAndNextTo = mapSubstationsByLine.entrySet().stream().flatMap(entry -> - Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()).map(Substation::getNullableCountry).filter(Objects::nonNull)).collect(Collectors.toSet()); + Stream.of(entry.getValue().getLeft(), entry.getValue().getRight()) + .filter(Objects::nonNull) + .map(Substation::getNullableCountry) + .filter(Objects::nonNull)).collect(Collectors.toSet()); Map substationGeoDataDb = getSubstationMapByCountries(network, countryAndNextTo); List geoData = new ArrayList<>(); - mapSubstationsByLine.forEach((key, value) -> { - LineGeoData geo = getLineGeoDataWithEndSubstations(linesGeoDataDb, substationGeoDataDb, key, value.getLeft(), value.getRight()); - if (geo != null) { - geoData.add(geo); - } - }); + mapSubstationsByLine.entrySet().stream() + .filter(entry -> entry.getValue() != null) + .filter(entry -> entry.getValue().getLeft() != null) + .filter(entry -> entry.getValue().getRight() != null) + .forEach(entry -> { + LineGeoData geo = getLineGeoDataWithEndSubstations(linesGeoDataDb, substationGeoDataDb, entry.getKey(), + entry.getValue().getLeft(), entry.getValue().getRight()); + if (geo != null) { + geoData.add(geo); + } + }); LOGGER.info("{} lines read from DB in {} ms", linesGeoDataDb.size(), stopWatch.getTime(TimeUnit.MILLISECONDS)); @@ -534,8 +542,8 @@ List getLinesByCountries(Network network, Set countries) { private Pair getSubstations(Identifiable identifiable) { return switch (identifiable.getType()) { - case LINE -> Pair.of(((Line) identifiable).getTerminal1().getVoltageLevel().getSubstation().orElseThrow(), - ((Line) identifiable).getTerminal2().getVoltageLevel().getSubstation().orElseThrow()); + case LINE -> Pair.of(((Line) identifiable).getTerminal1().getVoltageLevel().getSubstation().orElse(null), + ((Line) identifiable).getTerminal2().getVoltageLevel().getSubstation().orElse(null)); case TIE_LINE -> Pair.of(((TieLine) identifiable).getDanglingLine1().getTerminal().getVoltageLevel().getSubstation().orElseThrow(), ((TieLine) identifiable).getDanglingLine2().getTerminal().getVoltageLevel().getSubstation().orElseThrow()); @@ -546,16 +554,24 @@ private Pair getSubstations(Identifiable identifiable }; } + public boolean preferPreload(List ids) { + return ids == null || ids.size() > 4; + } + @Transactional(readOnly = true) public List getSubstationsData(Network network, Set countrySet, List substationIds) { CompletableFuture> substationGeoDataFuture = geoDataExecutionService.supplyAsync(() -> { - if (substationIds != null) { + if (substationIds != null && substationIds.size() < 4) { if (!countrySet.isEmpty()) { LOGGER.warn("Countries will not be taken into account to filter substation position."); } return getSubstationsByIds(network, new HashSet<>(substationIds)); } else { - return getSubstationsByCountries(network, countrySet); + List substationsByCountries = getSubstationsByCountries(network, countrySet); + if (substationIds != null && !substationIds.isEmpty()) { + return substationsByCountries.stream().filter(s -> substationIds.contains(s.getId())).toList(); + } + return substationsByCountries; } }); try { @@ -571,13 +587,17 @@ public List getSubstationsData(Network network, Set @Transactional(readOnly = true) public List getLinesData(Network network, Set countrySet, List lineIds) { CompletableFuture> lineGeoDataFuture = geoDataExecutionService.supplyAsync(() -> { - if (lineIds != null) { + if (!preferPreload(lineIds)) { if (!countrySet.isEmpty()) { LOGGER.warn("Countries will not be taken into account to filter line position."); } return getLinesByIds(network, new HashSet<>(lineIds)); } else { - return getLinesByCountries(network, countrySet); + List linesByCountries = getLinesByCountries(network, countrySet); + if (lineIds != null && !lineIds.isEmpty()) { + return linesByCountries.stream().filter(ln -> lineIds.contains(ln.getId())).toList(); + } + return linesByCountries; } }); try { diff --git a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java index df61aa8d..42f36603 100644 --- a/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java +++ b/src/test/java/org/gridsuite/geodata/server/GeoDataServiceTest.java @@ -245,6 +245,7 @@ void testNonExisting() { .setG2(0.0) .setB2(386E-6 / 2) .add(); + // if not geo-data is associated to a substation, this substation should not be mentionned in the returned value List substationsGeoData = geoDataService.getSubstationsByCountries(network, new HashSet<>(Collections.singletonList(Country.FR))); assertFalse(substationsGeoData.stream().anyMatch(Objects::isNull), "Must not contain nulls"); assertFalse(substationsGeoData.stream().anyMatch(s -> notexistsub1.getId().equals(s.getId())), @@ -258,6 +259,34 @@ void testNonExisting() { "Must not contain unknown lines " + notexistline.getId()); } + @Test + void outOfSubstationVoltageLevelShouldNotHinderLineDataGathering() { + Network network = EurostagTutorialExample1Factory.create(); + List existingVls = network.getVoltageLevelStream().toList(); + VoltageLevel p1 = network.newVoltageLevel() + .setId("PIQUAGE1").setNominalV(380).setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus bus1 = p1.getBusBreakerView().newBus() + .setId("NPIQ1") + .add(); + network.newLine() + .setId("LINE_PIQ_AT_A_SIDE") + .setVoltageLevel1(existingVls.get(0).getId()) + .setBus1(existingVls.get(0).getBusBreakerView().getBuses().iterator().next().getId()) + .setConnectableBus1(existingVls.get(0).getBusBreakerView().getBuses().iterator().next().getId()) + .setVoltageLevel2(p1.getId()).setBus2(bus1.getId()).setConnectableBus2(bus1.getId()) + .setR(3.0) + .setX(33.0) + .setG1(0.0) + .setB1(386E-6 / 2) + .setG2(0.0) + .setB2(386E-6 / 2) + .add(); + + List linesGeoData = geoDataService.getLinesByCountries(network, new HashSet<>(Collections.singletonList(Country.FR))); + assertEquals(2, linesGeoData.size()); + } + @Test void testSimilarNeighborhoodOffset() { Network network = EurostagTutorialExample1Factory.create();