GoBlog/geoTrack.go

118 lines
2.8 KiB
Go
Raw Normal View History

2021-11-10 10:13:30 +00:00
package main
import (
"encoding/json"
"errors"
"math"
"github.com/tkrajina/gpxgo/gpx"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
2021-11-13 19:19:46 +00:00
const gpxParameter = "gpx"
2021-11-10 15:27:27 +00:00
func (p *post) HasTrack() bool {
2021-11-13 19:19:46 +00:00
return p.firstParameter(gpxParameter) != ""
2021-11-10 10:13:30 +00:00
}
2021-11-10 15:27:27 +00:00
type trackResult struct {
2021-11-10 10:13:30 +00:00
HasPoints bool
2021-11-10 15:27:27 +00:00
Paths [][]*trackPoint
2021-11-10 10:13:30 +00:00
PathsJSON string
Kilometers string
Hours string
Name string
}
2021-11-10 15:27:27 +00:00
func (a *goBlog) getTrack(p *post) (result *trackResult, err error) {
2021-11-13 19:19:46 +00:00
gpxString := p.firstParameter(gpxParameter)
2021-11-10 10:13:30 +00:00
if gpxString == "" {
return nil, errors.New("no gpx parameter in post")
}
// Parse GPX
2021-11-10 15:27:27 +00:00
parseResult, err := trackParseGPX(gpxString)
2021-11-10 10:13:30 +00:00
if err != nil {
return nil, err
}
l, _ := language.Parse(a.cfg.Blogs[p.Blog].Lang)
lp := message.NewPrinter(l)
pathsJSON, err := json.Marshal(parseResult.paths)
if err != nil {
return nil, err
}
2021-11-10 15:27:27 +00:00
result = &trackResult{
2021-11-10 10:13:30 +00:00
HasPoints: len(parseResult.paths) > 0 && len(parseResult.paths[0]) > 0,
Paths: parseResult.paths,
PathsJSON: string(pathsJSON),
Name: parseResult.gpxData.Name,
Kilometers: lp.Sprintf("%.2f", parseResult.md.MovingDistance/1000),
Hours: lp.Sprintf(
"%.0f:%2.0f:%2.0f",
math.Floor(parseResult.md.MovingTime/3600), // Hours
math.Floor(math.Mod(parseResult.md.MovingTime, 3600)/60), // Minutes
math.Floor(math.Mod(parseResult.md.MovingTime, 60)), // Seconds
),
}
return result, nil
}
2021-11-10 15:27:27 +00:00
type trackPoint struct {
2021-11-10 10:13:30 +00:00
Lat, Lon float64
}
2021-11-10 15:27:27 +00:00
type trackParseResult struct {
paths [][]*trackPoint
2021-11-10 10:13:30 +00:00
gpxData *gpx.GPX
md *gpx.MovingData
}
2021-11-10 15:27:27 +00:00
func trackParseGPX(gpxString string) (result *trackParseResult, err error) {
result = &trackParseResult{}
2021-11-10 10:13:30 +00:00
2021-11-10 15:27:27 +00:00
type trackPath struct {
2021-11-10 10:13:30 +00:00
gpxMovingData *gpx.MovingData
2021-11-10 15:27:27 +00:00
points []*trackPoint
2021-11-10 10:13:30 +00:00
}
2021-11-10 15:27:27 +00:00
var paths []*trackPath
2021-11-10 10:13:30 +00:00
result.gpxData, err = gpx.ParseString(gpxString)
if err != nil {
return nil, err
}
for _, track := range result.gpxData.Tracks {
for _, segment := range track.Segments {
md := segment.MovingData()
2021-11-10 15:27:27 +00:00
path := &trackPath{
2021-11-10 10:13:30 +00:00
gpxMovingData: &md,
}
for _, point := range segment.Points {
2021-11-10 15:27:27 +00:00
path.points = append(path.points, &trackPoint{
2021-11-10 10:13:30 +00:00
Lat: point.GetLatitude(), Lon: point.GetLongitude(),
})
}
paths = append(paths, path)
}
}
result.md = &gpx.MovingData{}
for _, path := range paths {
// Combine moving data
result.md.MaxSpeed = math.Max(result.md.MaxSpeed, path.gpxMovingData.MaxSpeed)
result.md.MovingDistance = result.md.MovingDistance + path.gpxMovingData.MovingDistance
result.md.MovingTime = result.md.MovingTime + path.gpxMovingData.MovingTime
result.md.StoppedDistance = result.md.StoppedDistance + path.gpxMovingData.StoppedDistance
result.md.StoppedTime = result.md.StoppedTime + path.gpxMovingData.StoppedTime
// Add points
result.paths = append(result.paths, path.points)
}
return result, nil
}