Skip to content

Updated intersection logic #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 17 additions & 66 deletions geojson/geojson_s2_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,13 @@ func polylineIntersectsPolygons(pls []*s2.Polyline,
for _, pl := range pls {
for _, s2pgn := range s2pgns {
for i := 0; i < pl.NumEdges(); i++ {
edge := pl.Edge(i)
a := []float64{edge.V0.X, edge.V0.Y}
b := []float64{edge.V1.X, edge.V1.Y}

for i := 0; i < s2pgn.NumEdges(); i++ {
edgeB := s2pgn.Edge(i)
latLng1 := s2.LatLngFromPoint(edgeB.V0)
latLng2 := s2.LatLngFromPoint(edgeB.V1)
pl2 := s2.PolylineFromLatLngs([]s2.LatLng{latLng1, latLng2})

c := []float64{edgeB.V0.X, edgeB.V0.Y}
d := []float64{edgeB.V1.X, edgeB.V1.Y}

if doIntersect(a, b, c, d) {
if pl.Intersects(pl2) {
return true
}
}
Expand Down Expand Up @@ -144,20 +140,24 @@ func rectangleIntersectsWithPolygons(s2rect *s2.Rect,

func rectangleIntersectsWithLineStrings(s2rect *s2.Rect,
polylines []*s2.Polyline) bool {
// Early exit path if the envelope contains any of the linestring's vertices.
for _, pl := range polylines {
for i := 0; i < pl.NumEdges(); i++ {
edgeA := pl.Edge(i)
a := []float64{edgeA.V0.X, edgeA.V0.Y}
b := []float64{edgeA.V1.X, edgeA.V1.Y}
edge := pl.Edge(i)
if s2rect.IntersectsCell(s2.CellFromPoint(edge.V0)) ||
s2rect.IntersectsCell(s2.CellFromPoint(edge.V1)) {
return true
}
}
}

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

c := []float64{v1.X, v1.Y}
d := []float64{v2.X, v2.Y}

if doIntersect(a, b, c, d) {
if pl.Intersects(pl2) {
return true
}
}
Expand Down Expand Up @@ -259,55 +259,6 @@ func min(a, b float64) float64 {
return a
}

func onsegment(p, q, r []float64) bool {
if q[0] <= max(p[0], r[0]) && q[0] >= min(p[0], r[0]) &&
q[1] <= max(p[1], r[1]) && q[1] >= min(p[1], r[1]) {
return true
}

return false
}

func doIntersect(p1, q1, p2, q2 []float64) bool {
o1 := orientation(p1, q1, p2)
o2 := orientation(p1, q1, q2)
o3 := orientation(p2, q2, p1)
o4 := orientation(p2, q2, q1)

if o1 != o2 && o3 != o4 {
return true
}

if o1 == 0 && onsegment(p1, p2, q1) {
return true
}

if o2 == 0 && onsegment(p1, q2, q1) {
return true
}

if o3 == 0 && onsegment(p2, p1, q2) {
return true
}

if o4 == 0 && onsegment(p2, q1, q2) {
return true
}

return false
}

func orientation(p, q, r []float64) int {
val := (q[1]-p[1])*(r[0]-q[0]) - (q[0]-p[0])*(r[1]-q[1])
if val == 0 {
return 0
}
if val > 0 {
return 1
}
return 2
}

func StripCoveringTerms(terms []string) []string {
rv := make([]string, 0, len(terms))
for _, term := range terms {
Expand Down
39 changes: 11 additions & 28 deletions geojson/geojson_shapes_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type compositeShape interface {
Members() []index.GeoJSON
}

//--------------------------------------------------------
// --------------------------------------------------------
// Point represents the geoJSON point type and it
// implements the index.GeoJSON interface.
type Point struct {
Expand Down Expand Up @@ -141,7 +141,7 @@ func (p *Point) Coordinates() []float64 {
return p.Vertices
}

//--------------------------------------------------------
// --------------------------------------------------------
// MultiPoint represents the geoJSON multipoint type and it
// implements the index.GeoJSON interface as well as the
// compositeShap interface.
Expand Down Expand Up @@ -247,7 +247,7 @@ func (p *MultiPoint) Members() []index.GeoJSON {
return points
}

//--------------------------------------------------------
// --------------------------------------------------------
// LineString represents the geoJSON linestring type and it
// implements the index.GeoJSON interface.
type LineString struct {
Expand Down Expand Up @@ -309,7 +309,7 @@ func (ls *LineString) Coordinates() [][]float64 {
return ls.Vertices
}

//--------------------------------------------------------
// --------------------------------------------------------
// MultiLineString represents the geoJSON multilinestring type
// and it implements the index.GeoJSON interface as well as the
// compositeShap interface.
Expand Down Expand Up @@ -393,7 +393,7 @@ func (p *MultiLineString) Members() []index.GeoJSON {
return lines
}

//--------------------------------------------------------
// --------------------------------------------------------
// Polygon represents the geoJSON polygon type
// and it implements the index.GeoJSON interface.
type Polygon struct {
Expand Down Expand Up @@ -455,7 +455,7 @@ func (p *Polygon) Coordinates() [][][]float64 {
return p.Vertices
}

//--------------------------------------------------------
// --------------------------------------------------------
// MultiPolygon represents the geoJSON multipolygon type
// and it implements the index.GeoJSON interface as well as the
// compositeShap interface.
Expand Down Expand Up @@ -553,7 +553,7 @@ func (p *MultiPolygon) Members() []index.GeoJSON {
return polygons
}

//--------------------------------------------------------
// --------------------------------------------------------
// GeometryCollection represents the geoJSON geometryCollection type
// and it implements the index.GeoJSON interface as well as the
// compositeShap interface.
Expand Down Expand Up @@ -743,7 +743,7 @@ func (gc *GeometryCollection) UnmarshalJSON(data []byte) error {
return nil
}

//--------------------------------------------------------
// --------------------------------------------------------
// Circle represents a custom circle type and it
// implements the index.GeoJSON interface.
type Circle struct {
Expand Down Expand Up @@ -828,7 +828,7 @@ func (c *Circle) UnmarshalJSON(data []byte) error {
return err
}

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

// check if the other shape is a envelope.
if e, ok := other.(*Envelope); ok {
for _, pl := range pls {
for i := 0; i < pl.NumEdges(); i++ {
edge := pl.Edge(i)
latlng1 := s2.LatLngFromPoint(edge.V0)
latlng2 := s2.LatLngFromPoint(edge.V1)
a := []float64{latlng1.Lng.Degrees(), latlng1.Lat.Degrees()}
b := []float64{latlng2.Lng.Degrees(), latlng2.Lat.Degrees()}
for j := 0; j < 4; j++ {
v1 := e.r.Vertex(j)
v2 := e.r.Vertex((j + 1) % 4)
c := []float64{v1.Lng.Degrees(), v1.Lat.Degrees()}
d := []float64{v2.Lng.Degrees(), v2.Lat.Degrees()}
if doIntersect(a, b, c, d) {
return true, nil
}
}
}
}
res := rectangleIntersectsWithLineStrings(e.r, pls)

return false, nil
return res, nil
}

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