@@ -1016,3 +1016,86 @@ func TestCoverageIsValid(t *testing.T) {
10161016 })
10171017 }
10181018}
1019+
1020+ func TestClipByRect (t * testing.T ) {
1021+ for _ , tc := range []struct {
1022+ name string
1023+ input string
1024+ rect geom.Envelope
1025+ want string
1026+ }{
1027+ {
1028+ name : "polygon fully inside rect" ,
1029+ input : "POLYGON((1 1,1 2,2 2,2 1,1 1))" ,
1030+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 0 }, geom.XY {X : 3 , Y : 3 }),
1031+ want : "POLYGON((1 1,1 2,2 2,2 1,1 1))" ,
1032+ },
1033+ {
1034+ name : "polygon partially overlapping rect" ,
1035+ input : "POLYGON((0 0,0 4,4 4,4 0,0 0))" ,
1036+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1037+ want : "POLYGON((1 1,1 3,3 3,3 1,1 1))" ,
1038+ },
1039+ {
1040+ name : "polygon fully outside rect" ,
1041+ input : "POLYGON((0 0,0 1,1 1,1 0,0 0))" ,
1042+ rect : geom .NewEnvelope (geom.XY {X : 5 , Y : 5 }, geom.XY {X : 6 , Y : 6 }),
1043+ want : "GEOMETRYCOLLECTION EMPTY" ,
1044+ },
1045+ {
1046+ name : "linestring clipped by rect" ,
1047+ input : "LINESTRING(0 0,4 4)" ,
1048+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1049+ want : "LINESTRING(1 1,3 3)" ,
1050+ },
1051+ {
1052+ name : "point inside rect" ,
1053+ input : "POINT(2 2)" ,
1054+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1055+ want : "POINT(2 2)" ,
1056+ },
1057+ {
1058+ name : "point outside rect" ,
1059+ input : "POINT(0 0)" ,
1060+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1061+ want : "GEOMETRYCOLLECTION EMPTY" ,
1062+ },
1063+ {
1064+ name : "empty input geometry" ,
1065+ input : "GEOMETRYCOLLECTION EMPTY" ,
1066+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 0 }, geom.XY {X : 1 , Y : 1 }),
1067+ want : "GEOMETRYCOLLECTION EMPTY" ,
1068+ },
1069+ {
1070+ name : "u-shaped polygon clipped through both arms produces multipolygon" ,
1071+ input : "POLYGON((0 0,4 0,4 3,3 3,3 1,1 1,1 3,0 3,0 0))" ,
1072+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 2 }, geom.XY {X : 4 , Y : 4 }),
1073+ want : "MULTIPOLYGON(((0 2,0 3,1 3,1 2,0 2)),((3 2,3 3,4 3,4 2,3 2)))" ,
1074+ },
1075+ {
1076+ name : "polygon with hole inside rect" ,
1077+ input : "POLYGON((0 0,0 6,6 6,6 0,0 0),(2 2,4 2,4 4,2 4,2 2))" ,
1078+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 5 , Y : 5 }),
1079+ want : "POLYGON((1 1,1 5,5 5,5 1,1 1),(2 2,4 2,4 4,2 4,2 2))" ,
1080+ },
1081+ {
1082+ name : "polygon with hole partially outside rect removes hole" ,
1083+ input : "POLYGON((0 0,0 6,6 6,6 0,0 0),(1 1,3 1,3 3,1 3,1 1))" ,
1084+ rect : geom .NewEnvelope (geom.XY {X : 2 , Y : 2 }, geom.XY {X : 5 , Y : 5 }),
1085+ want : "POLYGON((2 3,2 5,5 5,5 2,3 2,3 3,2 3))" ,
1086+ },
1087+ {
1088+ name : "empty envelope" ,
1089+ input : "POLYGON((0 0,0 1,1 1,1 0,0 0))" ,
1090+ rect : geom.Envelope {},
1091+ want : "GEOMETRYCOLLECTION EMPTY" ,
1092+ },
1093+ } {
1094+ t .Run (tc .name , func (t * testing.T ) {
1095+ got , err := geos .ClipByRect (geomFromWKT (t , tc .input ), tc .rect )
1096+ skipIfUnsupported (t , err )
1097+ expectNoErr (t , err )
1098+ expectGeomEq (t , got , geomFromWKT (t , tc .want ), geom .IgnoreOrder )
1099+ })
1100+ }
1101+ }
0 commit comments