Skip to content

Infinite loop in RegionCoverer Interior Covering #152

Closed
@lukasbindreiter

Description

@lukasbindreiter

Hi,

I've just stumbled upon a case where RegionCoverer.InteriorCovering results in an infinite loop.

To be fair, the s2.Polygon in question isn't a valid polygon according to the restrictions:

  • Loops may not cross, i.e. the boundary of a loop may not intersect
    both the interior and exterior of any other loop.
  • Loops may not share edges, i.e. if a loop contains an edge AB, then
    no other loop may contain AB or BA.

since it consists of the same loop two times.

I still think this might be worth looking into - since an infinite loop is pretty dangerous to trigger in any case.

And it does work (even correctly) for the RegionCoverer.Covering variant.

Below is a fully reproducible example:

package main

import (
	"fmt"
	"github.com/golang/geo/s2"
)

func main() {
	// a closed-polygon, an area in mexico
	points := []s2.Point{
		s2.PointFromLatLng(s2.LatLngFromDegrees(20.15, -97.70)),
		s2.PointFromLatLng(s2.LatLngFromDegrees(19.72, -97.70)),
		s2.PointFromLatLng(s2.LatLngFromDegrees(19.72, -97.19)),
		s2.PointFromLatLng(s2.LatLngFromDegrees(20.15, -97.19)),
	}
	poly := s2.PolygonFromOrientedLoops([]*s2.Loop{s2.LoopFromPoints(points)})

	coverer := s2.RegionCoverer{MinLevel: 0, MaxLevel: 30, LevelMod: 1, MaxCells: 1}
	interiorCovering := coverer.InteriorCovering(poly) // works as intended
	fmt.Println(interiorCovering)                      // [4/023231102]

	// now let's try the same area again, but with two times the same loop
	// this happened for us when converting a GeoJSON multipolygon to a S2 polygon and we didn't validate the
	// non-overlapping constraint before

	multiPoly := s2.PolygonFromOrientedLoops([]*s2.Loop{s2.LoopFromPoints(points), s2.LoopFromPoints(points)})
	// the call below results in an infinite loop
	interiorCovering = coverer.InteriorCovering(multiPoly)
	fmt.Println(interiorCovering)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions