diff --git a/internal/clip/clip_test.go b/internal/clip/clip_test.go index a0bba35e..20dbe352 100644 --- a/internal/clip/clip_test.go +++ b/internal/clip/clip_test.go @@ -13,8 +13,8 @@ func LO(points []geometry.Point) *geojson.LineString { func RO(minX, minY, maxX, maxY float64) *geojson.Rect { return geojson.NewRect(geometry.Rect{ - Min: geometry.Point{X: 1.5, Y: 0.5}, - Max: geometry.Point{X: 2.5, Y: 1.8}, + Min: geometry.Point{X: minX, Y: minY}, + Max: geometry.Point{X: maxX, Y: maxY}, }) } @@ -61,8 +61,43 @@ func TestClipPolygonSimple(t *testing.T) { if !ok { t.Fatal("wrong type") } - if !cp.Base().Exterior.Empty() && len(cp.Base().Holes) != 1 { - t.Fatal("result must have two parts in Polygon") + if cp.Base().Exterior.Empty() { + t.Fatal("Empty result.") + } + if len(cp.Base().Holes) != 1 { + t.Fatal("result must be a two-ring Polygon") + } +} + +func TestClipPolygon2(t *testing.T) { + exterior := []geometry.Point{ + {X: 2, Y: 2}, + {X: 1, Y: 2}, + {X: 1.5, Y: 1.5}, + {X: 1, Y: 1}, + {X: 2, Y: 1}, + {X: 2, Y: 2}, + } + holes := [][]geometry.Point{ + []geometry.Point{ + {X: 1.9, Y: 1.9}, + {X: 1.2, Y: 1.9}, + {X: 1.45, Y: 1.65}, + {X: 1.9, Y: 1.5}, + {X: 1.9, Y: 1.9}, + }, + } + polygon := PPO(exterior, holes) + clipped := Clip(polygon, RO(1.1, 0.8, 1.15, 2.1)) + cp, ok := clipped.(*geojson.Polygon) + if !ok { + t.Fatal("wrong type") + } + if cp.Base().Exterior.Empty() { + t.Fatal("Empty result.") + } + if len(cp.Base().Holes) != 0 { + t.Fatal("result must be a single-ring Polygon") } } diff --git a/internal/clip/polygon.go b/internal/clip/polygon.go index a2bebe4d..9134e9db 100644 --- a/internal/clip/polygon.go +++ b/internal/clip/polygon.go @@ -18,7 +18,9 @@ func clipPolygon( for i := 0; i < len(ringPoints); i++ { ringPoints[i] = ring.PointAt(i) } - newPoints = append(newPoints, clipRing(ringPoints, rect)) + if clippedRing := clipRing(ringPoints, rect); len(clippedRing) > 0 { + newPoints = append(newPoints, clippedRing) + } } var exterior []geometry.Point