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

checkstyle

File:
1 edited

Legend:

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

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