Skip to content

Commit 30f5462

Browse files
committed
MB-66210: LineString and MultiLineString changes
1 parent 1674cdf commit 30f5462

File tree

3 files changed

+546
-59
lines changed

3 files changed

+546
-59
lines changed

geojson/geojson_s2_util.go

+28-29
Original file line numberDiff line numberDiff line change
@@ -39,33 +39,36 @@ func polylineIntersectsPoint(pls []*s2.Polyline,
3939
return false
4040
}
4141

42+
// check if any of the polyline vertices lie inside or
43+
// on the boundary of any of the polygons. Then check if
44+
// any of the polylines intersect with any of the edges of
45+
// the polygons
4246
func polylineIntersectsPolygons(pls []*s2.Polyline,
4347
s2pgns []*s2.Polygon) bool {
44-
// Early exit if the polygon contains any of the line's vertices.
48+
idx := s2.NewShapeIndex()
49+
for _, pgn := range s2pgns {
50+
idx.Add(pgn)
51+
}
52+
53+
containsQuery := s2.NewContainsPointQuery(idx, s2.VertexModelClosed)
4554
for _, pl := range pls {
46-
for i := 0; i < pl.NumEdges(); i++ {
47-
edge := pl.Edge(i)
48-
for _, s2pgn := range s2pgns {
49-
if s2pgn.IntersectsCell(s2.CellFromPoint(edge.V0)) ||
50-
s2pgn.IntersectsCell(s2.CellFromPoint(edge.V1)) {
51-
return true
52-
}
55+
for _, point := range *pl {
56+
if containsQuery.Contains(point) {
57+
return true
5358
}
5459
}
5560
}
5661

5762
for _, pl := range pls {
5863
for _, s2pgn := range s2pgns {
59-
for i := 0; i < pl.NumEdges(); i++ {
60-
for i := 0; i < s2pgn.NumEdges(); i++ {
61-
edgeB := s2pgn.Edge(i)
62-
latLng1 := s2.LatLngFromPoint(edgeB.V0)
63-
latLng2 := s2.LatLngFromPoint(edgeB.V1)
64-
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})
65-
66-
if pl.Intersects(pl2) {
67-
return true
68-
}
64+
for i := 0; i < s2pgn.NumEdges(); i++ {
65+
edgeB := s2pgn.Edge(i)
66+
latLng1 := s2.LatLngFromPoint(edgeB.V0)
67+
latLng2 := s2.LatLngFromPoint(edgeB.V1)
68+
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})
69+
70+
if pl.Intersects(pl2) {
71+
return true
6972
}
7073
}
7174
}
@@ -143,24 +146,20 @@ func rectangleIntersectsWithLineStrings(s2rect *s2.Rect,
143146
polylines []*s2.Polyline) bool {
144147
// Early exit path if the envelope contains any of the linestring's vertices.
145148
for _, pl := range polylines {
146-
for i := 0; i < pl.NumEdges(); i++ {
147-
edge := pl.Edge(i)
148-
if s2rect.IntersectsCell(s2.CellFromPoint(edge.V0)) ||
149-
s2rect.IntersectsCell(s2.CellFromPoint(edge.V1)) {
149+
for _, point := range *pl {
150+
if s2rect.ContainsPoint(point) {
150151
return true
151152
}
152153
}
153154
}
154155

155156
for _, pl := range polylines {
156-
for i := 0; i < pl.NumEdges(); i++ {
157-
for j := 0; j < 4; j++ {
158-
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{s2rect.Vertex(j),
159-
s2rect.Vertex((j + 1) % 4)})
157+
for i := 0; i < 4; i++ {
158+
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{s2rect.Vertex(i),
159+
s2rect.Vertex((i + 1) % 4)})
160160

161-
if pl.Intersects(pl2) {
162-
return true
163-
}
161+
if pl.Intersects(pl2) {
162+
return true
164163
}
165164
}
166165
}

geojson/geojson_shapes_impl.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ func (ls *LineString) Intersects(other index.GeoJSON) (bool, error) {
298298
}
299299

300300
func (ls *LineString) Contains(other index.GeoJSON) (bool, error) {
301+
ls.init()
301302
return checkLineStringsContainsShape([]*s2.Polyline{ls.pl}, other)
302303
}
303304

@@ -366,6 +367,7 @@ func (p *MultiLineString) Intersects(other index.GeoJSON) (bool, error) {
366367
}
367368

368369
func (p *MultiLineString) Contains(other index.GeoJSON) (bool, error) {
370+
p.init()
369371
return checkLineStringsContainsShape(p.pls, other)
370372
}
371373

@@ -1063,7 +1065,6 @@ func checkLineStringsIntersectsShape(pls []*s2.Polyline, shapeIn,
10631065
if p2, ok := other.(*MultiPoint); ok {
10641066
// check the intersection for any point in the collection.
10651067
for _, point := range p2.s2points {
1066-
10671068
if polylineIntersectsPoint(pls, point) {
10681069
return true, nil
10691070
}
@@ -1132,7 +1133,9 @@ func checkLineStringsIntersectsShape(pls []*s2.Polyline, shapeIn,
11321133
for i := 0; i < pl.NumEdges(); i++ {
11331134
edge := pl.Edge(i)
11341135
distance := s2.DistanceFromSegment(centre, edge.V0, edge.V1)
1135-
return distance <= c.s2cap.Radius(), nil
1136+
if distance <= c.s2cap.Radius() {
1137+
return true, nil
1138+
}
11361139
}
11371140
}
11381141

@@ -1154,6 +1157,27 @@ func checkLineStringsIntersectsShape(pls []*s2.Polyline, shapeIn,
11541157
// points and multipoints for the linestring vertices.
11551158
func checkLineStringsContainsShape(pls []*s2.Polyline,
11561159
other index.GeoJSON) (bool, error) {
1160+
// check if the other shape is a point.
1161+
if p2, ok := other.(*Point); ok {
1162+
if polylineIntersectsPoint(pls, p2.s2point) {
1163+
return true, nil
1164+
}
1165+
1166+
return false, nil
1167+
}
1168+
1169+
// check if the other shape is a multipoint.
1170+
if p2, ok := other.(*MultiPoint); ok {
1171+
// check the containment for every point in the collection.
1172+
for _, point := range p2.s2points {
1173+
if !polylineIntersectsPoint(pls, point) {
1174+
return false, nil
1175+
}
1176+
}
1177+
1178+
return true, nil
1179+
}
1180+
11571181
return false, nil
11581182
}
11591183

0 commit comments

Comments
 (0)