Skip to content

Commit a8f4556

Browse files
Updated intersection logic (#10)
* Changed polyline-polygon intersects logic Signed-off-by: Aditi Ahuja <[email protected]> * Modified logic for envelope linestring intersection. Signed-off-by: Aditi Ahuja <[email protected]>
1 parent 256c704 commit a8f4556

File tree

2 files changed

+28
-94
lines changed

2 files changed

+28
-94
lines changed

geojson/geojson_s2_util.go

+17-66
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,13 @@ func polylineIntersectsPolygons(pls []*s2.Polyline,
5656
for _, pl := range pls {
5757
for _, s2pgn := range s2pgns {
5858
for i := 0; i < pl.NumEdges(); i++ {
59-
edge := pl.Edge(i)
60-
a := []float64{edge.V0.X, edge.V0.Y}
61-
b := []float64{edge.V1.X, edge.V1.Y}
62-
6359
for i := 0; i < s2pgn.NumEdges(); i++ {
6460
edgeB := s2pgn.Edge(i)
61+
latLng1 := s2.LatLngFromPoint(edgeB.V0)
62+
latLng2 := s2.LatLngFromPoint(edgeB.V1)
63+
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})
6564

66-
c := []float64{edgeB.V0.X, edgeB.V0.Y}
67-
d := []float64{edgeB.V1.X, edgeB.V1.Y}
68-
69-
if doIntersect(a, b, c, d) {
65+
if pl.Intersects(pl2) {
7066
return true
7167
}
7268
}
@@ -144,20 +140,24 @@ func rectangleIntersectsWithPolygons(s2rect *s2.Rect,
144140

145141
func rectangleIntersectsWithLineStrings(s2rect *s2.Rect,
146142
polylines []*s2.Polyline) bool {
143+
// Early exit path if the envelope contains any of the linestring's vertices.
147144
for _, pl := range polylines {
148145
for i := 0; i < pl.NumEdges(); i++ {
149-
edgeA := pl.Edge(i)
150-
a := []float64{edgeA.V0.X, edgeA.V0.Y}
151-
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+
}
152153

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

157-
c := []float64{v1.X, v1.Y}
158-
d := []float64{v2.X, v2.Y}
159-
160-
if doIntersect(a, b, c, d) {
160+
if pl.Intersects(pl2) {
161161
return true
162162
}
163163
}
@@ -259,55 +259,6 @@ func min(a, b float64) float64 {
259259
return a
260260
}
261261

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

geojson/geojson_shapes_impl.go

+11-28
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)