mirror of
https://github.com/la5nta/pat
synced 2026-08-07 22:32:06 -04:00
77 lines
1.7 KiB
Go
77 lines
1.7 KiB
Go
package forms
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
|
|
"github.com/la5nta/pat/internal/gpsd"
|
|
"github.com/pd0mz/go-maidenhead"
|
|
)
|
|
|
|
type gpsStyle int
|
|
|
|
const (
|
|
// documentation: https://www.winlink.org/sites/default/files/RMSE_FORMS/insertion_tags.zip
|
|
signedDecimal gpsStyle = iota // 41.1234 -73.4567
|
|
decimal // 46.3795N 121.5835W
|
|
degreeMinute // 46-22.77N 121-35.01W
|
|
gridSquare // JO29PJ
|
|
)
|
|
|
|
func positionFmt(style gpsStyle, pos gpsd.Position) string {
|
|
const notAvailable = "(Not available)"
|
|
|
|
var (
|
|
northing string
|
|
easting string
|
|
latDegrees int
|
|
latMinutes float64
|
|
lonDegrees int
|
|
lonMinutes float64
|
|
)
|
|
|
|
noPos := gpsd.Position{}
|
|
if pos == noPos {
|
|
return notAvailable
|
|
}
|
|
switch style {
|
|
case gridSquare:
|
|
str, err := maidenhead.NewPoint(pos.Lat, pos.Lon).GridSquare()
|
|
if err != nil {
|
|
return notAvailable
|
|
}
|
|
return str
|
|
case degreeMinute:
|
|
{
|
|
latDegrees = int(math.Trunc(math.Abs(pos.Lat)))
|
|
latMinutes = (math.Abs(pos.Lat) - float64(latDegrees)) * 60
|
|
lonDegrees = int(math.Trunc(math.Abs(pos.Lon)))
|
|
lonMinutes = (math.Abs(pos.Lon) - float64(lonDegrees)) * 60
|
|
}
|
|
fallthrough
|
|
case decimal:
|
|
{
|
|
if pos.Lat >= 0 {
|
|
northing = "N"
|
|
} else {
|
|
northing = "S"
|
|
}
|
|
if pos.Lon >= 0 {
|
|
easting = "E"
|
|
} else {
|
|
easting = "W"
|
|
}
|
|
}
|
|
}
|
|
|
|
switch style {
|
|
case signedDecimal:
|
|
return fmt.Sprintf("%.4f %.4f", pos.Lat, pos.Lon)
|
|
case decimal:
|
|
return fmt.Sprintf("%.4f%s %.4f%s", math.Abs(pos.Lat), northing, math.Abs(pos.Lon), easting)
|
|
case degreeMinute:
|
|
return fmt.Sprintf("%02d-%05.2f%s %03d-%05.2f%s", latDegrees, latMinutes, northing, lonDegrees, lonMinutes, easting)
|
|
default:
|
|
panic("invalid style")
|
|
}
|
|
}
|