@@ -972,3 +972,86 @@ func TestCoverageIsValid(t *testing.T) {
972972 })
973973 }
974974}
975+
976+ func TestClipByRect (t * testing.T ) {
977+ for _ , tc := range []struct {
978+ name string
979+ input string
980+ rect geom.Envelope
981+ want string
982+ }{
983+ {
984+ name : "polygon fully inside rect" ,
985+ input : "POLYGON((1 1,1 2,2 2,2 1,1 1))" ,
986+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 0 }, geom.XY {X : 3 , Y : 3 }),
987+ want : "POLYGON((1 1,1 2,2 2,2 1,1 1))" ,
988+ },
989+ {
990+ name : "polygon partially overlapping rect" ,
991+ input : "POLYGON((0 0,0 4,4 4,4 0,0 0))" ,
992+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
993+ want : "POLYGON((1 1,1 3,3 3,3 1,1 1))" ,
994+ },
995+ {
996+ name : "polygon fully outside rect" ,
997+ input : "POLYGON((0 0,0 1,1 1,1 0,0 0))" ,
998+ rect : geom .NewEnvelope (geom.XY {X : 5 , Y : 5 }, geom.XY {X : 6 , Y : 6 }),
999+ want : "GEOMETRYCOLLECTION EMPTY" ,
1000+ },
1001+ {
1002+ name : "linestring clipped by rect" ,
1003+ input : "LINESTRING(0 0,4 4)" ,
1004+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1005+ want : "LINESTRING(1 1,3 3)" ,
1006+ },
1007+ {
1008+ name : "point inside rect" ,
1009+ input : "POINT(2 2)" ,
1010+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1011+ want : "POINT(2 2)" ,
1012+ },
1013+ {
1014+ name : "point outside rect" ,
1015+ input : "POINT(0 0)" ,
1016+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 3 , Y : 3 }),
1017+ want : "GEOMETRYCOLLECTION EMPTY" ,
1018+ },
1019+ {
1020+ name : "empty input geometry" ,
1021+ input : "GEOMETRYCOLLECTION EMPTY" ,
1022+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 0 }, geom.XY {X : 1 , Y : 1 }),
1023+ want : "GEOMETRYCOLLECTION EMPTY" ,
1024+ },
1025+ {
1026+ name : "u-shaped polygon clipped through both arms produces multipolygon" ,
1027+ input : "POLYGON((0 0,4 0,4 3,3 3,3 1,1 1,1 3,0 3,0 0))" ,
1028+ rect : geom .NewEnvelope (geom.XY {X : 0 , Y : 2 }, geom.XY {X : 4 , Y : 4 }),
1029+ want : "MULTIPOLYGON(((0 2,0 3,1 3,1 2,0 2)),((3 2,3 3,4 3,4 2,3 2)))" ,
1030+ },
1031+ {
1032+ name : "polygon with hole inside rect" ,
1033+ input : "POLYGON((0 0,0 6,6 6,6 0,0 0),(2 2,4 2,4 4,2 4,2 2))" ,
1034+ rect : geom .NewEnvelope (geom.XY {X : 1 , Y : 1 }, geom.XY {X : 5 , Y : 5 }),
1035+ want : "POLYGON((1 1,1 5,5 5,5 1,1 1),(2 2,4 2,4 4,2 4,2 2))" ,
1036+ },
1037+ {
1038+ name : "polygon with hole partially outside rect removes hole" ,
1039+ input : "POLYGON((0 0,0 6,6 6,6 0,0 0),(1 1,3 1,3 3,1 3,1 1))" ,
1040+ rect : geom .NewEnvelope (geom.XY {X : 2 , Y : 2 }, geom.XY {X : 5 , Y : 5 }),
1041+ want : "POLYGON((2 3,2 5,5 5,5 2,3 2,3 3,2 3))" ,
1042+ },
1043+ {
1044+ name : "empty envelope" ,
1045+ input : "POLYGON((0 0,0 1,1 1,1 0,0 0))" ,
1046+ rect : geom.Envelope {},
1047+ want : "GEOMETRYCOLLECTION EMPTY" ,
1048+ },
1049+ } {
1050+ t .Run (tc .name , func (t * testing.T ) {
1051+ got , err := geos .ClipByRect (geomFromWKT (t , tc .input ), tc .rect )
1052+ skipIfUnsupported (t , err )
1053+ expectNoErr (t , err )
1054+ expectGeomEq (t , got , geomFromWKT (t , tc .want ), geom .IgnoreOrder )
1055+ })
1056+ }
1057+ }
0 commit comments