-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgps-stats.go
206 lines (183 loc) · 5.72 KB
/
gps-stats.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"github.com/vvidovic/gps-stats/internal/stats"
"github.com/vvidovic/gps-stats/internal/version"
)
var (
helpFlag *bool
versionFlag *bool
statTypeFlag *string
cleanupDeltaSpeedFlag *float64
speedUnitsFlag *string
saveFilteredGpxFlag *bool
)
func main() {
helpFlag = flag.Bool("h", false, "Show gps-stats usage with examples")
versionFlag = flag.Bool("v", false, "Show gps-stats version")
statTypeFlag = flag.String("t", "all",
"Set the statistics type to print (all, 2s, 10sAvg, 10s1, 10s2, 10s3, 10s4, 10s5, 15m, 1h, 100m, 1nm, alpha - default all)")
cleanupDeltaSpeedFlag = flag.Float64("cs", 0,
"Clean up points where speed changes are more than given number of speed units (default 5 kts)")
speedUnitsFlag = flag.String("su", "kts",
"Set the speed units printed (kts, kmh, ms - default kts)")
saveFilteredGpxFlag = flag.Bool("sf", false, "Save filtered track to a new GPX file")
flag.Parse()
if *versionFlag {
showVersion()
} else if *helpFlag {
showUsage(0)
} else if len(flag.Args()) < 1 {
showUsage(1)
} else {
statType := stats.StatNone
switch *statTypeFlag {
case "all":
statType = stats.StatAll
case "2s":
statType = stats.Stat2s
case "10sAvg":
statType = stats.Stat10sAvg
case "10s1":
statType = stats.Stat10s1
case "10s2":
statType = stats.Stat10s2
case "10s3":
statType = stats.Stat10s3
case "10s4":
statType = stats.Stat10s4
case "10s5":
statType = stats.Stat10s5
case "15m":
statType = stats.Stat15m
case "1h":
statType = stats.Stat1h
case "100m":
statType = stats.Stat100m
case "1nm":
statType = stats.Stat1nm
case "alpha":
statType = stats.StatAlpha
default:
showUsage(2)
return
}
speedUnits := stats.UnitsKts
switch *speedUnitsFlag {
case "kts":
speedUnits = stats.UnitsKts
case "kmh":
speedUnits = stats.UnitsKmh
case "ms":
speedUnits = stats.UnitsMs
default:
showUsage(2)
return
}
for i := 0; i < len(flag.Args()); i++ {
printStatsForFile(flag.Args()[i], statType, speedUnits)
}
}
}
func printStatsForFile(filePath string, statType stats.StatFlag, speedUnits stats.UnitsFlag) {
f, err := os.Open(filePath)
if err != nil {
return
}
fileName := filepath.Base(f.Name())
r := bufio.NewReader(f)
points, err := stats.ReadPoints(r)
if err != nil && err != io.EOF {
fmt.Printf("Error reading track points from '%s': %v\n", fileName, err)
if statType == stats.StatAll {
fmt.Println("")
}
return
}
pointsNo := len(points.Ps)
cleanupDeltaSpeed := *cleanupDeltaSpeedFlag
if cleanupDeltaSpeed == 0 {
cleanupDeltaSpeed = stats.MsToUnits(stats.KtsToMs(5.0), speedUnits)
}
ps := stats.CleanUp(points, cleanupDeltaSpeed, speedUnits)
points.Ps = ps
pointsCleanedNo := len(ps)
if *saveFilteredGpxFlag {
newFilePath := filePath + ".filtered.gpx"
f, err := os.Create(newFilePath)
if err != nil {
fmt.Printf("Error creating new file '%s' for GPX export: %v\n", newFilePath, err)
if statType == stats.StatAll {
fmt.Println("")
}
return
}
err = stats.SavePointsAsGpx(points, f)
if err != nil {
fmt.Printf("Error saving file '%s' for GPX export: %v\n", newFilePath, err)
if statType == stats.StatAll {
fmt.Println("")
}
return
}
fmt.Printf("Filtered GPX file '%s' saved.\n", newFilePath)
if statType == stats.StatAll {
fmt.Println("")
}
}
s := stats.CalculateStats(ps, statType, speedUnits)
switch statType {
case stats.StatAll:
fmt.Printf("Found %d track points in '%s', after cleanup %d points left.\n",
pointsNo, fileName, pointsCleanedNo)
fmt.Print(s.TxtStats())
default:
fmt.Printf("%s (%s)", s.TxtSingleStat(statType), fileName)
}
fmt.Println("")
}
func showVersion() {
fmt.Printf("gps-stat version %s %s %s\n", version.Version, version.Platform, version.BuildTime)
os.Exit(0)
}
// usage prints usage help information with examples to console.
func showUsage(exitStatus int) {
fmt.Println("Usage:")
fmt.Printf(" %s [Flags] GPS_data_file1 [GPS_data_file2 ...]\n", os.Args[0])
fmt.Println("")
fmt.Println("Parses 1 or more GPS data files (SBN or GPX)")
fmt.Println("")
fmt.Println("Flags:")
fmt.Println(" -h Show usage (optional)")
fmt.Println(" -v Show version (optional)")
fmt.Println(" -t Set the statistics type to print (optional, default all)")
fmt.Println(" (all, 2s, 10sAvg, 10s1, 10s2, 10s3, 10s4, 10s5, 15m, 1h, 100m, 1nm, alpha)")
fmt.Println(" -su Set the speed units to print (optional, default kts)")
fmt.Println(" (kts, kmh, ms)")
fmt.Println(" -sf Save filtered points as a new GPX file without points detected as errors")
fmt.Println(" with suffix '.filtered.gpx' (optional)")
fmt.Println("")
fmt.Println(" -cs Clean up points where speed changes are more than given number of speed units (default 5 kts)")
fmt.Println(" Calculation uses 4 points. It calculates 3 speeds based on those points.")
fmt.Println(" After that, 2 speed changes are calculated and difference between those changes is")
fmt.Println(" used to filter points.")
fmt.Println("")
fmt.Println("Examples:")
fmt.Printf(" %s my_gps_data.SBN\n", os.Args[0])
fmt.Println(" - runs analysis of the SBN data")
fmt.Println("")
fmt.Printf(" %s -cs 7 my_gps_data.gpx\n", os.Args[0])
fmt.Println(" - runs analysis of the SBN data with custom clean up settings")
fmt.Println("")
fmt.Printf(" %s -t=1nm *.SBN *.gpx\n", os.Args[0])
fmt.Println(" - runs analysis of multiple SBN & GPX data only for 1 NM statistics")
fmt.Println("")
fmt.Printf(" %s -sf my_gps_data.GPX\n", os.Args[0])
fmt.Println(" - runs analysis of the GPX data and save a copy of track with filtered points detected as errors")
os.Exit(exitStatus)
}