ot-browser/cmd/ot-browser/location.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)
}