commit e15c42ff4a274db387e0af843c226f1e59021bb9
parent a3d48100ae5a2dfc017e085c53722efc80c8e515
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 31 Oct 2024 00:35:19 +0000
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
Diffstat:
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/lib/Track.hs b/lib/Track.hs
@@ -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
diff --git a/tests/UnitTest.hs b/tests/UnitTest.hs
@@ -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>
|]