Skip to content
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

[feature] add contains point functionality #242

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
47 changes: 47 additions & 0 deletions contains.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package geom

// https://wrfranklin.org/Research/Short_Notes/pnpoly.html
func pnPoly(coords []Coord, pt Coord) bool {
var in bool
n := len(coords)
for i, j := 0, n-1; i < n; j, i = i, i+1 {
if (coords[i][1] > pt[1]) != (coords[j][1] > pt[1]) && (pt[0] < (coords[j][0]-coords[i][0])*(pt[1]-coords[i][1])/(coords[j][1]-coords[i][1])+coords[i][0]) {
in = !in
}
}
return in
}

// ContainsPoint reports whether a geometry T contains the given point.
func ContainsPoint(geo T, point *Point) bool {
if geo.Bounds().OverlapsPoint(point.Layout(), point.Coords()) {
zero := NewPoint(point.Layout()).Coords()
switch g := geo.(type) {
case *Point:
return g == point
case *LinearRing:
pnPoly(g.Coords(), point.Coords())
case *Polygon:
var coords []Coord
for r := 0; r < g.NumLinearRings(); r++ {
ring := g.LinearRing(r)
c := ring.Coords()
coords = append(append(append(coords, zero), c...), zero)
}
return pnPoly(coords, point.Coords())
case *MultiPolygon:
for pl := 0; pl < g.NumPolygons(); pl++ {
if ContainsPoint(g.Polygon(pl), point) {
return true
}
}
case *GeometryCollection:
for i := 0; i < g.NumGeoms(); i++ {
if ContainsPoint(g.Geom(i), point) {
return true
}
}
}
}
return false
}
60 changes: 60 additions & 0 deletions contains_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package geom

import (
"testing"

"github.com/stretchr/testify/assert"
)

var testGeo = []struct {
geom T
pts []*Point
in []bool
}{
{
NewPolygon(XY).MustSetCoords([][]Coord{
{
{24.950899, 60.169158},
{24.953492, 60.169158},
{24.953510, 60.170104},
{24.950958, 60.169990},
{24.950899, 60.169158},
},
}),
[]*Point{
NewPoint(XY).MustSetCoords(Coord{24.952242, 60.1696017}),
NewPoint(XY).MustSetCoords(Coord{24.976567, 60.1612500}),
},
[]bool{
true,
false,
},
},
{
NewPolygon(XY).MustSetCoords([][]Coord{
{
{40.7711, -73.9345},
{40.7710, -73.9342},
{40.7704, -73.9344},
{40.7702, -73.9345},
{40.7711, -73.9345},
},
}),
[]*Point{
NewPoint(XY).MustSetCoords(Coord{40.7705, -73.9394}),
NewPoint(XY).MustSetCoords(Coord{40.7707, -73.9344}),
},
[]bool{
false,
true,
},
},
}

func TestContain(t *testing.T) {
for i, test := range testGeo {
for j, pt := range test.pts {
assert.Equal(t, test.in[j], ContainsPoint(test.geom, pt), "not match in geom[%d] and pt[%d]", i, j)
}
}
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/alecthomas/assert/v2 v2.4.0
github.com/lib/pq v1.10.9
github.com/ory/dockertest/v3 v3.9.1
github.com/stretchr/testify v1.8.1
github.com/twpayne/go-kml/v3 v3.1.0
)

Expand All @@ -17,6 +18,7 @@ require (
github.com/alecthomas/repr v0.3.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
Expand All @@ -31,8 +33,8 @@ require (
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.12 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/stretchr/testify v1.8.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
Expand Down
Loading