source: osm/applications/editors/josm/plugins/seachart/src/render/Signals.java@ 32090

Last change on this file since 32090 was 32090, checked in by malcolmh, 10 years ago

add RADRFLs

File size: 22.0 KB
Line 
1/* Copyright 2014 Malcolm Herring
2 *
3 * This is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License.
6 *
7 * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
8 */
9
10package render;
11
12import java.awt.Color;
13import java.awt.Font;
14import java.awt.geom.*;
15import java.text.DecimalFormat;
16import java.util.ArrayList;
17import java.util.EnumMap;
18
19import s57.S57val.CatLIT;
20import s57.S57val.ColCOL;
21import s57.S57att.*;
22import s57.S57obj.*;
23import s57.S57val.*;
24import s57.S57map.*;
25import symbols.Beacons;
26import symbols.Symbols;
27import symbols.Topmarks;
28import symbols.Symbols.*;
29
30public class Signals {
31
32 static final EnumMap<ColCOL, Color> LightColours = new EnumMap<ColCOL, Color>(ColCOL.class);
33 static {
34 LightColours.put(ColCOL.COL_WHT, new Color(0xffff00));
35 LightColours.put(ColCOL.COL_RED, new Color(0xff0000));
36 LightColours.put(ColCOL.COL_GRN, new Color(0x00ff00));
37 LightColours.put(ColCOL.COL_BLU, new Color(0x0000ff));
38 LightColours.put(ColCOL.COL_YEL, new Color(0xffff00));
39 LightColours.put(ColCOL.COL_AMB, new Color(0xffc200));
40 LightColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
41 LightColours.put(ColCOL.COL_ORG, Color.orange);
42 LightColours.put(ColCOL.COL_MAG, Color.magenta);
43 }
44
45 static final EnumMap<ColCOL, String> LightLetters = new EnumMap<ColCOL, String>(ColCOL.class);
46 static {
47 LightLetters.put(ColCOL.COL_WHT, "W");
48 LightLetters.put(ColCOL.COL_RED, "R");
49 LightLetters.put(ColCOL.COL_GRN, "G");
50 LightLetters.put(ColCOL.COL_BLU, "Bu");
51 LightLetters.put(ColCOL.COL_YEL, "Y");
52 LightLetters.put(ColCOL.COL_AMB, "Am");
53 LightLetters.put(ColCOL.COL_VIO, "Vi");
54 LightLetters.put(ColCOL.COL_ORG, "Or");
55 }
56
57 static final EnumMap<LitCHR, String> LightCharacters = new EnumMap<LitCHR, String>(LitCHR.class);
58 static {
59 LightCharacters.put(LitCHR.CHR_F, "F");
60 LightCharacters.put(LitCHR.CHR_FL, "Fl");
61 LightCharacters.put(LitCHR.CHR_LFL, "LFl");
62 LightCharacters.put(LitCHR.CHR_Q, "Q");
63 LightCharacters.put(LitCHR.CHR_VQ, "VQ");
64 LightCharacters.put(LitCHR.CHR_UQ, "UQ");
65 LightCharacters.put(LitCHR.CHR_ISO, "Iso");
66 LightCharacters.put(LitCHR.CHR_OC, "Oc");
67 LightCharacters.put(LitCHR.CHR_IQ, "IQ");
68 LightCharacters.put(LitCHR.CHR_IVQ, "IVQ");
69 LightCharacters.put(LitCHR.CHR_IUQ, "IUQ");
70 LightCharacters.put(LitCHR.CHR_MO, "Mo");
71 LightCharacters.put(LitCHR.CHR_FFL, "FFl");
72 LightCharacters.put(LitCHR.CHR_FLLFL, "FlLFl");
73 LightCharacters.put(LitCHR.CHR_OCFL, "OcFl");
74 LightCharacters.put(LitCHR.CHR_FLFL, "FLFl");
75 LightCharacters.put(LitCHR.CHR_ALOC, "Al.Oc");
76 LightCharacters.put(LitCHR.CHR_ALLFL, "Al.LFl");
77 LightCharacters.put(LitCHR.CHR_ALFL, "Al.Fl");
78 LightCharacters.put(LitCHR.CHR_ALGR, "Al.Gr");
79 LightCharacters.put(LitCHR.CHR_QLFL, "Q+LFl");
80 LightCharacters.put(LitCHR.CHR_VQLFL, "VQ+LFl");
81 LightCharacters.put(LitCHR.CHR_UQLFL, "UQ+LFl");
82 LightCharacters.put(LitCHR.CHR_AL, "Al");
83 LightCharacters.put(LitCHR.CHR_ALFFL, "Al.FFl");
84 }
85
86 static final EnumMap<CatFOG, String> fogSignals = new EnumMap<CatFOG, String>(CatFOG.class);
87 static {
88 fogSignals.put(CatFOG.FOG_EXPL, "Explos");
89 fogSignals.put(CatFOG.FOG_DIA, "Dia");
90 fogSignals.put(CatFOG.FOG_SIRN, "Siren");
91 fogSignals.put(CatFOG.FOG_NAUT, "Horn");
92 fogSignals.put(CatFOG.FOG_REED, "Horn");
93 fogSignals.put(CatFOG.FOG_TYPH, "Horn");
94 fogSignals.put(CatFOG.FOG_BELL, "Bell");
95 fogSignals.put(CatFOG.FOG_WHIS, "Whis");
96 fogSignals.put(CatFOG.FOG_GONG, "Gong");
97 fogSignals.put(CatFOG.FOG_HORN, "Horn");
98 }
99
100 static final DecimalFormat df = new DecimalFormat("#.#");
101
102 public static void addSignals() {
103 if (Rules.feature.objs.containsKey(Obj.RADRFL)) reflectors();
104 if (Rules.feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
105 if (Rules.feature.objs.containsKey(Obj.RTPBCN)) radarStations();
106 if (Rules.feature.objs.containsKey(Obj.RADSTA)) radarStations();
107 if (Rules.feature.objs.containsKey(Obj.RDOSTA)) radioStations();
108 if (Rules.feature.objs.containsKey(Obj.LIGHTS)) lights();
109 }
110
111 public static void reflectors() {
112 if (Renderer.zoom >= 14) {
113 switch (Rules.feature.type) {
114 case BCNLAT:
115 case BCNCAR:
116 case BCNISD:
117 case BCNSAW:
118 case BCNSPP:
119 case LITFLT:
120 case LITVES:
121 case BOYINB:
122 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
123 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -140)));
124 } else {
125 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -80)));
126 }
127 break;
128 case LITMAJ:
129 case LITMIN:
130 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
131 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
132 } else {
133 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -30)));
134 }
135 break;
136 case BOYLAT:
137 case BOYCAR:
138 case BOYISD:
139 case BOYSAW:
140 case BOYSPP:
141 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
142 if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR)) {
143 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(45, -140)));
144 } else {
145 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(25, -80)));
146 }
147 } else {
148 if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR)) {
149 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(30, -100)));
150 } else {
151 Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(10, -50)));
152 }
153 }
154 break;
155 default:
156 break;
157 }
158 }
159 }
160
161 public static void fogSignals() {
162 if (Renderer.zoom >= 11)
163 Renderer.symbol(Beacons.FogSignal);
164 if (Renderer.zoom >= 15) {
165 AttMap atts = Rules.feature.objs.get(Obj.FOGSIG).get(0);
166 String str = "";
167 if (atts.containsKey(Att.CATFOG)) {
168 str += fogSignals.get(((ArrayList<?>) (atts.get(Att.CATFOG).val)).get(0));
169 }
170 if (atts.containsKey(Att.SIGGRP)) {
171 str += "(" + atts.get(Att.SIGGRP).val + ")";
172 } else {
173 str += " ";
174 }
175 if (atts.containsKey(Att.SIGPER)) {
176 str += df.format(atts.get(Att.SIGPER).val) + "s";
177 }
178 if (atts.containsKey(Att.VALMXR)) {
179 str += df.format(atts.get(Att.VALMXR).val) + "M";
180 }
181 if (!str.isEmpty()) {
182 Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-60, -30)));
183 }
184 }
185 }
186
187 public static void radarStations() {
188 if (Renderer.zoom >= 11)
189 Renderer.symbol(Beacons.RadarStation);
190 if (Renderer.zoom >= 15) {
191 String bstr = "";
192 CatRTB cat = (CatRTB) Rules.getAttEnum(Obj.RTPBCN, Att.CATRTB);
193 String wal = Rules.getAttStr(Obj.RTPBCN, Att.RADWAL);
194 switch (cat) {
195 case RTB_RAMK:
196 bstr += " Ramark";
197 break;
198 case RTB_RACN:
199 bstr += " Racon";
200 String astr = Rules.getAttStr(Obj.RTPBCN, Att.SIGGRP);
201 if (!astr.isEmpty()) {
202 bstr += "(" + astr + ")";
203 }
204 Double per = (Double) Rules.getAttVal(Obj.RTPBCN, Att.SIGPER);
205 Double mxr = (Double) Rules.getAttVal(Obj.RTPBCN, Att.VALMXR);
206 if ((per != null) || (mxr != null)) {
207 bstr += (astr.isEmpty() ? " " : "");
208 if (per != null)
209 bstr += (per != 0) ? per.toString() + "s" : "";
210 if (mxr != null)
211 bstr += (mxr != 0) ? mxr.toString() + "M" : "";
212 }
213 break;
214 default:
215 break;
216 }
217 if (!wal.isEmpty()) {
218 switch (wal) {
219 case "0.03-X":
220 bstr += "(3cm)";
221 break;
222 case "0.10-S":
223 bstr += "(10cm)";
224 break;
225 }
226 }
227 if (!bstr.isEmpty()) {
228 Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
229 }
230 }
231 }
232
233 @SuppressWarnings("unchecked")
234 public static void radioStations() {
235 boolean vais = false;
236 String bstr = "";
237 if (Renderer.zoom >= 11) {
238 ArrayList<CatROS> cats = (ArrayList<CatROS>) Rules.getAttList(Obj.RDOSTA, Att.CATROS);
239 for (CatROS ros : cats) {
240 switch (ros) {
241 case ROS_OMNI:
242 bstr += " RC";
243 break;
244 case ROS_DIRL:
245 bstr += " RD";
246 break;
247 case ROS_ROTP:
248 bstr += " RW";
249 break;
250 case ROS_CNSL:
251 bstr += " Consol";
252 break;
253 case ROS_RDF:
254 bstr += " RG";
255 break;
256 case ROS_QTA:
257 bstr += " R";
258 break;
259 case ROS_AERO:
260 bstr += " AeroRC";
261 break;
262 case ROS_DECA:
263 bstr += " Decca";
264 break;
265 case ROS_LORN:
266 bstr += " Loran";
267 break;
268 case ROS_DGPS:
269 bstr += " DGPS";
270 break;
271 case ROS_TORN:
272 bstr += " Toran";
273 break;
274 case ROS_OMGA:
275 bstr += " Omega";
276 break;
277 case ROS_SYLD:
278 bstr += " Syledis";
279 break;
280 case ROS_CHKA:
281 bstr += " Chiaka";
282 break;
283 case ROS_PCOM:
284 case ROS_COMB:
285 case ROS_FACS:
286 case ROS_TIME:
287 break;
288 case ROS_PAIS:
289 case ROS_SAIS:
290 bstr += " AIS";
291 break;
292 case ROS_VAIS:
293 vais = true;
294 break;
295 case ROS_VANC:
296 vais = true;
297 Renderer.symbol(Topmarks.TopNorth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
298 break;
299 case ROS_VASC:
300 vais = true;
301 Renderer.symbol(Topmarks.TopSouth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
302 break;
303 case ROS_VAEC:
304 vais = true;
305 Renderer.symbol(Topmarks.TopEast, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
306 break;
307 case ROS_VAWC:
308 vais = true;
309 Renderer.symbol(Topmarks.TopWest, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
310 break;
311 case ROS_VAPL:
312 vais = true;
313 Renderer.symbol(Topmarks.TopCan, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
314 break;
315 case ROS_VASL:
316 vais = true;
317 Renderer.symbol(Topmarks.TopCone, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
318 break;
319 case ROS_VAID:
320 vais = true;
321 Renderer.symbol(Topmarks.TopIsol, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
322 break;
323 case ROS_VASW:
324 vais = true;
325 Renderer.symbol(Topmarks.TopSphere, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
326 break;
327 case ROS_VASP:
328 vais = true;
329 Renderer.symbol(Topmarks.TopX, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
330 break;
331 case ROS_VAWK:
332 vais = true;
333 Renderer.symbol(Topmarks.TopCross, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
334 break;
335 default:
336 break;
337 }
338 }
339 if (!vais) {
340 Renderer.symbol(Beacons.RadarStation);
341 }
342 }
343 if (Renderer.zoom >= 15) {
344 if (vais) {
345 Renderer.labelText("V-AIS", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 70)));
346 }
347 if (!bstr.isEmpty()) {
348 Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -110)));
349 }
350 }
351 }
352
353 class Sect {
354 int dir;
355 LitCHR chr;
356 ColCOL col;
357 ColCOL alt;
358 String grp;
359 double per;
360 double rng;
361 }
362
363 @SuppressWarnings("unchecked")
364 public static void lights() {
365 Enum<ColCOL> col = null;
366 Enum<ColCOL> tcol = null;
367 ObjTab lights = Rules.feature.objs.get(Obj.LIGHTS);
368 for (AttMap atts : lights.values()) {
369 if (atts.containsKey(Att.COLOUR)) {
370 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
371 if (cols.size() == 1) {
372 tcol = cols.get(0);
373 if (col == null) {
374 col = tcol;
375 } else if (tcol != col) {
376 col = ColCOL.COL_MAG;
377 break;
378 }
379 } else {
380 col = ColCOL.COL_MAG;
381 break;
382 }
383 }
384 }
385 Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
386 String str = "";
387 if (lights.get(1) != null) {
388 for (AttMap atts : lights.values()) {
389 Enum<ColCOL> col1 = null;
390 Enum<ColCOL> col2 = null;
391 double radius = 0.2;
392 double s1 = 361;
393 double s2 = 361;
394 Double dir = null;
395 if (atts.containsKey(Att.COLOUR)) {
396 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
397 col1 = cols.get(0);
398 if (cols.size() > 1)
399 col2 = cols.get(1);
400 } else {
401 continue;
402 }
403 if (atts.containsKey(Att.LITRAD)) {
404 radius = (Double) atts.get(Att.LITRAD).val;
405 }
406 if (atts.containsKey(Att.CATLIT)) {
407 ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
408 if (cats.contains(CatLIT.LIT_DIR)) {
409 if (atts.containsKey(Att.ORIENT)) {
410 dir = (Double) atts.get(Att.ORIENT).val;
411 s1 = ((dir - 4) + 360) % 360;
412 s2 = (dir + 4) % 360;
413 for (AttMap satts : lights.values()) {
414 double srad = 0.2;
415 double ss1 = 361;
416 double ss2 = 361;
417 Double sdir = null;
418 if (satts == atts) continue;
419 if (satts.containsKey(Att.LITRAD)) {
420 srad = (Double) satts.get(Att.LITRAD).val;
421 }
422 if (srad == radius) {
423 ArrayList<CatLIT> scats = (satts.containsKey(Att.CATLIT)) ? (ArrayList<CatLIT>) satts.get(Att.CATLIT).val : new ArrayList<CatLIT>();
424 if (scats.contains(CatLIT.LIT_DIR)) {
425 if (satts.containsKey(Att.ORIENT)) {
426 sdir = (Double) satts.get(Att.ORIENT).val;
427 ss1 = sdir;
428 ss2 = sdir;
429 }
430 } else {
431 if (satts.containsKey(Att.SECTR1)) {
432 ss1 = (Double) satts.get(Att.SECTR1).val;
433 }
434 if (satts.containsKey(Att.SECTR2)) {
435 ss2 = (Double) satts.get(Att.SECTR2).val;
436 }
437 }
438 if ((ss1 > 360) || (ss2 > 360)) continue;
439 if (sdir != null) {
440 if (((dir - sdir + 360) % 360) < 8) {
441 s1 = ((((sdir > dir) ? 360 : 0) + sdir + dir) / 2) % 360;
442 }
443 if (((sdir - dir + 360) % 360) < 8) {
444 s2 = ((((dir > sdir) ? 360 : 0) + sdir + dir) / 2) % 360;
445 }
446 } else {
447 if (((dir - ss2 + 360) % 360) < 4) {
448 s1 = ss2;
449 }
450 if (((ss1 - dir + 360) % 360) < 4) {
451 s2 = ss1;
452 }
453 }
454 }
455 }
456 }
457 }
458 }
459 if ((s1 > 360) && atts.containsKey(Att.SECTR1)) {
460 s1 = (Double) atts.get(Att.SECTR1).val;
461 } else if (dir == null) {
462 continue;
463 }
464 if ((s2 > 360) && atts.containsKey(Att.SECTR2)) {
465 s2 = (Double) atts.get(Att.SECTR2).val;
466 } else if (dir == null) {
467 continue;
468 }
469 str = "";
470 if (atts.containsKey(Att.LITCHR)) {
471 str += LightCharacters.get(((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0));
472 }
473 if (atts.containsKey(Att.SIGGRP)) {
474 str += "(" + atts.get(Att.SIGGRP).val + ")";
475 } else if (!str.isEmpty()) {
476 str += ".";
477 }
478 if (atts.containsKey(Att.COLOUR)) {
479 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
480 str += LightLetters.get(cols.get(0));
481 if (cols.size() > 1)
482 str += LightLetters.get(cols.get(1));
483 }
484 if (atts.containsKey(Att.SIGPER)) {
485 str += "." + df.format(atts.get(Att.SIGPER).val) + "s";
486 }
487 if ((s1 <= 360) && (s2 <= 360) && (s1 != s2))
488 Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
489 }
490 if (Renderer.zoom >= 15) {
491 class LitSect {
492 boolean dir;
493 LitCHR chr;
494 ColCOL col;
495 String grp;
496 double per;
497 double rng;
498 double hgt;
499 }
500 ArrayList<LitSect> litatts = new ArrayList<>();
501 for (AttMap atts : lights.values()) {
502 LitSect sect = new LitSect();
503 sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>)atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
504 sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
505 switch (sect.chr) {
506 case CHR_AL:
507 sect.chr = LitCHR.CHR_F;
508 break;
509 case CHR_ALOC:
510 sect.chr = LitCHR.CHR_OC;
511 break;
512 case CHR_ALLFL:
513 sect.chr = LitCHR.CHR_LFL;
514 break;
515 case CHR_ALFL:
516 sect.chr = LitCHR.CHR_FL;
517 break;
518 case CHR_ALFFL:
519 sect.chr = LitCHR.CHR_FFL;
520 break;
521 default:
522 break;
523 }
524 sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
525 sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
526 sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
527 sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
528 ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
529 sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
530 if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
531 litatts.add(sect);
532 }
533 ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
534 for (LitSect lit : litatts) {
535 boolean found = false;
536 for (ArrayList<LitSect> group : groupings) {
537 LitSect mem = group.get(0);
538 if ((lit.dir == mem.dir) && (lit.chr == mem.chr) && (lit.grp.equals(mem.grp)) && (lit.per == mem.per) && (lit.hgt == mem.hgt)) {
539 group.add(lit);
540 found = true;
541 }
542 }
543 if (!found) {
544 ArrayList<LitSect> tmp = new ArrayList<LitSect>();
545 tmp.add(lit);
546 groupings.add(tmp);
547 }
548 }
549 for (boolean moved = true; moved;) {
550 moved = false;
551 for (int i = 0; i < groupings.size() - 1; i++) {
552 if (groupings.get(i).size() < groupings.get(i + 1).size()) {
553 ArrayList<LitSect> tmp = groupings.remove(i);
554 groupings.add(i + 1, tmp);
555 moved = true;
556 }
557 }
558 }
559 class ColRng {
560 ColCOL col;
561 double rng;
562
563 public ColRng(ColCOL c, double r) {
564 col = c;
565 rng = r;
566 }
567 }
568 int y = -30;
569 for (ArrayList<LitSect> group : groupings) {
570 ArrayList<ColRng> colrng = new ArrayList<>();
571 for (LitSect lit : group) {
572 boolean found = false;
573 for (ColRng cr : colrng) {
574 if (cr.col == lit.col) {
575 if (lit.rng > cr.rng) {
576 cr.rng = lit.rng;
577 }
578 found = true;
579 }
580 }
581 if (!found) {
582 colrng.add(new ColRng(lit.col, lit.rng));
583 }
584 }
585 for (boolean moved = true; moved;) {
586 moved = false;
587 for (int i = 0; i < colrng.size() - 1; i++) {
588 if (colrng.get(i).rng < colrng.get(i + 1).rng) {
589 ColRng tmp = colrng.remove(i);
590 colrng.add(i + 1, tmp);
591 moved = true;
592 }
593 }
594 }
595 LitSect tmp = group.get(0);
596 str = (tmp.dir) ? "Dir" : "";
597 str += LightCharacters.get(tmp.chr);
598 if (!tmp.grp.isEmpty())
599 str += "(" + tmp.grp + ")";
600 else
601 str += ".";
602 for (ColRng cr : colrng) {
603 str += LightLetters.get(cr.col);
604 }
605 if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
606 str += ".";
607 if (tmp.per > 0)
608 str += df.format(tmp.per) + "s";
609 if (tmp.hgt > 0)
610 str += df.format(tmp.hgt) + "m";
611 if (colrng.get(0).rng > 0)
612 str += df.format(colrng.get(0).rng) + ((colrng.size() > 1) ? ((colrng.size() > 2) ? ("-" + df.format(colrng.get(colrng.size() - 1).rng)) : ("/" + df.format(colrng.get(1).rng))) : "") + "M";
613 Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
614 y += 40;
615 str = "";
616 }
617 }
618 } else {
619 if (Renderer.zoom >= 15) {
620 AttMap atts = lights.get(0);
621 ArrayList<CatLIT> cats = new ArrayList<>();
622 if (atts.containsKey(Att.CATLIT)) {
623 cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
624 }
625 str = (cats.contains(CatLIT.LIT_DIR)) ? "Dir" : "";
626 str += (atts.containsKey(Att.MLTYLT)) ? atts.get(Att.MLTYLT).val : "";
627 if (atts.containsKey(Att.LITCHR)) {
628 LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
629 if (atts.containsKey(Att.SIGGRP)) {
630 String grp = (String) atts.get(Att.SIGGRP).val;
631 switch (chr) {
632 case CHR_QLFL:
633 str += String.format("Q(%s)+LFl", grp);
634 break;
635 case CHR_VQLFL:
636 str += String.format("VQ(%s)+LFl", grp);
637 break;
638 case CHR_UQLFL:
639 str += String.format("UQ(%s)+LFl", grp);
640 break;
641 default:
642 str += String.format("%s(%s)", LightCharacters.get(chr), grp);
643 break;
644 }
645 } else {
646 str += LightCharacters.get(chr);
647 }
648 }
649 if (atts.containsKey(Att.COLOUR)) {
650 ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
651 if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
652 if (!str.isEmpty() && !str.endsWith(")")) {
653 str += ".";
654 }
655 for (ColCOL acol : cols) {
656 str += LightLetters.get(acol);
657 }
658 }
659 }
660 str += (cats.contains(CatLIT.LIT_VERT)) ? "(vert)" : "";
661 str += (cats.contains(CatLIT.LIT_HORI)) ? "(hor)" : "";
662 str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
663 str += (atts.containsKey(Att.SIGPER)) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
664 str += (atts.containsKey(Att.HEIGHT)) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
665 str += (atts.containsKey(Att.VALNMR)) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
666 str += (cats.contains(CatLIT.LIT_FRNT)) ? "(Front)" : "";
667 str += (cats.contains(CatLIT.LIT_REAR)) ? "(Rear)" : "";
668 str += (cats.contains(CatLIT.LIT_UPPR)) ? "(Upper)" : "";
669 str += (cats.contains(CatLIT.LIT_LOWR)) ? "(Lower)" : "";
670 Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
671 }
672 }
673 }
674}
Note: See TracBrowser for help on using the repository browser.