2 ########################################################
3 # routines to set up weather tiles
4 # Thorsten Renk, June 2011
5 ########################################################
9 # tile_start to execute jobs common for all tiles on startup
10 # tile_finished to execute jobs common for all tiles when tile creation is done
11 # set_NN_tile to set a weather tile of type NN
12 # create_NN to create the cloud configuration NN
13 # adjust_p to make sure pressure variation cannot exceed limits between tiles
14 # calc_geo to get local Cartesian geometry for latitude conversion
15 # get_lat to get latitude from Cartesian coordinates
16 # get_lon to get longitude from Cartesian coordinates
18 ####################################
20 ####################################
22 var tile_start = func {
25 if (local_weather.thread_flag == 1){setprop(lw~"tmp/thread-status","computing");}
28 var current_code = getprop(lw~"tiles/code");
29 var dir_index = getprop(lw~"tiles/tmp/dir-index");
30 props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("code").setValue(current_code);
32 #print(current_code, getprop(lw~"tiles/tmp/code"));
34 if (current_code != getprop(lw~"tiles/tmp/code"))
35 {weather_tiles.rnd_store = rand();}
37 # generate a handling array for models
40 append(weather_tile_management.modelArrays,array);
45 var tile_finished = func {
47 var current_code = getprop(lw~"tiles/code");
49 setprop(lw~"clouds/placement-index",0);
50 setsize(elat,0); setsize(elon,0); setsize(erad,0);
52 var dir_index = getprop(lw~"tiles/tmp/dir-index");
53 #props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("code").setValue(current_code);
55 local_weather.assemble_effect_array();
57 # add a noctilucent cloud patch
59 var tile_index = getprop("local-weather/tiles/tile-counter");
60 if ((tile_index == 1) and (getprop("environment/create-noctilucent-clouds")==1))
63 var blat = getprop(lw~"tiles/tmp/latitude-deg");
64 var blon = getprop(lw~"tiles/tmp/longitude-deg");
65 create_noctilucent_patch(blat, blon, 272000.0, alpha);
70 local_weather.top_shade = 1.0;
72 if (local_weather.debug_output_flag == 1)
73 {print("Finished setting up tile type ",current_code, " in direction ",dir_index);}
75 if (local_weather.thread_flag == 1)
76 {setprop(lw~"tmp/thread-status","placing");}
77 else # without worker threads, tile generation is complete at this point
78 {props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("generated-flag").setValue(2);}
87 ####################################
89 ####################################
91 var set_4_8_stratus_tile = func {
93 setprop(lw~"tiles/code","test");
102 var alpha = getprop(lw~"tmp/tile-orientation-deg");
103 var phi = alpha * math.pi/180.0;
104 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
106 # get tile center coordinates
108 var blat = getprop(lw~"tiles/tmp/latitude-deg");
109 var blon = getprop(lw~"tiles/tmp/longitude-deg");
112 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
114 local_weather.set_weather_station(blat, blon, alt_offset, 45000.0, 14.0, 12.0, 29.78);
118 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
121 #local_weather.create_cumosys(blat,blon, 3000.0, get_n(strength), 20000.0);
123 #create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
124 # create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
125 #create_6_8_stratus(blat, blon, 3000+alt_offset, alpha) ;
126 #create_4_8_tstratus_patches(blat, blon, 5000+alt_offset, alpha) ;
127 #create_4_8_sstratus_patches(blat, blon, 5000+alt_offset, alpha) ;
128 #create_4_8_cirrostratus_patches(blat, blon, 5000+alt_offset, alpha) ;
130 #create_4_8_cirrocumulus_streaks(blat, blon, 10000.0 + alt_offset, alpha);
131 #create_4_8_alttstratus_streaks(blat, blon, 5000+alt_offset, alpha) ;
132 # create_2_8_cirrocumulus_patches(blat, blon, 13000+alt_offset, alpha) ;
134 # create_8_8_nimbus_rain(blat, blon, 3000.0, alpha, 0.3) ;
135 #create_8_8_tstratus(blat, blon, 5000+alt_offset, alpha);
137 # create_8_8_cirrostratus(blat, blon, 30000.0, alpha);
139 #create_thunderstorm_scenario (blat, blon, 3000.0, alpha);
140 #create_big_thunderstorm (blat, blon, 3000.0, alpha);
142 #create_2_8_cirrus(blat, blon, 30000.0, alpha);
143 #create_2_8_cirrus(blat, blon, 20000.0, alpha);
144 # create_4_8_cirrus(blat, blon, 30000.0, alpha);
146 # create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ;
148 # create_detailed_stratocumulus_bank(blat, blon, 4000,alpha);
150 #create_4_8_tstratus_undulatus(blat, blon, 10000.0, alpha);
152 #local_weather.top_shade = 0.9;
154 #create_4_8_small_cumulus_alleys(blat, blon, 3000.0, alpha);
155 #create_4_8_cirrostratus_undulatus(blat, blon, 25000.0, alpha);
157 #create_2_8_mackarel(blat,blon, 12000.0, alpha);
158 #create_2_8_cirrocumulus_domains(blat, blon, 12000.0, alpha);
159 #create_2_8_altocumulus_perlucidus_domains(blat, blon, 12000.0, alpha);
160 #create_4_8_cirrostratus_mackarel(blat,blon, 25000.0, alpha);
161 #create_2_8_cirrocumulus_domains(blat,blon, 30000.0, alpha);
164 #local_weather.create_cumosys(blat,blon, 3000.0, get_n(strength), 20000.0);
165 local_weather.set_atmosphere_ipoint(blat, blon, 45000.0, 3000.0, 45000.0, 0.0, 15000.0, 17000.0, 0.8, 12000.0, 17000.0);
168 append(weather_dynamics.tile_convective_altitude,3000.0);
169 append(weather_dynamics.tile_convective_strength,0.0);
177 ####################################
179 ####################################
181 var set_high_pressure_core_tile = func {
183 #set_4_8_stratus_tile ();
186 setprop(lw~"tiles/code","high_pressure_core");
195 var alpha = getprop(lw~"tmp/tile-orientation-deg");
196 var phi = alpha * math.pi/180.0;
197 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
199 # get tile center coordinates
201 var blat = getprop(lw~"tiles/tmp/latitude-deg");
202 var blon = getprop(lw~"tiles/tmp/longitude-deg");
205 # get probabilistic values for the weather parameters
207 var vis = 25000.0 + rand() * 10000.0;
208 var T = 20.0 + rand() * 10.0;
209 var spread = 14.0 + 8.0 * rand();
211 var p = 1025.0 + rand() * 6.0; p = adjust_p(p);
213 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
215 # and set them at the tile center
216 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
220 var alt = spread * 400;
224 # bias Cumulus clouds towards smaller sizes due to lack of water vapour and convection
225 local_weather.convective_size_bias = -0.2 - rand() * 0.1;
229 if (rand() < small_scale_persistence)
238 # cloud scenario 1: weak cumulus development and blue thermals
240 strength = rand() * 0.05;
241 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
243 # generate a few blue thermals
245 if (local_weather.generate_thermal_lift_flag !=0)
247 local_weather.generate_thermal_lift_flag = 3;
248 strength = rand() * 0.4;
249 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
250 local_weather.generate_thermal_lift_flag = 2;
253 # and specify the atmosphere
254 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, 25000.0, 30000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0);
258 # cloud scenario 2: some Cirrocumulus patches
260 strength = rand() * 0.03;
261 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
263 #create_2_8_cirrocumulus(blat, blon, alt + alt_offset + 5000.0, alpha);
264 create_1_8_alttstratus_domains(blat, blon, alt + alt_offset + 5000.0, alpha);
266 create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
268 # and specify the atmosphere
269 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.1, alt+alt_offset +30000.0, alt+alt_offset + 35000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0);
273 # cloud scenario 3: Cirrostratus undulatus over weak cumulus
275 strength = rand() * 0.03;
276 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
278 create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
280 # and specify the atmosphere
281 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0);
286 # cloud scenario 4: Cirrocumulus mackerel sky
288 strength = rand() * 0.03;
289 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
291 ##create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
292 create_1_8_cirrocumulus_mackerel(blat, blon, alt + alt_offset + 32000.0, alpha);
293 #create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 32000.0, alpha);
296 # and specify the atmosphere
297 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
299 else if (rn > 0.5833)
301 # cloud scenario 5: Cirrus
303 create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
306 create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
309 create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
311 # and specify the atmosphere
312 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.95, alt+alt_offset, alt+alt_offset + 2500.0);
316 # cloud scenario 6: strong Cirrus cover
318 create_4_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
319 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
323 # cloud scenario 7: clear
325 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 33000.0, 1.0, alt+alt_offset, alt+alt_offset + 2500.0);
329 # cloud scenario 8: Stratiform hazy clouds
331 local_weather.top_shade = 0.8;
332 create_2_8_alttstratus_domains(blat, blon, alt+alt_offset, alpha);
333 local_weather.top_shade = 0.9;
334 create_4_8_tstratus_undulatus(blat, blon, alt+alt_offset + 4000, alpha);
336 # and specify the atmosphere
337 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
340 else if (rn > 0.0833)
342 # cloud scenario 9: Cirrocumulus
344 if (rand() > 0.4) # this is very expensive, so don't do it for every tile
345 {create_2_8_cirrocumulus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
347 # {create_2_8_cirrocumulus(blat, blon, alt + alt_offset + 26000.0, alpha);}
349 # and specify the atmosphere
350 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
355 # cloud scenario 10: amorphous Cirrostratus
357 strength = rand() * 0.03;
358 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
360 create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 32000.0, alpha);
362 # and specify the atmosphere
363 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.45, alt+alt_offset +28000.0, alt+alt_offset + 32000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
368 # store convective altitude and strength
370 append(weather_dynamics.tile_convective_altitude,alt);
371 append(weather_dynamics.tile_convective_strength,strength);
379 ####################################
381 ####################################
383 var set_high_pressure_tile = func {
385 setprop(lw~"tiles/code","high_pressure");
395 var alpha = getprop(lw~"tmp/tile-orientation-deg");
396 var phi = alpha * math.pi/180.0;
397 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
399 # get tile center coordinates
401 var blat = getprop(lw~"tiles/tmp/latitude-deg");
402 var blon = getprop(lw~"tiles/tmp/longitude-deg");
405 # get probabilistic values for the weather parameters
407 var vis = 20000.0 + rand() * 10000.0;
408 var T = 15.0 + rand() * 10.0;
409 var spread = 10.0 + 4.0 * rand();
411 var p = 1019.0 + rand() * 6.0; p = adjust_p(p);
413 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
415 # and set them at the tile center
416 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
419 var alt = spread * 400;
423 # print("alt: ",alt, "spread: ", spread, "offset: ", alt_offset);
427 if (rand() < small_scale_persistence)
432 # daily modulation - layers are more pronounced during morning and evening and dissolve during the day
434 var t = getprop("sim/time/utc/day-seconds");
435 t = t + getprop("sim/time/local-offset");
436 var sec_to_rad = 2.0 * math.pi/86400;
437 var t_factor1 = 0.5 * (1.0-math.cos((t * sec_to_rad)));
443 # cloud scenario 1: possible Cirrus over Cumulus
444 strength = 0.2 + rand() * 0.4;
445 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
447 # one or two Cirrus clouds
449 x = 2000.0 + rand() * 16000.0;
450 y = 2.0 * (rand()-0.5) * 18000;
451 var path = local_weather.select_cloud_model("Cirrus", "small");
452 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset + 25000.0 + rand() * 5000.0,alpha);
456 x = -2000.0 - rand() * 16000.0;
457 y = 2.0 * (rand()-0.5) * 18000;
458 var path = local_weather.select_cloud_model("Cirrus", "small");
459 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset +25000.0 + rand() * 5000.0,alpha);
462 # and specify the atmosphere
463 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +28000.0, alt+alt_offset + 30000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
468 # cloud scenario 2: Cirrostratus over weak Cumulus
470 strength = 0.2 + rand() * 0.2;
471 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
473 #create_2_8_cirrostratus(blat, blon, alt+alt_offset+25000.0, alpha);
474 create_2_8_cirrostratus_mackerel(blat, blon, alt+alt_offset+25000.0, alpha);
476 # and specify the atmosphere
477 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
482 # cloud scenario 3: Cirrocumulus sheet over Cumulus
484 strength = 0.2 + rand() * 0.2;
485 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
487 x = 2.0 * (rand()-0.5) * 5000;
488 y = 2.0 * (rand()-0.5) * 5000;
491 var path = local_weather.select_cloud_model("Cirrocumulus", "large");
492 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset +24000,alpha);
495 # and specify the atmosphere
496 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 24000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
501 # cloud scenario 4: Cirrostratus undulatus over weak Cumulus
503 strength = 0.15 + rand() * 0.15;
504 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
508 create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
512 create_4_8_cirrus_bundle(blat, blon, alt + alt_offset + 25000.0, alpha);
515 # and specify the atmosphere
516 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.35, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
520 # cloud scenario 5: some scattered Altocumuli over Cumulus
522 strength = 0.25 + rand() * 0.1;
523 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
525 create_1_8_altocumulus_scattered(blat, blon, alt+alt_offset+10000.0, alpha);
527 create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
529 # and specify the atmosphere
530 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
534 # cloud scenario 6: Cirrocumulus over Cumulus
535 strength = 0.2 + rand() * 0.1;
536 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
538 if (rand() > 0.6) # this is very expensive, so don't do it for every tile
539 {create_2_8_cirrocumulus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
541 {create_1_8_alttstratus_domains(blat, blon, alt + alt_offset + 26000.0, alpha);}
543 # and specify the atmosphere
544 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.3, alt+alt_offset +24000.0, alt+alt_offset + 26000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
548 # cloud scenario 7: just Cumulus
550 strength = 0.3 + rand() * 0.2;
551 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
553 # and specify the atmosphere
554 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
558 # cloud scenario 8: Altocumulus Perlucidus over Cumulus
560 strength = 0.2 + rand() * 0.1;
561 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
564 if (rand()>0.5* t_factor1)
565 {create_2_8_altocumulus_perlucidus_domains(blat, blon, alt + alt_offset + 12000.0, alpha);}
567 # and specify the atmosphere
568 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
572 # cloud scenario 9: Thin Stratus over Cumulus
574 strength = 0.2 + rand() * 0.1;
575 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
577 if (rand()>0.5* t_factor1)
578 {create_2_8_alttstratus_domains(blat, blon, alt + alt_offset + 12000.0, alpha);}
580 # and specify the atmosphere
581 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
585 # cloud scenario 10: Mackerel Cirrocumulus
587 strength = 0.3 + rand() * 0.1;
588 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
591 {create_1_8_cirrocumulus_mackerel(blat, blon, alt + alt_offset + 20000.0, alpha);}
593 # and specify the atmosphere
594 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.9, alt+alt_offset, alt+alt_offset + 2500.0);
599 # store convective altitude and strength
601 append(weather_dynamics.tile_convective_altitude,alt);
602 append(weather_dynamics.tile_convective_strength,strength);
610 ####################################
611 # high pressure border
612 ####################################
614 var set_high_pressure_border_tile = func {
616 setprop(lw~"tiles/code","high_pressure_border");
625 var alpha = getprop(lw~"tmp/tile-orientation-deg");
626 var phi = alpha * math.pi/180.0;
627 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
629 # get tile center coordinates
631 var blat = getprop(lw~"tiles/tmp/latitude-deg");
632 var blon = getprop(lw~"tiles/tmp/longitude-deg");
635 # get probabilistic values for the weather parameters
637 var vis = 15000.0 + rand() * 7000.0;
638 var T = 12.0 + rand() * 10.0;
639 var spread = 7.0 + 4.0 * rand();
641 var p = 1013.0 + rand() * 6.0; p = adjust_p(p);
643 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
645 # and set them at the tile center
646 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
649 # now a random selection of different possible cloud configuration scenarios
651 var alt = spread * 400;
658 if (rand() < small_scale_persistence)
668 # cloud scenario 1: Altocumulus patch over weak Cumulus
669 strength = 0.1 + rand() * 0.1;
670 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
672 #x = 2.0 * (rand()-0.5) * 5000;
673 #y = 2.0 * (rand()-0.5) * 5000;
674 #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,30,1000.0,0.2,1200.0,30,1000.0,0.2,1200.0,alpha ,1.0);
676 create_2_8_altocumulus_domains(blat, blon, alt+alt_offset +12000.0, alpha);
678 # and specify the atmosphere
679 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
684 # cloud scenario 2: Perlucidus variations
685 strength = 0.1 + rand() * 0.15;
686 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
688 #x = 2.0 * (rand()-0.5) * 10000;
689 #y = 2.0 * (rand()-0.5) * 10000;
690 #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,25,700.0,0.2,800.0,10,700.0,0.2,800.0,alpha ,1.4);
691 #x = 2.0 * (rand()-0.5) * 10000;
692 #y = 2.0 * (rand()-0.5) * 10000;
693 #local_weather.create_streak("Altocumulus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 12000.0+alt+alt_offset,1500.0,22,750.0,0.2,1000.0,8,750.0,0.2,1000.0,alpha ,1.1);
696 {create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset +12000.0, alpha);}
698 {create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset +12000.0, alpha);}
700 # and specify the atmosphere
701 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
706 # cloud scenario 3: Cirrus
708 strength = 0.1 + rand() * 0.1;
709 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
711 create_2_8_cirrus(blat, blon, alt + 28000.0 + alt_offset, alpha);
713 # and specify the atmosphere
714 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 22000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
719 # cloud scenario 4: thin Stratus streaks
721 strength = 0.7 + rand() * 0.3;
722 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
724 #create_4_8_alttstratus_streaks(blat, blon, alt+alt_offset +10000.0, alpha);
725 create_4_8_alttstratus_domains(blat, blon, alt+alt_offset +10000.0, alpha);
727 # and specify the atmosphere
728 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +10000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
733 # cloud scenario 5: scattered Altocumulus perlucidus
735 strength = 0.4 + rand() * 0.2;
736 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
738 var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
740 #local_weather.create_streak("Stratus (structured)",blat, blon, alt+6000.0+alt_offset+size_offset,1000.0,18,0.0,0.3,20000.0,18,0.0,0.3,20000.0,0.0,1.0);
741 create_4_8_sstratus_domains(blat, blon, alt+alt_offset+size_offset +6000.0, alpha);
742 #create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset+size_offset +6000.0, alpha);
744 # and specify the atmosphere
745 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
750 # cloud scenario 6: Cirrocumulus sheets
752 strength = 0.2 + rand() * 0.2;
753 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
756 for (var i = 0; i < 2; i = i + 1)
758 x = 2.0 * (rand()-0.5) * 10000;
759 y = -6000 + i * 12000 + 2.0 * (rand()-0.5) * 1000;
761 var beta = rand() * 90;
762 var alt_variation = rand() * 2000;
764 var path = local_weather.select_cloud_model("Cirrocumulus", "large");
765 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset +20000+ alt_variation,alpha+ beta);
768 # and specify the atmosphere
769 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
773 # cloud scenario 7: Thin Cirrocumulus sheets over weak Cumulus
775 strength = 0.05 + rand() * 0.1;
776 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
778 #create_4_8_cirrocumulus_streaks(blat, blon, alt + 6000.0 + alt_offset, alpha);
779 create_4_8_alttstratus_domains(blat, blon, alt + 6000.0 + alt_offset, alpha);
781 # and specify the atmosphere
782 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +6000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
787 # cloud scenario 8: Altocumulus perlucidus
789 create_4_8_altocumulus_perlucidus(blat, blon, alt + 10000.0 + alt_offset, alpha);
791 create_2_8_cirrus(blat, blon, alt + 30000.0 + alt_offset, alpha);
793 # and specify the atmosphere
794 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +26000.0, alt+alt_offset + 30000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
799 # cloud scenario 9: Cumulus, Altocumulus and Cirrus
801 strength = 0.3 + rand() * 0.15;
802 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
804 create_1_8_altocumulus_scattered(blat, blon, alt + 12000.0 + alt_offset, alpha);
805 create_2_8_altocumulus_streaks(blat, blon, alt + 12000.0 + alt_offset, alpha);
807 create_2_8_cirrus(blat, blon, alt + 30000.0 + alt_offset, alpha);
809 # and specify the atmosphere
810 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +26000.0, alt+alt_offset + 30000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
814 # cloud scenario 10: Cumulus alleys and Cirrus
816 create_4_8_cumulus_alleys(blat, blon, alt+ alt_offset, alpha);
817 create_4_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
819 # and specify the atmosphere
820 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.1, alt+alt_offset +30000.0, alt+alt_offset + 35000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
824 # store convective altitude and strength
826 append(weather_dynamics.tile_convective_altitude,alt);
827 append(weather_dynamics.tile_convective_strength,strength);
834 ####################################
835 # low pressure border
836 ####################################
838 var set_low_pressure_border_tile = func {
840 setprop(lw~"tiles/code","low_pressure_border");
849 var alpha = getprop(lw~"tmp/tile-orientation-deg");
850 var phi = alpha * math.pi/180.0;
853 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
856 # get tile center coordinates
858 var blat = getprop(lw~"tiles/tmp/latitude-deg");
859 var blon = getprop(lw~"tiles/tmp/longitude-deg");
862 # get probabilistic values for the weather parameters
864 var vis = 8000.0 + rand() * 8000.0;
865 var T = 10.0 + rand() * 10.0;
866 var spread = 6.0 + 2.0 * rand();
868 var p = 1007.0 + rand() * 6.0; p = adjust_p(p);
870 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
872 # and set them at the tile center
873 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
875 # altitude for the lowest layer
876 var alt = spread * 400.0;
879 # bias Cumulus clouds towards larger sizes due to lots of water vapour
880 local_weather.convective_size_bias = 0.2 + rand() * 0.2;
882 # now a random selection of different possible cloud configuration scenarios
886 if (rand() < small_scale_persistence)
895 # cloud scenario 1: low Stratocumulus, thin streaks above
897 strength = 0.05 + rand() * 0.1;
898 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
900 create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
902 create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+4000.0,alpha);
904 # and specify the atmosphere
905 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
910 # cloud scenario 2: weak Cumulus, Stratus undulatus above
912 strength = 0.2 + rand() * 0.2;
913 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
915 #create_6_8_tstratus_undulatus(blat, blon, alt+alt_offset+4000.0,alpha);
916 create_6_8_tstratus_mackerel(blat, blon, alt+alt_offset+4000.0,alpha);
918 create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+7000.0,alpha);
920 # and specify the atmosphere
921 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
925 # cloud scenario 3: Stratocumulus banks with patches above
927 create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
928 create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
930 create_4_8_alttstratus_domains(blat, blon, alt+alt_offset+4000.0,alpha);
932 # and specify the atmosphere
933 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0);
937 # cloud scenario 4: structured Stratus
939 alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
940 create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
942 create_2_8_alttstratus_domains(blat, blon, alt+alt_offset+7000.0,alpha);
943 # and specify the atmosphere
944 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.25, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0);
948 # cloud scenario 5: Stratus blending with Cumulus with Cirrocumulus above
950 strength = 0.1 + rand() * 0.1;
951 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
953 #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
954 create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
956 #create_4_8_cirrocumulus_undulatus(blat, blon, alt+alt_offset + 12000.0,alpha);
957 create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset + 12000.0,alpha);
959 # and specify the atmosphere
960 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.15, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
964 # cloud scenario 6: small Stratocumulus banks
966 create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
967 create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
969 #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
970 create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
972 create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
974 # and specify the atmosphere
975 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.3, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
979 # cloud scenario 7: blended structured and unstructured Stratiform clouds
981 #create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
982 create_4_8_tstratus_domains(blat, blon, alt+alt_offset,alpha);
984 create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
986 create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
988 # and specify the atmosphere
989 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
993 # cloud scenario 8: Cumulus alleys beneath a high dense stratus cover
995 local_weather.top_shade = 0.7;
996 create_4_8_cumulus_alleys(blat, blon, alt+ alt_offset, alpha);
998 local_weather.top_shade = 1.0;
999 #create_6_8_tstratus_undulatus(blat, blon, alt+alt_offset + 6000.0,alpha);
1000 create_6_8_tstratus_mackerel(blat, blon, alt+alt_offset + 6000.0,alpha);
1002 # and specify the atmosphere
1003 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.5, alt+alt_offset +5500.0, alt+alt_offset + 6500.0, 0.65, alt+alt_offset + 6000.0, alt+alt_offset + 7500.0);
1007 # cloud scenario 9: weak Cumulus benath a high dense stratus cover
1009 local_weather.top_shade = 0.6;
1011 strength = 0.2 + rand() * 0.2;
1012 #local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1014 var n = int(3000 * strength) * 0.2;
1015 local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 0.3,1.4 , size(elat), elat, elon, erad);
1017 local_weather.top_shade = 1.0;
1018 create_6_8_stratus(blat, blon, alt+alt_offset + 8000.0,alpha);
1020 create_1_8_cirrus_bundle(blat, blon, alt+alt_offset + 34000.0,alpha);
1022 # and specify the atmosphere
1023 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset + 8000.0, vis + 15000.0, 0.7, alt+alt_offset +7500.0, alt+alt_offset + 8500.0, 0.65, alt+alt_offset + 8000.0, alt+alt_offset + 9500.0);
1027 # cloud scenario 10: broken structured Stratus cover
1030 create_4_8_sstratus_bundle(blat, blon, alt+alt_offset,alpha);
1032 #create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
1034 # and specify the atmosphere
1035 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 15000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1041 # store convective altitude and strength
1043 append(weather_dynamics.tile_convective_altitude,alt);
1044 append(weather_dynamics.tile_convective_strength,strength);
1050 ####################################
1052 ####################################
1054 var set_low_pressure_tile = func {
1056 setprop(lw~"tiles/code","low_pressure");
1065 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1066 var phi = alpha * math.pi/180.0;
1069 if (local_weather.presampling_flag == 0)
1070 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1072 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1074 # get tile center coordinates
1076 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1077 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1080 # get probabilistic values for the weather parameters
1082 var vis = 8000.0 + rand() * 5000.0;
1083 var T = 5.0 + rand() * 10.0;
1084 var spread = 5.0 + 2.0 * rand();
1086 var p = 1001.0 + rand() * 6.0; p = adjust_p(p);
1088 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1090 # and set them at the tile center
1091 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1093 # altitude for the lowest layer
1094 var alt = spread * 400.0;
1101 if (rand() < small_scale_persistence)
1110 # cloud scenario 1: two patches of Nimbostratus with precipitation
1111 # overhead broken stratus layers
1114 x = 2.0 * (rand()-0.5) * 11000.0;
1115 y = 2.0 * (rand()-0.5) * 11000.0;
1116 var beta = rand() * 360.0;
1119 if (local_weather.hardcoded_clouds_flag == 1) {alt_eff = alt_eff - 3000.0;}
1121 local_weather.create_layer("Nimbus", blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt_eff+alt_offset, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 1, 1.0);
1122 local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt + alt_offset, 5000.0, 0.3, -1, -1, -1,0,-1 );
1123 local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt+alt_offset-300.0, 1500.0, 0.5, -1, -1, -1,0,-1 );
1125 x = 2.0 * (rand()-0.5) * 11000.0;
1126 y = 2.0 * (rand()-0.5) * 11000.0;
1127 var beta = rand() * 360.0;
1129 local_weather.create_layer("Nimbus", blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt_eff+alt_offset, 500.0, 10000.0, 6000.0, beta, 1.0, 0.2, 1, 1.0);
1130 local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt + alt_offset, 5000.0, 0.3, -1, -1, -1,0 ,-1);
1131 local_weather.create_effect_volume(2, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 8000.0, 4000.0, beta, 0.0, alt+alt_offset-300.0, 1500.0, 0.5, -1, -1, -1,0,-1 );
1133 #create_4_8_sstratus_undulatus(blat, blon, alt+alt_offset +3000.0, alpha);
1134 create_4_8_sstratus_bundle(blat, blon, alt+alt_offset +3000.0, alpha);
1136 create_2_8_tstratus(blat, blon, alt+alt_offset +6000.0, alpha);
1138 # and specify the atmosphere
1139 local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 22000.0, 0.2, alt+alt_offset +15000.0, alt+alt_offset + 20000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0);
1143 # cloud scenario 2: 8/8 Stratus with light precipitation
1144 # above broken cover
1147 alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1148 create_8_8_stratus(blat, blon, alt+alt_offset,alpha);
1149 local_weather.create_effect_volume(3, blat, blon, 18000.0, 18000.0, 0.0, 0.0, 1800.0, 8000.0, -1, -1, -1, -1, 0,-1);
1150 local_weather.create_effect_volume(3, blat, blon, 14000.0, 14000.0, 0.0, 0.0, 1500.0, 6000.0, 0.1, -1, -1, -1,0,-1 );
1151 create_2_8_sstratus_bundle(blat, blon, alt+alt_offset+3000,alpha);
1153 # and specify the atmosphere
1154 local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 25000.0, 0.3, alt+alt_offset +15000.0, alt+alt_offset + 20000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0);
1159 # cloud scenario 3: multiple broken layers
1162 alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1163 create_4_8_stratus(blat, blon, alt+alt_offset,alpha);
1164 create_4_8_stratus_patches(blat, blon, alt+alt_offset+3000,alpha);
1165 create_4_8_sstratus_bundle(blat, blon, alt+alt_offset+6000,alpha);
1166 create_2_8_tstratus(blat, blon, alt+alt_offset+8000,alpha);
1168 # and specify the atmosphere
1169 local_weather.set_atmosphere_ipoint(blat, blon, vis + 17000.0, alt+alt_offset, vis + 25000.0, 0.35, alt+alt_offset +10000.0, alt+alt_offset + 20000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1173 # cloud scenario 4: a low 6/8 layer and some clouds above
1176 alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
1177 create_6_8_stratus(blat, blon, alt+alt_offset,alpha);
1178 create_2_8_sstratus_bundle(blat, blon, alt+alt_offset+6000,alpha);
1180 # and specify the atmosphere
1181 local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 24000.0, 0.2, alt+alt_offset +15000.0, alt+alt_offset + 22000.0, 0.7 - rand() * 0.1, alt+alt_offset, alt+alt_offset + 2500.0);
1185 # cloud scenario 5: a low 8/8 layer without rain
1187 alt = alt + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
1188 create_8_8_nimbus_rain(blat, blon, alt+alt_offset, alpha,0.0);
1192 create_2_8_cirrus(blat, blon, alt+alt_offset + 28000.0,alpha);
1195 # and specify the atmosphere
1196 local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 24000.0, 0.05, alt+alt_offset +5000.0, alt+alt_offset + 8000.0, 0.55, alt+alt_offset, alt+alt_offset + 2500.0);
1198 # store convective altitude and strength
1200 append(weather_dynamics.tile_convective_altitude,alt);
1201 append(weather_dynamics.tile_convective_strength,strength);
1208 ####################################
1210 ####################################
1212 var set_low_pressure_core_tile = func {
1214 setprop(lw~"tiles/code","low_pressure_core");
1223 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1224 var phi = alpha * math.pi/180.0;
1226 if (local_weather.presampling_flag == 0)
1227 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1229 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1231 # get tile center coordinates
1233 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1234 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1237 # get probabilistic values for the weather parameters
1239 var vis = 5000.0 + rand() * 5000.0;
1240 var T = 3.0 + rand() * 7.0;
1241 var spread = 4.5 + 1.0 * rand();
1243 var p = 995.0 + rand() * 6.0; p = adjust_p(p);
1245 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1247 # and set them at the tile center
1248 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1251 # set a closed Nimbostratus layer
1253 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
1258 create_8_8_nimbus_rain(blat, blon, alt+alt_offset, alpha,0.4 + rand()*0.2);
1261 # and some broken Stratus cover above
1265 if (rand() < small_scale_persistence)
1270 if (rn > 0.5){create_4_8_stratus_patches(blat, blon, alt+alt_offset+3000.0, alpha);}
1271 else {create_4_8_stratus(blat, blon, alt+alt_offset+3000.0, alpha);}
1274 local_weather.set_atmosphere_ipoint(blat, blon, vis + 20000.0, alt+alt_offset, vis + 25000.0, 0.0, alt+alt_offset +15000.0, alt+alt_offset + 22000.0, 0.6, alt+alt_offset, alt+alt_offset + 3000.0);
1276 # store convective altitude and strength
1278 append(weather_dynamics.tile_convective_altitude,alt);
1279 append(weather_dynamics.tile_convective_strength,strength);
1286 ####################################
1288 ####################################
1290 var set_cold_sector_tile = func {
1292 setprop(lw~"tiles/code","cold_sector");
1301 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1302 var phi = alpha * math.pi/180.0;
1303 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1305 # get tile center coordinates
1307 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1308 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1311 # get probabilistic values for the weather parameters
1313 var vis = 40000.0 + rand() * 15000.0;
1314 var T = 8.0 + rand() * 8.0;
1315 var spread = 7.0 + 3.0 * rand();
1317 var p = 1005.0 + rand() * 10.0; p = adjust_p(p);
1319 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1321 # and set them at the tile center
1322 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1324 # altitude for the lowest layer
1325 var alt = spread * 400.0;
1328 # bias Cumulus clouds towards larger sizes due to strong convection
1329 local_weather.convective_size_bias = 0.3 + rand() * 0.1;
1333 if (rand() < small_scale_persistence)
1342 # cloud scenario 1: strong Cumulus development
1343 strength = 0.6 + rand() * 0.1;
1344 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1346 # and specify the atmosphere
1347 local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 18000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1352 # cloud scenario 2: Cirrocumulus sheets over Cumulus
1354 strength = 0.5 + rand() * 0.1;
1355 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1357 for (var i = 0; i < 2; i = i + 1)
1359 x = 2.0 * (rand()-0.5) * 10000;
1360 y = -6000 + i * 12000 + 2.0 * (rand()-0.5) * 1000;
1362 var beta = rand() * 90;
1363 var alt_variation = rand() * 2000;
1365 var path = local_weather.select_cloud_model("Cirrocumulus", "large");
1366 compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset +20000+ alt_variation,alpha+ beta);
1369 # and specify the atmosphere
1370 local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 18000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1374 #local_weather.create_effect_volume(3, blat, blon, 20000.0, 7000.0, alpha, 0.0, 80000.0, -1, -1, -1, -1, 15.0, -3,-1);
1376 # store convective altitude and strength
1378 append(weather_dynamics.tile_convective_altitude,alt);
1379 append(weather_dynamics.tile_convective_strength,strength);
1386 ####################################
1388 ####################################
1390 var set_warm_sector_tile = func {
1392 setprop(lw~"tiles/code","warm_sector");
1401 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1402 var phi = alpha * math.pi/180.0;
1403 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1405 # get tile center coordinates
1407 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1408 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1411 # get probabilistic values for the weather parameters
1413 var vis = 8000.0 + rand() * 5000.0;
1414 var T = 16.0 + rand() * 10.0;
1415 var spread = 6.0 + 3.0 * rand();
1417 var p = 1005.0 + rand() * 10.0; p = adjust_p(p);
1419 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1421 # and set them at the tile center
1422 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1424 # altitude for the lowest layer
1425 var alt = spread * 400.0;
1428 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1429 local_weather.convective_size_bias = 0.1 + rand() * 0.1;
1434 if (rand() < small_scale_persistence)
1441 # cloud scenario 1: weak Cumulus development, some Cirrostratus
1442 strength = 0.3 + rand() * 0.2;
1443 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1444 create_4_8_cirrostratus_patches(blat, blon, alt+alt_offset+25000.0, alpha);
1446 # and specify the atmosphere
1447 local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.3, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1451 # cloud scenario 2: weak Cumulus development under Altostratus streaks
1452 strength = 0.1 + rand() * 0.1;
1453 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1455 var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
1457 create_2_8_sstratus_bundle(blat, blon, alt+alt_offset + size_offset + 2000.0, alpha);
1458 create_2_8_sstratus_hires_bundle(blat, blon, alt+alt_offset + size_offset + 4000.0, alpha);
1460 # and specify the atmosphere
1461 local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1465 # cloud scenario 3: Cirrocumulus bank
1466 strength = 0.05 + rand() * 0.05;
1467 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1469 var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Cirrocumulus"];
1471 create_4_8_cirrocumulus_bank(blat, blon, alt+alt_offset + size_offset + 7000.0, alpha);
1473 # and specify the atmosphere
1474 local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.35, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.75, alt+alt_offset, alt+alt_offset + 2500.0);
1478 # cloud scenario 4: Cirrocumulus undulatus
1479 strength = 0.05 + rand() * 0.05;
1480 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1482 var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Cirrocumulus"];
1484 #create_4_8_cirrocumulus_undulatus(blat, blon, alt+alt_offset + size_offset + 6000.0, alpha);
1485 create_2_8_perlucidus_mackerel(blat, blon, alt+alt_offset + size_offset + 6000.0, alpha);
1487 # and specify the atmosphere
1488 local_weather.set_atmosphere_ipoint(blat, blon, vis + 1000.0, alt+alt_offset, vis + 3000.0, 0.2, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.72, alt+alt_offset, alt+alt_offset + 2500.0);
1493 # cloud scenario 5: weak Cumulus development under scattered Altostratus
1495 strength = 0.15 + rand() * 0.15;
1496 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1498 var size_offset = 0.5 * m_to_ft * local_weather.cloud_vertical_size_map["Stratus_structured"];
1500 local_weather.create_streak("Stratus (structured)",blat, blon, alt+4000.0+alt_offset+size_offset,1000.0,14,0.0,0.3,20000.0,14,0.0,0.3,20000.0,0.0,1.0);
1502 # and specify the atmosphere
1503 local_weather.set_atmosphere_ipoint(blat, blon, vis + 2000.0, alt+alt_offset, vis + 4000.0, 0.15, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.73, alt+alt_offset, alt+alt_offset + 2500.0);
1507 # store convective altitude and strength
1509 append(weather_dynamics.tile_convective_altitude,alt);
1510 append(weather_dynamics.tile_convective_strength,strength);
1518 ####################################
1520 ####################################
1522 var set_tropical_weather_tile = func {
1524 setprop(lw~"tiles/code","tropical_weather");
1533 var sec_to_rad = 2.0 * math.pi/86400; # conversion factor for sinusoidal dependence on daytime
1535 # get the local time of the day in seconds
1537 var t = getprop("sim/time/utc/day-seconds");
1538 t = t + getprop("sim/time/local-offset");
1540 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1541 var phi = alpha * math.pi/180.0;
1542 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1544 # get tile center coordinates
1546 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1547 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1550 # get probabilistic values for the weather parameters
1552 var vis = 9000.0 + rand() * 10000.0;
1553 var T = 20.0 + rand() * 15.0;
1554 var spread = 8.0 + 2.0 * rand();
1556 var p = 970 + rand() * 10.0; p = adjust_p(p);
1558 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1560 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
1562 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1564 # altitude for the lowest layer
1565 var alt = spread * 400.0;
1568 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1569 local_weather.convective_size_bias = 0.3 + rand() * 0.3;
1571 # tropical weather has a strong daily variation, call thunderstorm only in the correct afternoon time window
1573 var t_factor = 0.5 * (1.0-math.cos((t * sec_to_rad)-0.9));
1578 if (rn > (t_factor * t_factor * t_factor * t_factor)) # call a normal convective cloud system
1580 strength = 1.0 + rand() * 0.2;
1581 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1583 # and specify the atmosphere
1584 local_weather.set_atmosphere_ipoint(blat, blon, vis + 15000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0);
1590 # a random selection of different possible thunderstorm cloud configuration scenarios
1594 if (rand() < small_scale_persistence)
1601 # cloud scenario 1: 1-2 medium sized storms
1603 x = 2.0 * (rand()-0.5) * 12000;
1604 y = 2.0 * (rand()-0.5) * 12000;
1607 {create_medium_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1609 {create_small_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1611 if (rand() > 0.5) # we do a second thunderstorm
1613 x = 2.0 * (rand()-0.5) * 12000;
1614 y = 2.0 * (rand()-0.5) * 12000;
1616 {create_medium_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);}
1618 {create_small_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);}
1621 # and specify the atmosphere
1622 local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.65, alt+alt_offset, alt+alt_offset + 2500.0);
1626 # cloud scenario 2: Single big storm
1628 x = 2.0 * (rand()-0.5) * 12000;
1629 y = 2.0 * (rand()-0.5) * 12000;
1631 create_big_thunderstorm(blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset, alpha);
1633 # and specify the atmosphere
1634 local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.65, alt+alt_offset, alt+alt_offset + 2500.0);
1638 # the convective layer
1640 var strength = 0.5 * t_factor;
1641 var n = int(4000 * strength) * 0.2;
1642 local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 0.3,1.4 , size(elat), elat, elon, erad);
1643 local_weather.cumulus_exclusion_layer(blat, blon, alt+alt_offset, n, 20000.0, 20000.0, alpha, 1.9,2.5 , size(elat), elat, elon, erad);
1645 # some turbulence in the convection layer
1647 local_weather.create_effect_volume(3, blat, blon, 20000.0, 20000.0, alpha, 0.0, alt+3000.0+alt_offset, -1, -1, -1, 0.4, -1,0 ,-1);
1649 } # end thundercloud placement
1651 # store convective altitude and strength
1653 append(weather_dynamics.tile_convective_altitude,alt);
1654 append(weather_dynamics.tile_convective_strength,strength);
1663 ####################################
1665 ####################################
1667 var set_thunderstorms_tile = func {
1669 setprop(lw~"tiles/code","thunderstorms");
1679 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1680 var phi = alpha * math.pi/180.0;
1681 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1683 # get tile center coordinates
1685 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1686 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1689 # get probabilistic values for the weather parameters
1691 var vis = 9000.0 + rand() * 10000.0;
1692 var T = 10.0 + rand() * 15.0;
1693 var spread = 6.0 + 2.0 * rand();
1695 var p = 1000 + rand() * 10.0; p = adjust_p(p);
1697 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1699 # first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure)
1701 local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg);
1703 # altitude for the lowest layer
1704 var alt = spread * 400.0;
1707 # bias Cumulus clouds towards larger sizes due to lots of water vapour
1708 local_weather.convective_size_bias = 0.3 + rand() * 0.3;
1711 # and specify the atmosphere
1712 local_weather.set_atmosphere_ipoint(blat, blon, vis + 12000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.85, alt+alt_offset, alt+alt_offset + 2500.0);
1717 if (rand() < small_scale_persistence)
1722 create_thunderstorm_scenario (blat, blon, alt + alt_offset, alpha);
1724 # store convective altitude and strength
1726 append(weather_dynamics.tile_convective_altitude,alt);
1727 append(weather_dynamics.tile_convective_strength,strength);
1737 ####################################
1739 ####################################
1742 var set_coldfront_tile = func {
1744 setprop(lw~"tiles/code","coldfront");
1755 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1756 var phi = alpha * math.pi/180.0;
1757 var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
1759 # get tile center coordinates
1761 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1762 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1765 # get probabilistic values for the weather parameters
1767 var vis = 20000.0 + rand() * 10000.0;
1768 var T = 20.0 + rand() * 8.0;
1769 var spread = 8.0 + 2.0 * rand();
1771 var p = 1005 + rand() * 10.0; p = adjust_p(p);
1773 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1775 # first weather info for tile (lat, lon, visibility, temperature, dew point, pressure)
1779 x = 15000.0; y = 15000.0;
1780 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T-3.0, D-3.0, p * hp_to_inhg);
1782 x = -15000.0; y = 15000.0;
1783 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T-3.0, D-3.0, p * hp_to_inhg);
1787 x = 15000.0; y = -15000.0;
1788 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis*0.7, T+3.0, D+3.0, (p-2.0) * hp_to_inhg);
1790 x = -15000.0; y = -15000.0;
1791 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis*0.7, T+3.0, D+3.0, (p-2.0) * hp_to_inhg);
1793 # altitude for the lowest layer
1794 var alt = spread * 400.0;
1797 # thunderstorms first
1799 for (var i =0; i < 3; i=i+1)
1801 x = 2.0 * (rand()-0.5) * 15000;
1802 y = 2.0 * (rand()-0.5) * 2000 + 5000.0;
1804 {create_medium_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1806 {create_small_thunderstorm(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt+alt_offset, alpha);}
1809 # next the dense cloud layer underneath the thunderstorms
1815 var n = int(4000 * strength) * 0.2;
1816 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 10000.0, alpha, 1.5,2.5 , size(elat), elat, elon, erad);
1818 # then leading and traling Cumulus
1824 n = int(4000 * strength) * 0.15;
1825 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 2000.0, alpha, 0.5,1.8 , size(elat), elat, elon, erad);
1831 n = int(4000 * strength) * 0.15;
1832 local_weather.cumulus_exclusion_layer(blat+get_lat(x,y,phi), blon+ get_lon(x,y,phi), alt+alt_offset, n, 20000.0, 2000.0, alpha, 0.5,1.8 , size(elat), elat, elon, erad);
1834 # finally some thin stratus underneath the Cumulus
1838 local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,0.0,20,2000.0,0.2,1200.0,3,1500.0,0.2,1200.0,alpha,1.0);
1843 local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,0.0,20,2000.0,0.2,1200.0,3,1500.0,0.2,1200.0,alpha,1.0);
1846 # some turbulence in the convection layer
1849 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 11000.0, alpha, 0.0, alt+3000.0+alt_offset, -1, -1, -1, 0.4, -1,0 ,-1);
1851 # some rain and reduced visibility in its core
1854 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 8000.0, alpha, 0.0, alt+alt_offset, 10000.0, 0.1, -1, -1, -1,0,-1 );
1856 # and specify the atmosphere
1857 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 20000.0, 0.0, alt+alt_offset +20000.0, alt+alt_offset + 25000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0);
1859 # store convective altitude and strength
1861 append(weather_dynamics.tile_convective_altitude,alt);
1862 append(weather_dynamics.tile_convective_strength,strength);
1869 ####################################
1871 ####################################
1874 var set_warmfront1_tile = func {
1876 setprop(lw~"tiles/code","warmfront1");
1887 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1888 var phi = alpha * math.pi/180.0;
1890 if (local_weather.presampling_flag == 0)
1891 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1893 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
1895 # get tile center coordinates
1897 var blat = getprop(lw~"tiles/tmp/latitude-deg");
1898 var blon = getprop(lw~"tiles/tmp/longitude-deg");
1901 # get probabilistic values for the weather parameters
1903 var vis = 20000.0 + rand() * 5000.0;
1904 var T = 10.0 + rand() * 8.0;
1905 var spread = 9.0 + 4.0 * rand();
1907 var p = 1005 + rand() * 10.0; p = adjust_p(p);
1909 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
1911 # first weather info for tile (lat, lon, visibility, temperature, dew point, pressure)
1915 x = 15000.0; y = 15000.0;
1916 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
1918 x = -15000.0; y = 15000.0;
1919 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
1923 x = 15000.0; y = -15000.0;
1924 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
1926 x = -15000.0; y = -15000.0;
1927 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
1929 # altitude for the lowest layer
1930 var alt = spread * 400.0;
1932 # some weak Cumulus development
1934 var strength = 0.1 + rand() * 0.1;
1935 local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
1938 # high Cirrus leading
1940 x = 2.0 * (rand()-0.5) * 1000;
1941 y = 2.0 * (rand()-0.5) * 1000 - 9000.0;
1944 local_weather.create_streak("Cirrus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 25000.0+alt+alt_offset,1500.0,3,11000.0,0.0, 3000.0, 2,11000.0,0.0,3000.0,alpha ,1.0);
1947 # followed by random patches of Cirrostratus
1949 for (var i=0; i<6; i=i+1)
1951 var x = 2.0 * (rand()-0.5) * 15000;
1952 var y = 2.0 * (rand()-0.5) * 10000 + 10000;
1953 var beta = (rand() -0.5) * 180.0;
1954 var alt_shift = 0.0;
1955 if (local_weather.hardcoded_clouds_flag == 1) {alt_shift = local_weather.offset_map["Cirrostratus"];}
1957 local_weather.create_streak("Cirrostratus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 18000 + alt + alt_offset - alt_shift,300.0,4,2300.0,0.2,600.0,4,2300.0,0.2,600.0,alpha+beta,1.0);
1961 # and specify the atmosphere
1962 local_weather.set_atmosphere_ipoint(blat, blon, vis + 8000.0, alt+alt_offset, vis + 10000.0, rand() * 0.1, alt+alt_offset +18000.0, alt+alt_offset + 22000.0, 0.8, alt+alt_offset, alt+alt_offset + 2500.0);
1964 # store convective altitude and strength
1966 append(weather_dynamics.tile_convective_altitude,alt);
1967 append(weather_dynamics.tile_convective_strength,strength);
1974 ####################################
1976 ####################################
1979 var set_warmfront2_tile = func {
1981 setprop(lw~"tiles/code","warmfront2");
1992 var alpha = getprop(lw~"tmp/tile-orientation-deg");
1993 var phi = alpha * math.pi/180.0;
1995 if (local_weather.presampling_flag == 0)
1996 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
1998 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
2000 # get tile center coordinates
2002 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2003 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2006 # get probabilistic values for the weather parameters
2008 var vis = 15000.0 + rand() * 5000.0;
2009 var T = 13.0 + rand() * 8.0;
2010 var spread = 8.0 + 2.0 * rand();
2012 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2014 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2016 # first weather info for tile (lat, lon, visibility, temperature, dew point, pressure)
2020 x = 15000.0; y = 15000.0;
2021 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2023 x = -15000.0; y = 15000.0;
2024 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2028 x = 15000.0; y = -15000.0;
2029 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2031 x = -15000.0; y = -15000.0;
2032 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2034 # altitude for the lowest layer
2035 var alt = spread * 400.0;
2038 # followed by random patches of Cirrostratus
2040 var alt_shift = 0.0;
2041 if (local_weather.hardcoded_clouds_flag == 1) {alt_shift = local_weather.offset_map["Cirrostratus"];}
2043 for (var i=0; i<3; i=i+1)
2045 var x = 2.0 * (rand()-0.5) * 18000;
2046 var y = 2.0 * (rand()-0.5) * 5000 - 15000;
2047 var beta = (rand() -0.5) * 180.0;
2048 local_weather.create_streak("Cirrostratus",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 15000 + alt + alt_offset - alt_shift,300.0,4,2300.0,0.2,600.0,4,2300.0,0.2,600.0,alpha+beta,1.0);
2052 # patches of thin Altostratus
2054 for (var i=0; i<14; i=i+1)
2056 var x = 2.0 * (rand()-0.5) * 18000;
2057 var y = 2.0 * (rand()-0.5) * 9000 - 10000.0;
2058 var beta = (rand() -0.5) * 180.0;
2059 local_weather.create_streak("Stratus (thin)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +12000.0,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
2063 # patches of structured Stratus
2065 for (var i=0; i<10; i=i+1)
2067 var x = 2.0 * (rand()-0.5) * 9000;
2068 var y = 2.0 * (rand()-0.5) * 9000 + 2000;
2069 var beta = (rand() -0.5) * 180.0;
2070 local_weather.create_streak("Stratus (structured)",blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset+9000.0,300.0,5,900.0,0.2,500.0,7,900.0,0.2,500.0,alpha+beta,1.0);
2075 # merging with a broken Stratus layer
2080 local_weather.create_streak("Stratus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +5000.0,1000.0,30,0.0,0.2,20000.0,10,0.0,0.2,12000.0,alpha,1.0);
2083 # and specify the atmosphere
2084 local_weather.set_atmosphere_ipoint(blat, blon, vis + 6000.0, alt+alt_offset, vis + 8000.0, 0.15 + rand() * 0.15, alt+alt_offset +17000.0, alt+alt_offset + 21000.0, 0.7, alt+alt_offset, alt+alt_offset + 2500.0);
2086 # store convective altitude and strength
2088 append(weather_dynamics.tile_convective_altitude,alt);
2089 append(weather_dynamics.tile_convective_strength,strength);
2096 ####################################
2098 ####################################
2101 var set_warmfront3_tile = func {
2103 setprop(lw~"tiles/code","warmfront3");
2114 var alpha = getprop(lw~"tmp/tile-orientation-deg");
2115 var phi = alpha * math.pi/180.0;
2117 if (local_weather.presampling_flag == 0)
2118 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
2120 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
2122 # get tile center coordinates
2124 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2125 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2128 # get probabilistic values for the weather parameters
2130 var vis = 12000.0 + rand() * 3000.0;
2131 var T = 15.0 + rand() * 7.0;
2132 var spread = 7.0 + 2.0 * rand();
2134 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2136 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2138 # first weather info for tile (lat, lon, visibility, temperature, dew point, pressure)
2142 x = 15000.0; y = 15000.0;
2143 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2145 x = -15000.0; y = 15000.0;
2146 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2150 x = 15000.0; y = -15000.0;
2151 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2153 x = -15000.0; y = -15000.0;
2154 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2156 # altitude for the lowest layer
2157 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
2160 # closed Stratus layer
2165 local_weather.create_streak("Stratus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset +1000.0,500.0,32,1250.0,0.2,400.0,20,1250.0,0.2,400.0,alpha,1.0);
2171 # merging with a Nimbostratus layer
2176 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,32,1250.0,0.0,200.0,20,1250.0,0.0,200.0,alpha,1.0);
2180 # some rain beneath the stratus
2182 x=0.0; y = -10000.0;
2183 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 10000.0, alpha, 0.0, alt+alt_offset+1000, vis * 0.7, 0.1, -1, -1, -1,0 ,-1);
2185 # heavier rain beneath the Nimbostratus
2188 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 10000.0, alpha, 0.0, alt+alt_offset, vis * 0.5, 0.3, -1, -1, -1,0,-1 );
2191 # and specify the atmosphere
2192 local_weather.set_atmosphere_ipoint(blat, blon, vis + 6000.0, alt+alt_offset, vis + 8000.0, 0.05 + rand() * 0.05, alt+alt_offset +16000.0, alt+alt_offset + 20000.0, 0.6, alt+alt_offset, alt+alt_offset + 2500.0);
2195 # store convective altitude and strength
2197 append(weather_dynamics.tile_convective_altitude,alt);
2198 append(weather_dynamics.tile_convective_strength,strength);
2205 ####################################
2207 ####################################
2210 var set_warmfront4_tile = func {
2212 setprop(lw~"tiles/code","warmfront4");
2223 var alpha = getprop(lw~"tmp/tile-orientation-deg");
2224 var phi = alpha * math.pi/180.0;
2226 if (local_weather.presampling_flag == 0)
2227 {var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
2229 {var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
2231 # get tile center coordinates
2233 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2234 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2237 # get probabilistic values for the weather parameters
2239 var vis = 12000.0 + rand() * 3000.0;
2240 var T = 17.0 + rand() * 6.0;
2241 var spread = 5.0 + 2.0 * rand();
2243 var p = 1005 + rand() * 10.0; p = adjust_p(p);
2245 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2247 # first weather info for tile (lat, lon, visibility, temperature, dew point, pressure)
2251 x = 15000.0; y = 15000.0;
2252 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2254 x = -15000.0; y = 15000.0;
2255 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T+2.0, D+1.0, p * hp_to_inhg);
2259 x = 15000.0; y = -15000.0;
2260 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2262 x = -15000.0; y = -15000.0;
2263 local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg);
2265 # altitude for the lowest layer
2266 var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft;
2269 # low Nimbostratus layer
2274 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,32,1250.0,0.0,200.0,24,1250.0,0.0,200.0,alpha,1.0);
2277 # a little patchy structured Stratus above for effect
2279 create_2_8_sstratus(blat, blon, alt+alt_offset+3000.0, alpha);
2281 # eventually breaking up
2286 local_weather.create_streak("Nimbus",blat +get_lat(x,y,phi), blon+get_lon(x,y,phi), alt+alt_offset,500.0,25,1600.0,0.2,200.0,9,1400.0,0.3,200.0,alpha,1.0);
2290 # rain beneath the Nimbostratus
2293 local_weather.create_effect_volume(3, blat+get_lat(x,y,phi), blon+get_lon(x,y,phi), 20000.0, 15000.0, alpha, 0.0, alt+alt_offset, vis * 0.5, 0.3, -1, -1, -1,0 ,-1);
2296 # and specify the atmosphere
2297 local_weather.set_atmosphere_ipoint(blat, blon, vis + 10000.0, alt+alt_offset, vis + 12000.0, 0.1, alt+alt_offset +16000.0, alt+alt_offset + 20000.0, 0.5, alt+alt_offset, alt+alt_offset + 2500.0);
2299 # store convective altitude and strength
2301 append(weather_dynamics.tile_convective_altitude,alt);
2302 append(weather_dynamics.tile_convective_strength,strength);
2310 ####################################
2312 ####################################
2314 var set_METAR_tile = func {
2317 setprop(lw~"tiles/code","METAR");
2328 var alpha = getprop("/environment/metar/base-wind-dir-deg");
2329 var phi = alpha * math.pi/180.0;
2331 # it seems more recent Flightgear versions have absolute altitude
2332 # var metar_alt_offset = 700.0 + getprop("/environment/metar/station-elevation-ft");
2333 var metar_alt_offset = 700.0;
2335 # print("metar_alt_offset", metar_alt_offset);
2337 # get the local time of the day in seconds
2339 var t = getprop("sim/time/utc/day-seconds");
2340 t = t + getprop("sim/time/local-offset");
2342 # get tile center coordinates
2344 var blat = getprop(lw~"tiles/tmp/latitude-deg");
2345 var blon = getprop(lw~"tiles/tmp/longitude-deg");
2348 var rain_norm = getprop("/environment/metar/rain-norm");
2349 var snow_norm = getprop("/environment/metar/snow-norm");
2350 var p = inhg_to_hp * getprop("/environment/metar/pressure-sea-level-inhg");
2352 # now get the cloud layer info
2354 var layers = props.globals.getNode("/environment/metar/clouds", 1).getChildren("layer");
2355 var n_layers = size(layers); # the system initializes with 4 layers, but who knows...
2356 var n = 0; # start with lowest layer
2358 # now determine the nature of the lowest layer
2360 var cumulus_flag = 1; # default assumption - the lowest layer is cumulus
2361 var thunderstorm_flag = 0;
2362 var cover_low = 8 - 2 * layers[0].getNode("coverage-type").getValue(); # conversion to oktas
2363 var alt_low = layers[0].getNode("elevation-ft").getValue();
2365 # print("alt_low: ", alt_low);
2367 if ((alt_low < 0.0) or (cover_low ==0)) # we have to guess a value for the convective altitude for the visibility model
2370 # first check a few obvious criteria
2372 if (cover_low == 8) {cumulus_flag = 0;} # overcast sky is unlikely to be Cumulus, and we can't render it anyway
2373 if ((rain_norm > 0.0) or (snow_norm > 0.0)) {cumulus_flag = 0;} # Cumulus usually doesn't rain
2374 if (alt_low > 7000.0) {cumulus_flag = 0;} # Cumulus are low altitude clouds
2376 # now try matching time evolution of cumuli
2378 if ((cover_low == 5) or (cover_low == 6) or (cover_low == 7)) # broken
2380 if ((t < 39600) or (t > 68400)) {cumulus_flag = 0;} # not before 11:00 and not after 19:00
2383 if ((cover_low == 3) or (cover_low == 4)) # scattered
2385 if ((t < 32400) or (t > 75600)) {cumulus_flag = 0;} # not before 9:00 and not after 21:00
2388 # now see if there is a layer shading convective development
2390 var coverage_above = 8 - 2 * layers[1].getNode("coverage-type").getValue();
2391 var coverage_above2 = 8 - 2 * layers[2].getNode("coverage-type").getValue();
2393 if (coverage_above2 > coverage_above)
2394 {coverage_above = coverage_above2;}
2396 if (coverage_above > 6) {cumulus_flag = 0;} # no Cumulus with strong layer above
2398 # never do Cumulus when there's a thunderstorm
2399 if (getprop(lw~"METAR/thunderstorm-flag") ==1) {cumulus_flag = 0; thunderstorm_flag = 1;}
2401 # if cumulus_flag is still 1 at this point, the lowest layer is Cumulus
2402 # see if we need to adjust its strength
2404 if ((cumulus_flag == 1) and (cover_low > 0))
2406 if ((cover_low < 4) and (t > 39600) and (t < 68400)) {var strength = 0.4;}
2407 if ((cover_low < 2) and (t > 39600) and (t < 68400)) {var strength = 0.2;}
2408 else {var strength = 1.0;}
2409 local_weather.create_cumosys(blat,blon, alt_low+metar_alt_offset,get_n(strength), 20000.0);
2410 n = n + 1; # do not start parsing with lowest layer
2413 {var strength = 0.0;}
2416 # if thunderstorm_flag is 1, we do the lowest layer as thunderstorm scenario, somewhat ignoring the coverage info
2418 if (thunderstorm_flag == 1)
2420 create_thunderstorm_scenario(blat, blon, alt_low+metar_alt_offset, alpha);
2421 n = n + 1; # do not start parsing with lowest layer
2425 for (var i = n; i <n_layers; i=i+1)
2427 var altitude = layers[i].getNode("elevation-ft").getValue();
2428 # print("altitude: ",altitude);
2429 var cover = 8 - 2 * layers[i].getNode("coverage-type").getValue();
2431 if (cover == -2) {break;} # a clear cover layer indicates we are done
2433 if (n > 0) { rain_norm = 0.0; snow_norm = 0.0;} # rain and snow fall only from the lowest layer
2435 if (altitude < 9000.0) # draw Nimbostratus or Stratus models
2439 if ((altitude < 2000) or (rain_norm > 0.3))
2440 {create_8_8_nimbus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);}
2442 {create_8_8_stratus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);}
2444 else if ((cover < 8) and (cover > 4))
2446 if (cumulus_flag == 1)
2448 create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);
2452 if ((rain_norm > 0.1) and (altitude < 5000.0))
2454 create_6_8_nimbus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);
2456 else if (rain_norm > 0.0)
2458 create_6_8_stratus_rain(blat, blon, altitude+metar_alt_offset, alpha, rain_norm);
2462 if ((p > 1010.0) and (i == 0)) # the lowest layer may be Stratocumulus
2464 create_6_8_stratocumulus(blat, blon, altitude+metar_alt_offset, alpha);
2469 {create_6_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2471 {create_6_8_stratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2476 else if ((cover == 3) or (cover == 4))
2478 if ((p > 1010.0) and (i == 0)) # the lowest layer may be Stratocumulus
2480 create_4_8_stratocumulus(blat, blon, altitude+metar_alt_offset, alpha);
2486 {create_4_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2488 {create_4_8_stratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2490 {create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2492 {create_4_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2494 {create_4_8_sstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2499 if (cumulus_flag == 0)
2503 {create_2_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
2505 {create_2_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2507 {create_2_8_sstratus_hires_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2511 create_2_8_altocumulus_streaks(blat, blon, altitude+metar_alt_offset, alpha);
2515 else if ((altitude > 9000.0) and (altitude < 20000.0)) # select thin cloud layers
2519 if (altitude < 14000.0)
2520 {create_8_8_tstratus(blat, blon, altitude+metar_alt_offset, alpha);}
2522 {create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2526 if (altitude < 14000.0)
2527 {create_6_8_tstratus_mackerel(blat, blon, altitude+metar_alt_offset, alpha);}
2529 {create_6_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2535 {create_4_8_tstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2537 {create_4_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2539 {create_4_8_alttstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2541 {create_4_8_tstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2545 if (altitude < 14000.0)
2549 {create_2_8_tstratus(blat, blon, altitude+metar_alt_offset, alpha);}
2551 {create_2_8_sstratus_bundle(blat, blon, altitude+metar_alt_offset, alpha);}
2553 {create_2_8_altocumulus_perlucidus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2555 {create_2_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2561 {create_2_8_cirrocumulus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2563 {create_1_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2565 {create_2_8_alttstratus_domains(blat, blon, altitude+metar_alt_offset, alpha);}
2573 {create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2575 {create_6_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2580 {create_4_8_cirrostratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
2582 {create_4_8_cirrostratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
2588 {create_2_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
2590 {create_1_8_cirrocumulus(blat, blon, altitude+metar_alt_offset, alpha);}
2600 # store convective altitude and strength
2602 append(weather_dynamics.tile_convective_altitude,alt_low);
2603 append(weather_dynamics.tile_convective_strength,strength);
2610 ####################################
2611 # METAR station setup
2612 ####################################
2614 var set_METAR_weather_station = func {
2617 # get the METAR position info
2619 var station_lat = getprop("/environment/metar/station-latitude-deg");
2620 var station_lon = getprop("/environment/metar/station-longitude-deg");
2621 var metar_alt_offset = 700.0 + getprop("/environment/metar/station-elevation-ft");
2625 # get the weather parameters
2627 var vis = getprop("/environment/metar/max-visibility-m");
2628 var T = getprop("/environment/metar/temperature-sea-level-degc");
2629 var D = getprop("/environment/metar/dewpoint-sea-level-degc");
2630 var p = getprop("/environment/metar/pressure-sea-level-inhg");
2631 var rain_norm = getprop("/environment/metar/rain-norm");
2632 var snow_norm = getprop("/environment/metar/snow-norm");
2634 var windspeed = getprop("/environment/metar/base-wind-speed-kt");
2635 var wind_range_from = getprop("/environment/metar/base-wind-range-from");
2636 var wind_range_to = getprop("/environment/metar/base-wind-range-to");
2638 var gust_strength = getprop("/environment/metar/gust-wind-speed-kt");
2639 var alpha = getprop("/environment/metar/base-wind-dir-deg");
2642 # some METAR report just above max. visibility, if so we guess visibility based on pressure
2644 var is_visibility_max = 0;
2646 if (vis == 9999) {is_visibility_max = 1;}
2648 if ((vis > 16093) and (vis < 16094)) # that's 10 nm
2649 {is_visibility_max = 1;}
2651 if (is_visibility_max == 1)
2653 if (p * inhg_to_hp < 1000.0) {vis = 10000.0 + 5000 * rand();}
2654 else if (p * inhg_to_hp < 1010.0) {vis = 15000.0 + 7000 * rand();}
2655 else if (p * inhg_to_hp < 1020.0) {vis = 22000.0 + 14000.0 * rand();}
2656 else {vis = 30000.0 + 15000.0 * rand();}
2658 if (realistic_visibility_flag == 1) {vis = vis * realistic_visibility_multiplyer;}
2664 local_weather.set_weather_station(station_lat, station_lon, metar_alt_offset, vis, T, D, p);
2667 # get cloud layer info for lighting
2669 var coverage1 = 8 - 2 * getprop("/environment/metar/clouds/layer[0]/coverage-type");
2670 var layer_alt1 = getprop("/environment/metar/clouds/layer[0]/elevation-ft");
2672 var coverage2 = 8 - 2 * getprop("/environment/metar/clouds/layer[1]/coverage-type");
2673 var layer_alt2 = getprop("/environment/metar/clouds/layer[1]/elevation-ft");
2675 var coverage3 = 8 - 2 * getprop("/environment/metar/clouds/layer[2]/coverage-type");
2676 var layer_alt3 = getprop("/environment/metar/clouds/layer[2]/elevation-ft");
2678 var coverage4 = 8 - 2 * getprop("/environment/metar/clouds/layer[3]/coverage-type");
2679 var layer_alt4 = getprop("/environment/metar/clouds/layer[3]/elevation-ft");
2682 # determine the altitude of the main shading layer
2684 # default assumption - the lowest layer shades
2685 var alt_shade = layer_alt1; var coverage_shade = coverage1; var coverage_mult = 1.0;
2687 # if a higher layer is more opaque, it determines the shading unless it is a thin layer
2688 if ((coverage2 >= coverage1) and (layer_alt2 < 14000.0))
2689 {alt_shade = layer_alt2; coverage_shade = coverage2; coverage_mult = 0.9;}
2691 if ((coverage3 >= coverage1) and (coverage3 >= coverage2) and (layer_alt3 < 14000.0))
2692 {alt_shade = layer_alt3; coverage_shade = coverage3; coverage_mult = 0.8;}
2694 # determine the amount of shading
2696 # default assumption: no clouds
2699 if (coverage_shade < 1) # clear sky, we need to specify an altitude for the model
2700 {shade = 0.9; alt_shade = 9000.0;}
2701 else if (coverage_shade < 3)
2703 else if (coverage_shade < 5)
2705 else if (coverage_shade < 8)
2707 else if (coverage_shade == 8)
2710 shade = shade * coverage_mult;
2712 # see if we have any high-altitude clouds
2714 var ovcst = 0.0; var ovcst_alt = 20000.0;
2716 if (layer_alt1 > 20000.0)
2717 {ovcst_alt = layer_alt1; ovcst = ovcst + rand() * 0.1;}
2718 if (layer_alt2 > 20000.0)
2719 {ovcst_alt = layer_alt2; ovcst = ovcst + rand() * 0.1;}
2720 if (layer_alt3 > 20000.0)
2721 {ovcst_alt = layer_alt3; ovcst = ovcst + rand() * 0.1;}
2722 if (layer_alt4 > 20000.0)
2723 {ovcst_alt = layer_alt4; ovcst = ovcst + rand() * 0.1;}
2726 # and specify the atmosphere - currently default only
2727 local_weather.set_atmosphere_ipoint(station_lat, station_lon, vis + 10000.0, metar_alt_offset + alt_shade, vis + 20000.0, ovcst, ovcst_alt+metar_alt_offset - 5000.0, ovcst_alt+metar_alt_offset, shade, layer_alt1+metar_alt_offset, alt_shade+metar_alt_offset + 2500.0);
2729 # if we use aloft interpolated winds with METAR, also set a new wind interpolation point
2731 if ((local_weather.wind_model_flag == 5) and (getprop(lw~"tiles/tile-counter") !=1))
2733 # if zero winds are reported, we do not rotate the tile to face north but use the last value
2735 if ((alpha == 0.0) and (windspeed == 0.0))
2737 alpha = getprop(lw~"tmp/tile-orientation-deg");
2738 var phi = alpha * math.pi/180.0;
2742 var boundary_correction = 1.0/local_weather.get_slowdown_fraction();
2743 local_weather.set_wind_ipoint_metar(station_lat, station_lon, alpha, boundary_correction * windspeed);
2746 # also compute and set gust wind info
2748 var gust_angvar = 0.5 * weather_tile_management.relangle(wind_range_from, wind_range_to);
2750 if ((gust_strength > 0.0) or (gust_angvar > 0.0))
2752 var gust_relative_strength = (gust_strength - windspeed)/windspeed;
2753 setprop(lw~"tmp/gust-frequency-hz", 0.2 + rand()*0.8);
2757 var gust_relative_strength = 0.0;
2758 setprop(lw~"tmp/gust-frequency-hz", 0.0);
2762 setprop(lw~"tmp/gust-relative-strength", gust_relative_strength);
2763 setprop(lw~"tmp/gust-angular-variation-deg", gust_angvar);
2766 # and mark that we have used this station
2767 setprop(lw~"METAR/station-id",getprop("/environment/metar/station-id"));
2773 ####################################
2774 # mid-level cloud setup calls
2775 ####################################
2779 var create_8_8_tstratus = func (lat, lon, alt, alpha) {
2781 if (local_weather.hardcoded_clouds_flag == 1)
2783 alt = alt - local_weather.offset_map["Stratus_thin"];
2785 local_weather.create_streak("Stratus (thin)",lat, lon, alt,500.0,40,1000.0,0.0,400.0,40,1000.0,0.0,400.0,alpha,1.0);
2789 local_weather.create_streak("Stratus (thin)",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0);
2793 var create_8_8_cirrostratus = func (lat, lon, alt, alpha) {
2795 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
2797 local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,30,1300.0,0.0,400.0,30,1300.0,0.0,400.0,alpha,1.0);
2800 var create_8_8_nimbus = func (lat, lon, alt, alpha) {
2803 local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0);
2808 var create_8_8_nimbus_var1 = func (lat, lon, alt, alpha) {
2810 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2812 var phi = alpha * math.pi/180.0;
2814 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2816 for (var i = 0; i < 3; i=i+1)
2818 var x = -15000.0 + 30000.0 * rand();
2819 var y = -15000.0 + 30000.0 * rand();
2820 local_weather.create_streak("Stratocumulus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+600.0,200.0,11,1100.0,0.1,800.0,8,1100.0,0.1,800.0,alpha,1.4);
2825 var create_8_8_nimbus_var2 = func (lat, lon, alt, alpha) {
2827 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2829 var phi = alpha * math.pi/180.0;
2831 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2833 for (var i=0; i<8; i=i+1)
2835 var x = 2.0 * (rand()-0.5) * 18000;
2836 var y = 2.0 * (rand()-0.5) * 18000;
2837 var beta = (rand() -0.5) * 180.0;
2838 local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+1200.0,300.0,5,900.0,0.2,500.0,7,900.0,0.2,500.0,alpha+beta,1.0);
2845 var create_8_8_nimbus_var3 = func (lat, lon, alt, alpha) {
2847 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2849 var phi = alpha * math.pi/180.0;
2852 local_weather.create_streak("Nimbus",lat, lon, alt_eff,500.0,35,1150.0,0.0,200.0,35,1150.0,0.0,200.0,alpha,1.0);
2854 for (var i=0; i<6; i=i+1)
2856 var x = 2.0 * (rand()-0.5) * 18000;
2857 var y = 2.0 * (rand()-0.5) * 18000;
2858 var beta = (rand() -0.5) * 180.0;
2859 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt+1600.0,300.0,6,1200.0,0.2,700.0,6,1200.0,0.2,700.0,alpha+beta,1.0);
2864 var create_8_8_nimbus_rain = func (lat, lon, alt, alpha, rain) {
2866 if (local_weather.hardcoded_clouds_flag == 1) {var alt_eff = alt - local_weather.offset_map["Nimbus"]; }
2868 if (local_weather.detailed_clouds_flag == 0)
2869 {local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0);}
2872 #print(local_weather.offset_map["Nimbus"]);
2874 if (rn > 0.66) {create_8_8_nimbus_var1(lat, lon, alt, alpha);}
2875 else if (rn > 0.33) {create_8_8_nimbus_var2(lat, lon, alt, alpha);}
2876 else {create_8_8_nimbus_var3(lat, lon, alt, alpha);}
2878 # some ragged cloud fringes to avoid hard lines
2879 var phi = alpha * math.pi/180.0;
2880 var x = -15000.0 +rand() *30000.0;
2882 local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,12,1310.0,0.2,500.0,4,1310.0,0.0,1500.0,alpha,1.0);
2884 x=-15000.0 +rand() *30000.0; ; y=-24000.0;
2885 local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,12,1310.0,0.2,500.0,4,1310.0,0.0,1500.0,alpha,1.0);
2887 x=24000.0; y=-15000.0 +rand() *30000.0;
2888 local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,4,1310.0,0.0,1500.0,12,1310.0,0.2,500.0,alpha,1.0);
2890 x=-24000.0; y=-15000.0 +rand() *30000.0;
2891 local_weather.create_streak("Nimbus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_eff,500.0,4,1310.0,0.0,1500.0,12,1310.0,0.2,500.0,alpha,1.0);
2895 local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt+900.0, 500.0 + (1.0 - 0.5 * rain) * 5500.0, 0.5 * rain , -1, -1, -1,0 ,0.95);
2896 local_weather.create_effect_volume(3, lat , lon, 16000.0, 16000.0, alpha, 0.0, alt - 300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0 ,0.9);
2900 local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, alt, alt+900.0, 2000.0, -1 , -1, -1, -1,0 ,-1);
2901 local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, -1, rain , -1, -1, -1,0 ,0.9);
2906 var create_8_8_stratus = func (lat, lon, alt, alpha) {
2908 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
2910 local_weather.create_streak("Stratus",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0);
2914 var create_8_8_stratus_rain = func (lat, lon, alt, alpha, rain) {
2917 create_8_8_stratus(lat, lon, alt, alpha);
2922 local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, 500.0 + (1.0 - 0.5 * rain) * 5500.0, 0.5 * rain , -1, -1, -1,0 ,-1);
2923 local_weather.create_effect_volume(3, lat , lon, 16000.0, 16000.0, alpha, 0.0, alt - 300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0 ,0.9);
2927 local_weather.create_effect_volume(3, lat, lon, 20000.0, 20000.0, alpha, 0.0, alt, -1, rain , -1, -1, -1,0 ,0.9);
2932 var create_6_8_stratus = func (lat, lon, alt, alpha) {
2934 if (local_weather.hardcoded_clouds_flag == 1)
2936 alt = alt - local_weather.offset_map["Stratus"];
2938 for (var i = 0; i < 20; i = i + 1)
2940 var phi = alpha * math.pi/180.0;
2941 var x = 2.0 * (rand()-0.5) * 18000;
2942 var y = 2.0 * (rand()-0.5) * 18000;
2944 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,5,2300.0,0.2,500.0,5,2300.0,0.2,500.0,alpha,1.0);
2949 {local_weather.create_streak("Stratus",lat, lon, alt,500.0,20,0.0,0.2,20000.0,20,0.0,0.2,20000.0,alpha,1.0);}
2955 var create_6_8_nimbus_rain = func (lat, lon, alt, alpha, rain) {
2957 var phi = alpha * math.pi/180.0;
2959 var alt_cloud = alt;
2961 if (local_weather.hardcoded_clouds_flag == 1) {alt_cloud = alt_cloud - 3000.0;}
2963 for (var i = 0; i < 3; i = i + 1)
2965 var x = 2.0 * (rand()-0.5) * 2000.0 + i * 12000.0 - 12000.0;
2966 var y = 2.0 * (rand()-0.5) * 12000.0;
2967 var beta = rand() * 360.0;
2969 local_weather.create_layer("Nimbus", lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_cloud, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 1, 1.0);
2973 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt+900, 500.0 + (1.0-0.5*rain) * 5500.0, 0.5 * rain, -1, -1, -1,0,0.95 );
2974 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt-300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0,0.8);
2978 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, -1, rain, -1, -1, -1,0, 0.8 );
2979 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, alt-1500.0, alt+900.0, 2000.0, -1, -1, -1, -1,0, 0.8 );
2987 var create_6_8_stratus_rain = func (lat, lon, alt, alpha, rain) {
2989 var phi = alpha * math.pi/180.0;
2991 var alt_cloud = alt;
2993 if (local_weather.hardcoded_clouds_flag == 1) {alt_cloud = alt_cloud - local_weather.offset_map["Stratus"];}
2995 for (var i = 0; i < 3; i = i + 1)
2997 var x = 2.0 * (rand()-0.5) * 2000.0 + i * 12000.0 - 12000.0;
2998 var y = 2.0 * (rand()-0.5) * 12000.0;
2999 var beta = rand() * 360.0;
3001 local_weather.create_layer("Stratus", lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt_cloud, 500.0, 12000.0, 7000.0, beta, 1.0, 0.2, 0, 0.0);
3005 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, 500.0 + (1.0-0.5*rain) * 5500.0, 0.5 * rain, -1, -1, -1,0,0.95 );
3006 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 9000.0, 5000.0, beta, 0.0, alt-300.0, 500.0 + (1.0-rain) * 5500.0, rain, -1, -1, -1,0,0.8);
3010 local_weather.create_effect_volume(2, lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), 10000.0, 6000.0, beta, 0.0, alt, -1, rain, -1, -1, -1,0, 0.8 );
3018 var create_6_8_stratus_undulatus = func (lat, lon, alt, alpha) {
3020 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3022 local_weather.create_undulatus("Stratus",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0);
3025 var create_6_8_tstratus_undulatus = func (lat, lon, alt, alpha) {
3027 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3029 local_weather.create_undulatus("Stratus (thin)",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0);
3032 var create_6_8_tstratus_mackerel = func (lat, lon, alt, alpha) {
3034 var phi = alpha * math.pi/180.0;
3036 var x = 2.0 * (rand()-0.5) * 3000;
3037 var y = 2.0 * (rand()-0.5) * 3000;
3041 arg.cloud_spacing = 900.0;
3042 arg.undulatus_spacing = 4200.0;
3043 arg.undulatus_slant = 0.4;
3044 arg.undulatus_amplitude = 2000.0;
3048 arg.xsize = 35000.0 + rand() * 10000.0;
3049 arg.ysize = 35000.0 + rand() * 10000.0;
3050 arg.blat = lat + get_lat(x,y,phi);
3051 arg.blon = lon + get_lon(x,y,phi);
3055 arg.size_bias = 0.5;
3056 arg.type = "Stratus (thin)";
3058 local_weather.create_adv_undulatus(arg);
3063 var create_6_8_cirrostratus = func (lat, lon, alt, alpha) {
3065 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3067 local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,24,1500.0,0.0,900.0,24,1500.0,0.0,900.0,alpha,1.0);
3071 var create_6_8_stratocumulus = func (lat, lon, alt, alpha) {
3073 if (local_weather.detailed_clouds_flag == 1)
3075 for (var i=0; i< 2; i=i+1)
3077 var phi = alpha * math.pi/180.0;
3078 var x = 2.0 * (rand()-0.5) * 4000;
3079 var y = 2.0 * (rand()-0.5) * 4000;
3080 var beta = rand() * 360.0;
3081 create_detailed_stratocumulus_bank(lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt, alpha+beta);
3086 create_stratocumulus_bank(lat, lon, alt, alpha);
3087 create_stratocumulus_bank(lat, lon, alt, alpha);
3093 var create_4_8_stratus = func (lat, lon, alt, alpha) {
3095 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3097 var phi = alpha * math.pi/180.0;
3098 var x = 2.0 * (rand()-0.5) * 15000;
3099 var y = 2.0 * (rand()-0.5) * 15000;
3100 var beta = rand() * 360.0;
3102 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,20,1200.0,0.3,400.0,12,1200.0,0.3,400.0,beta,1.2);
3105 var x = 2.0 * (rand()-0.5) * 15000;
3106 var y = 2.0 * (rand()-0.5) * 15000;
3107 var beta = rand() * 360.0;
3109 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,18,1000.0,0.3,400.0,10,1000.0,0.3,400.0,beta,1.5);
3112 var x = 2.0 * (rand()-0.5) * 15000;
3113 var y = 2.0 * (rand()-0.5) * 15000;
3114 var beta = rand() * 360.0;
3116 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,15,1000.0,0.3,400.0,18,1000.0,0.3,400.0,beta,2.0);
3120 var create_4_8_stratus_patches = func (lat, lon, alt, alpha) {
3122 var phi = alpha * math.pi/180.0;
3124 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3126 for (var i=0; i<16; i=i+1)
3128 var x = 2.0 * (rand()-0.5) * 18000;
3129 var y = 2.0 * (rand()-0.5) * 18000;
3130 var beta = (rand() -0.5) * 180.0;
3131 local_weather.create_streak("Stratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
3137 var create_4_8_tstratus_patches = func (lat, lon, alt, alpha) {
3139 var phi = alpha * math.pi/180.0;
3141 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3143 for (var i=0; i<22; i=i+1)
3145 var x = 2.0 * (rand()-0.5) * 18000;
3146 var y = 2.0 * (rand()-0.5) * 18000;
3147 var beta = (rand() -0.5) * 180.0;
3149 var m = int(3 + rand() * 3);
3150 var n = int(3 + rand() * 5);
3152 local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
3158 var create_4_8_tstratus_domains = func (lat, lon, alt, alpha) {
3162 arg.xsize = 36000.0;
3163 arg.ysize = 36000.0;
3164 arg.min_domain_size_x = 5000.0;
3165 arg.max_domain_size_x = 24000.0;
3166 arg.min_domain_size_y = 5000.0;
3167 arg.max_domain_size_y = 24000.0;
3168 arg.node_fraction = 0.0;
3169 arg.halo_fraction = 0.4;
3177 arg.type = "Stratus (thin)";
3178 arg.subtype = "large";
3179 arg.ntype = "Altocumulus perlucidus";
3180 arg.nsubtype = "large";
3181 arg.htype = "Stratus (thin)";
3182 arg.hsubtype = "small";
3184 local_weather.create_domains(arg);
3188 var create_4_8_sstratus_patches = func (lat, lon, alt, alpha) {
3190 var phi = alpha * math.pi/180.0;
3192 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_structured"];}
3194 for (var i=0; i<22; i=i+1)
3196 var x = 2.0 * (rand()-0.5) * 18000;
3197 var y = 2.0 * (rand()-0.5) * 18000;
3198 var beta = (rand() -0.5) * 180.0;
3199 var m = int(3 + rand() * 5);
3200 var n = int(3 + rand() * 5);
3201 local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
3208 var create_4_8_cirrostratus_patches = func (lat, lon, alt, alpha) {
3210 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3212 var phi = alpha * math.pi/180.0;
3214 for (var i=0; i<6; i=i+1)
3216 var x = 2.0 * (rand()-0.5) * 12000;
3217 var y = 2.0 * (rand()-0.5) * 12000;
3218 var beta = (rand() -0.5) * 180.0;
3219 local_weather.create_streak("Cirrostratus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,2500.0,0.2,600.0,4,2500.0,0.2,600.0,alpha+beta,1.0);
3225 var create_4_8_cirrostratus_undulatus = func (lat, lon, alt, alpha) {
3227 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Cirrostratus"];}
3229 local_weather.create_undulatus("Cirrostratus",lat, lon, alt,300.0,5,8000.0,0.1,400.0,40,1000.0,0.1,100.0, 1500.0, alpha,1.0);
3233 var create_4_8_stratus_undulatus = func (lat, lon, alt, alpha) {
3235 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus"];}
3237 var phi = alpha * math.pi/180.0;
3238 var x = 2.0 * (rand()-0.5) * 5000;
3239 var y = 2.0 * (rand()-0.5) * 5000;
3240 var tri = 1.5 + 1.5*rand();
3241 var beta = (rand() -0.5) * 60.0;
3243 local_weather.create_streak("Stratus",lat+get_lat(x,y+4000,phi), lon+get_lon(x,y+4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3245 local_weather.create_streak("Stratus",lat+get_lat(x,y-4000,phi), lon+get_lon(x,y-4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+270.0+beta,tri);
3249 var create_4_8_tstratus_undulatus = func (lat, lon, alt, alpha) {
3251 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_thin"];}
3253 var phi = alpha * math.pi/180.0;
3254 var x = 2.0 * (rand()-0.5) * 5000;
3255 var y = 2.0 * (rand()-0.5) * 5000;
3256 var tri = 1.5 + 1.5*rand();
3257 var beta = (rand() -0.5) * 60.0;
3259 local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y+4000,phi), lon+get_lon(x,y+4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3261 local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y-4000,phi), lon+get_lon(x,y-4000,phi), alt,500.0,10,800.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+270.0+beta,tri);
3265 var create_4_8_sstratus_undulatus = func (lat, lon, alt, alpha) {
3267 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - local_weather.offset_map["Stratus_structured"];}
3269 var phi = alpha * math.pi/180.0;
3270 var x = 2.0 * (rand()-0.5) * 5000;
3271 var y = 2.0 * (rand()-0.5) * 5000;
3272 var tri = 1 + 1.5*rand();
3273 var beta = (rand() -0.5) * 60.0;
3275 local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,500.0,20,900.0,0.25,400.0,12,2800.0,0.15,600.0,alpha+90.0+beta,tri);
3280 var create_4_8_cirrocumulus_bank = func (lat, lon, alt, alpha) {
3282 if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;}