-
Notifications
You must be signed in to change notification settings - Fork 0
/
geosearch.go
71 lines (59 loc) · 1.35 KB
/
geosearch.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
package geosearch
import (
"time"
)
type Point struct {
Latitude float64
Longitude float64
}
type Object struct {
Id string
Point
Neighbours []*Object
}
type Result struct {
Object *Object
Distance float64
Took time.Duration
}
type GeoSearch struct {
objects []*Object
distanceBetweenNeighbours float64
}
func GeoSearchNew(distanceBetweenNeighbours float64) GeoSearch {
return GeoSearch{
objects: make([]*Object, 0),
distanceBetweenNeighbours: distanceBetweenNeighbours,
}
}
func (gs *GeoSearch) AddObject(obj *Object) {
if len(gs.objects) > 0 {
for i := 0; i < len(gs.objects); i++ {
distance := Haversine(obj.Point, gs.objects[i].Point)
if distance <= gs.distanceBetweenNeighbours {
obj.Neighbours = append(obj.Neighbours, gs.objects[i])
gs.objects[i].Neighbours = append(gs.objects[i].Neighbours, obj)
}
}
}
gs.objects = append(gs.objects, obj)
}
func (gs *GeoSearch) Search(point Point, obj *Object) Result {
start := time.Now()
distance := Haversine(point, obj.Point)
for {
found := false
for _, obj2 := range obj.Neighbours {
distance2 := Haversine(point, obj2.Point)
if distance2 < distance {
obj = obj2
distance = distance2
found = true
}
}
if !found {
break
}
}
return Result{Object: obj, Distance: distance, Took: time.Since(start)}
}