diff --git a/Data/GPS/Gps2HtmlReport/HTMLGenerator.hs b/Data/GPS/Gps2HtmlReport/HTMLGenerator.hs
new file mode 100644
--- /dev/null
+++ b/Data/GPS/Gps2HtmlReport/HTMLGenerator.hs
@@ -0,0 +1,84 @@
+{-# LANGUAGE ScopedTypeVariables  #-}
+
+-- | The `HTMLGenerator' module generates the HTML content for the index.html generated
+module Data.GPS.Gps2HtmlReport.HTMLGenerator where
+
+import Text.Html
+import Data.GPS hiding (src,link,href)
+import Text.Printf
+import Data.Maybe
+
+import Data.GPS.Gps2HtmlReport.JourneyStats
+
+-- | Takes all the WayPoints and generates the HTML file
+generateHtmlPage :: [WptType] -> Html
+generateHtmlPage points = 
+   let header1 = h1 $ stringToHtml "Journey Statistics"
+       header2 = h1 $ stringToHtml "Charts of the Journey"
+       header3 = h1 $ stringToHtml "OpenStreetMap Chart"
+       title = thetitle $ stringToHtml "GPX Track Report"
+       theStyle = style (stringToHtml cssContent) ! [thetype "text/css"]
+       theHeader = header $ concatHtml [title,theStyle]
+       mainArea = thediv (concatHtml [header1,statsTable points,br,header2,chartTable,header3,osmImg]) -- ! [identifier "main"]
+       theBody = body mainArea
+   in concatHtml [theHeader,theBody,pgFooter]
+
+-- | The OpenStreetMap image area
+osmImg :: Html
+osmImg = center $ image ! [src "osm.png"]
+
+-- | Takes all the WayPoints and calculates the journey statistics
+statsTable :: [WptType] -> Html
+statsTable points = 
+   let tblHeader1 = th $ stringToHtml "Journey Details"
+       tblHeader2 = th $ stringToHtml "Elevation"
+       tblHeader3 = th $ stringToHtml "Speed"
+       distTravelled = printf "%.2f" $ journeyDistance points
+       maybeMaxElePt = findPoint points (head points) ele (>)
+       maybeMinElePt = findPoint points (head points) ele (<)
+       maxElevation = printf "%.1f" (if isJust maybeMaxElePt then snd $ fromJust maybeMaxElePt else 0.0)
+       minElevation = printf "%.1f" (if isJust maybeMinElePt then snd $ fromJust maybeMinElePt else 0.0)
+       meanEle = printf "%.1f" $ meanElevation points
+       journeyMins = show $ round (journeyTime points) `div` 60
+       journeySecs = show $ round (journeyTime points) `rem` 60
+       mxSpd = printf "%.1f" $ maxSpeed points
+       meanSpd = printf "%.1f" $ meanJourneySpeed points
+       maybeDateOfJourney = dateOfJourney points
+       journeyDate = (if isJust maybeDateOfJourney then show $ fromJust maybeDateOfJourney else "") 
+       li1c1 = li $ stringToHtml ("Journey Date: "++ journeyDate)
+       li2c1 = li $ stringToHtml ("Distance Travelled: "++ distTravelled++"m")
+       li3c1 = li $ stringToHtml ("Journey Time: "++journeyMins++"m "++journeySecs++"s")
+       li1c2 = li $ stringToHtml ("Maximum Elevation: "++ maxElevation++"m")
+       li2c2 = li $ stringToHtml ("Minimum Elevation: "++minElevation++"m")
+       li3c2 = li $ stringToHtml ("Mean Elevation: "++ meanEle++"m")
+       li1c3 = li $ stringToHtml ("Maximum speed: "++ mxSpd++"m/s")
+       li2c3 = li $ stringToHtml ("Mean speed: "++meanSpd++"m/s")
+       col1 = td (concatHtml [li1c1,li2c1,li3c1]) ! [valign "top"]
+       col2 = td  (concatHtml [li1c2,li2c2,li3c2]) ! [valign "top"]
+       col3 = td  (concatHtml [li1c3,li2c3]) ! [valign "top"]
+       row1 = tr $ concatHtml [tblHeader1,tblHeader2,tblHeader3]
+       row2 = tr $ concatHtml [col1,col2,col3]
+       tbl = table (concatHtml [row1,row2]) -- ! [cellspacing 10]
+   in center tbl
+   
+-- | The CSS style text to format the rendering of the HTML page. It would be good to replace with Haskell HTML combinator library functions
+cssContent = "h1 {font-size: 22px;color: #335577;font-weight: bold; margin-top: 20px;margin-left: 70px;font-family: New Century Schoolbook, serif;} div {    width: 900px; margin-top: 50px; margin:0 auto;} table {border-spacing: 20px 0px;} footer {text-align:right; background-color:#EEEEEE; width:900px; margin:0 auto; margin-top: 30px}"
+
+-- | The area holding the Cairo charts
+chartTable = 
+   let img1 = image ! [src "chart1.png"]
+       img2 = image ! [src "chart2.png"]
+       cell1 =  td img1
+       cell2 = td img2
+       row1 = tr $ concatHtml [cell1,cell2]
+       tbl = table row1
+   in center tbl
+
+-- | The footer
+pgFooter = 
+   let projectLink = anchor (stringToHtml "gps2htmlReport") ! [href "https://github.com/robstewart57/Gps2HtmlReport"]
+       infoStr = stringToHtml "Report generated by "
+   in footer (concatHtml [infoStr,projectLink]) ! [identifier "main"]
+
+-- | This appears to be missing from the `html' package
+footer = tag "FOOTER"
diff --git a/Data/GPS/Gps2HtmlReport/JourneyCharts.hs b/Data/GPS/Gps2HtmlReport/JourneyCharts.hs
new file mode 100644
--- /dev/null
+++ b/Data/GPS/Gps2HtmlReport/JourneyCharts.hs
@@ -0,0 +1,114 @@
+-- | This module uses the JourneyStats module to generate
+-- the statistics about the journey WayPoints, then
+-- uses the Cairo bindings to generate the charts
+module Data.GPS.Gps2HtmlReport.JourneyCharts where
+
+import Data.GPS
+import Data.Maybe
+import Graphics.Rendering.Chart
+import Data.Accessor
+import Data.Colour
+import Data.Colour.Names
+
+import Data.GPS.Gps2HtmlReport.JourneyStats
+
+data OutputType = Window | PNG | PS | PDF | SVG
+
+chooseLineWidth Window = 1.0
+chooseLineWidth PNG = 1.0
+chooseLineWidth PDF = 0.25
+chooseLineWidth PS = 0.25
+chooseLineWidth SVG = 0.25
+
+-- | Generates the Cairo chart showing speed and elevation over time
+speedAndElevationOverTimeChart :: [WptType] -> OutputType -> Renderable ()
+speedAndElevationOverTimeChart points otype = toRenderable layout
+  where
+    layout = layout1_title ^="Speed, Average Speed & Elevation"
+           $ layout1_title_style ^= defaultFontStyle { font_size_ = 12.0 }
+           $ layout1_background ^= solidFillStyle (opaque white)
+           $ layout1_right_axis ^= defaultLayoutAxis { laxis_title_ = "Elevation (metres)", laxis_override_ = axisGridHide }
+           $ layout1_left_axis ^: laxis_title ^= "Speed (metres)"
+ 	   $ layout1_plots ^= [ Right (toPlot elevationArea),
+                                Left (toPlot speedLine),
+                                Left (toPlot avrSpeedLine)  
+                              ]
+           $ setLayout1Foreground fg
+           defaultLayout1
+
+    lineStyle c = line_width ^= 1 * chooseLineWidth otype
+                $ line_color ^= c
+                $ defaultPlotLines ^. plot_lines_style
+
+    theSpeeds = [(theTime,spd) | (theTime,spd) <- speedAtPoints points]
+
+    speedLine = plot_lines_style ^= lineStyle (opaque blue)
+           $ plot_lines_values ^= [[ (theTime,speed) | (theTime,speed) <- theSpeeds]]
+           $ plot_lines_title ^= "Speed"
+           $ defaultPlotLines
+
+    avrSpeedLine = plot_lines_style ^= lineStyle (red `withOpacity` 0.5)
+           $ plot_lines_values ^= [[ (theTime,speed) | (theTime,speed) <- avrSpeedOverTime theSpeeds 0.0 0.0 []]]
+           $ plot_lines_title ^= "Avr Speed"
+           $ defaultPlotLines 
+
+    elevationArea = plot_fillbetween_style ^= solidFillStyle (green `withOpacity` 0.1)
+           $ plot_fillbetween_values ^= [ (theTime,(0,elevation)) | (theTime,elevation) <- ptsElevation points]
+           $ plot_fillbetween_title ^= "Elevation"
+           $ defaultPlotFillBetween
+
+    fg = opaque black
+
+
+-- |  Generates the Cairo chart showing accumulative distance and elevation over time, with spots showing maximum and minimum elevation points
+accumDistanceAndElevationChart :: [WptType] -> OutputType -> Renderable ()
+accumDistanceAndElevationChart points otype = toRenderable layout
+  where
+    layout = layout1_title ^="Accumulative Distance & Elevation"
+           $ layout1_title_style ^= defaultFontStyle { font_size_ = 12.0 }
+           $ layout1_background ^= solidFillStyle (opaque white)
+           $ layout1_right_axis ^= defaultLayoutAxis { laxis_title_ = "Distance (metres)", laxis_override_ = axisGridHide }
+           $ layout1_left_axis ^: laxis_title ^= "Elevation (metres)"
+           $ layout1_plots ^= [ Right (toPlot accumDistanceArea),
+                                Left (toPlot elevationLine),
+                                Left (toPlot spots)
+                              ]
+           $ setLayout1Foreground fg
+           defaultLayout1
+
+    lineStyle c = line_width ^= 1 * chooseLineWidth otype
+                $ line_color ^= c
+                $ defaultPlotLines ^. plot_lines_style
+
+    elevationLine = plot_lines_style ^= lineStyle (opaque black)
+           $ plot_lines_values ^= [[ (theTime,elevation) | (theTime,elevation) <- ptsElevation points]]
+           $ plot_lines_title ^= "Elevation"
+           $ defaultPlotLines 
+
+    accumDistanceArea = plot_fillbetween_style ^= solidFillStyle (red `withOpacity` 0.2)
+           $ plot_fillbetween_values ^= [ (theTime,(0,accumDist)) | (theTime,accumDist) <- accumDistance points 0.0]
+           $ plot_fillbetween_title ^= "Distance"
+           $ defaultPlotFillBetween
+
+    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 (<)
+                   in (if isJust point then Just (fst $ fromJust point, snd $ fromJust point, 5 :: Double) else Nothing)
+
+    spots = area_spots_title ^= "Altitude"
+          $ area_spots_max_radius ^= 5
+          $ area_spots_values ^= (if  isJust spotMinPoint && isJust spotMaxPoint then [fromJust spotMinPoint,fromJust spotMaxPoint] else [])
+          $ defaultAreaSpots
+
+    fg = opaque black
+
+renderToPng :: (t, OutputType -> Renderable a) -> FilePath -> IO (PickFn a)
+renderToPng (_,ir) = renderableToPNGFile (ir Window) 384 288
+
+chart1 :: [WptType] -> (String, OutputType -> Renderable ())
+chart1 points = ("speedAndElevationOverTimeChart", speedAndElevationOverTimeChart points)
+
+chart2 :: [WptType] -> (String, OutputType -> Renderable ())
+chart2 points = ("accumDistanceAndElevationChart", accumDistanceAndElevationChart points)
+
diff --git a/Data/GPS/Gps2HtmlReport/JourneyStats.hs b/Data/GPS/Gps2HtmlReport/JourneyStats.hs
new file mode 100644
--- /dev/null
+++ b/Data/GPS/Gps2HtmlReport/JourneyStats.hs
@@ -0,0 +1,107 @@
+-- | This module provides the JourneyCharts and HTMLGenerator 
+-- modules with statistics for the charts, and the journey statistics
+module Data.GPS.Gps2HtmlReport.JourneyStats where
+
+import Data.GPS hiding (speed)
+import Data.Maybe
+import Data.Time.LocalTime
+import Data.Time.Clock
+import Data.Time.Calendar
+import Text.XML.XSD.DateTime
+
+-- | Takes all WayPoints, and creates a list of tuples containing (TimeStamp,Elevation)
+ptsElevation :: [WptType] -> [(LocalTime,Double)]
+ptsElevation = map (\point -> (utcToLocalTime dfltTZ (Text.XML.XSD.DateTime.toUTCTime (fromJust $ time point)) , fromJust $ ele point))
+
+-- | Takes all WayPoints, and creates a list of tuples containing (TimeStamp,AvrSpeedAtThisPoint)
+avrSpeedOverTime :: [(LocalTime,Speed)] -> Double -> Double -> [(LocalTime,Speed)] -> [(LocalTime,Speed)]
+avrSpeedOverTime [] _ _ _ = []
+avrSpeedOverTime [spd] totalSpeed numPoints iteratedAvr = iteratedAvr ++ [(fst spd, (snd spd + totalSpeed) / (numPoints+1))]
+avrSpeedOverTime (spd:spds) totalSpeed numPoints iteratedAvr = avrSpeedOverTime [spd] totalSpeed numPoints iteratedAvr ++ avrSpeedOverTime spds (snd spd + totalSpeed) (numPoints+1) iteratedAvr
+
+-- | Takes all WayPoints, and creates a list of tuples containing (TimeStamp,SpeedAtThisPoint) 
+speedAtPoints :: [WptType] -> [(LocalTime,Speed)]
+speedAtPoints [] = []
+speedAtPoints (point:points) = (lclTime $ fromJust (time point),0.0) : speedAtPoints' point points
+
+speedAtPoints' :: WptType -> [WptType] -> [(LocalTime, Speed)]
+speedAtPoints' _ [] = []
+speedAtPoints' prev [x]
+         | isJust (time x) = [(lclTime $ fromJust (time x), fromJust $ speed prev x)]
+         | otherwise = []
+speedAtPoints' prev (x:xs)
+         | isJust (time x) = (lclTime $ fromJust (time x), fromJust $ speed prev x) : speedAtPoints' x xs
+         | otherwise = [] ++ speedAtPoints' x xs
+
+-- | Takes all WayPoints, and creates a list of tuples containing (TimeStamp,JourneyDistanceAtPoint)
+accumDistance :: [WptType] -> Double -> [(LocalTime,Distance)]
+accumDistance [] _ = []
+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)
+
+-- | 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)
+findPoint [] _ _ _ = Nothing
+findPoint (point:points) currSelected wayPointElement equalityF
+   | equalityF (fromJust $ wayPointElement point) (fromJust $ wayPointElement currSelected) = findPoint points point wayPointElement equalityF
+   | otherwise = if null points
+                      then Just (lclTime (fromJust $ time currSelected), fromJust $ ele currSelected)
+                      else findPoint points currSelected wayPointElement equalityF
+
+-- | Calculates the total journey distance
+journeyDistance :: (Lat a, Lon a) => [a] -> Distance
+journeyDistance [] = 0.0
+journeyDistance [_] = 0.0
+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)
+
+-- | Calculates the maximum speed
+maxSpeed :: [WptType] -> Speed
+maxSpeed points =
+            let speedTuple = speedAtPoints points
+                speedList = map snd speedTuple
+                maxSpeed = foldr max 0.0 speedList
+            in maxSpeed
+
+-- | Calculates the average elevation throughout the journey
+meanElevation :: Ele a => [a] -> Double
+meanElevation points = 
+            let elevationVals = map (fromJust . ele) points
+                totalElevation = foldr (+) 0.0 elevationVals
+                theMean = totalElevation / fromIntegral (length points)
+            in theMean
+
+-- | Calculates the total journey time
+journeyTime :: Time a => [a] -> NominalDiffTime
+journeyTime [] = fromInteger 0
+journeyTime [_] = fromInteger 0
+journeyTime (point:points) = 
+             let startTime = toUTCTime (fromJust (time point))
+                 endTime = toUTCTime (fromJust (time $ last points))
+             in diffUTCTime endTime startTime
+
+-- | Extracts the date of the journey (from the first WayPoint)
+dateOfJourney :: Time a => [a] -> Maybe Day
+dateOfJourney [] = Nothing
+dateOfJourney (point:_) = Just $ utctDay $ toUTCTime $ fromJust (time point)
+
+lclTime :: DateTime -> LocalTime
+lclTime dteTime = utcToLocalTime dfltTZ (Text.XML.XSD.DateTime.toUTCTime dteTime)
+
+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
diff --git a/Data/GPS/Gps2HtmlReport/Main.hs b/Data/GPS/Gps2HtmlReport/Main.hs
new file mode 100644
--- /dev/null
+++ b/Data/GPS/Gps2HtmlReport/Main.hs
@@ -0,0 +1,41 @@
+module Main where
+
+import Data.GPS
+import System.FilePath
+import System.Directory
+import Text.Html
+
+import Data.GPS.Gps2HtmlReport.OsmChart
+import Data.GPS.Gps2HtmlReport.HTMLGenerator
+import Data.GPS.Gps2HtmlReport.JourneyCharts
+
+-- | Reads the current directory for all .gpx files, then maps to `generateReport' for each one
+main :: IO [()]
+main = 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
+
+-- | Creates empty directory for each web report
+createEmptyDir :: FilePath -> IO ()
+createEmptyDir dir = do
+       exists <- doesDirectoryExist dir
+       (if exists then removeDirectoryRecursive dir >> createDirectory dir else createDirectory dir)
+
+-- | Generates the HTML report for each .gpx file
+generateReport :: FilePath -> FilePath -> IO ()
+generateReport webDir gpxFile  = do
+         points <- readGPX gpxFile
+         case length points of
+          0 -> putStr "Unable to parse GPX file. Skipping..."
+          otherwise -> do
+           createEmptyDir webDir
+           renderToPng (chart1 points) (webDir++"/chart1.png")
+           renderToPng (chart2 points) (webDir++"/chart2.png")
+           writeFile (webDir++"/index.html") $ renderHtml $ generateHtmlPage points
+           createOsmMap webDir gpxFile
+           putStr $ "Processing '"++gpxFile++"' complete. Report saved in: "++webDir++"/index.html\n"
+           return ()
diff --git a/Data/GPS/Gps2HtmlReport/OsmChart.hs b/Data/GPS/Gps2HtmlReport/OsmChart.hs
new file mode 100644
--- /dev/null
+++ b/Data/GPS/Gps2HtmlReport/OsmChart.hs
@@ -0,0 +1,40 @@
+-- {-# 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
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Robert Stewart 2011
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of the author nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,74 @@
+GPS 2 HTML Report
+================
+
+This is a utility written in Haskell, to generate HTML reports from GPS track files.
+
+Included in the report:
+
+* Details of the journey... journey time, distance travelled etc..
+* Diagrams charting speed, elevation, accumulated distance etc..
+* OpenStreetMap diagram highlighting the GPS track
+
+An example can be seen [HERE](http://www.macs.hw.ac.uk/~rs46/gps2htmlreport/3/index.html).
+
+The Haddock documentation pages can be found [here](http://www.macs.hw.ac.uk/~rs46/gps2htmlreport/doc/).
+
+Installation
+------------
+It is assumed that you have the Haskell Platform installed.
+
+Just run these commands to configure and install the `gps2HtmlReport' utility, run these commands:
+
+```
+cabal configure
+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.
+
+On an RPM-based package manager, run this command as root:
+
+```
+yum install GraphicsMagick cairo
+```
+
+Prerequisites
+-------------
+First of all, you need to have your GPS date in a GPX file. There are many gpx exporters available. I use my Android phone to take GPX tracks, with a great application, [OSMTracker](https://code.google.com/p/osmtracker-android/). This application allows you to export your GPS tracks to GPX.
+
+Usage
+-----
+The program will search for all files ending in ".gpx", and for each one, generate a HTML report.
+
+```
+$ cd $location_of_gpx_files
+$ ls
+1.gpx 2.gpx 3.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
+```
+
+Notes
+-----
+This project requires testing!
+
+If you are able to use the utility to generate HTML reports, then I'd like to hear suggestions for improvements. If you are **unable** to run it, then I **really** want to hear from you. What the problem is; How far did you get; or better still, send me the .gpx file.
+
+I'd also like to know what is required to make this utility work on non-Linux systems. This has been tested on a Fedora Linux machine. Does it work on Mac OSX? Windows? What needs doing to run it on other Linux distro's?
+
+Either way, get in touch!
+
+To Do
+-----
+
+* 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.
+
+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.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/gps2htmlReport.cabal b/gps2htmlReport.cabal
new file mode 100644
--- /dev/null
+++ b/gps2htmlReport.cabal
@@ -0,0 +1,24 @@
+Name:                gps2htmlReport
+Version:             0.1
+Cabal-Version:       >=1.2
+Description:         Generate a HTML summary report of GPS tracks
+synopsis:            GPS to HTML Summary Report
+License:             BSD3
+License-file:        LICENSE
+Author:              Rob Stewart <robstewart57@googlemail.com>
+Maintainer:          Rob Stewart <robstewart57@googlemail.com>
+Homepage:	     https://github.com/robstewart57/Gps2HtmlReport
+bug-reports:	     https://github.com/robstewart57/Gps2HtmlReport
+Build-Type:          Simple
+stability:	     alpha
+category:	     Data
+extra-source-files:  README.md
+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
