nmea: parse degrees and minutes in lat/long

This commit is contained in:
Daniel 2025-05-18 18:01:56 +00:00
parent 015caf45c6
commit 36b1284996

View File

@ -54,6 +54,16 @@
nil nil
(tonumber s))) (tonumber s)))
(fn parse-coordinate [value sign]
(if (= value "")
nil
(let [(deg min) (string.match value "(..)(.+)")]
(print :deg value deg :min min)
(*
(+ (tonumber deg)
(/ (tonumber min) 60))
(case sign :N 1 :E 1 :S -1 :W -1)))))
(local (local
msg-types msg-types
{ {
@ -66,14 +76,9 @@
altitude _ altitude _
geoidal-separation _ geoidal-separation _
_ _ ] fields _ _ ] fields
latf (if (= lat "") ]
nil { :lat (parse-coordinate lat latsign)
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1))) :lon (parse-coordinate lon lonsign)
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))]
{ :lat latf
:lon lonf
: fix-quality : fix-quality
:total-space-vehicles (try-number total-space-vehicles) :total-space-vehicles (try-number total-space-vehicles)
:hdop (try-number hdop) :hdop (try-number hdop)
@ -86,39 +91,27 @@
knots bearing-true date knots bearing-true date
magn-var magn-var-sign magn-var magn-var-sign
mode nav-status &as fields]] mode nav-status &as fields]]
(let [latf (if (= lat "") (let [magnetic-variation (if (= magn-var "")
nil
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1)))
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))
magnetic-variation (if (= magn-var "")
nil nil
(* (tonumber magn-var) (* (tonumber magn-var)
(case magn-var-sign :E 1 :W -1)))] (case magn-var-sign :E 1 :W -1)))]
{ : utc { : utc
: valid : valid
:lat latf :lat (parse-coordinate lat latsign)
:lon lonf :lon (parse-coordinate lon lonsign)
:speed-knots (try-number knots) :speed-knots (try-number knots)
:bearing-true (try-number bearing-true) :bearing-true (try-number bearing-true)
: date : date
: magnetic-variation : magnetic-variation ;;; XXX probably wrong
: mode : mode
})) }))
:GNS :GNS
(fn [fields] (fn [fields]
(let [[utc lat latsign lon lonsign mode total-space-vehicles (let [[utc lat latsign lon lonsign mode total-space-vehicles
hdop altitude geoidal-separation _ _ nav-status] fields hdop altitude geoidal-separation _ _ nav-status] fields]
latf (if (= lat "") { :lat (parse-coordinate lat latsign)
nil :lon (parse-coordinate lon lonsign)
(* (tonumber lat) 0.01 (case latsign :N 1 :S -1)))
lonf (if (= lon "")
nil
(* (tonumber lon) 0.01 (case lonsign :E 1 :W -1)))]
{ :lat latf
:lon lonf
: mode : mode
:total-space-vehicles (try-number total-space-vehicles) :total-space-vehicles (try-number total-space-vehicles)
:hdop (try-number hdop) :hdop (try-number hdop)
@ -150,14 +143,16 @@
(tset :talker talker)) (tset :talker talker))
split))) split)))
;; XXX this is wrong. 5131.348976 is 51 degrees 31.348976 minutes
(expect= (expect=
(parse-line (parse-line
"$GNGNS,111134.00,5131.348976,N,00005.551003,W,AAAANN,19,0.7,20.3,47.0,,,V*0C\n") "$GNGNS,111134.00,5131.348976,N,00005.551003,W,AAAANN,19,0.7,20.3,47.0,,,V*0C\n")
{:altitude 20.3 {:altitude 20.3
:geoidal-separation 47 :geoidal-separation 47
:hdop 0.7 :hdop 0.7
:lat 51.31348976 :lat 51.522482933333
:lon -0.05551003 :lon -0.092516716666667
:message-type "GNS" :message-type "GNS"
:mode "AAAANN" :mode "AAAANN"
:nav-status "V" :nav-status "V"