From 3a3fcabf10595fa4f6388a7718cfc9cccbb27a4e Mon Sep 17 00:00:00 2001 From: Wangshu Pang Date: Tue, 4 Aug 2026 20:40:03 -0700 Subject: [PATCH] normalize latitude order in rectangleGeographic() #173 rectangleGeographic() already normalized longitude for antimeridian wraparound (x2 < x1) but not latitude, so lat1 > lat2 hit the y2 >= y1 precondition and threw IllegalArgumentException. Normalize lat1/lat2 to min/max, consistent with the existing longitude handling. Co-Authored-By: Claude Sonnet 5 --- .../davidmoten/rtree/geometry/Geometries.java | 4 +++- .../rtree/geometry/GeometriesTest.java | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/davidmoten/rtree/geometry/Geometries.java b/src/main/java/com/github/davidmoten/rtree/geometry/Geometries.java index f44d5fe5..4856a8db 100644 --- a/src/main/java/com/github/davidmoten/rtree/geometry/Geometries.java +++ b/src/main/java/com/github/davidmoten/rtree/geometry/Geometries.java @@ -51,7 +51,9 @@ public static Rectangle rectangleGeographic(float lon1, float lat1, float lon2, if (x2 < x1) { x2 += 360; } - return rectangle(x1, lat1, x2, lat2); + float y1 = Math.min(lat1, lat2); + float y2 = Math.max(lat1, lat2); + return rectangle(x1, y1, x2, y2); } private static Rectangle rectangleDouble(double x1, double y1, double x2, double y2) { diff --git a/src/test/java/com/github/davidmoten/rtree/geometry/GeometriesTest.java b/src/test/java/com/github/davidmoten/rtree/geometry/GeometriesTest.java index 7acd73a0..802aa140 100644 --- a/src/test/java/com/github/davidmoten/rtree/geometry/GeometriesTest.java +++ b/src/test/java/com/github/davidmoten/rtree/geometry/GeometriesTest.java @@ -96,6 +96,26 @@ public void testRectangleLatLong2() { assertEquals(10, r.x2(), PRECISION); } + @Test + public void testRectangleLatLongCrossingEquatorNorthToSouth() { + // entry point is north of the equator, exit point is south of it so + // latitude decreases from lat1 to lat2 (see issue 173) + Rectangle r = Geometries.rectangleGeographic(10, 5, 20, -5); + assertEquals(10, r.x1(), PRECISION); + assertEquals(20, r.x2(), PRECISION); + assertEquals(-5, r.y1(), PRECISION); + assertEquals(5, r.y2(), PRECISION); + } + + @Test + public void testRectangleLatLongCrossingEquatorSouthToNorth() { + Rectangle r = Geometries.rectangleGeographic(10, -5, 20, 5); + assertEquals(10, r.x1(), PRECISION); + assertEquals(20, r.x2(), PRECISION); + assertEquals(-5, r.y1(), PRECISION); + assertEquals(5, r.y2(), PRECISION); + } + @Test public void testPointLatLong() { Point point = Geometries.pointGeographic(181, 25);