Created
October 2, 2014 21:13
-
-
Save bagage/0025af69198e2ad71fc7 to your computer and use it in GitHub Desktop.
orienteering replay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import xml.etree.ElementTree as ET | |
from sys import argv | |
from os.path import splitext | |
import xml.dom.minidom as minidom | |
import random | |
from math import sin, cos, pi, atan, acos | |
import unicodedata | |
import re | |
class Color: | |
colors = ["ffff0000", | |
"ff0000ff", | |
"ff00ff00", | |
"ff00ffff", | |
"ffff00ff", | |
"ff8080ff", | |
"ff808080", | |
"ff000080", | |
"ff0080ff" | |
] | |
current = random.randint(0, len(colors)) | |
def random(): | |
Color.current = (Color.current + 1) % len(Color.colors) | |
return Color.colors[Color.current] | |
def gpx2kml(fileName, xmlNode): | |
tree = ET.parse(fileName) | |
root = tree.getroot() | |
trks = [] | |
runnerName = "" | |
for child in root: | |
if child.tag == "{http://www.topografix.com/GPX/1/1}metadata": | |
runnerName = child[0][0].text | |
if child.tag == "{http://www.topografix.com/GPX/1/1}trk": | |
trks.append(child) | |
trksegs = [] | |
for trk in trks: | |
for child in trk: | |
if child.tag == "{http://www.topografix.com/GPX/1/1}trkseg": | |
trksegs.append(child) | |
style = ET.SubElement( | |
document, "Style", id="s_hiker_" + slugify(runnerName)) | |
iconstyle = ET.SubElement(style, "IconStyle") | |
ET.SubElement(iconstyle, "color").text = Color.random() | |
ET.SubElement(iconstyle, "scale").text = "1.2" | |
ref = ET.SubElement(iconstyle, "Icon") | |
ET.SubElement( | |
ref, "href").text = "http://maps.google.com/mapfiles/kml/shapes/hiker.png" | |
ET.SubElement(iconstyle, "hotSpot", x="0.5", y="0", | |
xunits="fraction", yunits="fraction") | |
folder = ET.SubElement(xmlNode, "Folder") | |
ET.SubElement(folder, "name").text = runnerName | |
ET.SubElement(folder, "open").text = "0" | |
ET.SubElement(folder, "description") | |
for seg in trksegs: | |
for child in seg: | |
if child.tag == "{http://www.topografix.com/GPX/1/1}trkpt": | |
lat = child.get("lat") | |
lon = child.get("lon") | |
alt = child[0].text | |
time = child[-1].text | |
placemark = ET.SubElement(folder, "Placemark") | |
ET.SubElement(placemark, "styleUrl").text = "#s_hiker_" + \ | |
slugify(runnerName) | |
ts = ET.SubElement(placemark, "TimeStamp") | |
ET.SubElement(ts, "when").text = time | |
pt = ET.SubElement(placemark, "Point") | |
ET.SubElement( | |
pt, "coordinates").text = "{1},{0}".format(lat, lon) | |
def csv2kml(fileName, xmlNode ): | |
folder = ET.SubElement(xmlNode, "Folder") | |
ET.SubElement(folder, "name").text = "Checkpoints" | |
ET.SubElement(folder, "open").text = "0" | |
ET.SubElement(folder, "description") | |
with open(fileName, "r") as inFile: | |
for line in inFile: | |
placemark = ET.SubElement(folder, "Placemark") | |
ET.SubElement(placemark, "name").text = line.split(',')[0] | |
ET.SubElement(placemark, "styleUrl").text = "#s_checkpoint" | |
pt = ET.SubElement(placemark, "Point") | |
ET.SubElement( | |
pt, "coordinates").text = ",".join(line.split(',')[1:]) | |
def imagescall( fileName, xmlNode ): | |
pixels = [] | |
points = [] | |
imageFile = "" | |
imageSize = [] | |
with open(fileName, "r") as inFile: | |
line = inFile.readline().split(",") | |
imageFile = line[0] | |
imageSize = line[1:] | |
for line in inFile: | |
points.append(line.split(",")[:2]) | |
pixels.append(line.split(",")[2:]) | |
r = 6371 | |
for point in range(0, len(points)): | |
print( imageFile ) | |
print( r * sin( float(points[point][1]) * pi / 180 ) * cos( float(points[point][0]) * pi / 180 ) ) | |
print( r * sin( float(points[point][1]) * pi / 180 ) * sin( float(points[point][0]) * pi / 180 ) ) | |
x1 = r * sin( float(points[0][1]) * pi / 180 ) * cos( float(points[0][0]) * pi / 180 ) | |
y1 = r * sin( float(points[0][1]) * pi / 180 ) * sin( float(points[0][0]) * pi / 180 ) | |
x2 = r * sin( float(points[1][1]) * pi / 180 ) * cos( float(points[1][0]) * pi / 180 ) | |
y2 = r * sin( float(points[1][1]) * pi / 180 ) * sin( float(points[1][0]) * pi / 180 ) | |
dX1 = (x2 - x1) | |
dY1 = (y2 - y1) | |
X1 = int( pixels[0][0]) | |
Y1 = int( pixels[0][1]) | |
X2 = int( pixels[1][0]) | |
Y2 = int( pixels[1][1]) | |
dX2 = (X2 - X1) | |
dY2 = (Y2 - Y1) | |
dX = dX1/dX2 | |
dY = dY1/dY2 | |
x2 = r * sin( float(points[1][1]) * pi / 180 ) * cos( float(points[1][0]) * pi / 180 ) | |
y2 = r * sin( float(points[1][1]) * pi / 180 ) * sin( float(points[1][0]) * pi / 180 ) | |
# phi = atan( y / x ) | |
# theta = acos( z / r ) | |
# z = r * cos (theta) | |
overlay = ET.SubElement(xmlNode, "GroundOverlay") | |
ET.SubElement(overlay, "name").text = imageFile | |
icon = ET.SubElement(overlay, "Icon") | |
ET.SubElement(icon, "href").text = imageFile | |
ET.SubElement(icon, "viewBoundScale").text = "0.75" | |
latlonbox = ET.SubElement(overlay, "LatLonBox") | |
ET.SubElement(latlonbox, "north").text = "0" | |
ET.SubElement(latlonbox, "south").text = "0" | |
ET.SubElement(latlonbox, "east").text = "100" | |
ET.SubElement(latlonbox, "west").text = "100" | |
ET.SubElement(latlonbox, "rotate").text = "0" | |
def prettify(elem): | |
"""Return a pretty-printed XML string for the Element. | |
""" | |
rough_string = ET.tostring(elem, 'utf-8') | |
reparsed = minidom.parseString(rough_string) | |
return reparsed.toprettyxml(indent="\t") | |
def kml2file(root, filename): | |
"""Write a generated KML into a file | |
""" | |
with open(filename, "w") as outFile: | |
outFile.write(prettify(secondroot)) | |
def slugify(name): | |
"""Slugify a name to an ASCII valid string""" | |
name = unicodedata.normalize('NFKD', name).encode('ascii', 'ignore') | |
name = str(re.sub('[^\w\-]', '', name.decode()).strip().lower()) | |
return name | |
secondroot = ET.Element("kml", {"xmlns": "http://earth.google.com/kml/2.2"}) | |
document = ET.SubElement(secondroot, "Document") | |
ET.SubElement(document, "name").text = "CO" | |
ET.SubElement(document, "description") | |
style = ET.SubElement(document, "Style", id="s_checkpoint") | |
iconstyle = ET.SubElement(style, "IconStyle") | |
ET.SubElement(iconstyle, "scale").text = "1.2" | |
ref = ET.SubElement(iconstyle, "Icon") | |
ET.SubElement( | |
ref, "href").text = "http://maps.google.com/mapfiles/kml/paddle/red-circle.png" | |
ET.SubElement(iconstyle, "hotSpot", x="0.5", y="0", | |
xunits="fraction", yunits="fraction") | |
for f in argv[1:]: | |
if splitext( f )[-1] == ".gpx": | |
gpx2kml( f, document ) | |
if splitext( f )[-1] == ".chpt": | |
csv2kml( f, document ) | |
if splitext( f )[-1] == ".map": | |
imagescall( f, document ) | |
secondtree = ET.ElementTree(secondroot) | |
kml2file(secondroot, "output.kml") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment