diff --git a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/geo/HexagonUtil.java b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/geo/HexagonUtil.java index 75d7d115..e3b2b382 100644 --- a/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/geo/HexagonUtil.java +++ b/source/imaer-shared/src/main/java/nl/overheid/aerius/shared/domain/geo/HexagonUtil.java @@ -16,6 +16,8 @@ */ package nl.overheid.aerius.shared.domain.geo; +import java.util.function.DoubleUnaryOperator; + import nl.overheid.aerius.shared.MathUtil; import nl.overheid.aerius.shared.domain.v2.geojson.Point; import nl.overheid.aerius.shared.domain.v2.geojson.Polygon; @@ -27,6 +29,15 @@ public final class HexagonUtil { private HexagonUtil() {} + /** + * Returns a Geometry with a hexagon conforming to the given Point, and rounds the points of the hexagon + * + * @see #createHexagon(Point, HexagonZoomLevel, DoubleUnaryOperator) + */ + public static Polygon createHexagon(final Point point, final HexagonZoomLevel config) { + return createHexagon(point, config, MathUtil::round); + } + /** * Returns a Geometry with a hexagon conforming to the given Point and * HexagonConfiguration. The points of the hexagon are given in the following @@ -43,9 +54,10 @@ private HexagonUtil() {} * * @param point Center of the hexagon * @param config the hexagon zoom level for level 1 + * @param roundFunction function to round the coordinates of the hexagon with * @return Returns the hexagon as an AERIUS polygon */ - public static Polygon createHexagon(final Point point, final HexagonZoomLevel config) { + public static Polygon createHexagon(final Point point, final HexagonZoomLevel config, final DoubleUnaryOperator roundFunction) { // Store hexagon values final double[] horizontal = config.getHorizontal(); final double[] vertical = config.getVertical(); @@ -54,16 +66,16 @@ public static Polygon createHexagon(final Point point, final HexagonZoomLevel co // Iterate over the number of corners in a hexagon for (int i = 0; i < HexagonZoomLevel.HEXAGON_CORNERS; i++) { final double[] coordinate = new double[] { - MathUtil.round(point.getX() + horizontal[i]), - MathUtil.round(point.getY() + vertical[i]) + roundFunction.applyAsDouble(point.getX() + horizontal[i]), + roundFunction.applyAsDouble(point.getY() + vertical[i]) }; coordinates[i] = coordinate; } // Polygon first and last point need to be the same final double[] lastCoordinate = new double[] { - MathUtil.round(point.getX() + horizontal[0]), - MathUtil.round(point.getY() + vertical[0]) + roundFunction.applyAsDouble(point.getX() + horizontal[0]), + roundFunction.applyAsDouble(point.getY() + vertical[0]) }; coordinates[HexagonZoomLevel.HEXAGON_CORNERS] = lastCoordinate; final Polygon polygon = new Polygon(); diff --git a/source/imaer-shared/src/test/java/nl/overheid/aerius/shared/domain/geo/HexagonUtilTest.java b/source/imaer-shared/src/test/java/nl/overheid/aerius/shared/domain/geo/HexagonUtilTest.java index 56d66f75..6a382e7d 100644 --- a/source/imaer-shared/src/test/java/nl/overheid/aerius/shared/domain/geo/HexagonUtilTest.java +++ b/source/imaer-shared/src/test/java/nl/overheid/aerius/shared/domain/geo/HexagonUtilTest.java @@ -16,8 +16,17 @@ */ package nl.overheid.aerius.shared.domain.geo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import nl.overheid.aerius.shared.domain.v2.geojson.Point; import nl.overheid.aerius.shared.domain.v2.geojson.Polygon; @@ -25,22 +34,31 @@ /** * Test class for {@link HexagonUtil}. */ -public class HexagonUtilTest { +class HexagonUtilTest { private static final HexagonZoomLevel ZOOM_LEVEL_1 = new HexagonZoomLevel(1, 10000); - @Test - public void testCreateHexagon() { - assertCreateHexagon(); - // Run twice to test if cache works. - assertCreateHexagon(); + @ParameterizedTest + @MethodSource("createHexagon") + void testCreateHexagon(final boolean useDefaultMethod, final double[][][] results) { + final Point point = new Point(ZOOM_LEVEL_1.getHexagonRadius(), ZOOM_LEVEL_1.getHexagonHeight() / 2); + // When round use the default createHexagon method to test, otherwise the version with roundingFunction + final Polygon polygon = useDefaultMethod + ? HexagonUtil.createHexagon(point, ZOOM_LEVEL_1) + : HexagonUtil.createHexagon(point, ZOOM_LEVEL_1, d -> BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP).doubleValue()); + + Assertions.assertArrayEquals(results, polygon.getCoordinates(), "createHexagon zoom level 1"); } - private void assertCreateHexagon() { - final Point point = new Point(ZOOM_LEVEL_1.getHexagonRadius(), ZOOM_LEVEL_1.getHexagonHeight() / 2); - final Polygon polygon = HexagonUtil.createHexagon(point, ZOOM_LEVEL_1); + private static List createHexagon() { + return List.of( + Arguments.of(false, + new double[][][] {{{93.06, 107.457}, {124.081, 53.728}, {93.06, 0.0}, {31.02, 0.0}, {0.0, 53.728}, {31.02, 107.457}, {93.06, 107.457}}}), + Arguments.of(true, new double[][][] {{{93, 107}, {124, 54}, {93, 0}, {31, 0}, {0, 54}, {31, 107}, {93, 107}}})); + } - Assertions.assertArrayEquals(new double[][][] {{{93, 107}, {124, 54}, {93, 0}, {31, 0}, {0, 54}, {31, 107}, {93, 107}}}, polygon.getCoordinates(), - "createHexagon zoom level 1"); + @Test + void testGetDistanceLevelForCircle() { + assertEquals(2.0, HexagonUtil.getDistanceLevelForCircle(100, ZOOM_LEVEL_1), 1E-7, "Not the expected distance level for circle"); } }