Changeset 33941 in osm for applications/editors


Ignore:
Timestamp:
2017-12-08T14:05:44+01:00 (7 years ago)
Author:
malcolmh
Message:

new topmarks & lights

Location:
applications/editors/josm/plugins/seachart
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/seachart/jicons/examples.xml

    r33936 r33941  
    1414    <tag k="seamark:topmark:shape" v="cone, point up" />
    1515  </icon>
    16   <icon width="100" height="100" scale="0.5" file="floodlight" format="PNG" >
    17     <tag k="seamark:type" v="light_minor" />
    18     <tag k="seamark:light:category" v="floodlight" />
     16  <icon width="200" height="200" scale="0.5" file="hib" format="PNG" >
     17    <tag k="seamark:type" v="beacon_special_purpose" />
     18    <tag k="seamark:beacon_special_purpose:shape" v="stake" />
    1919    <tag k="seamark:topmark:shape" v="arrow" />
     20    <tag k="seamark:topmark:status" v="illuminated" />
    2021    <tag k="seamark:topmark:orientation" v="45" />
    2122  </icon>
  • applications/editors/josm/plugins/seachart/src/render/Rules.java

    r33937 r33941  
    8080public class Rules {
    8181
    82     static final DecimalFormat df = new DecimalFormat("#.#");
    83 
    84     static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<>(ColCOL.class);
    85     static {
    86         bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
    87         bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
    88         bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
    89         bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
    90         bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
    91         bodyColours.put(ColCOL.COL_BLU, Color.blue);
    92         bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
    93         bodyColours.put(ColCOL.COL_GRY, Color.gray);
    94         bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
    95         bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
    96         bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
    97         bodyColours.put(ColCOL.COL_ORG, Color.orange);
    98         bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
    99         bodyColours.put(ColCOL.COL_PNK, Color.pink);
    100     }
    101 
    102     static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<>(ColPAT.class);
    103     static {
    104         pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
    105         pattMap.put(ColPAT.PAT_HORI, Patt.H);
    106         pattMap.put(ColPAT.PAT_VERT, Patt.V);
    107         pattMap.put(ColPAT.PAT_DIAG, Patt.D);
    108         pattMap.put(ColPAT.PAT_BRDR, Patt.B);
    109         pattMap.put(ColPAT.PAT_SQUR, Patt.S);
    110         pattMap.put(ColPAT.PAT_CROS, Patt.C);
    111         pattMap.put(ColPAT.PAT_SALT, Patt.X);
    112         pattMap.put(ColPAT.PAT_STRP, Patt.H);
    113     }
    114 
    115     static String getName() {
    116         AttVal<?> name = feature.atts.get(Att.OBJNAM);
    117         if (name == null) {
    118             AttMap atts = feature.objs.get(feature.type).get(0);
    119             if (atts != null) {
    120                 name = atts.get(Att.OBJNAM);
    121             }
    122         }
    123         return (name != null) ? (String) name.val : null;
    124     }
    125 
    126     public static void addName(int z, Font font) {
    127         addName(z, font, Color.black, new Delta(Handle.CC, new AffineTransform()));
    128     }
    129 
    130     public static void addName(int z, Font font, Color colour) {
    131         addName(z, font, colour, new Delta(Handle.CC, new AffineTransform()));
    132     }
    133 
    134     public static void addName(int z, Font font, Delta delta) {
    135         addName(z, font, Color.black, delta);
    136     }
    137 
    138     public static void addName(int z, Font font, Color colour, Delta delta) {
    139         if (Renderer.zoom >= z) {
    140             String name = getName();
    141             if (name != null) {
    142                 Renderer.labelText(name, font, colour, delta);
    143             }
    144         }
    145     }
    146 
    147     static AttMap getAtts(Obj obj, int idx) {
    148         HashMap<Integer, AttMap> objs = feature.objs.get(obj);
    149         if (objs == null)
    150             return null;
    151         else
    152             return objs.get(idx);
    153     }
    154 
    155     public static Object getAttVal(Obj obj, Att att) {
    156         AttMap atts;
    157         HashMap<Integer, AttMap> objs;
    158         AttVal<?> item;
    159         if ((objs = feature.objs.get(obj)) != null)
    160             atts = objs.get(0);
    161         else
    162             return null;
    163         if ((item = atts.get(att)) == null)
    164             return null;
    165         else
    166             return item.val;
    167     }
    168 
    169     public static String getAttStr(Obj obj, Att att) {
    170         String str = (String) getAttVal(obj, att);
    171         if (str != null) {
    172             return str;
    173         }
    174         return "";
    175     }
    176 
    177     @SuppressWarnings("unchecked")
    178     public static Enum<?> getAttEnum(Obj obj, Att att) {
    179         ArrayList<?> list = (ArrayList<?>) getAttVal(obj, att);
    180         if (list != null) {
    181             return ((ArrayList<Enum<?>>) list).get(0);
    182         }
    183         return S57val.unknAtt(att);
    184     }
    185 
    186     @SuppressWarnings("unchecked")
    187     public static ArrayList<?> getAttList(Obj obj, Att att) {
    188         ArrayList<Enum<?>> list = (ArrayList<Enum<?>>) getAttVal(obj, att);
    189         if (list != null) {
    190             return list;
    191         }
    192         list = new ArrayList<>();
    193         list.add(S57val.unknAtt(att));
    194         return list;
    195     }
    196 
    197     @SuppressWarnings("unchecked")
    198     static Scheme getScheme(Obj obj) {
    199         ArrayList<Color> colours = new ArrayList<>();
    200         for (ColCOL col : (ArrayList<ColCOL>) getAttList(obj, Att.COLOUR)) {
    201             colours.add(bodyColours.get(col));
    202         }
    203         ArrayList<Patt> patterns = new ArrayList<>();
    204         for (ColPAT pat : (ArrayList<ColPAT>) getAttList(obj, Att.COLPAT)) {
    205             patterns.add(pattMap.get(pat));
    206         }
    207         return new Scheme(patterns, colours);
    208     }
    209 
    210     static boolean hasAttribute(Obj obj, Att att) {
    211         AttMap atts;
    212         if ((atts = getAtts(obj, 0)) != null) {
    213             AttVal<?> item = atts.get(att);
    214             return item != null;
    215         }
    216         return false;
    217     }
    218 
    219     static boolean testAttribute(Obj obj, Att att, Object val) {
    220         AttMap atts;
    221         if ((atts = getAtts(obj, 0)) != null) {
    222             AttVal<?> item = atts.get(att);
    223             if (item != null) {
    224                 switch (item.conv) {
    225                 case S:
    226                 case A:
    227                     return ((String) item.val).equals(val);
    228                 case E:
    229                 case L:
    230                     return ((ArrayList<?>) item.val).contains(val);
    231                 case F:
    232                 case I:
    233                     return item.val == val;
    234                 }
    235             }
    236         }
    237         return false;
    238     }
    239 
    240     static boolean hasObject(Obj obj) {
    241         return (feature.objs.containsKey(obj));
    242     }
    243 
    244     public static Feature feature;
    245     static ArrayList<Feature> objects;
    246 
    247     static boolean testObject(Obj obj) {
    248         return ((objects = Renderer.map.features.get(obj)) != null);
    249     }
    250 
    251     static boolean testFeature(Feature f) {
    252         return ((feature = f).reln == Rflag.MASTER);
    253     }
    254 
    255     public static boolean rules() {
    256         try {
    257         if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
    258             if (testObject(Obj.LNDARE)) for (Feature f : objects) if (testFeature(f)) areas();
    259             if (testObject(Obj.BUAARE)) for (Feature f : objects) if (testFeature(f)) areas();
    260             if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) areas();
    261             if (testObject(Obj.HRBBSN)) for (Feature f : objects) if (testFeature(f)) areas();
    262             if (testObject(Obj.LOKBSN)) for (Feature f : objects) if (testFeature(f)) areas();
    263             if (testObject(Obj.LKBSPT)) for (Feature f : objects) if (testFeature(f)) areas();
    264             if (testObject(Obj.LAKARE)) for (Feature f : objects) if (testFeature(f)) areas();
    265             if (testObject(Obj.RIVERS)) for (Feature f : objects) if (testFeature(f)) waterways();
    266             if (testObject(Obj.CANALS)) for (Feature f : objects) if (testFeature(f)) waterways();
    267             if (testObject(Obj.DEPARE)) for (Feature f : objects) if (testFeature(f)) areas();
    268             if (testObject(Obj.COALNE)) for (Feature f : objects) if (testFeature(f)) areas();
    269             if (testObject(Obj.ROADWY)) for (Feature f : objects) if (testFeature(f)) highways();
    270             if (testObject(Obj.RAILWY)) for (Feature f : objects) if (testFeature(f)) highways();
    271         }
    272         if (Renderer.context.ruleset() == RuleSet.ALL) {
    273             if (testObject(Obj.SOUNDG)) for (Feature f : objects) if (testFeature(f)) depths();
    274             if (testObject(Obj.DEPCNT)) for (Feature f : objects) if (testFeature(f)) depths();
    275         }
    276         if (testObject(Obj.SLCONS)) for (Feature f : objects) if (testFeature(f)) shoreline();
    277         if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
    278             if (testObject(Obj.PIPSOL)) for (Feature f : objects) if (testFeature(f)) pipelines();
    279             if (testObject(Obj.CBLSUB)) for (Feature f : objects) if (testFeature(f)) cables();
    280             if (testObject(Obj.PIPOHD)) for (Feature f : objects) if (testFeature(f)) pipelines();
    281             if (testObject(Obj.CBLOHD)) for (Feature f : objects) if (testFeature(f)) cables();
    282             if (testObject(Obj.TSEZNE)) for (Feature f : objects) if (testFeature(f)) separation();
    283             if (testObject(Obj.TSSCRS)) for (Feature f : objects) if (testFeature(f)) separation();
    284             if (testObject(Obj.TSSRON)) for (Feature f : objects) if (testFeature(f)) separation();
    285             if (testObject(Obj.TSELNE)) for (Feature f : objects) if (testFeature(f)) separation();
    286             if (testObject(Obj.TSSLPT)) for (Feature f : objects) if (testFeature(f)) separation();
    287             if (testObject(Obj.TSSBND)) for (Feature f : objects) if (testFeature(f)) separation();
    288             if (testObject(Obj.ISTZNE)) for (Feature f : objects) if (testFeature(f)) separation();
    289             if (testObject(Obj.SNDWAV)) for (Feature f : objects) if (testFeature(f)) areas();
    290             if (testObject(Obj.WEDKLP)) for (Feature f : objects) if (testFeature(f)) areas();
    291             if (testObject(Obj.OSPARE)) for (Feature f : objects) if (testFeature(f)) areas();
    292             if (testObject(Obj.FAIRWY)) for (Feature f : objects) if (testFeature(f)) areas();
    293             if (testObject(Obj.DRGARE)) for (Feature f : objects) if (testFeature(f)) areas();
    294             if (testObject(Obj.RESARE)) for (Feature f : objects) if (testFeature(f)) areas();
    295             if (testObject(Obj.PRCARE)) for (Feature f : objects) if (testFeature(f)) areas();
    296             if (testObject(Obj.SPLARE)) for (Feature f : objects) if (testFeature(f)) areas();
    297             if (testObject(Obj.SEAARE)) for (Feature f : objects) if (testFeature(f)) areas();
    298             if (testObject(Obj.OBSTRN)) for (Feature f : objects) if (testFeature(f)) obstructions();
    299             if (testObject(Obj.UWTROC)) for (Feature f : objects) if (testFeature(f)) obstructions();
    300             if (testObject(Obj.MARCUL)) for (Feature f : objects) if (testFeature(f)) areas();
    301             if (testObject(Obj.RECTRC)) for (Feature f : objects) if (testFeature(f)) transits();
    302             if (testObject(Obj.NAVLNE)) for (Feature f : objects) if (testFeature(f)) transits();
    303             if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) harbours();
    304             if (testObject(Obj.ACHARE)) for (Feature f : objects) if (testFeature(f)) harbours();
    305             if (testObject(Obj.ACHBRT)) for (Feature f : objects) if (testFeature(f)) harbours();
    306             if (testObject(Obj.BERTHS)) for (Feature f : objects) if (testFeature(f)) harbours();
    307             if (testObject(Obj.DISMAR)) for (Feature f : objects) if (testFeature(f)) distances();
    308             if (testObject(Obj.HULKES)) for (Feature f : objects) if (testFeature(f)) ports();
    309             if (testObject(Obj.CRANES)) for (Feature f : objects) if (testFeature(f)) ports();
    310             if (testObject(Obj.LNDMRK)) for (Feature f : objects) if (testFeature(f)) landmarks();
    311             if (testObject(Obj.SILTNK)) for (Feature f : objects) if (testFeature(f)) landmarks();
    312             if (testObject(Obj.BUISGL)) for (Feature f : objects) if (testFeature(f)) harbours();
    313             if (testObject(Obj.MORFAC)) for (Feature f : objects) if (testFeature(f)) moorings();
    314             if (testObject(Obj.NOTMRK)) for (Feature f : objects) if (testFeature(f)) notices();
    315             if (testObject(Obj.SMCFAC)) for (Feature f : objects) if (testFeature(f)) marinas();
    316             if (testObject(Obj.BRIDGE)) for (Feature f : objects) if (testFeature(f)) bridges();
    317             if (testObject(Obj.PILPNT)) for (Feature f : objects) if (testFeature(f)) points();
    318             if (testObject(Obj.TOPMAR)) for (Feature f : objects) if (testFeature(f)) points();
    319             if (testObject(Obj.DAYMAR)) for (Feature f : objects) if (testFeature(f)) points();
    320             if (testObject(Obj.FOGSIG)) for (Feature f : objects) if (testFeature(f)) points();
    321             if (testObject(Obj.RDOCAL)) for (Feature f : objects) if (testFeature(f)) callpoint();
    322             if (testObject(Obj.LITMIN)) for (Feature f : objects) if (testFeature(f)) lights();
    323             if (testObject(Obj.LITMAJ)) for (Feature f : objects) if (testFeature(f)) lights();
    324             if (testObject(Obj.LIGHTS)) for (Feature f : objects) if (testFeature(f)) lights();
    325             if (testObject(Obj.SISTAT)) for (Feature f : objects) if (testFeature(f)) stations();
    326             if (testObject(Obj.SISTAW)) for (Feature f : objects) if (testFeature(f)) stations();
    327             if (testObject(Obj.CGUSTA)) for (Feature f : objects) if (testFeature(f)) stations();
    328             if (testObject(Obj.RDOSTA)) for (Feature f : objects) if (testFeature(f)) stations();
    329             if (testObject(Obj.RADRFL)) for (Feature f : objects) if (testFeature(f)) stations();
    330             if (testObject(Obj.RADSTA)) for (Feature f : objects) if (testFeature(f)) stations();
    331             if (testObject(Obj.RTPBCN)) for (Feature f : objects) if (testFeature(f)) stations();
    332             if (testObject(Obj.RSCSTA)) for (Feature f : objects) if (testFeature(f)) stations();
    333             if (testObject(Obj.PILBOP)) for (Feature f : objects) if (testFeature(f)) stations();
    334             if (testObject(Obj.WTWGAG)) for (Feature f : objects) if (testFeature(f)) gauges();
    335             if (testObject(Obj.OFSPLF)) for (Feature f : objects) if (testFeature(f)) platforms();
    336             if (testObject(Obj.WRECKS)) for (Feature f : objects) if (testFeature(f)) wrecks();
    337             if (testObject(Obj.LITVES)) for (Feature f : objects) if (testFeature(f)) floats();
    338             if (testObject(Obj.LITFLT)) for (Feature f : objects) if (testFeature(f)) floats();
    339             if (testObject(Obj.BOYINB)) for (Feature f : objects) if (testFeature(f)) floats();
    340             if (testObject(Obj.BOYLAT)) for (Feature f : objects) if (testFeature(f)) buoys();
    341             if (testObject(Obj.BOYCAR)) for (Feature f : objects) if (testFeature(f)) buoys();
    342             if (testObject(Obj.BOYISD)) for (Feature f : objects) if (testFeature(f)) buoys();
    343             if (testObject(Obj.BOYSAW)) for (Feature f : objects) if (testFeature(f)) buoys();
    344             if (testObject(Obj.BOYSPP)) for (Feature f : objects) if (testFeature(f)) buoys();
    345             if (testObject(Obj.BCNLAT)) for (Feature f : objects) if (testFeature(f)) beacons();
    346             if (testObject(Obj.BCNCAR)) for (Feature f : objects) if (testFeature(f)) beacons();
    347             if (testObject(Obj.BCNISD)) for (Feature f : objects) if (testFeature(f)) beacons();
    348             if (testObject(Obj.BCNSAW)) for (Feature f : objects) if (testFeature(f)) beacons();
    349             if (testObject(Obj.BCNSPP)) for (Feature f : objects) if (testFeature(f)) beacons();
    350         }
    351         } catch (ConcurrentModificationException e) {
    352                 return false;
    353         } catch (Exception e) {
    354                 return true;
    355         }
    356         return true;
    357     }
    358 
    359     private static void areas() {
    360         String name = getName();
    361         switch (feature.type) {
    362         case BUAARE:
    363             Renderer.lineVector(new LineStyle(new Color(0x20000000, true)));
    364             break;
    365         case COALNE:
    366             if (Renderer.zoom >= 12)
    367                 Renderer.lineVector(new LineStyle(Color.black, 10));
    368             break;
    369         case DEPARE:
    370             Double depmax = 0.0;
    371             if (((depmax = (Double) getAttVal(Obj.DEPARE, Att.DRVAL2)) != null) && (depmax <= 0.0)) {
    372                 Renderer.lineVector(new LineStyle(Symbols.Gdries));
    373             }
    374             break;
    375         case LAKARE:
    376             if ((Renderer.zoom >= 12) || (feature.geom.area > 10.0))
    377                 Renderer.lineVector(new LineStyle(Symbols.Bwater));
    378             break;
    379         case DRGARE:
    380             if (Renderer.zoom < 16)
    381                 Renderer.lineVector(new LineStyle(Color.black, 8, new float[] {25, 25 }, new Color(0x40ffffff, true)));
    382             else
    383                 Renderer.lineVector(new LineStyle(Color.black, 8, new float[] {25, 25 }));
    384             addName(12, new Font("Arial", Font.PLAIN, 100), new Delta(Handle.CC, new AffineTransform()));
    385             break;
    386         case FAIRWY:
    387             if (feature.geom.area > 2.0) {
    388                 if (Renderer.zoom < 16)
    389                     Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] {50, 50 }, new Color(0x40ffffff, true)));
    390                 else
    391                     Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] {50, 50 }));
    392             } else {
    393                 if (Renderer.zoom >= 14)
    394                     Renderer.lineVector(new LineStyle(new Color(0x40ffffff, true)));
    395             }
    396             break;
    397         case LKBSPT:
    398         case LOKBSN:
    399         case HRBBSN:
    400             if (Renderer.zoom >= 12) {
    401                 Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
    402             } else {
    403                 Renderer.lineVector(new LineStyle(Symbols.Bwater));
    404             }
    405             break;
    406         case HRBFAC:
    407             if (feature.objs.get(Obj.HRBBSN) != null) {
    408                 if (Renderer.zoom >= 12) {
    409                     Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
    410                 } else {
    411                     Renderer.lineVector(new LineStyle(Symbols.Bwater));
    412                 }
    413             }
    414             break;
    415         case LNDARE:
    416             Renderer.lineVector(new LineStyle(Symbols.Yland));
    417             break;
    418         case MARCUL:
    419             if (Renderer.zoom >= 12) {
    420                 if (Renderer.zoom >= 14) {
    421                     Renderer.symbol(Areas.MarineFarm);
    422                 }
    423                 if ((feature.geom.area > 0.2) || ((feature.geom.area > 0.05) && (Renderer.zoom >= 14)) ||
    424                    ((feature.geom.area > 0.005) && (Renderer.zoom >= 16))) {
    425                     Renderer.lineVector(new LineStyle(Color.black, 4, new float[] {10, 10}));
    426                 }
    427             }
    428             break;
    429         case OSPARE:
    430             if (testAttribute(feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
    431                 Renderer.symbol(Areas.WindFarm);
    432                 Renderer.lineVector(new LineStyle(Color.black, 20, new float[] {40, 40}));
    433                 addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
    434             }
    435             break;
    436         case RESARE:
    437         case MIPARE:
    438             if (Renderer.zoom >= 12) {
    439                 Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mline);
    440                 if (testAttribute(feature.type, Att.CATREA, CatREA.REA_NWAK)) {
    441                     Renderer.symbol(Areas.NoWake);
    442                 }
    443             }
    444             break;
    445         case PRCARE:
    446             if (Renderer.zoom >= 12) {
    447                 Renderer.lineVector(new LineStyle(Symbols.Mline, 10, new float[] {40, 40}));
    448             }
    449             break;
    450         case SEAARE:
    451             switch ((CatSEA) getAttEnum(feature.type, Att.CATSEA)) {
    452             case SEA_RECH:
    453                 if ((Renderer.zoom >= 10) && (name != null))
    454                     if (feature.geom.prim == Pflag.LINE) {
    455                         Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
    456                     } else {
    457                         Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black,
    458                                 new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
    459                     }
    460                 break;
    461             case SEA_BAY:
    462                 if ((Renderer.zoom >= 12) && (name != null))
    463                     if (feature.geom.prim == Pflag.LINE) {
    464                         Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
    465                     } else {
    466                         Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black,
    467                                 new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
    468                     }
    469                 break;
    470             case SEA_SHOL:
    471                 if (Renderer.zoom >= 14) {
    472                     if (feature.geom.prim == Pflag.AREA) {
    473                         Renderer.lineVector(new LineStyle(new Color(0xc480ff), 4, new float[] {25, 25}));
    474                         if (name != null) {
    475                             Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black,
    476                                     new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
    477                             Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
    478                         }
    479                     } else if (feature.geom.prim == Pflag.LINE) {
    480                         if (name != null) {
    481                             Renderer.lineText(name, new Font("Arial", Font.ITALIC, 75), Color.black, -40);
    482                             Renderer.lineText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, 0);
    483                         }
    484                     } else {
    485                         if (name != null) {
    486                             Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black,
    487                                     new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
    488                             Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
    489                         }
    490                     }
    491                 }
    492                 break;
    493             case SEA_GAT:
    494             case SEA_NRRW:
    495                 addName(12, new Font("Arial", Font.PLAIN, 100));
    496                 break;
    497             default:
    498                 break;
    499             }
    500             break;
    501         case SNDWAV:
    502             if (Renderer.zoom >= 12) Renderer.fillPattern(Areas.Sandwaves);
    503             break;
    504         case WEDKLP:
    505             if (Renderer.zoom >= 12) {
    506                 switch ((CatWED) getAttEnum(feature.type, Att.CATWED)) {
    507                 case WED_KELP:
    508                     if (feature.geom.prim == Pflag.AREA) {
    509                         Renderer.fillPattern(Areas.KelpA);
    510                     } else {
    511                         Renderer.symbol(Areas.KelpS);
    512                     }
    513                     break;
    514                 default:
    515                     break;
    516                 }
    517             }
    518             break;
    519         case SPLARE:
    520             if (Renderer.zoom >= 12) {
    521                 Renderer.symbol(Areas.Plane, new Scheme(Symbols.Msymb));
    522                 Renderer.lineSymbols(Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Symbols.Mline);
    523             }
    524             addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
    525             break;
    526         default:
    527             break;
    528         }
    529     }
    530 
    531     @SuppressWarnings("unchecked")
    532     private static void beacons() {
    533         if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))
    534                 || ((Renderer.zoom >= 11) && ((feature.type == Obj.BCNSAW) || hasObject(Obj.RTPBCN)))) {
    535             BcnSHP shape = (BcnSHP) getAttEnum(feature.type, Att.BCNSHP);
    536             if (shape == BcnSHP.BCN_UNKN)
    537                 shape = BcnSHP.BCN_PILE;
    538             if ((shape == BcnSHP.BCN_WTHY) && (feature.type == Obj.BCNLAT)) {
    539                 switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
    540                 case LAM_PORT:
    541                     Renderer.symbol(Beacons.WithyPort);
    542                     break;
    543                 case LAM_STBD:
    544                     Renderer.symbol(Beacons.WithyStarboard);
    545                     break;
    546                 default:
    547                     Renderer.symbol(Beacons.Stake, getScheme(feature.type));
    548                 }
    549             } else if ((shape == BcnSHP.BCN_PRCH) && (feature.type == Obj.BCNLAT) && !(feature.objs.containsKey(Obj.TOPMAR))) {
    550                 switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
    551                 case LAM_PORT:
    552                     Renderer.symbol(Beacons.PerchPort);
    553                     break;
    554                 case LAM_STBD:
    555                     Renderer.symbol(Beacons.PerchStarboard);
    556                     break;
    557                 default:
    558                     Renderer.symbol(Beacons.Stake, getScheme(feature.type));
    559                 }
    560             } else {
    561                 Renderer.symbol(Beacons.Shapes.get(shape), getScheme(feature.type));
    562                 if (feature.objs.containsKey(Obj.TOPMAR)) {
    563                     AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    564                     if (topmap.containsKey(Att.TOPSHP)) {
    565                         Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    566                                 getScheme(Obj.TOPMAR), Topmarks.BeaconDelta);
    567                     }
    568                 } else if (feature.objs.containsKey(Obj.DAYMAR)) {
    569                     AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    570                     if (topmap.containsKey(Att.TOPSHP)) {
    571                         Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    572                                 getScheme(Obj.DAYMAR), Topmarks.BeaconDelta);
    573                     }
    574                 }
    575             }
    576             if (hasObject(Obj.NOTMRK))
    577                 notices();
    578             addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
    579             Signals.addSignals();
    580         }
    581     }
    582 
    583     @SuppressWarnings("unchecked")
    584     private static void buoys() {
    585         if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))
    586                 || ((Renderer.zoom >= 11) && ((feature.type == Obj.BOYSAW) || hasObject(Obj.RTPBCN)))) {
    587             BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
    588             if (shape == BoySHP.BOY_UNKN) shape = BoySHP.BOY_PILR;
    589             Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
    590             if (feature.objs.containsKey(Obj.TOPMAR)) {
    591                 AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    592                 if (topmap.containsKey(Att.TOPSHP)) {
    593                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    594                             getScheme(Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
    595                 }
    596             } else if (feature.objs.containsKey(Obj.DAYMAR)) {
    597                 AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    598                 if (topmap.containsKey(Att.TOPSHP)) {
    599                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    600                             getScheme(Obj.DAYMAR), Topmarks.BuoyDeltas.get(shape));
    601                 }
    602             }
    603             addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
    604             Signals.addSignals();
    605         }
    606     }
    607 
    608     private static void bridges() {
    609         if (Renderer.zoom >= 16) {
    610             double verclr, verccl, vercop, horclr;
    611             AttMap atts = feature.objs.get(Obj.BRIDGE).get(0);
    612             String vstr = "";
    613             String hstr = "";
    614             if (atts != null) {
    615                 if (atts.containsKey(Att.HORCLR)) {
    616                     horclr = (Double) atts.get(Att.HORCLR).val;
    617                     hstr = String.valueOf(horclr);
    618                 }
    619                 if (atts.containsKey(Att.VERCLR)) {
    620                     verclr = (Double) atts.get(Att.VERCLR).val;
    621                 } else {
    622                     verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
    623                 }
    624                 verccl = atts.containsKey(Att.VERCCL) ? (Double) atts.get(Att.VERCCL).val : 0;
    625                 vercop = atts.containsKey(Att.VERCOP) ? (Double) atts.get(Att.VERCOP).val : 0;
    626                 if (verclr > 0) {
    627                     vstr += String.valueOf(verclr);
    628                 } else if (verccl > 0) {
    629                     if (vercop == 0) {
    630                         vstr += String.valueOf(verccl) + "/-";
    631                     } else {
    632                         vstr += String.valueOf(verccl) + "/" + String.valueOf(vercop);
    633                     }
    634                 }
    635                 if (hstr.isEmpty() && !vstr.isEmpty()) {
    636                     Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white,
    637                             new Delta(Handle.CC));
    638                 } else if (!hstr.isEmpty() && !vstr.isEmpty()) {
    639                     Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white,
    640                             new Delta(Handle.BC));
    641                     Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white,
    642                             new Delta(Handle.TC));
    643                 } else if (!hstr.isEmpty() && vstr.isEmpty()) {
    644                     Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white,
    645                             new Delta(Handle.CC));
    646                 }
    647             }
    648         }
    649     }
    650 
    651     private static void cables() {
    652         if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
    653             if (feature.type == Obj.CBLSUB) {
    654                 Renderer.lineSymbols(Areas.Cable, 0.0, null, null, 0, Symbols.Mline);
    655             } else if (feature.type == Obj.CBLOHD) {
    656                 AttMap atts = feature.objs.get(Obj.CBLOHD).get(0);
    657                 if ((atts != null) && (atts.containsKey(Att.CATCBL)) && (atts.get(Att.CATCBL).val == CatCBL.CBL_POWR)) {
    658                     Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, Areas.CableFlash, 2, Color.black);
    659                 } else {
    660                     Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, null, 2, Color.black);
    661                 }
    662                 if (atts != null) {
    663                     if (atts.containsKey(Att.VERCLR)) {
    664                         Renderer.labelText(String.valueOf(atts.get(Att.VERCLR).val), new Font("Arial", Font.PLAIN, 50),
    665                                 Color.black, LabelStyle.VCLR, Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
    666                     } else if (atts.containsKey(Att.VERCSA)) {
    667                         Renderer.labelText(String.valueOf(atts.get(Att.VERCSA).val), new Font("Arial", Font.PLAIN, 50),
    668                                 Color.black, LabelStyle.PCLR, Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
    669                     }
    670                 }
    671             }
    672         }
    673     }
    674 
    675     private static void callpoint() {
    676         if (Renderer.zoom >= 14) {
    677             Symbol symb = Harbours.CallPoint2;
    678             TrfTRF trf = (TrfTRF) getAttEnum(feature.type, Att.TRAFIC);
    679             if (trf != TrfTRF.TRF_TWOW) {
    680                 symb = Harbours.CallPoint1;
    681             }
    682             Double orient = 0.0;
    683             if ((orient = (Double) getAttVal(feature.type, Att.ORIENT)) == null) {
    684                 orient = 0.0;
    685             }
    686             Renderer.symbol(symb, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(orient))));
    687             String chn;
    688             if (!(chn = getAttStr(feature.type, Att.COMCHA)).isEmpty()) {
    689                 Renderer.labelText(("Ch." + chn), new Font("Arial", Font.PLAIN, 50), Color.black,
    690                         new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 50)));
    691             }
    692         }
    693     }
    694 
    695     private static void depths() {
    696         switch (feature.type) {
    697         case SOUNDG:
    698             if ((Renderer.zoom >= 14) && hasAttribute(Obj.SOUNDG, Att.VALSOU)) {
    699                 double depth = (double) getAttVal(Obj.SOUNDG, Att.VALSOU);
    700                 String dstr = df.format(depth);
    701                 String[] tok = dstr.split("[-.]");
    702                 String ul = "";
    703                 String id = tok[0];
    704                 String dd = "";
    705                 if (tok[0].equals("")) {
    706                     for (int i = 0; i < tok[1].length(); i++) {
    707                         ul += "_";
    708                     }
    709                     id = tok[1];
    710                     dd = (tok.length == 3) ? tok[2] : "";
    711                 } else {
    712                     dd = (tok.length == 2) ? tok[1] : "";
    713                 }
    714                 Renderer.labelText(ul, new Font("Arial", Font.PLAIN, 30), Color.black,
    715                         new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 15)));
    716                 Renderer.labelText(id, new Font("Arial", Font.PLAIN, 30), Color.black,
    717                         new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 0)));
    718                 Renderer.labelText(dd, new Font("Arial", Font.PLAIN, 20), Color.black,
    719                         new Delta(Handle.LC, AffineTransform.getTranslateInstance(15, 10)));
    720             }
    721             break;
    722         case DEPCNT:
    723             break;
    724         default:
    725             break;
    726         }
    727     }
    728 
    729     private static void distances() {
    730         if (Renderer.zoom >= 14) {
    731             if (!testAttribute(Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
    732                 Renderer.symbol(Harbours.DistanceI);
    733             } else {
    734                 Renderer.symbol(Harbours.DistanceU);
    735             }
    736             if (Renderer.zoom >= 15) {
    737                 AttMap atts = getAtts(Obj.DISMAR, 0);
    738                 if ((atts != null) && (atts.containsKey(Att.WTWDIS))) {
    739                     Double dist = (Double) atts.get(Att.WTWDIS).val;
    740                     String str = "";
    741                     if (atts.containsKey(Att.HUNITS)) {
    742                         switch ((UniHLU) getAttEnum(Obj.DISMAR, Att.HUNITS)) {
    743                         case HLU_METR:
    744                             str += "m ";
    745                             break;
    746                         case HLU_FEET:
    747                             str += "ft ";
    748                             break;
    749                         case HLU_HMTR:
    750                             str += "hm ";
    751                             break;
    752                         case HLU_KMTR:
    753                             str += "km ";
    754                             break;
    755                         case HLU_SMIL:
    756                             str += "M ";
    757                             break;
    758                         case HLU_NMIL:
    759                             str += "NM ";
    760                             break;
    761                         default:
    762                             break;
    763                         }
    764                     }
    765                     str += String.format("%1.0f", dist);
    766                     Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black,
    767                             new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
    768                 }
    769             }
    770         }
    771     }
    772 
    773     @SuppressWarnings("unchecked")
    774     private static void floats() {
    775         if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) ||
    776                 (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
    777             switch (feature.type) {
    778             case LITVES:
    779                 Renderer.symbol(Buoys.Super, getScheme(feature.type));
    780                 break;
    781             case LITFLT:
    782                 Renderer.symbol(Buoys.Float, getScheme(feature.type));
    783                 break;
    784             case BOYINB:
    785                 Renderer.symbol(Buoys.Super, getScheme(feature.type));
    786                 break;
    787             default:
    788                 break;
    789             }
    790             if (feature.objs.containsKey(Obj.TOPMAR)) {
    791                 AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    792                 if (topmap.containsKey(Att.TOPSHP)) {
    793                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    794                             getScheme(Obj.TOPMAR), Topmarks.FloatDelta);
    795                 }
    796             } else if (feature.objs.containsKey(Obj.DAYMAR)) {
    797                 AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    798                 if (topmap.containsKey(Att.TOPSHP)) {
    799                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    800                             getScheme(Obj.DAYMAR), Topmarks.FloatDelta);
    801                 }
    802             }
    803             addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
    804             Signals.addSignals();
    805         }
    806     }
    807 
    808     private static void gauges() {
    809         if (Renderer.zoom >= 14) {
    810             Renderer.symbol(Harbours.TideGauge);
    811             addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
    812             Signals.addSignals();
    813         }
    814     }
    815 
    816     @SuppressWarnings("unchecked")
    817     private static void harbours() {
    818         String name = getName();
    819         switch (feature.type) {
    820         case ACHBRT:
    821             if (Renderer.zoom >= 14) {
    822                 Renderer.symbol(Harbours.Anchor, new Scheme(Symbols.Msymb));
    823                 if (Renderer.zoom >= 15) {
    824                     Renderer.labelText(name == null ? "" : name,
    825                             new Font("Arial", Font.PLAIN, 30), Symbols.Msymb, LabelStyle.RRCT, Symbols.Msymb, Color.white, new Delta(Handle.BC));
    826                 }
    827             }
    828             if (getAttVal(Obj.ACHBRT, Att.RADIUS) != null) {
    829                 double radius;
    830                 if ((radius = (Double) getAttVal(Obj.ACHBRT, Att.RADIUS)) != 0) {
    831                     UniHLU units = (UniHLU) getAttEnum(Obj.ACHBRT, Att.HUNITS);
    832                     if (units == UniHLU.HLU_UNKN) {
    833                         units = UniHLU.HLU_METR;
    834                     }
    835                     Renderer.lineCircle(new LineStyle(Symbols.Mline, 4, new float[] {10, 10}, null), radius, units);
    836                 }
    837             }
    838             break;
    839         case ACHARE:
    840             if (Renderer.zoom >= 12) {
    841                 if (feature.geom.prim != Pflag.AREA) {
    842                     Renderer.symbol(Harbours.Anchorage, new Scheme(Color.black));
    843                 } else {
    844                     Renderer.symbol(Harbours.Anchorage, new Scheme(Symbols.Mline));
    845                     Renderer.lineSymbols(Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Symbols.Mline);
    846                 }
    847                 addName(15, new Font("Arial", Font.BOLD, 60), Symbols.Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
    848                 ArrayList<StsSTS> sts = (ArrayList<StsSTS>) getAttList(Obj.ACHARE, Att.STATUS);
    849                 if ((Renderer.zoom >= 15) && (sts.contains(StsSTS.STS_RESV))) {
    850                     Renderer.labelText("Reserved",
    851                             new Font("Arial", Font.PLAIN, 50), Symbols.Mline, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
    852                 }
    853                 ArrayList<CatACH> cats = (ArrayList<CatACH>) getAttList(Obj.ACHARE, Att.CATACH);
    854                 int dy = (cats.size() - 1) * -30;
    855                 for (CatACH cat : cats) {
    856                     switch (cat) {
    857                     case ACH_DEEP:
    858                         Renderer.labelText("DW", new Font("Arial", Font.BOLD, 50), Symbols.Msymb,
    859                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    860                         dy += 60;
    861                         break;
    862                     case ACH_TANK:
    863                         Renderer.labelText("Tanker", new Font("Arial", Font.BOLD, 50), Symbols.Msymb,
    864                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    865                         dy += 60;
    866                         break;
    867                     case ACH_H24P:
    868                         Renderer.labelText("24h", new Font("Arial", Font.BOLD, 50), Symbols.Msymb,
    869                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    870                         dy += 60;
    871                         break;
    872                     case ACH_EXPL:
    873                         Renderer.symbol(Harbours.Explosives, new Scheme(Symbols.Msymb),
    874                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    875                         dy += 60;
    876                         break;
    877                     case ACH_QUAR:
    878                         Renderer.symbol(Harbours.Hospital, new Scheme(Symbols.Msymb),
    879                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    880                         dy += 60;
    881                         break;
    882                     case ACH_SEAP:
    883                         Renderer.symbol(Areas.Seaplane, new Scheme(Symbols.Msymb),
    884                                 new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
    885                         dy += 60;
    886                         break;
    887                     default:
    888                     }
    889                 }
    890             }
    891             break;
    892         case BERTHS:
    893             if (Renderer.zoom >= 14) {
    894                 Renderer.lineVector(new LineStyle(Symbols.Mline, 6, new float[] {20, 20}));
    895                 Renderer.labelText(name == null ? " " : name,
    896                         new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, LabelStyle.RRCT, Symbols.Mline, Color.white);
    897             }
    898             break;
    899         case BUISGL:
    900             if (Renderer.zoom >= 16) {
    901                                 if (hasAttribute(Obj.BUISGL, Att.STATUS) && (testAttribute(Obj.BUISGL, Att.STATUS, StsSTS.STS_ILLD))) {
    902                                         Renderer.symbol(Beacons.Floodlight);
    903                                 }
    904                 ArrayList<Symbol> symbols = new ArrayList<>();
    905                 ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(Obj.BUISGL, Att.FUNCTN);
    906                 for (FncFNC fnc : fncs) {
    907                     symbols.add(Landmarks.Funcs.get(fnc));
    908                 }
    909                 if (feature.objs.containsKey(Obj.SMCFAC)) {
    910                     ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
    911                     for (CatSCF scf : scfs) {
    912                         symbols.add(Facilities.Cats.get(scf));
    913                     }
    914                 }
    915                 Renderer.cluster(symbols);
    916             }
    917             break;
    918         case HRBFAC:
    919             if (Renderer.zoom >= 12) {
    920                 ArrayList<CatHAF> cathaf = (ArrayList<CatHAF>) getAttList(Obj.HRBFAC, Att.CATHAF);
    921                 if (cathaf.size() == 1) {
    922                     switch (cathaf.get(0)) {
    923                     case HAF_MRNA:
    924                         Renderer.symbol(Harbours.Marina);
    925                         break;
    926                     case HAF_MANF:
    927                         Renderer.symbol(Harbours.MarinaNF);
    928                         break;
    929                     case HAF_FISH:
    930                         Renderer.symbol(Harbours.Fishing);
    931                         break;
    932                     default:
    933                         Renderer.symbol(Harbours.Harbour);
    934                         break;
    935                     }
    936                 } else {
    937                     Renderer.symbol(Harbours.Harbour);
    938                 }
    939             }
    940             break;
    941         default:
    942             break;
    943         }
    944     }
    945 
    946     @SuppressWarnings("unchecked")
    947     private static void highways() {
    948         switch (feature.type) {
    949         case ROADWY:
    950             ArrayList<CatROD> cat = (ArrayList<CatROD>) (getAttList(Obj.ROADWY, Att.CATROD));
    951             if (cat.size() > 0) {
    952                 switch (cat.get(0)) {
    953                 case ROD_MWAY:
    954                     Renderer.lineVector(new LineStyle(Color.black, 20));
    955                     break;
    956                 case ROD_MAJR:
    957                     Renderer.lineVector(new LineStyle(Color.black, 15));
    958                     break;
    959                 case ROD_MINR:
    960                     Renderer.lineVector(new LineStyle(Color.black, 10));
    961                     break;
    962                 default:
    963                     Renderer.lineVector(new LineStyle(Color.black, 5));
    964                 }
    965             } else {
    966                 Renderer.lineVector(new LineStyle(Color.black, 5));
    967             }
    968             break;
    969         case RAILWY:
    970             Renderer.lineVector(new LineStyle(Color.gray, 10));
    971             Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {30, 30}));
    972             break;
    973         default:
    974         }
    975     }
    976 
    977     @SuppressWarnings("unchecked")
    978     private static void landmarks() {
    979         if (!hasAttribute(Obj.LNDMRK, Att.CATLMK)
    980                 && (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT))
    981                 && hasObject(Obj.LIGHTS))
    982             lights();
    983         else if (Renderer.zoom >= 12) {
    984             switch (feature.type) {
    985             case LNDMRK:
    986                                 if (hasAttribute(Obj.LNDMRK, Att.STATUS) && (testAttribute(Obj.LNDMRK, Att.STATUS, StsSTS.STS_ILLD))) {
    987                                         Renderer.symbol(Beacons.Floodlight);
    988                                 }
    989                 ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttList(feature.type, Att.CATLMK);
    990                 Symbol catSym = Landmarks.Shapes.get(cats.get(0));
    991                 ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(feature.type, Att.FUNCTN);
    992                 Symbol fncSym = Landmarks.Funcs.get(fncs.get(0));
    993                 if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
    994                     catSym = Landmarks.ChurchTower;
    995                 if (cats.get(0) == CatLMK.LMK_RADR)
    996                     fncSym = Landmarks.RadioTV;
    997                 Renderer.symbol(catSym);
    998                 Renderer.symbol(fncSym);
    999                 break;
    1000             case SILTNK:
    1001                 if (testAttribute(feature.type, Att.CATSIL, CatSIL.SIL_WTRT))
    1002                     Renderer.symbol(Landmarks.WaterTower);
    1003                 break;
    1004             default:
    1005                 break;
    1006             }
    1007             if (Renderer.zoom >= 15)
    1008                 addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
    1009             Signals.addSignals();
    1010         }
    1011     }
    1012 
    1013     @SuppressWarnings("unchecked")
    1014     private static void points() {
    1015         boolean ok = false;
    1016         switch (feature.type) {
    1017         case FOGSIG:
    1018             if (Renderer.zoom >= 12) {
    1019                 if (feature.objs.containsKey(Obj.LIGHTS))
    1020                     lights();
    1021                 else
    1022                     Renderer.symbol(Harbours.Post);
    1023                 ok = true;
    1024             }
    1025             break;
    1026         default:
    1027             if (Renderer.zoom >= 14) {
    1028                 if (feature.objs.containsKey(Obj.LIGHTS))
    1029                     lights();
    1030                 else
    1031                     Renderer.symbol(Harbours.Post);
    1032                 ok = true;
    1033             }
    1034             break;
    1035         }
    1036         if (ok) {
    1037             if (feature.objs.containsKey(Obj.TOPMAR)) {
    1038                 AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    1039                 if (topmap.containsKey(Att.TOPSHP)) {
    1040                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), null);
    1041                 }
    1042             } else if (feature.objs.containsKey(Obj.DAYMAR)) {
    1043                 AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    1044                 if (topmap.containsKey(Att.TOPSHP)) {
    1045                     Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), null);
    1046                 }
    1047             }
    1048             Signals.addSignals();
    1049         }
    1050     }
    1051 
    1052     @SuppressWarnings("unchecked")
    1053     private static void lights() {
    1054         boolean ok = false;
    1055         switch (feature.type) {
    1056         case LITMAJ:
    1057         case LNDMRK:
    1058                 if (Renderer.zoom >= 12) {
    1059                         Renderer.symbol(Beacons.LightMajor);
    1060                         ok = true;
    1061                 }
    1062                 break;
    1063         case LITMIN:
    1064         case LIGHTS:
    1065         case PILPNT:
    1066                 if (Renderer.zoom >= 14) {
    1067                         if (hasAttribute(Obj.LIGHTS, Att.CATLIT) && (testAttribute(Obj.LIGHTS, Att.CATLIT, CatLIT.LIT_FLDL))) {
    1068                                 Renderer.symbol(Beacons.Floodlight);
    1069                                 Renderer.symbol(Harbours.SignalStation);
    1070                         } else {
    1071                                 Renderer.symbol(Beacons.LightMinor);
    1072                         }
    1073                         ok = true;
    1074                 }
    1075                 break;
    1076         default:
    1077                 break;
    1078         }
    1079         if (ok) {
    1080                 AffineTransform tr = new AffineTransform();
    1081                 if (feature.objs.containsKey(Obj.TOPMAR)) {
    1082                         if (hasAttribute(Obj.TOPMAR, Att.STATUS) && (testAttribute(Obj.TOPMAR, Att.STATUS, StsSTS.STS_ILLD))) {
    1083                                 Renderer.symbol(Beacons.Floodlight);
    1084                         }
    1085                         AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    1086                         if (topmap.containsKey(Att.TOPSHP)) {
    1087                                 if (hasAttribute(Obj.TOPMAR, Att.ORIENT)) {
    1088                                         tr.rotate(Math.toRadians((Double)getAttVal(Obj.TOPMAR, Att.ORIENT)));
    1089                                 }
    1090                                 tr.translate(0, -20);
    1091                                 Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    1092                                                 getScheme(Obj.TOPMAR), new Delta(Handle.BC, tr));
    1093                         }
    1094                 } else if (feature.objs.containsKey(Obj.DAYMAR)) {
    1095                         if (hasAttribute(Obj.DAYMAR, Att.STATUS) && (testAttribute(Obj.DAYMAR, Att.STATUS, StsSTS.STS_ILLD))) {
    1096                                 Renderer.symbol(Beacons.Floodlight);
    1097                         }
    1098                         AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    1099                         if (topmap.containsKey(Att.TOPSHP)) {
    1100                                 if (hasAttribute(Obj.DAYMAR, Att.ORIENT)) {
    1101                                         tr.rotate(Math.toRadians((Double)getAttVal(Obj.DAYMAR, Att.ORIENT)));
    1102                                 }
    1103                                 tr.translate(0, -20);
    1104                                 Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)),
    1105                                                 getScheme(Obj.DAYMAR), new Delta(Handle.BC, tr));
    1106                         }
    1107                 }
    1108                 Signals.addSignals();
    1109         }
    1110     }
    1111 
    1112     @SuppressWarnings("unchecked")
    1113     private static void marinas() {
    1114         if (Renderer.zoom >= 16) {
    1115             ArrayList<Symbol> symbols = new ArrayList<>();
    1116             ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
    1117             for (CatSCF scf : scfs) {
    1118                 symbols.add(Facilities.Cats.get(scf));
    1119             }
    1120             Renderer.cluster(symbols);
    1121         }
    1122     }
    1123 
    1124     private static void moorings() {
    1125         if (Renderer.zoom >= 14) {
    1126             switch ((CatMOR) getAttEnum(feature.type, Att.CATMOR)) {
    1127             case MOR_DLPN:
    1128                 Renderer.symbol(Harbours.Dolphin);
    1129                 break;
    1130             case MOR_DDPN:
    1131                 Renderer.symbol(Harbours.DeviationDolphin);
    1132                 break;
    1133             case MOR_BLRD:
    1134             case MOR_POST:
    1135                 Renderer.symbol(Harbours.Bollard);
    1136                 break;
    1137             case MOR_BUOY:
    1138                 BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
    1139                 if (shape == BoySHP.BOY_UNKN) {
    1140                     shape = BoySHP.BOY_SPHR;
    1141                 }
    1142                 Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
    1143                 Renderer.symbol(Topmarks.TopMooring, Topmarks.BuoyDeltas.get(shape));
    1144                 break;
    1145             default:
    1146                 break;
    1147             }
    1148             Signals.addSignals();
    1149         }
    1150     }
    1151 
    1152     @SuppressWarnings("unchecked")
    1153     private static void notices() {
    1154         if (Renderer.zoom >= 14) {
    1155             double dx = 0.0, dy = 0.0;
    1156             switch (feature.type) {
    1157             case BCNCAR:
    1158             case BCNISD:
    1159             case BCNLAT:
    1160             case BCNSAW:
    1161             case BCNSPP:
    1162                 if (testAttribute(Obj.TOPMAR, Att.TOPSHP, TopSHP.TOP_BORD) || testAttribute(Obj.DAYMAR, Att.TOPSHP, TopSHP.TOP_BORD)) {
    1163                     dy = -100.0;
    1164                 } else {
    1165                     dy = -45.0;
    1166                 }
    1167                 break;
    1168             case NOTMRK:
    1169                 dy = 0.0;
    1170                 break;
    1171             default:
    1172                 return;
    1173             }
    1174             MarSYS sys = MarSYS.SYS_CEVN;
    1175             BnkWTW bnk = BnkWTW.BWW_UNKN;
    1176             AttVal<?> att = feature.atts.get(Att.MARSYS);
    1177             if (att != null) sys = (MarSYS) att.val;
    1178             att = feature.atts.get(Att.BNKWTW);
    1179             if (att != null) bnk = (BnkWTW) att.val;
    1180             ObjTab objs = feature.objs.get(Obj.NOTMRK);
    1181             int n = objs.size();
    1182             if (n > 5) {
    1183                 Renderer.symbol(Notices.Notice, new Delta(Handle.CC, AffineTransform.getTranslateInstance(dx, dy)));
    1184             } else {
    1185                 int i = 0;
    1186                 for (AttMap atts : objs.values()) {
    1187                     if (atts.get(Att.MARSYS) != null) sys = ((ArrayList<MarSYS>) (atts.get(Att.MARSYS).val)).get(0);
    1188                     if (atts.get(Att.BNKWTW) != null) bnk = ((ArrayList<BnkWTW>) (atts.get(Att.BNKWTW).val)).get(0);
    1189                     CatNMK cat = CatNMK.NMK_UNKN;
    1190                     if (atts.get(Att.CATNMK) != null) cat = ((ArrayList<CatNMK>) (atts.get(Att.CATNMK).val)).get(0);
    1191                     Symbol sym = Notices.getNotice(cat, sys, bnk);
    1192                     Scheme sch = Notices.getScheme(sys, bnk);
    1193                     ArrayList<AddMRK> add = new ArrayList<>();
    1194                     if (atts.get(Att.ADDMRK) != null) add = (ArrayList<AddMRK>) (atts.get(Att.ADDMRK).val);
    1195                     Handle h = Handle.CC;
    1196                     double ax = 0.0;
    1197                     double ay = 0.0;
    1198                     switch (i) {
    1199                     case 0:
    1200                         if (n != 1) h = null;
    1201                         break;
    1202                     case 1:
    1203                         if (n <= 3) {
    1204                             h = Handle.RC;
    1205                             ax = -30;
    1206                             ay = dy;
    1207                         } else {
    1208                             h = Handle.BR;
    1209                         }
    1210                         break;
    1211                     case 2:
    1212                         if (n <= 3)
    1213                             h = Handle.LC;
    1214                         else
    1215                             h = Handle.BL;
    1216                         break;
    1217                     case 3:
    1218                         if (n == 4)
    1219                             h = Handle.TC;
    1220                         else
    1221                             h = Handle.TR;
    1222                         break;
    1223                     case 4:
    1224                         h = Handle.TL;
    1225                         break;
    1226                     }
    1227                     if (h != null) {
    1228                         Renderer.symbol(sym, sch, new Delta(h, AffineTransform.getTranslateInstance(dx, dy)));
    1229                         if (!add.isEmpty())
    1230                             Renderer.symbol(Notices.NoticeBoard, new Delta(Handle.BC, AffineTransform.getTranslateInstance(ax, ay - 30)));
    1231                     }
    1232                     i++;
    1233                 }
    1234             }
    1235         }
    1236     }
    1237 
    1238     private static void obstructions() {
    1239         if ((Renderer.zoom >= 12) && (feature.type == Obj.OBSTRN)) {
    1240             if (getAttEnum(feature.type, Att.CATOBS) == CatOBS.OBS_BOOM) {
    1241                 Renderer.lineVector(new LineStyle(Color.black, 5, new float[] {20, 20}, null));
    1242                 if (Renderer.zoom >= 15) {
    1243                     Renderer.lineText("Boom", new Font("Arial", Font.PLAIN, 80), Color.black, -20);
    1244                 }
    1245             }
    1246         }
    1247         if ((Renderer.zoom >= 14) && (feature.type == Obj.UWTROC)) {
    1248             switch ((WatLEV) getAttEnum(feature.type, Att.WATLEV)) {
    1249             case LEV_CVRS:
    1250                 Renderer.symbol(Areas.RockC);
    1251                 break;
    1252             case LEV_AWSH:
    1253                 Renderer.symbol(Areas.RockA);
    1254                 break;
    1255             default:
    1256                 Renderer.symbol(Areas.Rock);
    1257             }
    1258         } else {
    1259             Renderer.symbol(Areas.Rock);
    1260         }
    1261     }
    1262 
    1263     private static void pipelines() {
    1264         if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
    1265             if (feature.type == Obj.PIPSOL) {
    1266                 Renderer.lineSymbols(Areas.Pipeline, 1.0, null, null, 0, Symbols.Mline);
    1267             } else if (feature.type == Obj.PIPOHD) {
    1268                 Renderer.lineVector(new LineStyle(Color.black, 8));
    1269                 AttMap atts = feature.atts;
    1270                 double verclr = 0;
    1271                 if (atts != null) {
    1272                     if (atts.containsKey(Att.VERCLR)) {
    1273                         verclr = (Double) atts.get(Att.VERCLR).val;
    1274                     } else {
    1275                         verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
    1276                     }
    1277                     if (verclr > 0) {
    1278                         Renderer.labelText(String.valueOf(verclr), new Font("Arial", Font.PLAIN, 50), Color.black, LabelStyle.VCLR,
    1279                                 Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
    1280                     }
    1281                 }
    1282             }
    1283         }
    1284     }
    1285 
    1286     @SuppressWarnings("unchecked")
    1287     private static void platforms() {
    1288         ArrayList<CatOFP> cats = (ArrayList<CatOFP>) getAttList(Obj.OFSPLF, Att.CATOFP);
    1289         if (cats.get(0) == CatOFP.OFP_FPSO)
    1290             Renderer.symbol(Buoys.Storage);
    1291         else
    1292             Renderer.symbol(Landmarks.Platform);
    1293         addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
    1294         Signals.addSignals();
    1295     }
    1296 
    1297     private static void ports() {
    1298         if (Renderer.zoom >= 14) {
    1299             if (feature.type == Obj.CRANES) {
    1300                 if ((CatCRN) getAttEnum(feature.type, Att.CATCRN) == CatCRN.CRN_CONT)
    1301                     Renderer.symbol(Harbours.ContainerCrane);
    1302                 else
    1303                     Renderer.symbol(Harbours.PortCrane);
    1304             } else if (feature.type == Obj.HULKES) {
    1305                 Renderer.lineVector(new LineStyle(Color.black, 4, null, new Color(0xffe000)));
    1306                 addName(15, new Font("Arial", Font.BOLD, 40));
    1307             }
    1308         }
    1309     }
    1310 
    1311     private static void separation() {
    1312         switch (feature.type) {
    1313         case TSEZNE:
    1314         case TSSCRS:
    1315         case TSSRON:
    1316             if (Renderer.zoom <= 15)
    1317                 Renderer.lineVector(new LineStyle(Symbols.Mtss));
    1318             else
    1319                 Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
    1320             addName(10, new Font("Arial", Font.BOLD, 150), Symbols.Mline);
    1321             break;
    1322         case TSELNE:
    1323             Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
    1324             break;
    1325         case TSSLPT:
    1326             Renderer.lineSymbols(Areas.LaneArrow, 0.5, null, null, 0, Symbols.Mtss);
    1327             break;
    1328         case TSSBND:
    1329             Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, new float[] {40, 40}, null));
    1330             break;
    1331         case ISTZNE:
    1332             Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mtss);
    1333             break;
    1334         default:
    1335             break;
    1336         }
    1337     }
    1338 
    1339     @SuppressWarnings("unchecked")
    1340     private static void shoreline() {
    1341         CatSLC cat = (CatSLC) getAttEnum(feature.type, Att.CATSLC);
    1342         if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
    1343             if ((cat != CatSLC.SLC_SWAY) && (cat != CatSLC.SLC_TWAL)) {
    1344                 if (Renderer.zoom >= 12) {
    1345                     Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Yland));
    1346                 } else {
    1347                     Renderer.lineVector(new LineStyle(Symbols.Yland));
    1348                 }
    1349             }
    1350         }
    1351         if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
    1352             if (Renderer.zoom >= 12) {
    1353                 switch (cat) {
    1354                 case SLC_TWAL:
    1355                     WatLEV lev = (WatLEV) getAttEnum(feature.type, Att.WATLEV);
    1356                     if (lev == WatLEV.LEV_CVRS) {
    1357                         Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {40, 40}, null));
    1358                         if (Renderer.zoom >= 15)
    1359                             Renderer.lineText("(covers)", new Font("Arial", Font.PLAIN, 60), Color.black, 80);
    1360                     } else {
    1361                         Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
    1362                     }
    1363                     if (Renderer.zoom >= 15)
    1364                         Renderer.lineText("Training Wall", new Font("Arial", Font.PLAIN, 60), Color.black, -30);
    1365                     break;
    1366                 case SLC_SWAY:
    1367                     Renderer.lineVector(new LineStyle(Color.black, 2, null, new Color(0xffe000)));
    1368                     if ((Renderer.zoom >= 16) && feature.objs.containsKey(Obj.SMCFAC)) {
    1369                         ArrayList<Symbol> symbols = new ArrayList<>();
    1370                         ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
    1371                         for (CatSCF scf : scfs) {
    1372                             symbols.add(Facilities.Cats.get(scf));
    1373                         }
    1374                         Renderer.cluster(symbols);
    1375                     }
    1376                     break;
    1377                 default:
    1378                     break;
    1379                 }
    1380             }
    1381         }
    1382     }
    1383 
    1384     @SuppressWarnings("unchecked")
    1385     private static void stations() {
    1386         if (Renderer.zoom >= 14) {
    1387             String str = "";
    1388             switch (feature.type) {
    1389             case SISTAT:
    1390                 Renderer.symbol(Harbours.SignalStation);
    1391                 str = "SS";
    1392                 ArrayList<CatSIT> tcats = (ArrayList<CatSIT>) getAttList(Obj.SISTAT, Att.CATSIT);
    1393                 switch (tcats.get(0)) {
    1394                 case SIT_IPT:
    1395                     str += "(INT)";
    1396                     break;
    1397                 case SIT_PRTE:
    1398                     str += "(Traffic)";
    1399                     break;
    1400                 case SIT_PRTC:
    1401                     str += "(Port Control)";
    1402                     break;
    1403                 case SIT_LOCK:
    1404                     str += "(Lock)";
    1405                     break;
    1406                 case SIT_BRDG:
    1407                     str += "(Bridge)";
    1408                     break;
    1409                 default:
    1410                     break;
    1411                 }
    1412                 break;
    1413             case SISTAW:
    1414                 Renderer.symbol(Harbours.SignalStation);
    1415                 str = "SS";
    1416                 str = "SS";
    1417                 ArrayList<CatSIW> wcats = (ArrayList<CatSIW>) getAttList(Obj.SISTAW, Att.CATSIW);
    1418                 switch (wcats.get(0)) {
    1419                 case SIW_STRM:
    1420                     str += "(Storm)";
    1421                     break;
    1422                 case SIW_WTHR:
    1423                     str += "(Weather)";
    1424                     break;
    1425                 case SIW_ICE:
    1426                     str += "(Ice)";
    1427                     break;
    1428                 case SIW_TIDG:
    1429                     str = "Tide gauge";
    1430                     break;
    1431                 case SIW_TIDS:
    1432                     str = "Tide scale";
    1433                     break;
    1434                 case SIW_TIDE:
    1435                     str += "(Tide)";
    1436                     break;
    1437                 case SIW_TSTR:
    1438                     str += "(Stream)";
    1439                     break;
    1440                 case SIW_DNGR:
    1441                     str += "(Danger)";
    1442                     break;
    1443                 case SIW_MILY:
    1444                     str += "(Firing)";
    1445                     break;
    1446                 case SIW_TIME:
    1447                     str += "(Time)";
    1448                     break;
    1449                 default:
    1450                     break;
    1451                 }
    1452                 break;
    1453             case RDOSTA:
    1454             case RTPBCN:
    1455                 Renderer.symbol(Harbours.SignalStation);
    1456                 Renderer.symbol(Beacons.RadarStation);
    1457                 break;
    1458             case RADRFL:
    1459                 Renderer.symbol(Topmarks.RadarReflector);
    1460                 break;
    1461             case RADSTA:
    1462                 Renderer.symbol(Harbours.SignalStation);
    1463                 Renderer.symbol(Beacons.RadarStation);
    1464                 Renderer.labelText("Ra", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb,
    1465                         new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
    1466                 break;
    1467             case PILBOP:
    1468                 Renderer.symbol(Harbours.Pilot);
    1469                 addName(15, new Font("Arial", Font.BOLD, 40), Symbols.Msymb,
    1470                         new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, -40)));
    1471                 CatPIL cat = (CatPIL) getAttEnum(feature.type, Att.CATPIL);
    1472                 if (cat == CatPIL.PIL_HELI) {
    1473                     Renderer.labelText("H", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb,
    1474                             new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
    1475                 }
    1476                 break;
    1477             case CGUSTA:
    1478                 Renderer.symbol(Harbours.SignalStation);
    1479                 str = "CG";
    1480                 if (feature.objs.containsKey(Obj.RSCSTA)) Renderer.symbol(Harbours.Rescue,
    1481                         new Delta(Handle.CC, AffineTransform.getTranslateInstance(130, 0)));
    1482                 break;
    1483             case RSCSTA:
    1484                 Renderer.symbol(Harbours.Rescue);
    1485                 break;
    1486             default:
    1487                 break;
    1488             }
    1489             if ((Renderer.zoom >= 15) && !str.isEmpty()) {
    1490                 Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black,
    1491                         new Delta(Handle.LC, AffineTransform.getTranslateInstance(40, 0)));
    1492             }
    1493             Signals.addSignals();
    1494         }
    1495     }
    1496 
    1497     private static void transits() {
    1498         if (Renderer.zoom >= 14) {
    1499             if (feature.type == Obj.RECTRC) Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
    1500             else if (feature.type == Obj.NAVLNE) Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {25, 25}, null));
    1501         }
    1502         if (Renderer.zoom >= 15) {
    1503             String str = "";
    1504             String name = getName();
    1505             if (name != null)
    1506                 str += name + " ";
    1507             Double ort;
    1508             if ((ort = (Double) getAttVal(feature.type, Att.ORIENT)) != null) {
    1509                 str += df.format(ort) + "º";
    1510                 if (!str.isEmpty())
    1511                     Renderer.lineText(str, new Font("Arial", Font.PLAIN, 80), Color.black, -20);
    1512             }
    1513         }
    1514     }
    1515 
    1516     private static void waterways() {
    1517         Renderer.lineVector(new LineStyle(Symbols.Bwater, 20, (feature.geom.prim == Pflag.AREA) ? Symbols.Bwater : null));
    1518     }
    1519 
    1520     private static void wrecks() {
    1521         if (Renderer.zoom >= 14) {
    1522             switch ((CatWRK) getAttEnum(feature.type, Att.CATWRK)) {
    1523             case WRK_DNGR:
    1524             case WRK_MSTS:
    1525                 Renderer.symbol(Areas.WreckD);
    1526                 break;
    1527             case WRK_HULS:
    1528                 Renderer.symbol(Areas.WreckS);
    1529                 break;
    1530             default:
    1531                 Renderer.symbol(Areas.WreckND);
    1532             }
    1533         }
    1534     }
     82        static final DecimalFormat df = new DecimalFormat("#.#");
     83
     84        static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<>(ColCOL.class);
     85        static {
     86                bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
     87                bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
     88                bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
     89                bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
     90                bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
     91                bodyColours.put(ColCOL.COL_BLU, Color.blue);
     92                bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
     93                bodyColours.put(ColCOL.COL_GRY, Color.gray);
     94                bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
     95                bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
     96                bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
     97                bodyColours.put(ColCOL.COL_ORG, Color.orange);
     98                bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
     99                bodyColours.put(ColCOL.COL_PNK, Color.pink);
     100        }
     101
     102        static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<>(ColPAT.class);
     103        static {
     104                pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
     105                pattMap.put(ColPAT.PAT_HORI, Patt.H);
     106                pattMap.put(ColPAT.PAT_VERT, Patt.V);
     107                pattMap.put(ColPAT.PAT_DIAG, Patt.D);
     108                pattMap.put(ColPAT.PAT_BRDR, Patt.B);
     109                pattMap.put(ColPAT.PAT_SQUR, Patt.S);
     110                pattMap.put(ColPAT.PAT_CROS, Patt.C);
     111                pattMap.put(ColPAT.PAT_SALT, Patt.X);
     112                pattMap.put(ColPAT.PAT_STRP, Patt.H);
     113        }
     114
     115        static String getName() {
     116                AttVal<?> name = feature.atts.get(Att.OBJNAM);
     117                if (name == null) {
     118                        AttMap atts = feature.objs.get(feature.type).get(0);
     119                        if (atts != null) {
     120                                name = atts.get(Att.OBJNAM);
     121                        }
     122                }
     123                return (name != null) ? (String) name.val : null;
     124        }
     125
     126        public static void addName(int z, Font font) {
     127                addName(z, font, Color.black, new Delta(Handle.CC, new AffineTransform()));
     128        }
     129
     130        public static void addName(int z, Font font, Color colour) {
     131                addName(z, font, colour, new Delta(Handle.CC, new AffineTransform()));
     132        }
     133
     134        public static void addName(int z, Font font, Delta delta) {
     135                addName(z, font, Color.black, delta);
     136        }
     137
     138        public static void addName(int z, Font font, Color colour, Delta delta) {
     139                if (Renderer.zoom >= z) {
     140                        String name = getName();
     141                        if (name != null) {
     142                                Renderer.labelText(name, font, colour, delta);
     143                        }
     144                }
     145        }
     146
     147        static AttMap getAtts(Obj obj, int idx) {
     148                HashMap<Integer, AttMap> objs = feature.objs.get(obj);
     149                if (objs == null)
     150                        return null;
     151                else
     152                        return objs.get(idx);
     153        }
     154
     155        public static Object getAttVal(Obj obj, Att att) {
     156                AttMap atts;
     157                HashMap<Integer, AttMap> objs;
     158                AttVal<?> item;
     159                if ((objs = feature.objs.get(obj)) != null)
     160                        atts = objs.get(0);
     161                else
     162                        return null;
     163                if ((item = atts.get(att)) == null)
     164                        return null;
     165                else
     166                        return item.val;
     167        }
     168
     169        public static String getAttStr(Obj obj, Att att) {
     170                String str = (String) getAttVal(obj, att);
     171                if (str != null) {
     172                        return str;
     173                }
     174                return "";
     175        }
     176
     177        @SuppressWarnings("unchecked")
     178        public static Enum<?> getAttEnum(Obj obj, Att att) {
     179                ArrayList<?> list = (ArrayList<?>) getAttVal(obj, att);
     180                if (list != null) {
     181                        return ((ArrayList<Enum<?>>) list).get(0);
     182                }
     183                return S57val.unknAtt(att);
     184        }
     185
     186        @SuppressWarnings("unchecked")
     187        public static ArrayList<?> getAttList(Obj obj, Att att) {
     188                ArrayList<Enum<?>> list = (ArrayList<Enum<?>>) getAttVal(obj, att);
     189                if (list != null) {
     190                        return list;
     191                }
     192                list = new ArrayList<>();
     193                list.add(S57val.unknAtt(att));
     194                return list;
     195        }
     196
     197        @SuppressWarnings("unchecked")
     198        static Scheme getScheme(Obj obj) {
     199                ArrayList<Color> colours = new ArrayList<>();
     200                for (ColCOL col : (ArrayList<ColCOL>) getAttList(obj, Att.COLOUR)) {
     201                        colours.add(bodyColours.get(col));
     202                }
     203                ArrayList<Patt> patterns = new ArrayList<>();
     204                for (ColPAT pat : (ArrayList<ColPAT>) getAttList(obj, Att.COLPAT)) {
     205                        patterns.add(pattMap.get(pat));
     206                }
     207                return new Scheme(patterns, colours);
     208        }
     209
     210        static boolean hasAttribute(Obj obj, Att att) {
     211                AttMap atts;
     212                if ((atts = getAtts(obj, 0)) != null) {
     213                        AttVal<?> item = atts.get(att);
     214                        return item != null;
     215                }
     216                return false;
     217        }
     218
     219        static boolean testAttribute(Obj obj, Att att, Object val) {
     220                AttMap atts;
     221                if ((atts = getAtts(obj, 0)) != null) {
     222                        AttVal<?> item = atts.get(att);
     223                        if (item != null) {
     224                                switch (item.conv) {
     225                                case S:
     226                                case A:
     227                                        return ((String) item.val).equals(val);
     228                                case E:
     229                                case L:
     230                                        return ((ArrayList<?>) item.val).contains(val);
     231                                case F:
     232                                case I:
     233                                        return item.val == val;
     234                                }
     235                        }
     236                }
     237                return false;
     238        }
     239
     240        static boolean hasObject(Obj obj) {
     241                return (feature.objs.containsKey(obj));
     242        }
     243
     244        public static Feature feature;
     245        static ArrayList<Feature> objects;
     246
     247        static boolean testObject(Obj obj) {
     248                return ((objects = Renderer.map.features.get(obj)) != null);
     249        }
     250
     251        static boolean testFeature(Feature f) {
     252                return ((feature = f).reln == Rflag.MASTER);
     253        }
     254
     255        public static boolean rules() {
     256                try {
     257                        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
     258                                if (testObject(Obj.LNDARE)) for (Feature f : objects) if (testFeature(f)) areas();
     259                                if (testObject(Obj.BUAARE)) for (Feature f : objects) if (testFeature(f)) areas();
     260                                if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) areas();
     261                                if (testObject(Obj.HRBBSN)) for (Feature f : objects) if (testFeature(f)) areas();
     262                                if (testObject(Obj.LOKBSN)) for (Feature f : objects) if (testFeature(f)) areas();
     263                                if (testObject(Obj.LKBSPT)) for (Feature f : objects) if (testFeature(f)) areas();
     264                                if (testObject(Obj.LAKARE)) for (Feature f : objects) if (testFeature(f)) areas();
     265                                if (testObject(Obj.RIVERS)) for (Feature f : objects) if (testFeature(f)) waterways();
     266                                if (testObject(Obj.CANALS)) for (Feature f : objects) if (testFeature(f)) waterways();
     267                                if (testObject(Obj.DEPARE)) for (Feature f : objects) if (testFeature(f)) areas();
     268                                if (testObject(Obj.COALNE)) for (Feature f : objects) if (testFeature(f)) areas();
     269                                if (testObject(Obj.ROADWY)) for (Feature f : objects) if (testFeature(f)) highways();
     270                                if (testObject(Obj.RAILWY)) for (Feature f : objects) if (testFeature(f)) highways();
     271                        }
     272                        if (Renderer.context.ruleset() == RuleSet.ALL) {
     273                                if (testObject(Obj.SOUNDG)) for (Feature f : objects) if (testFeature(f)) depths();
     274                                if (testObject(Obj.DEPCNT)) for (Feature f : objects) if (testFeature(f)) depths();
     275                        }
     276                        if (testObject(Obj.SLCONS)) for (Feature f : objects) if (testFeature(f)) shoreline();
     277                        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
     278                                if (testObject(Obj.PIPSOL)) for (Feature f : objects) if (testFeature(f)) pipelines();
     279                                if (testObject(Obj.CBLSUB)) for (Feature f : objects) if (testFeature(f)) cables();
     280                                if (testObject(Obj.PIPOHD)) for (Feature f : objects) if (testFeature(f)) pipelines();
     281                                if (testObject(Obj.CBLOHD)) for (Feature f : objects) if (testFeature(f)) cables();
     282                                if (testObject(Obj.TSEZNE)) for (Feature f : objects) if (testFeature(f)) separation();
     283                                if (testObject(Obj.TSSCRS)) for (Feature f : objects) if (testFeature(f)) separation();
     284                                if (testObject(Obj.TSSRON)) for (Feature f : objects) if (testFeature(f)) separation();
     285                                if (testObject(Obj.TSELNE)) for (Feature f : objects) if (testFeature(f)) separation();
     286                                if (testObject(Obj.TSSLPT)) for (Feature f : objects) if (testFeature(f)) separation();
     287                                if (testObject(Obj.TSSBND)) for (Feature f : objects) if (testFeature(f)) separation();
     288                                if (testObject(Obj.ISTZNE)) for (Feature f : objects) if (testFeature(f)) separation();
     289                                if (testObject(Obj.SNDWAV)) for (Feature f : objects) if (testFeature(f)) areas();
     290                                if (testObject(Obj.WEDKLP)) for (Feature f : objects) if (testFeature(f)) areas();
     291                                if (testObject(Obj.OSPARE)) for (Feature f : objects) if (testFeature(f)) areas();
     292                                if (testObject(Obj.FAIRWY)) for (Feature f : objects) if (testFeature(f)) areas();
     293                                if (testObject(Obj.DRGARE)) for (Feature f : objects) if (testFeature(f)) areas();
     294                                if (testObject(Obj.RESARE)) for (Feature f : objects) if (testFeature(f)) areas();
     295                                if (testObject(Obj.PRCARE)) for (Feature f : objects) if (testFeature(f)) areas();
     296                                if (testObject(Obj.SPLARE)) for (Feature f : objects) if (testFeature(f)) areas();
     297                                if (testObject(Obj.SEAARE)) for (Feature f : objects) if (testFeature(f)) areas();
     298                                if (testObject(Obj.OBSTRN)) for (Feature f : objects) if (testFeature(f)) obstructions();
     299                                if (testObject(Obj.UWTROC)) for (Feature f : objects) if (testFeature(f)) obstructions();
     300                                if (testObject(Obj.MARCUL)) for (Feature f : objects) if (testFeature(f)) areas();
     301                                if (testObject(Obj.RECTRC)) for (Feature f : objects) if (testFeature(f)) transits();
     302                                if (testObject(Obj.NAVLNE)) for (Feature f : objects) if (testFeature(f)) transits();
     303                                if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) harbours();
     304                                if (testObject(Obj.ACHARE)) for (Feature f : objects) if (testFeature(f)) harbours();
     305                                if (testObject(Obj.ACHBRT)) for (Feature f : objects) if (testFeature(f)) harbours();
     306                                if (testObject(Obj.BERTHS)) for (Feature f : objects) if (testFeature(f)) harbours();
     307                                if (testObject(Obj.DISMAR)) for (Feature f : objects) if (testFeature(f)) distances();
     308                                if (testObject(Obj.HULKES)) for (Feature f : objects) if (testFeature(f)) ports();
     309                                if (testObject(Obj.CRANES)) for (Feature f : objects) if (testFeature(f)) ports();
     310                                if (testObject(Obj.LNDMRK)) for (Feature f : objects) if (testFeature(f)) landmarks();
     311                                if (testObject(Obj.SILTNK)) for (Feature f : objects) if (testFeature(f)) landmarks();
     312                                if (testObject(Obj.BUISGL)) for (Feature f : objects) if (testFeature(f)) harbours();
     313                                if (testObject(Obj.MORFAC)) for (Feature f : objects) if (testFeature(f)) moorings();
     314                                if (testObject(Obj.NOTMRK)) for (Feature f : objects) if (testFeature(f)) notices();
     315                                if (testObject(Obj.SMCFAC)) for (Feature f : objects) if (testFeature(f)) marinas();
     316                                if (testObject(Obj.BRIDGE)) for (Feature f : objects) if (testFeature(f)) bridges();
     317                                if (testObject(Obj.PILPNT)) for (Feature f : objects) if (testFeature(f)) points();
     318                                if (testObject(Obj.TOPMAR)) for (Feature f : objects) if (testFeature(f)) points();
     319                                if (testObject(Obj.DAYMAR)) for (Feature f : objects) if (testFeature(f)) points();
     320                                if (testObject(Obj.FOGSIG)) for (Feature f : objects) if (testFeature(f)) points();
     321                                if (testObject(Obj.RDOCAL)) for (Feature f : objects) if (testFeature(f)) callpoint();
     322                                if (testObject(Obj.LITMIN)) for (Feature f : objects) if (testFeature(f)) lights();
     323                                if (testObject(Obj.LITMAJ)) for (Feature f : objects) if (testFeature(f)) lights();
     324                                if (testObject(Obj.LIGHTS)) for (Feature f : objects) if (testFeature(f)) lights();
     325                                if (testObject(Obj.SISTAT)) for (Feature f : objects) if (testFeature(f)) stations();
     326                                if (testObject(Obj.SISTAW)) for (Feature f : objects) if (testFeature(f)) stations();
     327                                if (testObject(Obj.CGUSTA)) for (Feature f : objects) if (testFeature(f)) stations();
     328                                if (testObject(Obj.RDOSTA)) for (Feature f : objects) if (testFeature(f)) stations();
     329                                if (testObject(Obj.RADRFL)) for (Feature f : objects) if (testFeature(f)) stations();
     330                                if (testObject(Obj.RADSTA)) for (Feature f : objects) if (testFeature(f)) stations();
     331                                if (testObject(Obj.RTPBCN)) for (Feature f : objects) if (testFeature(f)) stations();
     332                                if (testObject(Obj.RSCSTA)) for (Feature f : objects) if (testFeature(f)) stations();
     333                                if (testObject(Obj.PILBOP)) for (Feature f : objects) if (testFeature(f)) stations();
     334                                if (testObject(Obj.WTWGAG)) for (Feature f : objects) if (testFeature(f)) gauges();
     335                                if (testObject(Obj.OFSPLF)) for (Feature f : objects) if (testFeature(f)) platforms();
     336                                if (testObject(Obj.WRECKS)) for (Feature f : objects) if (testFeature(f)) wrecks();
     337                                if (testObject(Obj.LITVES)) for (Feature f : objects) if (testFeature(f)) floats();
     338                                if (testObject(Obj.LITFLT)) for (Feature f : objects) if (testFeature(f)) floats();
     339                                if (testObject(Obj.BOYINB)) for (Feature f : objects) if (testFeature(f)) floats();
     340                                if (testObject(Obj.BOYLAT)) for (Feature f : objects) if (testFeature(f)) buoys();
     341                                if (testObject(Obj.BOYCAR)) for (Feature f : objects) if (testFeature(f)) buoys();
     342                                if (testObject(Obj.BOYISD)) for (Feature f : objects) if (testFeature(f)) buoys();
     343                                if (testObject(Obj.BOYSAW)) for (Feature f : objects) if (testFeature(f)) buoys();
     344                                if (testObject(Obj.BOYSPP)) for (Feature f : objects) if (testFeature(f)) buoys();
     345                                if (testObject(Obj.BCNLAT)) for (Feature f : objects) if (testFeature(f)) beacons();
     346                                if (testObject(Obj.BCNCAR)) for (Feature f : objects) if (testFeature(f)) beacons();
     347                                if (testObject(Obj.BCNISD)) for (Feature f : objects) if (testFeature(f)) beacons();
     348                                if (testObject(Obj.BCNSAW)) for (Feature f : objects) if (testFeature(f)) beacons();
     349                                if (testObject(Obj.BCNSPP)) for (Feature f : objects) if (testFeature(f)) beacons();
     350                        }
     351                } catch (ConcurrentModificationException e) {
     352                        return false;
     353                } catch (Exception e) {
     354                        return true;
     355                }
     356                return true;
     357        }
     358
     359        private static void areas() {
     360                String name = getName();
     361                switch (feature.type) {
     362                case BUAARE:
     363                        Renderer.lineVector(new LineStyle(new Color(0x20000000, true)));
     364                        break;
     365                case COALNE:
     366                        if (Renderer.zoom >= 12)
     367                                Renderer.lineVector(new LineStyle(Color.black, 10));
     368                        break;
     369                case DEPARE:
     370                        Double depmax = 0.0;
     371                        if (((depmax = (Double) getAttVal(Obj.DEPARE, Att.DRVAL2)) != null) && (depmax <= 0.0)) {
     372                                Renderer.lineVector(new LineStyle(Symbols.Gdries));
     373                        }
     374                        break;
     375                case LAKARE:
     376                        if ((Renderer.zoom >= 12) || (feature.geom.area > 10.0))
     377                                Renderer.lineVector(new LineStyle(Symbols.Bwater));
     378                        break;
     379                case DRGARE:
     380                        if (Renderer.zoom < 16)
     381                                Renderer.lineVector(new LineStyle(Color.black, 8, new float[] { 25, 25 }, new Color(0x40ffffff, true)));
     382                        else
     383                                Renderer.lineVector(new LineStyle(Color.black, 8, new float[] { 25, 25 }));
     384                        addName(12, new Font("Arial", Font.PLAIN, 100), new Delta(Handle.CC, new AffineTransform()));
     385                        break;
     386                case FAIRWY:
     387                        if (feature.geom.area > 2.0) {
     388                                if (Renderer.zoom < 16)
     389                                        Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] { 50, 50 }, new Color(0x40ffffff, true)));
     390                                else
     391                                        Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] { 50, 50 }));
     392                        } else {
     393                                if (Renderer.zoom >= 14)
     394                                        Renderer.lineVector(new LineStyle(new Color(0x40ffffff, true)));
     395                        }
     396                        break;
     397                case LKBSPT:
     398                case LOKBSN:
     399                case HRBBSN:
     400                        if (Renderer.zoom >= 12) {
     401                                Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
     402                        } else {
     403                                Renderer.lineVector(new LineStyle(Symbols.Bwater));
     404                        }
     405                        break;
     406                case HRBFAC:
     407                        if (feature.objs.get(Obj.HRBBSN) != null) {
     408                                if (Renderer.zoom >= 12) {
     409                                        Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
     410                                } else {
     411                                        Renderer.lineVector(new LineStyle(Symbols.Bwater));
     412                                }
     413                        }
     414                        break;
     415                case LNDARE:
     416                        Renderer.lineVector(new LineStyle(Symbols.Yland));
     417                        break;
     418                case MARCUL:
     419                        if (Renderer.zoom >= 12) {
     420                                if (Renderer.zoom >= 14) {
     421                                        Renderer.symbol(Areas.MarineFarm);
     422                                }
     423                                if ((feature.geom.area > 0.2) || ((feature.geom.area > 0.05) && (Renderer.zoom >= 14)) || ((feature.geom.area > 0.005) && (Renderer.zoom >= 16))) {
     424                                        Renderer.lineVector(new LineStyle(Color.black, 4, new float[] { 10, 10 }));
     425                                }
     426                        }
     427                        break;
     428                case OSPARE:
     429                        if (testAttribute(feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
     430                                Renderer.symbol(Areas.WindFarm);
     431                                Renderer.lineVector(new LineStyle(Color.black, 20, new float[] { 40, 40 }));
     432                                addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
     433                        }
     434                        break;
     435                case RESARE:
     436                case MIPARE:
     437                        if (Renderer.zoom >= 12) {
     438                                Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mline);
     439                                if (testAttribute(feature.type, Att.CATREA, CatREA.REA_NWAK)) {
     440                                        Renderer.symbol(Areas.NoWake);
     441                                }
     442                        }
     443                        break;
     444                case PRCARE:
     445                        if (Renderer.zoom >= 12) {
     446                                Renderer.lineVector(new LineStyle(Symbols.Mline, 10, new float[] { 40, 40 }));
     447                        }
     448                        break;
     449                case SEAARE:
     450                        switch ((CatSEA) getAttEnum(feature.type, Att.CATSEA)) {
     451                        case SEA_RECH:
     452                                if ((Renderer.zoom >= 10) && (name != null))
     453                                        if (feature.geom.prim == Pflag.LINE) {
     454                                                Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
     455                                        } else {
     456                                                Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
     457                                        }
     458                                break;
     459                        case SEA_BAY:
     460                                if ((Renderer.zoom >= 12) && (name != null))
     461                                        if (feature.geom.prim == Pflag.LINE) {
     462                                                Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
     463                                        } else {
     464                                                Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
     465                                        }
     466                                break;
     467                        case SEA_SHOL:
     468                                if (Renderer.zoom >= 14) {
     469                                        if (feature.geom.prim == Pflag.AREA) {
     470                                                Renderer.lineVector(new LineStyle(new Color(0xc480ff), 4, new float[] { 25, 25 }));
     471                                                if (name != null) {
     472                                                        Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
     473                                                        Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
     474                                                }
     475                                        } else if (feature.geom.prim == Pflag.LINE) {
     476                                                if (name != null) {
     477                                                        Renderer.lineText(name, new Font("Arial", Font.ITALIC, 75), Color.black, -40);
     478                                                        Renderer.lineText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, 0);
     479                                                }
     480                                        } else {
     481                                                if (name != null) {
     482                                                        Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
     483                                                        Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
     484                                                }
     485                                        }
     486                                }
     487                                break;
     488                        case SEA_GAT:
     489                        case SEA_NRRW:
     490                                addName(12, new Font("Arial", Font.PLAIN, 100));
     491                                break;
     492                        default:
     493                                break;
     494                        }
     495                        break;
     496                case SNDWAV:
     497                        if (Renderer.zoom >= 12)
     498                                Renderer.fillPattern(Areas.Sandwaves);
     499                        break;
     500                case WEDKLP:
     501                        if (Renderer.zoom >= 12) {
     502                                switch ((CatWED) getAttEnum(feature.type, Att.CATWED)) {
     503                                case WED_KELP:
     504                                        if (feature.geom.prim == Pflag.AREA) {
     505                                                Renderer.fillPattern(Areas.KelpA);
     506                                        } else {
     507                                                Renderer.symbol(Areas.KelpS);
     508                                        }
     509                                        break;
     510                                default:
     511                                        break;
     512                                }
     513                        }
     514                        break;
     515                case SPLARE:
     516                        if (Renderer.zoom >= 12) {
     517                                Renderer.symbol(Areas.Plane, new Scheme(Symbols.Msymb));
     518                                Renderer.lineSymbols(Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Symbols.Mline);
     519                        }
     520                        addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
     521                        break;
     522                default:
     523                        break;
     524                }
     525        }
     526
     527        @SuppressWarnings("unchecked")
     528        private static void beacons() {
     529                if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR))) || ((Renderer.zoom >= 11) && ((feature.type == Obj.BCNSAW) || hasObject(Obj.RTPBCN)))) {
     530                        BcnSHP shape = (BcnSHP) getAttEnum(feature.type, Att.BCNSHP);
     531                        if (shape == BcnSHP.BCN_UNKN)
     532                                shape = BcnSHP.BCN_PILE;
     533                        if ((shape == BcnSHP.BCN_WTHY) && (feature.type == Obj.BCNLAT)) {
     534                                switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
     535                                case LAM_PORT:
     536                                        Renderer.symbol(Beacons.WithyPort);
     537                                        break;
     538                                case LAM_STBD:
     539                                        Renderer.symbol(Beacons.WithyStarboard);
     540                                        break;
     541                                default:
     542                                        Renderer.symbol(Beacons.Stake, getScheme(feature.type));
     543                                }
     544                        } else if ((shape == BcnSHP.BCN_PRCH) && (feature.type == Obj.BCNLAT) && !(feature.objs.containsKey(Obj.TOPMAR))) {
     545                                switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
     546                                case LAM_PORT:
     547                                        Renderer.symbol(Beacons.PerchPort);
     548                                        break;
     549                                case LAM_STBD:
     550                                        Renderer.symbol(Beacons.PerchStarboard);
     551                                        break;
     552                                default:
     553                                        Renderer.symbol(Beacons.Stake, getScheme(feature.type));
     554                                }
     555                        } else {
     556                                Renderer.symbol(Beacons.Shapes.get(shape), getScheme(feature.type));
     557                                if (feature.objs.containsKey(Obj.TOPMAR)) {
     558                                        AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     559                                        if (topmap.containsKey(Att.TOPSHP)) {
     560                                                Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BeaconDelta);
     561                                        }
     562                                } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     563                                        AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     564                                        if (topmap.containsKey(Att.TOPSHP)) {
     565                                                Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BeaconDelta);
     566                                        }
     567                                }
     568                        }
     569                        if (hasObject(Obj.NOTMRK))
     570                                notices();
     571                        addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
     572                        Signals.addSignals();
     573                }
     574        }
     575
     576        @SuppressWarnings("unchecked")
     577        private static void buoys() {
     578                if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR))) || ((Renderer.zoom >= 11) && ((feature.type == Obj.BOYSAW) || hasObject(Obj.RTPBCN)))) {
     579                        BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
     580                        if (shape == BoySHP.BOY_UNKN)
     581                                shape = BoySHP.BOY_PILR;
     582                        Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
     583                        if (feature.objs.containsKey(Obj.TOPMAR)) {
     584                                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     585                                if (topmap.containsKey(Att.TOPSHP)) {
     586                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
     587                                }
     588                        } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     589                                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     590                                if (topmap.containsKey(Att.TOPSHP)) {
     591                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BuoyDeltas.get(shape));
     592                                }
     593                        }
     594                        addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
     595                        Signals.addSignals();
     596                }
     597        }
     598
     599        private static void bridges() {
     600                if (Renderer.zoom >= 16) {
     601                        double verclr, verccl, vercop, horclr;
     602                        AttMap atts = feature.objs.get(Obj.BRIDGE).get(0);
     603                        String vstr = "";
     604                        String hstr = "";
     605                        if (atts != null) {
     606                                if (atts.containsKey(Att.HORCLR)) {
     607                                        horclr = (Double) atts.get(Att.HORCLR).val;
     608                                        hstr = String.valueOf(horclr);
     609                                }
     610                                if (atts.containsKey(Att.VERCLR)) {
     611                                        verclr = (Double) atts.get(Att.VERCLR).val;
     612                                } else {
     613                                        verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
     614                                }
     615                                verccl = atts.containsKey(Att.VERCCL) ? (Double) atts.get(Att.VERCCL).val : 0;
     616                                vercop = atts.containsKey(Att.VERCOP) ? (Double) atts.get(Att.VERCOP).val : 0;
     617                                if (verclr > 0) {
     618                                        vstr += String.valueOf(verclr);
     619                                } else if (verccl > 0) {
     620                                        if (vercop == 0) {
     621                                                vstr += String.valueOf(verccl) + "/-";
     622                                        } else {
     623                                                vstr += String.valueOf(verccl) + "/" + String.valueOf(vercop);
     624                                        }
     625                                }
     626                                if (hstr.isEmpty() && !vstr.isEmpty()) {
     627                                        Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.CC));
     628                                } else if (!hstr.isEmpty() && !vstr.isEmpty()) {
     629                                        Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.BC));
     630                                        Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.TC));
     631                                } else if (!hstr.isEmpty() && vstr.isEmpty()) {
     632                                        Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.CC));
     633                                }
     634                        }
     635                }
     636        }
     637
     638        private static void cables() {
     639                if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
     640                        if (feature.type == Obj.CBLSUB) {
     641                                Renderer.lineSymbols(Areas.Cable, 0.0, null, null, 0, Symbols.Mline);
     642                        } else if (feature.type == Obj.CBLOHD) {
     643                                AttMap atts = feature.objs.get(Obj.CBLOHD).get(0);
     644                                if ((atts != null) && (atts.containsKey(Att.CATCBL)) && (atts.get(Att.CATCBL).val == CatCBL.CBL_POWR)) {
     645                                        Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, Areas.CableFlash, 2, Color.black);
     646                                } else {
     647                                        Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, null, 2, Color.black);
     648                                }
     649                                if (atts != null) {
     650                                        if (atts.containsKey(Att.VERCLR)) {
     651                                                Renderer.labelText(String.valueOf(atts.get(Att.VERCLR).val), new Font("Arial", Font.PLAIN, 50), Color.black, LabelStyle.VCLR, Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
     652                                        } else if (atts.containsKey(Att.VERCSA)) {
     653                                                Renderer.labelText(String.valueOf(atts.get(Att.VERCSA).val), new Font("Arial", Font.PLAIN, 50), Color.black, LabelStyle.PCLR, Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
     654                                        }
     655                                }
     656                        }
     657                }
     658        }
     659
     660        private static void callpoint() {
     661                if (Renderer.zoom >= 14) {
     662                        Symbol symb = Harbours.CallPoint2;
     663                        TrfTRF trf = (TrfTRF) getAttEnum(feature.type, Att.TRAFIC);
     664                        if (trf != TrfTRF.TRF_TWOW) {
     665                                symb = Harbours.CallPoint1;
     666                        }
     667                        Double orient = 0.0;
     668                        if ((orient = (Double) getAttVal(feature.type, Att.ORIENT)) == null) {
     669                                orient = 0.0;
     670                        }
     671                        Renderer.symbol(symb, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(orient))));
     672                        String chn;
     673                        if (!(chn = getAttStr(feature.type, Att.COMCHA)).isEmpty()) {
     674                                Renderer.labelText(("Ch." + chn), new Font("Arial", Font.PLAIN, 50), Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 50)));
     675                        }
     676                }
     677        }
     678
     679        private static void depths() {
     680                switch (feature.type) {
     681                case SOUNDG:
     682                        if ((Renderer.zoom >= 14) && hasAttribute(Obj.SOUNDG, Att.VALSOU)) {
     683                                double depth = (double) getAttVal(Obj.SOUNDG, Att.VALSOU);
     684                                String dstr = df.format(depth);
     685                                String[] tok = dstr.split("[-.]");
     686                                String ul = "";
     687                                String id = tok[0];
     688                                String dd = "";
     689                                if (tok[0].equals("")) {
     690                                        for (int i = 0; i < tok[1].length(); i++) {
     691                                                ul += "_";
     692                                        }
     693                                        id = tok[1];
     694                                        dd = (tok.length == 3) ? tok[2] : "";
     695                                } else {
     696                                        dd = (tok.length == 2) ? tok[1] : "";
     697                                }
     698                                Renderer.labelText(ul, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 15)));
     699                                Renderer.labelText(id, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 0)));
     700                                Renderer.labelText(dd, new Font("Arial", Font.PLAIN, 20), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(15, 10)));
     701                        }
     702                        break;
     703                case DEPCNT:
     704                        break;
     705                default:
     706                        break;
     707                }
     708        }
     709
     710        private static void distances() {
     711                if (Renderer.zoom >= 14) {
     712                        if (!testAttribute(Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
     713                                Renderer.symbol(Harbours.DistanceI);
     714                        } else {
     715                                Renderer.symbol(Harbours.DistanceU);
     716                        }
     717                        if (Renderer.zoom >= 15) {
     718                                AttMap atts = getAtts(Obj.DISMAR, 0);
     719                                if ((atts != null) && (atts.containsKey(Att.WTWDIS))) {
     720                                        Double dist = (Double) atts.get(Att.WTWDIS).val;
     721                                        String str = "";
     722                                        if (atts.containsKey(Att.HUNITS)) {
     723                                                switch ((UniHLU) getAttEnum(Obj.DISMAR, Att.HUNITS)) {
     724                                                case HLU_METR:
     725                                                        str += "m ";
     726                                                        break;
     727                                                case HLU_FEET:
     728                                                        str += "ft ";
     729                                                        break;
     730                                                case HLU_HMTR:
     731                                                        str += "hm ";
     732                                                        break;
     733                                                case HLU_KMTR:
     734                                                        str += "km ";
     735                                                        break;
     736                                                case HLU_SMIL:
     737                                                        str += "M ";
     738                                                        break;
     739                                                case HLU_NMIL:
     740                                                        str += "NM ";
     741                                                        break;
     742                                                default:
     743                                                        break;
     744                                                }
     745                                        }
     746                                        str += String.format("%1.0f", dist);
     747                                        Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
     748                                }
     749                        }
     750                }
     751        }
     752
     753        @SuppressWarnings("unchecked")
     754        private static void floats() {
     755                if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) || (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
     756                        switch (feature.type) {
     757                        case LITVES:
     758                                Renderer.symbol(Buoys.Super, getScheme(feature.type));
     759                                break;
     760                        case LITFLT:
     761                                Renderer.symbol(Buoys.Float, getScheme(feature.type));
     762                                break;
     763                        case BOYINB:
     764                                Renderer.symbol(Buoys.Super, getScheme(feature.type));
     765                                break;
     766                        default:
     767                                break;
     768                        }
     769                        if (feature.objs.containsKey(Obj.TOPMAR)) {
     770                                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     771                                if (topmap.containsKey(Att.TOPSHP)) {
     772                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.FloatDelta);
     773                                }
     774                        } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     775                                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     776                                if (topmap.containsKey(Att.TOPSHP)) {
     777                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.FloatDelta);
     778                                }
     779                        }
     780                        addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
     781                        Signals.addSignals();
     782                }
     783        }
     784
     785        private static void gauges() {
     786                if (Renderer.zoom >= 14) {
     787                        Renderer.symbol(Harbours.TideGauge);
     788                        addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
     789                        Signals.addSignals();
     790                }
     791        }
     792
     793        @SuppressWarnings("unchecked")
     794        private static void harbours() {
     795                String name = getName();
     796                switch (feature.type) {
     797                case ACHBRT:
     798                        if (Renderer.zoom >= 14) {
     799                                Renderer.symbol(Harbours.Anchor, new Scheme(Symbols.Msymb));
     800                                if (Renderer.zoom >= 15) {
     801                                        Renderer.labelText(name == null ? "" : name, new Font("Arial", Font.PLAIN, 30), Symbols.Msymb, LabelStyle.RRCT, Symbols.Msymb, Color.white, new Delta(Handle.BC));
     802                                }
     803                        }
     804                        if (getAttVal(Obj.ACHBRT, Att.RADIUS) != null) {
     805                                double radius;
     806                                if ((radius = (Double) getAttVal(Obj.ACHBRT, Att.RADIUS)) != 0) {
     807                                        UniHLU units = (UniHLU) getAttEnum(Obj.ACHBRT, Att.HUNITS);
     808                                        if (units == UniHLU.HLU_UNKN) {
     809                                                units = UniHLU.HLU_METR;
     810                                        }
     811                                        Renderer.lineCircle(new LineStyle(Symbols.Mline, 4, new float[] { 10, 10 }, null), radius, units);
     812                                }
     813                        }
     814                        break;
     815                case ACHARE:
     816                        if (Renderer.zoom >= 12) {
     817                                if (feature.geom.prim != Pflag.AREA) {
     818                                        Renderer.symbol(Harbours.Anchorage, new Scheme(Color.black));
     819                                } else {
     820                                        Renderer.symbol(Harbours.Anchorage, new Scheme(Symbols.Mline));
     821                                        Renderer.lineSymbols(Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Symbols.Mline);
     822                                }
     823                                addName(15, new Font("Arial", Font.BOLD, 60), Symbols.Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
     824                                ArrayList<StsSTS> sts = (ArrayList<StsSTS>) getAttList(Obj.ACHARE, Att.STATUS);
     825                                if ((Renderer.zoom >= 15) && (sts.contains(StsSTS.STS_RESV))) {
     826                                        Renderer.labelText("Reserved", new Font("Arial", Font.PLAIN, 50), Symbols.Mline, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
     827                                }
     828                                ArrayList<CatACH> cats = (ArrayList<CatACH>) getAttList(Obj.ACHARE, Att.CATACH);
     829                                int dy = (cats.size() - 1) * -30;
     830                                for (CatACH cat : cats) {
     831                                        switch (cat) {
     832                                        case ACH_DEEP:
     833                                                Renderer.labelText("DW", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     834                                                dy += 60;
     835                                                break;
     836                                        case ACH_TANK:
     837                                                Renderer.labelText("Tanker", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     838                                                dy += 60;
     839                                                break;
     840                                        case ACH_H24P:
     841                                                Renderer.labelText("24h", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     842                                                dy += 60;
     843                                                break;
     844                                        case ACH_EXPL:
     845                                                Renderer.symbol(Harbours.Explosives, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     846                                                dy += 60;
     847                                                break;
     848                                        case ACH_QUAR:
     849                                                Renderer.symbol(Harbours.Hospital, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     850                                                dy += 60;
     851                                                break;
     852                                        case ACH_SEAP:
     853                                                Renderer.symbol(Areas.Seaplane, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
     854                                                dy += 60;
     855                                                break;
     856                                        default:
     857                                        }
     858                                }
     859                        }
     860                        break;
     861                case BERTHS:
     862                        if (Renderer.zoom >= 14) {
     863                                Renderer.lineVector(new LineStyle(Symbols.Mline, 6, new float[] { 20, 20 }));
     864                                Renderer.labelText(name == null ? " " : name, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, LabelStyle.RRCT, Symbols.Mline, Color.white);
     865                        }
     866                        break;
     867                case BUISGL:
     868                        if (Renderer.zoom >= 16) {
     869                                if (hasAttribute(Obj.BUISGL, Att.STATUS) && (testAttribute(Obj.BUISGL, Att.STATUS, StsSTS.STS_ILLD))) {
     870                                        Renderer.symbol(Beacons.Floodlight);
     871                                }
     872                                ArrayList<Symbol> symbols = new ArrayList<>();
     873                                ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(Obj.BUISGL, Att.FUNCTN);
     874                                for (FncFNC fnc : fncs) {
     875                                        symbols.add(Landmarks.Funcs.get(fnc));
     876                                }
     877                                if (feature.objs.containsKey(Obj.SMCFAC)) {
     878                                        ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
     879                                        for (CatSCF scf : scfs) {
     880                                                symbols.add(Facilities.Cats.get(scf));
     881                                        }
     882                                }
     883                                Renderer.cluster(symbols);
     884                        }
     885                        break;
     886                case HRBFAC:
     887                        if (Renderer.zoom >= 12) {
     888                                ArrayList<CatHAF> cathaf = (ArrayList<CatHAF>) getAttList(Obj.HRBFAC, Att.CATHAF);
     889                                if (cathaf.size() == 1) {
     890                                        switch (cathaf.get(0)) {
     891                                        case HAF_MRNA:
     892                                                Renderer.symbol(Harbours.Marina);
     893                                                break;
     894                                        case HAF_MANF:
     895                                                Renderer.symbol(Harbours.MarinaNF);
     896                                                break;
     897                                        case HAF_FISH:
     898                                                Renderer.symbol(Harbours.Fishing);
     899                                                break;
     900                                        default:
     901                                                Renderer.symbol(Harbours.Harbour);
     902                                                break;
     903                                        }
     904                                } else {
     905                                        Renderer.symbol(Harbours.Harbour);
     906                                }
     907                        }
     908                        break;
     909                default:
     910                        break;
     911                }
     912        }
     913
     914        @SuppressWarnings("unchecked")
     915        private static void highways() {
     916                switch (feature.type) {
     917                case ROADWY:
     918                        ArrayList<CatROD> cat = (ArrayList<CatROD>) (getAttList(Obj.ROADWY, Att.CATROD));
     919                        if (cat.size() > 0) {
     920                                switch (cat.get(0)) {
     921                                case ROD_MWAY:
     922                                        Renderer.lineVector(new LineStyle(Color.black, 20));
     923                                        break;
     924                                case ROD_MAJR:
     925                                        Renderer.lineVector(new LineStyle(Color.black, 15));
     926                                        break;
     927                                case ROD_MINR:
     928                                        Renderer.lineVector(new LineStyle(Color.black, 10));
     929                                        break;
     930                                default:
     931                                        Renderer.lineVector(new LineStyle(Color.black, 5));
     932                                }
     933                        } else {
     934                                Renderer.lineVector(new LineStyle(Color.black, 5));
     935                        }
     936                        break;
     937                case RAILWY:
     938                        Renderer.lineVector(new LineStyle(Color.gray, 10));
     939                        Renderer.lineVector(new LineStyle(Color.black, 10, new float[] { 30, 30 }));
     940                        break;
     941                default:
     942                }
     943        }
     944
     945        @SuppressWarnings("unchecked")
     946        private static void landmarks() {
     947                if (!hasAttribute(Obj.LNDMRK, Att.CATLMK) && (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT)) && hasObject(Obj.LIGHTS))
     948                        lights();
     949                else if (Renderer.zoom >= 12) {
     950                        switch (feature.type) {
     951                        case LNDMRK:
     952                                if (hasAttribute(Obj.LNDMRK, Att.STATUS) && (testAttribute(Obj.LNDMRK, Att.STATUS, StsSTS.STS_ILLD))) {
     953                                        Renderer.symbol(Beacons.Floodlight);
     954                                }
     955                                ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttList(feature.type, Att.CATLMK);
     956                                Symbol catSym = Landmarks.Shapes.get(cats.get(0));
     957                                ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(feature.type, Att.FUNCTN);
     958                                Symbol fncSym = Landmarks.Funcs.get(fncs.get(0));
     959                                if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
     960                                        catSym = Landmarks.ChurchTower;
     961                                if (cats.get(0) == CatLMK.LMK_RADR)
     962                                        fncSym = Landmarks.RadioTV;
     963                                Renderer.symbol(catSym);
     964                                Renderer.symbol(fncSym);
     965                                break;
     966                        case SILTNK:
     967                                if (testAttribute(feature.type, Att.CATSIL, CatSIL.SIL_WTRT))
     968                                        Renderer.symbol(Landmarks.WaterTower);
     969                                break;
     970                        default:
     971                                break;
     972                        }
     973                        if (Renderer.zoom >= 15)
     974                                addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
     975                        Signals.addSignals();
     976                }
     977        }
     978
     979        @SuppressWarnings("unchecked")
     980        private static void points() {
     981                boolean ok = false;
     982                switch (feature.type) {
     983                case FOGSIG:
     984                        if (Renderer.zoom >= 12) {
     985                                if (feature.objs.containsKey(Obj.LIGHTS))
     986                                        lights();
     987                                else
     988                                        Renderer.symbol(Harbours.Post);
     989                                ok = true;
     990                        }
     991                        break;
     992                default:
     993                        if (Renderer.zoom >= 14) {
     994                                if (feature.objs.containsKey(Obj.LIGHTS))
     995                                        lights();
     996                                else
     997                                        Renderer.symbol(Harbours.Post);
     998                                ok = true;
     999                        }
     1000                        break;
     1001                }
     1002                if (ok) {
     1003                        if (feature.objs.containsKey(Obj.TOPMAR)) {
     1004                                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     1005                                if (topmap.containsKey(Att.TOPSHP)) {
     1006                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), null);
     1007                                }
     1008                        } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     1009                                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     1010                                if (topmap.containsKey(Att.TOPSHP)) {
     1011                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), null);
     1012                                }
     1013                        }
     1014                        Signals.addSignals();
     1015                }
     1016        }
     1017
     1018        @SuppressWarnings("unchecked")
     1019        private static void lights() {
     1020                boolean ok = false;
     1021                switch (feature.type) {
     1022                case LITMAJ:
     1023                case LNDMRK:
     1024                        if (Renderer.zoom >= 12) {
     1025                                Renderer.symbol(Beacons.LightMajor);
     1026                                ok = true;
     1027                        }
     1028                        break;
     1029                case LITMIN:
     1030                case LIGHTS:
     1031                case PILPNT:
     1032                        if (Renderer.zoom >= 14) {
     1033                                if (hasAttribute(Obj.LIGHTS, Att.CATLIT) && (testAttribute(Obj.LIGHTS, Att.CATLIT, CatLIT.LIT_FLDL))) {
     1034                                        Renderer.symbol(Beacons.Floodlight);
     1035                                        Renderer.symbol(Harbours.SignalStation);
     1036                                } else {
     1037                                        Renderer.symbol(Beacons.LightMinor);
     1038                                }
     1039                                ok = true;
     1040                        }
     1041                        break;
     1042                default:
     1043                        break;
     1044                }
     1045                if (ok) {
     1046                        AffineTransform tr = new AffineTransform();
     1047                        if (feature.objs.containsKey(Obj.TOPMAR)) {
     1048                                if (hasAttribute(Obj.TOPMAR, Att.STATUS) && (testAttribute(Obj.TOPMAR, Att.STATUS, StsSTS.STS_ILLD))) {
     1049                                        Renderer.symbol(Beacons.Floodlight);
     1050                                }
     1051                                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     1052                                if (topmap.containsKey(Att.TOPSHP)) {
     1053                                        if (hasAttribute(Obj.TOPMAR, Att.ORIENT)) {
     1054                                                tr.rotate(Math.toRadians((Double) getAttVal(Obj.TOPMAR, Att.ORIENT)));
     1055                                        }
     1056                                        tr.translate(0, -20);
     1057                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), new Delta(Handle.BC, tr));
     1058                                }
     1059                        } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     1060                                if (hasAttribute(Obj.DAYMAR, Att.STATUS) && (testAttribute(Obj.DAYMAR, Att.STATUS, StsSTS.STS_ILLD))) {
     1061                                        Renderer.symbol(Beacons.Floodlight);
     1062                                }
     1063                                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     1064                                if (topmap.containsKey(Att.TOPSHP)) {
     1065                                        if (hasAttribute(Obj.DAYMAR, Att.ORIENT)) {
     1066                                                tr.rotate(Math.toRadians((Double) getAttVal(Obj.DAYMAR, Att.ORIENT)));
     1067                                        }
     1068                                        tr.translate(0, -20);
     1069                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), new Delta(Handle.BC, tr));
     1070                                }
     1071                        }
     1072                        Signals.addSignals();
     1073                }
     1074        }
     1075
     1076        @SuppressWarnings("unchecked")
     1077        private static void marinas() {
     1078                if (Renderer.zoom >= 16) {
     1079                        ArrayList<Symbol> symbols = new ArrayList<>();
     1080                        ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
     1081                        for (CatSCF scf : scfs) {
     1082                                symbols.add(Facilities.Cats.get(scf));
     1083                        }
     1084                        Renderer.cluster(symbols);
     1085                }
     1086        }
     1087
     1088        private static void moorings() {
     1089                if (Renderer.zoom >= 14) {
     1090                        switch ((CatMOR) getAttEnum(feature.type, Att.CATMOR)) {
     1091                        case MOR_DLPN:
     1092                                Renderer.symbol(Harbours.Dolphin);
     1093                                break;
     1094                        case MOR_DDPN:
     1095                                Renderer.symbol(Harbours.DeviationDolphin);
     1096                                break;
     1097                        case MOR_BLRD:
     1098                        case MOR_POST:
     1099                                Renderer.symbol(Harbours.Bollard);
     1100                                break;
     1101                        case MOR_BUOY:
     1102                                BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
     1103                                if (shape == BoySHP.BOY_UNKN) {
     1104                                        shape = BoySHP.BOY_SPHR;
     1105                                }
     1106                                Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
     1107                                Renderer.symbol(Topmarks.TopMooring, Topmarks.BuoyDeltas.get(shape));
     1108                                break;
     1109                        default:
     1110                                break;
     1111                        }
     1112                        Signals.addSignals();
     1113                }
     1114        }
     1115
     1116        @SuppressWarnings("unchecked")
     1117        private static void notices() {
     1118                if (Renderer.zoom >= 14) {
     1119                        double dx = 0.0, dy = 0.0;
     1120                        switch (feature.type) {
     1121                        case BCNCAR:
     1122                        case BCNISD:
     1123                        case BCNLAT:
     1124                        case BCNSAW:
     1125                        case BCNSPP:
     1126                                if (testAttribute(Obj.TOPMAR, Att.TOPSHP, TopSHP.TOP_BORD) || testAttribute(Obj.DAYMAR, Att.TOPSHP, TopSHP.TOP_BORD)) {
     1127                                        dy = -100.0;
     1128                                } else {
     1129                                        dy = -45.0;
     1130                                }
     1131                                break;
     1132                        case NOTMRK:
     1133                                dy = 0.0;
     1134                                break;
     1135                        default:
     1136                                return;
     1137                        }
     1138                        MarSYS sys = MarSYS.SYS_CEVN;
     1139                        BnkWTW bnk = BnkWTW.BWW_UNKN;
     1140                        AttVal<?> att = feature.atts.get(Att.MARSYS);
     1141                        if (att != null)
     1142                                sys = (MarSYS) att.val;
     1143                        att = feature.atts.get(Att.BNKWTW);
     1144                        if (att != null)
     1145                                bnk = (BnkWTW) att.val;
     1146                        ObjTab objs = feature.objs.get(Obj.NOTMRK);
     1147                        int n = objs.size();
     1148                        if (n > 5) {
     1149                                Renderer.symbol(Notices.Notice, new Delta(Handle.CC, AffineTransform.getTranslateInstance(dx, dy)));
     1150                        } else {
     1151                                int i = 0;
     1152                                for (AttMap atts : objs.values()) {
     1153                                        if (atts.get(Att.MARSYS) != null)
     1154                                                sys = ((ArrayList<MarSYS>) (atts.get(Att.MARSYS).val)).get(0);
     1155                                        if (atts.get(Att.BNKWTW) != null)
     1156                                                bnk = ((ArrayList<BnkWTW>) (atts.get(Att.BNKWTW).val)).get(0);
     1157                                        CatNMK cat = CatNMK.NMK_UNKN;
     1158                                        if (atts.get(Att.CATNMK) != null)
     1159                                                cat = ((ArrayList<CatNMK>) (atts.get(Att.CATNMK).val)).get(0);
     1160                                        Symbol sym = Notices.getNotice(cat, sys, bnk);
     1161                                        Scheme sch = Notices.getScheme(sys, bnk);
     1162                                        ArrayList<AddMRK> add = new ArrayList<>();
     1163                                        if (atts.get(Att.ADDMRK) != null)
     1164                                                add = (ArrayList<AddMRK>) (atts.get(Att.ADDMRK).val);
     1165                                        Handle h = Handle.CC;
     1166                                        double ax = 0.0;
     1167                                        double ay = 0.0;
     1168                                        switch (i) {
     1169                                        case 0:
     1170                                                if (n != 1)
     1171                                                        h = null;
     1172                                                break;
     1173                                        case 1:
     1174                                                if (n <= 3) {
     1175                                                        h = Handle.RC;
     1176                                                        ax = -30;
     1177                                                        ay = dy;
     1178                                                } else {
     1179                                                        h = Handle.BR;
     1180                                                }
     1181                                                break;
     1182                                        case 2:
     1183                                                if (n <= 3)
     1184                                                        h = Handle.LC;
     1185                                                else
     1186                                                        h = Handle.BL;
     1187                                                break;
     1188                                        case 3:
     1189                                                if (n == 4)
     1190                                                        h = Handle.TC;
     1191                                                else
     1192                                                        h = Handle.TR;
     1193                                                break;
     1194                                        case 4:
     1195                                                h = Handle.TL;
     1196                                                break;
     1197                                        }
     1198                                        if (h != null) {
     1199                                                Renderer.symbol(sym, sch, new Delta(h, AffineTransform.getTranslateInstance(dx, dy)));
     1200                                                if (!add.isEmpty())
     1201                                                        Renderer.symbol(Notices.NoticeBoard, new Delta(Handle.BC, AffineTransform.getTranslateInstance(ax, ay - 30)));
     1202                                        }
     1203                                        i++;
     1204                                }
     1205                        }
     1206                }
     1207        }
     1208
     1209        private static void obstructions() {
     1210                if ((Renderer.zoom >= 12) && (feature.type == Obj.OBSTRN)) {
     1211                        if (getAttEnum(feature.type, Att.CATOBS) == CatOBS.OBS_BOOM) {
     1212                                Renderer.lineVector(new LineStyle(Color.black, 5, new float[] { 20, 20 }, null));
     1213                                if (Renderer.zoom >= 15) {
     1214                                        Renderer.lineText("Boom", new Font("Arial", Font.PLAIN, 80), Color.black, -20);
     1215                                }
     1216                        }
     1217                }
     1218                if ((Renderer.zoom >= 14) && (feature.type == Obj.UWTROC)) {
     1219                        switch ((WatLEV) getAttEnum(feature.type, Att.WATLEV)) {
     1220                        case LEV_CVRS:
     1221                                Renderer.symbol(Areas.RockC);
     1222                                break;
     1223                        case LEV_AWSH:
     1224                                Renderer.symbol(Areas.RockA);
     1225                                break;
     1226                        default:
     1227                                Renderer.symbol(Areas.Rock);
     1228                        }
     1229                } else {
     1230                        Renderer.symbol(Areas.Rock);
     1231                }
     1232        }
     1233
     1234        private static void pipelines() {
     1235                if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
     1236                        if (feature.type == Obj.PIPSOL) {
     1237                                Renderer.lineSymbols(Areas.Pipeline, 1.0, null, null, 0, Symbols.Mline);
     1238                        } else if (feature.type == Obj.PIPOHD) {
     1239                                Renderer.lineVector(new LineStyle(Color.black, 8));
     1240                                AttMap atts = feature.atts;
     1241                                double verclr = 0;
     1242                                if (atts != null) {
     1243                                        if (atts.containsKey(Att.VERCLR)) {
     1244                                                verclr = (Double) atts.get(Att.VERCLR).val;
     1245                                        } else {
     1246                                                verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
     1247                                        }
     1248                                        if (verclr > 0) {
     1249                                                Renderer.labelText(String.valueOf(verclr), new Font("Arial", Font.PLAIN, 50), Color.black, LabelStyle.VCLR, Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 25)));
     1250                                        }
     1251                                }
     1252                        }
     1253                }
     1254        }
     1255
     1256        @SuppressWarnings("unchecked")
     1257        private static void platforms() {
     1258                ArrayList<CatOFP> cats = (ArrayList<CatOFP>) getAttList(Obj.OFSPLF, Att.CATOFP);
     1259                if (cats.get(0) == CatOFP.OFP_FPSO)
     1260                        Renderer.symbol(Buoys.Storage);
     1261                else
     1262                        Renderer.symbol(Landmarks.Platform);
     1263                addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
     1264                Signals.addSignals();
     1265        }
     1266
     1267        private static void ports() {
     1268                if (Renderer.zoom >= 14) {
     1269                        if (feature.type == Obj.CRANES) {
     1270                                if ((CatCRN) getAttEnum(feature.type, Att.CATCRN) == CatCRN.CRN_CONT)
     1271                                        Renderer.symbol(Harbours.ContainerCrane);
     1272                                else
     1273                                        Renderer.symbol(Harbours.PortCrane);
     1274                        } else if (feature.type == Obj.HULKES) {
     1275                                Renderer.lineVector(new LineStyle(Color.black, 4, null, new Color(0xffe000)));
     1276                                addName(15, new Font("Arial", Font.BOLD, 40));
     1277                        }
     1278                }
     1279        }
     1280
     1281        private static void separation() {
     1282                switch (feature.type) {
     1283                case TSEZNE:
     1284                case TSSCRS:
     1285                case TSSRON:
     1286                        if (Renderer.zoom <= 15)
     1287                                Renderer.lineVector(new LineStyle(Symbols.Mtss));
     1288                        else
     1289                                Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
     1290                        addName(10, new Font("Arial", Font.BOLD, 150), Symbols.Mline);
     1291                        break;
     1292                case TSELNE:
     1293                        Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
     1294                        break;
     1295                case TSSLPT:
     1296                        Renderer.lineSymbols(Areas.LaneArrow, 0.5, null, null, 0, Symbols.Mtss);
     1297                        break;
     1298                case TSSBND:
     1299                        Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, new float[] { 40, 40 }, null));
     1300                        break;
     1301                case ISTZNE:
     1302                        Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mtss);
     1303                        break;
     1304                default:
     1305                        break;
     1306                }
     1307        }
     1308
     1309        @SuppressWarnings("unchecked")
     1310        private static void shoreline() {
     1311                CatSLC cat = (CatSLC) getAttEnum(feature.type, Att.CATSLC);
     1312                if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
     1313                        if ((cat != CatSLC.SLC_SWAY) && (cat != CatSLC.SLC_TWAL)) {
     1314                                if (Renderer.zoom >= 12) {
     1315                                        Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Yland));
     1316                                } else {
     1317                                        Renderer.lineVector(new LineStyle(Symbols.Yland));
     1318                                }
     1319                        }
     1320                }
     1321                if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
     1322                        if (Renderer.zoom >= 12) {
     1323                                switch (cat) {
     1324                                case SLC_TWAL:
     1325                                        WatLEV lev = (WatLEV) getAttEnum(feature.type, Att.WATLEV);
     1326                                        if (lev == WatLEV.LEV_CVRS) {
     1327                                                Renderer.lineVector(new LineStyle(Color.black, 10, new float[] { 40, 40 }, null));
     1328                                                if (Renderer.zoom >= 15)
     1329                                                        Renderer.lineText("(covers)", new Font("Arial", Font.PLAIN, 60), Color.black, 80);
     1330                                        } else {
     1331                                                Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
     1332                                        }
     1333                                        if (Renderer.zoom >= 15)
     1334                                                Renderer.lineText("Training Wall", new Font("Arial", Font.PLAIN, 60), Color.black, -30);
     1335                                        break;
     1336                                case SLC_SWAY:
     1337                                        Renderer.lineVector(new LineStyle(Color.black, 2, null, new Color(0xffe000)));
     1338                                        if ((Renderer.zoom >= 16) && feature.objs.containsKey(Obj.SMCFAC)) {
     1339                                                ArrayList<Symbol> symbols = new ArrayList<>();
     1340                                                ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
     1341                                                for (CatSCF scf : scfs) {
     1342                                                        symbols.add(Facilities.Cats.get(scf));
     1343                                                }
     1344                                                Renderer.cluster(symbols);
     1345                                        }
     1346                                        break;
     1347                                default:
     1348                                        break;
     1349                                }
     1350                        }
     1351                }
     1352        }
     1353
     1354        @SuppressWarnings("unchecked")
     1355        private static void stations() {
     1356                if (Renderer.zoom >= 14) {
     1357                        String str = "";
     1358                        switch (feature.type) {
     1359                        case SISTAT:
     1360                                Renderer.symbol(Harbours.SignalStation);
     1361                                str = "SS";
     1362                                ArrayList<CatSIT> tcats = (ArrayList<CatSIT>) getAttList(Obj.SISTAT, Att.CATSIT);
     1363                                switch (tcats.get(0)) {
     1364                                case SIT_IPT:
     1365                                        str += "(INT)";
     1366                                        break;
     1367                                case SIT_PRTE:
     1368                                        str += "(Traffic)";
     1369                                        break;
     1370                                case SIT_PRTC:
     1371                                        str += "(Port Control)";
     1372                                        break;
     1373                                case SIT_LOCK:
     1374                                        str += "(Lock)";
     1375                                        break;
     1376                                case SIT_BRDG:
     1377                                        str += "(Bridge)";
     1378                                        break;
     1379                                default:
     1380                                        break;
     1381                                }
     1382                                break;
     1383                        case SISTAW:
     1384                                Renderer.symbol(Harbours.SignalStation);
     1385                                str = "SS";
     1386                                str = "SS";
     1387                                ArrayList<CatSIW> wcats = (ArrayList<CatSIW>) getAttList(Obj.SISTAW, Att.CATSIW);
     1388                                switch (wcats.get(0)) {
     1389                                case SIW_STRM:
     1390                                        str += "(Storm)";
     1391                                        break;
     1392                                case SIW_WTHR:
     1393                                        str += "(Weather)";
     1394                                        break;
     1395                                case SIW_ICE:
     1396                                        str += "(Ice)";
     1397                                        break;
     1398                                case SIW_TIDG:
     1399                                        str = "Tide gauge";
     1400                                        break;
     1401                                case SIW_TIDS:
     1402                                        str = "Tide scale";
     1403                                        break;
     1404                                case SIW_TIDE:
     1405                                        str += "(Tide)";
     1406                                        break;
     1407                                case SIW_TSTR:
     1408                                        str += "(Stream)";
     1409                                        break;
     1410                                case SIW_DNGR:
     1411                                        str += "(Danger)";
     1412                                        break;
     1413                                case SIW_MILY:
     1414                                        str += "(Firing)";
     1415                                        break;
     1416                                case SIW_TIME:
     1417                                        str += "(Time)";
     1418                                        break;
     1419                                default:
     1420                                        break;
     1421                                }
     1422                                break;
     1423                        case RDOSTA:
     1424                        case RTPBCN:
     1425                                Renderer.symbol(Harbours.SignalStation);
     1426                                Renderer.symbol(Beacons.RadarStation);
     1427                                break;
     1428                        case RADRFL:
     1429                                Renderer.symbol(Topmarks.RadarReflector);
     1430                                break;
     1431                        case RADSTA:
     1432                                Renderer.symbol(Harbours.SignalStation);
     1433                                Renderer.symbol(Beacons.RadarStation);
     1434                                Renderer.labelText("Ra", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
     1435                                break;
     1436                        case PILBOP:
     1437                                Renderer.symbol(Harbours.Pilot);
     1438                                addName(15, new Font("Arial", Font.BOLD, 40), Symbols.Msymb, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, -40)));
     1439                                CatPIL cat = (CatPIL) getAttEnum(feature.type, Att.CATPIL);
     1440                                if (cat == CatPIL.PIL_HELI) {
     1441                                        Renderer.labelText("H", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
     1442                                }
     1443                                break;
     1444                        case CGUSTA:
     1445                                Renderer.symbol(Harbours.SignalStation);
     1446                                str = "CG";
     1447                                if (feature.objs.containsKey(Obj.RSCSTA))
     1448                                        Renderer.symbol(Harbours.Rescue, new Delta(Handle.CC, AffineTransform.getTranslateInstance(130, 0)));
     1449                                break;
     1450                        case RSCSTA:
     1451                                Renderer.symbol(Harbours.Rescue);
     1452                                break;
     1453                        default:
     1454                                break;
     1455                        }
     1456                        if ((Renderer.zoom >= 15) && !str.isEmpty()) {
     1457                                Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(40, 0)));
     1458                        }
     1459                        Signals.addSignals();
     1460                }
     1461        }
     1462
     1463        private static void transits() {
     1464                if (Renderer.zoom >= 14) {
     1465                        if (feature.type == Obj.RECTRC)
     1466                                Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
     1467                        else if (feature.type == Obj.NAVLNE)
     1468                                Renderer.lineVector(new LineStyle(Color.black, 10, new float[] { 25, 25 }, null));
     1469                }
     1470                if (Renderer.zoom >= 15) {
     1471                        String str = "";
     1472                        String name = getName();
     1473                        if (name != null)
     1474                                str += name + " ";
     1475                        Double ort;
     1476                        if ((ort = (Double) getAttVal(feature.type, Att.ORIENT)) != null) {
     1477                                str += df.format(ort) + "º";
     1478                                if (!str.isEmpty())
     1479                                        Renderer.lineText(str, new Font("Arial", Font.PLAIN, 80), Color.black, -20);
     1480                        }
     1481                }
     1482        }
     1483
     1484        private static void waterways() {
     1485                Renderer.lineVector(new LineStyle(Symbols.Bwater, 20, (feature.geom.prim == Pflag.AREA) ? Symbols.Bwater : null));
     1486        }
     1487
     1488        private static void wrecks() {
     1489                if (Renderer.zoom >= 14) {
     1490                        switch ((CatWRK) getAttEnum(feature.type, Att.CATWRK)) {
     1491                        case WRK_DNGR:
     1492                        case WRK_MSTS:
     1493                                Renderer.symbol(Areas.WreckD);
     1494                                break;
     1495                        case WRK_HULS:
     1496                                Renderer.symbol(Areas.WreckS);
     1497                                break;
     1498                        default:
     1499                                Renderer.symbol(Areas.WreckND);
     1500                        }
     1501                }
     1502        }
    15351503}
Note: See TracChangeset for help on using the changeset viewer.