|
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 |