forked from gsn/predictor
114 lines
3.1 KiB
Go
114 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math"
|
|
"os"
|
|
)
|
|
|
|
type Point struct {
|
|
Datetime string `json:"datetime"`
|
|
Latitude float64 `json:"latitude"`
|
|
Longitude float64 `json:"longitude"`
|
|
Altitude float64 `json:"altitude"`
|
|
}
|
|
|
|
type Stage struct {
|
|
Stage string `json:"stage"`
|
|
Trajectory []Point `json:"trajectory"`
|
|
}
|
|
|
|
type Prediction struct {
|
|
Prediction []Stage `json:"prediction"`
|
|
}
|
|
|
|
func haversine(lat1, lon1, lat2, lon2 float64) float64 {
|
|
R := 6371000.0
|
|
phi1, phi2 := lat1*math.Pi/180, lat2*math.Pi/180
|
|
dphi := (lat2 - lat1) * math.Pi / 180
|
|
dlam := (lon2 - lon1) * math.Pi / 180
|
|
a := math.Sin(dphi/2)*math.Sin(dphi/2) + math.Cos(phi1)*math.Cos(phi2)*math.Sin(dlam/2)*math.Sin(dlam/2)
|
|
return R * 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
|
}
|
|
|
|
func load(path string) Prediction {
|
|
data, _ := os.ReadFile(path)
|
|
var p Prediction
|
|
json.Unmarshal(data, &p)
|
|
return p
|
|
}
|
|
|
|
func main() {
|
|
our := load("c:/tmp/our.json")
|
|
taw := load("c:/tmp/tawhiri.json")
|
|
|
|
// Find burst and landing points
|
|
var ourBurst, ourLand, tawBurst, tawLand Point
|
|
for _, s := range our.Prediction {
|
|
t := s.Trajectory
|
|
if s.Stage == "ascent" {
|
|
ourBurst = t[len(t)-1]
|
|
}
|
|
if s.Stage == "descent" {
|
|
ourLand = t[len(t)-1]
|
|
}
|
|
}
|
|
for _, s := range taw.Prediction {
|
|
t := s.Trajectory
|
|
if s.Stage == "ascent" {
|
|
tawBurst = t[len(t)-1]
|
|
}
|
|
if s.Stage == "descent" {
|
|
tawLand = t[len(t)-1]
|
|
}
|
|
}
|
|
|
|
fmt.Println("=== Burst Point ===")
|
|
fmt.Printf(" Our: lat=%.4f, lon=%.4f, alt=%.0f, time=%s\n", ourBurst.Latitude, ourBurst.Longitude, ourBurst.Altitude, ourBurst.Datetime)
|
|
fmt.Printf(" Tawhiri: lat=%.4f, lon=%.4f, alt=%.0f, time=%s\n", tawBurst.Latitude, tawBurst.Longitude, tawBurst.Altitude, tawBurst.Datetime)
|
|
burstDist := haversine(ourBurst.Latitude, ourBurst.Longitude, tawBurst.Latitude, tawBurst.Longitude)
|
|
fmt.Printf(" Distance: %.2f km\n", burstDist/1000)
|
|
|
|
fmt.Println()
|
|
fmt.Println("=== Landing Point ===")
|
|
fmt.Printf(" Our: lat=%.4f, lon=%.4f, alt=%.0f, time=%s\n", ourLand.Latitude, ourLand.Longitude, ourLand.Altitude, ourLand.Datetime)
|
|
fmt.Printf(" Tawhiri: lat=%.4f, lon=%.4f, alt=%.0f, time=%s\n", tawLand.Latitude, tawLand.Longitude, tawLand.Altitude, tawLand.Datetime)
|
|
landDist := haversine(ourLand.Latitude, ourLand.Longitude, tawLand.Latitude, tawLand.Longitude)
|
|
fmt.Printf(" Distance: %.2f km\n", landDist/1000)
|
|
|
|
fmt.Println()
|
|
fmt.Println("=== Trajectory Comparison (every 10 min) ===")
|
|
ourPts := map[string]Point{}
|
|
tawPts := map[string]Point{}
|
|
for _, s := range our.Prediction {
|
|
for _, p := range s.Trajectory {
|
|
ourPts[p.Datetime] = p
|
|
}
|
|
}
|
|
for _, s := range taw.Prediction {
|
|
for _, p := range s.Trajectory {
|
|
tawPts[p.Datetime] = p
|
|
}
|
|
}
|
|
|
|
// Collect common times
|
|
var common []string
|
|
for _, s := range our.Prediction {
|
|
for _, p := range s.Trajectory {
|
|
if _, ok := tawPts[p.Datetime]; ok {
|
|
common = append(common, p.Datetime)
|
|
}
|
|
}
|
|
}
|
|
|
|
for i, t := range common {
|
|
if i%10 == 0 {
|
|
o := ourPts[t]
|
|
tw := tawPts[t]
|
|
d := haversine(o.Latitude, o.Longitude, tw.Latitude, tw.Longitude)
|
|
fmt.Printf(" %s: dist=%.2f km (our: %.3f,%.3f vs taw: %.3f,%.3f)\n",
|
|
t, d/1000, o.Latitude, o.Longitude, tw.Latitude, tw.Longitude)
|
|
}
|
|
}
|
|
}
|