-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeo.go
68 lines (52 loc) · 1.51 KB
/
geo.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
package geo
import "math"
// calculate distance by two point
// http://www.movable-type.co.uk/scripts/latlong.html
const (
// one degree in radians
radPerDegree = math.Pi / 180.0
// Earth's radius in kilometres
earthRadius = 6371
)
// Point represents a single set of coordinates on Earth.
type Point struct {
lat, lon float64
}
// NewPoint returns a new Point with specified lat/lon coordinates in degrees.
func NewPoint(lat, lon float64) Point {
return Point{
lat: lat,
lon: lon,
}
}
// RadLat returns point's Latitude in radians.
func (p Point) RadLat() float64 {
return p.lat * radPerDegree
}
// RadLon returns point's Longtitude in radians.
func (p Point) RadLon() float64 {
return p.lon * radPerDegree
}
func (p Point) Lat() float64 {
return p.lat
}
func (p Point) Lon() float64 {
return p.lon
}
// DistanceHav calculates the distance between two points in kilometres.
// Haversine distance formula is used to calculate the distance.
func CalDistance(lon1, lat1, lon2, lat2 float64) float64 {
// http://www.movable-type.co.uk/scripts/latlong.html
p1 := Point{lat: lat1, lon: lon1}
p2 := Point{lat: lat2, lon: lon2}
lat1 = p1.RadLat()
lat2 = p2.RadLat()
deltaLat := lat2 - lat1
deltaLon := p2.RadLon() - p1.RadLon()
sqSinDLat := math.Pow(math.Sin(deltaLat/2), 2)
sqSinDLon := math.Pow(math.Sin(deltaLon/2), 2)
// left and right-hand sides of an eq for Haversine
a := sqSinDLat + sqSinDLon*math.Cos(lat1)*math.Cos(lat2)
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
return earthRadius * c
}