handle bad data

where by "handle" we mean that Track.parse now returns an Either
instead of making up data points that lie on the equator
This commit is contained in:
Daniel Barlow 2024-10-31 00:35:19 +00:00
parent a3d48100ae
commit e15c42ff4a
2 changed files with 26 additions and 26 deletions

View File

@ -53,16 +53,12 @@ gpxNS localName =
tpxNS localName = tpxNS localName =
Name localName (Just "http://www.garmin.com/xmlschemas/TrackPointExtension/v2") Nothing Name localName (Just "http://www.garmin.com/xmlschemas/TrackPointExtension/v2") Nothing
mkPoint pos =
Point
pos
Nothing
(UTCTime (toEnum 60631) 43200)
Nothing
Nothing
Nothing
elToPoint :: Cursor -> Point data BadFile = BadFile deriving (Show)
instance Exception BadFile
elToPoint :: Cursor -> Either SomeException Point
elToPoint c = elToPoint c =
case node c of case node c of
NodeElement (Element _ attrs _) -> NodeElement (Element _ attrs _) ->
@ -86,25 +82,27 @@ elToPoint c =
>>= element (Name "PowerInWatts" (Just "http://www.garmin.com/xmlschemas/PowerExtension/v1") Nothing) >>= element (Name "PowerInWatts" (Just "http://www.garmin.com/xmlschemas/PowerExtension/v1") Nothing)
>>= child >>= child
>>= content >>= content
in Point parsedTime =
(Pos lat lon) listToMaybe ts
( (listToMaybe ele) >>= return . asFloat ) >>= (Data.Time.ISO8601.parseISO8601 . Data.Text.unpack)
( case ts of in case parsedTime of
[e] -> case Data.Time.ISO8601.parseISO8601 (Data.Text.unpack e) of Nothing -> Left (toException BadFile)
Just utime -> utime Just utime ->
_ -> UTCTime (toEnum 0) 0 Right $
_ -> UTCTime (toEnum 0) 0 Point
) (Pos lat lon)
( (listToMaybe cadence) >>= return . asInt) (listToMaybe ele >>= return . asFloat)
( (listToMaybe power) >>= return . asInt) utime
Nothing (listToMaybe cadence >>= return . asInt)
(listToMaybe power >>= return . asInt)
Nothing
where where
asFloat v = (read (Data.Text.unpack v) :: Float) asFloat v = (read (Data.Text.unpack v) :: Float)
asInt v = (read (Data.Text.unpack v) :: Int) asInt v = (read (Data.Text.unpack v) :: Int)
getAttr name = maybe 0 asFloat (Map.lookup name attrs) getAttr name = maybe 0 asFloat (Map.lookup name attrs)
_ -> mkPoint (Pos 0 0) _ -> Left (toException BadFile)
getPoints :: Cursor -> [Point] getPoints :: Cursor -> Either SomeException [Point]
getPoints c = getPoints c =
let trkpts = let trkpts =
element (gpxNS "gpx") c element (gpxNS "gpx") c
@ -112,12 +110,12 @@ getPoints c =
>>= element (gpxNS "trk") >>= element (gpxNS "trk")
>>= descendant >>= descendant
>>= element (gpxNS "trkpt") >>= element (gpxNS "trkpt")
in List.map elToPoint trkpts in traverse elToPoint trkpts
parse :: String -> Either SomeException [Point] parse :: String -> Either SomeException [Point]
parse str = do parse str = do
gpx <- parseText def (T.pack str) gpx <- parseText def (T.pack str)
return (getPoints (fromDocument gpx)) getPoints (fromDocument gpx)
length :: Track -> Int length :: Track -> Int
length = Data.List.length length = Data.List.length

View File

@ -34,7 +34,9 @@ onepoint =
wrap wrap
[r| [r|
<trk> <trkseg> <trk> <trkseg>
<trkpt lat="51" lon="-0.1"> </trkpt> <trkpt lat="51" lon="-0.1">
<time>2024-10-23T08:34:59.779+01:00</time>
</trkpt>
</trkseg> </trk> </trkseg> </trk>
|] |]