import sys
import xml.sax.saxutils
from math import *
class Kml():
def __init__(self):
self.out = sys.stdout
self.placemark = Placemark(self)
self.tour = Tour(self)
self.playlist = Playlist(self)
self.flyto = FlyTo(self)
self.lookat = LookAt(self)
self.camera = Camera(self)
self.document = Document(self)
self.folder = Folder(self)
self.xml = Xml(self)
def documentProlog(self, fn):
self.xml.head()
self.document.head(fn)
def documentEpilog(self):
self.document.tail()
self.xml.tail()
def folderProlog(self, fn):
self.folder.head(fn)
def folderEpilog(self):
self.folder.tail()
def tourProlog(self, fn):
self.tour.head(fn)
self.playlist.head()
def tourEpilog(self):
self.playlist.tail()
self.tour.tail()
def placemarkProlog(self, fn):
self.xml.head()
self.placemark.head(fn)
def placemarkEpilog(self):
self.placemark.tail()
self.xml.tail()
def urlPlacemark(self, url, path):
# ref = '<a href="http://{}/index.py">{}</a>'.format(qualname, qualname)
ref = '<a href="{}">{}</a>'.format(url, path)
p = self.pr
p('<Placemark>')
p('<name>{ref}</name>'.format(ref = xml.sax.saxutils.escape(ref)))
p('</Placemark>')
def wait(self, dur):
self.pr('\n<gx:Wait><gx:duration>{}</gx:duration></gx:Wait>'.format(dur))
def comm(self, c):
self.pr('\n<!-- {} -->'.format(c))
def pr(self, s):
print(s, file=self.out)
class Xml():
def __init__(self, kml):
self.kml = kml
def head(self):
self.kml.pr('<?xml version="1.0" encoding="UTF-8"?>')
self.kml.pr('<kml')
self.kml.pr('xmlns="http://www.opengis.net/kml/2.2"')
self.kml.pr('xmlns:gx="http://www.google.com/kml/ext/2.2"')
self.kml.pr('>')
def tail(self):
self.kml.pr('\n</kml>')
class Document():
def __init__(self, kml):
self.kml = kml
def head(self, fn):
self.kml.pr('<Document>')
self.kml.pr('<name>{}</name>'.format(fn))
self.kml.pr('<open>1</open>')
def tail(self):
self.kml.pr('\n</Document>')
class Folder():
def __init__(self, kml):
self.kml = kml
def head(self, fn):
self.kml.pr('<Folder>')
self.kml.pr('<name>{}</name>'.format(fn))
self.kml.pr('<open>1</open>')
def tail(self):
self.kml.pr('\n</Folder>')
class Tour():
def __init__(self, kml):
self.kml = kml
def head(self, fn):
self.kml.pr('\n<gx:Tour>')
self.kml.pr('<name>{}</name>'.format(fn))
def tail(self):
self.kml.pr('\n</gx:Tour>')
class Playlist():
def __init__(self, kml):
self.kml = kml
def head(self):
self.kml.pr('\n<gx:Playlist>')
def tail(self):
self.kml.wait(1)
self.kml.pr('\n</gx:Playlist>')
class FlyTo():
def __init__(self, kml):
self.kml = kml
def head(self, dur, smooth):
self.kml.pr('<gx:FlyTo>')
self.kml.pr('<gx:duration>{}</gx:duration>'.format(dur))
self.kml.pr('<gx:flyToMode>{}</gx:flyToMode>'.format('smooth' if smooth else 'bounce'))
def tail(self):
self.kml.pr('\n</gx:FlyTo>')
class LookAt():
def __init__(self, kml):
self.kml = kml
def run(self, long,lat,alt,head,tilt,range):
self.kml.pr('\n<LookAt>')
self.kml.pr('<latitude>{}</latitude>'.format(lat))
self.kml.pr('<longitude>{}</longitude>'.format(long))
self.kml.pr('<altitude>{}</altitude>'.format(alt))
self.kml.pr('<heading>{}</heading>'.format(head))
self.kml.pr('<tilt>{}</tilt>'.format(tilt))
self.kml.pr('<range>{}</range>'.format(range))
self.kml.pr('<altitudeMode>relativeToGround</altitudeMode>')
self.kml.pr('</LookAt>')
class Camera():
def __init__(self, kml):
self.kml = kml
def run(self,long,lat,alt,head,tilt,roll):
self.kml.pr('<Camera>')
self.kml.pr('<latitude>{}</latitude>'.format(lat))
self.kml.pr('<longitude>{}</longitude>'.format(long))
self.kml.pr('<altitude>{}</altitude>'.format(alt))
self.kml.pr('<heading>{}</heading>'.format(head))
self.kml.pr('<tilt>{}</tilt>'.format(tilt))
self.kml.pr('<roll>{}</roll>'.format(roll))
self.kml.pr('<altitudeMode>relativeToSeaFloor</altitudeMode>')
self.kml.pr('</Camera>')
def runL(self, long, lat, alt, head, tilt, range, roll):
# dostává parametry LookAt, které konvertuje na parametry Camera tak, aby pohled byl stejný
dLO, dLA, Z = l2c(lat, head, tilt, range)
self.run(long + dLO, lat + dLA, Z, head, tilt, roll)
class Placemark():
def __init__(self, kml):
self.kml = kml
def head(self, fn):
self.kml.pr('<Placemark>')
self.kml.pr('<name>{}</name>'.format(fn))
self.kml.pr('<visibility>0</visibility>')
self.kml.pr('<styleUrl>#PIN_YELLOW</styleUrl>')
def tail(self):
self.kml.pr('\n</Placemark>')
class SpeedAdjust():
keys = ['none', 'linear', 'parabolic', 'tangential', 'exponential']
abrv = {'none':'none', 'linear':'lin', 'parabolic':'par', 'tangential':'tang', 'exponential':'exp'}
def __init__(self, const, koef, steps, config):
self.slowdowns = {'none':self.Const, 'linear':self.Linear, 'parabolic':self.Parabolic, 'tangential':self.Tangent, 'exponential':self.Exponential}
self.const = const
self.koef = koef
self.steps = steps
self.c = config
def phase(self):
return 1 - self.c.xi / self.c.x0.val
class Const():
p = 1 # empirická konstanta
def __init__(self, sa):
self.sa = sa
def koef(self):
return self.p / self.sa.const
class Linear():
p = 2 # empirická konstanta
def __init__(self, sa):
self.sa = sa
def koef(self):
return self.p * self.sa.koef * self.sa.phase() / self.sa.const
class Parabolic():
p = 2 # empirická konstanta
def __init__(self, sa):
self.sa = sa
def koef(self):
return self.p * pow(self.sa.koef * self.sa.phase(), 2) / self.sa.const
class Tangent():
p = 1 # empirická konstanta
def __init__(self, sa):
self.sa = sa
def koef(self):
margin = atan(self.sa.koef) # < pi/2
return (1 + self.p * tan(self.sa.phase() * margin)) / self.sa.const
class Exponential():
p = 1 # empirická konstanta
def __init__(self, sa):
self.sa = sa
def koef(self):
return pow(e, self.p * self.sa.koef * self.sa.phase()) / self.sa.const
def canonGeodetic(a):
if(a > 360 or a < -360): a = a % 360
if(a > 180): a = a - 360
if(a < -180): a = a + 360
return a
def can360(a360):
if(a360 < 0): a360 = a360 + 360
elif(a360 > 360): a360 = a360 - 360
return a360
def can180(a180):
if(a180 < -180): a180 = a180 + 360
elif(a180 > 180): a180 = a180 - 360
return a180
def l2c(lat, head, tilt, range):
RZ = 6378000
RL = RZ * cos(radians(lat))
Hc = can360(head + 180)
Z = range * cos(radians(tilt))
d = sqrt(pow(range,2) - pow(Z,2))
dLA = degrees(atan(d * cos(radians(Hc)) / RZ))
dLO = degrees(atan(d * sin(radians(Hc)) / RL))
return dLO, dLA, Z
def deb(s):
print('+++ {}'.format(s), file=sys.stderr)