diff --git a/src/main/java/gov/usgs/earthquake/nshmp/geo/Bounds.java b/src/main/java/gov/usgs/earthquake/nshmp/geo/Bounds.java index bdb9962dfd37704363450f000feafc329c9c3f0c..1b458a109fd88ec5f6ba20aa2e348f189a6ac6d4 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/geo/Bounds.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/geo/Bounds.java @@ -1,5 +1,7 @@ package gov.usgs.earthquake.nshmp.geo; +import static com.google.common.base.Preconditions.checkArgument; + import java.util.Arrays; import java.util.Objects; @@ -8,7 +10,7 @@ import java.util.Objects; * coordinate ({@link #min}) and an upper-right coordinate ({@link #max}). * * <p>Bounds are 2-dimensional in that the depth component of the corners will - * always be 0. The bounds of any {@code Iterable<Location>} may be computed + * always be zero. The bounds of any {@code Iterable<Location>} may be computed * using {@link Locations#bounds(Iterable)}. * * @author U.S. Geological Survey @@ -21,19 +23,31 @@ public final class Bounds { /** The upper right coordinate (maximum longitude and latitude). */ public final Location max; - /* - * Bounds creation is restricted to the geo package so the burden of checking - * that min and max are actually min and max lies with classes that create - * bounds objects. + /** + * Create a new {@code Bounds} object. + * + * @param minLat minimum latitude + * @param minLon minimum longitude + * @param maxLat maximum latitude + * @param maxLon maximum longitude */ + public static Bounds create( + double minLat, + double minLon, + double maxLat, + double maxLon) { - Bounds(Location min, Location max) { - this.min = min; - this.max = max; + checkArgument(minLat < maxLat, "minLat >= maxLat"); + checkArgument(minLon < maxLon, "minLon >= maxLon"); + + return new Bounds( + Location.create(minLon, minLat), + Location.create(maxLon, maxLat)); } - Bounds(double minLat, double minLon, double maxLat, double maxLon) { - this(Location.create(minLon, minLat), Location.create(maxLon, maxLat)); + private Bounds(Location min, Location max) { + this.min = min; + this.max = max; } /** @@ -71,9 +85,6 @@ public final class Bounds { return false; } Bounds other = (Bounds) obj; - if (min == other.min && max == other.max) { - return true; - } return min.equals(other.min) && max.equals(other.max); } diff --git a/src/main/java/gov/usgs/earthquake/nshmp/geo/Locations.java b/src/main/java/gov/usgs/earthquake/nshmp/geo/Locations.java index d9b0a3cc8788d6930bb43053723903a6ca0f80b3..d08f23541c37cc0c1f58b84710229053fda96278 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/geo/Locations.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/geo/Locations.java @@ -562,7 +562,7 @@ public final class Locations { minLat = loc.latitude < minLat ? loc.latitude : minLat; maxLat = loc.latitude > maxLat ? loc.latitude : maxLat; } - return new Bounds(minLat, minLon, maxLat, maxLon); + return Bounds.create(minLat, minLon, maxLat, maxLon); } /** diff --git a/src/main/java/gov/usgs/earthquake/nshmp/geo/Region.java b/src/main/java/gov/usgs/earthquake/nshmp/geo/Region.java index 0bae48db783f0b1aa17a3a9a8a9450a1511f795b..f2af7202dd6a20f67e5a36030551212019ef3c61 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/geo/Region.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/geo/Region.java @@ -289,7 +289,7 @@ public class Region { */ public Bounds bounds() { Rectangle2D bounds = area.getBounds2D(); - return new Bounds( + return Bounds.create( bounds.getMinY(), bounds.getMinX(), bounds.getMaxY(), diff --git a/src/test/java/gov/usgs/earthquake/nshmp/geo/BoundsTests.java b/src/test/java/gov/usgs/earthquake/nshmp/geo/BoundsTests.java index fb04d6b067d834567569ed1641d6947c96ce356f..aac1b1990d11072957e6b3953733e72abdc7721a 100644 --- a/src/test/java/gov/usgs/earthquake/nshmp/geo/BoundsTests.java +++ b/src/test/java/gov/usgs/earthquake/nshmp/geo/BoundsTests.java @@ -3,7 +3,7 @@ package gov.usgs.earthquake.nshmp.geo; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; @@ -21,21 +21,27 @@ class BoundsTests { private static final Location MIN = Location.create(MIN_LON, MIN_LAT); private static final Location MAX = Location.create(MAX_LON, MAX_LAT); - private static final Location BAD = Location.create(0.0, 0.0); @Test - final void minMax() { - Bounds b = new Bounds(MIN, MAX); - assertSame(MIN, b.min); - assertSame(MAX, b.max); - b = new Bounds(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); + void createIAE() { + assertThrows(IllegalArgumentException.class, () -> { + Bounds.create(MIN_LAT, MAX_LON, MAX_LAT, MIN_LON); + }); + assertThrows(IllegalArgumentException.class, () -> { + Bounds.create(MAX_LAT, MIN_LON, MIN_LAT, MAX_LON); + }); + } + + @Test + void minMax() { + Bounds b = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); assertEquals(MIN, b.min); assertEquals(MAX, b.max); } @Test void toList() { - Bounds b = new Bounds(MIN, MAX); + Bounds b = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); LocationList bList = b.toList(); // Expected bounds are anti-clockwise starting at the bottom left point LocationList oList = LocationList.of( @@ -49,41 +55,38 @@ class BoundsTests { @Test void toArray() { - Bounds b = new Bounds(MIN, MAX); + Bounds b = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); double[] coords = new double[] { MIN_LON, MIN_LAT, MAX_LON, MAX_LAT }; assertArrayEquals(coords, b.toArray(), 0.0); } @Test void equalsTest() { - Bounds b1 = new Bounds(MIN, MAX); + Bounds b1 = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); assertEquals(b1, b1); assertNotEquals(b1, null); assertNotEquals(b1, "test"); - Bounds b2 = new Bounds(MIN, MAX); + Bounds b2 = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); assertEquals(b1, b2); - b2 = new Bounds(MIN, BAD); + b2 = Bounds.create(MIN_LAT, MIN_LON, 0.0, 0.0); assertNotEquals(b1, b2); - b2 = new Bounds(BAD, MAX); + b2 = Bounds.create(0.0, 0.0, MAX_LAT, MAX_LON); assertNotEquals(b1, b2); - - b2 = new Bounds(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); - assertEquals(b1, b2); } @Test void hashCodeTest() { - Bounds b1 = new Bounds(MIN, MAX); - Bounds b2 = new Bounds(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); + Bounds b1 = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); + Bounds b2 = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); assertEquals(b1.hashCode(), b2.hashCode()); - b2 = new Bounds(0, 0, 2, 2); + b2 = Bounds.create(0, 0, 2, 2); assertNotEquals(b1.hashCode(), b2.hashCode()); } @Test void toStringTest() { - Bounds b = new Bounds(MIN, MAX); + Bounds b = Bounds.create(MIN_LAT, MIN_LON, MAX_LAT, MAX_LON); assertEquals("[-10.0, -10.0, 10.0, 10.0]", b.toString()); }