|
0
|
1 |
import json
|
|
|
2 |
import os
|
|
|
3 |
|
|
|
4 |
import targets
|
|
|
5 |
from kml import *
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
class Config:
|
|
|
9 |
class Value:
|
|
|
10 |
def __init__(self, key, val):
|
|
|
11 |
self.key = key
|
|
|
12 |
self.val = val
|
|
|
13 |
self.chk = True
|
|
|
14 |
self.keyact = key + '_actual'
|
|
|
15 |
|
|
|
16 |
def extract(self, p):
|
|
|
17 |
if self.key in p:
|
|
|
18 |
self.val = p[self.key][0]
|
|
|
19 |
self.chk = True
|
|
|
20 |
|
|
|
21 |
class ValueN(Value):
|
|
|
22 |
def extract(self, p):
|
|
|
23 |
if self.key in p:
|
|
|
24 |
try:
|
|
|
25 |
self.val = float(p[self.key][0])
|
|
|
26 |
self.chk = True
|
|
|
27 |
except:
|
|
|
28 |
self.val = p[self.key][0]
|
|
|
29 |
self.chk = False
|
|
|
30 |
|
|
|
31 |
def __init__(self):
|
|
|
32 |
# -------------------------------------------------
|
|
|
33 |
# zadání - vstupní veličiny
|
|
|
34 |
# -------------------------------------------------
|
|
|
35 |
self.name = self.Value('NA', 'flyby')
|
|
|
36 |
self.targname = self.Value('TA', '')
|
|
|
37 |
self.lat = self.ValueN('LA', targets.Stalin.lat)
|
|
|
38 |
self.long = self.ValueN('LO', targets.Stalin.long)
|
|
|
39 |
self.h0 = self.ValueN('H0', 300)
|
|
|
40 |
self.x0 = self.ValueN('X0', 8000)
|
|
|
41 |
self.y0 = self.ValueN('Y0', -12000)
|
|
|
42 |
self.z0 = self.ValueN('Z0', 12000)
|
|
|
43 |
self.x1 = self.ValueN('X1', 0)
|
|
|
44 |
self.y1 = self.ValueN('Y1', -150)
|
|
|
45 |
self.z1 = self.ValueN('Z1', 100)
|
|
|
46 |
self.exp = self.ValueN('EX', 2)
|
|
|
47 |
self.steps = self.ValueN('ST', 600)
|
|
|
48 |
self.speedfact = self.ValueN('SPF', 1)
|
|
|
49 |
self.slowdown = self.Value('SLD', 'tangential')
|
|
|
50 |
self.slowdfact = self.ValueN('SLF', 1)
|
|
|
51 |
self.flyby = self.ValueN('FL', 1)
|
|
|
52 |
self.influentials = ['name', 'targname', 'lat', 'long', 'h0', 'x0', 'y0', 'z0',
|
|
|
53 |
'x1', 'y1', 'z1', 'exp', 'steps', 'speedfact', 'slowdown', 'slowdfact', 'flyby']
|
|
|
54 |
|
|
|
55 |
# -------------------------------------------------
|
|
|
56 |
# počáteční podmínky
|
|
|
57 |
# -------------------------------------------------
|
|
|
58 |
self.dXmin = 0.1 # min delta X při numerické konvergenci
|
|
|
59 |
self.minZ = 60 # minimální přípustná výška nad terénem v metrech
|
|
|
60 |
self.dHmax = 5 # empirické maximální přípustné otočení pohledu v jednom kroku ve stupních
|
|
|
61 |
self.durOpt = 23 # empirické optimum: rychlost otáčení pohledu = 23°/sec
|
|
|
62 |
self.stepsMax = 9999
|
|
|
63 |
|
|
|
64 |
# -------------------------------------------------
|
|
|
65 |
# provozní konstanty
|
|
|
66 |
# -------------------------------------------------
|
|
|
67 |
self.configsrv = 'kml'
|
|
|
68 |
self.dnldsrv = 'flyby'
|
|
|
69 |
if 'HTTP_HOST' in os.environ:
|
|
|
70 |
h = os.environ['HTTP_HOST'].split('.')
|
|
|
71 |
self.srvhost = h[0].lower()
|
|
|
72 |
self.srvdomain = '.'.join(h[1:])
|
|
|
73 |
self.dnldqual = '.'.join((self.dnldsrv, self.srvdomain))
|
|
|
74 |
self.configqual = '.'.join((self.configsrv, self.srvdomain))
|
|
|
75 |
_reqPath = os.environ['HTTP_HOST'] + os.environ['REQUEST_URI'].split('?')[0]
|
|
|
76 |
_configKeyWord = 'kml'
|
|
|
77 |
_dnldKeyWord = 'flyby'
|
|
|
78 |
self.configReq = _reqPath.lower().find(_configKeyWord) > -1
|
|
|
79 |
self.dnldReq = _reqPath.lower().find(_dnldKeyWord) > -1
|
|
|
80 |
_reqUrl = '{scheme}://{host}:{port}{path}'.\
|
|
|
81 |
format(scheme=os.environ['REQUEST_SCHEME'],
|
|
|
82 |
host=os.environ['HTTP_HOST'],
|
|
|
83 |
port=os.environ['SERVER_PORT'],
|
|
|
84 |
path=os.environ['REQUEST_URI'].split('?')[0])
|
|
|
85 |
self.dnldUrl = _reqUrl.lower().replace(_configKeyWord, _dnldKeyWord)
|
|
|
86 |
deb('self.dnldUrl=%s' % self.dnldUrl)
|
|
|
87 |
self.dnldPath = _reqPath.lower().replace(_configKeyWord, _dnldKeyWord)
|
|
|
88 |
deb('self.dnldPath=%s' % self.dnldPath)
|
|
|
89 |
self.defaultlat = 50.1
|
|
|
90 |
self.defaultlong = 14.3
|
|
|
91 |
self.parmsdir = 'params'
|
|
|
92 |
self.targsdir = 'targets'
|
|
|
93 |
self.kmlfn = 'flyby' # jméno výstupu - neměnné
|
|
|
94 |
self.zipped = False
|
|
|
95 |
# zipping se nedá v současnosti používat, protože Google Earth se s ním nechová standardně
|
|
|
96 |
# - viz .../memo/googleearth
|
|
|
97 |
self.kmlfile = '{}.{}'.format(self.kmlfn, 'kmz' if self.zipped else 'kml')
|
|
|
98 |
self.urlfile = 'url.kml'
|
|
|
99 |
self.msg = ''
|
|
|
100 |
self.flagged = False
|
|
|
101 |
|
|
|
102 |
def adjust(self):
|
|
|
103 |
self.x0.val = fabs(self.x0.val)
|
|
|
104 |
if self.x0.val < self.dXmin:
|
|
|
105 |
self.x0.val = 0
|
|
|
106 |
self.x1.val = 0
|
|
|
107 |
if self.z0.val < self.minZ:
|
|
|
108 |
self.z0.val = self.minZ
|
|
|
109 |
if self.z1.val < self.minZ:
|
|
|
110 |
self.z1.val = self.minZ
|
|
|
111 |
self.steps.val = int(round(self.steps.val))
|
|
|
112 |
if self.steps.val <= 0:
|
|
|
113 |
self.steps.val = 20
|
|
|
114 |
if self.steps.val > self.stepsMax:
|
|
|
115 |
self.steps.val = self.stepsMax
|
|
|
116 |
self.exp.val = fabs(self.exp.val)
|
|
|
117 |
self.flyby.val = int(fabs(self.flyby.val))
|
|
|
118 |
|
|
|
119 |
if self.x0.val > 0:
|
|
|
120 |
self.r0 = degrees(atan(self.y0.val / self.x0.val)) # lokální azimut na startu
|
|
|
121 |
self.r1 = 90 if self.y1.val < 0 else -90 # lokální azimut v průletu
|
|
|
122 |
if self.y1.val == 0:
|
|
|
123 |
if self.y0.val == 0:
|
|
|
124 |
self.r1 = 90
|
|
|
125 |
else:
|
|
|
126 |
self.r1 = 90 * fabs(self.y0.val) / self.y0.val
|
|
|
127 |
if self.exp.val <= 1:
|
|
|
128 |
self.r1 = -self.r1
|
|
|
129 |
self.h1 = can360(self.h0.val + self.r0 + self.r1) # azimut v průletu
|
|
|
130 |
self.h2 = can360(self.h0.val + 2 * (self.h1 - self.h0.val)) # azimut na konci
|
|
|
131 |
|
|
|
132 |
dY = self.y1.val - self.y0.val
|
|
|
133 |
dZ = self.z1.val - self.z0.val
|
|
|
134 |
if dY == 0:
|
|
|
135 |
self.A = pi / 2 if dZ < 0 else -pi / 2
|
|
|
136 |
else:
|
|
|
137 |
self.A = atan(dZ / dY) # sklon roviny letu, horiz = 0
|
|
|
138 |
if dY > 0:
|
|
|
139 |
self.A = self.A + pi if dZ <= 0 else self.A - pi
|
|
|
140 |
|
|
|
141 |
F = sqrt(pow(dY, 2) + pow(dZ, 2)) # maximální funkční hodnota
|
|
|
142 |
if self.x0.val > 0:
|
|
|
143 |
self.K = F / pow(self.x0.val, self.exp.val) # koeficient paraboly
|
|
|
144 |
|
|
|
145 |
sa = SpeedAdjust(self.speedfact.val, self.slowdfact.val, self.steps.val, self)
|
|
|
146 |
self.speedAdjust = sa.slowdowns[self.slowdown.val](sa)
|
|
|
147 |
|
|
|
148 |
self.lastH = self.h0.val
|
|
|
149 |
self.lastX, self.lastY, self.lastZ = self.x0.val, self.y0.val, self.z0.val
|
|
|
150 |
self.dX = -2 * self.x0.val / self.steps.val
|
|
|
151 |
if fabs(self.dX) < self.dXmin:
|
|
|
152 |
self.dX = -self.dXmin
|
|
|
153 |
self.sumSteps, self.sumDur = 0, 0
|
|
|
154 |
self.rr = []
|
|
|
155 |
|
|
|
156 |
def update_influentials(self, p):
|
|
|
157 |
for n in self.influentials:
|
|
|
158 |
v = eval('self.{}'.format(n))
|
|
|
159 |
v.extract(p)
|
|
|
160 |
self.flagged += (not v.chk)
|
|
|
161 |
|
|
|
162 |
v = self.lat
|
|
|
163 |
if v.chk:
|
|
|
164 |
v.chk = (v.val >= -90 and v.val <= 90)
|
|
|
165 |
v = self.long
|
|
|
166 |
if v.chk:
|
|
|
167 |
v.chk = v.val >= -180 and v.val <= 180
|
|
|
168 |
v = self.slowdown
|
|
|
169 |
v.chk = v.val in SpeedAdjust.keys
|
|
|
170 |
|
|
|
171 |
self.flagged = False
|
|
|
172 |
for n in self.influentials:
|
|
|
173 |
v = eval('self.{}'.format(n))
|
|
|
174 |
self.flagged += (not v.chk)
|
|
|
175 |
|
|
|
176 |
def parmspath(self):
|
|
|
177 |
return os.path.join(self.parmsdir, self.name.val)
|
|
|
178 |
|
|
|
179 |
def parmsls(self):
|
|
|
180 |
l = os.listdir(self.parmsdir)
|
|
|
181 |
l.sort()
|
|
|
182 |
#deb("l={}".format(l))
|
|
|
183 |
return l
|
|
|
184 |
|
|
|
185 |
def targspath(self, name):
|
|
|
186 |
return os.path.join(self.targsdir, name)
|
|
|
187 |
|
|
|
188 |
def targsls(self):
|
|
|
189 |
l = os.listdir(self.targsdir)
|
|
|
190 |
l.sort()
|
|
|
191 |
return l
|
|
|
192 |
|
|
|
193 |
def gettarget(self, name):
|
|
|
194 |
fn = name if name != '' else 'point'
|
|
|
195 |
path = self.targspath(fn)
|
|
|
196 |
long = self.defaultlong
|
|
|
197 |
lat = self.defaultlat
|
|
|
198 |
if os.path.exists(path):
|
|
|
199 |
g = {}
|
|
|
200 |
for p in open(path).read().split(','):
|
|
|
201 |
k, v = p.split('=')
|
|
|
202 |
g[k] = v
|
|
|
203 |
if self.long.key in g:
|
|
|
204 |
long = g[self.long.key]
|
|
|
205 |
if self.lat.key in g:
|
|
|
206 |
lat = g[self.lat.key]
|
|
|
207 |
return long, lat
|
|
|
208 |
|
|
|
209 |
def storetarget(self, name, long, lat):
|
|
|
210 |
fn = name if name != '' else 'point'
|
|
|
211 |
path = self.targspath(fn)
|
|
|
212 |
open(path, mode='w').write('{}={},{}={}'.format(self.lat.key, lat, self.long.key, long))
|
|
|
213 |
|
|
|
214 |
def restoreparms(self):
|
|
|
215 |
if not os.path.exists(self.parmspath()):
|
|
|
216 |
return
|
|
|
217 |
parms = dict(json.load(open(self.parmspath())))
|
|
|
218 |
# for p in open(self.parmspath()).read().split(','):
|
|
|
219 |
# k,v = p.split('=')
|
|
|
220 |
# parms[k] = [v]
|
|
|
221 |
self.update_influentials(parms)
|
|
|
222 |
|
|
|
223 |
def storeparms(self):
|
|
|
224 |
if not self.name:
|
|
|
225 |
return
|
|
|
226 |
# s = []
|
|
|
227 |
p = {}
|
|
|
228 |
for n in self.influentials:
|
|
|
229 |
v = eval('self.{}'.format(n))
|
|
|
230 |
# s = s + ['='.join((v.key,str(v.val)))]
|
|
|
231 |
p[v.key] = [str(v.val)]
|
|
|
232 |
# open(self.parmspath(), mode='w').write(','.join(s))
|
|
|
233 |
json.dump(p, open(self.parmspath(), mode='w'), ensure_ascii=False)
|
|
|
234 |
|
|
|
235 |
def printparms(self):
|
|
|
236 |
s = []
|
|
|
237 |
for n in self.influentials:
|
|
|
238 |
v = eval('self.{}'.format(n))
|
|
|
239 |
s = s + ['{}={}'.format(v.key, v.val)]
|
|
|
240 |
return '\n'.join(s)
|
|
|
241 |
|
|
|
242 |
def adjustenv(self):
|
|
|
243 |
p = {}
|
|
|
244 |
for k in os.environ:
|
|
|
245 |
p[k] = [os.environ[k]]
|
|
|
246 |
return p
|