/
location.go
107 lines (87 loc) · 2.15 KB
/
location.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
99
100
101
102
103
104
105
106
107
package latvis
import (
"errors"
"time"
)
type Coordinate struct {
Lat float64
Lng float64
}
type BoundingBox struct {
lowerLeft Coordinate
upperRight Coordinate
}
func NewBoundingBox(lowerLeft, upperRight Coordinate) (*BoundingBox, error) {
if lowerLeft.Lat > upperRight.Lat {
return nil, errors.New("Latitude of lowerLeft must be less than longitude of upperRight")
}
return &BoundingBox{lowerLeft: lowerLeft, upperRight: upperRight}, nil
}
func (b *BoundingBox) LowerLeft() Coordinate {
return b.lowerLeft
}
func (b *BoundingBox) UpperRight() Coordinate {
return b.upperRight
}
func (b *BoundingBox) isReversed() bool {
return b.lowerLeft.Lng > b.upperRight.Lng
}
func (b *BoundingBox) Contains(c *Coordinate) bool {
boxShift := 0.0
pointShift := 0.0
if b.isReversed() {
boxShift = 360.0
if c.Lng < 0 {
pointShift = 360.0
}
}
return c.Lat > b.lowerLeft.Lat &&
c.Lat < b.upperRight.Lat &&
c.Lng+pointShift > b.lowerLeft.Lng &&
c.Lng+pointShift < b.upperRight.Lng+boxShift
}
func (b *BoundingBox) WidthFraction(c *Coordinate) float64 {
if b.isReversed() && c.Lng < 0 {
return (c.Lng + 360.0 - b.lowerLeft.Lng) / b.Width()
}
return (c.Lng - b.lowerLeft.Lng) / b.Width()
}
func (b *BoundingBox) HeightFraction(c *Coordinate) float64 {
return (c.Lat - b.lowerLeft.Lat) / b.Height()
}
func (b *BoundingBox) Width() float64 {
if b.isReversed() {
return b.upperRight.Lng - b.lowerLeft.Lng + 360
}
return b.upperRight.Lng - b.lowerLeft.Lng
}
func (b *BoundingBox) Height() float64 {
return b.upperRight.Lat - b.lowerLeft.Lat
}
type History []*Coordinate
func (h *History) Len() int {
return len(*h)
}
func (h *History) Add(c *Coordinate) {
history := *h
curLen := len(history)
if curLen+1 > cap(history) {
newHistory := make([]*Coordinate, curLen, 2*curLen+1)
copy(newHistory, history)
history = newHistory
}
history = history[0 : curLen+1]
history[curLen] = c
*h = history
}
func (this *History) AddAll(that *History) {
for i := 0; i < that.Len(); i++ {
this.Add(that.At(i))
}
}
func (h *History) At(i int) *Coordinate {
return (*h)[i]
}
type HistorySource interface {
FetchRange(start, end time.Time) (*History, error)
}