Skip to content

Commit c1e383d

Browse files
committed
Fix for Polygon-LineString containment
Consider the LineString between vertices of a polygon as within the polygon. And non-vertex linestrings along the edges (boundary linestrings) aren't considered inside the polygon.
1 parent e435177 commit c1e383d

File tree

1 file changed

+21
-13
lines changed

1 file changed

+21
-13
lines changed

geojson/geojson_s2_util.go

+21-13
Original file line numberDiff line numberDiff line change
@@ -102,29 +102,37 @@ func polygonsIntersectsLinestrings(s2pgn *s2.Polygon,
102102
func polygonsContainsLineStrings(s2pgns []*s2.Polygon,
103103
pls []*s2.Polyline) bool {
104104
linesWithIn := make(map[int]struct{})
105+
checker := s2.NewCrossingEdgeQuery(s2.NewShapeIndex())
105106
nextLine:
106107
for lineIndex, pl := range pls {
107108
for i := 0; i < len(*pl)-1; i++ {
108109
start := (*pl)[i]
109110
end := (*pl)[i+1]
110111

111-
// check whether both the end vertices are inside the polygon.
112112
for _, s2pgn := range s2pgns {
113-
if s2pgn.ContainsPoint(start) && s2pgn.ContainsPoint(end) {
114-
// if both endpoints lie within the polygon then check
115-
// for any edge intersections to confirm the containment.
116-
for i := 0; i < s2pgn.NumEdges(); i++ {
117-
edgeA := s2pgn.Edge(i)
118-
a := []float64{edgeA.V0.X, edgeA.V0.Y}
119-
b := []float64{edgeA.V1.X, edgeA.V1.Y}
120-
c := []float64{start.X, start.Y}
121-
d := []float64{end.X, end.Y}
122-
if doIntersect(a, b, c, d) {
123-
continue nextLine
124-
}
113+
containsStart := s2pgn.ContainsPoint(start)
114+
containsEnd := s2pgn.ContainsPoint(end)
115+
if containsStart && containsEnd {
116+
crossings := checker.Crossings(start, end, s2pgn, s2.CrossingTypeInterior)
117+
if len(crossings) > 0 {
118+
continue nextLine
125119
}
126120
linesWithIn[lineIndex] = struct{}{}
127121
continue nextLine
122+
} else {
123+
for _, loop := range s2pgn.Loops() {
124+
for i := 0; i < loop.NumVertices(); i++ {
125+
if !containsStart && start.ApproxEqual(loop.Vertex(i)) {
126+
containsStart = true
127+
} else if !containsEnd && end.ApproxEqual(loop.Vertex(i)) {
128+
containsEnd = true
129+
}
130+
if containsStart && containsEnd {
131+
linesWithIn[lineIndex] = struct{}{}
132+
continue nextLine
133+
}
134+
}
135+
}
128136
}
129137
}
130138
}

0 commit comments

Comments
 (0)