diff --git a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/ops/OPSLimits.java b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/ops/OPSLimits.java index 9cd1bedb..ca9e9dbc 100644 --- a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/ops/OPSLimits.java +++ b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/ops/OPSLimits.java @@ -500,4 +500,9 @@ public double buildingDiameterMaximum() { return Double.MAX_VALUE; } + + @Override + public int buildingMaximumPerSituation() { + return Integer.MAX_VALUE; + } } diff --git a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/building/BuildingLimits.java b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/building/BuildingLimits.java index e8fc544d..301cca4c 100644 --- a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/building/BuildingLimits.java +++ b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/building/BuildingLimits.java @@ -51,4 +51,6 @@ default boolean isBuildingUpperLimitWarning() { double buildingDiameterMinimum(); double buildingDiameterMaximum(); + + int buildingMaximumPerSituation(); } diff --git a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/characteristics/adms/ADMSLimits.java b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/characteristics/adms/ADMSLimits.java index d495a959..0dd7cec4 100644 --- a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/characteristics/adms/ADMSLimits.java +++ b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/v2/characteristics/adms/ADMSLimits.java @@ -133,6 +133,8 @@ public final class ADMSLimits implements BuildingLimits { public static final boolean SPATIALLY_VARYING_ROUGHNESS_DEFAULT = true; public static final boolean ADMS_COMPLEX_TERRAIN_DEFAULT = false; + private static final int ADMS_MAX_BUILDINGS_PER_SITUATION = 50; + public static final ADMSLimits INSTANCE = new ADMSLimits(); private ADMSLimits() { @@ -193,4 +195,9 @@ public double buildingDiameterMinimum() { public double buildingDiameterMaximum() { return BUILDING_DIAMETER_MAXIMUM; } + + @Override + public int buildingMaximumPerSituation() { + return ADMS_MAX_BUILDINGS_PER_SITUATION; + } } diff --git a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/exception/ImaerExceptionReason.java b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/exception/ImaerExceptionReason.java index f02e9985..9fd17a1e 100644 --- a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/exception/ImaerExceptionReason.java +++ b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/exception/ImaerExceptionReason.java @@ -648,6 +648,13 @@ public enum ImaerExceptionReason implements Reason { */ BUILDING_HEIGHT_TOO_HIGH(5244), + /** + * There are more buildings in a situation than the maximum + * + * @param 0 The maximum number of allowed buildings + */ + TOO_MANY_BUILDINGS_IN_SITUATION(5245), + /** * Value is <= 0. * diff --git a/source/imaer-util/src/main/java/nl/overheid/aerius/validation/BuildingValidator.java b/source/imaer-util/src/main/java/nl/overheid/aerius/validation/BuildingValidator.java index f172f43d..27b5d347 100644 --- a/source/imaer-util/src/main/java/nl/overheid/aerius/validation/BuildingValidator.java +++ b/source/imaer-util/src/main/java/nl/overheid/aerius/validation/BuildingValidator.java @@ -45,6 +45,7 @@ public static void validateBuildings(final List buildings, fina public static void validateBuildings(final List buildings, final BuildingLimits buildingLimits, final List errors, final List warnings) { + checkBuildingCount(buildings, buildingLimits, errors); for (final BuildingFeature feature : buildings) { checkBuildingGeometry(feature, buildingLimits, errors); checkBuildingHeight(feature, buildingLimits, errors, warnings); @@ -52,6 +53,12 @@ public static void validateBuildings(final List buildings, fina } } + private static void checkBuildingCount(final List buildings, final BuildingLimits buildingLimits, final List errors) { + if (buildings.size() > buildingLimits.buildingMaximumPerSituation()) { + errors.add(new AeriusException(ImaerExceptionReason.TOO_MANY_BUILDINGS_IN_SITUATION, String.valueOf(buildingLimits.buildingMaximumPerSituation()))); + } + } + private static void checkBuildingGeometry(final BuildingFeature feature, final BuildingLimits buildingLimits, final List errors) { // Only polygon and point geometries are supported. diff --git a/source/imaer-util/src/test/java/nl/overheid/aerius/validation/BuildingValidatorTest.java b/source/imaer-util/src/test/java/nl/overheid/aerius/validation/BuildingValidatorTest.java index 964ac15e..dc2e2b23 100644 --- a/source/imaer-util/src/test/java/nl/overheid/aerius/validation/BuildingValidatorTest.java +++ b/source/imaer-util/src/test/java/nl/overheid/aerius/validation/BuildingValidatorTest.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -162,6 +163,23 @@ void testCircularBuildingNotAllowed() { assertEquals(List.of(), warnings, "No warnings"); } + @Test + void testTooManyBuildings() { + final BuildingFeature building = createBuilding(1); + building.setGeometry(new Point(0, 0)); + building.getProperties().setDiameter(1); + + final List errors = new ArrayList<>(); + final List warnings = new ArrayList<>(); + + BuildingValidator.validateBuildings(IntStream.range(1, 80).mapToObj(s -> building).toList(), limits(false), errors, warnings); + + assertEquals(1, errors.size(), "Number of errors"); + assertEquals(ImaerExceptionReason.TOO_MANY_BUILDINGS_IN_SITUATION, errors.get(0).getReason(), "Error reason"); + assertArrayEquals(new Object[] {"50"}, errors.get(0).getArgs(), "Arguments"); + assertEquals(List.of(), warnings, "No warnings"); + } + private static BuildingLimits limits(final boolean upperLimitWarning) { final BuildingLimits limits = mock(BuildingLimits.class); lenient().when(limits.isCircularBuildingSupported()).thenReturn(true); @@ -170,6 +188,7 @@ private static BuildingLimits limits(final boolean upperLimitWarning) { lenient().when(limits.buildingDiameterMinimum()).thenReturn(0.0); lenient().when(limits.buildingDiameterMaximum()).thenReturn(3.0); lenient().when(limits.isBuildingUpperLimitWarning()).thenReturn(upperLimitWarning); + lenient().when(limits.buildingMaximumPerSituation()).thenReturn(50); return limits; }