I borrowed some code from pyTrainer.
A file, called startingPoints.py, that creates a data structure to manages list of points:
import math
class Point (object):
def __init__ (self, lat, lon):
self._lat = lat
self._lon = lon
def getLatitude (self):
return self._lat
def getLongitude (self):
return self._lon
def __str__ (self):
retVal = str(self._lat) + ',' + str(self._lon)
return retVal
def distanceInKm (self, other):
d2r = math.pi / 180.0
dlong = (self._lon - other._lon) * d2r
dlat = (self._lat - other._lat) * d2r
a = math.pow (math.sin (dlat / 2.0), 2) + math.cos (self._lat * d2r) * math.cos (other._lat * d2r) \
* math.pow(math.sin (dlong/2.0), 2)
c = 2.0 * math.atan2 (math.sqrt(a), math.sqrt(1.0 -a))
d = 6367.0 * c
return d
class PointList (object):
def __init__ (self):
self._list = []
def appendPoint (self, point):
found = False
for p in self._list:
if p.distanceInKm (point) < 1.0:
found = True
break
if not found:
self._list.append (point)
def __str__ (self):
retVal = ""
for p in self._list:
retVal += str (p) + "\n"
return retVal
def __getitem__ (self, key):
return self._list [key]
def len (self):
return len (self._list)
def getParameters (self):
# Returns max, min & average
maxLat = -50000.0
minLat = 50000.0
maxLon = -50000.0
minLon = 50000.0
avLon = 0.0
avLat = 0.0
total = float (len (self._list))
for s in self._list:
lon = s.getLongitude ()
lat = s.getLatitude ()
if lon > maxLon:
maxLon = lon
if lon < minLon:
minLon = lon
if lat > maxLat:
maxLat = lat
if lat < minLat:
minLat = lat
avLon += lon / total
avLat += lat / total
return maxLat, minLat, maxLon, minLon, avLat, avLon
Another file to generate the map file:
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
class PrintMap (object):
def __init__ (self):
pass
def printMap (self, filename, startingPoints):
maxLat, minLat, maxLon, minLon, avLat, avLon = startingPoints.getParameters ()
fp = open (filename, "w")
fp.write (
"""<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript">
function initialize ()
{
var mapOptions = {
center: new google.maps.LatLng (""")
fp.write (str(avLat) + ',' + str(avLon))
fp.write ("""),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map (document.getElementById ("map_canvas"), mapOptions);""")
fp.write ("var swlatlng = new google.maps.LatLng (%f, %f);\n" % (minLat, minLon))
fp.write ("var nelatlng = new google.maps.LatLng (%f, %f);\n" % (maxLat, maxLon))
fp.write ('''var boundsBox = new google.maps.LatLngBounds(swlatlng, nelatlng );\n
map.fitBounds(boundsBox);\n''')
no_of_points = startingPoints.len ()
for i in range (0, no_of_points):
p = startingPoints [i]
markerName = "point" + str (i)
content = " var startmarker = new google.maps.Marker ({\n" + \
"position: new google.maps.LatLng (" + \
str (p.getLatitude ()) + "," + str (p.getLongitude ()) + \
"),\n" + \
"map: map,\n" + \
'title: "' + markerName + '"})\n\n'
fp.write (content)
fp.write ("""
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map_canvas"/></div>
</body>
</html>""")
And finally a file to parse the TCX files:
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import logging
import sys
import traceback
from lxml import etree
from startingPoints import Point, PointList
from printMap import PrintMap
class parseTCX (object):
def __init__ (self):
pass
def validate(self, xmldoc, schema):
logging.debug(">>")
xmlschema_doc = etree.parse("./" + schema)
xmlschema = etree.XMLSchema(xmlschema_doc)
logging.debug("<<")
return xmlschema.validate(xmldoc)
def parseFile (self, filename):
startingPoints = PointList ()
logging.debug ("Parsing file " + filename)
try:
xmldoc = etree.parse(filename)
valid_xml = self.validate(xmldoc, "schemas/GarminTrainingCenterDatabase_v2.xsd")
if (valid_xml):
logging.debug ("It is a valid file " + filename)
activities = xmldoc.findall(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Activity")
for activity in activities:
point = activity.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Trackpoint")
if point != None:
pos = point.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}Position")
if pos != None:
lat = pos.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}LatitudeDegrees")
lon = pos.find(".//{http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2}LongitudeDegrees")
startingPoints.appendPoint (Point (float(lat.text), float(lon.text)))
except:
logging.debug("Traceback: %s" % traceback.format_exc())
return startingPoints
if __name__ == "__main__":
logging.basicConfig(format='%(asctime)-6s: %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG,
filename="parseTCX.log")
filename = sys.argv[1]
P = parseTCX ()
startingPoints = P.parseFile (filename)
M = PrintMap ()
M.printMap ("mapa.html", startingPoints)