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

View File

@ -34,7 +34,9 @@ onepoint =
wrap
[r|
<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>
|]