59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
type Location struct {
|
|
Timestamp int64
|
|
Lon float32
|
|
Lat float32
|
|
Alt float32
|
|
Acc float32
|
|
}
|
|
|
|
// Distance computes the distance (in meters) between two points
|
|
func (loc *Location) Distance(loc2 Location) float32 {
|
|
R := 6371e3 // metres
|
|
// Angles are in radians ( * math.Pi/180.0)
|
|
phi1 := loc.Lat * math.Pi / 180.0
|
|
phi2 := loc.Lon * math.Pi / 180.0
|
|
deltaPhi := (loc2.Lat - loc.Lat) * math.Pi / 180.0
|
|
deltaLambda := (loc2.Lon - loc.Lon) * math.Pi / 180.0
|
|
|
|
a := math.Sin(float64(deltaPhi/2))*math.Sin(float64(deltaPhi/2.0)) +
|
|
math.Cos(float64(phi1))*math.Cos(float64(phi2))*
|
|
math.Sin(float64(deltaLambda/2))*math.Sin(float64(deltaLambda/2))
|
|
c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
|
return float32(R * c)
|
|
}
|
|
|
|
/* Basic plausability check for the values */
|
|
func (l *Location) IsPlausible() bool {
|
|
// I keep those two comparisons for now
|
|
if l.Timestamp == 0 && l.Lon == 0 && l.Lat == 0 {
|
|
return false
|
|
}
|
|
// Sometimes I get updates with no location but a valid timestamp. Don't record those
|
|
if l.Lon == 0 && l.Lat == 0 {
|
|
return false
|
|
}
|
|
// Out of bounds
|
|
if l.Lon < -180 || l.Lon > 180 {
|
|
return false
|
|
}
|
|
if l.Lat < -90 || l.Lat > 90 {
|
|
return false
|
|
}
|
|
// Negative accuracy is not accepted
|
|
if l.Acc < 0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (l Location) String() string {
|
|
return fmt.Sprintf("Location{%d,%5.2f,%5.2f,%5.2f,%3.0f}", l.Timestamp, l.Lon, l.Lat, l.Alt, l.Acc)
|
|
}
|