-
Notifications
You must be signed in to change notification settings - Fork 6
/
stop_collection.go
98 lines (83 loc) · 2.17 KB
/
stop_collection.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package gtfs
import (
"math"
"sort"
)
type StopDistanceResult struct {
Stop *Stop
Distance float64
}
type StopDistanceResults []*StopDistanceResult
func (s StopDistanceResults) Len() int { return len(s) }
func (s StopDistanceResults) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s StopDistanceResults) Less(i, j int) bool { return s[i].Distance < s[j].Distance }
type StopCollection struct {
Stops map[string]*Stop
qt *QuadTree
maxLat float64
maxLon float64
minLat float64
minLon float64
}
func NewStopCollection() StopCollection {
return StopCollection{
Stops: make(map[string]*Stop),
qt: nil,
maxLat: math.Inf(-1),
maxLon: math.Inf(-1),
minLat: math.Inf(1),
minLon: math.Inf(1),
}
}
func (c *StopCollection) Length() int {
return len(c.Stops)
}
func (c *StopCollection) Stop(id string) (stop *Stop) {
return c.Stops[id]
}
func (c *StopCollection) SetStop(id string, stop *Stop) {
c.Stops[id] = stop
c.maxLat = math.Max(c.maxLat, stop.Lat)
c.maxLon = math.Max(c.maxLon, stop.Lon)
c.minLat = math.Min(c.minLat, stop.Lat)
c.minLon = math.Min(c.minLon, stop.Lon)
}
func (c *StopCollection) createQuadtree() {
c.qt = CreateQuadtree(c.minLat, c.maxLat, c.minLon, c.maxLon)
for _, stop := range c.Stops {
c.qt.Insert(stop)
}
}
func (c *StopCollection) StopsByName(name string) (results []*Stop) {
for _, stop := range c.Stops {
if stop.Name == name {
results = append(results, stop)
}
}
return
}
func (c *StopCollection) StopsByProximity(lat, lng, radius float64) (results []*Stop) {
if c.qt == nil {
c.createQuadtree()
}
return c.qt.SearchByProximity(lat, lng, radius)
}
func (c *StopCollection) StopDistancesByProximity(lat, lng, radius float64) (results StopDistanceResults) {
stops := c.StopsByProximity(lat, lng, radius)
stopdistances := make(StopDistanceResults, len(stops))
for i, stop := range stops {
stopdistances[i] = &StopDistanceResult{Stop: stop, Distance: stop.DistanceToCoordinate(lat, lng)}
}
sort.Sort(stopdistances)
return stopdistances
}
func (c *StopCollection) RandomStop() (stopX *Stop) {
stopsCount := 0
for _, stopX = range c.Stops {
if stopsCount > 10 {
break
}
stopsCount += 1
}
return
}