use real gpx namespace

This commit is contained in:
Daniel Barlow 2024-10-30 13:30:33 +00:00
parent 90101760a2
commit c514c20e68
3 changed files with 40 additions and 14 deletions

View File

@ -36,6 +36,8 @@ data Point = Point {
-- TODO do we even need this type? -- TODO do we even need this type?
type Track = [Point] type Track = [Point]
gpxNS = "http://www.topografix.com/GPX/1/1"
mkPoint pos = mkPoint pos =
Point Point
pos pos
@ -52,7 +54,7 @@ elToPoint c =
let let
lat = getAttr "lat" lat = getAttr "lat"
lon = getAttr "lon" lon = getAttr "lon"
ele = child c >>= element "ele" >>= child >>= content ele = child c >>= element (Name "ele" (Just gpxNS) Nothing) >>= child >>= content
in Point (Pos lat lon) in Point (Pos lat lon)
(case ele of (case ele of
e:[] -> Just $ asFloat e e:[] -> Just $ asFloat e
@ -72,12 +74,13 @@ elToPoint c =
getPoints :: Cursor -> [Point] getPoints :: Cursor -> [Point]
getPoints c = getPoints c =
let let
ns n = Name n (Just gpxNS) Nothing
trkpts = trkpts =
child c >>= element (ns "gpx") c >>= child >>=
element "trk" >>= descendant >>= element (ns "trk") >>= descendant >>=
element "trkpt" element (ns "trkpt")
in in
List.map elToPoint trkpts (List.map elToPoint trkpts)
parse :: String -> Either SomeException [Point] parse :: String -> Either SomeException [Point]
parse str = do parse str = do

View File

@ -101,5 +101,6 @@ test-suite tests
build-depends: build-depends:
base >=4.7 && <5 base >=4.7 && <5
, souplesse-lib , souplesse-lib
, raw-strings-qq
, HUnit , HUnit
default-language: GHC2021 default-language: GHC2021

View File

@ -1,30 +1,52 @@
{-# LANGUAGE QuasiQuotes #-}
module Main where module Main where
import qualified Track import qualified Track
import Text.RawString.QQ(r)
import Test.HUnit import Test.HUnit
import qualified System.Exit as Exit import qualified System.Exit as Exit
import Control.Exception import Control.Exception
import Debug.Trace (trace, traceShow) import Debug.Trace (trace, traceShow)
onepoint = preamble = [r|
"<gpx> <trk> <trkseg> \n\ <?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.1"
creator="OpenTracks"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:topografix="http://www.topografix.com/GPX/Private/TopoGrafix/0/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:opentracks="http://opentracksapp.com/xmlschemas/v1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v2"
xmlns:gpxtrkx="http://www.garmin.com/xmlschemas/TrackStatsExtension/v1"
xmlns:cluetrust="http://www.cluetrust.com/Schemas/"
xmlns:pwr="http://www.garmin.com/xmlschemas/PowerExtension/v1"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.topografix.com/GPX/Private/TopoGrafix/0/1 http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 https://www8.garmin.com/xmlschemas/TrackPointExtensionv2.xsd http://www.garmin.com/xmlschemas/PowerExtension/v1 https://www8.garmin.com/xmlschemas/PowerExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackStatsExtension/v1 http://www.cluetrust.com/Schemas http://www.cluetrust.com/Schemas/gpxdata10.xsd http://opentracksapp.com/xmlschemas/v1 http://opentracksapp.com/xmlschemas/OpenTracks_v1.xsd">
|]
wrap x = preamble ++ x ++ "</gpx>"
onepoint = wrap $
"<trk> <trkseg> \n\
\<trkpt lat=\"51\" lon=\"-0.1\"> </trkpt> \n\ \<trkpt lat=\"51\" lon=\"-0.1\"> </trkpt> \n\
\</trkseg> </trk> </gpx>" \</trkseg> </trk>"
onepointEle = onepointWithAttrs = wrap $
"<gpx> <trk> <trkseg> \n\ "<trk> <trkseg> \n\
\<trkpt lat=\"51\" lon=\"-0.1\"> \n\ \<trkpt lat=\"51\" lon=\"-0.1\"> \n\
\ <ele>25.2</ele>\n\ \ <ele>25.2</ele>\n\
\</trkpt> \n\ \</trkpt> \n\
\</trkseg> </trk> </gpx>" \</trkseg> </trk>"
test1 = TestCase $ test1 = TestCase $
case Track.parse "<gpx></gpx>" of case Track.parse (wrap "") of
Left err -> assertFailure (displayException err) Left err -> assertFailure (displayException err)
Right t -> assertEqual "empty track has no elements" Right t -> assertEqual "empty track has no elements"
0 (Track.length t) 0 (Track.length t)
testMalformed = TestCase $ testMalformed = TestCase $
case Track.parse "<gpx><dgdsfg>></gpx>" of case Track.parse (wrap "<dgdsfg>>") of
Left err -> assertBool "syntax error" True Left err -> assertBool "syntax error" True
Right _ -> assertFailure "no error message parsing bad xml" Right _ -> assertFailure "no error message parsing bad xml"
@ -48,7 +70,7 @@ test3 = TestCase $
Right [] -> assertFailure "no points" Right [] -> assertFailure "no points"
test4 = TestCase $ test4 = TestCase $
case Track.parse onepointEle case Track.parse onepointWithAttrs
of of
Left err -> assertFailure (displayException err) Left err -> assertFailure (displayException err)
Right (p:ps) -> Right (p:ps) ->