Skip to content

Commit 1bc1d50

Browse files
Fix for linestrings enclosed by polygon (#9)
Address case where linestrings are partially or completely enclosed by the polygon.
1 parent 6c4acc9 commit 1bc1d50

File tree

3 files changed

+22
-27
lines changed

3 files changed

+22
-27
lines changed

geojson/geojson_s2_util.go

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ func polylineIntersectsPoint(pls []*s2.Polyline,
4040

4141
func polylineIntersectsPolygons(pls []*s2.Polyline,
4242
s2pgns []*s2.Polygon) bool {
43+
// Early exit if the polygon contains any of the line's vertices.
44+
for _, pl := range pls {
45+
for i := 0; i < pl.NumEdges(); i++ {
46+
edge := pl.Edge(i)
47+
for _, s2pgn := range s2pgns {
48+
if s2pgn.IntersectsCell(s2.CellFromPoint(edge.V0)) ||
49+
s2pgn.IntersectsCell(s2.CellFromPoint(edge.V1)) {
50+
return true
51+
}
52+
}
53+
}
54+
}
55+
4356
for _, pl := range pls {
4457
for _, s2pgn := range s2pgns {
4558
for i := 0; i < pl.NumEdges(); i++ {
@@ -75,30 +88,6 @@ func geometryCollectionIntersectsShape(gc *GeometryCollection,
7588
return false
7689
}
7790

78-
func polygonsIntersectsLinestrings(s2pgn *s2.Polygon,
79-
pls []*s2.Polyline) bool {
80-
for _, pl := range pls {
81-
for i := 0; i < pl.NumEdges(); i++ {
82-
edge := pl.Edge(i)
83-
a := []float64{edge.V0.X, edge.V0.Y}
84-
b := []float64{edge.V1.X, edge.V1.Y}
85-
86-
for j := 0; j < s2pgn.NumEdges(); j++ {
87-
edgeB := s2pgn.Edge(j)
88-
89-
c := []float64{edgeB.V0.X, edgeB.V0.Y}
90-
d := []float64{edgeB.V1.X, edgeB.V1.Y}
91-
92-
if doIntersect(a, b, c, d) {
93-
return true
94-
}
95-
}
96-
}
97-
}
98-
99-
return false
100-
}
101-
10291
func polygonsContainsLineStrings(s2pgns []*s2.Polygon,
10392
pls []*s2.Polyline) bool {
10493
linesWithIn := make(map[int]struct{})

geojson/geojson_shapes_impl.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,8 +1232,8 @@ func checkPolygonIntersectsShape(s2pgn *s2.Polygon, shapeIn,
12321232
// check if the other shape is a linestring.
12331233
if ls, ok := other.(*LineString); ok {
12341234

1235-
if polygonsIntersectsLinestrings(s2pgn,
1236-
[]*s2.Polyline{ls.pl}) {
1235+
if polylineIntersectsPolygons([]*s2.Polyline{ls.pl},
1236+
[]*s2.Polygon{s2pgn}) {
12371237
return true, nil
12381238
}
12391239

@@ -1243,7 +1243,7 @@ func checkPolygonIntersectsShape(s2pgn *s2.Polygon, shapeIn,
12431243
// check if the other shape is a multilinestring.
12441244
if mls, ok := other.(*MultiLineString); ok {
12451245

1246-
if polygonsIntersectsLinestrings(s2pgn, mls.pls) {
1246+
if polylineIntersectsPolygons(mls.pls, []*s2.Polygon{s2pgn}) {
12471247
return true, nil
12481248
}
12491249

geojson/geojson_shapes_util.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,12 @@ var GlueBytes = []byte("##")
391391
// can be used later while filering the doc values.
392392
func NewGeometryCollection(coordinates [][][][][]float64,
393393
typs []string) (index.GeoJSON, []byte, error) {
394+
if typs == nil {
395+
return nil, nil, fmt.Errorf("nil type information")
396+
}
397+
if len(typs) < len(coordinates) {
398+
return nil, nil, fmt.Errorf("missing type information for some shapes")
399+
}
394400
shapes := make([]index.GeoJSON, 0, len(coordinates))
395401
for i, vertices := range coordinates {
396402
s, _, err := NewGeoJsonShape(vertices, typs[i])

0 commit comments

Comments
 (0)