Ignore:
Timestamp:
2016-06-24T03:48:12+02:00 (10 years ago)
Author:
donvip
Message:

checkstyle

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/seachart/src/render/Signals.java

    r32393 r32394  
    1212import java.awt.Color;
    1313import java.awt.Font;
    14 import java.awt.geom.*;
     14import java.awt.geom.AffineTransform;
    1515import java.text.DecimalFormat;
    1616import java.util.ArrayList;
    1717import java.util.EnumMap;
    1818
     19import s57.S57att.Att;
     20import s57.S57map.AttMap;
     21import s57.S57map.ObjTab;
     22import s57.S57obj.Obj;
     23import s57.S57val.BoySHP;
     24import s57.S57val.CatFOG;
    1925import s57.S57val.CatLIT;
     26import s57.S57val.CatROS;
     27import s57.S57val.CatRTB;
    2028import s57.S57val.ColCOL;
    21 import s57.S57att.*;
    22 import s57.S57obj.*;
    23 import s57.S57val.*;
    24 import s57.S57map.*;
     29import s57.S57val.LitCHR;
    2530import symbols.Beacons;
    2631import symbols.Symbols;
     32import symbols.Symbols.Delta;
     33import symbols.Symbols.Handle;
     34import symbols.Symbols.Scheme;
    2735import 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
     37public 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    }
    686695}
Note: See TracChangeset for help on using the changeset viewer.