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