@@ -530,34 +530,34 @@ public void testLineStringWithPartialNaNCoordinates() {
530530
531531 /**
532532 * Tests the end-to-end case for updating and merging bounding boxes with mixed valid and NaN coordinates.
533- *
533+ * <p>
534534 * Scenario - Parquet file with multiple row groups:
535535 * file-level bbox: [1, 9, 100, 900]
536- *
536+ * <p>
537537 * Row group 1: [1, 2, 100, 100]
538538 * - POINT (1, 100)
539539 * - POINT (2, NaN)
540- *
540+ * <p>
541541 * Row group 2: [3, 3, 300, 300]
542542 * - POINT (3, 300)
543543 * - POINT (NaN, NaN)
544- *
544+ * <p>
545545 * Row group 3: no valid bbox
546546 * - POINT (5, NaN)
547547 * - POINT (6, NaN)
548- *
548+ * <p>
549549 * Row group 4: [7, 8, 700, 800]
550550 * - POINT (7, 700)
551551 * - POINT (8, 800)
552- *
552+ * <p>
553553 * Row group 5: no valid bbox
554554 * - POINT (NaN, NaN)
555555 * - POINT (NaN, NaN)
556- *
556+ * <p>
557557 * Row group 6: [9, 9, 900, 900]
558558 * - POINT (9, 900)
559559 * - LINESTRING EMPTY
560- *
560+ * <p>
561561 * The test verifies that:
562562 * 1. Individual row group bounding boxes correctly handle NaN coordinates
563563 * 2. The merge operation correctly combines valid bounding boxes and ignores invalid ones
@@ -681,4 +681,146 @@ public void testMergingRowGroupBoundingBoxes() {
681681 Assert .assertEquals (900.0 , reverseMergeBox .getYMax (), 0.0 );
682682 Assert .assertTrue (reverseMergeBox .isValid ());
683683 }
684+
685+ @ Test
686+ public void testIsXValidAndIsYValid () {
687+ // Test with valid X and Y
688+ BoundingBox validBox = new BoundingBox (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 );
689+ Assert .assertTrue (validBox .isXValid ());
690+ Assert .assertTrue (validBox .isYValid ());
691+ Assert .assertTrue (validBox .isXYValid ());
692+ Assert .assertTrue (validBox .isZValid ());
693+ Assert .assertTrue (validBox .isMValid ());
694+
695+ // Test with invalid X (NaN)
696+ BoundingBox invalidXBox = new BoundingBox (Double .NaN , 2 , 3 , 4 , 5 , 6 , 7 , 8 );
697+ Assert .assertFalse (invalidXBox .isXValid ());
698+ Assert .assertTrue (invalidXBox .isYValid ());
699+ Assert .assertFalse (invalidXBox .isXYValid ());
700+ Assert .assertTrue (invalidXBox .isZValid ());
701+ Assert .assertTrue (invalidXBox .isMValid ());
702+
703+ // Test with invalid Y (NaN)
704+ BoundingBox invalidYBox = new BoundingBox (1 , 2 , Double .NaN , 4 , 5 , 6 , 7 , 8 );
705+ Assert .assertTrue (invalidYBox .isXValid ());
706+ Assert .assertFalse (invalidYBox .isYValid ());
707+ Assert .assertFalse (invalidXBox .isXYValid ());
708+ Assert .assertTrue (invalidXBox .isZValid ());
709+ Assert .assertTrue (invalidXBox .isMValid ());
710+
711+ // Test with both X and Y invalid
712+ BoundingBox invalidXYBox = new BoundingBox (Double .NaN , Double .NaN , Double .NaN , Double .NaN , 5 , 6 , 7 , 8 );
713+ Assert .assertFalse (invalidXYBox .isXValid ());
714+ Assert .assertFalse (invalidXYBox .isYValid ());
715+ Assert .assertFalse (invalidXYBox .isXYValid ());
716+ Assert .assertTrue (invalidXBox .isZValid ());
717+ Assert .assertTrue (invalidXBox .isMValid ());
718+ }
719+
720+ @ Test
721+ public void testIsXEmptyAndIsYEmpty () {
722+ // Empty bounding box (initial state)
723+ BoundingBox emptyBox = new BoundingBox ();
724+ Assert .assertTrue (emptyBox .isXEmpty ());
725+ Assert .assertTrue (emptyBox .isYEmpty ());
726+ Assert .assertTrue (emptyBox .isXYEmpty ());
727+
728+ // Non-empty box
729+ BoundingBox nonEmptyBox = new BoundingBox (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 );
730+ Assert .assertFalse (nonEmptyBox .isXEmpty ());
731+ Assert .assertFalse (nonEmptyBox .isYEmpty ());
732+ Assert .assertFalse (nonEmptyBox .isXYEmpty ());
733+
734+ // Box with empty X dimension only
735+ GeometryFactory gf = new GeometryFactory ();
736+ BoundingBox emptyXBox = new BoundingBox ();
737+ // Only update Y dimension
738+ emptyXBox .update (gf .createPoint (new Coordinate (Double .NaN , 5 )));
739+ Assert .assertTrue (emptyXBox .isXEmpty ());
740+ Assert .assertFalse (emptyXBox .isYEmpty ());
741+ Assert .assertTrue (emptyXBox .isXYEmpty ());
742+
743+ // Box with empty Y dimension only
744+ BoundingBox emptyYBox = new BoundingBox ();
745+ // Only update X dimension
746+ emptyYBox .update (gf .createPoint (new Coordinate (10 , Double .NaN )));
747+ Assert .assertFalse (emptyYBox .isXEmpty ());
748+ Assert .assertTrue (emptyYBox .isYEmpty ());
749+ Assert .assertTrue (emptyYBox .isXYEmpty ());
750+ }
751+
752+ @ Test
753+ public void testIsXWraparound () {
754+ // Normal bounding box (no wraparound)
755+ BoundingBox normalBox = new BoundingBox (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 );
756+ Assert .assertFalse (normalBox .isXWraparound ());
757+
758+ // Wraparound box (xMin > xMax)
759+ BoundingBox wraparoundBox = new BoundingBox (170 , 20 , 10 , 20 , 0 , 0 , 0 , 0 );
760+ Assert .assertTrue (wraparoundBox .isXWraparound ());
761+
762+ // Edge case: equal bounds
763+ BoundingBox equalBoundsBox = new BoundingBox (10 , 10 , 20 , 20 , 0 , 0 , 0 , 0 );
764+ Assert .assertFalse (equalBoundsBox .isXWraparound ());
765+
766+ // Test static method directly
767+ Assert .assertTrue (BoundingBox .isWraparound (180 , -180 ));
768+ Assert .assertFalse (BoundingBox .isWraparound (-180 , 180 ));
769+
770+ // Test with infinity values
771+ Assert .assertFalse (BoundingBox .isWraparound (Double .POSITIVE_INFINITY , Double .NEGATIVE_INFINITY ));
772+ Assert .assertFalse (BoundingBox .isWraparound (Double .NEGATIVE_INFINITY , Double .POSITIVE_INFINITY ));
773+ Assert .assertFalse (BoundingBox .isWraparound (Double .POSITIVE_INFINITY , Double .POSITIVE_INFINITY ));
774+ Assert .assertFalse (BoundingBox .isWraparound (Double .NEGATIVE_INFINITY , Double .NEGATIVE_INFINITY ));
775+
776+ // Check edge cases
777+ Assert .assertFalse (BoundingBox .isWraparound (0.0 , Double .POSITIVE_INFINITY ));
778+ Assert .assertFalse (BoundingBox .isWraparound (Double .NEGATIVE_INFINITY , 0.0 ));
779+ }
780+
781+ @ Test
782+ public void testWraparoundHandlingInMerge () {
783+ // Test with two normal boxes
784+ BoundingBox box1 = new BoundingBox (10 , 20 , 10 , 20 , 0 , 0 , 0 , 0 );
785+ BoundingBox box2 = new BoundingBox (15 , 25 , 15 , 25 , 0 , 0 , 0 , 0 );
786+ box1 .merge (box2 );
787+
788+ Assert .assertTrue (box1 .isValid ());
789+ Assert .assertEquals (10.0 , box1 .getXMin (), 0.0 );
790+ Assert .assertEquals (25.0 , box1 .getXMax (), 0.0 );
791+
792+ // Test with one wraparound box
793+ BoundingBox normalBox = new BoundingBox (0 , 10 , 0 , 10 , 0 , 0 , 0 , 0 );
794+ BoundingBox wraparoundBox = new BoundingBox (170 , -170 , 5 , 15 , 0 , 0 , 0 , 0 );
795+
796+ normalBox .merge (wraparoundBox );
797+
798+ Assert .assertFalse (normalBox .isValid ());
799+ Assert .assertTrue (Double .isNaN (normalBox .getXMin ()));
800+ Assert .assertTrue (Double .isNaN (normalBox .getXMax ()));
801+ Assert .assertEquals (0.0 , normalBox .getYMin (), 0.0 );
802+ Assert .assertEquals (15.0 , normalBox .getYMax (), 0.0 );
803+ }
804+
805+ @ Test
806+ public void testWraparoundBoxMergingNormalBox () {
807+ // Create a normal bounding box
808+ BoundingBox normalBox = new BoundingBox (0 , 10 , 0 , 10 , 0 , 0 , 0 , 0 );
809+
810+ // Create a wraparound bounding box (xMin > xMax)
811+ BoundingBox wraparoundBox = new BoundingBox (170 , -170 , 5 , 15 , 0 , 0 , 0 , 0 );
812+
813+ // Merge the normal box into the wraparound box
814+ wraparoundBox .merge (normalBox );
815+
816+ // After merging, X dimension should be marked as invalid (NaN)
817+ // because we don't support merging wraparound bounds
818+ Assert .assertFalse (wraparoundBox .isValid ());
819+ Assert .assertTrue (Double .isNaN (wraparoundBox .getXMin ()));
820+ Assert .assertTrue (Double .isNaN (wraparoundBox .getXMax ()));
821+
822+ // Y dimension should be properly merged
823+ Assert .assertEquals (0.0 , wraparoundBox .getYMin (), 0.0 );
824+ Assert .assertEquals (15.0 , wraparoundBox .getYMax (), 0.0 );
825+ }
684826}
0 commit comments