kml/kml.py
author hh
Mon, 18 May 2020 08:48:51 +0200
changeset 0 bb616224c02a
permissions -rw-r--r--
--
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
hh
parents:
diff changeset
     1
import sys
hh
parents:
diff changeset
     2
import xml.sax.saxutils
hh
parents:
diff changeset
     3
from math import *
hh
parents:
diff changeset
     4
hh
parents:
diff changeset
     5
class Kml():
hh
parents:
diff changeset
     6
    def __init__(self):
hh
parents:
diff changeset
     7
        self.out = sys.stdout
hh
parents:
diff changeset
     8
        self.placemark = Placemark(self)
hh
parents:
diff changeset
     9
        self.tour = Tour(self)
hh
parents:
diff changeset
    10
        self.playlist = Playlist(self)
hh
parents:
diff changeset
    11
        self.flyto = FlyTo(self)
hh
parents:
diff changeset
    12
        self.lookat = LookAt(self)
hh
parents:
diff changeset
    13
        self.camera = Camera(self)
hh
parents:
diff changeset
    14
        self.document = Document(self)
hh
parents:
diff changeset
    15
        self.folder = Folder(self)
hh
parents:
diff changeset
    16
        self.xml = Xml(self)
hh
parents:
diff changeset
    17
hh
parents:
diff changeset
    18
    def documentProlog(self, fn):
hh
parents:
diff changeset
    19
        self.xml.head()
hh
parents:
diff changeset
    20
        self.document.head(fn)
hh
parents:
diff changeset
    21
hh
parents:
diff changeset
    22
    def documentEpilog(self):
hh
parents:
diff changeset
    23
        self.document.tail()
hh
parents:
diff changeset
    24
        self.xml.tail()
hh
parents:
diff changeset
    25
hh
parents:
diff changeset
    26
    def folderProlog(self, fn):
hh
parents:
diff changeset
    27
        self.folder.head(fn)
hh
parents:
diff changeset
    28
hh
parents:
diff changeset
    29
    def folderEpilog(self):
hh
parents:
diff changeset
    30
        self.folder.tail()
hh
parents:
diff changeset
    31
hh
parents:
diff changeset
    32
    def tourProlog(self, fn):
hh
parents:
diff changeset
    33
        self.tour.head(fn)
hh
parents:
diff changeset
    34
        self.playlist.head()
hh
parents:
diff changeset
    35
hh
parents:
diff changeset
    36
    def tourEpilog(self):
hh
parents:
diff changeset
    37
        self.playlist.tail()
hh
parents:
diff changeset
    38
        self.tour.tail()
hh
parents:
diff changeset
    39
hh
parents:
diff changeset
    40
    def placemarkProlog(self, fn):
hh
parents:
diff changeset
    41
        self.xml.head()
hh
parents:
diff changeset
    42
        self.placemark.head(fn)
hh
parents:
diff changeset
    43
hh
parents:
diff changeset
    44
    def placemarkEpilog(self):
hh
parents:
diff changeset
    45
        self.placemark.tail()
hh
parents:
diff changeset
    46
        self.xml.tail()
hh
parents:
diff changeset
    47
hh
parents:
diff changeset
    48
    def urlPlacemark(self, url, path):
hh
parents:
diff changeset
    49
        # ref = '<a href="http://{}/index.py">{}</a>'.format(qualname, qualname)
hh
parents:
diff changeset
    50
        ref = '<a href="{}">{}</a>'.format(url, path)
hh
parents:
diff changeset
    51
        p = self.pr
hh
parents:
diff changeset
    52
        p('<Placemark>')
hh
parents:
diff changeset
    53
        p('<name>{ref}</name>'.format(ref = xml.sax.saxutils.escape(ref)))
hh
parents:
diff changeset
    54
        p('</Placemark>')
hh
parents:
diff changeset
    55
hh
parents:
diff changeset
    56
    def wait(self, dur):
hh
parents:
diff changeset
    57
        self.pr('\n<gx:Wait><gx:duration>{}</gx:duration></gx:Wait>'.format(dur))
hh
parents:
diff changeset
    58
hh
parents:
diff changeset
    59
    def comm(self, c):
hh
parents:
diff changeset
    60
        self.pr('\n<!-- {} -->'.format(c))
hh
parents:
diff changeset
    61
hh
parents:
diff changeset
    62
    def pr(self, s):
hh
parents:
diff changeset
    63
        print(s, file=self.out)
hh
parents:
diff changeset
    64
hh
parents:
diff changeset
    65
class Xml():
hh
parents:
diff changeset
    66
    def __init__(self, kml):
hh
parents:
diff changeset
    67
        self.kml = kml
hh
parents:
diff changeset
    68
hh
parents:
diff changeset
    69
    def head(self):
hh
parents:
diff changeset
    70
        self.kml.pr('<?xml version="1.0" encoding="UTF-8"?>')
hh
parents:
diff changeset
    71
        self.kml.pr('<kml')
hh
parents:
diff changeset
    72
        self.kml.pr('xmlns="http://www.opengis.net/kml/2.2"')
hh
parents:
diff changeset
    73
        self.kml.pr('xmlns:gx="http://www.google.com/kml/ext/2.2"')
hh
parents:
diff changeset
    74
        self.kml.pr('>')
hh
parents:
diff changeset
    75
hh
parents:
diff changeset
    76
    def tail(self):
hh
parents:
diff changeset
    77
        self.kml.pr('\n</kml>')
hh
parents:
diff changeset
    78
hh
parents:
diff changeset
    79
class Document():
hh
parents:
diff changeset
    80
    def __init__(self, kml):
hh
parents:
diff changeset
    81
        self.kml = kml
hh
parents:
diff changeset
    82
hh
parents:
diff changeset
    83
    def head(self, fn):
hh
parents:
diff changeset
    84
        self.kml.pr('<Document>')
hh
parents:
diff changeset
    85
        self.kml.pr('<name>{}</name>'.format(fn))
hh
parents:
diff changeset
    86
        self.kml.pr('<open>1</open>')
hh
parents:
diff changeset
    87
hh
parents:
diff changeset
    88
    def tail(self):
hh
parents:
diff changeset
    89
        self.kml.pr('\n</Document>')
hh
parents:
diff changeset
    90
hh
parents:
diff changeset
    91
hh
parents:
diff changeset
    92
class Folder():
hh
parents:
diff changeset
    93
    def __init__(self, kml):
hh
parents:
diff changeset
    94
        self.kml = kml
hh
parents:
diff changeset
    95
hh
parents:
diff changeset
    96
    def head(self, fn):
hh
parents:
diff changeset
    97
        self.kml.pr('<Folder>')
hh
parents:
diff changeset
    98
        self.kml.pr('<name>{}</name>'.format(fn))
hh
parents:
diff changeset
    99
        self.kml.pr('<open>1</open>')
hh
parents:
diff changeset
   100
hh
parents:
diff changeset
   101
    def tail(self):
hh
parents:
diff changeset
   102
        self.kml.pr('\n</Folder>')
hh
parents:
diff changeset
   103
hh
parents:
diff changeset
   104
class Tour():
hh
parents:
diff changeset
   105
    def __init__(self, kml):
hh
parents:
diff changeset
   106
        self.kml = kml
hh
parents:
diff changeset
   107
hh
parents:
diff changeset
   108
    def head(self, fn):
hh
parents:
diff changeset
   109
        self.kml.pr('\n<gx:Tour>')
hh
parents:
diff changeset
   110
        self.kml.pr('<name>{}</name>'.format(fn))
hh
parents:
diff changeset
   111
hh
parents:
diff changeset
   112
    def tail(self):
hh
parents:
diff changeset
   113
        self.kml.pr('\n</gx:Tour>')
hh
parents:
diff changeset
   114
hh
parents:
diff changeset
   115
class Playlist():
hh
parents:
diff changeset
   116
    def __init__(self, kml):
hh
parents:
diff changeset
   117
        self.kml = kml
hh
parents:
diff changeset
   118
hh
parents:
diff changeset
   119
    def head(self):
hh
parents:
diff changeset
   120
        self.kml.pr('\n<gx:Playlist>')
hh
parents:
diff changeset
   121
hh
parents:
diff changeset
   122
    def tail(self):
hh
parents:
diff changeset
   123
        self.kml.wait(1)
hh
parents:
diff changeset
   124
        self.kml.pr('\n</gx:Playlist>')
hh
parents:
diff changeset
   125
hh
parents:
diff changeset
   126
class FlyTo():
hh
parents:
diff changeset
   127
    def __init__(self, kml):
hh
parents:
diff changeset
   128
        self.kml = kml
hh
parents:
diff changeset
   129
hh
parents:
diff changeset
   130
    def head(self, dur, smooth):
hh
parents:
diff changeset
   131
        self.kml.pr('<gx:FlyTo>')
hh
parents:
diff changeset
   132
        self.kml.pr('<gx:duration>{}</gx:duration>'.format(dur))
hh
parents:
diff changeset
   133
        self.kml.pr('<gx:flyToMode>{}</gx:flyToMode>'.format('smooth' if smooth else 'bounce'))
hh
parents:
diff changeset
   134
hh
parents:
diff changeset
   135
    def tail(self):
hh
parents:
diff changeset
   136
        self.kml.pr('\n</gx:FlyTo>')
hh
parents:
diff changeset
   137
hh
parents:
diff changeset
   138
class LookAt():
hh
parents:
diff changeset
   139
    def __init__(self, kml):
hh
parents:
diff changeset
   140
        self.kml = kml
hh
parents:
diff changeset
   141
hh
parents:
diff changeset
   142
    def run(self, long,lat,alt,head,tilt,range):
hh
parents:
diff changeset
   143
        self.kml.pr('\n<LookAt>')
hh
parents:
diff changeset
   144
        self.kml.pr('<latitude>{}</latitude>'.format(lat))
hh
parents:
diff changeset
   145
        self.kml.pr('<longitude>{}</longitude>'.format(long))
hh
parents:
diff changeset
   146
        self.kml.pr('<altitude>{}</altitude>'.format(alt))
hh
parents:
diff changeset
   147
        self.kml.pr('<heading>{}</heading>'.format(head))
hh
parents:
diff changeset
   148
        self.kml.pr('<tilt>{}</tilt>'.format(tilt))
hh
parents:
diff changeset
   149
        self.kml.pr('<range>{}</range>'.format(range))
hh
parents:
diff changeset
   150
        self.kml.pr('<altitudeMode>relativeToGround</altitudeMode>')
hh
parents:
diff changeset
   151
        self.kml.pr('</LookAt>')
hh
parents:
diff changeset
   152
hh
parents:
diff changeset
   153
class Camera():
hh
parents:
diff changeset
   154
    def __init__(self, kml):
hh
parents:
diff changeset
   155
        self.kml = kml
hh
parents:
diff changeset
   156
hh
parents:
diff changeset
   157
    def run(self,long,lat,alt,head,tilt,roll):
hh
parents:
diff changeset
   158
        self.kml.pr('<Camera>')
hh
parents:
diff changeset
   159
        self.kml.pr('<latitude>{}</latitude>'.format(lat))
hh
parents:
diff changeset
   160
        self.kml.pr('<longitude>{}</longitude>'.format(long))
hh
parents:
diff changeset
   161
        self.kml.pr('<altitude>{}</altitude>'.format(alt))
hh
parents:
diff changeset
   162
        self.kml.pr('<heading>{}</heading>'.format(head))
hh
parents:
diff changeset
   163
        self.kml.pr('<tilt>{}</tilt>'.format(tilt))
hh
parents:
diff changeset
   164
        self.kml.pr('<roll>{}</roll>'.format(roll))
hh
parents:
diff changeset
   165
        self.kml.pr('<altitudeMode>relativeToSeaFloor</altitudeMode>')
hh
parents:
diff changeset
   166
        self.kml.pr('</Camera>')
hh
parents:
diff changeset
   167
hh
parents:
diff changeset
   168
    def runL(self, long, lat, alt, head, tilt, range, roll):
hh
parents:
diff changeset
   169
        # dostává parametry LookAt, které konvertuje na parametry Camera tak, aby pohled byl stejný
hh
parents:
diff changeset
   170
        dLO, dLA, Z = l2c(lat, head, tilt, range)
hh
parents:
diff changeset
   171
        self.run(long + dLO, lat + dLA, Z, head, tilt, roll)
hh
parents:
diff changeset
   172
hh
parents:
diff changeset
   173
class Placemark():
hh
parents:
diff changeset
   174
    def __init__(self, kml):
hh
parents:
diff changeset
   175
        self.kml = kml
hh
parents:
diff changeset
   176
hh
parents:
diff changeset
   177
    def head(self, fn):
hh
parents:
diff changeset
   178
        self.kml.pr('<Placemark>')
hh
parents:
diff changeset
   179
        self.kml.pr('<name>{}</name>'.format(fn))
hh
parents:
diff changeset
   180
        self.kml.pr('<visibility>0</visibility>')
hh
parents:
diff changeset
   181
        self.kml.pr('<styleUrl>#PIN_YELLOW</styleUrl>')
hh
parents:
diff changeset
   182
hh
parents:
diff changeset
   183
    def tail(self):
hh
parents:
diff changeset
   184
        self.kml.pr('\n</Placemark>')
hh
parents:
diff changeset
   185
hh
parents:
diff changeset
   186
class SpeedAdjust():
hh
parents:
diff changeset
   187
    keys = ['none', 'linear', 'parabolic', 'tangential', 'exponential']
hh
parents:
diff changeset
   188
    abrv = {'none':'none', 'linear':'lin', 'parabolic':'par', 'tangential':'tang', 'exponential':'exp'}
hh
parents:
diff changeset
   189
hh
parents:
diff changeset
   190
    def __init__(self, const, koef, steps, config):
hh
parents:
diff changeset
   191
        self.slowdowns = {'none':self.Const, 'linear':self.Linear, 'parabolic':self.Parabolic, 'tangential':self.Tangent, 'exponential':self.Exponential}
hh
parents:
diff changeset
   192
        self.const = const
hh
parents:
diff changeset
   193
        self.koef = koef
hh
parents:
diff changeset
   194
        self.steps = steps
hh
parents:
diff changeset
   195
        self.c = config
hh
parents:
diff changeset
   196
hh
parents:
diff changeset
   197
    def phase(self):
hh
parents:
diff changeset
   198
        return 1 - self.c.xi / self.c.x0.val
hh
parents:
diff changeset
   199
hh
parents:
diff changeset
   200
    class Const():
hh
parents:
diff changeset
   201
        p = 1					# empirická konstanta
hh
parents:
diff changeset
   202
        def __init__(self, sa):
hh
parents:
diff changeset
   203
            self.sa = sa
hh
parents:
diff changeset
   204
        def koef(self):
hh
parents:
diff changeset
   205
            return self.p / self.sa.const
hh
parents:
diff changeset
   206
hh
parents:
diff changeset
   207
    class Linear():
hh
parents:
diff changeset
   208
        p = 2					# empirická konstanta
hh
parents:
diff changeset
   209
        def __init__(self, sa):
hh
parents:
diff changeset
   210
            self.sa = sa
hh
parents:
diff changeset
   211
        def koef(self):
hh
parents:
diff changeset
   212
            return self.p * self.sa.koef * self.sa.phase() / self.sa.const
hh
parents:
diff changeset
   213
hh
parents:
diff changeset
   214
    class Parabolic():
hh
parents:
diff changeset
   215
        p = 2					# empirická konstanta
hh
parents:
diff changeset
   216
        def __init__(self, sa):
hh
parents:
diff changeset
   217
            self.sa = sa
hh
parents:
diff changeset
   218
        def koef(self):
hh
parents:
diff changeset
   219
            return self.p * pow(self.sa.koef * self.sa.phase(), 2) / self.sa.const
hh
parents:
diff changeset
   220
hh
parents:
diff changeset
   221
    class Tangent():
hh
parents:
diff changeset
   222
        p = 1					# empirická konstanta
hh
parents:
diff changeset
   223
        def __init__(self, sa):
hh
parents:
diff changeset
   224
            self.sa = sa
hh
parents:
diff changeset
   225
        def koef(self):
hh
parents:
diff changeset
   226
            margin = atan(self.sa.koef)		# < pi/2
hh
parents:
diff changeset
   227
            return (1 + self.p * tan(self.sa.phase() * margin)) / self.sa.const
hh
parents:
diff changeset
   228
hh
parents:
diff changeset
   229
    class Exponential():
hh
parents:
diff changeset
   230
        p = 1					# empirická konstanta
hh
parents:
diff changeset
   231
        def __init__(self, sa):
hh
parents:
diff changeset
   232
            self.sa = sa
hh
parents:
diff changeset
   233
        def koef(self):
hh
parents:
diff changeset
   234
            return pow(e, self.p * self.sa.koef * self.sa.phase()) / self.sa.const
hh
parents:
diff changeset
   235
hh
parents:
diff changeset
   236
def canonGeodetic(a):
hh
parents:
diff changeset
   237
    if(a > 360 or a < -360): a = a % 360
hh
parents:
diff changeset
   238
    if(a > 180): a = a - 360
hh
parents:
diff changeset
   239
    if(a < -180): a = a + 360
hh
parents:
diff changeset
   240
    return a
hh
parents:
diff changeset
   241
hh
parents:
diff changeset
   242
def can360(a360):
hh
parents:
diff changeset
   243
    if(a360 < 0): a360 = a360 + 360
hh
parents:
diff changeset
   244
    elif(a360 > 360): a360 = a360 - 360
hh
parents:
diff changeset
   245
    return a360
hh
parents:
diff changeset
   246
hh
parents:
diff changeset
   247
def can180(a180):
hh
parents:
diff changeset
   248
    if(a180 < -180): a180 = a180 + 360
hh
parents:
diff changeset
   249
    elif(a180 > 180): a180 = a180 - 360
hh
parents:
diff changeset
   250
    return a180
hh
parents:
diff changeset
   251
hh
parents:
diff changeset
   252
def l2c(lat, head, tilt, range):
hh
parents:
diff changeset
   253
    RZ = 6378000
hh
parents:
diff changeset
   254
    RL = RZ * cos(radians(lat))
hh
parents:
diff changeset
   255
    Hc = can360(head + 180)
hh
parents:
diff changeset
   256
    Z = range * cos(radians(tilt))
hh
parents:
diff changeset
   257
    d = sqrt(pow(range,2) - pow(Z,2))
hh
parents:
diff changeset
   258
    dLA = degrees(atan(d * cos(radians(Hc)) / RZ))
hh
parents:
diff changeset
   259
    dLO = degrees(atan(d * sin(radians(Hc)) / RL))
hh
parents:
diff changeset
   260
    return dLO, dLA, Z
hh
parents:
diff changeset
   261
hh
parents:
diff changeset
   262
def deb(s):
hh
parents:
diff changeset
   263
    print('+++ {}'.format(s), file=sys.stderr)