gps2htmlReport 0.1 → 0.2
raw patch · 9 files changed
+357/−81 lines, 9 filesdep +bytestringdep +cmdargsdep +download-curldep ~gpsbinary-added
Dependencies added: bytestring, cmdargs, download-curl, hsmagick
Dependency ranges changed: gps
Files
- Data/GPS/Gps2HtmlReport/DrawOsm.hs +241/−0
- Data/GPS/Gps2HtmlReport/HTMLGenerator.hs +0/−1
- Data/GPS/Gps2HtmlReport/JourneyCharts.hs +4/−2
- Data/GPS/Gps2HtmlReport/JourneyStats.hs +4/−14
- Data/GPS/Gps2HtmlReport/Main.hs +70/−7
- Data/GPS/Gps2HtmlReport/OsmChart.hs +0/−40
- LiberationMono-Bold.ttf binary
- README.md +34/−12
- gps2htmlReport.cabal +4/−5
+ Data/GPS/Gps2HtmlReport/DrawOsm.hs view
@@ -0,0 +1,241 @@++module Data.GPS.Gps2HtmlReport.DrawOsm where++import Prelude+import Data.GPS+import Graphics.Transform.Magick.Types hiding (Image, minimum, maximum)+import Network.Curl.Download+import Data.Bits+import Graphics.GD+import Data.Maybe++import Data.GPS.Gps2HtmlReport.JourneyStats++baseurl = "http://tile.openstreetmap.org"+tilesprefix = "tile"+tilesourcename = "osmrender"+-- zoom = 16::Int++data TileCoords = TileCoords { minX :: Int+ , maxX :: Int + , minY :: Int + , maxY :: Int + } +++tileNumbers :: Double -> Double -> Int -> [(Int,Int)]+tileNumbers latitude longitude zoom = + let xtile = ((longitude+180) / 360) * fromInteger (shift (1::Integer) zoom)+ tmp = log (tan (latitude*pi / 180) + secant (latitude * pi / 180))+ ytile = ((1-tmp / pi) / 2.0) * fromInteger (shift (1::Integer) zoom)+ bounds x = [ceiling x, floor x]+ in [(xt,yt) | xt <- bounds xtile, yt <- bounds ytile]++maxTile :: [(Int,Int)] -> (Int,Int)+maxTile [] = error "There is no max tile of an empty list"+maxTile (x:xs) = go x xs+ where+ go a [] = a+ go a (y:ys) = if fst y >= fst a && snd y >= snd a then go y ys else go a ys++secant :: Floating a => a -> a+secant a = 1 / cos a++initCoords :: TileCoords+initCoords = TileCoords {minX = 1000000, maxX = -1000, minY = 1000000, maxY = -1000}++-- | Determines the minimum and maximum of the X and Y tiles+-- to be downloaded from OSM+determineTiles :: [WptType] -> TileCoords -> Int -> TileCoords+determineTiles [] _ _ = initCoords+determineTiles [wpt] tCoords zoom =+ let curMinX = minX tCoords+ curMaxX = maxX tCoords+ curMinY = minY tCoords+ curMaxY = maxY tCoords+ tiles = tileNumbers (value (lat wpt)) (value (lon wpt)) zoom+ newMaxX = maximum $ curMaxX : map fst tiles+ newMinX = minimum $ curMinX : map fst tiles+ newMaxY = maximum $ curMaxY : map snd tiles+ newMinY = minimum $ curMinY : map snd tiles + in tCoords {minX = newMinX, maxX = newMaxX, minY = newMinY, maxY = newMaxY}++determineTiles (wpt:wpts) tCoords zoom = + let tileScope = determineTiles [wpt] tCoords zoom+ in determineTiles wpts tileScope zoom++deltaLat :: TileCoords -> Int+deltaLat tCoords = maxX tCoords - minX tCoords++deltaLong :: TileCoords -> Int+deltaLong tCoords = maxY tCoords - minY tCoords++maxNumAutoTiles = 32++zoom :: TileCoords -> Int+zoom = zoomCalc++zoomCalc :: TileCoords -> Int+zoomCalc tCoords = + let numxtiles = maxX tCoords - minX tCoords + 1+ numytiles = maxY tCoords - minY tCoords + 1+ div = getZoomDiv numxtiles numytiles 0+ in 16 - div++getZoomDiv x y i+ | (x+1)*(y+1) > maxNumAutoTiles = getZoomDiv (shiftR x 1) (shiftR y 1) (i+1)+ | otherwise = i++-- | Takes the boundaries of the OSM tiles, and generates+-- [(Int,Int)] containing a list of all OSM tiles that+-- need downloading+selectedTiles :: TileCoords -> [(Int,Int)]+selectedTiles tCoords = + let minx = minX tCoords+ maxx = maxX tCoords+ miny = minY tCoords+ maxy = maxY tCoords+ in [(i,j) | i <- [minx..maxx], j <- [miny..maxy]]+ +-- | Formats the filename string+filenameStr :: (Show a, Show a1) => a -> a1 -> String+filenameStr xTile yTile = tilesprefix ++ tilesourcename ++ "-z"++show zoom++"-x"++show xTile++"-y"++show yTile++".png"++-- | Formats the URL string+urlStr xTile yTile zoom = baseurl ++"/"++show zoom++"/"++show xTile++"/"++show yTile++".png"+++rectangle :: Int -> Int -> Graphics.Transform.Magick.Types.Rectangle+rectangle x' y' = Rectangle {width=256, height=256, x = x'*256, y = y'*256}++-- | Takes the URL of a given OSM tile and uses curl to download it+downloadFile :: String -> IO Image+downloadFile url = do+ response <- openURI url+ case response of+ Left err -> error err+ Right img -> loadPngByteString img++-- | Takes the boundaries of the OSM tiles covering the+-- the 'Trail', uses 'placeTile' to download the tile+-- and to place each tile on the background layer+makeOSMLayer :: TileCoords -> Int -> IO Image+makeOSMLayer tCoords zoom = do+ backgroundImg <- newImage (((maxX tCoords - minX tCoords)+1)*256,((maxY tCoords - minY tCoords)+1)*256)+ mapM_ (\(a,b) -> placeTile a b backgroundImg tCoords zoom) (selectedTiles tCoords)+ return backgroundImg++-- | Used to create a mosaic of all downloaded OSM tiles to generate+-- the background layer for plotting the 'Trail' onto the 'Image'+placeTile :: Int -> Int -> Graphics.GD.Image -> TileCoords -> Int -> IO ()+placeTile x y backgroundImg tCoords zoom = do+ img <- downloadFile $ urlStr x y zoom+ copyRegion (0,0) (256,256) img (256*(x-minX tCoords),256*(y-minY tCoords)) backgroundImg++projectMercToLat :: Floating a => a -> a+projectMercToLat rely = (180 / pi) * atan (sinh rely)++-- | Used by @pixelPosForCoord@ for N,S,E,W coordinates for (x,y) values+project :: Int -> Int -> Int -> (Double,Double,Double,Double)+project x y zoom = + let unit = 1.0 / (2.0 ** fromIntegral zoom)+ rely1 = fromIntegral y * unit+ rely2 = rely1 + unit+ limity = pi+ rangey = 2.0 * limity+ rely1' = limity - rangey * rely1+ rely2' = limity - rangey * rely2+ lat1 = projectMercToLat rely1'+ lat2 = projectMercToLat rely2'+ unit' = 360.0 / (2.0 ** fromIntegral zoom)+ long1 = (-180.0) + fromIntegral x * unit'+ in (lat2,long1,lat1,long1+unit') -- S,W,N,E+ +-- | Takes a WptType, and the OSM tile boundaries+-- and generates (x,y) points to be placed on the 'Image'+pixelPosForCoord :: (Lon a, Lat a, Integral t, Integral t1) => [a] -> TileCoords -> Int -> (t, t1)+pixelPosForCoord [] _ _ = (0,0)+pixelPosForCoord [wpt] tCoord zoom =+ let lat' = value $ lat wpt+ lon' = value $ lon wpt+ tile = maxTile $ tileNumbers lat' lon' zoom+ xoffset = (fst tile - minX tCoord) * 256+ yoffset = (snd tile - minY tCoord) * 256+ (south,west,north,east) = (uncurry project tile zoom)+ x = round $ (lon' - west) * 256.0 / (east - west) + fromIntegral xoffset+ y = round $ (lat' - north) * 256.0 / (south - north) + fromIntegral yoffset+ in (x,y)++-- | Takes the 'WptType' and draws lines between every+-- point to point connection in the 'Trail'+drawLines :: [WptType] -> TileCoords -> Image -> Int -> IO Image+drawLines [] _ img _ = return img+drawLines [_] _ img _ = return img+drawLines (wpt:wpts) tCoord img zoom = do+ let start = pixelPosForCoord [wpt] tCoord zoom+ end = pixelPosForCoord [head wpts] tCoord zoom+ minEle = fromMaybe 0 $ fmap snd $ findPoint wpts wpt ele (<)+ maxEle = fromMaybe 0 $ fmap snd $ findPoint wpts wpt ele (>)+ drawLine' start end img (minEle,fromJust $ ele wpt,maxEle) 0+ drawLines wpts tCoord img zoom++-- | This is a fix on the fact that the 'drawLine' function+-- provided by the GD bindings do not provid a `width' parameter+drawLine' :: Point -> Point -> Image -> (Double,Double,Double) -> Int -> IO ()+drawLine' start end img (minEle,ele',maxEle) i+ | i < 6 = do+ drawLine (fst start+(i-1),snd start-(i-1)) (fst end+(i-1),snd end-(i-1)) color' img+ drawLine (fst start+(i+1),snd start-(i-1)) (fst end+(i+1),snd end-(i-1)) color' img+ drawLine (fst start+(i+1),snd start-(i+1)) (fst end+(i+1),snd end-(i+1)) color' img+ drawLine (fst start+(i-1),snd start-(i+1)) (fst end+(i-1),snd end-(i+1)) color' img+ drawLine' start end img (minEle,ele',maxEle) (i+1)+ | otherwise = return ()+ where range = maxEle - minEle+ x' = ele' - minEle+ x'' = x' / range+ color' = lineColor $ round $ 255.0*x''++-- | Uses a sliding scale for the red value in the RGB Color+-- to show a sliding color from green to yellow in accordance+-- with the relative elevation of a given WptType in the Trail+lineColor :: Int -> Graphics.GD.Color+lineColor redVal = rgb redVal 255 0++-- | Adds the copyright text in accordance with+-- http://wiki.openstreetmap.org/wiki/Legal_FAQ+addCopyright :: Graphics.GD.Image -> IO (Graphics.GD.Point, Graphics.GD.Point, Graphics.GD.Point, Graphics.GD.Point)+addCopyright img = do+ size <- imageSize img+ let copyrightS = "Tile images © OpenStreetMap (and) contributors, CC-BY-SA"+ pos = (10,snd size-10)+ black = rgb 0 0 0+ useFontConfig True+ drawString "monospace" 6.0 0.0 pos copyrightS black img++-- | If the generated OSM image has a greater width than 800 pixels, it is scaled to have a width of 800 pixels.+fitToWidth :: Image -> IO Image+fitToWidth img = do+ dimensions <- imageSize img+ let width = fst dimensions+ if width > 800 then resizeImg img dimensions else return img++-- | Uses the GraphicsMagick bindings the resize the image+resizeImg :: Image -> (Int,Int) -> IO Image +resizeImg img dimensions = do+ let resizeRatio = fromIntegral (fst dimensions) / 800.0+ height = round (fromIntegral (snd dimensions) / resizeRatio)+ resizeImage 800 height img++-- | Takes the destination directory for the web content,+-- the (Trail WptType), and uses the DrawOsm functions+-- to generate an `osm.png' file showing the trail.+generateOsmMap :: String -> [WptType] -> IO ()+generateOsmMap webDir points = do+ let tiles = determineTiles points initCoords 16+ zoom = zoomCalc tiles+ tiles' = determineTiles points initCoords zoom+ backgroundImg <- makeOSMLayer tiles' zoom+ imgWithLines <- drawLines points tiles' backgroundImg zoom+ resizedImg <- fitToWidth imgWithLines+ addCopyright resizedImg+ savePngFile (webDir++"/osm.png") resizedImg
Data/GPS/Gps2HtmlReport/HTMLGenerator.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE ScopedTypeVariables #-} -- | The `HTMLGenerator' module generates the HTML content for the index.html generated module Data.GPS.Gps2HtmlReport.HTMLGenerator where
Data/GPS/Gps2HtmlReport/JourneyCharts.hs view
@@ -9,6 +9,7 @@ import Data.Accessor import Data.Colour import Data.Colour.Names+import Data.Time.LocalTime import Data.GPS.Gps2HtmlReport.JourneyStats @@ -35,12 +36,13 @@ ] $ setLayout1Foreground fg defaultLayout1+ lineStyle c = line_width ^= 1 * chooseLineWidth otype $ line_color ^= c $ defaultPlotLines ^. plot_lines_style - theSpeeds = [(theTime,spd) | (theTime,spd) <- speedAtPoints points]+ theSpeeds = [(utcToLocalTime utc theTime,spd) | (theTime,spd) <- avgSpeeds 10 points] speedLine = plot_lines_style ^= lineStyle (opaque blue) $ plot_lines_values ^= [[ (theTime,speed) | (theTime,speed) <- theSpeeds]]@@ -90,7 +92,7 @@ $ plot_fillbetween_title ^= "Distance" $ defaultPlotFillBetween - spotMaxPoint = let point = findPoint points (head points) ele (>)+ spotMaxPoint = let point = findPoint points (head points) ele (>) in (if isJust point then Just (fst $ fromJust point, snd $ fromJust point, 5 :: Double) else Nothing) spotMinPoint = let point = findPoint points (head points) ele (<)
Data/GPS/Gps2HtmlReport/JourneyStats.hs view
@@ -2,7 +2,7 @@ -- modules with statistics for the charts, and the journey statistics module Data.GPS.Gps2HtmlReport.JourneyStats where -import Data.GPS hiding (speed)+import Data.GPS -- hiding (speed) import Data.Maybe import Data.Time.LocalTime import Data.Time.Clock@@ -39,7 +39,7 @@ accumDistance [x] _ = [(lclTime $ fromJust (time x),0.0)] accumDistance (x:xs) acc = let dist = distance x (head xs) - in (lclTime $ fromJust (time x), dist + acc ) : accumDistance (tail xs) (dist + acc)+ in (lclTime $ fromJust (time x), dist + acc ) : accumDistance xs (dist + acc) -- | Takes all WayPoints, an element in wptType, and an Eq function, returning a single WayPoint findPoint :: [WptType] -> WptType -> (WptType -> Maybe Double) -> (Double -> Double -> Bool) -> Maybe (LocalTime,Double)@@ -57,8 +57,8 @@ journeyDistance (point:points) = distance point (head points) + journeyDistance points -- | Calculates the average speed of the journey-meanJourneySpeed :: (Lat a, Lon a) => [a] -> Distance-meanJourneySpeed points = journeyDistance points / fromIntegral (length points)+meanJourneySpeed :: (Lat a, Lon a, Time a) => [a] -> Distance+meanJourneySpeed points = journeyDistance points / realToFrac (journeyTime points) -- | Calculates the maximum speed maxSpeed :: [WptType] -> Speed@@ -95,13 +95,3 @@ dfltTZ :: TimeZone dfltTZ = TimeZone {timeZoneMinutes=0,timeZoneSummerOnly=False,timeZoneName="GMT"}---- | Overides the `speed' function in the `gps' package-speed :: (Lat loc, Lon loc, Time loc) => loc -> loc -> Maybe Speed-speed a b = - case (getUTCTime b, getUTCTime a) of- (Just x, Just y) -> Just $ distance a b / realToFrac (diffUTCTime x y) - _ -> Nothing--getUTCTime :: (Lat a, Lon a, Time a) => a -> Maybe UTCTime-getUTCTime = fmap toUTCTime . time
Data/GPS/Gps2HtmlReport/Main.hs view
@@ -1,23 +1,71 @@++{-# LANGUAGE RecordWildCards,DeriveDataTypeable #-}+ module Main where -import Data.GPS+import Data.GPS hiding (name, id) import System.FilePath import System.Directory-import Text.Html+import Text.Html hiding (name)+import System.Console.CmdArgs -import Data.GPS.Gps2HtmlReport.OsmChart import Data.GPS.Gps2HtmlReport.HTMLGenerator import Data.GPS.Gps2HtmlReport.JourneyCharts+import Data.GPS.Gps2HtmlReport.DrawOsm --- | Reads the current directory for all .gpx files, then maps to `generateReport' for each one+data MyOptions = MyOptions+ { imageOnly :: Bool+ } deriving (Data, Typeable, Show, Eq)++-- Customize your options, including help messages, shortened names, etc.+myProgOpts :: MyOptions+myProgOpts = MyOptions+ { imageOnly = def &= help "Generates only an image of the track overlay on an OpenStreetMap layer"+ }++getOpts :: IO MyOptions+getOpts = cmdArgs $ myProgOpts+ &= verbosityArgs [explicit, name "Verbose", name "V"] []+ &= versionArg [explicit, name "version", name "v", summary _PROGRAM_INFO]+ &= summary (_PROGRAM_INFO ++ ", " ++ _COPYRIGHT)+ &= help _PROGRAM_ABOUT+ &= helpArg [explicit, name "help", name "h"]+ &= program _PROGRAM_NAME++_PROGRAM_NAME = "gps2HtmlReport"+_PROGRAM_VERSION = "0.2"+_PROGRAM_INFO = _PROGRAM_NAME ++ " version " ++ _PROGRAM_VERSION+_PROGRAM_ABOUT = "A Haskell utility to generate HTML page reports of GPS Tracks and Track overlays on OpenStreetMap tiles"+_COPYRIGHT = "(C) Rob Stewart 2011"+ main :: IO [()] main = do+ opts <- getOpts+ optionHandler opts++-- Before directly calling your main program, you should warn your user about incorrect arguments, if any.+optionHandler :: MyOptions -> IO [()]+optionHandler opts@MyOptions{..} =+ exec opts++exec :: MyOptions -> IO [()]+exec MyOptions{..} =+ if imageOnly+ then processGps False+ else processGps True+ ++-- | Reads the current directory for all .gpx files, then maps to `generateReport' for each one+processGps :: Bool -> IO [()]+processGps fullReport = do curDir <- getCurrentDirectory allFiles <- getDirectoryContents curDir let allFilesSplit = map splitExtension allFiles let gpxFiles = filter (\(_,b) -> b==".gpx") allFilesSplit putStr ("Processing "++show (length gpxFiles)++" file(s)...\n")- mapM (\(a,b) -> generateReport (curDir++"/"++a) (a++b)) gpxFiles+ if fullReport+ then mapM (\(a,b) -> generateReport (curDir++"/"++a) (a++b)) gpxFiles+ else mapM (\(a,b) -> generateImgOnly (curDir++"/"++a) (a++b)) gpxFiles -- | Creates empty directory for each web report createEmptyDir :: FilePath -> IO ()@@ -31,11 +79,26 @@ points <- readGPX gpxFile case length points of 0 -> putStr "Unable to parse GPX file. Skipping..."- otherwise -> do+ _ -> do createEmptyDir webDir+ putStr "Generating statistical charts...\n" renderToPng (chart1 points) (webDir++"/chart1.png") renderToPng (chart2 points) (webDir++"/chart2.png") writeFile (webDir++"/index.html") $ renderHtml $ generateHtmlPage points- createOsmMap webDir gpxFile+ putStr "Downloading OpenStreetMap tiles...\n"+ generateOsmMap webDir points putStr $ "Processing '"++gpxFile++"' complete. Report saved in: "++webDir++"/index.html\n"+ return ()++-- | Generates the HTML report for each .gpx file+generateImgOnly :: FilePath -> FilePath -> IO ()+generateImgOnly webDir gpxFile = do+ points <- readGPX gpxFile+ case length points of+ 0 -> putStr "Unable to parse GPX file. Skipping..."+ _ -> do+ createEmptyDir webDir+ putStr "Downloading OpenStreetMap tiles...\n"+ generateOsmMap webDir points+ putStr $ "Processing '"++gpxFile++"' complete. Image saved in: "++webDir++"/osm.png\n" return ()
− Data/GPS/Gps2HtmlReport/OsmChart.hs
@@ -1,40 +0,0 @@--- {-# LANGUAGE ScopedTypeVariables #-}---- | This module utilizes the perl gpx2png program--- to download the OSM tiles, and the GraphicsMagick bindings--- to resize the OSM image if necessary-module Data.GPS.Gps2HtmlReport.OsmChart where--import System.FilePath-import System.Directory-import System.Process-import Graphics.GD-import Control.Monad---- | If the generated OSM image has a greater width than 800 pixels, it is scaled to have a width of 800 pixels.-fitToWidth :: FilePath -> IO ()-fitToWidth imgPath = do- img <- loadPngFile imgPath- dimensions <- imageSize img- let width = fst dimensions- when (width > 800) $ resizeImg imgPath img dimensions---- | Uses the GraphicsMagick bindings the resize the image-resizeImg :: FilePath -> Image -> (Int,Int) -> IO () -resizeImg imgPath img dimensions = do- let resizeRatio = fromIntegral (fst dimensions) / 800.0- height = round (fromIntegral (snd dimensions) / resizeRatio)- resizedImg <- resizeImage 800 height img- savePngFile imgPath resizedImg- --- | Calls the perl `gpx2png' utility to download the relevant OSM tiles-createOsmMap :: String -> String -> IO [()]-createOsmMap webDir gpxFile = do- (_,_,_,pid) <- createProcess (shell ("perl gpx2png/gpx2png.pl -q -o "++webDir++"/osm.png "++ gpxFile))- waitForProcess pid- fitToWidth $ webDir++"/osm.png"- curDir <- getCurrentDirectory- allFiles <- getDirectoryContents curDir- let allFilesSplit = map splitExtension allFiles- let tmpPngFiles = filter (\(_,b) -> b==".png") allFilesSplit- mapM (\(a,b) -> removeFile (a++b) ) tmpPngFiles
+ LiberationMono-Bold.ttf view
binary file changed (absent → 105428 bytes)
README.md view
@@ -24,12 +24,12 @@ cabal install ``` -This Haskell program also makes use of the bindings to **GraphcsMagick** and **Cairo**, and so the necessary system packages need to be installed, via a *nix package manager.+This Haskell program also makes use of the bindings to **GraphcsMagick** and **Cairo**, and so the necessary system packages need to be installed, via a Linux package manager. On an RPM-based package manager, run this command as root: ```-yum install GraphicsMagick cairo+yum install GraphicsMagick cairo alex happy gtk2hs-buildtools ``` Prerequisites@@ -43,14 +43,24 @@ ``` $ cd $location_of_gpx_files $ ls-1.gpx 2.gpx 3.gpx+1.gpx $ gps2HtmlReport-Processing 3 file(s)...-Processing '1.gpx' complete. Report saved in: /home/foo/gps_tracks/1/index.html-Processing '2.gpx' complete. Report saved in: /home/foo/gps_tracks/2/index.html-Processing '3.gpx' complete. Report saved in: /home/foo/gps_tracks/3/index.html+Processing 1 file(s)...+Generating statistical charts...+Downloading OpenStreetMap tiles...+Processing '1.gpx' complete. Report saved in: /home/foo/bar/1/index.html ``` +Alternatively, you can you this program to simply generate an image of your track on top of an OpenStreetMap layer.++```+$ gps2htmlReport --imageonly+Processing 1 file(s)...+Downloading OpenStreetMap tiles...+Processing '1.gpx' complete. Image saved in: /home/foo/bar/1/osm.png+```++ Notes ----- This project requires testing!@@ -61,14 +71,26 @@ Either way, get in touch! -To Do++Problems ----- -* It would be great to port the perl `gpx2png' utility to Haskell, eliminating this dependency.-* This Haskell program currently makes use of elevation, latitude and longitude. There are many other attributes possibly available in WptType. Ideas for what to do with these attributes [here](http://hackage.haskell.org/packages/archive/GPX/0.4.8/doc/html/Data-Geo-GPX-WptType.html#t:WptType) most welcome.+If you receive this error when trying to run the program:+```+can't load .so/.DLL for: stdc++ (libstdc++.so: cannot open shared object file: No such file or directory)+``` +... then you are experiencing this bug: [#5289](http://hackage.haskell.org/trac/ghc/ticket/5289).++To fix this++* Fedora 32bit: $# ln -vs $(gcc --print-file-name=libstdc++.so) /usr/lib/+* Fedora 64bit: $# ln -vs $(gcc --print-file-name=libstdc++.so) /usr/lib64/+* Ubuntu 32bit: $# ln -vs $(gcc --print-file-name=libstdc++.so) /usr/local/lib/+* Ubuntu 64bit: $# ln -vs $(gcc --print-file-name=libstdc++.so) /usr/local/lib64/++ Credits --------Thanks goes to the developers of the [gpx2png project](http://wiki.openstreetmap.org/wiki/Gpx2png), which is used to generate the OpenStreetMap image. -In addition, thanks to [Thomas DuBuisson](http://www.haskellers.com/user/TomMD), for implementing the `gps' package and contributing it to Hackage.+Thanks to [Thomas DuBuisson](http://www.haskellers.com/user/TomMD), for implementing the `gps' package and contributing it to Hackage.
gps2htmlReport.cabal view
@@ -1,5 +1,5 @@ Name: gps2htmlReport-Version: 0.1+Version: 0.2 Cabal-Version: >=1.2 Description: Generate a HTML summary report of GPS tracks synopsis: GPS to HTML Summary Report@@ -12,13 +12,12 @@ Build-Type: Simple stability: alpha category: Data-extra-source-files: README.md+extra-source-files: README.md LiberationMono-Bold.ttf tested-with: GHC ==7.0.2 Executable gps2htmlReport Main-is: Data/GPS/Gps2HtmlReport/Main.hs library- Build-Depends: base >= 4 && < 5, html, gps, time, cairo, Chart, random, data-accessor, colour, xsd, filepath, directory, process, gd- Extensions: ScopedTypeVariables- Exposed-Modules: Data.GPS.Gps2HtmlReport.HTMLGenerator, Data.GPS.Gps2HtmlReport.JourneyStats, Data.GPS.Gps2HtmlReport.JourneyCharts, Data.GPS.Gps2HtmlReport.OsmChart+ Build-Depends: base >= 4 && < 5, html, gps >= 0.8.1, time, cairo, Chart, random, data-accessor, colour, xsd, filepath, directory, process, gd, bytestring, download-curl, hsmagick, cmdargs+ Exposed-Modules: Data.GPS.Gps2HtmlReport.HTMLGenerator, Data.GPS.Gps2HtmlReport.JourneyStats, Data.GPS.Gps2HtmlReport.JourneyCharts, Data.GPS.Gps2HtmlReport.DrawOsm