-
Notifications
You must be signed in to change notification settings - Fork 13
/
joins.go
77 lines (61 loc) · 1.73 KB
/
joins.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package turf
import (
"github.com/tomchavakis/geojson"
"github.com/tomchavakis/geojson/geometry"
)
// PointInPolygon takes a Point and a Polygon and determines if the point resides inside the polygon
func PointInPolygon(point geometry.Point, polygon geometry.Polygon) (bool, error) {
pArr := []geometry.Polygon{}
pArr = append(pArr, polygon)
mp, err := geometry.NewMultiPolygon(pArr)
if err != nil {
return false, err
}
return PointInMultiPolygon(point, *mp), nil
}
// PointInMultiPolygon takes a Point and a MultiPolygon and determines if the point resides inside the polygon
func PointInMultiPolygon(p geometry.Point, mp geometry.MultiPolygon) bool {
insidePoly := false
polys := mp.Coordinates
for i := 0; i < len(polys) && !insidePoly; i++ {
//check if it is in the outer ring first
if inRing(p, polys[i].Coordinates[0].Coordinates) {
inHole := false
temp := 1
// check for the point in any of the holes
for temp < len(polys[i].Coordinates) && !inHole {
if inRing(p, polys[i].Coordinates[temp].Coordinates) {
inHole = true
}
temp++
}
if !inHole {
insidePoly = true
}
}
}
return insidePoly
}
// InBBOX returns true if the point is within the Bounding Box
func InBBOX(pt geometry.Point, bbox geojson.BBOX) bool {
return bbox.West <= pt.Lng &&
bbox.South <= pt.Lat &&
bbox.East >= pt.Lng &&
bbox.North >= pt.Lat
}
func inRing(pt geometry.Point, ring []geometry.Point) bool {
isInside := false
j := 0
for i := 0; i < len(ring); i++ {
xi := ring[i].Lng
yi := ring[i].Lat
xj := ring[j].Lng
yj := ring[j].Lat
intersect := (yi > pt.Lat) != (yj > pt.Lat) && (pt.Lng < (xj-xi)*(pt.Lat-yi)/(yj-yi)+xi)
if intersect {
isInside = !isInside
}
j = i
}
return isInside
}