Skip to content

Commit 3a97f16

Browse files
metonymic-smokeyAditi Ahuja
authored andcommitted
Modified logic for envelope linestring intersection.
1 parent 44b143d commit 3a97f16

File tree

2 files changed

+26
-88
lines changed

2 files changed

+26
-88
lines changed

geojson/geojson_s2_util.go

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ func polylineIntersectsPolygons(pls []*s2.Polyline,
6060
edgeB := s2pgn.Edge(i)
6161
latLng1 := s2.LatLngFromPoint(edgeB.V0)
6262
latLng2 := s2.LatLngFromPoint(edgeB.V1)
63-
pgnLine := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})
63+
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})
6464

65-
if pl.Intersects(pgnLine) {
65+
if pl.Intersects(pl2) {
6666
return true
6767
}
6868
}
@@ -140,20 +140,24 @@ func rectangleIntersectsWithPolygons(s2rect *s2.Rect,
140140

141141
func rectangleIntersectsWithLineStrings(s2rect *s2.Rect,
142142
polylines []*s2.Polyline) bool {
143+
// Early exit path if the envelope contains any of the linestring's vertices.
143144
for _, pl := range polylines {
144145
for i := 0; i < pl.NumEdges(); i++ {
145-
edgeA := pl.Edge(i)
146-
a := []float64{edgeA.V0.X, edgeA.V0.Y}
147-
b := []float64{edgeA.V1.X, edgeA.V1.Y}
146+
edge := pl.Edge(i)
147+
if s2rect.IntersectsCell(s2.CellFromPoint(edge.V0)) ||
148+
s2rect.IntersectsCell(s2.CellFromPoint(edge.V1)) {
149+
return true
150+
}
151+
}
152+
}
148153

154+
for _, pl := range polylines {
155+
for i := 0; i < pl.NumEdges(); i++ {
149156
for j := 0; j < 4; j++ {
150-
v1 := s2.PointFromLatLng(s2rect.Vertex(j))
151-
v2 := s2.PointFromLatLng(s2rect.Vertex((j + 1) % 4))
157+
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{s2rect.Vertex(j),
158+
s2rect.Vertex((j + 1) % 4)})
152159

153-
c := []float64{v1.X, v1.Y}
154-
d := []float64{v2.X, v2.Y}
155-
156-
if doIntersect(a, b, c, d) {
160+
if pl.Intersects(pl2) {
157161
return true
158162
}
159163
}
@@ -255,55 +259,6 @@ func min(a, b float64) float64 {
255259
return a
256260
}
257261

258-
func onsegment(p, q, r []float64) bool {
259-
if q[0] <= max(p[0], r[0]) && q[0] >= min(p[0], r[0]) &&
260-
q[1] <= max(p[1], r[1]) && q[1] >= min(p[1], r[1]) {
261-
return true
262-
}
263-
264-
return false
265-
}
266-
267-
func doIntersect(p1, q1, p2, q2 []float64) bool {
268-
o1 := orientation(p1, q1, p2)
269-
o2 := orientation(p1, q1, q2)
270-
o3 := orientation(p2, q2, p1)
271-
o4 := orientation(p2, q2, q1)
272-
273-
if o1 != o2 && o3 != o4 {
274-
return true
275-
}
276-
277-
if o1 == 0 && onsegment(p1, p2, q1) {
278-
return true
279-
}
280-
281-
if o2 == 0 && onsegment(p1, q2, q1) {
282-
return true
283-
}
284-
285-
if o3 == 0 && onsegment(p2, p1, q2) {
286-
return true
287-
}
288-
289-
if o4 == 0 && onsegment(p2, q1, q2) {
290-
return true
291-
}
292-
293-
return false
294-
}
295-
296-
func orientation(p, q, r []float64) int {
297-
val := (q[1]-p[1])*(r[0]-q[0]) - (q[0]-p[0])*(r[1]-q[1])
298-
if val == 0 {
299-
return 0
300-
}
301-
if val > 0 {
302-
return 1
303-
}
304-
return 2
305-
}
306-
307262
func StripCoveringTerms(terms []string) []string {
308263
rv := make([]string, 0, len(terms))
309264
for _, term := range terms {

geojson/geojson_shapes_impl.go

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ type compositeShape interface {
7777
Members() []index.GeoJSON
7878
}
7979

80-
//--------------------------------------------------------
80+
// --------------------------------------------------------
8181
// Point represents the geoJSON point type and it
8282
// implements the index.GeoJSON interface.
8383
type Point struct {
@@ -141,7 +141,7 @@ func (p *Point) Coordinates() []float64 {
141141
return p.Vertices
142142
}
143143

144-
//--------------------------------------------------------
144+
// --------------------------------------------------------
145145
// MultiPoint represents the geoJSON multipoint type and it
146146
// implements the index.GeoJSON interface as well as the
147147
// compositeShap interface.
@@ -247,7 +247,7 @@ func (p *MultiPoint) Members() []index.GeoJSON {
247247
return points
248248
}
249249

250-
//--------------------------------------------------------
250+
// --------------------------------------------------------
251251
// LineString represents the geoJSON linestring type and it
252252
// implements the index.GeoJSON interface.
253253
type LineString struct {
@@ -309,7 +309,7 @@ func (ls *LineString) Coordinates() [][]float64 {
309309
return ls.Vertices
310310
}
311311

312-
//--------------------------------------------------------
312+
// --------------------------------------------------------
313313
// MultiLineString represents the geoJSON multilinestring type
314314
// and it implements the index.GeoJSON interface as well as the
315315
// compositeShap interface.
@@ -393,7 +393,7 @@ func (p *MultiLineString) Members() []index.GeoJSON {
393393
return lines
394394
}
395395

396-
//--------------------------------------------------------
396+
// --------------------------------------------------------
397397
// Polygon represents the geoJSON polygon type
398398
// and it implements the index.GeoJSON interface.
399399
type Polygon struct {
@@ -455,7 +455,7 @@ func (p *Polygon) Coordinates() [][][]float64 {
455455
return p.Vertices
456456
}
457457

458-
//--------------------------------------------------------
458+
// --------------------------------------------------------
459459
// MultiPolygon represents the geoJSON multipolygon type
460460
// and it implements the index.GeoJSON interface as well as the
461461
// compositeShap interface.
@@ -553,7 +553,7 @@ func (p *MultiPolygon) Members() []index.GeoJSON {
553553
return polygons
554554
}
555555

556-
//--------------------------------------------------------
556+
// --------------------------------------------------------
557557
// GeometryCollection represents the geoJSON geometryCollection type
558558
// and it implements the index.GeoJSON interface as well as the
559559
// compositeShap interface.
@@ -743,7 +743,7 @@ func (gc *GeometryCollection) UnmarshalJSON(data []byte) error {
743743
return nil
744744
}
745745

746-
//--------------------------------------------------------
746+
// --------------------------------------------------------
747747
// Circle represents a custom circle type and it
748748
// implements the index.GeoJSON interface.
749749
type Circle struct {
@@ -828,7 +828,7 @@ func (c *Circle) UnmarshalJSON(data []byte) error {
828828
return err
829829
}
830830

831-
//--------------------------------------------------------
831+
// --------------------------------------------------------
832832
// Envelope represents the envelope/bounding box type and it
833833
// implements the index.GeoJSON interface.
834834
type Envelope struct {
@@ -1143,26 +1143,9 @@ func checkLineStringsIntersectsShape(pls []*s2.Polyline, shapeIn,
11431143

11441144
// check if the other shape is a envelope.
11451145
if e, ok := other.(*Envelope); ok {
1146-
for _, pl := range pls {
1147-
for i := 0; i < pl.NumEdges(); i++ {
1148-
edge := pl.Edge(i)
1149-
latlng1 := s2.LatLngFromPoint(edge.V0)
1150-
latlng2 := s2.LatLngFromPoint(edge.V1)
1151-
a := []float64{latlng1.Lng.Degrees(), latlng1.Lat.Degrees()}
1152-
b := []float64{latlng2.Lng.Degrees(), latlng2.Lat.Degrees()}
1153-
for j := 0; j < 4; j++ {
1154-
v1 := e.r.Vertex(j)
1155-
v2 := e.r.Vertex((j + 1) % 4)
1156-
c := []float64{v1.Lng.Degrees(), v1.Lat.Degrees()}
1157-
d := []float64{v2.Lng.Degrees(), v2.Lat.Degrees()}
1158-
if doIntersect(a, b, c, d) {
1159-
return true, nil
1160-
}
1161-
}
1162-
}
1163-
}
1146+
res := rectangleIntersectsWithLineStrings(e.r, pls)
11641147

1165-
return false, nil
1148+
return res, nil
11661149
}
11671150

11681151
return false, fmt.Errorf("unknown geojson type: %s "+

0 commit comments

Comments
 (0)