diff -r 000000000000 -r bb616224c02a kml/kml.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kml/kml.py Mon May 18 08:48:51 2020 +0200 @@ -0,0 +1,263 @@ +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 = '{}'.format(qualname, qualname) + ref = '{}'.format(url, path) + p = self.pr + p('') + p('{ref}'.format(ref = xml.sax.saxutils.escape(ref))) + p('') + + def wait(self, dur): + self.pr('\n{}'.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('') + self.kml.pr('') + + def tail(self): + self.kml.pr('\n') + +class Document(): + def __init__(self, kml): + self.kml = kml + + def head(self, fn): + self.kml.pr('') + self.kml.pr('{}'.format(fn)) + self.kml.pr('1') + + def tail(self): + self.kml.pr('\n') + + +class Folder(): + def __init__(self, kml): + self.kml = kml + + def head(self, fn): + self.kml.pr('') + self.kml.pr('{}'.format(fn)) + self.kml.pr('1') + + def tail(self): + self.kml.pr('\n') + +class Tour(): + def __init__(self, kml): + self.kml = kml + + def head(self, fn): + self.kml.pr('\n') + self.kml.pr('{}'.format(fn)) + + def tail(self): + self.kml.pr('\n') + +class Playlist(): + def __init__(self, kml): + self.kml = kml + + def head(self): + self.kml.pr('\n') + + def tail(self): + self.kml.wait(1) + self.kml.pr('\n') + +class FlyTo(): + def __init__(self, kml): + self.kml = kml + + def head(self, dur, smooth): + self.kml.pr('') + self.kml.pr('{}'.format(dur)) + self.kml.pr('{}'.format('smooth' if smooth else 'bounce')) + + def tail(self): + self.kml.pr('\n') + +class LookAt(): + def __init__(self, kml): + self.kml = kml + + def run(self, long,lat,alt,head,tilt,range): + self.kml.pr('\n') + self.kml.pr('{}'.format(lat)) + self.kml.pr('{}'.format(long)) + self.kml.pr('{}'.format(alt)) + self.kml.pr('{}'.format(head)) + self.kml.pr('{}'.format(tilt)) + self.kml.pr('{}'.format(range)) + self.kml.pr('relativeToGround') + self.kml.pr('') + +class Camera(): + def __init__(self, kml): + self.kml = kml + + def run(self,long,lat,alt,head,tilt,roll): + self.kml.pr('') + self.kml.pr('{}'.format(lat)) + self.kml.pr('{}'.format(long)) + self.kml.pr('{}'.format(alt)) + self.kml.pr('{}'.format(head)) + self.kml.pr('{}'.format(tilt)) + self.kml.pr('{}'.format(roll)) + self.kml.pr('relativeToSeaFloor') + self.kml.pr('') + + 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('') + self.kml.pr('{}'.format(fn)) + self.kml.pr('0') + self.kml.pr('#PIN_YELLOW') + + def tail(self): + self.kml.pr('\n') + +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)