Changeset 32394 in osm


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

checkstyle

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

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/seachart/.project

    r32368 r32394  
    1616                        </arguments>
    1717                </buildCommand>
     18                <buildCommand>
     19                        <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
     20                        <arguments>
     21                        </arguments>
     22                </buildCommand>
    1823        </buildSpec>
    1924        <natures>
    2025                <nature>org.eclipse.jdt.core.javanature</nature>
     26                <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
    2127        </natures>
    2228</projectDescription>
  • applications/editors/josm/plugins/seachart/src/render/ChartContext.java

    r32082 r32394  
    1414
    1515import s57.S57map;
    16 import s57.S57map.*;
     16import s57.S57map.Feature;
     17import s57.S57map.Snode;
    1718
    1819public interface ChartContext {
    19         public enum RuleSet { ALL, BASE, SEAMARK }
     20    enum RuleSet { ALL, BASE, SEAMARK }
    2021
    21         Point2D getPoint(Snode coord);
    22         double mile(Feature feature);
    23         boolean clip();
    24         Color background(S57map map);
    25         RuleSet ruleset();
     22    Point2D getPoint(Snode coord);
     23
     24    double mile(Feature feature);
     25
     26    boolean clip();
     27
     28    Color background(S57map map);
     29
     30    RuleSet ruleset();
    2631}
  • applications/editors/josm/plugins/seachart/src/render/Renderer.java

    r32380 r32394  
    1010package render;
    1111
    12 import java.awt.*;
    13 import java.awt.font.*;
    14 import java.awt.geom.*;
    15 import java.awt.image.*;
    16 import java.util.*;
    17 
    18 import s57.S57val.*;
     12import java.awt.BasicStroke;
     13import java.awt.Color;
     14import java.awt.Font;
     15import java.awt.Graphics2D;
     16import java.awt.Rectangle;
     17import java.awt.RenderingHints;
     18import java.awt.TexturePaint;
     19import java.awt.font.FontRenderContext;
     20import java.awt.font.GlyphVector;
     21import java.awt.geom.AffineTransform;
     22import java.awt.geom.Arc2D;
     23import java.awt.geom.Ellipse2D;
     24import java.awt.geom.GeneralPath;
     25import java.awt.geom.Line2D;
     26import java.awt.geom.Path2D;
     27import java.awt.geom.Point2D;
     28import java.awt.geom.Rectangle2D;
     29import java.awt.geom.RoundRectangle2D;
     30import java.awt.image.AffineTransformOp;
     31import java.awt.image.BufferedImage;
     32import java.util.ArrayList;
     33
    1934import s57.S57map;
    20 import s57.S57map.*;
     35import s57.S57map.GeomIterator;
     36import s57.S57map.Pflag;
     37import s57.S57map.Snode;
     38import s57.S57val.UniHLU;
    2139import symbols.Areas;
    2240import symbols.Symbols;
    23 import symbols.Symbols.*;
     41import symbols.Symbols.Caption;
     42import symbols.Symbols.Delta;
     43import symbols.Symbols.Form;
     44import symbols.Symbols.Handle;
     45import symbols.Symbols.Instr;
     46import symbols.Symbols.LineStyle;
     47import symbols.Symbols.Scheme;
     48import symbols.Symbols.SubSymbol;
     49import symbols.Symbols.Symbol;
    2450
    2551public class Renderer {
    2652
    27         public static final double symbolScale[] = { 256.0, 128.0, 64.0, 32.0, 16.0, 8.0, 4.0, 2.0, 1.0, 0.61, 0.372, 0.227, 0.138, 0.0843, 0.0514, 0.0313, 0.0191, 0.0117, 0.007 };
    28 
    29         public enum LabelStyle { NONE, RRCT, RECT, ELPS, CIRC, VCLR, PCLR, HCLR }
    30 
    31         static ChartContext context;
    32         static S57map map;
    33         static double sScale;
    34         static Graphics2D g2;
    35         static int zoom;
    36 
    37         public static void reRender(Graphics2D g, Rectangle rect, int z, double factor, S57map m, ChartContext c) {
    38                 g2 = g;
    39                 zoom = z;
    40                 context = c;
    41                 map = m;
    42                 sScale = symbolScale[zoom] * factor;
    43                 if (map != null) {
    44                         if (context.clip()) {
    45                                 Point2D tl = context.getPoint(map.new Snode(map.bounds.maxlat, map.bounds.minlon));
    46                                 Point2D br = context.getPoint(map.new Snode(map.bounds.minlat, map.bounds.maxlon));
    47                                 g2.clip(new Rectangle2D.Double(tl.getX(), tl.getY(), (br.getX() - tl.getX()), (br.getY() - tl.getY())));
    48                         }
    49                         g2.setBackground(context.background(map));
    50                         g2.clearRect(rect.x, rect.y, rect.width, rect.height);
    51                         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    52                         g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
    53                         g2.setStroke(new BasicStroke(0, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
    54                         Rules.rules();
    55                 }
    56         }
    57 
    58         public static void symbol(Symbol symbol) {
    59                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    60                 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, null);
    61         }
    62         public static void symbol(Symbol symbol, Scheme scheme) {
    63                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    64                 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, null);
    65         }
    66         public static void symbol(Symbol symbol, Delta delta) {
    67                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    68                 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, delta);
    69         }
    70         public static void symbol(Symbol symbol, Scheme scheme, Delta delta) {
    71                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    72                 Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, delta);
    73         }
    74        
    75         public static void cluster(ArrayList<Symbol> symbols) {
    76                 Rectangle2D.Double bbox = null;
    77                 if (symbols.size() > 4) {
    78                         for (Instr instr : symbols.get(0)) {
    79                                 if (instr.type == Form.BBOX) {
    80                                         bbox = (Rectangle2D.Double) instr.params;
    81                                         break;
    82                                 }
    83                         }
    84                         if (bbox == null) return;
    85                 }
    86                 switch (symbols.size()) {
    87                 case 1:
    88                         symbol(symbols.get(0), new Delta(Handle.CC, new AffineTransform()));
    89                         break;
    90                 case 2:
    91                         symbol(symbols.get(0), new Delta(Handle.RC, new AffineTransform()));
    92                         symbol(symbols.get(1), new Delta(Handle.LC, new AffineTransform()));
    93                         break;
    94                 case 3:
    95                         symbol(symbols.get(0), new Delta(Handle.BC, new AffineTransform()));
    96                         symbol(symbols.get(1), new Delta(Handle.TR, new AffineTransform()));
    97                         symbol(symbols.get(2), new Delta(Handle.TL, new AffineTransform()));
    98                         break;
    99                 case 4:
    100                         symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
    101                         symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
    102                         symbol(symbols.get(2), new Delta(Handle.TR, new AffineTransform()));
    103                         symbol(symbols.get(3), new Delta(Handle.TL, new AffineTransform()));
    104                         break;
    105                 case 5:
    106                         symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
    107                         symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
    108                         symbol(symbols.get(2), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    109                         symbol(symbols.get(3), new Delta(Handle.TC, new AffineTransform()));
    110                         symbol(symbols.get(4), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    111                         break;
    112                 case 6:
    113                         symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    114                         symbol(symbols.get(1), new Delta(Handle.BC, new AffineTransform()));
    115                         symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    116                         symbol(symbols.get(3), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    117                         symbol(symbols.get(4), new Delta(Handle.TC, new AffineTransform()));
    118                         symbol(symbols.get(5), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    119                         break;
    120                 case 7:
    121                         symbol(symbols.get(0), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
    122                         symbol(symbols.get(1), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    123                         symbol(symbols.get(2), new Delta(Handle.CC, new AffineTransform()));
    124                         symbol(symbols.get(3), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    125                         symbol(symbols.get(4), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
    126                         symbol(symbols.get(5), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
    127                         symbol(symbols.get(6), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
    128                         break;
    129                 case 8:
    130                         symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
    131                         symbol(symbols.get(1), new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
    132                         symbol(symbols.get(2), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    133                         symbol(symbols.get(3), new Delta(Handle.CC, new AffineTransform()));
    134                         symbol(symbols.get(4), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    135                         symbol(symbols.get(5), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
    136                         symbol(symbols.get(6), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
    137                         symbol(symbols.get(7), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
    138                         break;
    139                 case 9:
    140                         symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, -bbox.height/2)));
    141                         symbol(symbols.get(1), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
    142                         symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, -bbox.height/2)));
    143                         symbol(symbols.get(3), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
    144                         symbol(symbols.get(4), new Delta(Handle.CC, new AffineTransform()));
    145                         symbol(symbols.get(5), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
    146                         symbol(symbols.get(6), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
    147                         symbol(symbols.get(7), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
    148                         symbol(symbols.get(8), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
    149                         break;
    150                 }
    151         }
    152 
    153         private static Rectangle2D.Double symbolSize(Symbol symbol) {
    154                 Symbol ssymb = symbol;
    155                 while (ssymb != null) {
    156                         for (Instr item : symbol) {
    157                                 if (item.type == Form.BBOX) {
    158                                         return (Rectangle2D.Double) item.params;
    159                                 }
    160                                 if (item.type == Form.SYMB) {
    161                                         ssymb = ((SubSymbol) item.params).instr;
    162                                         break;
    163                                 }
    164                         }
    165                         if (ssymb == symbol)
    166                                 break;
    167                 }
    168                 return null;
    169         }
    170 
    171         public static void lineSymbols(Symbol prisymb, double space, Symbol secsymb, Symbol tersymb, int ratio, Color col) {
    172                 if ((Rules.feature.geom.prim == Pflag.NOSP) || (Rules.feature.geom.prim == Pflag.POINT))
    173                         return;
    174                 Rectangle2D.Double prect = symbolSize(prisymb);
    175                 Rectangle2D.Double srect = symbolSize(secsymb);
    176                 Rectangle2D.Double trect = symbolSize(tersymb);
    177                 if (srect == null)
    178                         ratio = 0;
    179                 if (prect != null) {
    180                         double psize = Math.abs(prect.getY()) * sScale;
    181                         double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
    182                         double tsize = (trect != null) ? Math.abs(srect.getY()) * sScale : 0;
    183                         Point2D prev = new Point2D.Double();
    184                         Point2D next = new Point2D.Double();
    185                         Point2D curr = new Point2D.Double();
    186                         Point2D succ = new Point2D.Double();
    187                         boolean gap = true;
    188                         boolean piv = false;
    189                         double len = 0;
    190                         double angle = 0;
    191                         int stcount = ratio;
    192                         boolean stflag = false;
    193                         Symbol symbol = prisymb;
    194                         GeomIterator git = map.new GeomIterator(Rules.feature.geom);
    195                         while (git.hasComp()) {
    196                                 git.nextComp();
    197                                 boolean first = true;
    198                                 while (git.hasEdge()) {
    199                                         git.nextEdge();
    200                                         while (git.hasNode()) {
    201                                                 Snode node = git.next();
    202                                                 if (node == null) continue;
    203                                                 prev = next;
    204                                                 next = context.getPoint(node);
    205                                                 angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
    206                                                 piv = true;
    207                                                 if (first) {
    208                                                         curr = succ = next;
    209                                                         gap = (space > 0);
    210                                                         stcount = ratio - 1;
    211                                                         symbol = prisymb;
    212                                                         len = gap ? psize * space * 0.5 : psize;
    213                                                         first = false;
    214                                                 } else {
    215                                                         while (curr.distance(next) >= len) {
    216                                                                 if (piv) {
    217                                                                         double rem = len;
    218                                                                         double s = prev.distance(next);
    219                                                                         double p = curr.distance(prev);
    220                                                                         if ((s > 0) && (p > 0)) {
    221                                                                                 double n = curr.distance(next);
    222                                                                                 double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
    223                                                                                 double phi = Math.asin(p / len * Math.sin(theta));
    224                                                                                 rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
    225                                                                         }
    226                                                                         succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
    227                                                                         piv = false;
    228                                                                 } else {
    229                                                                         succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
    230                                                                 }
    231                                                                 if (!gap) {
    232                                                                         Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(), new Scheme(col),
    233                                                                                         new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX())) + Math.toRadians(90))));
    234                                                                 }
    235                                                                 if (space > 0)
    236                                                                         gap = !gap;
    237                                                                 curr = succ;
    238                                                                 len = gap ? (psize * space) : (--stcount == 0) ? (stflag ? tsize : ssize) : psize;
    239                                                                 if (stcount == 0) {
    240                                                                         symbol = stflag ? tersymb : secsymb;
    241                                                                         if (trect != null)
    242                                                                                 stflag = !stflag;
    243                                                                         stcount = ratio;
    244                                                                 } else {
    245                                                                         symbol = prisymb;
    246                                                                 }
    247                                                         }
    248                                                 }
    249                                         }
    250                                 }
    251                         }
    252                 }
    253         }
    254 
    255         public static void lineVector(LineStyle style) {
    256                 Path2D.Double p = new Path2D.Double();
    257                 p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    258                 Point2D point;
    259                 GeomIterator git = map.new GeomIterator(Rules.feature.geom);
    260                 while (git.hasComp()) {
    261                         git.nextComp();
    262                         boolean first = true;
    263                         while (git.hasEdge()) {
    264                                 git.nextEdge();
    265                                 point = context.getPoint(git.next());
    266                                 if (first) {
    267                                         p.moveTo(point.getX(), point.getY());
    268                                         first = false;
    269                                 } else {
    270                                         p.lineTo(point.getX(), point.getY());
    271                                 }
    272                                 while (git.hasNode()) {
    273                                         Snode node = git.next();
    274                                         if (node == null) continue;
    275                                         point = context.getPoint(node);
    276                                         p.lineTo(point.getX(), point.getY());
    277                                 }
    278                         }
    279                 }
    280                 if ((style.fill != null) && (Rules.feature.geom.prim == Pflag.AREA)) {
    281                         g2.setPaint(style.fill);
    282                         g2.fill(p);
    283                 }
    284                 if (style.line != null) {
    285                         if (style.dash != null) {
    286                                 float[] dash = new float[style.dash.length];
    287                                 System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
    288                                 for (int i = 0; i < style.dash.length; i++) {
    289                                         dash[i] *= (float) sScale;
    290                                 }
    291                                 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
    292                         } else {
    293                                 g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    294                         }
    295                         g2.setPaint(style.line);
    296                         g2.draw(p);
    297                 }
    298         }
    299        
    300         public static void lineCircle(LineStyle style, double radius, UniHLU units) {
    301                 switch (units) {
    302                 case HLU_FEET:
    303                         radius /= 6076;
    304                         break;
    305                 case HLU_KMTR:
    306                         radius /= 1.852;
    307                         break;
    308                 case HLU_HMTR:
    309                         radius /= 18.52;
    310                         break;
    311                 case HLU_SMIL:
    312                         radius /= 1.15078;
    313                         break;
    314                 case HLU_NMIL:
    315                         break;
    316                 default:
    317                         radius /= 1852;
    318                         break;
    319                 }
    320                 radius *= context.mile(Rules.feature);
    321                 Symbol circle = new Symbol();
    322                 if (style.fill != null) {
    323                         circle.add(new Instr(Form.FILL, style.fill));
    324                         circle.add(new Instr(Form.RSHP, new Ellipse2D.Double(-radius,-radius,radius*2,radius*2)));
    325                 }
    326                 circle.add(new Instr(Form.FILL, style.line));
    327                 circle.add(new Instr(Form.STRK, new BasicStroke(style.width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, style.dash, 0)));
    328                 circle.add(new Instr(Form.ELPS, new Ellipse2D.Double(-radius,-radius,radius*2,radius*2)));
    329                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    330                 Symbols.drawSymbol(g2, circle, 1, point.getX(), point.getY(), null, null);
    331         }
    332 
    333         public static void fillPattern(BufferedImage image) {
    334                 Path2D.Double p = new Path2D.Double();
    335                 p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    336                 Point2D point;
    337                 switch (Rules.feature.geom.prim) {
    338                 case POINT:
    339                         point = context.getPoint(Rules.feature.geom.centre);
    340                         g2.drawImage(image, new AffineTransformOp(AffineTransform.getScaleInstance(sScale, sScale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
    341                                         (int)(point.getX() - (50 * sScale)), (int)(point.getY() - (50 * sScale)));
    342                         break;
    343                 case AREA:
    344                         GeomIterator git = map.new GeomIterator(Rules.feature.geom);
    345                         while (git.hasComp()) {
    346                                 git.nextComp();
    347                                 boolean newComp = true;
    348                                 while (git.hasEdge()) {
    349                                         git.nextEdge();
    350                                         point = context.getPoint(git.next());
    351                                         if (newComp) {
    352                                                 p.moveTo(point.getX(), point.getY());
    353                                                 newComp = false;
    354                                         } else {
    355                                                 p.lineTo(point.getX(), point.getY());
    356                                         }
    357                                         while (git.hasNode()) {
    358                                                 Snode node = git.next();
    359                                                 if (node == null) continue;
    360                                                 point = context.getPoint(node);
    361                                                 p.lineTo(point.getX(), point.getY());
    362                                         }
    363                                 }
    364                         }
    365             g2.setPaint(new TexturePaint(image, new Rectangle(0, 0, 1 + (int)(300 * sScale), 1 + (int)(300 * sScale))));
    366             g2.fill(p);
    367             break;
    368                 default:
    369                         break;
    370                 }
    371         }
    372        
    373         public static void labelText(String str, Font font, Color tc) {
    374                 labelText(str, font, tc, LabelStyle.NONE, null, null, null);
    375         }
    376         public static void labelText(String str, Font font, Color tc, Delta delta) {
    377                 labelText(str, font, tc, LabelStyle.NONE, null, null, delta);
    378         }
    379         public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg) {
    380                 labelText(str, font, tc, style, fg, null, null);
    381         }
    382         public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg) {
    383                 labelText(str, font, tc, style, fg, bg, null);
    384         }
    385         public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Delta delta) {
    386                 labelText(str, font, tc, style, fg, null, delta);
    387         }
    388         public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg, Delta delta) {
    389                 if (delta == null) delta = new Delta(Handle.CC);
    390                 if (bg == null) bg = new Color(0x00000000, true);
    391                 if ((str == null) || (str.isEmpty())) str = " ";
    392     FontRenderContext frc = g2.getFontRenderContext();
    393     GlyphVector gv = font.deriveFont((float)(font.getSize())).createGlyphVector(frc, str.equals(" ") ? "M" : str);
    394     Rectangle2D bounds = gv.getVisualBounds();
    395     double width = bounds.getWidth();
    396     double height = bounds.getHeight();
    397                 Symbol label = new Symbol();
    398                 double lx, ly, tx, ty;
    399                 switch (style) {
    400                 case RRCT:
    401                         width += height * 1.0;
    402                         height *= 1.5;
    403             if (width < height) width = height;
    404             lx = -width / 2;
    405             ly = -height / 2;
    406             tx = lx + (height * 0.34);
    407             ty = ly + (height * 0.17);
    408                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
    409                         label.add(new Instr(Form.FILL, bg));
    410                         label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
    411                         label.add(new Instr(Form.FILL, fg));
    412                         label.add(new Instr(Form.STRK, new BasicStroke(1 + (int)(height/10), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    413                         label.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
    414                         break;
    415                 case VCLR:
    416                         width += height * 1.0;
    417                         height *= 2.0;
    418             if (width < height) width = height;
    419             lx = -width / 2;
    420             ly = -height / 2;
    421             tx = lx + (height * 0.27);
    422             ty = ly + (height * 0.25);
    423                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
    424                         label.add(new Instr(Form.FILL, bg));
    425                         label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
    426                         label.add(new Instr(Form.FILL, fg));
    427                         int sw = 1 + (int)(height/10);
    428                         double po = sw / 2;
    429                         label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    430                         Path2D.Double p = new Path2D.Double(); p.moveTo(-height*0.2,-ly-po); p.lineTo(height*0.2,-ly-po); p.moveTo(0,-ly-po); p.lineTo(0,-ly-po-(height*0.15));
    431                         p.moveTo(-height*0.2,ly+po); p.lineTo((height*0.2),ly+po); p.moveTo(0,ly+po); p.lineTo(0,ly+po+(height*0.15));
    432                         label.add(new Instr(Form.PLIN, p));
    433                         break;
    434                 case PCLR:
    435                         width += height * 1.0;
    436                         height *= 2.0;
    437             if (width < height) width = height;
    438             lx = -width / 2;
    439             ly = -height / 2;
    440             tx = lx + (height * 0.27);
    441             ty = ly + (height * 0.25);
    442                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
    443                         label.add(new Instr(Form.FILL, bg));
    444                         label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
    445                         label.add(new Instr(Form.FILL, fg));
    446                         sw = 1 + (int)(height/10);
    447                         po = sw / 2;
    448                         label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    449                         p = new Path2D.Double(); p.moveTo(-height*0.2,-ly-po); p.lineTo(height*0.2,-ly-po); p.moveTo(0,-ly-po); p.lineTo(0,-ly-po-(height*0.15));
    450                         p.moveTo(-height*0.2,ly+po); p.lineTo((height*0.2),ly+po); p.moveTo(0,ly+po); p.lineTo(0,ly+po+(height*0.15));
    451                         label.add(new Instr(Form.PLIN, p));
    452                         label.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.CableFlash, 1, 0, 0, null, new Delta(Handle.CC, new AffineTransform(0,-1,1,0,-width/2,0)))));
    453                         label.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.CableFlash, 1, 0, 0, null, new Delta(Handle.CC, new AffineTransform(0,-1,1,0,width/2,0)))));
    454                         break;
    455                 case HCLR:
    456                         width += height * 1.5;
    457                         height *= 1.5;
    458             if (width < height) width = height;
    459             lx = -width / 2;
    460             ly = -height / 2;
    461             tx = lx + (height * 0.5);
    462             ty = ly + (height * 0.17);
    463                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
    464                         label.add(new Instr(Form.FILL, bg));
    465                         label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
    466                         label.add(new Instr(Form.FILL, fg));
    467                         sw = 1 + (int)(height/10);
    468                         double vo = height / 4;
    469                         label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    470                         p = new Path2D.Double(); p.moveTo(-width*0.4-sw,-ly-vo); p.lineTo(-width*0.4-sw,ly+vo); p.moveTo(-width*0.4-sw,0); p.lineTo(-width*0.4+sw,0);
    471                         p.moveTo(width*0.4+sw,-ly-vo); p.lineTo(width*0.4+sw,ly+vo); p.moveTo(width*0.4-sw,0); p.lineTo(width*0.4+sw,0);
    472                         label.add(new Instr(Form.PLIN, p));
    473                         break;
    474                 default:
    475                         lx = -width / 2;
    476                         ly = -height / 2;
    477                         tx = lx;
    478                         ty = ly;
    479                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
    480                         break;
    481                 }
    482                 label.add(new Instr(Form.TEXT, new Caption(str, font, tc, new Delta(Handle.TL, AffineTransform.getTranslateInstance(tx, ty)))));
    483                 Point2D point = context.getPoint(Rules.feature.geom.centre);
    484                 Symbols.drawSymbol(g2, label, sScale, point.getX(), point.getY(), null, delta);
    485         }
    486 
    487         public static void lineText(String str, Font font, Color colour, double dy) {
    488                 if (!str.isEmpty()) {
    489                         g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    490                         g2.setPaint(colour);
    491                         FontRenderContext frc = g2.getFontRenderContext();
    492                         GlyphVector gv = font.deriveFont(font.getSize2D() * (float) sScale).createGlyphVector(frc, str);
    493                         double width = gv.getVisualBounds().getWidth();
    494                         double height = gv.getVisualBounds().getHeight();
    495                         double offset = (Rules.feature.geom.length * context.mile(Rules.feature) - width) / 2;
    496                         if (offset > 0) {
    497                                 Point2D before = null;
    498                                 Point2D after = null;
    499                                 ArrayList<Point2D> between = new ArrayList<>();
    500                                 Point2D prev = null;
    501                                 Point2D next = null;
    502                                 double length = 0;
    503                                 double lb = 0;
    504                                 double la = 0;
    505                                 GeomIterator git = map.new GeomIterator(Rules.feature.geom);
    506                                 if (git.hasComp()) {
    507                                         git.nextComp();
    508                                         while (git.hasEdge()) {
    509                                                 git.nextEdge();
    510                                                 while (git.hasNode()) {
    511                                                         Snode node = git.next();
    512                                                         if (node == null)
    513                                                                 continue;
    514                                                         prev = next;
    515                                                         next = context.getPoint(node);
    516                                                         if (prev != null)
    517                                                                 length += Math.sqrt(Math.pow((next.getX() - prev.getX()), 2) + Math.pow((next.getY() - prev.getY()), 2));
    518                                                         if (length < offset) {
    519                                                                 before = next;
    520                                                                 lb = la = length;
    521                                                         } else if (after == null) {
    522                                                                 if (length > (offset + width)) {
    523                                                                         after = next;
    524                                                                         la = length;
    525                                                                         break;
    526                                                                 } else {
    527                                                                         between.add(next);
    528                                                                 }
    529                                                         }
    530                                                 }
    531                                                 if (after != null)
    532                                                         break;
    533                                         }
    534                                 }
    535                                 if (after != null) {
    536                                         double angle = Math.atan2((after.getY() - before.getY()), (after.getX() - before.getX()));
    537                                         double rotate = Math.abs(angle) < (Math.PI / 2) ? angle : angle + Math.PI;
    538                                         Point2D mid = new Point2D.Double((before.getX() + after.getX()) / 2, (before.getY() + after.getY()) / 2);
    539                                         Point2D centre = context.getPoint(Rules.feature.geom.centre);
    540                                         AffineTransform pos = AffineTransform.getTranslateInstance(-dy * Math.sin(rotate), dy * Math.cos(rotate));
    541                                         pos.rotate(rotate);
    542                                         pos.translate((mid.getX() - centre.getX()), (mid.getY() - centre.getY()));
    543                                         Symbol label = new Symbol();
    544                                         label.add(new Instr(Form.BBOX, new Rectangle2D.Double((-width / 2), (-height), width, height)));
    545                                         label.add(new Instr(Form.TEXT, new Caption(str, font, colour, new Delta(Handle.BC))));
    546                                         Symbols.drawSymbol(g2, label, sScale, centre.getX(), centre.getY(), null, new Delta(Handle.BC, pos));
    547                                 }
    548                         }
    549                 }
    550         }
    551        
    552         public static void lightSector(Color col1, Color col2, double radius, double s1, double s2, Double dir, String str) {
    553                 if ((zoom >= 16) && (radius > 0.2)) {
    554                         radius /= (Math.pow(2, zoom-15));
    555                 }
    556                 double mid = (((s1 + s2)  / 2) + (s1 > s2 ? 180 : 0)) % 360;
    557                 g2.setStroke(new BasicStroke((float) (3.0 * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, new float[] {20 * (float)sScale, 20 * (float)sScale}, 0));
    558                 g2.setPaint(Color.black);
    559                 Point2D.Double centre = (Point2D.Double) context.getPoint(Rules.feature.geom.centre);
    560                 double radial = radius * context.mile(Rules.feature);
    561                 if (dir != null) {
    562                         g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(dir)), centre.y + radial * Math.cos(Math.toRadians(dir))));
    563                 } else {
    564                         if ((s1 != 0.0) || (s2 != 360.0)) {
    565                                 g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(s1)), centre.y + radial * Math.cos(Math.toRadians(s1))));
    566                                 g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(s2)), centre.y + radial * Math.cos(Math.toRadians(s2))));
    567                         }
    568                 }
    569                 double arcWidth =  10.0 * sScale;
    570                 g2.setStroke(new BasicStroke((float)arcWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1));
    571                 g2.setPaint(col1);
    572                 g2.draw(new Arc2D.Double(centre.x - radial, centre.y - radial, 2 * radial, 2 * radial, -(s1 + 90), ((s1 < s2) ? (s1 - s2) : (s1 - s2 - 360)), Arc2D.OPEN));
    573                 if (col2 != null) {
    574                         g2.setPaint(col2);
    575                         g2.draw(new Arc2D.Double(centre.x - radial + arcWidth, centre.y - radial + arcWidth, 2 * (radial - arcWidth), 2 * (radial - arcWidth), -(s1 + 90), ((s1 < s2) ? (s1 - s2) : (s1 - s2 - 360)), Arc2D.OPEN));
    576                 }
    577                 if ((str != null) && (!str.isEmpty())) {
    578                         Font font = new Font("Arial", Font.PLAIN, 40);
    579                         double arc = (s2 > s1) ? (s2 - s1) : (s2 - s1 + 360);
    580                         double awidth = (Math.toRadians(arc) * radial);
    581                         boolean hand = ((mid > 270) || (mid < 90));
    582                         double phi = Math.toRadians(mid);
    583                         radial += 30 * sScale;
    584                         AffineTransform at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
    585                         if ((font.getSize() * sScale * str.length()) < awidth) {
    586                                 at.rotate(Math.toRadians(mid + (hand ? 0 : 180)));
    587                                 labelText(str, font, Color.black, new Delta(Handle.CC, at));
    588                         } else if ((font.getSize() * sScale) < awidth) {
    589                                 hand = (mid < 180);
    590                                 at.rotate(Math.toRadians(mid + (hand ? -90 : 90)));
    591                                 labelText(str, font, Color.black, hand ? new Delta(Handle.RC, at) : new Delta(Handle.LC, at));
    592                         }
    593                         if (dir != null) {
    594                                 font = new Font("Arial", Font.PLAIN, 30);
    595                                 str = dir + "°";
    596                                 hand = (dir > 180);
    597                                 phi = Math.toRadians(dir + (hand ? -0.5 : 0.5));
    598                                 radial -= 70 * sScale;
    599                                 at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
    600                                 at.rotate(Math.toRadians(dir + (hand ? 90 : -90)));
    601                                 labelText(str, font, Color.black, hand ? new Delta(Handle.BR, at) : new Delta(Handle.BL, at));
    602                         }
    603                 }
    604         }
     53    public static final double[] symbolScale = {256.0, 128.0, 64.0, 32.0, 16.0, 8.0, 4.0, 2.0, 1.0, 0.61, 0.372, 0.227, 0.138, 0.0843, 0.0514, 0.0313, 0.0191, 0.0117, 0.007 };
     54
     55    public enum LabelStyle { NONE, RRCT, RECT, ELPS, CIRC, VCLR, PCLR, HCLR }
     56
     57    static ChartContext context;
     58    static S57map map;
     59    static double sScale;
     60    static Graphics2D g2;
     61    static int zoom;
     62
     63    public static void reRender(Graphics2D g, Rectangle rect, int z, double factor, S57map m, ChartContext c) {
     64        g2 = g;
     65        zoom = z;
     66        context = c;
     67        map = m;
     68        sScale = symbolScale[zoom] * factor;
     69        if (map != null) {
     70            if (context.clip()) {
     71                Point2D tl = context.getPoint(map.new Snode(map.bounds.maxlat, map.bounds.minlon));
     72                Point2D br = context.getPoint(map.new Snode(map.bounds.minlat, map.bounds.maxlon));
     73                g2.clip(new Rectangle2D.Double(tl.getX(), tl.getY(), (br.getX() - tl.getX()), (br.getY() - tl.getY())));
     74            }
     75            g2.setBackground(context.background(map));
     76            g2.clearRect(rect.x, rect.y, rect.width, rect.height);
     77            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     78            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
     79            g2.setStroke(new BasicStroke(0, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
     80            Rules.rules();
     81        }
     82    }
     83
     84    public static void symbol(Symbol symbol) {
     85        Point2D point = context.getPoint(Rules.feature.geom.centre);
     86        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, null);
     87    }
     88
     89    public static void symbol(Symbol symbol, Scheme scheme) {
     90        Point2D point = context.getPoint(Rules.feature.geom.centre);
     91        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, null);
     92    }
     93
     94    public static void symbol(Symbol symbol, Delta delta) {
     95        Point2D point = context.getPoint(Rules.feature.geom.centre);
     96        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, delta);
     97    }
     98
     99    public static void symbol(Symbol symbol, Scheme scheme, Delta delta) {
     100        Point2D point = context.getPoint(Rules.feature.geom.centre);
     101        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, delta);
     102    }
     103
     104    public static void cluster(ArrayList<Symbol> symbols) {
     105        Rectangle2D.Double bbox = null;
     106        if (symbols.size() > 4) {
     107            for (Instr instr : symbols.get(0)) {
     108                if (instr.type == Form.BBOX) {
     109                    bbox = (Rectangle2D.Double) instr.params;
     110                    break;
     111                }
     112            }
     113            if (bbox == null) return;
     114        }
     115        switch (symbols.size()) {
     116        case 1:
     117            symbol(symbols.get(0), new Delta(Handle.CC, new AffineTransform()));
     118            break;
     119        case 2:
     120            symbol(symbols.get(0), new Delta(Handle.RC, new AffineTransform()));
     121            symbol(symbols.get(1), new Delta(Handle.LC, new AffineTransform()));
     122            break;
     123        case 3:
     124            symbol(symbols.get(0), new Delta(Handle.BC, new AffineTransform()));
     125            symbol(symbols.get(1), new Delta(Handle.TR, new AffineTransform()));
     126            symbol(symbols.get(2), new Delta(Handle.TL, new AffineTransform()));
     127            break;
     128        case 4:
     129            symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
     130            symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
     131            symbol(symbols.get(2), new Delta(Handle.TR, new AffineTransform()));
     132            symbol(symbols.get(3), new Delta(Handle.TL, new AffineTransform()));
     133            break;
     134        case 5:
     135            symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
     136            symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
     137            symbol(symbols.get(2), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     138            symbol(symbols.get(3), new Delta(Handle.TC, new AffineTransform()));
     139            symbol(symbols.get(4), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     140            break;
     141        case 6:
     142            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     143            symbol(symbols.get(1), new Delta(Handle.BC, new AffineTransform()));
     144            symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     145            symbol(symbols.get(3), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     146            symbol(symbols.get(4), new Delta(Handle.TC, new AffineTransform()));
     147            symbol(symbols.get(5), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     148            break;
     149        case 7:
     150            symbol(symbols.get(0), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
     151            symbol(symbols.get(1), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     152            symbol(symbols.get(2), new Delta(Handle.CC, new AffineTransform()));
     153            symbol(symbols.get(3), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     154            symbol(symbols.get(4), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
     155            symbol(symbols.get(5), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
     156            symbol(symbols.get(6), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
     157            break;
     158        case 8:
     159            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
     160            symbol(symbols.get(1), new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
     161            symbol(symbols.get(2), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     162            symbol(symbols.get(3), new Delta(Handle.CC, new AffineTransform()));
     163            symbol(symbols.get(4), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     164            symbol(symbols.get(5), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
     165            symbol(symbols.get(6), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
     166            symbol(symbols.get(7), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
     167            break;
     168        case 9:
     169            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, -bbox.height/2)));
     170            symbol(symbols.get(1), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
     171            symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, -bbox.height/2)));
     172            symbol(symbols.get(3), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
     173            symbol(symbols.get(4), new Delta(Handle.CC, new AffineTransform()));
     174            symbol(symbols.get(5), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
     175            symbol(symbols.get(6), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
     176            symbol(symbols.get(7), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
     177            symbol(symbols.get(8), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
     178            break;
     179        }
     180    }
     181
     182    private static Rectangle2D.Double symbolSize(Symbol symbol) {
     183        Symbol ssymb = symbol;
     184        while (ssymb != null) {
     185            for (Instr item : symbol) {
     186                if (item.type == Form.BBOX) {
     187                    return (Rectangle2D.Double) item.params;
     188                }
     189                if (item.type == Form.SYMB) {
     190                    ssymb = ((SubSymbol) item.params).instr;
     191                    break;
     192                }
     193            }
     194            if (ssymb == symbol)
     195                break;
     196        }
     197        return null;
     198    }
     199
     200    public static void lineSymbols(Symbol prisymb, double space, Symbol secsymb, Symbol tersymb, int ratio, Color col) {
     201        if ((Rules.feature.geom.prim == Pflag.NOSP) || (Rules.feature.geom.prim == Pflag.POINT))
     202            return;
     203        Rectangle2D.Double prect = symbolSize(prisymb);
     204        Rectangle2D.Double srect = symbolSize(secsymb);
     205        Rectangle2D.Double trect = symbolSize(tersymb);
     206        if (srect == null)
     207            ratio = 0;
     208        if (prect != null) {
     209            double psize = Math.abs(prect.getY()) * sScale;
     210            double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
     211            double tsize = (trect != null) ? Math.abs(srect.getY()) * sScale : 0;
     212            Point2D prev = new Point2D.Double();
     213            Point2D next = new Point2D.Double();
     214            Point2D curr = new Point2D.Double();
     215            Point2D succ = new Point2D.Double();
     216            boolean gap = true;
     217            boolean piv = false;
     218            double len = 0;
     219            double angle = 0;
     220            int stcount = ratio;
     221            boolean stflag = false;
     222            Symbol symbol = prisymb;
     223            GeomIterator git = map.new GeomIterator(Rules.feature.geom);
     224            while (git.hasComp()) {
     225                git.nextComp();
     226                boolean first = true;
     227                while (git.hasEdge()) {
     228                    git.nextEdge();
     229                    while (git.hasNode()) {
     230                        Snode node = git.next();
     231                        if (node == null) continue;
     232                        prev = next;
     233                        next = context.getPoint(node);
     234                        angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
     235                        piv = true;
     236                        if (first) {
     237                            curr = succ = next;
     238                            gap = (space > 0);
     239                            stcount = ratio - 1;
     240                            symbol = prisymb;
     241                            len = gap ? psize * space * 0.5 : psize;
     242                            first = false;
     243                        } else {
     244                            while (curr.distance(next) >= len) {
     245                                if (piv) {
     246                                    double rem = len;
     247                                    double s = prev.distance(next);
     248                                    double p = curr.distance(prev);
     249                                    if ((s > 0) && (p > 0)) {
     250                                        double n = curr.distance(next);
     251                                        double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
     252                                        double phi = Math.asin(p / len * Math.sin(theta));
     253                                        rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
     254                                    }
     255                                    succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
     256                                    piv = false;
     257                                } else {
     258                                    succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
     259                                }
     260                                if (!gap) {
     261                                    Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(), new Scheme(col),
     262                                            new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX())) + Math.toRadians(90))));
     263                                }
     264                                if (space > 0)
     265                                    gap = !gap;
     266                                curr = succ;
     267                                len = gap ? (psize * space) : (--stcount == 0) ? (stflag ? tsize : ssize) : psize;
     268                                if (stcount == 0) {
     269                                    symbol = stflag ? tersymb : secsymb;
     270                                    if (trect != null)
     271                                        stflag = !stflag;
     272                                    stcount = ratio;
     273                                } else {
     274                                    symbol = prisymb;
     275                                }
     276                            }
     277                        }
     278                    }
     279                }
     280            }
     281        }
     282    }
     283
     284    public static void lineVector(LineStyle style) {
     285        Path2D.Double p = new Path2D.Double();
     286        p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     287        Point2D point;
     288        GeomIterator git = map.new GeomIterator(Rules.feature.geom);
     289        while (git.hasComp()) {
     290            git.nextComp();
     291            boolean first = true;
     292            while (git.hasEdge()) {
     293                git.nextEdge();
     294                point = context.getPoint(git.next());
     295                if (first) {
     296                    p.moveTo(point.getX(), point.getY());
     297                    first = false;
     298                } else {
     299                    p.lineTo(point.getX(), point.getY());
     300                }
     301                while (git.hasNode()) {
     302                    Snode node = git.next();
     303                    if (node == null) continue;
     304                    point = context.getPoint(node);
     305                    p.lineTo(point.getX(), point.getY());
     306                }
     307            }
     308        }
     309        if ((style.fill != null) && (Rules.feature.geom.prim == Pflag.AREA)) {
     310            g2.setPaint(style.fill);
     311            g2.fill(p);
     312        }
     313        if (style.line != null) {
     314            if (style.dash != null) {
     315                float[] dash = new float[style.dash.length];
     316                System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
     317                for (int i = 0; i < style.dash.length; i++) {
     318                    dash[i] *= (float) sScale;
     319                }
     320                g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
     321            } else {
     322                g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     323            }
     324            g2.setPaint(style.line);
     325            g2.draw(p);
     326        }
     327    }
     328
     329    public static void lineCircle(LineStyle style, double radius, UniHLU units) {
     330        switch (units) {
     331        case HLU_FEET:
     332            radius /= 6076;
     333            break;
     334        case HLU_KMTR:
     335            radius /= 1.852;
     336            break;
     337        case HLU_HMTR:
     338            radius /= 18.52;
     339            break;
     340        case HLU_SMIL:
     341            radius /= 1.15078;
     342            break;
     343        case HLU_NMIL:
     344            break;
     345        default:
     346            radius /= 1852;
     347            break;
     348        }
     349        radius *= context.mile(Rules.feature);
     350        Symbol circle = new Symbol();
     351        if (style.fill != null) {
     352            circle.add(new Instr(Form.FILL, style.fill));
     353            circle.add(new Instr(Form.RSHP, new Ellipse2D.Double(-radius, -radius, radius*2, radius*2)));
     354        }
     355        circle.add(new Instr(Form.FILL, style.line));
     356        circle.add(new Instr(Form.STRK, new BasicStroke(style.width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, style.dash, 0)));
     357        circle.add(new Instr(Form.ELPS, new Ellipse2D.Double(-radius, -radius, radius*2, radius*2)));
     358        Point2D point = context.getPoint(Rules.feature.geom.centre);
     359        Symbols.drawSymbol(g2, circle, 1, point.getX(), point.getY(), null, null);
     360    }
     361
     362    public static void fillPattern(BufferedImage image) {
     363        Path2D.Double p = new Path2D.Double();
     364        p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     365        Point2D point;
     366        switch (Rules.feature.geom.prim) {
     367        case POINT:
     368            point = context.getPoint(Rules.feature.geom.centre);
     369            g2.drawImage(image, new AffineTransformOp(AffineTransform.getScaleInstance(sScale, sScale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
     370                    (int) (point.getX() - (50 * sScale)), (int) (point.getY() - (50 * sScale)));
     371            break;
     372        case AREA:
     373            GeomIterator git = map.new GeomIterator(Rules.feature.geom);
     374            while (git.hasComp()) {
     375                git.nextComp();
     376                boolean newComp = true;
     377                while (git.hasEdge()) {
     378                    git.nextEdge();
     379                    point = context.getPoint(git.next());
     380                    if (newComp) {
     381                        p.moveTo(point.getX(), point.getY());
     382                        newComp = false;
     383                    } else {
     384                        p.lineTo(point.getX(), point.getY());
     385                    }
     386                    while (git.hasNode()) {
     387                        Snode node = git.next();
     388                        if (node == null) continue;
     389                        point = context.getPoint(node);
     390                        p.lineTo(point.getX(), point.getY());
     391                    }
     392                }
     393            }
     394            g2.setPaint(new TexturePaint(image, new Rectangle(0, 0, 1 + (int) (300 * sScale), 1 + (int) (300 * sScale))));
     395            g2.fill(p);
     396            break;
     397        default:
     398            break;
     399        }
     400    }
     401
     402    public static void labelText(String str, Font font, Color tc) {
     403        labelText(str, font, tc, LabelStyle.NONE, null, null, null);
     404    }
     405
     406    public static void labelText(String str, Font font, Color tc, Delta delta) {
     407        labelText(str, font, tc, LabelStyle.NONE, null, null, delta);
     408    }
     409
     410    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg) {
     411        labelText(str, font, tc, style, fg, null, null);
     412    }
     413
     414    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg) {
     415        labelText(str, font, tc, style, fg, bg, null);
     416    }
     417
     418    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Delta delta) {
     419        labelText(str, font, tc, style, fg, null, delta);
     420    }
     421
     422    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg, Delta delta) {
     423        if (delta == null) delta = new Delta(Handle.CC);
     424        if (bg == null) bg = new Color(0x00000000, true);
     425        if ((str == null) || (str.isEmpty())) str = " ";
     426        FontRenderContext frc = g2.getFontRenderContext();
     427        GlyphVector gv = font.deriveFont((float) (font.getSize())).createGlyphVector(frc, str.equals(" ") ? "M" : str);
     428        Rectangle2D bounds = gv.getVisualBounds();
     429        double width = bounds.getWidth();
     430        double height = bounds.getHeight();
     431        Symbol label = new Symbol();
     432        double lx, ly, tx, ty;
     433        switch (style) {
     434        case RRCT:
     435            width += height * 1.0;
     436            height *= 1.5;
     437            if (width < height) width = height;
     438            lx = -width / 2;
     439            ly = -height / 2;
     440            tx = lx + (height * 0.34);
     441            ty = ly + (height * 0.17);
     442            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
     443            label.add(new Instr(Form.FILL, bg));
     444            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
     445            label.add(new Instr(Form.FILL, fg));
     446            label.add(new Instr(Form.STRK, new BasicStroke(1 + (int) (height/10), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     447            label.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
     448            break;
     449        case VCLR:
     450            width += height * 1.0;
     451            height *= 2.0;
     452            if (width < height) width = height;
     453            lx = -width / 2;
     454            ly = -height / 2;
     455            tx = lx + (height * 0.27);
     456            ty = ly + (height * 0.25);
     457            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
     458            label.add(new Instr(Form.FILL, bg));
     459            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
     460            label.add(new Instr(Form.FILL, fg));
     461            int sw = 1 + (int) (height/10);
     462            double po = sw / 2;
     463            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     464            Path2D.Double p = new Path2D.Double(); p.moveTo(-height*0.2, -ly-po); p.lineTo(height*0.2, -ly-po); p.moveTo(0, -ly-po); p.lineTo(0, -ly-po-(height*0.15));
     465            p.moveTo(-height*0.2, ly+po); p.lineTo((height*0.2), ly+po); p.moveTo(0, ly+po); p.lineTo(0, ly+po+(height*0.15));
     466            label.add(new Instr(Form.PLIN, p));
     467            break;
     468        case PCLR:
     469            width += height * 1.0;
     470            height *= 2.0;
     471            if (width < height) width = height;
     472            lx = -width / 2;
     473            ly = -height / 2;
     474            tx = lx + (height * 0.27);
     475            ty = ly + (height * 0.25);
     476            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
     477            label.add(new Instr(Form.FILL, bg));
     478            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
     479            label.add(new Instr(Form.FILL, fg));
     480            sw = 1 + (int) (height/10);
     481            po = sw / 2;
     482            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     483            p = new Path2D.Double(); p.moveTo(-height*0.2, -ly-po); p.lineTo(height*0.2, -ly-po); p.moveTo(0, -ly-po); p.lineTo(0, -ly-po-(height*0.15));
     484            p.moveTo(-height*0.2, ly+po); p.lineTo((height*0.2), ly+po); p.moveTo(0, ly+po); p.lineTo(0, ly+po+(height*0.15));
     485            label.add(new Instr(Form.PLIN, p));
     486            label.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.CableFlash, 1, 0, 0, null, new Delta(Handle.CC, new AffineTransform(0, -1, 1, 0, -width/2, 0)))));
     487            label.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.CableFlash, 1, 0, 0, null, new Delta(Handle.CC, new AffineTransform(0, -1, 1, 0, width/2, 0)))));
     488            break;
     489        case HCLR:
     490            width += height * 1.5;
     491            height *= 1.5;
     492            if (width < height) width = height;
     493            lx = -width / 2;
     494            ly = -height / 2;
     495            tx = lx + (height * 0.5);
     496            ty = ly + (height * 0.17);
     497            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
     498            label.add(new Instr(Form.FILL, bg));
     499            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
     500            label.add(new Instr(Form.FILL, fg));
     501            sw = 1 + (int) (height/10);
     502            double vo = height / 4;
     503            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     504            p = new Path2D.Double(); p.moveTo(-width*0.4-sw, -ly-vo); p.lineTo(-width*0.4-sw, ly+vo); p.moveTo(-width*0.4-sw, 0); p.lineTo(-width*0.4+sw, 0);
     505            p.moveTo(width*0.4+sw, -ly-vo); p.lineTo(width*0.4+sw, ly+vo); p.moveTo(width*0.4-sw, 0); p.lineTo(width*0.4+sw, 0);
     506            label.add(new Instr(Form.PLIN, p));
     507            break;
     508        default:
     509            lx = -width / 2;
     510            ly = -height / 2;
     511            tx = lx;
     512            ty = ly;
     513            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
     514            break;
     515        }
     516        label.add(new Instr(Form.TEXT, new Caption(str, font, tc, new Delta(Handle.TL, AffineTransform.getTranslateInstance(tx, ty)))));
     517        Point2D point = context.getPoint(Rules.feature.geom.centre);
     518        Symbols.drawSymbol(g2, label, sScale, point.getX(), point.getY(), null, delta);
     519    }
     520
     521    public static void lineText(String str, Font font, Color colour, double dy) {
     522        if (!str.isEmpty()) {
     523            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
     524            g2.setPaint(colour);
     525            FontRenderContext frc = g2.getFontRenderContext();
     526            GlyphVector gv = font.deriveFont(font.getSize2D() * (float) sScale).createGlyphVector(frc, str);
     527            double width = gv.getVisualBounds().getWidth();
     528            double height = gv.getVisualBounds().getHeight();
     529            double offset = (Rules.feature.geom.length * context.mile(Rules.feature) - width) / 2;
     530            if (offset > 0) {
     531                Point2D before = null;
     532                Point2D after = null;
     533                ArrayList<Point2D> between = new ArrayList<>();
     534                Point2D prev = null;
     535                Point2D next = null;
     536                double length = 0;
     537                double lb = 0;
     538                double la = 0;
     539                GeomIterator git = map.new GeomIterator(Rules.feature.geom);
     540                if (git.hasComp()) {
     541                    git.nextComp();
     542                    while (git.hasEdge()) {
     543                        git.nextEdge();
     544                        while (git.hasNode()) {
     545                            Snode node = git.next();
     546                            if (node == null)
     547                                continue;
     548                            prev = next;
     549                            next = context.getPoint(node);
     550                            if (prev != null)
     551                                length += Math.sqrt(Math.pow((next.getX() - prev.getX()), 2) + Math.pow((next.getY() - prev.getY()), 2));
     552                            if (length < offset) {
     553                                before = next;
     554                                lb = la = length;
     555                            } else if (after == null) {
     556                                if (length > (offset + width)) {
     557                                    after = next;
     558                                    la = length;
     559                                    break;
     560                                } else {
     561                                    between.add(next);
     562                                }
     563                            }
     564                        }
     565                        if (after != null)
     566                            break;
     567                    }
     568                }
     569                if (after != null) {
     570                    double angle = Math.atan2((after.getY() - before.getY()), (after.getX() - before.getX()));
     571                    double rotate = Math.abs(angle) < (Math.PI / 2) ? angle : angle + Math.PI;
     572                    Point2D mid = new Point2D.Double((before.getX() + after.getX()) / 2, (before.getY() + after.getY()) / 2);
     573                    Point2D centre = context.getPoint(Rules.feature.geom.centre);
     574                    AffineTransform pos = AffineTransform.getTranslateInstance(-dy * Math.sin(rotate), dy * Math.cos(rotate));
     575                    pos.rotate(rotate);
     576                    pos.translate((mid.getX() - centre.getX()), (mid.getY() - centre.getY()));
     577                    Symbol label = new Symbol();
     578                    label.add(new Instr(Form.BBOX, new Rectangle2D.Double((-width / 2), (-height), width, height)));
     579                    label.add(new Instr(Form.TEXT, new Caption(str, font, colour, new Delta(Handle.BC))));
     580                    Symbols.drawSymbol(g2, label, sScale, centre.getX(), centre.getY(), null, new Delta(Handle.BC, pos));
     581                }
     582            }
     583        }
     584    }
     585
     586    public static void lightSector(Color col1, Color col2, double radius, double s1, double s2, Double dir, String str) {
     587        if ((zoom >= 16) && (radius > 0.2)) {
     588            radius /= (Math.pow(2, zoom-15));
     589        }
     590        double mid = (((s1 + s2) / 2) + (s1 > s2 ? 180 : 0)) % 360;
     591        g2.setStroke(new BasicStroke((float) (3.0 * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, new float[] {20 * (float) sScale, 20 * (float) sScale}, 0));
     592        g2.setPaint(Color.black);
     593        Point2D.Double centre = (Point2D.Double) context.getPoint(Rules.feature.geom.centre);
     594        double radial = radius * context.mile(Rules.feature);
     595        if (dir != null) {
     596            g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(dir)), centre.y + radial * Math.cos(Math.toRadians(dir))));
     597        } else {
     598            if ((s1 != 0.0) || (s2 != 360.0)) {
     599                g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(s1)), centre.y + radial * Math.cos(Math.toRadians(s1))));
     600                g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(s2)), centre.y + radial * Math.cos(Math.toRadians(s2))));
     601            }
     602        }
     603        double arcWidth = 10.0 * sScale;
     604        g2.setStroke(new BasicStroke((float) arcWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1));
     605        g2.setPaint(col1);
     606        g2.draw(new Arc2D.Double(centre.x - radial, centre.y - radial, 2 * radial, 2 * radial, -(s1 + 90), ((s1 < s2) ? (s1 - s2) : (s1 - s2 - 360)), Arc2D.OPEN));
     607        if (col2 != null) {
     608            g2.setPaint(col2);
     609            g2.draw(new Arc2D.Double(centre.x - radial + arcWidth, centre.y - radial + arcWidth, 2 * (radial - arcWidth), 2 * (radial - arcWidth), -(s1 + 90), ((s1 < s2) ? (s1 - s2) : (s1 - s2 - 360)), Arc2D.OPEN));
     610        }
     611        if ((str != null) && (!str.isEmpty())) {
     612            Font font = new Font("Arial", Font.PLAIN, 40);
     613            double arc = (s2 > s1) ? (s2 - s1) : (s2 - s1 + 360);
     614            double awidth = (Math.toRadians(arc) * radial);
     615            boolean hand = ((mid > 270) || (mid < 90));
     616            double phi = Math.toRadians(mid);
     617            radial += 30 * sScale;
     618            AffineTransform at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
     619            if ((font.getSize() * sScale * str.length()) < awidth) {
     620                at.rotate(Math.toRadians(mid + (hand ? 0 : 180)));
     621                labelText(str, font, Color.black, new Delta(Handle.CC, at));
     622            } else if ((font.getSize() * sScale) < awidth) {
     623                hand = (mid < 180);
     624                at.rotate(Math.toRadians(mid + (hand ? -90 : 90)));
     625                labelText(str, font, Color.black, hand ? new Delta(Handle.RC, at) : new Delta(Handle.LC, at));
     626            }
     627            if (dir != null) {
     628                font = new Font("Arial", Font.PLAIN, 30);
     629                str = dir + "°";
     630                hand = (dir > 180);
     631                phi = Math.toRadians(dir + (hand ? -0.5 : 0.5));
     632                radial -= 70 * sScale;
     633                at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
     634                at.rotate(Math.toRadians(dir + (hand ? 90 : -90)));
     635                labelText(str, font, Color.black, hand ? new Delta(Handle.BR, at) : new Delta(Handle.BL, at));
     636            }
     637        }
     638    }
    605639}
  • 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}
  • applications/editors/josm/plugins/seachart/src/render/Signals.java

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

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57obj.*;
     12import java.util.EnumMap;
     13import java.util.HashMap;
     14
     15import s57.S57obj.Obj;
    1516
    1617public class S57att { // S57 Attribute lookup tables & methods
    17  
    18  public enum Att {
    19    UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
    20    CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
    21    CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
    22    CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
    23    DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
    24    MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
    25    SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
    26    SURTYP, TECSOU, TXTDSC, TS_TSP, TS_TSV, T_ACWL, T_HWLW, T_MTOD, T_THDF, T_TINT, T_TSVL, T_VAHC, TIMEND, TIMSTA, TOPSHP, TRAFIC, VALACM, VALDCO, VALLMA, VALMAG,
    27    VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
    28    DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
    29    MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
    30    CATCCL, CATCOM, CATHBR, CATRFD, CATTML, CATGAG, CATVTR, CATTAB, CATEXS, LG_SPD, LG_SPR, LG_BME, LG_LGS, LG_DRT, LG_WDP, LG_WDU, LG_REL, LG_FNC, LG_DES, LG_PBR,
    31    LC_CSI, LC_CSE, LC_ASI, LC_ASE, LC_CCI, LC_CCE, LC_BM1, LC_BM2, LC_LG1, LC_LG2, LC_DR1, LC_DR2, LC_SP1, LC_SP2, LC_WD1, LC_WD2, LITRAD, CATCVR, HUNITS
    32  }
    33 
    34  private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
    35  static {
    36   AttS57.put(Att.UNKATT, 0); AttS57.put(Att.AGENCY, 1); AttS57.put(Att.BCNSHP, 2); AttS57.put(Att.BUISHP, 3); AttS57.put(Att.BOYSHP, 4); AttS57.put(Att.BURDEP, 5);
    37   AttS57.put(Att.CALSGN, 6); AttS57.put(Att.CATAIR, 7); AttS57.put(Att.CATACH, 8); AttS57.put(Att.CATBRG, 9); AttS57.put(Att.CATBUA, 10); AttS57.put(Att.CATCBL, 11);
    38   AttS57.put(Att.CATCAN, 12); AttS57.put(Att.CATCAM, 13); AttS57.put(Att.CATCHP, 14); AttS57.put(Att.CATCOA, 15); AttS57.put(Att.CATCTR, 16); AttS57.put(Att.CATCON, 17);
    39   AttS57.put(Att.CATCVR, 18); AttS57.put(Att.CATCRN, 19); AttS57.put(Att.CATDAM, 20); AttS57.put(Att.CATDIS, 21); AttS57.put(Att.CATDOC, 22); AttS57.put(Att.CATDPG, 23);
    40   AttS57.put(Att.CATFNC, 24); AttS57.put(Att.CATFRY, 25); AttS57.put(Att.CATFIF, 26); AttS57.put(Att.CATFOG, 27); AttS57.put(Att.CATFOR, 28); AttS57.put(Att.CATGAT, 29);
    41   AttS57.put(Att.CATHAF, 30); AttS57.put(Att.CATHLK, 31); AttS57.put(Att.CATICE, 32); AttS57.put(Att.CATINB, 33); AttS57.put(Att.CATLND, 34); AttS57.put(Att.CATLMK, 35);
    42   AttS57.put(Att.CATLAM, 36); AttS57.put(Att.CATLIT, 37); AttS57.put(Att.CATMFA, 38); AttS57.put(Att.CATMPA, 39); AttS57.put(Att.CATMOR, 40); AttS57.put(Att.CATNAV, 41);
    43   AttS57.put(Att.CATOBS, 42); AttS57.put(Att.CATOFP, 43); AttS57.put(Att.CATOLB, 44); AttS57.put(Att.CATPLE, 45); AttS57.put(Att.CATPIL, 46); AttS57.put(Att.CATPIP, 47);
    44   AttS57.put(Att.CATPRA, 48); AttS57.put(Att.CATPYL, 49); AttS57.put(Att.CATRAS, 51); AttS57.put(Att.CATRTB, 52); AttS57.put(Att.CATROS, 53); AttS57.put(Att.CATTRK, 54);
    45   AttS57.put(Att.CATRSC, 55); AttS57.put(Att.CATREA, 56); AttS57.put(Att.CATROD, 57); AttS57.put(Att.CATRUN, 58); AttS57.put(Att.CATSEA, 59); AttS57.put(Att.CATSLC, 60);
    46   AttS57.put(Att.CATSIT, 61); AttS57.put(Att.CATSIW, 62); AttS57.put(Att.CATSIL, 63); AttS57.put(Att.CATSLO, 64); AttS57.put(Att.CATSCF, 65); AttS57.put(Att.CATSPM, 66);
    47   AttS57.put(Att.CATTSS, 67); AttS57.put(Att.CATVEG, 68); AttS57.put(Att.CATWAT, 69); AttS57.put(Att.CATWED, 70); AttS57.put(Att.CATWRK, 71); AttS57.put(Att.COLOUR, 75);
    48   AttS57.put(Att.COLPAT, 76); AttS57.put(Att.COMCHA, 77); AttS57.put(Att.CONDTN, 81); AttS57.put(Att.CONRAD, 82); AttS57.put(Att.CONVIS, 83); AttS57.put(Att.CURVEL, 84);
    49   AttS57.put(Att.DATEND, 85); AttS57.put(Att.DATSTA, 86); AttS57.put(Att.DRVAL1, 87); AttS57.put(Att.DRVAL2, 88); AttS57.put(Att.ELEVAT, 90); AttS57.put(Att.ESTRNG, 91);
    50   AttS57.put(Att.EXCLIT, 92); AttS57.put(Att.EXPSOU, 93); AttS57.put(Att.FUNCTN, 94); AttS57.put(Att.HEIGHT, 95); AttS57.put(Att.HUNITS, 96); AttS57.put(Att.HORACC, 97);
    51   AttS57.put(Att.HORCLR, 98); AttS57.put(Att.HORLEN, 99); AttS57.put(Att.HORWID, 100); AttS57.put(Att.ICEFAC, 101); AttS57.put(Att.INFORM, 102); AttS57.put(Att.JRSDTN, 103);
    52   AttS57.put(Att.LIFCAP, 106); AttS57.put(Att.LITCHR, 107); AttS57.put(Att.LITVIS, 108); AttS57.put(Att.MARSYS, 109); AttS57.put(Att.MLTYLT, 110); AttS57.put(Att.NATION, 111);
    53   AttS57.put(Att.NATCON, 112); AttS57.put(Att.NATSUR, 113); AttS57.put(Att.NATQUA, 114); AttS57.put(Att.NMDATE, 115); AttS57.put(Att.OBJNAM, 116); AttS57.put(Att.ORIENT, 117);
    54   AttS57.put(Att.PEREND, 118); AttS57.put(Att.PERSTA, 119); AttS57.put(Att.PICREP, 120); AttS57.put(Att.PILDST, 121); AttS57.put(Att.PRCTRY, 122); AttS57.put(Att.PRODCT, 123);
    55   AttS57.put(Att.PUBREF, 124); AttS57.put(Att.QUASOU, 125); AttS57.put(Att.RADWAL, 126); AttS57.put(Att.RADIUS, 127); AttS57.put(Att.RYRMGV, 130); AttS57.put(Att.RESTRN, 131);
    56   AttS57.put(Att.SCAMIN, 133); AttS57.put(Att.SCVAL1, 134); AttS57.put(Att.SCVAL2, 135); AttS57.put(Att.SECTR1, 136); AttS57.put(Att.SECTR2, 137); AttS57.put(Att.SHIPAM, 138);
    57   AttS57.put(Att.SIGFRQ, 139); AttS57.put(Att.SIGGEN, 140); AttS57.put(Att.SIGGRP, 141); AttS57.put(Att.SIGPER, 142); AttS57.put(Att.SIGSEQ, 143); AttS57.put(Att.SOUACC, 144);
    58   AttS57.put(Att.SDISMX, 145); AttS57.put(Att.SDISMN, 146); AttS57.put(Att.SORDAT, 147); AttS57.put(Att.SORIND, 148); AttS57.put(Att.STATUS, 149); AttS57.put(Att.SURATH, 150);
    59   AttS57.put(Att.SUREND, 151); AttS57.put(Att.SURSTA, 152); AttS57.put(Att.SURTYP, 153); AttS57.put(Att.TECSOU, 156); AttS57.put(Att.TXTDSC, 158); AttS57.put(Att.TIMEND, 168);
    60   AttS57.put(Att.TIMSTA, 169); AttS57.put(Att.TOPSHP, 171); AttS57.put(Att.TRAFIC, 172); AttS57.put(Att.VALACM, 173); AttS57.put(Att.VALDCO, 174); AttS57.put(Att.VALLMA, 175);
    61   AttS57.put(Att.VALMAG, 176); AttS57.put(Att.VALMXR, 177); AttS57.put(Att.VALNMR, 178); AttS57.put(Att.VALSOU, 179); AttS57.put(Att.VERACC, 180); AttS57.put(Att.VERCLR, 181);
    62   AttS57.put(Att.VERCCL, 182); AttS57.put(Att.VERCOP, 183); AttS57.put(Att.VERCSA, 184); AttS57.put(Att.VERDAT, 185); AttS57.put(Att.VERLEN, 186); AttS57.put(Att.WATLEV, 187);
    63   AttS57.put(Att.CAT_TS, 188); AttS57.put(Att.NINFOM, 300); AttS57.put(Att.NOBJNM, 301); AttS57.put(Att.NPLDST, 302); AttS57.put(Att.NTXTDS, 304); AttS57.put(Att.HORDAT, 400);
    64   AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
    65  }
    66 
    67  private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
    68  static {
    69   AttIENC.put(Att.CATACH, 17000); AttIENC.put(Att.CATDIS, 17001); AttIENC.put(Att.CATSIT, 17002); AttIENC.put(Att.CATSIW, 17003); AttIENC.put(Att.RESTRN, 17004);
    70   AttIENC.put(Att.VERDAT, 17005); AttIENC.put(Att.CATBRG, 17006); AttIENC.put(Att.CATFRY, 17007); AttIENC.put(Att.CATHAF, 17008); AttIENC.put(Att.MARSYS, 17009);
    71   AttIENC.put(Att.CATCHP, 17010); AttIENC.put(Att.CATLAM, 17011); AttIENC.put(Att.CATSLC, 17012); AttIENC.put(Att.ADDMRK, 17050); AttIENC.put(Att.CATNMK, 17052);
    72   AttIENC.put(Att.CLSDNG, 17055); AttIENC.put(Att.DIRIMP, 17056); AttIENC.put(Att.DISBK1, 17057); AttIENC.put(Att.DISBK2, 17058); AttIENC.put(Att.DISIPU, 17059);
    73   AttIENC.put(Att.DISIPD, 17060); AttIENC.put(Att.ELEVA1, 17061); AttIENC.put(Att.ELEVA2, 17062); AttIENC.put(Att.FNCTNM, 17063); AttIENC.put(Att.WTWDIS, 17064);
    74   AttIENC.put(Att.BUNVES, 17065); AttIENC.put(Att.CATBRT, 17066); AttIENC.put(Att.CATBUN, 17067); AttIENC.put(Att.CATCCL, 17069); AttIENC.put(Att.CATHBR, 17070);
    75   AttIENC.put(Att.CATRFD, 17071); AttIENC.put(Att.CATTML, 17072); AttIENC.put(Att.COMCTN, 17073); AttIENC.put(Att.HORCLL, 17074); AttIENC.put(Att.HORCLW, 17075);
    76   AttIENC.put(Att.TRSHGD, 17076); AttIENC.put(Att.UNLOCD, 17077); AttIENC.put(Att.CATGAG, 17078); AttIENC.put(Att.HIGWAT, 17080); AttIENC.put(Att.HIGNAM, 17081);
    77   AttIENC.put(Att.LOWWAT, 17082); AttIENC.put(Att.LOWNAM, 17083); AttIENC.put(Att.MEAWAT, 17084); AttIENC.put(Att.MEANAM, 17085); AttIENC.put(Att.OTHWAT, 17086);
    78   AttIENC.put(Att.OTHNAM, 17087); AttIENC.put(Att.REFLEV, 17088); AttIENC.put(Att.SDRLEV, 17089); AttIENC.put(Att.VCRLEV, 17090); AttIENC.put(Att.CATVTR, 17091);
    79   AttIENC.put(Att.CATTAB, 17092); AttIENC.put(Att.SCHREF, 17093); AttIENC.put(Att.USESHP, 17094); AttIENC.put(Att.CURVHW, 17095); AttIENC.put(Att.CURVLW, 17096);
    80   AttIENC.put(Att.CURVMW, 17097); AttIENC.put(Att.CURVOW, 17098); AttIENC.put(Att.APTREF, 17099); AttIENC.put(Att.CATEXS, 17100); AttIENC.put(Att.CATCBL, 17101);
    81   AttIENC.put(Att.CATHLK, 17102); AttIENC.put(Att.HUNITS, 17103); AttIENC.put(Att.WATLEV, 17104); AttIENC.put(Att.LG_SPD, 18001); AttIENC.put(Att.LG_SPR, 18002);
    82   AttIENC.put(Att.LG_BME, 18003); AttIENC.put(Att.LG_LGS, 18004); AttIENC.put(Att.LG_DRT, 18005); AttIENC.put(Att.LG_WDP, 18006); AttIENC.put(Att.LG_WDU, 18007);
    83   AttIENC.put(Att.LG_REL, 18008); AttIENC.put(Att.LG_FNC, 18009); AttIENC.put(Att.LG_DES, 18010); AttIENC.put(Att.LG_PBR, 18011); AttIENC.put(Att.LC_CSI, 18012);
    84   AttIENC.put(Att.LC_CSE, 18013); AttIENC.put(Att.LC_ASI, 18014); AttIENC.put(Att.LC_ASE, 18015); AttIENC.put(Att.LC_CCI, 18016); AttIENC.put(Att.LC_CCE, 18017);
    85   AttIENC.put(Att.LC_BM1, 18018); AttIENC.put(Att.LC_BM2, 18019); AttIENC.put(Att.LC_LG1, 18020); AttIENC.put(Att.LC_LG2, 18021); AttIENC.put(Att.LC_DR1, 18022);
    86   AttIENC.put(Att.LC_DR2, 18023); AttIENC.put(Att.LC_SP1, 18024); AttIENC.put(Att.LC_SP2, 18025); AttIENC.put(Att.LC_WD1, 18026); AttIENC.put(Att.LC_WD2, 18027);
    87   AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
    88  }
    89  
    90  private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
    91  static {
    92   AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
    93   AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
    94   AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
    95   AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
    96   AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
    97   AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
    98   AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
    99   AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
    100   AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
    101   AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
    102   AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
    103   AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
    104   AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
    105   AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
    106   AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
    107   AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
    108   AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
    109   AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
    110   AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
    111   AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
    112   AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
    113   AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
    114   AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
    115   AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
    116   AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
    117   AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
    118   AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
    119   AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
    120   AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
    121   AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
    122   AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
    123   AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
    124   AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
    125   AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
    126   AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
    127   AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
    128   AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
    129   AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
    130   AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
    131   AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
    132   AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
    133   AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
    134   AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
    135   AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
    136   AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
    137   AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
    138   AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
    139   AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
    140   AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
    141   AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
    142   AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
    143   AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
    144   AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
    145   AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
    146   AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
    147   AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
    148  }
    149  private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static { Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
    150  private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static { Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
    151  private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static { Agency.put(Obj.UNKOBJ, Att.AGENCY); }
    152  private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static { Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
    153  private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static { Authority.put(Obj.UNKOBJ, Att.SURATH); }
    154  private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static { Availability.put(Obj.UNKOBJ, Att.BUNVES); }
    155  private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static { Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
    156  private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static { Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
    157  private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class); static {
    158   Category.put(Obj.ACHARE, Att.CATACH); Category.put(Obj.ACHBRT, Att.CATACH); Category.put(Obj.AIRARE, Att.CATAIR); Category.put(Obj.BCNCAR, Att.CATCAM); Category.put(Obj.BCNLAT, Att.CATLAM);
    159   Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM); Category.put(Obj.DAYMAR, Att.CATSPM);
    160   Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
    161   Category.put(Obj.CBLARE, Att.CATCBL); Category.put(Obj.CBLOHD, Att.CATCBL); Category.put(Obj.CBLSUB, Att.CATCBL); Category.put(Obj.CHKPNT, Att.CATCHP); Category.put(Obj.COMARE, Att.CATCOM);
    162   Category.put(Obj.COALNE, Att.CATCOA); Category.put(Obj.CONVYR, Att.CATCON); Category.put(Obj.CRANES, Att.CATCRN); Category.put(Obj.CTRPNT, Att.CATCTR); Category.put(Obj.DAMCON, Att.CATDAM);
    163   Category.put(Obj.DISMAR, Att.CATDIS); Category.put(Obj.DMPGRD, Att.CATDPG); Category.put(Obj.DOCARE, Att.CATDOC); Category.put(Obj.EXCNST, Att.CATEXS); Category.put(Obj.FERYRT, Att.CATFRY);
    164   Category.put(Obj.FNCLNE, Att.CATFNC); Category.put(Obj.FOGSIG, Att.CATFOG); Category.put(Obj.FORSTC, Att.CATFOR); Category.put(Obj.FSHFAC, Att.CATFIF); Category.put(Obj.GATCON, Att.CATGAT);
    165   Category.put(Obj.HRBFAC, Att.CATHAF); Category.put(Obj.HRBARE, Att.CATHBR); Category.put(Obj.HRBBSN, Att.CATHBR); Category.put(Obj.HULKES, Att.CATHLK); Category.put(Obj.ICEARE, Att.CATICE);
    166   Category.put(Obj.LNDRGN, Att.CATLND); Category.put(Obj.LNDMRK, Att.CATLMK); Category.put(Obj.LIGHTS, Att.CATLIT); Category.put(Obj.M_COVR, Att.CATCVR); Category.put(Obj.MARCUL, Att.CATMFA);
    167   Category.put(Obj.MIPARE, Att.CATMPA); Category.put(Obj.MORFAC, Att.CATMOR); Category.put(Obj.NAVLNE, Att.CATNAV); Category.put(Obj.NOTMRK, Att.CATNMK); Category.put(Obj.OBSTRN, Att.CATOBS);
    168   Category.put(Obj.OFSPLF, Att.CATOFP); Category.put(Obj.OILBAR, Att.CATOLB); Category.put(Obj.OSPARE, Att.CATPRA); Category.put(Obj.PILPNT, Att.CATPLE); Category.put(Obj.PILBOP, Att.CATPIL);
    169   Category.put(Obj.PIPARE, Att.CATPIP); Category.put(Obj.PIPOHD, Att.CATPIP); Category.put(Obj.PIPSOL, Att.CATPIP); Category.put(Obj.PRDARE, Att.CATPRA); Category.put(Obj.PYLONS, Att.CATPYL);
    170   Category.put(Obj.RADSTA, Att.CATRAS); Category.put(Obj.RCRTCL, Att.CATTRK); Category.put(Obj.RCTLPT, Att.CATTRK); Category.put(Obj.RDOSTA, Att.CATROS); Category.put(Obj.RDOCAL, Att.CATCOM);
    171   Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
    172   Category.put(Obj.RTPBCN, Att.CATRTB); Category.put(Obj.ROADWY, Att.CATROD); Category.put(Obj.RUNWAY, Att.CATRUN); Category.put(Obj.SEAARE, Att.CATSEA); Category.put(Obj.SILTNK, Att.CATSIL);
    173   Category.put(Obj.SISTAT, Att.CATSIT); Category.put(Obj.SISTAW, Att.CATSIW); Category.put(Obj.SLCONS, Att.CATSLC); Category.put(Obj.SLOTOP, Att.CATSLO); Category.put(Obj.SLOGRD, Att.CATSLO);
    174   Category.put(Obj.SMCFAC, Att.CATSCF); Category.put(Obj.TERMNL, Att.CATTML); Category.put(Obj.TS_FEB, Att.CAT_TS); Category.put(Obj.TSELNE, Att.CATTSS); Category.put(Obj.TSEZNE, Att.CATTSS);
    175   Category.put(Obj.TSSBND, Att.CATTSS); Category.put(Obj.TSSCRS, Att.CATTSS); Category.put(Obj.TSSLPT, Att.CATTSS); Category.put(Obj.TSSRON, Att.CATTSS); Category.put(Obj.TWRTPT, Att.CATTRK);
    176   Category.put(Obj.VEGATN, Att.CATVEG); Category.put(Obj.VEHTRF, Att.CATVTR); Category.put(Obj.WATTUR, Att.CATWAT); Category.put(Obj.WEDKLP, Att.CATWED); Category.put(Obj.WRECKS, Att.CATWRK);
    177   Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
    178  }
    179  
    180  private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static { Channel.put(Obj.UNKOBJ, Att.COMCHA); }
    181  private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static { Character.put(Obj.UNKOBJ, Att.LITCHR); }
    182  private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static { Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
    183  private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static { Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
    184  private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static { Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
    185  private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static { Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
    186  private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static { Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
    187  private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static { Colour.put(Obj.UNKOBJ, Att.COLOUR); }
    188  private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static { Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
    189  private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static { Communication.put(Obj.UNKOBJ, Att.COMCTN); }
    190  private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static { Condition.put(Obj.UNKOBJ, Att.CONDTN); }
    191  private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static { Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
    192  private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static { Construction.put(Obj.UNKOBJ, Att.NATCON); }
    193  private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static { Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
    194  private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static { Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
    195  private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static { Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
    196  private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static { Description.put(Obj.UNKOBJ, Att.TXTDSC); }
    197  private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static { Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
    198  private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static { Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
    199  private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static { Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
    200  private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static { Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
    201  private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static { Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
    202  private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static { Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
    203  private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static { End_date.put(Obj.UNKOBJ, Att.DATEND); }
    204  private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static { End_time.put(Obj.UNKOBJ, Att.TIMEND); }
    205  private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static { Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
    206  private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static { Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
    207  private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static { Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
    208  private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static { Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
    209  private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static { Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
    210  private static final EnumMap<Obj, Att> Function = new EnumMap<>(Obj.class); static { Function.put(Obj.BUISGL, Att.FUNCTN); Function.put(Obj.LNDMRK, Att.FUNCTN); Function.put(Obj.NOTMRK, Att.FNCTNM); }
    211  private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static { Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
    212  private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static { Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
    213  private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static { Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
    214  private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static { Group.put(Obj.UNKOBJ, Att.SIGGRP); }
    215  private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static { Height.put(Obj.UNKOBJ, Att.HEIGHT); }
    216  private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static { High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
    217  private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static { High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
    218  private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static { High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
    219  private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static { Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
    220  private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static { Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
    221  private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static { Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
    222  private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static { Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
    223  private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static { Information.put(Obj.UNKOBJ, Att.INFORM); }
    224  private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static { Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
    225  private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static { Length.put(Obj.UNKOBJ, Att.HORLEN); }
    226  private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static { Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
    227  private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static { Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
    228  private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static { Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
    229  private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static { Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
    230  private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static { Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
    231  private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static { Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
    232  private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static { Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
    233  private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static { Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
    234  private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static { Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
    235  private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static { Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
    236  private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static { Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
    237  private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static { Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
    238  private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static { Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
    239  private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static { Message.put(Obj.UNKOBJ, Att.UPDMSG); }
    240  private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static { Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
    241  private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static { Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
    242  private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static { Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
    243  private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static { Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
    244  private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static { Name.put(Obj.UNKOBJ, Att.OBJNAM); }
    245  private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static { National_information.put(Obj.UNKOBJ, Att.NINFOM); }
    246  private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static { Nationality.put(Obj.UNKOBJ, Att.NATION); }
    247  private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static { National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
    248  private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static { National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
    249  private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static { National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
    250  private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static { Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
    251  private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static { Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
    252  private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static { Operation.put(Obj.UNKOBJ, Att.CATTAB); }
    253  private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static { Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
    254  private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static { Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
    255  private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static { Period.put(Obj.UNKOBJ, Att.SIGPER); }
    256  private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static { Period_end.put(Obj.UNKOBJ, Att.PEREND); }
    257  private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static { Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
    258  private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static { Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
    259  private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static { Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
    260  private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static { Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
    261  private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static { Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
    262  private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static { Product.put(Obj.UNKOBJ, Att.PRODCT); }
    263  private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static { Quality.put(Obj.UNKOBJ, Att.QUASOU); }
    264  private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static { Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
    265  private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static { Range.put(Obj.UNKOBJ, Att.VALNMR); }
    266  private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static { Reference.put(Obj.UNKOBJ, Att.PUBREF); }
    267  private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static { Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
    268  private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static { Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
    269  private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static { Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
    270  private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static { Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
    271   Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
    272   Shape.put(Obj.BOYCAR, Att.BOYSHP); Shape.put(Obj.BOYISD, Att.BOYSHP); Shape.put(Obj.BOYLAT, Att.BOYSHP); Shape.put(Obj.BOYSAW, Att.BOYSHP); Shape.put(Obj.BOYSPP, Att.BOYSHP);
    273   Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
    274   Shape.put(Obj.SILTNK, Att.BUISHP);
    275  }
    276  private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static { Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
    277  private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static { Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
    278  private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static { Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
    279  private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static { Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
    280  private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static { Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
    281  private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static { Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
    282  private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static { Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
    283  private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static { Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
    284  private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static { Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
    285  private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static { Status.put(Obj.UNKOBJ, Att.STATUS); }
    286  private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static { Surface.put(Obj.UNKOBJ, Att.NATSUR); }
    287  private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static { Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
    288  private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static { Survey.put(Obj.UNKOBJ, Att.SURTYP); }
    289  private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static { Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
    290  private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static { Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
    291  private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static { System.put(Obj.UNKOBJ, Att.MARSYS); }
    292  private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static { Technique.put(Obj.UNKOBJ, Att.TECSOU); }
    293  private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static { Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
    294  private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static { Units.put(Obj.UNKOBJ, Att.HUNITS); }
    295  private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static { Use.put(Obj.UNKOBJ, Att.USESHP); }
    296  private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static { Variation.put(Obj.UNKOBJ, Att.VALMAG); }
    297  private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static { Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
    298  private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static { Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
    299  private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static { Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
    300  private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static { Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
    301  private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static { Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
    302  private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static { Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
    303  private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static { Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
    304  private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static { Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
    305  private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static { Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
    306  private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static { Width.put(Obj.UNKOBJ, Att.HORWID); }
    307  private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static { Year.put(Obj.UNKOBJ, Att.RYRMGV); }
    308  
    309  private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
    310  static {
    311   StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
    312   StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
    313   StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
    314   StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
    315   StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
    316   StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
    317   StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
    318   StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
    319   StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
    320   StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
    321   StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
    322   StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
    323   StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
    324   StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
    325   StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
    326   StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
    327   StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
    328   StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
    329   StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
    330   StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
    331   StrAtt.put("national_name", National_name); StrAtt.put("national_pilot_district", National_pilot_district); StrAtt.put("nm_date", Nm_date); StrAtt.put("other_velocity", Other_velocity);
    332   StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
    333   StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
    334   StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
    335   StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
    336   StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
    337   StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
    338   StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
    339   StrAtt.put("survey_end", Survey_end); StrAtt.put("survey_start", Survey_start); StrAtt.put("system", System); StrAtt.put("technique", Technique); StrAtt.put("traffic_flow", Traffic_flow);
    340   StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
    341   StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
    342   StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
    343  }
    344 
    345  public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
    346                 for (Att att : AttS57.keySet()) {
    347                         if (AttS57.get(att) == attl) return att;
    348                 }
    349                 for (Att att : AttIENC.keySet()) {
    350                         if (AttIENC.get(att) == attl) return att;
    351                 }
    352   return Att.UNKATT;
    353  }
    354  
    355  public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
    356   if (AttS57.containsKey(attribute))
    357    return AttS57.get(attribute);
    358   else if (AttIENC.containsKey(attribute))
    359    return AttIENC.get(attribute);
    360   return 0;
    361  }
    362 
    363  public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
    364    return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
    365  }
    366 
    367  public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
    368   String str = AttStr.get(attribute);
    369   return str != null ? str : "";
    370  }
    371  
    372  public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
    373    if ((attribute != null) && !attribute.isEmpty()) {
    374    EnumMap<Obj, Att> map = StrAtt.get(attribute);
    375    if (map != null) {
    376     if (map.containsKey(obj)) {
    377      return map.get(obj);
    378     } else if (map.containsKey(Obj.UNKOBJ)) {
    379      return map.get(Obj.UNKOBJ);
    380     } else {
    381      return Att.UNKATT;
    382     }
    383    }
    384    }
    385   return Att.UNKATT;
    386  }
    387 
     18    // CHECKSTYLE.OFF: LineLength
     19
     20    public enum Att {
     21        UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
     22        CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
     23        CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
     24        CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
     25        DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
     26        MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
     27        SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
     28        SURTYP, TECSOU, TXTDSC, TS_TSP, TS_TSV, T_ACWL, T_HWLW, T_MTOD, T_THDF, T_TINT, T_TSVL, T_VAHC, TIMEND, TIMSTA, TOPSHP, TRAFIC, VALACM, VALDCO, VALLMA, VALMAG,
     29        VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
     30        DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
     31        MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
     32        CATCCL, CATCOM, CATHBR, CATRFD, CATTML, CATGAG, CATVTR, CATTAB, CATEXS, LG_SPD, LG_SPR, LG_BME, LG_LGS, LG_DRT, LG_WDP, LG_WDU, LG_REL, LG_FNC, LG_DES, LG_PBR,
     33        LC_CSI, LC_CSE, LC_ASI, LC_ASE, LC_CCI, LC_CCE, LC_BM1, LC_BM2, LC_LG1, LC_LG2, LC_DR1, LC_DR2, LC_SP1, LC_SP2, LC_WD1, LC_WD2, LITRAD, CATCVR, HUNITS
     34    }
     35
     36    private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
     37    static {
     38        AttS57.put(Att.UNKATT, 0); AttS57.put(Att.AGENCY, 1); AttS57.put(Att.BCNSHP, 2); AttS57.put(Att.BUISHP, 3); AttS57.put(Att.BOYSHP, 4); AttS57.put(Att.BURDEP, 5);
     39        AttS57.put(Att.CALSGN, 6); AttS57.put(Att.CATAIR, 7); AttS57.put(Att.CATACH, 8); AttS57.put(Att.CATBRG, 9); AttS57.put(Att.CATBUA, 10); AttS57.put(Att.CATCBL, 11);
     40        AttS57.put(Att.CATCAN, 12); AttS57.put(Att.CATCAM, 13); AttS57.put(Att.CATCHP, 14); AttS57.put(Att.CATCOA, 15); AttS57.put(Att.CATCTR, 16); AttS57.put(Att.CATCON, 17);
     41        AttS57.put(Att.CATCVR, 18); AttS57.put(Att.CATCRN, 19); AttS57.put(Att.CATDAM, 20); AttS57.put(Att.CATDIS, 21); AttS57.put(Att.CATDOC, 22); AttS57.put(Att.CATDPG, 23);
     42        AttS57.put(Att.CATFNC, 24); AttS57.put(Att.CATFRY, 25); AttS57.put(Att.CATFIF, 26); AttS57.put(Att.CATFOG, 27); AttS57.put(Att.CATFOR, 28); AttS57.put(Att.CATGAT, 29);
     43        AttS57.put(Att.CATHAF, 30); AttS57.put(Att.CATHLK, 31); AttS57.put(Att.CATICE, 32); AttS57.put(Att.CATINB, 33); AttS57.put(Att.CATLND, 34); AttS57.put(Att.CATLMK, 35);
     44        AttS57.put(Att.CATLAM, 36); AttS57.put(Att.CATLIT, 37); AttS57.put(Att.CATMFA, 38); AttS57.put(Att.CATMPA, 39); AttS57.put(Att.CATMOR, 40); AttS57.put(Att.CATNAV, 41);
     45        AttS57.put(Att.CATOBS, 42); AttS57.put(Att.CATOFP, 43); AttS57.put(Att.CATOLB, 44); AttS57.put(Att.CATPLE, 45); AttS57.put(Att.CATPIL, 46); AttS57.put(Att.CATPIP, 47);
     46        AttS57.put(Att.CATPRA, 48); AttS57.put(Att.CATPYL, 49); AttS57.put(Att.CATRAS, 51); AttS57.put(Att.CATRTB, 52); AttS57.put(Att.CATROS, 53); AttS57.put(Att.CATTRK, 54);
     47        AttS57.put(Att.CATRSC, 55); AttS57.put(Att.CATREA, 56); AttS57.put(Att.CATROD, 57); AttS57.put(Att.CATRUN, 58); AttS57.put(Att.CATSEA, 59); AttS57.put(Att.CATSLC, 60);
     48        AttS57.put(Att.CATSIT, 61); AttS57.put(Att.CATSIW, 62); AttS57.put(Att.CATSIL, 63); AttS57.put(Att.CATSLO, 64); AttS57.put(Att.CATSCF, 65); AttS57.put(Att.CATSPM, 66);
     49        AttS57.put(Att.CATTSS, 67); AttS57.put(Att.CATVEG, 68); AttS57.put(Att.CATWAT, 69); AttS57.put(Att.CATWED, 70); AttS57.put(Att.CATWRK, 71); AttS57.put(Att.COLOUR, 75);
     50        AttS57.put(Att.COLPAT, 76); AttS57.put(Att.COMCHA, 77); AttS57.put(Att.CONDTN, 81); AttS57.put(Att.CONRAD, 82); AttS57.put(Att.CONVIS, 83); AttS57.put(Att.CURVEL, 84);
     51        AttS57.put(Att.DATEND, 85); AttS57.put(Att.DATSTA, 86); AttS57.put(Att.DRVAL1, 87); AttS57.put(Att.DRVAL2, 88); AttS57.put(Att.ELEVAT, 90); AttS57.put(Att.ESTRNG, 91);
     52        AttS57.put(Att.EXCLIT, 92); AttS57.put(Att.EXPSOU, 93); AttS57.put(Att.FUNCTN, 94); AttS57.put(Att.HEIGHT, 95); AttS57.put(Att.HUNITS, 96); AttS57.put(Att.HORACC, 97);
     53        AttS57.put(Att.HORCLR, 98); AttS57.put(Att.HORLEN, 99); AttS57.put(Att.HORWID, 100); AttS57.put(Att.ICEFAC, 101); AttS57.put(Att.INFORM, 102); AttS57.put(Att.JRSDTN, 103);
     54        AttS57.put(Att.LIFCAP, 106); AttS57.put(Att.LITCHR, 107); AttS57.put(Att.LITVIS, 108); AttS57.put(Att.MARSYS, 109); AttS57.put(Att.MLTYLT, 110); AttS57.put(Att.NATION, 111);
     55        AttS57.put(Att.NATCON, 112); AttS57.put(Att.NATSUR, 113); AttS57.put(Att.NATQUA, 114); AttS57.put(Att.NMDATE, 115); AttS57.put(Att.OBJNAM, 116); AttS57.put(Att.ORIENT, 117);
     56        AttS57.put(Att.PEREND, 118); AttS57.put(Att.PERSTA, 119); AttS57.put(Att.PICREP, 120); AttS57.put(Att.PILDST, 121); AttS57.put(Att.PRCTRY, 122); AttS57.put(Att.PRODCT, 123);
     57        AttS57.put(Att.PUBREF, 124); AttS57.put(Att.QUASOU, 125); AttS57.put(Att.RADWAL, 126); AttS57.put(Att.RADIUS, 127); AttS57.put(Att.RYRMGV, 130); AttS57.put(Att.RESTRN, 131);
     58        AttS57.put(Att.SCAMIN, 133); AttS57.put(Att.SCVAL1, 134); AttS57.put(Att.SCVAL2, 135); AttS57.put(Att.SECTR1, 136); AttS57.put(Att.SECTR2, 137); AttS57.put(Att.SHIPAM, 138);
     59        AttS57.put(Att.SIGFRQ, 139); AttS57.put(Att.SIGGEN, 140); AttS57.put(Att.SIGGRP, 141); AttS57.put(Att.SIGPER, 142); AttS57.put(Att.SIGSEQ, 143); AttS57.put(Att.SOUACC, 144);
     60        AttS57.put(Att.SDISMX, 145); AttS57.put(Att.SDISMN, 146); AttS57.put(Att.SORDAT, 147); AttS57.put(Att.SORIND, 148); AttS57.put(Att.STATUS, 149); AttS57.put(Att.SURATH, 150);
     61        AttS57.put(Att.SUREND, 151); AttS57.put(Att.SURSTA, 152); AttS57.put(Att.SURTYP, 153); AttS57.put(Att.TECSOU, 156); AttS57.put(Att.TXTDSC, 158); AttS57.put(Att.TIMEND, 168);
     62        AttS57.put(Att.TIMSTA, 169); AttS57.put(Att.TOPSHP, 171); AttS57.put(Att.TRAFIC, 172); AttS57.put(Att.VALACM, 173); AttS57.put(Att.VALDCO, 174); AttS57.put(Att.VALLMA, 175);
     63        AttS57.put(Att.VALMAG, 176); AttS57.put(Att.VALMXR, 177); AttS57.put(Att.VALNMR, 178); AttS57.put(Att.VALSOU, 179); AttS57.put(Att.VERACC, 180); AttS57.put(Att.VERCLR, 181);
     64        AttS57.put(Att.VERCCL, 182); AttS57.put(Att.VERCOP, 183); AttS57.put(Att.VERCSA, 184); AttS57.put(Att.VERDAT, 185); AttS57.put(Att.VERLEN, 186); AttS57.put(Att.WATLEV, 187);
     65        AttS57.put(Att.CAT_TS, 188); AttS57.put(Att.NINFOM, 300); AttS57.put(Att.NOBJNM, 301); AttS57.put(Att.NPLDST, 302); AttS57.put(Att.NTXTDS, 304); AttS57.put(Att.HORDAT, 400);
     66        AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
     67    }
     68
     69    private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
     70    static {
     71        AttIENC.put(Att.CATACH, 17000); AttIENC.put(Att.CATDIS, 17001); AttIENC.put(Att.CATSIT, 17002); AttIENC.put(Att.CATSIW, 17003); AttIENC.put(Att.RESTRN, 17004);
     72        AttIENC.put(Att.VERDAT, 17005); AttIENC.put(Att.CATBRG, 17006); AttIENC.put(Att.CATFRY, 17007); AttIENC.put(Att.CATHAF, 17008); AttIENC.put(Att.MARSYS, 17009);
     73        AttIENC.put(Att.CATCHP, 17010); AttIENC.put(Att.CATLAM, 17011); AttIENC.put(Att.CATSLC, 17012); AttIENC.put(Att.ADDMRK, 17050); AttIENC.put(Att.CATNMK, 17052);
     74        AttIENC.put(Att.CLSDNG, 17055); AttIENC.put(Att.DIRIMP, 17056); AttIENC.put(Att.DISBK1, 17057); AttIENC.put(Att.DISBK2, 17058); AttIENC.put(Att.DISIPU, 17059);
     75        AttIENC.put(Att.DISIPD, 17060); AttIENC.put(Att.ELEVA1, 17061); AttIENC.put(Att.ELEVA2, 17062); AttIENC.put(Att.FNCTNM, 17063); AttIENC.put(Att.WTWDIS, 17064);
     76        AttIENC.put(Att.BUNVES, 17065); AttIENC.put(Att.CATBRT, 17066); AttIENC.put(Att.CATBUN, 17067); AttIENC.put(Att.CATCCL, 17069); AttIENC.put(Att.CATHBR, 17070);
     77        AttIENC.put(Att.CATRFD, 17071); AttIENC.put(Att.CATTML, 17072); AttIENC.put(Att.COMCTN, 17073); AttIENC.put(Att.HORCLL, 17074); AttIENC.put(Att.HORCLW, 17075);
     78        AttIENC.put(Att.TRSHGD, 17076); AttIENC.put(Att.UNLOCD, 17077); AttIENC.put(Att.CATGAG, 17078); AttIENC.put(Att.HIGWAT, 17080); AttIENC.put(Att.HIGNAM, 17081);
     79        AttIENC.put(Att.LOWWAT, 17082); AttIENC.put(Att.LOWNAM, 17083); AttIENC.put(Att.MEAWAT, 17084); AttIENC.put(Att.MEANAM, 17085); AttIENC.put(Att.OTHWAT, 17086);
     80        AttIENC.put(Att.OTHNAM, 17087); AttIENC.put(Att.REFLEV, 17088); AttIENC.put(Att.SDRLEV, 17089); AttIENC.put(Att.VCRLEV, 17090); AttIENC.put(Att.CATVTR, 17091);
     81        AttIENC.put(Att.CATTAB, 17092); AttIENC.put(Att.SCHREF, 17093); AttIENC.put(Att.USESHP, 17094); AttIENC.put(Att.CURVHW, 17095); AttIENC.put(Att.CURVLW, 17096);
     82        AttIENC.put(Att.CURVMW, 17097); AttIENC.put(Att.CURVOW, 17098); AttIENC.put(Att.APTREF, 17099); AttIENC.put(Att.CATEXS, 17100); AttIENC.put(Att.CATCBL, 17101);
     83        AttIENC.put(Att.CATHLK, 17102); AttIENC.put(Att.HUNITS, 17103); AttIENC.put(Att.WATLEV, 17104); AttIENC.put(Att.LG_SPD, 18001); AttIENC.put(Att.LG_SPR, 18002);
     84        AttIENC.put(Att.LG_BME, 18003); AttIENC.put(Att.LG_LGS, 18004); AttIENC.put(Att.LG_DRT, 18005); AttIENC.put(Att.LG_WDP, 18006); AttIENC.put(Att.LG_WDU, 18007);
     85        AttIENC.put(Att.LG_REL, 18008); AttIENC.put(Att.LG_FNC, 18009); AttIENC.put(Att.LG_DES, 18010); AttIENC.put(Att.LG_PBR, 18011); AttIENC.put(Att.LC_CSI, 18012);
     86        AttIENC.put(Att.LC_CSE, 18013); AttIENC.put(Att.LC_ASI, 18014); AttIENC.put(Att.LC_ASE, 18015); AttIENC.put(Att.LC_CCI, 18016); AttIENC.put(Att.LC_CCE, 18017);
     87        AttIENC.put(Att.LC_BM1, 18018); AttIENC.put(Att.LC_BM2, 18019); AttIENC.put(Att.LC_LG1, 18020); AttIENC.put(Att.LC_LG2, 18021); AttIENC.put(Att.LC_DR1, 18022);
     88        AttIENC.put(Att.LC_DR2, 18023); AttIENC.put(Att.LC_SP1, 18024); AttIENC.put(Att.LC_SP2, 18025); AttIENC.put(Att.LC_WD1, 18026); AttIENC.put(Att.LC_WD2, 18027);
     89        AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
     90    }
     91
     92    private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
     93    static {
     94        AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
     95        AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
     96        AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
     97        AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
     98        AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
     99        AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
     100        AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
     101        AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
     102        AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
     103        AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
     104        AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
     105        AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
     106        AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
     107        AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
     108        AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
     109        AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
     110        AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
     111        AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
     112        AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
     113        AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
     114        AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
     115        AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
     116        AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
     117        AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
     118        AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
     119        AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
     120        AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
     121        AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
     122        AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
     123        AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
     124        AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
     125        AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
     126        AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
     127        AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
     128        AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
     129        AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
     130        AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
     131        AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
     132        AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
     133        AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
     134        AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
     135        AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
     136        AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
     137        AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
     138        AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
     139        AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
     140        AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
     141        AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
     142        AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
     143        AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
     144        AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
     145        AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
     146        AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
     147        AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
     148        AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
     149        AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
     150    }
     151
     152    private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static {
     153        Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
     154
     155    private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static {
     156        Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
     157
     158    private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static {
     159        Agency.put(Obj.UNKOBJ, Att.AGENCY); }
     160
     161    private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static {
     162        Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
     163
     164    private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static {
     165        Authority.put(Obj.UNKOBJ, Att.SURATH); }
     166
     167    private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static {
     168        Availability.put(Obj.UNKOBJ, Att.BUNVES); }
     169
     170    private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static {
     171        Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
     172
     173    private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static {
     174        Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
     175
     176    private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class);
     177    static {
     178        Category.put(Obj.ACHARE, Att.CATACH); Category.put(Obj.ACHBRT, Att.CATACH); Category.put(Obj.AIRARE, Att.CATAIR); Category.put(Obj.BCNCAR, Att.CATCAM); Category.put(Obj.BCNLAT, Att.CATLAM);
     179        Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM); Category.put(Obj.DAYMAR, Att.CATSPM);
     180        Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
     181        Category.put(Obj.CBLARE, Att.CATCBL); Category.put(Obj.CBLOHD, Att.CATCBL); Category.put(Obj.CBLSUB, Att.CATCBL); Category.put(Obj.CHKPNT, Att.CATCHP); Category.put(Obj.COMARE, Att.CATCOM);
     182        Category.put(Obj.COALNE, Att.CATCOA); Category.put(Obj.CONVYR, Att.CATCON); Category.put(Obj.CRANES, Att.CATCRN); Category.put(Obj.CTRPNT, Att.CATCTR); Category.put(Obj.DAMCON, Att.CATDAM);
     183        Category.put(Obj.DISMAR, Att.CATDIS); Category.put(Obj.DMPGRD, Att.CATDPG); Category.put(Obj.DOCARE, Att.CATDOC); Category.put(Obj.EXCNST, Att.CATEXS); Category.put(Obj.FERYRT, Att.CATFRY);
     184        Category.put(Obj.FNCLNE, Att.CATFNC); Category.put(Obj.FOGSIG, Att.CATFOG); Category.put(Obj.FORSTC, Att.CATFOR); Category.put(Obj.FSHFAC, Att.CATFIF); Category.put(Obj.GATCON, Att.CATGAT);
     185        Category.put(Obj.HRBFAC, Att.CATHAF); Category.put(Obj.HRBARE, Att.CATHBR); Category.put(Obj.HRBBSN, Att.CATHBR); Category.put(Obj.HULKES, Att.CATHLK); Category.put(Obj.ICEARE, Att.CATICE);
     186        Category.put(Obj.LNDRGN, Att.CATLND); Category.put(Obj.LNDMRK, Att.CATLMK); Category.put(Obj.LIGHTS, Att.CATLIT); Category.put(Obj.M_COVR, Att.CATCVR); Category.put(Obj.MARCUL, Att.CATMFA);
     187        Category.put(Obj.MIPARE, Att.CATMPA); Category.put(Obj.MORFAC, Att.CATMOR); Category.put(Obj.NAVLNE, Att.CATNAV); Category.put(Obj.NOTMRK, Att.CATNMK); Category.put(Obj.OBSTRN, Att.CATOBS);
     188        Category.put(Obj.OFSPLF, Att.CATOFP); Category.put(Obj.OILBAR, Att.CATOLB); Category.put(Obj.OSPARE, Att.CATPRA); Category.put(Obj.PILPNT, Att.CATPLE); Category.put(Obj.PILBOP, Att.CATPIL);
     189        Category.put(Obj.PIPARE, Att.CATPIP); Category.put(Obj.PIPOHD, Att.CATPIP); Category.put(Obj.PIPSOL, Att.CATPIP); Category.put(Obj.PRDARE, Att.CATPRA); Category.put(Obj.PYLONS, Att.CATPYL);
     190        Category.put(Obj.RADSTA, Att.CATRAS); Category.put(Obj.RCRTCL, Att.CATTRK); Category.put(Obj.RCTLPT, Att.CATTRK); Category.put(Obj.RDOSTA, Att.CATROS); Category.put(Obj.RDOCAL, Att.CATCOM);
     191        Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
     192        Category.put(Obj.RTPBCN, Att.CATRTB); Category.put(Obj.ROADWY, Att.CATROD); Category.put(Obj.RUNWAY, Att.CATRUN); Category.put(Obj.SEAARE, Att.CATSEA); Category.put(Obj.SILTNK, Att.CATSIL);
     193        Category.put(Obj.SISTAT, Att.CATSIT); Category.put(Obj.SISTAW, Att.CATSIW); Category.put(Obj.SLCONS, Att.CATSLC); Category.put(Obj.SLOTOP, Att.CATSLO); Category.put(Obj.SLOGRD, Att.CATSLO);
     194        Category.put(Obj.SMCFAC, Att.CATSCF); Category.put(Obj.TERMNL, Att.CATTML); Category.put(Obj.TS_FEB, Att.CAT_TS); Category.put(Obj.TSELNE, Att.CATTSS); Category.put(Obj.TSEZNE, Att.CATTSS);
     195        Category.put(Obj.TSSBND, Att.CATTSS); Category.put(Obj.TSSCRS, Att.CATTSS); Category.put(Obj.TSSLPT, Att.CATTSS); Category.put(Obj.TSSRON, Att.CATTSS); Category.put(Obj.TWRTPT, Att.CATTRK);
     196        Category.put(Obj.VEGATN, Att.CATVEG); Category.put(Obj.VEHTRF, Att.CATVTR); Category.put(Obj.WATTUR, Att.CATWAT); Category.put(Obj.WEDKLP, Att.CATWED); Category.put(Obj.WRECKS, Att.CATWRK);
     197        Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
     198    }
     199
     200    private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static {
     201        Channel.put(Obj.UNKOBJ, Att.COMCHA); }
     202
     203    private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static {
     204        Character.put(Obj.UNKOBJ, Att.LITCHR); }
     205
     206    private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static {
     207        Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
     208
     209    private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static {
     210        Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
     211
     212    private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static {
     213        Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
     214
     215    private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static {
     216        Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
     217
     218    private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static {
     219        Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
     220
     221    private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static {
     222        Colour.put(Obj.UNKOBJ, Att.COLOUR); }
     223
     224    private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static {
     225        Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
     226
     227    private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static {
     228        Communication.put(Obj.UNKOBJ, Att.COMCTN); }
     229
     230    private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static {
     231        Condition.put(Obj.UNKOBJ, Att.CONDTN); }
     232
     233    private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static {
     234        Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
     235
     236    private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static {
     237        Construction.put(Obj.UNKOBJ, Att.NATCON); }
     238
     239    private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static {
     240        Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
     241
     242    private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static {
     243        Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
     244
     245    private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static {
     246        Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
     247
     248    private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static {
     249        Description.put(Obj.UNKOBJ, Att.TXTDSC); }
     250
     251    private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static {
     252        Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
     253
     254    private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static {
     255        Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
     256
     257    private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static {
     258        Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
     259
     260    private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static {
     261        Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
     262
     263    private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static {
     264        Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
     265
     266    private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static {
     267        Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
     268
     269    private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static {
     270        End_date.put(Obj.UNKOBJ, Att.DATEND); }
     271
     272    private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static {
     273        End_time.put(Obj.UNKOBJ, Att.TIMEND); }
     274
     275    private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static {
     276        Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
     277
     278    private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static {
     279        Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
     280
     281    private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static {
     282        Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
     283
     284    private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static {
     285        Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
     286
     287    private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static {
     288        Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
     289
     290    private static final EnumMap<Obj, Att> Function = new EnumMap<>(Obj.class); static {
     291        Function.put(Obj.BUISGL, Att.FUNCTN); Function.put(Obj.LNDMRK, Att.FUNCTN); Function.put(Obj.NOTMRK, Att.FNCTNM); }
     292
     293    private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static {
     294        Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
     295
     296    private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static {
     297        Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
     298
     299    private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static {
     300        Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
     301
     302    private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static {
     303        Group.put(Obj.UNKOBJ, Att.SIGGRP); }
     304
     305    private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static {
     306        Height.put(Obj.UNKOBJ, Att.HEIGHT); }
     307
     308    private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static {
     309        High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
     310
     311    private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static {
     312        High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
     313
     314    private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static {
     315        High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
     316
     317    private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static {
     318        Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
     319
     320    private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static {
     321        Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
     322
     323    private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static {
     324        Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
     325
     326    private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static {
     327        Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
     328
     329    private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static {
     330        Information.put(Obj.UNKOBJ, Att.INFORM); }
     331
     332    private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static {
     333        Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
     334
     335    private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static {
     336        Length.put(Obj.UNKOBJ, Att.HORLEN); }
     337
     338    private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static {
     339        Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
     340
     341    private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static {
     342        Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
     343
     344    private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static {
     345        Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
     346
     347    private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static {
     348        Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
     349
     350    private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static {
     351        Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
     352
     353    private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static {
     354        Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
     355
     356    private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static {
     357        Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
     358
     359    private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static {
     360        Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
     361
     362    private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static {
     363        Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
     364
     365    private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static {
     366        Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
     367
     368    private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static {
     369        Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
     370
     371    private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static {
     372        Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
     373
     374    private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static {
     375        Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
     376
     377    private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static {
     378        Message.put(Obj.UNKOBJ, Att.UPDMSG); }
     379
     380    private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static {
     381        Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
     382
     383    private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static {
     384        Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
     385
     386    private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static {
     387        Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
     388
     389    private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static {
     390        Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
     391
     392    private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static {
     393        Name.put(Obj.UNKOBJ, Att.OBJNAM); }
     394
     395    private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static {
     396        National_information.put(Obj.UNKOBJ, Att.NINFOM); }
     397
     398    private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static {
     399        Nationality.put(Obj.UNKOBJ, Att.NATION); }
     400
     401    private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static {
     402        National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
     403
     404    private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static {
     405        National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
     406
     407    private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static {
     408        National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
     409
     410    private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static {
     411        Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
     412
     413    private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static {
     414        Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
     415
     416    private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static {
     417        Operation.put(Obj.UNKOBJ, Att.CATTAB); }
     418
     419    private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static {
     420        Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
     421
     422    private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static {
     423        Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
     424
     425    private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static {
     426        Period.put(Obj.UNKOBJ, Att.SIGPER); }
     427
     428    private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static {
     429        Period_end.put(Obj.UNKOBJ, Att.PEREND); }
     430
     431    private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static {
     432        Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
     433
     434    private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static {
     435        Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
     436
     437    private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static {
     438        Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
     439
     440    private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static {
     441        Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
     442
     443    private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static {
     444        Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
     445
     446    private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static {
     447        Product.put(Obj.UNKOBJ, Att.PRODCT); }
     448
     449    private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static {
     450        Quality.put(Obj.UNKOBJ, Att.QUASOU); }
     451
     452    private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static {
     453        Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
     454
     455    private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static {
     456        Range.put(Obj.UNKOBJ, Att.VALNMR); }
     457
     458    private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static {
     459        Reference.put(Obj.UNKOBJ, Att.PUBREF); }
     460
     461    private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static {
     462        Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
     463
     464    private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static {
     465        Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
     466
     467    private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static {
     468        Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
     469
     470    private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static {
     471        Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
     472        Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
     473        Shape.put(Obj.BOYCAR, Att.BOYSHP); Shape.put(Obj.BOYISD, Att.BOYSHP); Shape.put(Obj.BOYLAT, Att.BOYSHP); Shape.put(Obj.BOYSAW, Att.BOYSHP); Shape.put(Obj.BOYSPP, Att.BOYSHP);
     474        Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
     475        Shape.put(Obj.SILTNK, Att.BUISHP);
     476    }
     477
     478    private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static {
     479        Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
     480
     481    private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static {
     482        Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
     483
     484    private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static {
     485        Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
     486
     487    private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static {
     488        Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
     489
     490    private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static {
     491        Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
     492
     493    private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static {
     494        Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
     495
     496    private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static {
     497        Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
     498
     499    private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static {
     500        Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
     501
     502    private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static {
     503        Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
     504
     505    private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static {
     506        Status.put(Obj.UNKOBJ, Att.STATUS); }
     507
     508    private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static {
     509        Surface.put(Obj.UNKOBJ, Att.NATSUR); }
     510
     511    private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static {
     512        Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
     513
     514    private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static {
     515        Survey.put(Obj.UNKOBJ, Att.SURTYP); }
     516
     517    private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static {
     518        Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
     519
     520    private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static {
     521        Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
     522
     523    private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static {
     524        System.put(Obj.UNKOBJ, Att.MARSYS); }
     525
     526    private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static {
     527        Technique.put(Obj.UNKOBJ, Att.TECSOU); }
     528
     529    private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static {
     530        Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
     531
     532    private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static {
     533        Units.put(Obj.UNKOBJ, Att.HUNITS); }
     534
     535    private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static {
     536        Use.put(Obj.UNKOBJ, Att.USESHP); }
     537
     538    private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static {
     539        Variation.put(Obj.UNKOBJ, Att.VALMAG); }
     540
     541    private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static {
     542        Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
     543
     544    private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static {
     545        Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
     546
     547    private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static {
     548        Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
     549
     550    private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static {
     551        Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
     552
     553    private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static {
     554        Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
     555
     556    private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static {
     557        Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
     558
     559    private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static {
     560        Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
     561
     562    private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static {
     563        Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
     564
     565    private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static {
     566        Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
     567
     568    private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static {
     569        Width.put(Obj.UNKOBJ, Att.HORWID); }
     570
     571    private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static {
     572        Year.put(Obj.UNKOBJ, Att.RYRMGV); }
     573
     574    private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
     575    static {
     576        StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
     577        StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
     578        StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
     579        StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
     580        StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
     581        StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
     582        StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
     583        StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
     584        StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
     585        StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
     586        StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
     587        StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
     588        StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
     589        StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
     590        StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
     591        StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
     592        StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
     593        StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
     594        StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
     595        StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
     596        StrAtt.put("national_name", National_name); StrAtt.put("national_pilot_district", National_pilot_district); StrAtt.put("nm_date", Nm_date); StrAtt.put("other_velocity", Other_velocity);
     597        StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
     598        StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
     599        StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
     600        StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
     601        StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
     602        StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
     603        StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
     604        StrAtt.put("survey_end", Survey_end); StrAtt.put("survey_start", Survey_start); StrAtt.put("system", System); StrAtt.put("technique", Technique); StrAtt.put("traffic_flow", Traffic_flow);
     605        StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
     606        StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
     607        StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
     608    }
     609
     610    public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
     611        for (Att att : AttS57.keySet()) {
     612            if (AttS57.get(att) == attl) return att;
     613        }
     614        for (Att att : AttIENC.keySet()) {
     615            if (AttIENC.get(att) == attl) return att;
     616        }
     617        return Att.UNKATT;
     618    }
     619
     620    public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
     621        if (AttS57.containsKey(attribute))
     622            return AttS57.get(attribute);
     623        else if (AttIENC.containsKey(attribute))
     624            return AttIENC.get(attribute);
     625        return 0;
     626    }
     627
     628    public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
     629        return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
     630    }
     631
     632    public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
     633        String str = AttStr.get(attribute);
     634        return str != null ? str : "";
     635    }
     636
     637    public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
     638        if ((attribute != null) && !attribute.isEmpty()) {
     639            EnumMap<Obj, Att> map = StrAtt.get(attribute);
     640            if (map != null) {
     641                if (map.containsKey(obj)) {
     642                    return map.get(obj);
     643                } else if (map.containsKey(Obj.UNKOBJ)) {
     644                    return map.get(Obj.UNKOBJ);
     645                } else {
     646                    return Att.UNKATT;
     647                }
     648            }
     649        }
     650        return Att.UNKATT;
     651    }
    388652}
  • applications/editors/josm/plugins/seachart/src/s57/S57box.java

    r32082 r32394  
    1212import java.util.ArrayList;
    1313
    14 import s57.S57map.*;
    15 import s57.S57obj.*;
     14import s57.S57map.Edge;
     15import s57.S57map.Feature;
     16import s57.S57map.Pflag;
     17import s57.S57map.Rflag;
     18import s57.S57map.Snode;
     19import s57.S57obj.Obj;
    1620
    1721public class S57box { //S57 bounding box truncation
    18        
    19         enum Ext {I, N, W, S, E }
    20        
    21         static Ext getExt(S57map map, double lat, double lon) {
    22                 if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
    23                         return Ext.N;
    24                 } else if (lon <= map.bounds.minlon) {
    25                         return Ext.W;
    26                 } else if (lat <= map.bounds.minlat) {
    27                         return Ext.S;
    28                 } else if (lon >= map.bounds.maxlon) {
    29                         return Ext.E;
    30                 }               return Ext.I;
    31         }
    32        
    33         public static void bBox(S57map map) {
    34                 /* Truncations
    35                  * Points: delete point features outside BB
    36                  * Lines: Truncate edges at BB boundaries
    37                  * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
    38                  * Remove nodes outside BB
    39                  * Remove edges that are completely outside BB
    40                  */
    41                 class Land {
    42                         long first;
    43                         Snode start;
    44                         Ext sbound;
    45                         long last;
    46                         Snode end;
    47                         Ext ebound;
    48                         Feature land;
     22    // CHECKSTYLE.OFF: LineLength
    4923
    50                         Land(Feature l) {
    51                                 land = l;
    52                                 first = last = 0;
    53                                 start = end = null;
    54                                 sbound = ebound = Ext.I;
    55                         }
    56                 }
    57                 if (map.features.get(Obj.COALNE) != null) {
    58                         ArrayList<Feature> coasts = new ArrayList<>();
    59                         ArrayList<Land> lands = new ArrayList<>();
    60                         if (map.features.get(Obj.LNDARE) == null) {
    61                                 map.features.put(Obj.LNDARE, new ArrayList<Feature>());
    62                         }
    63                         for (Feature feature : map.features.get(Obj.COALNE)) {
    64                                 Feature land = map.new Feature();
    65                                 land.id = ++map.xref;
    66                                 land.type = Obj.LNDARE;
    67                                 land.reln = Rflag.MASTER;
    68                                 land.objs.put(Obj.LNDARE, map.new ObjTab());
    69                                 land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
    70                                 if (feature.geom.prim == Pflag.AREA) {
    71                                         land.geom = feature.geom;
    72                                         map.features.get(Obj.LNDARE).add(land);
    73                                 } else if (feature.geom.prim == Pflag.LINE) {
    74                                         land.geom.prim = Pflag.LINE;
    75                                         land.geom.elems.addAll(feature.geom.elems);
    76                                         coasts.add(land);
    77                                 }
    78                         }
    79                         while (coasts.size() > 0) {
    80                                 Feature land = coasts.remove(0);
    81                                 Edge fedge = map.edges.get(land.geom.elems.get(0).id);
    82                                 long first = fedge.first;
    83                                 long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
    84                                 if (coasts.size() > 0) {
    85                                         boolean added = true;
    86                                         while (added) {
    87                                                 added = false;
    88                                                 for (int i = 0; i < coasts.size(); i++) {
    89                                                         Feature coast = coasts.get(i);
    90                                                         Edge edge = map.edges.get(coast.geom.elems.get(0).id);
    91                                                         if (edge.first == last) {
    92                                                                 land.geom.elems.add(coast.geom.elems.get(0));
    93                                                                 last = edge.last;
    94                                                                 coasts.remove(i--);
    95                                                                 added = true;
    96                                                         } else if (edge.last == first) {
    97                                                                 land.geom.elems.add(0, coast.geom.elems.get(0));
    98                                                                 first = edge.first;
    99                                                                 coasts.remove(i--);
    100                                                                 added = true;
    101                                                         }
    102                                                 }
    103                                         }
    104                                 }
    105                                 lands.add(new Land(land));
    106                         }
    107                         ArrayList<Land> islands = new ArrayList<>();
    108                         for (Land land : lands) {
    109                                 map.sortGeom(land.land);
    110                                 if (land.land.geom.prim == Pflag.AREA) {
    111                                         islands.add(land);
    112                                         map.features.get(Obj.LNDARE).add(land.land);
    113                                 }
    114                         }
    115                         for (Land island : islands) {
    116                                 lands.remove(island);
    117                         }
    118                         for (Land land : lands) {
    119                                 land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
    120                                 land.start = map.nodes.get(land.first);
    121                                 land.sbound = getExt(map, land.start.lat, land.start.lon);
    122                                 land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
    123                                 land.end = map.nodes.get(land.last);
    124                                 land.ebound = getExt(map, land.end.lat, land.end.lon);
    125                         }
    126                         islands = new ArrayList<>();
    127                         for (Land land : lands) {
    128                                 if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
    129                                         islands.add(land);
    130                                 }
    131                         }
    132                         for (Land island : islands) {
    133                                 lands.remove(island);
    134                         }
    135                         for (Land land : lands) {
    136                                 Edge nedge = map.new Edge();
    137                                 nedge.first = land.last;
    138                                 nedge.last = land.first;
    139                                 Ext bound = land.ebound;
    140                                 while (bound != land.sbound) {
    141                                         switch (bound) {
    142                                         case N:
    143                                                 nedge.nodes.add(1l);
    144                                                 bound = Ext.W;
    145                                                 break;
    146                                         case W:
    147                                                 nedge.nodes.add(2l);
    148                                                 bound = Ext.S;
    149                                                 break;
    150                                         case S:
    151                                                 nedge.nodes.add(3l);
    152                                                 bound = Ext.E;
    153                                                 break;
    154                                         case E:
    155                                                 nedge.nodes.add(4l);
    156                                                 bound = Ext.N;
    157                                                 break;
    158                                         default:
    159                                                 continue;
    160                                         }
    161                                 }
    162                                 map.edges.put(++map.xref, nedge);
    163                                 land.land.geom.elems.add(map.new Prim(map.xref));
    164                                 land.land.geom.comps.get(0).size++;
    165                                 land.land.geom.prim = Pflag.AREA;
    166                                 map.features.get(Obj.LNDARE).add(land.land);
    167                         }
    168                 }
    169                 return;
     24    enum Ext { I, N, W, S, E }
    17025
    171         }
     26    static Ext getExt(S57map map, double lat, double lon) {
     27        if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
     28            return Ext.N;
     29        } else if (lon <= map.bounds.minlon) {
     30            return Ext.W;
     31        } else if (lat <= map.bounds.minlat) {
     32            return Ext.S;
     33        } else if (lon >= map.bounds.maxlon) {
     34            return Ext.E;
     35        }
     36        return Ext.I;
     37    }
     38
     39    public static void bBox(S57map map) {
     40        /* Truncations
     41         * Points: delete point features outside BB
     42         * Lines: Truncate edges at BB boundaries
     43         * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
     44         * Remove nodes outside BB
     45         * Remove edges that are completely outside BB
     46         */
     47        class Land {
     48            long first;
     49            Snode start;
     50            Ext sbound;
     51            long last;
     52            Snode end;
     53            Ext ebound;
     54            Feature land;
     55
     56            Land(Feature l) {
     57                land = l;
     58                first = last = 0;
     59                start = end = null;
     60                sbound = ebound = Ext.I;
     61            }
     62        }
     63
     64        if (map.features.get(Obj.COALNE) != null) {
     65            ArrayList<Feature> coasts = new ArrayList<>();
     66            ArrayList<Land> lands = new ArrayList<>();
     67            if (map.features.get(Obj.LNDARE) == null) {
     68                map.features.put(Obj.LNDARE, new ArrayList<Feature>());
     69            }
     70            for (Feature feature : map.features.get(Obj.COALNE)) {
     71                Feature land = map.new Feature();
     72                land.id = ++map.xref;
     73                land.type = Obj.LNDARE;
     74                land.reln = Rflag.MASTER;
     75                land.objs.put(Obj.LNDARE, map.new ObjTab());
     76                land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
     77                if (feature.geom.prim == Pflag.AREA) {
     78                    land.geom = feature.geom;
     79                    map.features.get(Obj.LNDARE).add(land);
     80                } else if (feature.geom.prim == Pflag.LINE) {
     81                    land.geom.prim = Pflag.LINE;
     82                    land.geom.elems.addAll(feature.geom.elems);
     83                    coasts.add(land);
     84                }
     85            }
     86            while (coasts.size() > 0) {
     87                Feature land = coasts.remove(0);
     88                Edge fedge = map.edges.get(land.geom.elems.get(0).id);
     89                long first = fedge.first;
     90                long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
     91                if (coasts.size() > 0) {
     92                    boolean added = true;
     93                    while (added) {
     94                        added = false;
     95                        for (int i = 0; i < coasts.size(); i++) {
     96                            Feature coast = coasts.get(i);
     97                            Edge edge = map.edges.get(coast.geom.elems.get(0).id);
     98                            if (edge.first == last) {
     99                                land.geom.elems.add(coast.geom.elems.get(0));
     100                                last = edge.last;
     101                                coasts.remove(i--);
     102                                added = true;
     103                            } else if (edge.last == first) {
     104                                land.geom.elems.add(0, coast.geom.elems.get(0));
     105                                first = edge.first;
     106                                coasts.remove(i--);
     107                                added = true;
     108                            }
     109                        }
     110                    }
     111                }
     112                lands.add(new Land(land));
     113            }
     114            ArrayList<Land> islands = new ArrayList<>();
     115            for (Land land : lands) {
     116                map.sortGeom(land.land);
     117                if (land.land.geom.prim == Pflag.AREA) {
     118                    islands.add(land);
     119                    map.features.get(Obj.LNDARE).add(land.land);
     120                }
     121            }
     122            for (Land island : islands) {
     123                lands.remove(island);
     124            }
     125            for (Land land : lands) {
     126                land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
     127                land.start = map.nodes.get(land.first);
     128                land.sbound = getExt(map, land.start.lat, land.start.lon);
     129                land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
     130                land.end = map.nodes.get(land.last);
     131                land.ebound = getExt(map, land.end.lat, land.end.lon);
     132            }
     133            islands = new ArrayList<>();
     134            for (Land land : lands) {
     135                if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
     136                    islands.add(land);
     137                }
     138            }
     139            for (Land island : islands) {
     140                lands.remove(island);
     141            }
     142            for (Land land : lands) {
     143                Edge nedge = map.new Edge();
     144                nedge.first = land.last;
     145                nedge.last = land.first;
     146                Ext bound = land.ebound;
     147                while (bound != land.sbound) {
     148                    switch (bound) {
     149                    case N:
     150                        nedge.nodes.add(1L);
     151                        bound = Ext.W;
     152                        break;
     153                    case W:
     154                        nedge.nodes.add(2L);
     155                        bound = Ext.S;
     156                        break;
     157                    case S:
     158                        nedge.nodes.add(3L);
     159                        bound = Ext.E;
     160                        break;
     161                    case E:
     162                        nedge.nodes.add(4L);
     163                        bound = Ext.N;
     164                        break;
     165                    default:
     166                        continue;
     167                    }
     168                }
     169                map.edges.put(++map.xref, nedge);
     170                land.land.geom.elems.add(map.new Prim(map.xref));
     171                land.land.geom.comps.get(0).size++;
     172                land.land.geom.prim = Pflag.AREA;
     173                map.features.get(Obj.LNDARE).add(land.land);
     174            }
     175        }
     176        return;
     177
     178    }
    172179
    173180}
  • applications/editors/josm/plugins/seachart/src/s57/S57dat.java

    r32380 r32394  
    1111
    1212import java.io.UnsupportedEncodingException;
    13 import java.util.*;
    14 
    15 import s57.S57map.*;
    16 import s57.S57obj.*;
     13import java.util.ArrayList;
     14import java.util.Arrays;
     15import java.util.EnumMap;
     16
     17import s57.S57map.Feature;
     18import s57.S57map.Pflag;
     19import s57.S57obj.Obj;
    1720
    1821public class S57dat { // S57 ENC file fields lookup tables & methods
    19        
    20         public static class S57conv {
    21                 int asc;        // 0=A(), 1+=A(n)
    22                 int bin;        // 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE)
    23                 S57conv(int a, int b) {
    24                         asc = a; bin = b;
    25                 }
    26         }
    27        
    28         public enum S57subf { I8RN, RCNM, RCID, EXPP, INTU, DSNM, EDTN, UPDN, UADT, ISDT, STED, PRSP, PSDN, PRED, PROF, AGEN, COMT, DSTR, AALL, NALL, NOMR, NOCR, NOGR, NOLR, NOIN, NOCN,
    29                 NOED, NOFA, HDAT, VDAT, SDAT, CSCL, DUNI, HUNI, PUNI, COUN, COMF, SOMF, PROJ, PRP1, PRP2, PRP3, PRP4, FEAS, FNOR, FPMF, RPID, RYCO, RXCO, CURP, RXVL, RYVL, PRCO, ESDT,
    30                 LSDT, DCRT, CODT, PACC, HACC, SACC, FILE, LFIL, VOLM, IMPL, SLAT, WLON, NLAT, ELON, CRCS, NAM1, NAM2, OORA, OAAC, OACO, OALL, OATY, DEFN, AUTH, RFTP, RFVL, ATLB, ATDO,
    31                 ADMU, ADFT, RAVA, DVAL, DVSD, OBLB, ASET, PRIM, GRUP, OBJL, RVER, RUIN, FIDN, FIDS, ATTL, ATVL, FFUI, FFIX, NFPT, LNAM, RIND, FSUI, FSIX, NSPT, NAME, ORNT, USAG, MASK,
    32                 VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
    33 
    34         private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
    35         static {
    36                 convs.put(S57subf.I8RN, new S57conv(5,2));
    37                 convs.put(S57subf.RCNM, new S57conv(2,1)); convs.put(S57subf.RCID, new S57conv(10,4)); convs.put(S57subf.EXPP, new S57conv(1,1));
    38                 convs.put(S57subf.INTU, new S57conv(1,1)); convs.put(S57subf.DSNM, new S57conv(0,0)); convs.put(S57subf.EDTN, new S57conv(0,0));
    39                 convs.put(S57subf.UPDN, new S57conv(0,0)); convs.put(S57subf.UADT, new S57conv(8,0)); convs.put(S57subf.ISDT, new S57conv(8,0));
    40                 convs.put(S57subf.STED, new S57conv(4,0)); convs.put(S57subf.PRSP, new S57conv(3,1)); convs.put(S57subf.PSDN, new S57conv(0,0));
    41                 convs.put(S57subf.PRED, new S57conv(0,0)); convs.put(S57subf.PROF, new S57conv(2,1)); convs.put(S57subf.AGEN, new S57conv(2,2));
    42                 convs.put(S57subf.COMT, new S57conv(0,0)); convs.put(S57subf.DSTR, new S57conv(2,1)); convs.put(S57subf.AALL, new S57conv(1,1));
    43                 convs.put(S57subf.NALL, new S57conv(1,1)); convs.put(S57subf.NOMR, new S57conv(0,4)); convs.put(S57subf.NOCR, new S57conv(0,4));
    44                 convs.put(S57subf.NOGR, new S57conv(0,4)); convs.put(S57subf.NOLR, new S57conv(0,4)); convs.put(S57subf.NOIN, new S57conv(0,4));
    45                 convs.put(S57subf.NOCN, new S57conv(0,4)); convs.put(S57subf.NOED, new S57conv(0,4)); convs.put(S57subf.NOFA, new S57conv(0,4));
    46                 convs.put(S57subf.HDAT, new S57conv(3,1)); convs.put(S57subf.VDAT, new S57conv(2,1)); convs.put(S57subf.SDAT, new S57conv(2,1));
    47                 convs.put(S57subf.CSCL, new S57conv(0,4)); convs.put(S57subf.DUNI, new S57conv(2,1)); convs.put(S57subf.HUNI, new S57conv(2,1));
    48                 convs.put(S57subf.PUNI, new S57conv(2,1)); convs.put(S57subf.COUN, new S57conv(2,1)); convs.put(S57subf.COMF, new S57conv(0,4));
    49                 convs.put(S57subf.SOMF, new S57conv(0,4)); convs.put(S57subf.PROJ, new S57conv(3,1)); convs.put(S57subf.PRP1, new S57conv(0,-4));
    50                 convs.put(S57subf.PRP2, new S57conv(0,-4)); convs.put(S57subf.PRP3, new S57conv(0,-4)); convs.put(S57subf.PRP4, new S57conv(0,-4));
    51                 convs.put(S57subf.FEAS, new S57conv(0,-4)); convs.put(S57subf.FNOR, new S57conv(0,-4)); convs.put(S57subf.FPMF, new S57conv(0,4));
    52                 convs.put(S57subf.RPID, new S57conv(1,1)); convs.put(S57subf.RYCO, new S57conv(0,-4)); convs.put(S57subf.RXCO, new S57conv(0,-4));
    53                 convs.put(S57subf.CURP, new S57conv(2,1)); convs.put(S57subf.RXVL, new S57conv(0,-4)); convs.put(S57subf.RYVL, new S57conv(0,-4));
    54                 convs.put(S57subf.PRCO, new S57conv(2,2)); convs.put(S57subf.ESDT, new S57conv(8,0)); convs.put(S57subf.LSDT, new S57conv(8,0));
    55                 convs.put(S57subf.DCRT, new S57conv(0,0)); convs.put(S57subf.CODT, new S57conv(8,0)); convs.put(S57subf.PACC, new S57conv(0,4));
    56                 convs.put(S57subf.HACC, new S57conv(0,4)); convs.put(S57subf.SACC, new S57conv(0,4)); convs.put(S57subf.FILE, new S57conv(0,0));
    57                 convs.put(S57subf.LFIL, new S57conv(0,0)); convs.put(S57subf.VOLM, new S57conv(0,0)); convs.put(S57subf.IMPL, new S57conv(3,0));
    58                 convs.put(S57subf.SLAT, new S57conv(0,0)); convs.put(S57subf.WLON, new S57conv(0,0)); convs.put(S57subf.NLAT, new S57conv(0,0));
    59                 convs.put(S57subf.ELON, new S57conv(0,0)); convs.put(S57subf.CRCS, new S57conv(0,0)); convs.put(S57subf.NAM1, new S57conv(12,5));
    60                 convs.put(S57subf.NAM2, new S57conv(12,5)); convs.put(S57subf.OORA, new S57conv(1,1)); convs.put(S57subf.OAAC, new S57conv(6,0));
    61                 convs.put(S57subf.OACO, new S57conv(5,2)); convs.put(S57subf.OALL, new S57conv(0,0)); convs.put(S57subf.OATY, new S57conv(1,1));
    62                 convs.put(S57subf.DEFN, new S57conv(0,0)); convs.put(S57subf.AUTH, new S57conv(2,2)); convs.put(S57subf.RFTP, new S57conv(2,1));
    63                 convs.put(S57subf.RFVL, new S57conv(0,0)); convs.put(S57subf.ATLB, new S57conv(5,2)); convs.put(S57subf.ATDO, new S57conv(1,1));
    64                 convs.put(S57subf.ADMU, new S57conv(0,0)); convs.put(S57subf.ADFT, new S57conv(0,0)); convs.put(S57subf.RAVA, new S57conv(1,1));
    65                 convs.put(S57subf.DVAL, new S57conv(0,0)); convs.put(S57subf.DVSD, new S57conv(0,0)); convs.put(S57subf.OBLB, new S57conv(5,2));
    66                 convs.put(S57subf.ASET, new S57conv(1,1)); convs.put(S57subf.PRIM, new S57conv(1,1)); convs.put(S57subf.GRUP, new S57conv(3,1));
    67                 convs.put(S57subf.OBJL, new S57conv(5,2)); convs.put(S57subf.RVER, new S57conv(3,2)); convs.put(S57subf.RUIN, new S57conv(1,1));
    68                 convs.put(S57subf.FIDN, new S57conv(10,4)); convs.put(S57subf.FIDS, new S57conv(5,2)); convs.put(S57subf.ATTL, new S57conv(5,2));
    69                 convs.put(S57subf.ATVL, new S57conv(0,0)); convs.put(S57subf.FFUI, new S57conv(1,1)); convs.put(S57subf.FFIX, new S57conv(0,2));
    70                 convs.put(S57subf.NFPT, new S57conv(0,2)); convs.put(S57subf.LNAM, new S57conv(17,8)); convs.put(S57subf.RIND, new S57conv(0,1));
    71                 convs.put(S57subf.FSUI, new S57conv(1,1)); convs.put(S57subf.FSIX, new S57conv(0,2)); convs.put(S57subf.NSPT, new S57conv(0,2));
    72                 convs.put(S57subf.NAME, new S57conv(12,5)); convs.put(S57subf.ORNT, new S57conv(1,1)); convs.put(S57subf.USAG, new S57conv(1,1));
    73                 convs.put(S57subf.MASK, new S57conv(1,1)); convs.put(S57subf.VPUI, new S57conv(1,1)); convs.put(S57subf.VPIX, new S57conv(0,2));
    74                 convs.put(S57subf.NVPT, new S57conv(0,2)); convs.put(S57subf.TOPI, new S57conv(1,1)); convs.put(S57subf.CCUI, new S57conv(1,1));
    75                 convs.put(S57subf.CCIX, new S57conv(0,2)); convs.put(S57subf.CCNC, new S57conv(0,2)); convs.put(S57subf.YCOO, new S57conv(0,-4));
    76                 convs.put(S57subf.XCOO, new S57conv(0,-4)); convs.put(S57subf.VE3D, new S57conv(0,-4)); convs.put(S57subf.ATYP, new S57conv(1,1));
    77                 convs.put(S57subf.SURF, new S57conv(1,1)); convs.put(S57subf.ORDR, new S57conv(1,1)); convs.put(S57subf.RESO, new S57conv(0,4));
    78                 convs.put(S57subf.STPT, new S57conv(0,0)); convs.put(S57subf.CTPT, new S57conv(0,0)); convs.put(S57subf.ENPT, new S57conv(0,0));
    79                 convs.put(S57subf.CDPM, new S57conv(0,0)); convs.put(S57subf.CDPR, new S57conv(0,0));
    80         }
    81        
    82         public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
    83                 FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
    84        
    85         private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
    86         private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
    87                         S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
    88         private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
    89                         S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA ));
    90         private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
    91                         S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT ));
    92         private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
    93                         S57subf.FPMF, S57subf.COMT ));
    94         private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
    95                         S57subf.COMT ));
    96         private static ArrayList<S57subf> S57dsht = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRCO, S57subf.ESDT, S57subf.LSDT, S57subf.DCRT, S57subf.CODT, S57subf.COMT ));
    97         private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT ));
    98         private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
    99                         S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT ));
    100         private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT ));
    101         private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
    102                         S57subf.DEFN, S57subf.AUTH, S57subf.COMT ));
    103         private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
    104         private static ArrayList<S57subf> S57dddi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.ATLB, S57subf.ATDO, S57subf.ADMU, S57subf.ADFT, S57subf.AUTH, S57subf.COMT ));
    105         private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH ));
    106         private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
    107         private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB ));
    108         private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH ));
    109         private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN ));
    110         private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS ));
    111         private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
    112         private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    113         private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    114         private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT ));
    115         private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT ));
    116         private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT ));
    117         private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK ));
    118         private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN ));
    119         private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    120         private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT ));
    121         private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK ));
    122         private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC ));
    123         private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
    124         private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D ));
    125         private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF ));
    126         private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO ));
    127         private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO ));
    128         private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
    129        
    130         private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
    131         static {
    132                 fields.put(S57field.I8RI, S57i8ri);
    133                 fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
    134                 fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
    135                 fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
    136                 fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
    137                 fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
    138                 fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
    139                 fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
    140                 fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
    141                 fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d);
    142         }
    143        
    144         private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
    145         private static byte[] buffer;
    146         private static int offset;
    147         private static int maxoff;
    148         private static int index;
    149         private static S57field field;
    150         private static String aall = "US-ASCII";
    151         private static String nall = "US-ASCII";
    152         public static int rnum;
    153        
    154         private static S57conv findSubf(S57subf subf) {
    155                 ArrayList<S57subf> subs = fields.get(field);
    156                 boolean wrap = false;
    157                 while (true) {
    158                         if (index == subs.size()) {
    159                                 if (!wrap) {
    160                                         index = 0;
    161                                         wrap = true;
    162                                 } else {
    163                                         System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
    164                                         System.exit(-1);
    165                                 }
    166                         }
    167                         S57subf sub = subs.get(index++);
    168                         S57conv conv = convs.get(sub);
    169                         if (sub == subf) {
    170                                 return conv;
    171                         } else {
    172                                 offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
    173                         }
    174                 }
    175         }
    176        
    177         public static void setField(byte[] buf, int off, S57field fld, int len) {
    178                 buffer = buf;
    179                 offset = off;
    180                 maxoff = off + len - 1;
    181                 field = fld;
    182                 index = 0;
    183         }
    184        
    185         public static boolean more() {
    186                 return (offset < maxoff);
    187         }
    188        
    189         public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
    190                 buffer = buf;
    191                 offset = off;
    192                 index = 0;
    193                 return decSubf(fld, subf);
    194         }
    195        
    196         public static Object decSubf(S57field fld, S57subf subf) {
    197                 field = fld;
    198                 index = 0;
    199                 return decSubf(subf);
    200         }
    201 
    202         public static Object decSubf(S57subf subf) {
    203                 S57conv conv = findSubf(subf);
    204                 if (conv.bin == 0) {
    205                         String str = "";
    206                         int i = 0;
    207                         if (conv.asc == 0) {
    208                                 for (i=0; buffer[offset+i] != 0x1f; i++) {}
    209                                 try {
    210                                         String charset = "";
    211                                         if (field == S57field.ATTF) charset = aall;
    212                                         else if (field == S57field.NATF) charset = nall;
    213                                         else charset = "US-ASCII";
    214                                         str = new String(buffer, offset, i, charset);
    215                                 } catch (UnsupportedEncodingException e) {
    216                                         e.printStackTrace();
    217                                 }
    218                                 offset += i + 1;
    219                         } else {
    220                                 str = new String(buffer, offset, conv.asc);
    221                                 offset += conv.asc;
    222                         }
    223                         return str;
    224                 } else {
    225                         int f = Math.abs(conv.bin);
    226                         if (f < 5) {
    227                                 long val = buffer[offset + --f];
    228                                 if (conv.bin > 0)
    229                                         val &= 0xff;
    230                                 while (f > 0) {
    231                                         val = (val << 8) + (buffer[offset + --f] & 0xff);
    232                                 }
    233                                 offset += Math.abs(conv.bin);
    234                                 if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
    235                                         String charset = "";
    236                                         switch ((int)val) {
    237                                         case 0:
    238                                                 charset = "US-ASCII";
    239                                                 break;
    240                                         case 1:
    241                                                 charset = "ISO-8859-1";
    242                                                 break;
    243                                         case 2:
    244                                                 charset = "UTF-16LE";
    245                                                 break;
    246                                         }
    247                                         if (subf == S57subf.NALL) {
    248                                                 nall = charset;
    249                                         } else {
    250                                                 aall = charset;
    251                                         }
    252                                 }
    253                                 return val;
    254                         } else {
    255                                 if (f == 5) {
    256                                         long val = buffer[offset++] & 0xff;
    257                                         f--;
    258                                         while (f > 0) {
    259                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    260                                         }
    261                                         offset += 4;
    262                                         return val;
    263                                 } else {
    264                                         long val = buffer[offset++] & 0xff;
    265                                         val = (val << 8) + (buffer[offset++] & 0xff);
    266                                         f = 4;
    267                                         while (f > 0) {
    268                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    269                                         }
    270                                         offset += 4;
    271                                         f = 2;
    272                                         while (f > 0) {
    273                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    274                                         }
    275                                         offset += 2;
    276                                         return val;
    277                                 }
    278                         }
    279                 }
    280         }
    281 
    282         public static byte[] encSubf(S57subf subf, Object val) {
    283                 S57conv conv = convs.get(subf);
    284                 if ((conv.bin == 0) || asc) {
    285                         String sval = "";
    286                         if (val instanceof String) {
    287                                 sval = (String) val;
    288                         } else if (val instanceof Integer) {
    289                                 sval = ((Integer)val).toString();
    290                         } else if (val instanceof Long) {
    291                                 sval = ((Long)val).toString();
    292                         } else if (val instanceof Double) {
    293                                 sval = ((Double)val).toString();
    294                         }
    295                         index = sval.length();
    296                         try {
    297                                 buffer = ((String) sval + " ").getBytes("ISO-8859-1");
    298                         } catch (Exception e) {
    299                                 System.err.println(e.getMessage());
    300                                 System.exit(-1);
    301                         }
    302                         if (conv.asc == 0) {
    303                                 buffer[index] = 0x01f;
    304                         } else {
    305                                 buffer = Arrays.copyOf(buffer, conv.asc);
    306                                 while (index < buffer.length) {
    307                                         buffer[index++] = ' ';
    308                                 }
    309                         }
    310                 } else {
    311                         int f = Math.abs(conv.bin);
    312                         long lval;
    313                         if (val instanceof String) {
    314                                 lval = Long.parseLong((String)val);
    315                         } else  if (val instanceof Double) {
    316                                 double dval = (double) val;
    317                                 lval = (long) dval;
    318                         } else  if (val instanceof Integer) {
    319                                 lval = (int) val;
    320                         } else {
    321                                 lval = (long) val;
    322                         }
    323                         buffer = new byte[f];
    324                         for (int i = 0; i < f; i++) {
    325                                 buffer[i] = (byte) (lval & 0xff);
    326                                 lval >>= 8;
    327                         }
    328                 }
    329                 return buffer;
    330         }
    331 
    332         static class Index {
    333                 byte[] field;
    334                 int length;
    335                 int offset;
    336                 Index (byte[] id, int l, int o) {
    337                         field = id;
    338                         length = l;
    339                         offset = o;
    340                 }
    341         }
    342        
    343         public static class Fparams {
    344                 public S57field field;
    345                 public Object[] params;
    346                 public Fparams(S57field f, Object[] p) {
    347                         field = f;
    348                         params = p;
    349                 }
    350         };
    351 
    352         static boolean asc = false;
    353        
    354         public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
    355                 asc = true;
    356                 return encRecord(Integer.parseInt(i8rn), fparams);
    357         }
    358        
    359         public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
    360                 ArrayList<Index> index = new ArrayList<>();
    361                 int offset = 3;
    362                 int maxlen = 3;
    363                 byte[] buf = encSubf(S57subf.I8RN, i8rn);
    364                 buf = Arrays.copyOf(buf, 3);
    365                 buf[2] = 0x1e;
    366                 index.add(new Index("0001".getBytes(), 3, 0));
    367                 for (Fparams sfparams : fparams) {
    368                         for (int ip = 0; ip < sfparams.params.length; ) {
    369                                 for (S57subf subf : fields.get(sfparams.field)) {
    370                                         byte[] next = encSubf(subf, sfparams.params[ip++]);
    371                                         buf = Arrays.copyOf(buf, (buf.length + next.length));
    372                                         System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
    373                                 }
    374                         }
    375                         buf = Arrays.copyOf(buf, (buf.length + 1));
    376                         buf[buf.length-1] = 0x1e;
    377                         int flen = buf.length - offset;
    378                         index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
    379                         maxlen = (flen > maxlen) ? flen : maxlen;
    380                         offset += flen;
    381                 }
    382                 int mlen = String.valueOf(maxlen).length();
    383                 String ffmt = "%0" + mlen + "d";
    384                 int olen = String.valueOf(offset).length();
    385                 String ofmt = "%0" + olen + "d";
    386                 int ilen = 4 + mlen + olen;
    387                 int isiz = (ilen * index.size()) + 1;
    388                 byte[] ibuf = new byte[isiz];
    389                 int i = 0;
    390                 for (Index item : index) {
    391                         for (byte ch : item.field) {
    392                                 ibuf[i++] = ch;
    393                         }
    394                         byte[] digits = String.format(ffmt, item.length).getBytes();
    395                         for (byte ch : digits) {
    396                                 ibuf[i++] = ch;
    397                         }
    398                         digits = String.format(ofmt, item.offset).getBytes();
    399                         for (byte ch : digits) {
    400                                 ibuf[i++] = ch;
    401                         }
    402                 }
    403                 ibuf[i] = 0x1e;
    404                 byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
    405                 System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
    406                 System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
    407                 fbuf[20] = (byte)(mlen + 0x30);
    408                 fbuf[21] = (byte)(olen + 0x30);
    409                 System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
    410                 System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
    411                 asc = false;
    412                 return fbuf;
    413         }
    414 
    415         enum Prims { N, P, L, A, PA, PL, LA, PLA }
    416         private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
    417         static {
    418                 S57prims.put(Obj.UNKOBJ, Prims.PLA); S57prims.put(Obj.M_COVR, Prims.A); S57prims.put(Obj.M_NSYS, Prims.A); S57prims.put(Obj.AIRARE, Prims.PA);
    419                 S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
    420                 S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
    421                 S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
    422                 S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
    423                 S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
    424                 S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
    425                 S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
    426                 S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
    427                 S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
    428                 S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
    429                 S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
    430                 S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
    431                 S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
    432                 S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
    433                 S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
    434                 S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
    435                 S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
    436                 S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
    437                 S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
    438                 S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
    439                 S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
    440                 S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
    441                 S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
    442                 S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
    443                 S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
    444                 S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
    445                 S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
    446                 S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
    447                 S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
    448                 S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
    449                 S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
    450                 S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
    451                 S57prims.put(Obj.SWPARE, Prims.A); S57prims.put(Obj.TESARE, Prims.A); S57prims.put(Obj.TS_PRH, Prims.PA); S57prims.put(Obj.TS_PNH, Prims.PA);
    452                 S57prims.put(Obj.TS_PAD, Prims.PA); S57prims.put(Obj.TS_TIS, Prims.PA); S57prims.put(Obj.T_HMON, Prims.PA); S57prims.put(Obj.T_NHMN, Prims.PA);
    453                 S57prims.put(Obj.T_TIMS, Prims.PA); S57prims.put(Obj.TIDEWY, Prims.LA); S57prims.put(Obj.TOPMAR, Prims.P); S57prims.put(Obj.TSELNE, Prims.LA);
    454                 S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
    455                 S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
    456                 S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
    457                 S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
    458                 S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
    459                 S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
    460                 S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
    461                 S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
    462                 S57prims.put(Obj.LG_SDM, Prims.A); S57prims.put(Obj.LG_VSP, Prims.A); S57prims.put(Obj.LITMAJ, Prims.P);  S57prims.put(Obj.LITMIN, Prims.P);
    463         }
    464 
    465         public static void S57geoms(S57map map) {
    466                 for (ArrayList<Feature> list : map.features.values()) {
    467                         for (Feature feature : list) {
    468                                 switch (S57prims.get(feature.type)) {
    469                                 case N:
    470                                         break;
    471                                 case P:
    472                                         if (feature.geom.prim != Pflag.POINT) {
    473 //                                              Snode node = feature.geom.centre;
    474 //                                              node.flg = Nflag.ISOL;
    475 //                                              map.nodes.put(++map.xref, node);
    476 //                                              feature.geom = map.new Geom(Pflag.POINT);
    477 //                                              feature.geom.centre = node;
    478 //                                              feature.geom.elems.add(map.new Prim(map.xref));
    479                                         }
    480                                         break;
    481                                 case L:
    482                                         break;
    483                                 case A:
    484                                         break;
    485                                 case PA:
    486                                         break;
    487                                 case PL:
    488                                         break;
    489                                 case LA:
    490                                         if (feature.geom.prim == Pflag.POINT) {
    491 //                                              list.remove(feature);
    492                                         }
    493                                         break;
    494                                 case PLA:
    495                                         // No changes needed
    496                                         break;
    497                                 }
    498                         }
    499                 }
    500         }
     22    // CHECKSTYLE.OFF: LineLength
     23
     24    public static class S57conv {
     25        int asc;    // 0=A(), 1+=A(n)
     26        int bin;    // 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE)
     27        S57conv(int a, int b) {
     28            asc = a; bin = b;
     29        }
     30    }
     31
     32    public enum S57subf { I8RN, RCNM, RCID, EXPP, INTU, DSNM, EDTN, UPDN, UADT, ISDT, STED, PRSP, PSDN, PRED, PROF, AGEN, COMT, DSTR, AALL, NALL, NOMR, NOCR, NOGR, NOLR, NOIN, NOCN,
     33        NOED, NOFA, HDAT, VDAT, SDAT, CSCL, DUNI, HUNI, PUNI, COUN, COMF, SOMF, PROJ, PRP1, PRP2, PRP3, PRP4, FEAS, FNOR, FPMF, RPID, RYCO, RXCO, CURP, RXVL, RYVL, PRCO, ESDT,
     34        LSDT, DCRT, CODT, PACC, HACC, SACC, FILE, LFIL, VOLM, IMPL, SLAT, WLON, NLAT, ELON, CRCS, NAM1, NAM2, OORA, OAAC, OACO, OALL, OATY, DEFN, AUTH, RFTP, RFVL, ATLB, ATDO,
     35        ADMU, ADFT, RAVA, DVAL, DVSD, OBLB, ASET, PRIM, GRUP, OBJL, RVER, RUIN, FIDN, FIDS, ATTL, ATVL, FFUI, FFIX, NFPT, LNAM, RIND, FSUI, FSIX, NSPT, NAME, ORNT, USAG, MASK,
     36        VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
     37
     38    private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
     39    static {
     40        convs.put(S57subf.I8RN, new S57conv(5, 2));
     41        convs.put(S57subf.RCNM, new S57conv(2, 1)); convs.put(S57subf.RCID, new S57conv(10, 4)); convs.put(S57subf.EXPP, new S57conv(1, 1));
     42        convs.put(S57subf.INTU, new S57conv(1, 1)); convs.put(S57subf.DSNM, new S57conv(0, 0)); convs.put(S57subf.EDTN, new S57conv(0, 0));
     43        convs.put(S57subf.UPDN, new S57conv(0, 0)); convs.put(S57subf.UADT, new S57conv(8, 0)); convs.put(S57subf.ISDT, new S57conv(8, 0));
     44        convs.put(S57subf.STED, new S57conv(4, 0)); convs.put(S57subf.PRSP, new S57conv(3, 1)); convs.put(S57subf.PSDN, new S57conv(0, 0));
     45        convs.put(S57subf.PRED, new S57conv(0, 0)); convs.put(S57subf.PROF, new S57conv(2, 1)); convs.put(S57subf.AGEN, new S57conv(2, 2));
     46        convs.put(S57subf.COMT, new S57conv(0, 0)); convs.put(S57subf.DSTR, new S57conv(2, 1)); convs.put(S57subf.AALL, new S57conv(1, 1));
     47        convs.put(S57subf.NALL, new S57conv(1, 1)); convs.put(S57subf.NOMR, new S57conv(0, 4)); convs.put(S57subf.NOCR, new S57conv(0, 4));
     48        convs.put(S57subf.NOGR, new S57conv(0, 4)); convs.put(S57subf.NOLR, new S57conv(0, 4)); convs.put(S57subf.NOIN, new S57conv(0, 4));
     49        convs.put(S57subf.NOCN, new S57conv(0, 4)); convs.put(S57subf.NOED, new S57conv(0, 4)); convs.put(S57subf.NOFA, new S57conv(0, 4));
     50        convs.put(S57subf.HDAT, new S57conv(3, 1)); convs.put(S57subf.VDAT, new S57conv(2, 1)); convs.put(S57subf.SDAT, new S57conv(2, 1));
     51        convs.put(S57subf.CSCL, new S57conv(0, 4)); convs.put(S57subf.DUNI, new S57conv(2, 1)); convs.put(S57subf.HUNI, new S57conv(2, 1));
     52        convs.put(S57subf.PUNI, new S57conv(2, 1)); convs.put(S57subf.COUN, new S57conv(2, 1)); convs.put(S57subf.COMF, new S57conv(0, 4));
     53        convs.put(S57subf.SOMF, new S57conv(0, 4)); convs.put(S57subf.PROJ, new S57conv(3, 1)); convs.put(S57subf.PRP1, new S57conv(0, -4));
     54        convs.put(S57subf.PRP2, new S57conv(0, -4)); convs.put(S57subf.PRP3, new S57conv(0, -4)); convs.put(S57subf.PRP4, new S57conv(0, -4));
     55        convs.put(S57subf.FEAS, new S57conv(0, -4)); convs.put(S57subf.FNOR, new S57conv(0, -4)); convs.put(S57subf.FPMF, new S57conv(0, 4));
     56        convs.put(S57subf.RPID, new S57conv(1, 1)); convs.put(S57subf.RYCO, new S57conv(0, -4)); convs.put(S57subf.RXCO, new S57conv(0, -4));
     57        convs.put(S57subf.CURP, new S57conv(2, 1)); convs.put(S57subf.RXVL, new S57conv(0, -4)); convs.put(S57subf.RYVL, new S57conv(0, -4));
     58        convs.put(S57subf.PRCO, new S57conv(2, 2)); convs.put(S57subf.ESDT, new S57conv(8, 0)); convs.put(S57subf.LSDT, new S57conv(8, 0));
     59        convs.put(S57subf.DCRT, new S57conv(0, 0)); convs.put(S57subf.CODT, new S57conv(8, 0)); convs.put(S57subf.PACC, new S57conv(0, 4));
     60        convs.put(S57subf.HACC, new S57conv(0, 4)); convs.put(S57subf.SACC, new S57conv(0, 4)); convs.put(S57subf.FILE, new S57conv(0, 0));
     61        convs.put(S57subf.LFIL, new S57conv(0, 0)); convs.put(S57subf.VOLM, new S57conv(0, 0)); convs.put(S57subf.IMPL, new S57conv(3, 0));
     62        convs.put(S57subf.SLAT, new S57conv(0, 0)); convs.put(S57subf.WLON, new S57conv(0, 0)); convs.put(S57subf.NLAT, new S57conv(0, 0));
     63        convs.put(S57subf.ELON, new S57conv(0, 0)); convs.put(S57subf.CRCS, new S57conv(0, 0)); convs.put(S57subf.NAM1, new S57conv(12, 5));
     64        convs.put(S57subf.NAM2, new S57conv(12, 5)); convs.put(S57subf.OORA, new S57conv(1, 1)); convs.put(S57subf.OAAC, new S57conv(6, 0));
     65        convs.put(S57subf.OACO, new S57conv(5, 2)); convs.put(S57subf.OALL, new S57conv(0, 0)); convs.put(S57subf.OATY, new S57conv(1, 1));
     66        convs.put(S57subf.DEFN, new S57conv(0, 0)); convs.put(S57subf.AUTH, new S57conv(2, 2)); convs.put(S57subf.RFTP, new S57conv(2, 1));
     67        convs.put(S57subf.RFVL, new S57conv(0, 0)); convs.put(S57subf.ATLB, new S57conv(5, 2)); convs.put(S57subf.ATDO, new S57conv(1, 1));
     68        convs.put(S57subf.ADMU, new S57conv(0, 0)); convs.put(S57subf.ADFT, new S57conv(0, 0)); convs.put(S57subf.RAVA, new S57conv(1, 1));
     69        convs.put(S57subf.DVAL, new S57conv(0, 0)); convs.put(S57subf.DVSD, new S57conv(0, 0)); convs.put(S57subf.OBLB, new S57conv(5, 2));
     70        convs.put(S57subf.ASET, new S57conv(1, 1)); convs.put(S57subf.PRIM, new S57conv(1, 1)); convs.put(S57subf.GRUP, new S57conv(3, 1));
     71        convs.put(S57subf.OBJL, new S57conv(5, 2)); convs.put(S57subf.RVER, new S57conv(3, 2)); convs.put(S57subf.RUIN, new S57conv(1, 1));
     72        convs.put(S57subf.FIDN, new S57conv(10, 4)); convs.put(S57subf.FIDS, new S57conv(5, 2)); convs.put(S57subf.ATTL, new S57conv(5, 2));
     73        convs.put(S57subf.ATVL, new S57conv(0, 0)); convs.put(S57subf.FFUI, new S57conv(1, 1)); convs.put(S57subf.FFIX, new S57conv(0, 2));
     74        convs.put(S57subf.NFPT, new S57conv(0, 2)); convs.put(S57subf.LNAM, new S57conv(17, 8)); convs.put(S57subf.RIND, new S57conv(0, 1));
     75        convs.put(S57subf.FSUI, new S57conv(1, 1)); convs.put(S57subf.FSIX, new S57conv(0, 2)); convs.put(S57subf.NSPT, new S57conv(0, 2));
     76        convs.put(S57subf.NAME, new S57conv(12, 5)); convs.put(S57subf.ORNT, new S57conv(1, 1)); convs.put(S57subf.USAG, new S57conv(1, 1));
     77        convs.put(S57subf.MASK, new S57conv(1, 1)); convs.put(S57subf.VPUI, new S57conv(1, 1)); convs.put(S57subf.VPIX, new S57conv(0, 2));
     78        convs.put(S57subf.NVPT, new S57conv(0, 2)); convs.put(S57subf.TOPI, new S57conv(1, 1)); convs.put(S57subf.CCUI, new S57conv(1, 1));
     79        convs.put(S57subf.CCIX, new S57conv(0, 2)); convs.put(S57subf.CCNC, new S57conv(0, 2)); convs.put(S57subf.YCOO, new S57conv(0, -4));
     80        convs.put(S57subf.XCOO, new S57conv(0, -4)); convs.put(S57subf.VE3D, new S57conv(0, -4)); convs.put(S57subf.ATYP, new S57conv(1, 1));
     81        convs.put(S57subf.SURF, new S57conv(1, 1)); convs.put(S57subf.ORDR, new S57conv(1, 1)); convs.put(S57subf.RESO, new S57conv(0, 4));
     82        convs.put(S57subf.STPT, new S57conv(0, 0)); convs.put(S57subf.CTPT, new S57conv(0, 0)); convs.put(S57subf.ENPT, new S57conv(0, 0));
     83        convs.put(S57subf.CDPM, new S57conv(0, 0)); convs.put(S57subf.CDPR, new S57conv(0, 0));
     84    }
     85
     86    public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
     87        FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
     88
     89    private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
     90    private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
     91            S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
     92    private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
     93            S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA));
     94    private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
     95            S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT));
     96    private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
     97            S57subf.FPMF, S57subf.COMT));
     98    private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
     99            S57subf.COMT));
     100    private static ArrayList<S57subf> S57dsht = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRCO, S57subf.ESDT, S57subf.LSDT, S57subf.DCRT, S57subf.CODT, S57subf.COMT));
     101    private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT));
     102    private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
     103            S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT));
     104    private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT));
     105    private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
     106            S57subf.DEFN, S57subf.AUTH, S57subf.COMT));
     107    private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
     108    private static ArrayList<S57subf> S57dddi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.ATLB, S57subf.ATDO, S57subf.ADMU, S57subf.ADFT, S57subf.AUTH, S57subf.COMT));
     109    private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH));
     110    private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
     111    private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB));
     112    private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH));
     113    private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN));
     114    private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS));
     115    private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
     116    private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     117    private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     118    private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT));
     119    private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT));
     120    private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT));
     121    private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK));
     122    private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN));
     123    private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     124    private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT));
     125    private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK));
     126    private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC));
     127    private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
     128    private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D));
     129    private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF));
     130    private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO));
     131    private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO));
     132    private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
     133
     134    private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
     135    static {
     136        fields.put(S57field.I8RI, S57i8ri);
     137        fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
     138        fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
     139        fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
     140        fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
     141        fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
     142        fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
     143        fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
     144        fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
     145        fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d);
     146    }
     147
     148    private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
     149    private static byte[] buffer;
     150    private static int offset;
     151    private static int maxoff;
     152    private static int index;
     153    private static S57field field;
     154    private static String aall = "US-ASCII";
     155    private static String nall = "US-ASCII";
     156    public static int rnum;
     157
     158    private static S57conv findSubf(S57subf subf) {
     159        ArrayList<S57subf> subs = fields.get(field);
     160        boolean wrap = false;
     161        while (true) {
     162            if (index == subs.size()) {
     163                if (!wrap) {
     164                    index = 0;
     165                    wrap = true;
     166                } else {
     167                    System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
     168                    System.exit(-1);
     169                }
     170            }
     171            S57subf sub = subs.get(index++);
     172            S57conv conv = convs.get(sub);
     173            if (sub == subf) {
     174                return conv;
     175            } else {
     176                offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
     177            }
     178        }
     179    }
     180
     181    public static void setField(byte[] buf, int off, S57field fld, int len) {
     182        buffer = buf;
     183        offset = off;
     184        maxoff = off + len - 1;
     185        field = fld;
     186        index = 0;
     187    }
     188
     189    public static boolean more() {
     190        return (offset < maxoff);
     191    }
     192
     193    public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
     194        buffer = buf;
     195        offset = off;
     196        index = 0;
     197        return decSubf(fld, subf);
     198    }
     199
     200    public static Object decSubf(S57field fld, S57subf subf) {
     201        field = fld;
     202        index = 0;
     203        return decSubf(subf);
     204    }
     205
     206    public static Object decSubf(S57subf subf) {
     207        S57conv conv = findSubf(subf);
     208        if (conv.bin == 0) {
     209            String str = "";
     210            int i = 0;
     211            if (conv.asc == 0) {
     212                for (i = 0; buffer[offset+i] != 0x1f; i++) { }
     213                try {
     214                    String charset = "";
     215                    if (field == S57field.ATTF) charset = aall;
     216                    else if (field == S57field.NATF) charset = nall;
     217                    else charset = "US-ASCII";
     218                    str = new String(buffer, offset, i, charset);
     219                } catch (UnsupportedEncodingException e) {
     220                    e.printStackTrace();
     221                }
     222                offset += i + 1;
     223            } else {
     224                str = new String(buffer, offset, conv.asc);
     225                offset += conv.asc;
     226            }
     227            return str;
     228        } else {
     229            int f = Math.abs(conv.bin);
     230            if (f < 5) {
     231                long val = buffer[offset + --f];
     232                if (conv.bin > 0)
     233                    val &= 0xff;
     234                while (f > 0) {
     235                    val = (val << 8) + (buffer[offset + --f] & 0xff);
     236                }
     237                offset += Math.abs(conv.bin);
     238                if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
     239                    String charset = "";
     240                    switch ((int) val) {
     241                    case 0:
     242                        charset = "US-ASCII";
     243                        break;
     244                    case 1:
     245                        charset = "ISO-8859-1";
     246                        break;
     247                    case 2:
     248                        charset = "UTF-16LE";
     249                        break;
     250                    }
     251                    if (subf == S57subf.NALL) {
     252                        nall = charset;
     253                    } else {
     254                        aall = charset;
     255                    }
     256                }
     257                return val;
     258            } else {
     259                if (f == 5) {
     260                    long val = buffer[offset++] & 0xff;
     261                    f--;
     262                    while (f > 0) {
     263                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     264                    }
     265                    offset += 4;
     266                    return val;
     267                } else {
     268                    long val = buffer[offset++] & 0xff;
     269                    val = (val << 8) + (buffer[offset++] & 0xff);
     270                    f = 4;
     271                    while (f > 0) {
     272                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     273                    }
     274                    offset += 4;
     275                    f = 2;
     276                    while (f > 0) {
     277                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     278                    }
     279                    offset += 2;
     280                    return val;
     281                }
     282            }
     283        }
     284    }
     285
     286    public static byte[] encSubf(S57subf subf, Object val) {
     287        S57conv conv = convs.get(subf);
     288        if ((conv.bin == 0) || asc) {
     289            String sval = "";
     290            if (val instanceof String) {
     291                sval = (String) val;
     292            } else if (val instanceof Integer) {
     293                sval = ((Integer) val).toString();
     294            } else if (val instanceof Long) {
     295                sval = ((Long) val).toString();
     296            } else if (val instanceof Double) {
     297                sval = ((Double) val).toString();
     298            }
     299            index = sval.length();
     300            try {
     301                buffer = (sval + " ").getBytes("ISO-8859-1");
     302            } catch (Exception e) {
     303                System.err.println(e.getMessage());
     304                System.exit(-1);
     305            }
     306            if (conv.asc == 0) {
     307                buffer[index] = 0x01f;
     308            } else {
     309                buffer = Arrays.copyOf(buffer, conv.asc);
     310                while (index < buffer.length) {
     311                    buffer[index++] = ' ';
     312                }
     313            }
     314        } else {
     315            int f = Math.abs(conv.bin);
     316            long lval;
     317            if (val instanceof String) {
     318                lval = Long.parseLong((String) val);
     319            } else if (val instanceof Double) {
     320                double dval = (double) val;
     321                lval = (long) dval;
     322            } else if (val instanceof Integer) {
     323                lval = (int) val;
     324            } else {
     325                lval = (long) val;
     326            }
     327            buffer = new byte[f];
     328            for (int i = 0; i < f; i++) {
     329                buffer[i] = (byte) (lval & 0xff);
     330                lval >>= 8;
     331            }
     332        }
     333        return buffer;
     334    }
     335
     336    static class Index {
     337        byte[] field;
     338        int length;
     339        int offset;
     340        Index(byte[] id, int l, int o) {
     341            field = id;
     342            length = l;
     343            offset = o;
     344        }
     345    }
     346
     347    public static class Fparams {
     348        public S57field field;
     349        public Object[] params;
     350        public Fparams(S57field f, Object[] p) {
     351            field = f;
     352            params = p;
     353        }
     354    }
     355
     356    static boolean asc = false;
     357
     358    public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
     359        asc = true;
     360        return encRecord(Integer.parseInt(i8rn), fparams);
     361    }
     362
     363    public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
     364        ArrayList<Index> index = new ArrayList<>();
     365        int offset = 3;
     366        int maxlen = 3;
     367        byte[] buf = encSubf(S57subf.I8RN, i8rn);
     368        buf = Arrays.copyOf(buf, 3);
     369        buf[2] = 0x1e;
     370        index.add(new Index("0001".getBytes(), 3, 0));
     371        for (Fparams sfparams : fparams) {
     372            for (int ip = 0; ip < sfparams.params.length;) {
     373                for (S57subf subf : fields.get(sfparams.field)) {
     374                    byte[] next = encSubf(subf, sfparams.params[ip++]);
     375                    buf = Arrays.copyOf(buf, (buf.length + next.length));
     376                    System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
     377                }
     378            }
     379            buf = Arrays.copyOf(buf, (buf.length + 1));
     380            buf[buf.length-1] = 0x1e;
     381            int flen = buf.length - offset;
     382            index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
     383            maxlen = (flen > maxlen) ? flen : maxlen;
     384            offset += flen;
     385        }
     386        int mlen = String.valueOf(maxlen).length();
     387        String ffmt = "%0" + mlen + "d";
     388        int olen = String.valueOf(offset).length();
     389        String ofmt = "%0" + olen + "d";
     390        int ilen = 4 + mlen + olen;
     391        int isiz = (ilen * index.size()) + 1;
     392        byte[] ibuf = new byte[isiz];
     393        int i = 0;
     394        for (Index item : index) {
     395            for (byte ch : item.field) {
     396                ibuf[i++] = ch;
     397            }
     398            byte[] digits = String.format(ffmt, item.length).getBytes();
     399            for (byte ch : digits) {
     400                ibuf[i++] = ch;
     401            }
     402            digits = String.format(ofmt, item.offset).getBytes();
     403            for (byte ch : digits) {
     404                ibuf[i++] = ch;
     405            }
     406        }
     407        ibuf[i] = 0x1e;
     408        byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
     409        System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
     410        System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
     411        fbuf[20] = (byte) (mlen + 0x30);
     412        fbuf[21] = (byte) (olen + 0x30);
     413        System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
     414        System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
     415        asc = false;
     416        return fbuf;
     417    }
     418
     419    enum Prims { N, P, L, A, PA, PL, LA, PLA }
     420
     421    private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
     422    static {
     423        S57prims.put(Obj.UNKOBJ, Prims.PLA); S57prims.put(Obj.M_COVR, Prims.A); S57prims.put(Obj.M_NSYS, Prims.A); S57prims.put(Obj.AIRARE, Prims.PA);
     424        S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
     425        S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
     426        S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
     427        S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
     428        S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
     429        S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
     430        S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
     431        S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
     432        S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
     433        S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
     434        S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
     435        S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
     436        S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
     437        S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
     438        S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
     439        S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
     440        S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
     441        S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
     442        S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
     443        S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
     444        S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
     445        S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
     446        S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
     447        S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
     448        S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
     449        S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
     450        S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
     451        S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
     452        S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
     453        S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
     454        S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
     455        S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
     456        S57prims.put(Obj.SWPARE, Prims.A); S57prims.put(Obj.TESARE, Prims.A); S57prims.put(Obj.TS_PRH, Prims.PA); S57prims.put(Obj.TS_PNH, Prims.PA);
     457        S57prims.put(Obj.TS_PAD, Prims.PA); S57prims.put(Obj.TS_TIS, Prims.PA); S57prims.put(Obj.T_HMON, Prims.PA); S57prims.put(Obj.T_NHMN, Prims.PA);
     458        S57prims.put(Obj.T_TIMS, Prims.PA); S57prims.put(Obj.TIDEWY, Prims.LA); S57prims.put(Obj.TOPMAR, Prims.P); S57prims.put(Obj.TSELNE, Prims.LA);
     459        S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
     460        S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
     461        S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
     462        S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
     463        S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
     464        S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
     465        S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
     466        S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
     467        S57prims.put(Obj.LG_SDM, Prims.A); S57prims.put(Obj.LG_VSP, Prims.A); S57prims.put(Obj.LITMAJ, Prims.P); S57prims.put(Obj.LITMIN, Prims.P);
     468    }
     469
     470    public static void S57geoms(S57map map) {
     471        for (ArrayList<Feature> list : map.features.values()) {
     472            for (Feature feature : list) {
     473                switch (S57prims.get(feature.type)) {
     474                case N:
     475                    break;
     476                case P:
     477                    if (feature.geom.prim != Pflag.POINT) {
     478                        //                        Snode node = feature.geom.centre;
     479                        //                        node.flg = Nflag.ISOL;
     480                        //                        map.nodes.put(++map.xref, node);
     481                        //                        feature.geom = map.new Geom(Pflag.POINT);
     482                        //                        feature.geom.centre = node;
     483                        //                        feature.geom.elems.add(map.new Prim(map.xref));
     484                    }
     485                    break;
     486                case L:
     487                    break;
     488                case A:
     489                    break;
     490                case PA:
     491                    break;
     492                case PL:
     493                    break;
     494                case LA:
     495                    if (feature.geom.prim == Pflag.POINT) {
     496                        //                        list.remove(feature);
     497                    }
     498                    break;
     499                case PLA:
     500                    // No changes needed
     501                    break;
     502                }
     503            }
     504        }
     505    }
    501506}
  • applications/editors/josm/plugins/seachart/src/s57/S57dec.java

    r32380 r32394  
    1313import java.io.IOException;
    1414
    15 import s57.S57dat.*;
    16 import s57.S57map.*;
     15import s57.S57dat.S57field;
     16import s57.S57dat.S57subf;
     17import s57.S57map.Nflag;
    1718
    1819public class S57dec { // S57 ENC file input & map conversion
    19 
    20         public static void decodeChart(FileInputStream in, S57map map) throws IOException {
    21                 S57dat.rnum = 0;
    22                 byte[] leader = new byte[24];
    23                 byte[] record = new byte[0];
    24                 boolean ddr = false;
    25                 int length = 0;
    26                 int fields = 0;;
    27                 int mapfl, mapfp, mapts, entry;
    28                 String tag;
    29                 int len;
    30                 int pos;
    31                 boolean inFeature = false;
    32 
    33                 double comf = 1;
    34                 double somf = 1;
    35                 long name = 0;
    36                 S57map.Nflag nflag = Nflag.ANON;
    37                 S57map.Pflag pflag = S57map.Pflag.NOSP;
    38                 long objl = 0;
    39                
    40                 while (in.read(leader) == 24) {
    41                         try {
    42                         length = Integer.parseInt(new String(leader, 0, 5)) - 24;
    43                         record = new byte[length];
    44                         ddr = (leader[6] == 'L');
    45                         fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
    46                         } catch (Exception e) {
    47                                 System.err.println("Invalid file format - Encrypted/compressed ENC file?");
    48                                 System.exit(-1);
    49                         }
    50                         mapfl = leader[20] - '0';
    51                         mapfp = leader[21] - '0';
    52                         mapts = leader[23] - '0';
    53                         entry = mapfl + mapfp + mapts;
    54                         if (in.read(record) != length)
    55                                 break;
    56                         for (int idx = 0; idx < fields-1; idx += entry) {
    57                                 tag = new String(record, idx, mapts);
    58                                 len = Integer.parseInt(new String(record, idx+mapts, mapfl));
    59                                 pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
    60                                 if (!ddr) {
    61                                         switch (tag.toString()) {
    62                                         case "0001":
    63                                                 int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
    64 //                                              if (i8rn != ++S57dat.rnum) {
    65 //                                                      System.err.println("Out of order record ID");
    66 //                                                      in.close();
    67 //                                                      System.exit(-1);
    68 //                                              }
    69                                                 break;
    70                                         case "DSSI":
    71                                                 S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
    72                                                 S57dat.decSubf(S57subf.NALL);
    73                                                 break;
    74                                         case "DSPM":
    75                                                 comf = (double) (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
    76                                                 somf = (double) (Long) S57dat.decSubf(S57subf.SOMF);
    77                                                 break;
    78                                         case "FRID":
    79                                                 inFeature = true;
    80                                                 switch (((Long)S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
    81                                                 case 1:
    82                                                         pflag = S57map.Pflag.POINT;
    83                                                         break;
    84                                                 case 2:
    85                                                         pflag = S57map.Pflag.LINE;
    86                                                         break;
    87                                                 case 3:
    88                                                         pflag = S57map.Pflag.AREA;
    89                                                         break;
    90                                                 default:
    91                                                         pflag = S57map.Pflag.NOSP;
    92                                                 }
    93                                                 objl = (Long)S57dat.decSubf(S57subf.OBJL);
    94                                                 break;
    95                                         case "FOID":
    96                                                 name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
    97                                                 map.newFeature(name, pflag, objl);
    98                                                 break;
    99                                         case "ATTF":
    100                                                 S57dat.setField(record, fields + pos, S57field.ATTF, len);
    101                                                 do {
    102                                                         long attl = (Long) S57dat.decSubf(S57subf.ATTL);
    103                                                         String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
    104                                                         if (!atvl.isEmpty()) {
    105                                                                 map.newAtt(attl, atvl);
    106                                                         }
    107                                                 } while (S57dat.more());
    108                                                 break;
    109                                         case "FFPT":
    110                                                 S57dat.setField(record, fields + pos, S57field.FFPT, len);
    111                                                 do {
    112                                                         name = (long) S57dat.decSubf(S57subf.LNAM);
    113                                                         int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
    114                                                         S57dat.decSubf(S57subf.COMT);
    115                                                         map.refObj(name, rind);
    116                                                 } while (S57dat.more());
    117                                                 break;
    118                                         case "FSPT":
    119                                                 S57dat.setField(record, fields + pos, S57field.FSPT, len);
    120                                                 do {
    121                                                         name = (long) S57dat.decSubf(S57subf.NAME) << 16;
    122                                                         map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
    123                                                         S57dat.decSubf(S57subf.MASK);
    124                                                 } while (S57dat.more());
    125                                                 break;
    126                                         case "VRID":
    127                                                 inFeature = false;
    128                                                 name = (long) (Long)S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
    129                                                 switch ((int) name) {
    130                                                 case 110:
    131                                                         nflag = Nflag.ISOL;
    132                                                         break;
    133                                                 case 120:
    134                                                         nflag = Nflag.CONN;
    135                                                         break;
    136                                                 default:
    137                                                         nflag = Nflag.ANON;
    138                                                         break;
    139                                                 }
    140                                                 name <<= 32;
    141                                                 name += (long) S57dat.decSubf(S57subf.RCID);
    142                                                 name <<= 16;
    143                                                 if (nflag == Nflag.ANON) {
    144                                                         map.newEdge(name);
    145                                                 }
    146                                                 break;
    147                                         case "VRPT":
    148                                                 S57dat.setField(record, fields + pos, S57field.VRPT, len);
    149                                                 do {
    150                                                         long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
    151                                                         int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
    152                                                         map.addConn(conn, topi);
    153                                                         S57dat.decSubf(S57subf.MASK);
    154                                                 } while (S57dat.more());
    155                                                 break;
    156                                         case "SG2D":
    157                                                 S57dat.setField(record, fields + pos, S57field.SG2D, len);
    158                                                 do {
    159                                                         double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
    160                                                         double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
    161                                                         if (nflag == Nflag.ANON) {
    162                                                                 map.newNode(++name, lat, lon, nflag);
    163                                                         } else {
    164                                                                 map.newNode(name, lat, lon, nflag);
    165                                                         }
    166                                                         lat = Math.toRadians(lat);
    167                                                         lon = Math.toRadians(lon);
    168                                                         if (lat < map.bounds.minlat)
    169                                                                 map.bounds.minlat = lat;
    170                                                         if (lat > map.bounds.maxlat)
    171                                                                 map.bounds.maxlat = lat;
    172                                                         if (lon < map.bounds.minlon)
    173                                                                 map.bounds.minlon = lon;
    174                                                         if (lon > map.bounds.maxlon)
    175                                                                 map.bounds.maxlon = lon;
    176                                                 } while (S57dat.more());
    177                                                 break;
    178                                         case "SG3D":
    179                                                 S57dat.setField(record, fields + pos, S57field.SG3D, len);
    180                                                 do {
    181                                                         double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
    182                                                         double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
    183                                                         double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
    184                                                         map.newNode(name++, lat, lon, depth);
    185                                                         lat = Math.toRadians(lat);
    186                                                         lon = Math.toRadians(lon);
    187                                                         if (lat < map.bounds.minlat)
    188                                                                 map.bounds.minlat = lat;
    189                                                         if (lat > map.bounds.maxlat)
    190                                                                 map.bounds.maxlat = lat;
    191                                                         if (lon < map.bounds.minlon)
    192                                                                 map.bounds.minlon = lon;
    193                                                         if (lon > map.bounds.maxlon)
    194                                                                 map.bounds.maxlon = lon;
    195                                                 } while (S57dat.more());
    196                                                 break;
    197                                         default:
    198                                                 break;
    199                                         }
    200                                 }
    201                                 if (inFeature) {
    202                                         map.endFeature();
    203                                         inFeature = false;
    204                                 }
    205                         }
    206                 }
    207                 map.endFile();
    208                 in.close();
    209                
    210                 return;
    211         }
    212        
     20    // CHECKSTYLE.OFF: LineLength
     21
     22    public static void decodeChart(FileInputStream in, S57map map) throws IOException {
     23        S57dat.rnum = 0;
     24        byte[] leader = new byte[24];
     25        byte[] record = new byte[0];
     26        boolean ddr = false;
     27        int length = 0;
     28        int fields = 0;;
     29        int mapfl, mapfp, mapts, entry;
     30        String tag;
     31        int len;
     32        int pos;
     33        boolean inFeature = false;
     34
     35        double comf = 1;
     36        double somf = 1;
     37        long name = 0;
     38        S57map.Nflag nflag = Nflag.ANON;
     39        S57map.Pflag pflag = S57map.Pflag.NOSP;
     40        long objl = 0;
     41
     42        while (in.read(leader) == 24) {
     43            try {
     44                length = Integer.parseInt(new String(leader, 0, 5)) - 24;
     45                record = new byte[length];
     46                ddr = (leader[6] == 'L');
     47                fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
     48            } catch (Exception e) {
     49                System.err.println("Invalid file format - Encrypted/compressed ENC file?");
     50                System.exit(-1);
     51            }
     52            mapfl = leader[20] - '0';
     53            mapfp = leader[21] - '0';
     54            mapts = leader[23] - '0';
     55            entry = mapfl + mapfp + mapts;
     56            if (in.read(record) != length)
     57                break;
     58            for (int idx = 0; idx < fields-1; idx += entry) {
     59                tag = new String(record, idx, mapts);
     60                len = Integer.parseInt(new String(record, idx+mapts, mapfl));
     61                pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
     62                if (!ddr) {
     63                    switch (tag.toString()) {
     64                    case "0001":
     65                        int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
     66                        //                        if (i8rn != ++S57dat.rnum) {
     67                        //                            System.err.println("Out of order record ID");
     68                        //                            in.close();
     69                        //                            System.exit(-1);
     70                        //                        }
     71                        break;
     72                    case "DSSI":
     73                        S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
     74                        S57dat.decSubf(S57subf.NALL);
     75                        break;
     76                    case "DSPM":
     77                        comf = (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
     78                        somf = (Long) S57dat.decSubf(S57subf.SOMF);
     79                        break;
     80                    case "FRID":
     81                        inFeature = true;
     82                        switch (((Long) S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
     83                        case 1:
     84                            pflag = S57map.Pflag.POINT;
     85                            break;
     86                        case 2:
     87                            pflag = S57map.Pflag.LINE;
     88                            break;
     89                        case 3:
     90                            pflag = S57map.Pflag.AREA;
     91                            break;
     92                        default:
     93                            pflag = S57map.Pflag.NOSP;
     94                        }
     95                        objl = (Long) S57dat.decSubf(S57subf.OBJL);
     96                        break;
     97                    case "FOID":
     98                        name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
     99                        map.newFeature(name, pflag, objl);
     100                        break;
     101                    case "ATTF":
     102                        S57dat.setField(record, fields + pos, S57field.ATTF, len);
     103                        do {
     104                            long attl = (Long) S57dat.decSubf(S57subf.ATTL);
     105                            String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
     106                            if (!atvl.isEmpty()) {
     107                                map.newAtt(attl, atvl);
     108                            }
     109                        } while (S57dat.more());
     110                        break;
     111                    case "FFPT":
     112                        S57dat.setField(record, fields + pos, S57field.FFPT, len);
     113                        do {
     114                            name = (long) S57dat.decSubf(S57subf.LNAM);
     115                            int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
     116                            S57dat.decSubf(S57subf.COMT);
     117                            map.refObj(name, rind);
     118                        } while (S57dat.more());
     119                        break;
     120                    case "FSPT":
     121                        S57dat.setField(record, fields + pos, S57field.FSPT, len);
     122                        do {
     123                            name = (long) S57dat.decSubf(S57subf.NAME) << 16;
     124                            map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
     125                            S57dat.decSubf(S57subf.MASK);
     126                        } while (S57dat.more());
     127                        break;
     128                    case "VRID":
     129                        inFeature = false;
     130                        name = (Long) S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
     131                        switch ((int) name) {
     132                        case 110:
     133                            nflag = Nflag.ISOL;
     134                            break;
     135                        case 120:
     136                            nflag = Nflag.CONN;
     137                            break;
     138                        default:
     139                            nflag = Nflag.ANON;
     140                            break;
     141                        }
     142                        name <<= 32;
     143                        name += (long) S57dat.decSubf(S57subf.RCID);
     144                        name <<= 16;
     145                        if (nflag == Nflag.ANON) {
     146                            map.newEdge(name);
     147                        }
     148                        break;
     149                    case "VRPT":
     150                        S57dat.setField(record, fields + pos, S57field.VRPT, len);
     151                        do {
     152                            long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
     153                            int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
     154                            map.addConn(conn, topi);
     155                            S57dat.decSubf(S57subf.MASK);
     156                        } while (S57dat.more());
     157                        break;
     158                    case "SG2D":
     159                        S57dat.setField(record, fields + pos, S57field.SG2D, len);
     160                        do {
     161                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
     162                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
     163                            if (nflag == Nflag.ANON) {
     164                                map.newNode(++name, lat, lon, nflag);
     165                            } else {
     166                                map.newNode(name, lat, lon, nflag);
     167                            }
     168                            lat = Math.toRadians(lat);
     169                            lon = Math.toRadians(lon);
     170                            if (lat < map.bounds.minlat)
     171                                map.bounds.minlat = lat;
     172                            if (lat > map.bounds.maxlat)
     173                                map.bounds.maxlat = lat;
     174                            if (lon < map.bounds.minlon)
     175                                map.bounds.minlon = lon;
     176                            if (lon > map.bounds.maxlon)
     177                                map.bounds.maxlon = lon;
     178                        } while (S57dat.more());
     179                        break;
     180                    case "SG3D":
     181                        S57dat.setField(record, fields + pos, S57field.SG3D, len);
     182                        do {
     183                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
     184                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
     185                            double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
     186                            map.newNode(name++, lat, lon, depth);
     187                            lat = Math.toRadians(lat);
     188                            lon = Math.toRadians(lon);
     189                            if (lat < map.bounds.minlat)
     190                                map.bounds.minlat = lat;
     191                            if (lat > map.bounds.maxlat)
     192                                map.bounds.maxlat = lat;
     193                            if (lon < map.bounds.minlon)
     194                                map.bounds.minlon = lon;
     195                            if (lon > map.bounds.maxlon)
     196                                map.bounds.maxlon = lon;
     197                        } while (S57dat.more());
     198                        break;
     199                    default:
     200                        break;
     201                    }
     202                }
     203                if (inFeature) {
     204                    map.endFeature();
     205                    inFeature = false;
     206                }
     207            }
     208        }
     209        map.endFile();
     210        in.close();
     211
     212        return;
     213    }
     214
    213215}
  • applications/editors/josm/plugins/seachart/src/s57/S57enc.java

    r31846 r32394  
    2121import java.util.zip.CRC32;
    2222
    23 import s57.S57obj.*;
     23import s57.S57att.Att;
     24import s57.S57dat.Fparams;
     25import s57.S57dat.S57field;
     26import s57.S57map.AttMap;
     27import s57.S57map.Feature;
     28import s57.S57map.Nflag;
     29import s57.S57map.ObjTab;
     30import s57.S57map.Pflag;
     31import s57.S57map.Prim;
     32import s57.S57obj.Obj;
    2433import s57.S57val.AttVal;
    25 import s57.S57att.Att;
    26 import s57.S57dat.*;
    27 import s57.S57map.*;
    2834
    2935public class S57enc { // S57 ENC file generation
    30 
    31         private static final byte[] header = {
    32                
    33                 '0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
    34                 '0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
    35                 'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
    36                 'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
    37                 'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
    38                 'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
    39                 'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
    40                 'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
    41                 'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
    42                 // File control field
    43                 '0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
    44                 '0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
    45                 '0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
    46                 'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
    47                 '0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
    48                 'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
    49                 // Record identifier fields
    50                 '0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
    51                 'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
    52                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
    53                 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
    54                 'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
    55                 '!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
    56                 'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
    57                 '4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
    58                 ',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
    59                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
    60                 'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
    61                 'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
    62                 '!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
    63                 'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
    64                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
    65                 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
    66                 '!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
    67                 'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
    68                 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
    69                 '1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
    70                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
    71                 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
    72                 '!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
    73                 '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
    74                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
    75                 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
    76                 '!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
    77                 '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
    78                 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
    79                 '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
    80                 '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
    81                 't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
    82                 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
    83                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
    84                 ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
    85                 'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
    86                 ')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
    87                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
    88                 ' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
    89                 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
    90                 '(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
    91                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
    92                 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
    93                 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
    94                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
    95                 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
    96                 '1', '2', ',', 'A', ')', 0x1e,
    97                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
    98                 'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
    99                 '!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
    100                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
    101                 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
    102                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
    103                 'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
    104                 '!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
    105         };
    106        
    107         static final double COMF=10000000;
    108         static final double SOMF=10;
    109        
    110         static String file = "0S000000.000";
    111         static int intu = 0;
    112         static String code = "0S";
    113         static int agen = 3878;
    114         static int cscl = 10000;
    115         static int vdat = 23;
    116         static int duni = 1;
    117         static int huni = 1;
    118        
    119         static int idx;
    120         static int recs;
    121        
    122         static int isols;
    123         static int conns;
    124         static int metas;
    125         static int geos;
    126         static int edges;
    127        
    128         static long hash(long val) {
    129                 byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
    130                 CRC32 crc = new CRC32();
    131                 crc.update(bval);
    132                 return crc.getValue();
    133         }
    134 
    135         public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
    136                
    137                 for (Entry<String, String> entry : meta.entrySet()) {
    138                         try {
    139                                 switch (entry.getKey()) {
    140                                 case "FILE":
    141                                         file = entry.getValue();
    142                                         break;
    143                                 case "INTU":
    144                                         intu = Integer.parseInt(entry.getValue());
    145                                         break;
    146                                 case "AGEN":
    147                                         String[] tokens = entry.getValue().split("/");
    148                                         code = tokens[0];
    149                                         agen = Integer.parseInt(tokens[1]);
    150                                         break;
    151                                 case "VDAT":
    152                                         vdat = Integer.parseInt(entry.getValue());
    153                                         break;
    154                                 case "CSCL":
    155                                         cscl = Integer.parseInt(entry.getValue());
    156                                         break;
    157                                 case "DUNI":
    158                                         duni = Integer.parseInt(entry.getValue());
    159                                         break;
    160                                 case "HUNI":
    161                                         huni = Integer.parseInt(entry.getValue());
    162                                         break;
    163                                 }
    164                         } catch (Exception e) {
    165                                 System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
    166                                 System.exit(-1);
    167                         }
    168                 }
    169                
    170                 //M_COVR & MNSYS in BB if not in map
    171                 if (!map.features.containsKey(Obj.M_COVR)) {
    172                         S57osm.OSMmeta(map);
    173                 }
    174                
    175                 S57dat.S57geoms(map);
    176 
    177                 byte[] record;
    178                 ArrayList<Fparams> fields;
    179 
    180                 isols = conns = metas = geos = edges = 0;
    181                 String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
    182                 ArrayList<Fparams> ds = new ArrayList<>();
    183                 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
    184                 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
    185                 ArrayList<Fparams> dp = new ArrayList<>();
    186                 dp.add(new Fparams(S57field.DSPM, new Object[] { 20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
    187 
    188                 System.arraycopy(header, 0, buf, 0, header.length);
    189                 idx = header.length;
    190                 record = S57dat.encRecord(1, ds);
    191                 System.arraycopy(record, 0, buf, idx, record.length);
    192                 idx += record.length;
    193                 record = S57dat.encRecord(2, dp);
    194                 System.arraycopy(record, 0, buf, idx, record.length);
    195                 idx += record.length;
    196                 recs = 3;
    197 
    198                 // Depths
    199                 Object[] depths = new Object[0];
    200                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    201                         S57map.Snode node = entry.getValue();
    202                         if (node.flg == Nflag.DPTH) {
    203                                 Object[] dval = new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
    204                                 depths = Arrays.copyOf(depths, (depths.length + dval.length));
    205                                 System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
    206                         }
    207                 }
    208                 if (depths.length > 0) {
    209                         fields = new ArrayList<>();
    210                         fields.add(new Fparams(S57field.VRID, new Object[] { 110, -2, 1, 1 }));
    211                         fields.add(new Fparams(S57field.SG3D, depths));
    212                         record = S57dat.encRecord(recs++, fields);
    213                         System.arraycopy(record, 0, buf, idx, record.length);
    214                         idx += record.length;
    215                         isols++;
    216                 }
    217 
    218                 // Isolated nodes
    219                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    220                         S57map.Snode node = entry.getValue();
    221                         if (node.flg == Nflag.ISOL) {
    222                                 fields = new ArrayList<>();
    223                                 fields.add(new Fparams(S57field.VRID, new Object[] { 110, hash(entry.getKey()), 1, 1 }));
    224                                 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
    225                                 record = S57dat.encRecord(recs++, fields);
    226                                 System.arraycopy(record, 0, buf, idx, record.length);
    227                                 idx += record.length;
    228                                 isols++;
    229                         }
    230                 }
    231 
    232                 // Connected nodes
    233                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    234                         S57map.Snode node = entry.getValue();
    235                         if (node.flg == Nflag.CONN) {
    236                                 fields = new ArrayList<>();
    237                                 fields.add(new Fparams(S57field.VRID, new Object[] { 120, hash(entry.getKey()), 1, 1 }));
    238                                 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
    239                                 record = S57dat.encRecord(recs++, fields);
    240                                 System.arraycopy(record, 0, buf, idx, record.length);
    241                                 idx += record.length;
    242                                 conns++;
    243                         }
    244                 }
    245 
    246                 // Edges
    247                 for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
    248                         S57map.Edge edge = entry.getValue();
    249                         fields = new ArrayList<>();
    250                         fields.add(new Fparams(S57field.VRID, new Object[] { 130, hash(entry.getKey()), 1, 1 }));
    251                         fields.add(new Fparams(S57field.VRPT, new Object[] { (((hash(edge.first) & 0xffffffff) << 8) + 120l), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120l), 255, 255, 2, 255 }));
    252                         Object[] nodes = new Object[0];
    253                         for (long ref : edge.nodes) {
    254                                 Object[] nval = new Object[] { (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
    255                                 nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
    256                                 System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
    257                         }
    258                         if (nodes.length > 0) {
    259                                 fields.add(new Fparams(S57field.SG2D, nodes));
    260                         }
    261                         record = S57dat.encRecord(recs++, fields);
    262                         System.arraycopy(record, 0, buf, idx, record.length);
    263                         idx += record.length;
    264                         edges++;
    265                 }
    266 
    267                 // Meta & Geo objects
    268                 boolean soundings = false;
    269                 for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
    270                         Obj obj = entry.getKey();
    271                         for (Feature feature : entry.getValue()) {
    272                                 if (obj == Obj.SOUNDG) {
    273                                         if (soundings) {
    274                                                 continue;
    275                                         } else {
    276                                                 soundings = true;
    277                                         }
    278                                 }
    279                                 int prim = feature.geom.prim.ordinal();
    280                                 prim = (prim == 0) ? 255 : prim;
    281                                 int grup = ((obj == Obj.DEPARE) || (obj == Obj.DRGARE) || (obj == Obj.FLODOC) || (obj == Obj.HULKES) || (obj == Obj.LNDARE) || (obj == Obj.PONTON) || (obj == Obj.UNSARE)) ? 1 : 2;
    282 
    283                                 ArrayList<Fparams> geom = new ArrayList<>();
    284                                 int outers = 0;
    285                                 outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
    286                                 for (Prim elem : feature.geom.elems) {
    287                                         if (feature.geom.prim == Pflag.POINT) {
    288                                                 if (obj == Obj.SOUNDG) {
    289                                                         geom.add(new Fparams(S57field.FSPT, new Object[] { ((-2 << 8) + 110l), 255, 255, 255 }));
    290                                                 } else {
    291                                                         geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120l : 110l)), 255, 255, 255 }));
    292                                                 }
    293                                         } else {
    294                                                 geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + 130l), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
    295                                         }
    296                                 }
    297 
    298                                 ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
    299                                 ArrayList<Long> slaves = new ArrayList<>();
    300                                 long slaveid = feature.id + 0x0100000000000000l;
    301                                 for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
    302                                         Obj objobj = objs.getKey();
    303                                         boolean master = true;
    304                                         for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
    305                                                 ArrayList<Fparams> objatts = new ArrayList<>();
    306                                                 master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
    307                                                 long id = hash(master ? feature.id : slaveid);
    308                                                 objatts.add(new Fparams(S57field.FRID, new Object[] { 100, id, prim, grup, S57obj.encodeType(objobj), 1, 1 }));
    309                                                 objatts.add(new Fparams(S57field.FOID, new Object[] { agen, id, 1 }));
    310                                                 Object[] attf = new Object[0];
    311                                                 Object[] natf = new Object[0];
    312                                                 AttMap atts = map.new AttMap();
    313                                                 atts.putAll(object.getValue());
    314                                                 if (master) {
    315                                                         atts.putAll(feature.atts);
    316                                                 }
    317                                                 for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
    318                                                         if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
    319                                                                 long attl = S57att.encodeAttribute(att.getKey());
    320                                                                 Object[] next = new Object[] { attl, S57val.encodeValue(att.getValue(), att.getKey()) };
    321                                                                 if ((attl < 300) || (attl > 304)) {
    322                                                                         attf = Arrays.copyOf(attf, (attf.length + next.length));
    323                                                                         System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
    324                                                                 } else {
    325                                                                         natf = Arrays.copyOf(natf, (natf.length + next.length));
    326                                                                         System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
    327                                                                 }
    328                                                         }
    329                                                 }
    330                                                 if (attf.length > 0) {
    331                                                         objatts.add(new Fparams(S57field.ATTF, attf));
    332                                                 }
    333                                                 if (natf.length > 0) {
    334                                                         objatts.add(new Fparams(S57field.NATF, attf));
    335                                                 }
    336                                                 if (master) {
    337                                                         objects.add(objatts);
    338                                                 } else {
    339                                                         slaves.add(id);
    340                                                         objects.add(0, objatts);
    341                                                         slaveid += 0x0100000000000000l;
    342                                                 }
    343                                         }
    344                                 }
    345 
    346                                 if (!slaves.isEmpty()) {
    347                                         ArrayList<Fparams> refs = new ArrayList<>();
    348                                         Object[] params = new Object[0];
    349                                         while (!slaves.isEmpty()) {
    350                                                 long id = slaves.remove(0);
    351                                                 Object[] next = new Object[] { (long) ((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)), 2, "" };
    352                                                 params = Arrays.copyOf(params, (params.length + next.length));
    353                                                 System.arraycopy(next, 0, params, (params.length - next.length), next.length);
    354                                         }
    355                                         refs.add(new Fparams(S57field.FFPT, params));
    356                                         objects.get(objects.size() - 1).addAll(refs);
    357                                 }
    358 
    359                                 for (ArrayList<Fparams> object : objects) {
    360                                         object.addAll(geom);
    361                                         record = S57dat.encRecord(recs++, object);
    362                                         System.arraycopy(record, 0, buf, idx, record.length);
    363                                         idx += record.length;
    364                                         if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
    365                                                 metas++;
    366                                         } else {
    367                                                 geos++;
    368                                         }
    369                                 }
    370                         }
    371                 }
    372 
    373                 // Re-write DSID/DSSI with final totals
    374                 ds = new ArrayList<>();
    375                 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
    376                 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
    377                 record = S57dat.encRecord(1, ds);
    378                 System.arraycopy(record, 0, buf, header.length, record.length);
    379 
    380                 return idx;
    381         }
     36    // CHECKSTYLE.OFF: LineLength
     37
     38    private static final byte[] header = {
     39
     40            '0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
     41            '0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
     42            'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
     43            'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
     44            'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
     45            'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
     46            'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
     47            'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
     48            'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
     49            // File control field
     50            '0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
     51            '0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
     52            '0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
     53            'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
     54            '0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
     55            'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
     56            // Record identifier fields
     57            '0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
     58            'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
     59            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
     60            'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
     61            'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
     62            '!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
     63            'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
     64            '4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
     65            ',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
     66            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
     67            'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
     68            'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
     69            '!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
     70            'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
     71            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
     72            't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
     73            '!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
     74            'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
     75            'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
     76            '1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
     77            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
     78            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
     79            '!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
     80            '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
     81            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
     82            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
     83            '!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
     84            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
     85            't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
     86            '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
     87            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
     88            't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
     89            'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
     90            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
     91            ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
     92            'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
     93            ')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
     94            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
     95            ' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
     96            'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
     97            '(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
     98            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
     99            'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
     100            'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
     101            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
     102            'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
     103            '1', '2', ',', 'A', ')', 0x1e,
     104            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
     105            'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
     106            '!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
     107            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
     108            'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
     109            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
     110            'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
     111            '!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
     112    };
     113
     114    static final double COMF = 10000000;
     115    static final double SOMF = 10;
     116
     117    static String file = "0S000000.000";
     118    static int intu = 0;
     119    static String code = "0S";
     120    static int agen = 3878;
     121    static int cscl = 10000;
     122    static int vdat = 23;
     123    static int duni = 1;
     124    static int huni = 1;
     125
     126    static int idx;
     127    static int recs;
     128
     129    static int isols;
     130    static int conns;
     131    static int metas;
     132    static int geos;
     133    static int edges;
     134
     135    static long hash(long val) {
     136        byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
     137        CRC32 crc = new CRC32();
     138        crc.update(bval);
     139        return crc.getValue();
     140    }
     141
     142    public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
     143
     144        for (Entry<String, String> entry : meta.entrySet()) {
     145            try {
     146                switch (entry.getKey()) {
     147                case "FILE":
     148                    file = entry.getValue();
     149                    break;
     150                case "INTU":
     151                    intu = Integer.parseInt(entry.getValue());
     152                    break;
     153                case "AGEN":
     154                    String[] tokens = entry.getValue().split("/");
     155                    code = tokens[0];
     156                    agen = Integer.parseInt(tokens[1]);
     157                    break;
     158                case "VDAT":
     159                    vdat = Integer.parseInt(entry.getValue());
     160                    break;
     161                case "CSCL":
     162                    cscl = Integer.parseInt(entry.getValue());
     163                    break;
     164                case "DUNI":
     165                    duni = Integer.parseInt(entry.getValue());
     166                    break;
     167                case "HUNI":
     168                    huni = Integer.parseInt(entry.getValue());
     169                    break;
     170                }
     171            } catch (Exception e) {
     172                System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
     173                System.exit(-1);
     174            }
     175        }
     176
     177        //M_COVR & MNSYS in BB if not in map
     178        if (!map.features.containsKey(Obj.M_COVR)) {
     179            S57osm.OSMmeta(map);
     180        }
     181
     182        S57dat.S57geoms(map);
     183
     184        byte[] record;
     185        ArrayList<Fparams> fields;
     186
     187        isols = conns = metas = geos = edges = 0;
     188        String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
     189        ArrayList<Fparams> ds = new ArrayList<>();
     190        ds.add(new Fparams(S57field.DSID, new Object[] {10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
     191        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
     192        ArrayList<Fparams> dp = new ArrayList<>();
     193        dp.add(new Fparams(S57field.DSPM, new Object[] {20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
     194
     195        System.arraycopy(header, 0, buf, 0, header.length);
     196        idx = header.length;
     197        record = S57dat.encRecord(1, ds);
     198        System.arraycopy(record, 0, buf, idx, record.length);
     199        idx += record.length;
     200        record = S57dat.encRecord(2, dp);
     201        System.arraycopy(record, 0, buf, idx, record.length);
     202        idx += record.length;
     203        recs = 3;
     204
     205        // Depths
     206        Object[] depths = new Object[0];
     207        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     208            S57map.Snode node = entry.getValue();
     209            if (node.flg == Nflag.DPTH) {
     210                Object[] dval = new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
     211                depths = Arrays.copyOf(depths, (depths.length + dval.length));
     212                System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
     213            }
     214        }
     215        if (depths.length > 0) {
     216            fields = new ArrayList<>();
     217            fields.add(new Fparams(S57field.VRID, new Object[] {110, -2, 1, 1 }));
     218            fields.add(new Fparams(S57field.SG3D, depths));
     219            record = S57dat.encRecord(recs++, fields);
     220            System.arraycopy(record, 0, buf, idx, record.length);
     221            idx += record.length;
     222            isols++;
     223        }
     224
     225        // Isolated nodes
     226        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     227            S57map.Snode node = entry.getValue();
     228            if (node.flg == Nflag.ISOL) {
     229                fields = new ArrayList<>();
     230                fields.add(new Fparams(S57field.VRID, new Object[] {110, hash(entry.getKey()), 1, 1 }));
     231                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
     232                record = S57dat.encRecord(recs++, fields);
     233                System.arraycopy(record, 0, buf, idx, record.length);
     234                idx += record.length;
     235                isols++;
     236            }
     237        }
     238
     239        // Connected nodes
     240        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     241            S57map.Snode node = entry.getValue();
     242            if (node.flg == Nflag.CONN) {
     243                fields = new ArrayList<>();
     244                fields.add(new Fparams(S57field.VRID, new Object[] {120, hash(entry.getKey()), 1, 1 }));
     245                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
     246                record = S57dat.encRecord(recs++, fields);
     247                System.arraycopy(record, 0, buf, idx, record.length);
     248                idx += record.length;
     249                conns++;
     250            }
     251        }
     252
     253        // Edges
     254        for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
     255            S57map.Edge edge = entry.getValue();
     256            fields = new ArrayList<>();
     257            fields.add(new Fparams(S57field.VRID, new Object[] {130, hash(entry.getKey()), 1, 1}));
     258            fields.add(new Fparams(S57field.VRPT, new Object[] {(((hash(edge.first) & 0xffffffff) << 8) + 120L), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120L), 255, 255, 2, 255 }));
     259            Object[] nodes = new Object[0];
     260            for (long ref : edge.nodes) {
     261                Object[] nval = new Object[] {(Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
     262                nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
     263                System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
     264            }
     265            if (nodes.length > 0) {
     266                fields.add(new Fparams(S57field.SG2D, nodes));
     267            }
     268            record = S57dat.encRecord(recs++, fields);
     269            System.arraycopy(record, 0, buf, idx, record.length);
     270            idx += record.length;
     271            edges++;
     272        }
     273
     274        // Meta & Geo objects
     275        boolean soundings = false;
     276        for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
     277            Obj obj = entry.getKey();
     278            for (Feature feature : entry.getValue()) {
     279                if (obj == Obj.SOUNDG) {
     280                    if (soundings) {
     281                        continue;
     282                    } else {
     283                        soundings = true;
     284                    }
     285                }
     286                int prim = feature.geom.prim.ordinal();
     287                prim = (prim == 0) ? 255 : prim;
     288                int grup = ((obj == Obj.DEPARE) || (obj == Obj.DRGARE) || (obj == Obj.FLODOC) || (obj == Obj.HULKES) || (obj == Obj.LNDARE) || (obj == Obj.PONTON) || (obj == Obj.UNSARE)) ? 1 : 2;
     289
     290                ArrayList<Fparams> geom = new ArrayList<>();
     291                int outers = 0;
     292                outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
     293                for (Prim elem : feature.geom.elems) {
     294                    if (feature.geom.prim == Pflag.POINT) {
     295                        if (obj == Obj.SOUNDG) {
     296                            geom.add(new Fparams(S57field.FSPT, new Object[] {((-2 << 8) + 110L), 255, 255, 255 }));
     297                        } else {
     298                            geom.add(new Fparams(S57field.FSPT, new Object[] {((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120L : 110L)), 255, 255, 255 }));
     299                        }
     300                    } else {
     301                        geom.add(new Fparams(S57field.FSPT, new Object[] {((hash(elem.id) << 8) + 130L), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
     302                    }
     303                }
     304
     305                ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
     306                ArrayList<Long> slaves = new ArrayList<>();
     307                long slaveid = feature.id + 0x0100000000000000L;
     308                for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
     309                    Obj objobj = objs.getKey();
     310                    boolean master = true;
     311                    for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
     312                        ArrayList<Fparams> objatts = new ArrayList<>();
     313                        master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
     314                        long id = hash(master ? feature.id : slaveid);
     315                        objatts.add(new Fparams(S57field.FRID, new Object[] {100, id, prim, grup, S57obj.encodeType(objobj), 1, 1}));
     316                        objatts.add(new Fparams(S57field.FOID, new Object[] {agen, id, 1}));
     317                        Object[] attf = new Object[0];
     318                        Object[] natf = new Object[0];
     319                        AttMap atts = map.new AttMap();
     320                        atts.putAll(object.getValue());
     321                        if (master) {
     322                            atts.putAll(feature.atts);
     323                        }
     324                        for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
     325                            if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
     326                                long attl = S57att.encodeAttribute(att.getKey());
     327                                Object[] next = new Object[] {attl, S57val.encodeValue(att.getValue(), att.getKey())};
     328                                if ((attl < 300) || (attl > 304)) {
     329                                    attf = Arrays.copyOf(attf, (attf.length + next.length));
     330                                    System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
     331                                } else {
     332                                    natf = Arrays.copyOf(natf, (natf.length + next.length));
     333                                    System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
     334                                }
     335                            }
     336                        }
     337                        if (attf.length > 0) {
     338                            objatts.add(new Fparams(S57field.ATTF, attf));
     339                        }
     340                        if (natf.length > 0) {
     341                            objatts.add(new Fparams(S57field.NATF, attf));
     342                        }
     343                        if (master) {
     344                            objects.add(objatts);
     345                        } else {
     346                            slaves.add(id);
     347                            objects.add(0, objatts);
     348                            slaveid += 0x0100000000000000L;
     349                        }
     350                    }
     351                }
     352
     353                if (!slaves.isEmpty()) {
     354                    ArrayList<Fparams> refs = new ArrayList<>();
     355                    Object[] params = new Object[0];
     356                    while (!slaves.isEmpty()) {
     357                        long id = slaves.remove(0);
     358                        Object[] next = new Object[] {(long) ((((id & 0xffffffff) + 0x100000000L) << 16) + (agen & 0xffff)), 2, "" };
     359                        params = Arrays.copyOf(params, (params.length + next.length));
     360                        System.arraycopy(next, 0, params, (params.length - next.length), next.length);
     361                    }
     362                    refs.add(new Fparams(S57field.FFPT, params));
     363                    objects.get(objects.size() - 1).addAll(refs);
     364                }
     365
     366                for (ArrayList<Fparams> object : objects) {
     367                    object.addAll(geom);
     368                    record = S57dat.encRecord(recs++, object);
     369                    System.arraycopy(record, 0, buf, idx, record.length);
     370                    idx += record.length;
     371                    if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
     372                        metas++;
     373                    } else {
     374                        geos++;
     375                    }
     376                }
     377            }
     378        }
     379
     380        // Re-write DSID/DSSI with final totals
     381        ds = new ArrayList<>();
     382        ds.add(new Fparams(S57field.DSID, new Object[] {10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
     383        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
     384        record = S57dat.encRecord(1, ds);
     385        System.arraycopy(record, 0, buf, header.length, record.length);
     386
     387        return idx;
     388    }
    382389
    383390}
  • applications/editors/josm/plugins/seachart/src/s57/S57map.java

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57obj;
    15 import s57.S57obj.*;
    16 import s57.S57att;
    17 import s57.S57att.*;
    18 import s57.S57val;
    19 import s57.S57val.*;
    20 import s57.S57osm;
    21 import s57.S57osm.*;
     12import java.util.ArrayList;
     13import java.util.EnumMap;
     14import java.util.HashMap;
     15import java.util.ListIterator;
     16
     17import s57.S57att.Att;
     18import s57.S57obj.Obj;
     19import s57.S57osm.KeyVal;
     20import s57.S57val.AttVal;
    2221
    2322public class S57map { // S57/OSM map generation methods
    24        
    25         public class MapBounds {
    26                 public double minlat;
    27                 public double minlon;
    28                 public double maxlat;
    29                 public double maxlon;
    30                 public MapBounds() {
    31                         minlat = Math.toRadians(90);
    32                         minlon = Math.toRadians(180);
    33                         maxlat = Math.toRadians(-90);
    34                         maxlon = Math.toRadians(-180);
    35                 }
    36         }
    37 
    38         public enum Nflag {
    39                 ANON,   // Edge inner nodes
    40                 ISOL,   // Node not part of Edge
    41                 CONN,   // Edge first and last nodes
    42                 TRNK, // Edge truncated polygon nodes
    43                 DPTH    // Sounding nodes
    44         }
    45 
    46         public class Snode {    // All coordinates in map
    47                 public double lat;      // Latitude in radians
    48                 public double lon;      // Longitude in radians
    49                 public Nflag flg;               // Role of node
    50                 public double val;      // Optional value
    51 
    52                 public Snode() {
    53                         flg = Nflag.ANON;
    54                         lat = 0;
    55                         lon = 0;
    56                         val = 0;
    57                 }
    58                 public Snode(double ilat, double ilon) {
    59                         flg = Nflag.ANON;
    60                         lat = ilat;
    61                         lon = ilon;
    62                         val = 0;
    63                 }
    64                 public Snode(double ilat, double ilon, Nflag iflg) {
    65                         lat = ilat;
    66                         lon = ilon;
    67                         flg = iflg;
    68                         val = 0;
    69                 }
    70                 public Snode(double ilat, double ilon, double ival) {
    71                         flg = Nflag.DPTH;
    72                         lat = ilat;
    73                         lon = ilon;
    74                         val = ival;
    75                 }
    76         }
    77 
    78         public class Edge {             // A polyline segment
    79                 public long first;      // First CONN node
    80                 public long last;               // Last CONN node
    81                 public ArrayList<Long> nodes; // Inner ANON nodes
    82 
    83                 public Edge() {
    84                         first = 0;
    85                         last = 0;
    86                         nodes = new ArrayList<>();
    87                 }
    88         }
    89        
    90         public enum Rflag {
    91                 UNKN, MASTER, SLAVE
    92         }
    93        
    94         public class Reln {
    95                 public long id;
    96                 public Rflag reln;
    97                 public Reln(long i, Rflag r) {
    98                         id = i;
    99                         reln = r;
    100                 }
    101         }
    102 
    103         public class RelTab extends ArrayList<Reln> {
    104                 public RelTab() {
    105                         super();
    106                 }
    107         }
    108 
    109         public class ObjTab extends HashMap<Integer, AttMap> {
    110                 public ObjTab() {
    111                         super();
    112                 }
    113         }
    114 
    115         public class ObjMap extends EnumMap<Obj, ObjTab> {
    116                 public ObjMap() {
    117                         super(Obj.class);
    118                 }
    119         }
    120 
    121         public class AttMap extends HashMap<Att, AttVal<?>> {
    122                 public AttMap() {
    123                         super();
    124                 }
    125         }
    126 
    127         public class NodeTab extends HashMap<Long, Snode> {
    128                 public NodeTab() {
    129                         super();
    130                 }
    131         }
    132 
    133         public class EdgeTab extends HashMap<Long, Edge> {
    134                 public EdgeTab() {
    135                         super();
    136                 }
    137         }
    138 
    139         public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
    140                 public FtrMap() {
    141                         super(Obj.class);
    142                 }
    143         }
    144 
    145         public class FtrTab extends HashMap<Long, Feature> {
    146                 public FtrTab() {
    147                         super();
    148                 }
    149         }
    150 
    151         public class Prim {                             // Spatial element
    152                 public long id;                                 // Snode ID for POINTs, Edge ID for LINEs & AREAs)
    153                 public boolean forward; // Direction of vector used (LINEs & AREAs)
    154                 public boolean outer;           // Exterior/Interior boundary (AREAs)
    155                 public boolean trunc;           // Cell limit truncation
    156                 public Prim() {
    157                         id = 0; forward = true; outer = true; trunc = false;
    158                 }
    159                 public Prim(long i) {
    160                         id = i; forward = true; outer = true; trunc = false;
    161                 }
    162                 public Prim(long i, boolean o) {
    163                         id = i; forward = true; outer = o; trunc = false;
    164                 }
    165                 public Prim(long i, boolean f, boolean o) {
    166                         id = i; forward = f; outer = o; trunc = false;
    167                 }
    168                 public Prim(long i, boolean f, boolean o, boolean t) {
    169                         id = i; forward = f; outer = o; trunc = t;
    170                 }
    171         }
    172        
    173         public class Comp {                     // Composite spatial element
    174                 public long ref;                        // ID of Comp
    175                 public int size;                        // Number of Prims in this Comp
    176                 public Comp(long r, int s) {
    177                         ref = r;
    178                         size = s;
    179                 }
    180         }
    181        
    182         public enum Pflag {
    183                 NOSP, POINT, LINE, AREA
    184         }
    185        
    186         public class Geom {                                                     // Geometric structure of feature
    187                 public Pflag prim;                                              // Geometry type
    188                 public ArrayList<Prim> elems;   // Ordered list of elements
    189                 public int outers;                                              // Number of outers
    190                 public int inners;                                              // Number of inners
    191                 public ArrayList<Comp> comps;   // Ordered list of compounds
    192                 public double area;                                             // Area of feature
    193                 public double length;                                   // Length of feature
    194                 public Snode centre;                                    // Centre of feature
    195                 public Geom(Pflag p) {
    196                         prim = p;
    197                         elems = new ArrayList<>();
    198                         outers = inners = 0;
    199                         comps = new ArrayList<>();
    200                         area = 0;
    201                         length = 0;
    202                         centre = new Snode();
    203                 }
    204         }
    205        
    206         public class Feature {
    207                 public long id;                         // Ref for this feature
    208                 public Rflag reln;              // Relationship status
    209                 public Geom geom;                       // Geometry data
    210                 public Obj type;                        // Feature type
    211                 public AttMap atts;             // Feature attributes
    212                 public RelTab rels;             // Related objects
    213                 public ObjMap objs;             // Slave object attributes
    214 
    215                 Feature() {
    216                         id = 0;
    217                         reln = Rflag.UNKN;
    218                         geom = new Geom(Pflag.NOSP);
    219                         type = Obj.UNKOBJ;
    220                         atts = new AttMap();
    221                         rels = new RelTab();
    222                         objs = new ObjMap();
    223                 }
    224         }
    225        
    226         public MapBounds bounds;
    227         public NodeTab nodes;
    228         public EdgeTab edges;
    229         public FtrMap features;
    230         public FtrTab index;
    231         public long xref;
    232 
    233         private long cref;
    234         private Feature feature;
    235         private Edge edge;
    236         private ArrayList<KeyVal<?>> osm;
    237         private boolean sea;
    238 
    239         public S57map(boolean s) {
    240                 sea = s;
    241                 nodes = new NodeTab();          // All nodes in map
    242                 edges = new EdgeTab();          // All edges in map
    243                 feature = new Feature();        // Current feature being built
    244                 features = new FtrMap();        // All features in map, grouped by type
    245                 index = new FtrTab();                   // Feature look-up table
    246                 bounds = new MapBounds();
    247                 cref = 0x0000ffffffff0000L;// Compound reference generator
    248                 xref = 0x0fff000000000000L;// Extras reference generator
    249         }
    250 
    251         // S57 map building methods
    252        
    253         public void newNode(long id, double lat, double lon, Nflag flag) {
    254                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
    255                 if (flag == Nflag.ANON) {
    256                         edge.nodes.add(id);
    257                 }
    258         }
    259 
    260         public void newNode(long id, double lat, double lon, double depth) {
    261                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
    262         }
    263 
    264         public void newFeature(long id, Pflag p, long objl) {
    265                 feature = new Feature();
    266                 Obj obj = S57obj.decodeType(objl);
    267                 feature.geom = new Geom(p);
    268                 feature.type = obj;
    269                 if (obj != Obj.UNKOBJ) {
    270                         index.put(id, feature);
    271                         feature.id = id;
    272                 }
    273         }
    274        
    275         public void refObj(long id, int rind) {
    276                 Rflag r = Rflag.UNKN;
    277                 switch (rind) {
    278                 case 1:
    279                         r = Rflag.MASTER;
    280                         break;
    281                 case 2:
    282                         r = Rflag.SLAVE;
    283                         break;
    284                 case 3:
    285                         r = Rflag.UNKN;
    286                         break;
    287                 }
    288                 feature.rels.add(new Reln(id, r));
    289         }
    290        
    291         public void endFeature() {
    292                
    293         }
    294        
    295         public void newAtt(long attl, String atvl) {
    296                 Att att = S57att.decodeAttribute(attl);
    297                 AttVal<?> val = S57val.decodeValue(atvl, att);
    298                 feature.atts.put(att, val);
    299         }
    300 
    301         public void newPrim(long id, long ornt, long usag) {
    302                 feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
    303         }
    304 
    305         public void addConn(long id, int topi) {
    306                 if (topi == 1) {
    307                         edge.first = id;
    308                 } else {
    309                         edge.last = id;
    310                 }
    311         }
    312 
    313         public void newEdge(long id) {
    314                 edge = new Edge();
    315                 edges.put(id, edge);
    316         }
    317 
    318         public void endFile() {
    319                 for (long id : index.keySet()) {
    320                         Feature feature = index.get(id);
    321                         sortGeom(feature);
    322                         for (Reln reln : feature.rels) {
    323                                 Feature rel = index.get(reln.id);
    324                                 if (cmpGeoms(feature.geom, rel.geom)) {
    325                                         switch (reln.reln) {
    326                                         case SLAVE:
    327                                                 feature.reln = Rflag.MASTER;
    328                                                 break;
    329                                         default:
    330                                                 feature.reln = Rflag.UNKN;
    331                                                 break;
    332                                         }
    333                                         rel.reln = reln.reln;
    334                                 } else {
    335                                         reln.reln = Rflag.UNKN;
    336                                 }
    337                         }
    338                 }
    339                 for (long id : index.keySet()) {
    340                         Feature feature = index.get(id);
    341                         if (feature.reln == Rflag.UNKN) {
    342                                 feature.reln = Rflag.MASTER;
    343                         }
    344                         if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
    345                                 if (features.get(feature.type) == null) {
    346                                         features.put(feature.type, new ArrayList<Feature>());
    347                                 }
    348                                 features.get(feature.type).add(feature);
    349                         }
    350                 }
    351                 for (long id : index.keySet()) {
    352                         Feature feature = index.get(id);
    353                         for (Reln reln : feature.rels) {
    354                                 Feature rel = index.get(reln.id);
    355                                 if (rel.reln == Rflag.SLAVE) {
    356                                         if (feature.objs.get(rel.type) == null) {
    357                                                 feature.objs.put(rel.type, new ObjTab());
    358                                         }
    359                                         ObjTab tab = feature.objs.get(rel.type);
    360                                         int ix = tab.size();
    361                                         tab.put(ix, rel.atts);
    362                                 }
    363                         }
    364                 }
    365         }
    366 
    367         // OSM map building methods
    368 
    369         public void addNode(long id, double lat, double lon) {
    370                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
    371                 feature = new Feature();
    372                 feature.id = id;
    373                 feature.reln = Rflag.UNKN;
    374                 feature.geom.prim = Pflag.POINT;
    375                 feature.geom.elems.add(new Prim(id));
    376                 edge = null;
    377                 osm =  new ArrayList<>();
    378         }
    379 
    380         public void addEdge(long id) {
    381                 feature = new Feature();
    382                 feature.id = id;
    383                 feature.reln = Rflag.UNKN;
    384                 feature.geom.prim = Pflag.LINE;
    385                 feature.geom.elems.add(new Prim(id));
    386                 edge = new Edge();
    387                 osm = new ArrayList<>();
    388         }
    389 
    390         public void addToEdge(long node) {
    391                 if (edge.first == 0) {
    392                         edge.first = node;
    393                         nodes.get(node).flg = Nflag.CONN;
    394                 } else {
    395                         if (edge.last != 0) {
    396                                 edge.nodes.add(edge.last);
    397                         }
    398                         edge.last = node;
    399                 }
    400         }
    401 
    402         public void addArea(long id) {
    403                 feature = new Feature();
    404                 feature.id = id;
    405                 feature.reln = Rflag.UNKN;
    406                 feature.geom.prim = Pflag.AREA;
    407                 edge = null;
    408                 osm = new ArrayList<>();
    409         }
    410 
    411         public void addToArea(long id, boolean outer) {
    412                 feature.geom.elems.add(new Prim(id, outer));
    413         }
    414 
    415         public void addTag(String key, String val) {
    416                 feature.reln = Rflag.MASTER;
    417                 String subkeys[] = key.split(":");
    418                 if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
    419                         Obj obj = S57obj.enumType(subkeys[1]);
    420                         if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
    421                                 int idx = 0;
    422                                 Att att = Att.UNKATT;
    423                                 try {
    424                                         idx = Integer.parseInt(subkeys[2]);
    425                                         if (subkeys.length == 4) {
    426                                                 att = s57.S57att.enumAttribute(subkeys[3], obj);
    427                                         }
    428                                 } catch (Exception e) {
    429                                         att = S57att.enumAttribute(subkeys[2], obj);
    430                                 }
    431                                 ObjTab objs = feature.objs.get(obj);
    432                                 if (objs == null) {
    433                                         objs = new ObjTab();
    434                                         feature.objs.put(obj, objs);
    435                                 }
    436                                 AttMap atts = objs.get(idx);
    437                                 if (atts == null) {
    438                                         atts = new AttMap();
    439                                         objs.put(idx, atts);
    440                                 }
    441                                 AttVal<?> attval = S57val.convertValue(val, att);
    442                                 if (attval.val != null) {
    443                                         if (att == Att.VALSOU) {
    444                                                 Snode node = nodes.get(feature.geom.elems.get(0).id);
    445                                                 node.val = (Double) attval.val;
    446                                         }
    447                                         atts.put(att, attval);
    448                                 }
    449                         } else {
    450                                 if (subkeys[1].equals("type")) {
    451                                         obj = S57obj.enumType(val);
    452                                         feature.type = obj;
    453                                         ObjTab objs = feature.objs.get(obj);
    454                                         if (objs == null) {
    455                                                 objs = new ObjTab();
    456                                                 feature.objs.put(obj, objs);
    457                                         }
    458                                         AttMap atts = objs.get(0);
    459                                         if (atts == null) {
    460                                                 atts = new AttMap();
    461                                                 objs.put(0, atts);
    462                                         }
    463                                         if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
    464                                                 Snode node = nodes.get(feature.geom.elems.get(0).id);
    465                                                 node.flg = Nflag.DPTH;
    466                                         }
    467                                 } else {
    468                                         if (obj != Obj.UNKOBJ) {
    469                                                 if (val.equals("yes")) {
    470                                                         ObjTab objs = feature.objs.get(obj);
    471                                                         if (objs == null) {
    472                                                                 objs = new ObjTab();
    473                                                                 feature.objs.put(obj, objs);
    474                                                         }
    475                                                 }
    476                                         } else {
    477                                                 Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
    478                                                 if (att != Att.UNKATT) {
    479                                                         AttVal<?> attval = S57val.convertValue(val, att);
    480                                                         if (attval.val != null)
    481                                                                 feature.atts.put(att, attval);
    482                                                 }
    483                                         }
    484                                 }
    485                         }
    486                 } else if (!sea) {
    487                         S57osm.OSMtag(osm, key, val);
    488                 }
    489         }
    490 
    491         public void tagsDone(long id) {
    492                 switch (feature.geom.prim) {
    493                 case POINT:
    494                         Snode node = nodes.get(id);
    495                         if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
    496                                 node.flg = Nflag.ISOL;
    497                         }
    498                         break;
    499                 case LINE:
    500                         edges.put(id, edge);
    501                         nodes.get(edge.first).flg = Nflag.CONN;
    502                         nodes.get(edge.last).flg = Nflag.CONN;
    503                         if (edge.first == edge.last) {
    504                                 feature.geom.prim = Pflag.AREA;
    505                         }
    506                         break;
    507                 case AREA:
    508                         break;
    509                 default:
    510                         break;
    511                 }
    512                 if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
    513                         if (feature.type != Obj.UNKOBJ) {
    514                                 index.put(id, feature);
    515                                 if (features.get(feature.type) == null) {
    516                                         features.put(feature.type, new ArrayList<Feature>());
    517                                 }
    518                                 features.get(feature.type).add(feature);
    519                         }
    520                         for (KeyVal<?> kvx : osm) {
    521                                 Feature base = new Feature();
    522                                 base.reln = Rflag.MASTER;
    523                                 base.geom = feature.geom;
    524                                 base.type = kvx.obj;
    525                                 ObjTab objs = new ObjTab();
    526                                 base.objs.put(kvx.obj, objs);
    527                                 AttMap atts = new AttMap();
    528                                 objs.put(0, atts);
    529                                 if (kvx.att != Att.UNKATT) {
    530                                         atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
    531                                 }
    532                                 index.put(++xref, base);
    533                                 if (features.get(kvx.obj) == null) {
    534                                         features.put(kvx.obj, new ArrayList<Feature>());
    535                                 }
    536                                 features.get(kvx.obj).add(base);
    537                         }
    538 /*                      if (!osm.isEmpty()) {
    539                                 if (feature.type == Obj.UNKOBJ) {
    540                                         feature.type = osm.obj;
    541                                         ObjTab objs = feature.objs.get(osm.obj);
    542                                         if (objs == null) {
    543                                                 objs = new ObjTab();
    544                                                 feature.objs.put(osm.obj, objs);
    545                                         }
    546                                         AttMap atts = objs.get(0);
    547                                         if (atts == null) {
    548                                                 atts = new AttMap();
    549                                                 objs.put(0, atts);
    550                                         }
    551                                         if (osm.att != Att.UNKATT) {
    552                                                 atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
    553                                         }
    554                                 } else {
    555                                         Feature base = new Feature();
    556                                         base.reln = Rflag.MASTER;
    557                                         base.geom = feature.geom;
    558                                         base.type = osm.obj;
    559                                         ObjTab objs = new ObjTab();
    560                                         base.objs.put(osm.obj, objs);
    561                                         AttMap atts = new AttMap();
    562                                         objs.put(0, atts);
    563                                         if (osm.att != Att.UNKATT) {
    564                                                 atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
    565                                         }
    566                                         index.put(++xref, base);
    567                                         if (features.get(osm.obj) == null) {
    568                                                 features.put(osm.obj, new ArrayList<Feature>());
    569                                         }
    570                                         features.get(osm.obj).add(base);
    571                                 }
    572                         }*/
    573                 }
    574         }
    575        
    576         public void mapDone() {
    577                 if (!sea) {
    578                         S57box.bBox(this);
    579                 }
    580         }
    581        
    582         // Utility methods
    583 
    584         public boolean sortGeom(Feature feature) {
    585                 try {
    586                         Geom sort = new Geom(feature.geom.prim);
    587                         long first = 0;
    588                         long last = 0;
    589                         Comp comp = null;
    590                         boolean next = true;
    591                         feature.geom.length = 0;
    592                         feature.geom.area = 0;
    593                         if (feature.geom.elems.isEmpty()) {
    594                                 return false;
    595                         }
    596                         if (feature.geom.prim == Pflag.POINT) {
    597                                 feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
    598                                 return true;
    599                         }
    600                         Geom outer = new Geom(feature.geom.prim);
    601                         Geom inner = new Geom(feature.geom.prim);
    602                         for (Prim prim : feature.geom.elems) {
    603                                 if (prim.outer) {
    604                                         outer.elems.add(prim);
    605                                 } else {
    606                                         inner.elems.add(prim);
    607                                 }
    608                         }
    609                         boolean outin = true;
    610                         int sweep = outer.elems.size();
    611                         if (sweep == 0) {
    612                                 return false;
    613                         }
    614                         int prev = sweep;
    615                         int top = 0;
    616                         while (!outer.elems.isEmpty()) {
    617                                 Prim prim = outer.elems.remove(0);
    618                                 Edge edge = edges.get(prim.id);
    619                                 if (edge == null) {
    620                                         return false;
    621                                 }
    622                                 if (next == true) {
    623                                         next = false;
    624                                         first = edge.first;
    625                                         last = edge.last;
    626                                         prim.forward = true;
    627                                         sort.elems.add(prim);
    628                                         if (prim.outer) {
    629                                                 sort.outers++;
    630                                         } else {
    631                                                 sort.inners++;
    632                                         }
    633                                         comp = new Comp(cref++, 1);
    634                                         sort.comps.add(comp);
    635                                 } else {
    636                                         if (edge.first == last) {
    637                                                 sort.elems.add(prim);
    638                                                 last = edge.last;
    639                                                 prim.forward = true;
    640                                                 comp.size++;
    641                                         } else if (edge.last == first) {
    642                                                 sort.elems.add(top, prim);
    643                                                 first = edge.first;
    644                                                 prim.forward = true;
    645                                                 comp.size++;
    646                                         } else if (edge.last == last) {
    647                                                 sort.elems.add(prim);
    648                                                 last = edge.first;
    649                                                 prim.forward = false;
    650                                                 comp.size++;
    651                                         } else if (edge.first == first) {
    652                                                 sort.elems.add(top, prim);
    653                                                 first = edge.last;
    654                                                 prim.forward = false;
    655                                                 comp.size++;
    656                                         } else {
    657                                                 outer.elems.add(prim);
    658                                         }
    659                                 }
    660                                 if (--sweep == 0) {
    661                                         sweep = outer.elems.size();
    662                                         if ((sweep == 0) || (sweep == prev)) {
    663                                                 if ((sort.prim == Pflag.AREA) && (first != last)) {
    664                                                         return false;
    665                                                 }
    666                                                 if (outin) {
    667                                                         if (sweep != 0) {
    668                                                                 return false;
    669                                                         }
    670                                                         outer = inner;
    671                                                         outin = false;
    672                                                         sweep = outer.elems.size();
    673                                                 }
    674                                                 next = true;
    675                                                 top = sort.elems.size();
    676                                         }
    677                                         prev = sweep;
    678                                 }
    679                         }
    680                         if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
    681                                 sort.prim = Pflag.AREA;
    682                         }
    683                         feature.geom = sort;
    684                         if (feature.geom.prim == Pflag.AREA) {
    685                                 int ie = 0;
    686                                 int ic = 0;
    687                                 while (ie < feature.geom.elems.size()) {
    688                                         double area = calcArea(feature.geom, ic);
    689                                         if (ie == 0)
    690                                                 feature.geom.area = Math.abs(area) * 3444 * 3444;
    691                                         if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
    692                                                 ArrayList<Prim> tmp = new ArrayList<>();
    693                                                 for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
    694                                                         Prim p = feature.geom.elems.remove(ie);
    695                                                         p.forward = !p.forward;
    696                                                         tmp.add(0, p);
    697                                                 }
    698                                                 feature.geom.elems.addAll(ie, tmp);
    699                                         }
    700                                         ie += feature.geom.comps.get(ic).size;
    701                                         ic++;
    702                                 }
    703                         }
    704                         feature.geom.length = calcLength(feature.geom);
    705                         feature.geom.centre = calcCentroid(feature);
    706                         return true;
    707                 } catch (Exception e) {
    708                         return false;
    709                 }
    710         }
    711        
    712         public boolean cmpGeoms (Geom g1, Geom g2) {
    713                 return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
    714         }
    715        
    716         public class EdgeIterator {
    717                 Edge edge;
    718                 boolean forward;
    719                 ListIterator<Long> it;
    720 
    721                 public EdgeIterator(Edge e, boolean dir) {
    722                         edge = e;
    723                         forward = dir;
    724                         it = null;
    725                 }
    726 
    727                 public boolean hasNext() {
    728                         return (edge != null);
    729                 }
    730 
    731                 public long nextRef() {
    732                         long ref = 0;
    733                         if (forward) {
    734                                 if (it == null) {
    735                                         ref = edge.first;
    736                                         it = edge.nodes.listIterator();
    737                                 } else {
    738                                         if (it.hasNext()) {
    739                                                 ref = it.next();
    740                                         } else {
    741                                                 ref = edge.last;
    742                                                 edge = null;
    743                                         }
    744                                 }
    745                         } else {
    746                                 if (it == null) {
    747                                         ref = edge.last;
    748                                         it = edge.nodes.listIterator(edge.nodes.size());
    749                                 } else {
    750                                         if (it.hasPrevious()) {
    751                                                 ref = it.previous();
    752                                         } else {
    753                                                 ref = edge.first;
    754                                                 edge = null;
    755                                         }
    756                                 }
    757                         }
    758                         return ref;
    759                 }
    760                
    761                 public Snode next() {
    762                         return nodes.get(nextRef());
    763                 }
    764         }
    765 
    766         public class GeomIterator {
    767                 Geom geom;
    768                 Prim prim;
    769                 EdgeIterator eit;
    770                 ListIterator<S57map.Prim> ite;
    771                 ListIterator<Comp> itc;
    772                 Comp comp;
    773                 int ec;
    774                 long lastref;
    775 
    776                 public GeomIterator(Geom g) {
    777                         geom = g;
    778                         lastref = 0;
    779                         ite = geom.elems.listIterator();
    780                         itc = geom.comps.listIterator();
    781                 }
    782                
    783                 public boolean hasComp() {
    784                         return (itc.hasNext());
    785                 }
    786                
    787                 public long nextComp() {
    788                         comp = itc.next();
    789                         ec = comp.size;
    790                         lastref = 0;
    791                         return comp.ref;
    792                 }
    793                
    794                 public boolean hasEdge() {
    795                         return (ec > 0) && ite.hasNext();
    796                 }
    797                
    798                 public long nextEdge() {
    799                         prim = ite.next();
    800                         eit = new EdgeIterator(edges.get(prim.id), prim.forward);
    801                         ec--;
    802                         return prim.id;
    803                 }
    804                
    805                 public boolean hasNode() {
    806                         return (eit.hasNext());
    807                 }
    808                
    809                 public long nextRef(boolean all) {
    810                         long ref = eit.nextRef();
    811                         if (!all && (ref == lastref)) {
    812                                 ref = eit.nextRef();
    813                         }
    814                         lastref = ref;
    815                         return ref;
    816                 }
    817                
    818                 public long nextRef() {
    819                         return nextRef(false);
    820                 }
    821                
    822                 public Snode next() {
    823                         return nodes.get(nextRef());
    824                 }
    825         }
    826        
    827         double calcArea(Geom geom, int comp) {
    828                 Snode node;
    829                 double lat, lon, llon, llat;
    830                 lat = lon = llon = llat = 0;
    831                 double sigma = 0;
    832                 GeomIterator git = new GeomIterator(geom);
    833                 for (int i = 0; i <= comp; i++) {
    834                         if (git.hasComp()) {
    835                                 git.nextComp();
    836                                 while (git.hasEdge()) {
    837                                         git.nextEdge();
    838                                         while (git.hasNode()) {
    839                                                 node = git.next();
    840                                                 if (node == null)
    841                                                         continue;
    842                                                 llon = lon;
    843                                                 llat = lat;
    844                                                 lat = node.lat;
    845                                                 lon = node.lon;
    846                                                 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
    847                                         }
    848                                 }
    849                                 if (i != comp)
    850                                         sigma = lat = lon = llon = llat = 0;
    851                         }
    852                 }
    853                 return sigma / 2.0;
    854         }
    855 
    856         double calcLength(Geom geom) {
    857                 Snode node;
    858                 double lat, lon, llon, llat;
    859                 lat = lon = llon = llat = 0;
    860                 double sigma = 0;
    861                 boolean first = true;
    862                 GeomIterator git = new GeomIterator(geom);
    863                 while (git.hasComp()) {
    864                         git.nextComp();
    865                         while (git.hasEdge()) {
    866                                 git.nextEdge();
    867                                 while (git.hasNode()) {
    868                                         node = git.next();
    869                                         if (first) {
    870                                                 first = false;
    871                                                 lat = node.lat;
    872                                                 lon = node.lon;
    873                                         } else if (node != null) {
    874                                                 llat = lat;
    875                                                 llon = lon;
    876                                                 lat = node.lat;
    877                                                 lon = node.lon;
    878                                                 sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
    879                                         }
    880                                 }
    881                         }
    882                 }
    883                 return sigma * 3444;
    884         }
    885 
    886         Snode calcCentroid(Feature feature) {
    887                 double lat, lon, slat, slon, llat, llon;
    888                 llat = llon = lat = lon = slat = slon = 0;
    889                 double sarc = 0;
    890                 boolean first = true;
    891                 switch (feature.geom.prim) {
    892                 case POINT:
    893                         return nodes.get(feature.geom.elems.get(0).id);
    894                 case LINE:
    895                         GeomIterator git = new GeomIterator(feature.geom);
    896                         while (git.hasComp()) {
    897                                 git.nextComp();
    898                                 while (git.hasEdge()) {
    899                                         git.nextEdge();
    900                                         while (git.hasNode()) {
    901                                                 Snode node = git.next();
    902                                                 if (node == null) continue;
    903                                                 lat = node.lat;
    904                                                 lon = node.lon;
    905                                                 if (first) {
    906                                                         first = false;
    907                                                 } else {
    908                                                         sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    909                                                 }
    910                                                 llat = lat;
    911                                                 llon = lon;
    912                                         }
    913                                 }
    914                         }
    915                         double harc = sarc / 2;
    916                         sarc = 0;
    917                         first = true;
    918                         git = new GeomIterator(feature.geom);
    919                         while (git.hasComp()) {
    920                                 git.nextComp();
    921                                 while (git.hasEdge()) {
    922                                         git.nextEdge();
    923                                         while (git.hasNode()) {
    924                                                 Snode node = git.next();
    925                                                 if (node == null) continue;
    926                                                 lat = node.lat;
    927                                                 lon = node.lon;
    928                                                 if (first) {
    929                                                         first = false;
    930                                                 } else {
    931                                                         sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    932                                                         if (sarc > harc)
    933                                                                 break;
    934                                                 }
    935                                                 harc -= sarc;
    936                                                 llat = lat;
    937                                                 llon = lon;
    938                                         }
    939                                 }
    940                         }
    941                         return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
    942                 case AREA:
    943                         git = new GeomIterator(feature.geom);
    944                         while (git.hasComp()) {
    945                                 git.nextComp();
    946                                 while (git.hasEdge()) {
    947                                         git.nextEdge();
    948                                         while (git.hasNode()) {
    949                                                 Snode node = git.next();
    950                                                 lat = node.lat;
    951                                                 lon = node.lon;
    952                                                 if (first) {
    953                                                         first = false;
    954                                                 } else {
    955                                                         double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    956                                                         slat += ((lat + llat) / 2 * arc);
    957                                                         slon += ((lon + llon) / 2 * arc);
    958                                                         sarc += arc;
    959                                                 }
    960                                                 llon = lon;
    961                                                 llat = lat;
    962                                         }
    963                                 }
    964                         }
    965                         return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
    966                 default:
    967                 }
    968                 return null;
    969         }
     23    // CHECKSTYLE.OFF: LineLength
     24
     25    public class MapBounds {
     26        public double minlat;
     27        public double minlon;
     28        public double maxlat;
     29        public double maxlon;
     30        public MapBounds() {
     31            minlat = Math.toRadians(90);
     32            minlon = Math.toRadians(180);
     33            maxlat = Math.toRadians(-90);
     34            maxlon = Math.toRadians(-180);
     35        }
     36    }
     37
     38    public enum Nflag {
     39        ANON,    // Edge inner nodes
     40        ISOL,    // Node not part of Edge
     41        CONN,    // Edge first and last nodes
     42        TRNK, // Edge truncated polygon nodes
     43        DPTH    // Sounding nodes
     44    }
     45
     46    public class Snode {    // All coordinates in map
     47        public double lat;    // Latitude in radians
     48        public double lon;    // Longitude in radians
     49        public Nflag flg;        // Role of node
     50        public double val;    // Optional value
     51
     52        public Snode() {
     53            flg = Nflag.ANON;
     54            lat = 0;
     55            lon = 0;
     56            val = 0;
     57        }
     58
     59        public Snode(double ilat, double ilon) {
     60            flg = Nflag.ANON;
     61            lat = ilat;
     62            lon = ilon;
     63            val = 0;
     64        }
     65
     66        public Snode(double ilat, double ilon, Nflag iflg) {
     67            lat = ilat;
     68            lon = ilon;
     69            flg = iflg;
     70            val = 0;
     71        }
     72
     73        public Snode(double ilat, double ilon, double ival) {
     74            flg = Nflag.DPTH;
     75            lat = ilat;
     76            lon = ilon;
     77            val = ival;
     78        }
     79    }
     80
     81    public class Edge {        // A polyline segment
     82        public long first;    // First CONN node
     83        public long last;        // Last CONN node
     84        public ArrayList<Long> nodes; // Inner ANON nodes
     85
     86        public Edge() {
     87            first = 0;
     88            last = 0;
     89            nodes = new ArrayList<>();
     90        }
     91    }
     92
     93    public enum Rflag {
     94        UNKN, MASTER, SLAVE
     95    }
     96
     97    public class Reln {
     98        public long id;
     99        public Rflag reln;
     100        public Reln(long i, Rflag r) {
     101            id = i;
     102            reln = r;
     103        }
     104    }
     105
     106    public class RelTab extends ArrayList<Reln> {
     107        public RelTab() {
     108            super();
     109        }
     110    }
     111
     112    public class ObjTab extends HashMap<Integer, AttMap> {
     113        public ObjTab() {
     114            super();
     115        }
     116    }
     117
     118    public class ObjMap extends EnumMap<Obj, ObjTab> {
     119        public ObjMap() {
     120            super(Obj.class);
     121        }
     122    }
     123
     124    public class AttMap extends HashMap<Att, AttVal<?>> {
     125        public AttMap() {
     126            super();
     127        }
     128    }
     129
     130    public class NodeTab extends HashMap<Long, Snode> {
     131        public NodeTab() {
     132            super();
     133        }
     134    }
     135
     136    public class EdgeTab extends HashMap<Long, Edge> {
     137        public EdgeTab() {
     138            super();
     139        }
     140    }
     141
     142    public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
     143        public FtrMap() {
     144            super(Obj.class);
     145        }
     146    }
     147
     148    public class FtrTab extends HashMap<Long, Feature> {
     149        public FtrTab() {
     150            super();
     151        }
     152    }
     153
     154    public class Prim {                // Spatial element
     155        public long id;                    // Snode ID for POINTs, Edge ID for LINEs & AREAs)
     156        public boolean forward;    // Direction of vector used (LINEs & AREAs)
     157        public boolean outer;        // Exterior/Interior boundary (AREAs)
     158        public boolean trunc;        // Cell limit truncation
     159        public Prim() {
     160            id = 0; forward = true; outer = true; trunc = false;
     161        }
     162
     163        public Prim(long i) {
     164            id = i; forward = true; outer = true; trunc = false;
     165        }
     166
     167        public Prim(long i, boolean o) {
     168            id = i; forward = true; outer = o; trunc = false;
     169        }
     170
     171        public Prim(long i, boolean f, boolean o) {
     172            id = i; forward = f; outer = o; trunc = false;
     173        }
     174
     175        public Prim(long i, boolean f, boolean o, boolean t) {
     176            id = i; forward = f; outer = o; trunc = t;
     177        }
     178    }
     179
     180    public class Comp {            // Composite spatial element
     181        public long ref;            // ID of Comp
     182        public int size;            // Number of Prims in this Comp
     183        public Comp(long r, int s) {
     184            ref = r;
     185            size = s;
     186        }
     187    }
     188
     189    public enum Pflag {
     190        NOSP, POINT, LINE, AREA
     191    }
     192
     193    public class Geom {                            // Geometric structure of feature
     194        public Pflag prim;                        // Geometry type
     195        public ArrayList<Prim> elems;    // Ordered list of elements
     196        public int outers;                        // Number of outers
     197        public int inners;                        // Number of inners
     198        public ArrayList<Comp> comps;    // Ordered list of compounds
     199        public double area;                        // Area of feature
     200        public double length;                    // Length of feature
     201        public Snode centre;                    // Centre of feature
     202        public Geom(Pflag p) {
     203            prim = p;
     204            elems = new ArrayList<>();
     205            outers = inners = 0;
     206            comps = new ArrayList<>();
     207            area = 0;
     208            length = 0;
     209            centre = new Snode();
     210        }
     211    }
     212
     213    public class Feature {
     214        public long id;                // Ref for this feature
     215        public Rflag reln;        // Relationship status
     216        public Geom geom;            // Geometry data
     217        public Obj type;            // Feature type
     218        public AttMap atts;        // Feature attributes
     219        public RelTab rels;        // Related objects
     220        public ObjMap objs;        // Slave object attributes
     221
     222        Feature() {
     223            id = 0;
     224            reln = Rflag.UNKN;
     225            geom = new Geom(Pflag.NOSP);
     226            type = Obj.UNKOBJ;
     227            atts = new AttMap();
     228            rels = new RelTab();
     229            objs = new ObjMap();
     230        }
     231    }
     232
     233    public MapBounds bounds;
     234    public NodeTab nodes;
     235    public EdgeTab edges;
     236    public FtrMap features;
     237    public FtrTab index;
     238    public long xref;
     239
     240    private long cref;
     241    private Feature feature;
     242    private Edge edge;
     243    private ArrayList<KeyVal<?>> osm;
     244    private boolean sea;
     245
     246    public S57map(boolean s) {
     247        sea = s;
     248        nodes = new NodeTab();      // All nodes in map
     249        edges = new EdgeTab();      // All edges in map
     250        feature = new Feature();    // Current feature being built
     251        features = new FtrMap();    // All features in map, grouped by type
     252        index = new FtrTab();       // Feature look-up table
     253        bounds = new MapBounds();
     254        cref = 0x0000ffffffff0000L; // Compound reference generator
     255        xref = 0x0fff000000000000L; // Extras reference generator
     256    }
     257
     258    // S57 map building methods
     259
     260    public void newNode(long id, double lat, double lon, Nflag flag) {
     261        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
     262        if (flag == Nflag.ANON) {
     263            edge.nodes.add(id);
     264        }
     265    }
     266
     267    public void newNode(long id, double lat, double lon, double depth) {
     268        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
     269    }
     270
     271    public void newFeature(long id, Pflag p, long objl) {
     272        feature = new Feature();
     273        Obj obj = S57obj.decodeType(objl);
     274        feature.geom = new Geom(p);
     275        feature.type = obj;
     276        if (obj != Obj.UNKOBJ) {
     277            index.put(id, feature);
     278            feature.id = id;
     279        }
     280    }
     281
     282    public void refObj(long id, int rind) {
     283        Rflag r = Rflag.UNKN;
     284        switch (rind) {
     285        case 1:
     286            r = Rflag.MASTER;
     287            break;
     288        case 2:
     289            r = Rflag.SLAVE;
     290            break;
     291        case 3:
     292            r = Rflag.UNKN;
     293            break;
     294        }
     295        feature.rels.add(new Reln(id, r));
     296    }
     297
     298    public void endFeature() {
     299
     300    }
     301
     302    public void newAtt(long attl, String atvl) {
     303        Att att = S57att.decodeAttribute(attl);
     304        AttVal<?> val = S57val.decodeValue(atvl, att);
     305        feature.atts.put(att, val);
     306    }
     307
     308    public void newPrim(long id, long ornt, long usag) {
     309        feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
     310    }
     311
     312    public void addConn(long id, int topi) {
     313        if (topi == 1) {
     314            edge.first = id;
     315        } else {
     316            edge.last = id;
     317        }
     318    }
     319
     320    public void newEdge(long id) {
     321        edge = new Edge();
     322        edges.put(id, edge);
     323    }
     324
     325    public void endFile() {
     326        for (long id : index.keySet()) {
     327            Feature feature = index.get(id);
     328            sortGeom(feature);
     329            for (Reln reln : feature.rels) {
     330                Feature rel = index.get(reln.id);
     331                if (cmpGeoms(feature.geom, rel.geom)) {
     332                    switch (reln.reln) {
     333                    case SLAVE:
     334                        feature.reln = Rflag.MASTER;
     335                        break;
     336                    default:
     337                        feature.reln = Rflag.UNKN;
     338                        break;
     339                    }
     340                    rel.reln = reln.reln;
     341                } else {
     342                    reln.reln = Rflag.UNKN;
     343                }
     344            }
     345        }
     346        for (long id : index.keySet()) {
     347            Feature feature = index.get(id);
     348            if (feature.reln == Rflag.UNKN) {
     349                feature.reln = Rflag.MASTER;
     350            }
     351            if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
     352                if (features.get(feature.type) == null) {
     353                    features.put(feature.type, new ArrayList<Feature>());
     354                }
     355                features.get(feature.type).add(feature);
     356            }
     357        }
     358        for (long id : index.keySet()) {
     359            Feature feature = index.get(id);
     360            for (Reln reln : feature.rels) {
     361                Feature rel = index.get(reln.id);
     362                if (rel.reln == Rflag.SLAVE) {
     363                    if (feature.objs.get(rel.type) == null) {
     364                        feature.objs.put(rel.type, new ObjTab());
     365                    }
     366                    ObjTab tab = feature.objs.get(rel.type);
     367                    int ix = tab.size();
     368                    tab.put(ix, rel.atts);
     369                }
     370            }
     371        }
     372    }
     373
     374    // OSM map building methods
     375
     376    public void addNode(long id, double lat, double lon) {
     377        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
     378        feature = new Feature();
     379        feature.id = id;
     380        feature.reln = Rflag.UNKN;
     381        feature.geom.prim = Pflag.POINT;
     382        feature.geom.elems.add(new Prim(id));
     383        edge = null;
     384        osm = new ArrayList<>();
     385    }
     386
     387    public void addEdge(long id) {
     388        feature = new Feature();
     389        feature.id = id;
     390        feature.reln = Rflag.UNKN;
     391        feature.geom.prim = Pflag.LINE;
     392        feature.geom.elems.add(new Prim(id));
     393        edge = new Edge();
     394        osm = new ArrayList<>();
     395    }
     396
     397    public void addToEdge(long node) {
     398        if (edge.first == 0) {
     399            edge.first = node;
     400            nodes.get(node).flg = Nflag.CONN;
     401        } else {
     402            if (edge.last != 0) {
     403                edge.nodes.add(edge.last);
     404            }
     405            edge.last = node;
     406        }
     407    }
     408
     409    public void addArea(long id) {
     410        feature = new Feature();
     411        feature.id = id;
     412        feature.reln = Rflag.UNKN;
     413        feature.geom.prim = Pflag.AREA;
     414        edge = null;
     415        osm = new ArrayList<>();
     416    }
     417
     418    public void addToArea(long id, boolean outer) {
     419        feature.geom.elems.add(new Prim(id, outer));
     420    }
     421
     422    public void addTag(String key, String val) {
     423        feature.reln = Rflag.MASTER;
     424        String[] subkeys = key.split(":");
     425        if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
     426            Obj obj = S57obj.enumType(subkeys[1]);
     427            if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
     428                int idx = 0;
     429                Att att = Att.UNKATT;
     430                try {
     431                    idx = Integer.parseInt(subkeys[2]);
     432                    if (subkeys.length == 4) {
     433                        att = s57.S57att.enumAttribute(subkeys[3], obj);
     434                    }
     435                } catch (Exception e) {
     436                    att = S57att.enumAttribute(subkeys[2], obj);
     437                }
     438                ObjTab objs = feature.objs.get(obj);
     439                if (objs == null) {
     440                    objs = new ObjTab();
     441                    feature.objs.put(obj, objs);
     442                }
     443                AttMap atts = objs.get(idx);
     444                if (atts == null) {
     445                    atts = new AttMap();
     446                    objs.put(idx, atts);
     447                }
     448                AttVal<?> attval = S57val.convertValue(val, att);
     449                if (attval.val != null) {
     450                    if (att == Att.VALSOU) {
     451                        Snode node = nodes.get(feature.geom.elems.get(0).id);
     452                        node.val = (Double) attval.val;
     453                    }
     454                    atts.put(att, attval);
     455                }
     456            } else {
     457                if (subkeys[1].equals("type")) {
     458                    obj = S57obj.enumType(val);
     459                    feature.type = obj;
     460                    ObjTab objs = feature.objs.get(obj);
     461                    if (objs == null) {
     462                        objs = new ObjTab();
     463                        feature.objs.put(obj, objs);
     464                    }
     465                    AttMap atts = objs.get(0);
     466                    if (atts == null) {
     467                        atts = new AttMap();
     468                        objs.put(0, atts);
     469                    }
     470                    if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
     471                        Snode node = nodes.get(feature.geom.elems.get(0).id);
     472                        node.flg = Nflag.DPTH;
     473                    }
     474                } else {
     475                    if (obj != Obj.UNKOBJ) {
     476                        if (val.equals("yes")) {
     477                            ObjTab objs = feature.objs.get(obj);
     478                            if (objs == null) {
     479                                objs = new ObjTab();
     480                                feature.objs.put(obj, objs);
     481                            }
     482                        }
     483                    } else {
     484                        Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
     485                        if (att != Att.UNKATT) {
     486                            AttVal<?> attval = S57val.convertValue(val, att);
     487                            if (attval.val != null)
     488                                feature.atts.put(att, attval);
     489                        }
     490                    }
     491                }
     492            }
     493        } else if (!sea) {
     494            S57osm.OSMtag(osm, key, val);
     495        }
     496    }
     497
     498    public void tagsDone(long id) {
     499        switch (feature.geom.prim) {
     500        case POINT:
     501            Snode node = nodes.get(id);
     502            if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
     503                node.flg = Nflag.ISOL;
     504            }
     505            break;
     506        case LINE:
     507            edges.put(id, edge);
     508            nodes.get(edge.first).flg = Nflag.CONN;
     509            nodes.get(edge.last).flg = Nflag.CONN;
     510            if (edge.first == edge.last) {
     511                feature.geom.prim = Pflag.AREA;
     512            }
     513            break;
     514        case AREA:
     515            break;
     516        default:
     517            break;
     518        }
     519        if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
     520            if (feature.type != Obj.UNKOBJ) {
     521                index.put(id, feature);
     522                if (features.get(feature.type) == null) {
     523                    features.put(feature.type, new ArrayList<Feature>());
     524                }
     525                features.get(feature.type).add(feature);
     526            }
     527            for (KeyVal<?> kvx : osm) {
     528                Feature base = new Feature();
     529                base.reln = Rflag.MASTER;
     530                base.geom = feature.geom;
     531                base.type = kvx.obj;
     532                ObjTab objs = new ObjTab();
     533                base.objs.put(kvx.obj, objs);
     534                AttMap atts = new AttMap();
     535                objs.put(0, atts);
     536                if (kvx.att != Att.UNKATT) {
     537                    atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
     538                }
     539                index.put(++xref, base);
     540                if (features.get(kvx.obj) == null) {
     541                    features.put(kvx.obj, new ArrayList<Feature>());
     542                }
     543                features.get(kvx.obj).add(base);
     544            }
     545            /*            if (!osm.isEmpty()) {
     546                if (feature.type == Obj.UNKOBJ) {
     547                    feature.type = osm.obj;
     548                    ObjTab objs = feature.objs.get(osm.obj);
     549                    if (objs == null) {
     550                        objs = new ObjTab();
     551                        feature.objs.put(osm.obj, objs);
     552                    }
     553                    AttMap atts = objs.get(0);
     554                    if (atts == null) {
     555                        atts = new AttMap();
     556                        objs.put(0, atts);
     557                    }
     558                    if (osm.att != Att.UNKATT) {
     559                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
     560                    }
     561                } else {
     562                    Feature base = new Feature();
     563                    base.reln = Rflag.MASTER;
     564                    base.geom = feature.geom;
     565                    base.type = osm.obj;
     566                    ObjTab objs = new ObjTab();
     567                    base.objs.put(osm.obj, objs);
     568                    AttMap atts = new AttMap();
     569                    objs.put(0, atts);
     570                    if (osm.att != Att.UNKATT) {
     571                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
     572                    }
     573                    index.put(++xref, base);
     574                    if (features.get(osm.obj) == null) {
     575                        features.put(osm.obj, new ArrayList<Feature>());
     576                    }
     577                    features.get(osm.obj).add(base);
     578                }
     579            }*/
     580        }
     581    }
     582
     583    public void mapDone() {
     584        if (!sea) {
     585            S57box.bBox(this);
     586        }
     587    }
     588
     589    // Utility methods
     590
     591    public boolean sortGeom(Feature feature) {
     592        try {
     593            Geom sort = new Geom(feature.geom.prim);
     594            long first = 0;
     595            long last = 0;
     596            Comp comp = null;
     597            boolean next = true;
     598            feature.geom.length = 0;
     599            feature.geom.area = 0;
     600            if (feature.geom.elems.isEmpty()) {
     601                return false;
     602            }
     603            if (feature.geom.prim == Pflag.POINT) {
     604                feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
     605                return true;
     606            }
     607            Geom outer = new Geom(feature.geom.prim);
     608            Geom inner = new Geom(feature.geom.prim);
     609            for (Prim prim : feature.geom.elems) {
     610                if (prim.outer) {
     611                    outer.elems.add(prim);
     612                } else {
     613                    inner.elems.add(prim);
     614                }
     615            }
     616            boolean outin = true;
     617            int sweep = outer.elems.size();
     618            if (sweep == 0) {
     619                return false;
     620            }
     621            int prev = sweep;
     622            int top = 0;
     623            while (!outer.elems.isEmpty()) {
     624                Prim prim = outer.elems.remove(0);
     625                Edge edge = edges.get(prim.id);
     626                if (edge == null) {
     627                    return false;
     628                }
     629                if (next == true) {
     630                    next = false;
     631                    first = edge.first;
     632                    last = edge.last;
     633                    prim.forward = true;
     634                    sort.elems.add(prim);
     635                    if (prim.outer) {
     636                        sort.outers++;
     637                    } else {
     638                        sort.inners++;
     639                    }
     640                    comp = new Comp(cref++, 1);
     641                    sort.comps.add(comp);
     642                } else {
     643                    if (edge.first == last) {
     644                        sort.elems.add(prim);
     645                        last = edge.last;
     646                        prim.forward = true;
     647                        comp.size++;
     648                    } else if (edge.last == first) {
     649                        sort.elems.add(top, prim);
     650                        first = edge.first;
     651                        prim.forward = true;
     652                        comp.size++;
     653                    } else if (edge.last == last) {
     654                        sort.elems.add(prim);
     655                        last = edge.first;
     656                        prim.forward = false;
     657                        comp.size++;
     658                    } else if (edge.first == first) {
     659                        sort.elems.add(top, prim);
     660                        first = edge.last;
     661                        prim.forward = false;
     662                        comp.size++;
     663                    } else {
     664                        outer.elems.add(prim);
     665                    }
     666                }
     667                if (--sweep == 0) {
     668                    sweep = outer.elems.size();
     669                    if ((sweep == 0) || (sweep == prev)) {
     670                        if ((sort.prim == Pflag.AREA) && (first != last)) {
     671                            return false;
     672                        }
     673                        if (outin) {
     674                            if (sweep != 0) {
     675                                return false;
     676                            }
     677                            outer = inner;
     678                            outin = false;
     679                            sweep = outer.elems.size();
     680                        }
     681                        next = true;
     682                        top = sort.elems.size();
     683                    }
     684                    prev = sweep;
     685                }
     686            }
     687            if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
     688                sort.prim = Pflag.AREA;
     689            }
     690            feature.geom = sort;
     691            if (feature.geom.prim == Pflag.AREA) {
     692                int ie = 0;
     693                int ic = 0;
     694                while (ie < feature.geom.elems.size()) {
     695                    double area = calcArea(feature.geom, ic);
     696                    if (ie == 0)
     697                        feature.geom.area = Math.abs(area) * 3444 * 3444;
     698                    if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
     699                        ArrayList<Prim> tmp = new ArrayList<>();
     700                        for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
     701                            Prim p = feature.geom.elems.remove(ie);
     702                            p.forward = !p.forward;
     703                            tmp.add(0, p);
     704                        }
     705                        feature.geom.elems.addAll(ie, tmp);
     706                    }
     707                    ie += feature.geom.comps.get(ic).size;
     708                    ic++;
     709                }
     710            }
     711            feature.geom.length = calcLength(feature.geom);
     712            feature.geom.centre = calcCentroid(feature);
     713            return true;
     714        } catch (Exception e) {
     715            return false;
     716        }
     717    }
     718
     719    public boolean cmpGeoms(Geom g1, Geom g2) {
     720        return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
     721    }
     722
     723    public class EdgeIterator {
     724        Edge edge;
     725        boolean forward;
     726        ListIterator<Long> it;
     727
     728        public EdgeIterator(Edge e, boolean dir) {
     729            edge = e;
     730            forward = dir;
     731            it = null;
     732        }
     733
     734        public boolean hasNext() {
     735            return (edge != null);
     736        }
     737
     738        public long nextRef() {
     739            long ref = 0;
     740            if (forward) {
     741                if (it == null) {
     742                    ref = edge.first;
     743                    it = edge.nodes.listIterator();
     744                } else {
     745                    if (it.hasNext()) {
     746                        ref = it.next();
     747                    } else {
     748                        ref = edge.last;
     749                        edge = null;
     750                    }
     751                }
     752            } else {
     753                if (it == null) {
     754                    ref = edge.last;
     755                    it = edge.nodes.listIterator(edge.nodes.size());
     756                } else {
     757                    if (it.hasPrevious()) {
     758                        ref = it.previous();
     759                    } else {
     760                        ref = edge.first;
     761                        edge = null;
     762                    }
     763                }
     764            }
     765            return ref;
     766        }
     767
     768        public Snode next() {
     769            return nodes.get(nextRef());
     770        }
     771    }
     772
     773    public class GeomIterator {
     774        Geom geom;
     775        Prim prim;
     776        EdgeIterator eit;
     777        ListIterator<S57map.Prim> ite;
     778        ListIterator<Comp> itc;
     779        Comp comp;
     780        int ec;
     781        long lastref;
     782
     783        public GeomIterator(Geom g) {
     784            geom = g;
     785            lastref = 0;
     786            ite = geom.elems.listIterator();
     787            itc = geom.comps.listIterator();
     788        }
     789
     790        public boolean hasComp() {
     791            return (itc.hasNext());
     792        }
     793
     794        public long nextComp() {
     795            comp = itc.next();
     796            ec = comp.size;
     797            lastref = 0;
     798            return comp.ref;
     799        }
     800
     801        public boolean hasEdge() {
     802            return (ec > 0) && ite.hasNext();
     803        }
     804
     805        public long nextEdge() {
     806            prim = ite.next();
     807            eit = new EdgeIterator(edges.get(prim.id), prim.forward);
     808            ec--;
     809            return prim.id;
     810        }
     811
     812        public boolean hasNode() {
     813            return (eit.hasNext());
     814        }
     815
     816        public long nextRef(boolean all) {
     817            long ref = eit.nextRef();
     818            if (!all && (ref == lastref)) {
     819                ref = eit.nextRef();
     820            }
     821            lastref = ref;
     822            return ref;
     823        }
     824
     825        public long nextRef() {
     826            return nextRef(false);
     827        }
     828
     829        public Snode next() {
     830            return nodes.get(nextRef());
     831        }
     832    }
     833
     834    double calcArea(Geom geom, int comp) {
     835        Snode node;
     836        double lat, lon, llon, llat;
     837        lat = lon = llon = llat = 0;
     838        double sigma = 0;
     839        GeomIterator git = new GeomIterator(geom);
     840        for (int i = 0; i <= comp; i++) {
     841            if (git.hasComp()) {
     842                git.nextComp();
     843                while (git.hasEdge()) {
     844                    git.nextEdge();
     845                    while (git.hasNode()) {
     846                        node = git.next();
     847                        if (node == null)
     848                            continue;
     849                        llon = lon;
     850                        llat = lat;
     851                        lat = node.lat;
     852                        lon = node.lon;
     853                        sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
     854                    }
     855                }
     856                if (i != comp)
     857                    sigma = lat = lon = llon = llat = 0;
     858            }
     859        }
     860        return sigma / 2.0;
     861    }
     862
     863    double calcLength(Geom geom) {
     864        Snode node;
     865        double lat, lon, llon, llat;
     866        lat = lon = llon = llat = 0;
     867        double sigma = 0;
     868        boolean first = true;
     869        GeomIterator git = new GeomIterator(geom);
     870        while (git.hasComp()) {
     871            git.nextComp();
     872            while (git.hasEdge()) {
     873                git.nextEdge();
     874                while (git.hasNode()) {
     875                    node = git.next();
     876                    if (first) {
     877                        first = false;
     878                        lat = node.lat;
     879                        lon = node.lon;
     880                    } else if (node != null) {
     881                        llat = lat;
     882                        llon = lon;
     883                        lat = node.lat;
     884                        lon = node.lon;
     885                        sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
     886                    }
     887                }
     888            }
     889        }
     890        return sigma * 3444;
     891    }
     892
     893    Snode calcCentroid(Feature feature) {
     894        double lat, lon, slat, slon, llat, llon;
     895        llat = llon = lat = lon = slat = slon = 0;
     896        double sarc = 0;
     897        boolean first = true;
     898        switch (feature.geom.prim) {
     899        case POINT:
     900            return nodes.get(feature.geom.elems.get(0).id);
     901        case LINE:
     902            GeomIterator git = new GeomIterator(feature.geom);
     903            while (git.hasComp()) {
     904                git.nextComp();
     905                while (git.hasEdge()) {
     906                    git.nextEdge();
     907                    while (git.hasNode()) {
     908                        Snode node = git.next();
     909                        if (node == null) continue;
     910                        lat = node.lat;
     911                        lon = node.lon;
     912                        if (first) {
     913                            first = false;
     914                        } else {
     915                            sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     916                        }
     917                        llat = lat;
     918                        llon = lon;
     919                    }
     920                }
     921            }
     922            double harc = sarc / 2;
     923            sarc = 0;
     924            first = true;
     925            git = new GeomIterator(feature.geom);
     926            while (git.hasComp()) {
     927                git.nextComp();
     928                while (git.hasEdge()) {
     929                    git.nextEdge();
     930                    while (git.hasNode()) {
     931                        Snode node = git.next();
     932                        if (node == null) continue;
     933                        lat = node.lat;
     934                        lon = node.lon;
     935                        if (first) {
     936                            first = false;
     937                        } else {
     938                            sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     939                            if (sarc > harc)
     940                                break;
     941                        }
     942                        harc -= sarc;
     943                        llat = lat;
     944                        llon = lon;
     945                    }
     946                }
     947            }
     948            return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
     949        case AREA:
     950            git = new GeomIterator(feature.geom);
     951            while (git.hasComp()) {
     952                git.nextComp();
     953                while (git.hasEdge()) {
     954                    git.nextEdge();
     955                    while (git.hasNode()) {
     956                        Snode node = git.next();
     957                        lat = node.lat;
     958                        lon = node.lon;
     959                        if (first) {
     960                            first = false;
     961                        } else {
     962                            double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     963                            slat += ((lat + llat) / 2 * arc);
     964                            slon += ((lon + llon) / 2 * arc);
     965                            sarc += arc;
     966                        }
     967                        llon = lon;
     968                        llat = lat;
     969                    }
     970                }
     971            }
     972            return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
     973        default:
     974        }
     975        return null;
     976    }
    970977
    971978}
  • applications/editors/josm/plugins/seachart/src/s57/S57obj.java

    r31846 r32394  
    1010package s57;
    1111
    12 import java.util.*;
     12import java.util.EnumMap;
     13import java.util.HashMap;
     14import java.util.Map;
    1315
    1416public class S57obj { // S57 Object lookup tables & methods
    15        
    16         public enum Obj {
    17                 UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
    18                 BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
    19                 COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
    20                 DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
    21                 HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
    22                 MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
    23                 PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
    24                 RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
    25                 SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
    26                 TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
    27                 WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
    28                 LG_SDM, LG_VSP, LITMIN, LITMAJ
    29         }
     17    // CHECKSTYLE.OFF: LineLength
    3018
    31         private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
    32         static {
    33                 ObjS57.put(Obj.UNKOBJ,0);
    34                 ObjS57.put(Obj.AIRARE,2); ObjS57.put(Obj.ACHBRT,3); ObjS57.put(Obj.ACHARE,4); ObjS57.put(Obj.BCNCAR,5); ObjS57.put(Obj.BCNISD,6);
    35                 ObjS57.put(Obj.BCNLAT,7); ObjS57.put(Obj.BCNSAW,8); ObjS57.put(Obj.BCNSPP,9); ObjS57.put(Obj.BERTHS,10); ObjS57.put(Obj.BRIDGE,11);
    36                 ObjS57.put(Obj.BUISGL,12); ObjS57.put(Obj.BUAARE,13); ObjS57.put(Obj.BOYCAR,14); ObjS57.put(Obj.BOYINB,15); ObjS57.put(Obj.BOYISD,16);
    37                 ObjS57.put(Obj.BOYLAT,17); ObjS57.put(Obj.BOYSAW,18); ObjS57.put(Obj.BOYSPP,19); ObjS57.put(Obj.CBLARE,20); ObjS57.put(Obj.CBLOHD,21);
    38                 ObjS57.put(Obj.CBLSUB,22); ObjS57.put(Obj.CANALS,23); ObjS57.put(Obj.CTSARE,25); ObjS57.put(Obj.CAUSWY,26); ObjS57.put(Obj.CTNARE,27);
    39                 ObjS57.put(Obj.CHKPNT,28); ObjS57.put(Obj.CGUSTA,29); ObjS57.put(Obj.COALNE,30); ObjS57.put(Obj.CONZNE,31); ObjS57.put(Obj.COSARE,32);
    40                 ObjS57.put(Obj.CTRPNT,33); ObjS57.put(Obj.CONVYR,34); ObjS57.put(Obj.CRANES,35); ObjS57.put(Obj.CURENT,36); ObjS57.put(Obj.CUSZNE,37);
    41                 ObjS57.put(Obj.DAMCON,38); ObjS57.put(Obj.DAYMAR,39); ObjS57.put(Obj.DWRTCL,40); ObjS57.put(Obj.DWRTPT,41); ObjS57.put(Obj.DEPARE,42);
    42                 ObjS57.put(Obj.DEPCNT,43); ObjS57.put(Obj.DISMAR,44); ObjS57.put(Obj.DOCARE,45); ObjS57.put(Obj.DRGARE,46); ObjS57.put(Obj.DRYDOC,47);
    43                 ObjS57.put(Obj.DMPGRD,48); ObjS57.put(Obj.DYKCON,49); ObjS57.put(Obj.EXEZNE,50); ObjS57.put(Obj.FAIRWY,51); ObjS57.put(Obj.FNCLNE,52);
    44                 ObjS57.put(Obj.FERYRT,53); ObjS57.put(Obj.FSHZNE,54); ObjS57.put(Obj.FSHFAC,55); ObjS57.put(Obj.FSHGRD,56); ObjS57.put(Obj.FLODOC,57);
    45                 ObjS57.put(Obj.FOGSIG,58); ObjS57.put(Obj.FORSTC,59); ObjS57.put(Obj.FRPARE,60); ObjS57.put(Obj.GATCON,61); ObjS57.put(Obj.GRIDRN,62);
    46                 ObjS57.put(Obj.HRBARE,63); ObjS57.put(Obj.HRBFAC,64); ObjS57.put(Obj.HULKES,65); ObjS57.put(Obj.ICEARE,66); ObjS57.put(Obj.ICNARE,67);
    47                 ObjS57.put(Obj.ISTZNE,68); ObjS57.put(Obj.LAKARE,69); ObjS57.put(Obj.LNDARE,71); ObjS57.put(Obj.LNDELV,72); ObjS57.put(Obj.LNDRGN,73);
    48                 ObjS57.put(Obj.LNDMRK,74); ObjS57.put(Obj.LIGHTS,75); ObjS57.put(Obj.LITFLT,76); ObjS57.put(Obj.LITVES,77); ObjS57.put(Obj.LOCMAG,78);
    49                 ObjS57.put(Obj.LOKBSN,79); ObjS57.put(Obj.LOGPON,80); ObjS57.put(Obj.MAGVAR,81); ObjS57.put(Obj.MARCUL,82); ObjS57.put(Obj.MIPARE,83);
    50                 ObjS57.put(Obj.MORFAC,84); ObjS57.put(Obj.NAVLNE,85); ObjS57.put(Obj.OBSTRN,86); ObjS57.put(Obj.OFSPLF,87); ObjS57.put(Obj.OSPARE,88);
    51                 ObjS57.put(Obj.OILBAR,89); ObjS57.put(Obj.PILPNT,90); ObjS57.put(Obj.PILBOP,91); ObjS57.put(Obj.PIPARE,92); ObjS57.put(Obj.PIPOHD,93);
    52                 ObjS57.put(Obj.PIPSOL,94); ObjS57.put(Obj.PONTON,95); ObjS57.put(Obj.PRCARE,96); ObjS57.put(Obj.PRDARE,97); ObjS57.put(Obj.PYLONS,98);
    53                 ObjS57.put(Obj.RADLNE,99); ObjS57.put(Obj.RADRNG,100); ObjS57.put(Obj.RADRFL,101); ObjS57.put(Obj.RADSTA,102); ObjS57.put(Obj.RTPBCN,103);
    54                 ObjS57.put(Obj.RDOCAL,104); ObjS57.put(Obj.RDOSTA,105); ObjS57.put(Obj.RAILWY,106);     ObjS57.put(Obj.RAPIDS,107);     ObjS57.put(Obj.RCRTCL,108);
    55                 ObjS57.put(Obj.RECTRC,109); ObjS57.put(Obj.RCTLPT,110); ObjS57.put(Obj.RSCSTA,111);     ObjS57.put(Obj.RESARE,112);     ObjS57.put(Obj.RETRFL,113);
    56                 ObjS57.put(Obj.RIVERS,114); ObjS57.put(Obj.ROADWY,116); ObjS57.put(Obj.RUNWAY,117);     ObjS57.put(Obj.SNDWAV,118);     ObjS57.put(Obj.SEAARE,119);
    57                 ObjS57.put(Obj.SPLARE,120); ObjS57.put(Obj.SBDARE,121); ObjS57.put(Obj.SLCONS,122);     ObjS57.put(Obj.SISTAT,123);     ObjS57.put(Obj.SISTAW,124);
    58                 ObjS57.put(Obj.SILTNK,125); ObjS57.put(Obj.SLOTOP,126); ObjS57.put(Obj.SLOGRD,127);     ObjS57.put(Obj.SMCFAC,128);     ObjS57.put(Obj.SOUNDG,129);
    59                 ObjS57.put(Obj.SPRING,130); ObjS57.put(Obj.STSLNE,132); ObjS57.put(Obj.SUBTLN,133);     ObjS57.put(Obj.SWPARE,134); ObjS57.put(Obj.TESARE,135);
    60                 ObjS57.put(Obj.TS_PRH,136);     ObjS57.put(Obj.TS_PNH,137); ObjS57.put(Obj.TS_PAD,138); ObjS57.put(Obj.TS_TIS,139); ObjS57.put(Obj.T_HMON,140);
    61                 ObjS57.put(Obj.T_NHMN,141);     ObjS57.put(Obj.T_TIMS,142);     ObjS57.put(Obj.TIDEWY,143);     ObjS57.put(Obj.TOPMAR,144); ObjS57.put(Obj.TSELNE,145);
    62                 ObjS57.put(Obj.TSSBND,146);     ObjS57.put(Obj.TSSCRS,147);     ObjS57.put(Obj.TSSLPT,148);     ObjS57.put(Obj.TSSRON,149); ObjS57.put(Obj.TSEZNE,150);
    63                 ObjS57.put(Obj.TUNNEL,151);     ObjS57.put(Obj.TWRTPT,152);     ObjS57.put(Obj.UWTROC,153);     ObjS57.put(Obj.UNSARE,154); ObjS57.put(Obj.VEGATN,155);
    64                 ObjS57.put(Obj.WATTUR,156);     ObjS57.put(Obj.WATFAL,157);     ObjS57.put(Obj.WEDKLP,158);     ObjS57.put(Obj.WRECKS,159); ObjS57.put(Obj.TS_FEB,160);
    65                 ObjS57.put(Obj.MPAARE,199); ObjS57.put(Obj.M_COVR,302); ObjS57.put(Obj.M_NSYS,306); ObjS57.put(Obj.LITMAJ,74); ObjS57.put(Obj.LITMIN,90);
    66         }
     19    public enum Obj {
     20        UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
     21        BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
     22        COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
     23        DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
     24        HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
     25        MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
     26        PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
     27        RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
     28        SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
     29        TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
     30        WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
     31        LG_SDM, LG_VSP, LITMIN, LITMAJ
     32    }
    6733
    68         private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
    69         static {
    70                 ObjIENC.put(Obj.UNKOBJ, 0);
    71                 ObjIENC.put(Obj.ACHBRT, 17000); ObjIENC.put(Obj.ACHARE, 17001); ObjIENC.put(Obj.DEPARE, 17003); ObjIENC.put(Obj.DISMAR, 17004); ObjIENC.put(Obj.RESARE, 17005);
    72                 ObjIENC.put(Obj.SISTAT, 17007); ObjIENC.put(Obj.SISTAW, 17008); ObjIENC.put(Obj.TOPMAR, 17009); ObjIENC.put(Obj.BERTHS, 17010); ObjIENC.put(Obj.BRIDGE, 17011);
    73                 ObjIENC.put(Obj.CBLOHD, 17012); ObjIENC.put(Obj.FERYRT, 17013); ObjIENC.put(Obj.HRBARE, 17014); ObjIENC.put(Obj.HRBFAC, 17015); ObjIENC.put(Obj.LOKBSN, 17016);
    74                 ObjIENC.put(Obj.RDOCAL, 17017); ObjIENC.put(Obj.CURENT, 17019); ObjIENC.put(Obj.HULKES, 17020); ObjIENC.put(Obj.PONTON, 17021); ObjIENC.put(Obj.PIPOHD, 17024);
    75                 ObjIENC.put(Obj.FLODOC, 17025); ObjIENC.put(Obj.CHKPNT, 17027); ObjIENC.put(Obj.BCNLAT, 17028); ObjIENC.put(Obj.BOYLAT, 17029); ObjIENC.put(Obj.CRANES, 17030);
    76                 ObjIENC.put(Obj.GATCON, 17031); ObjIENC.put(Obj.SLCONS, 17032); ObjIENC.put(Obj.UWTROC, 17033); ObjIENC.put(Obj.CONVYR, 17034); ObjIENC.put(Obj.NOTMRK, 17050);
    77                 ObjIENC.put(Obj.WTWAXS, 17051); ObjIENC.put(Obj.WTWPRF, 17052); ObjIENC.put(Obj.BUNSTA, 17054); ObjIENC.put(Obj.COMARE, 17055); ObjIENC.put(Obj.HRBBSN, 17056);
    78                 ObjIENC.put(Obj.LKBSPT, 17058); ObjIENC.put(Obj.PRTARE, 17059); ObjIENC.put(Obj.REFDMP, 17062); ObjIENC.put(Obj.TERMNL, 17064); ObjIENC.put(Obj.TRNBSN, 17065);
    79                 ObjIENC.put(Obj.WTWARE, 17066); ObjIENC.put(Obj.WTWGAG, 17067); ObjIENC.put(Obj.TISDGE, 17068); ObjIENC.put(Obj.VEHTRF, 17069); ObjIENC.put(Obj.EXCNST, 17070);
    80                 ObjIENC.put(Obj.LG_SDM, 18001); ObjIENC.put(Obj.LG_VSP, 18002);
    81         }
     34    private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
     35    static {
     36        ObjS57.put(Obj.UNKOBJ, 0);
     37        ObjS57.put(Obj.AIRARE, 2); ObjS57.put(Obj.ACHBRT, 3); ObjS57.put(Obj.ACHARE, 4); ObjS57.put(Obj.BCNCAR, 5); ObjS57.put(Obj.BCNISD, 6);
     38        ObjS57.put(Obj.BCNLAT, 7); ObjS57.put(Obj.BCNSAW, 8); ObjS57.put(Obj.BCNSPP, 9); ObjS57.put(Obj.BERTHS, 10); ObjS57.put(Obj.BRIDGE, 11);
     39        ObjS57.put(Obj.BUISGL, 12); ObjS57.put(Obj.BUAARE, 13); ObjS57.put(Obj.BOYCAR, 14); ObjS57.put(Obj.BOYINB, 15); ObjS57.put(Obj.BOYISD, 16);
     40        ObjS57.put(Obj.BOYLAT, 17); ObjS57.put(Obj.BOYSAW, 18); ObjS57.put(Obj.BOYSPP, 19); ObjS57.put(Obj.CBLARE, 20); ObjS57.put(Obj.CBLOHD, 21);
     41        ObjS57.put(Obj.CBLSUB, 22); ObjS57.put(Obj.CANALS, 23); ObjS57.put(Obj.CTSARE, 25); ObjS57.put(Obj.CAUSWY, 26); ObjS57.put(Obj.CTNARE, 27);
     42        ObjS57.put(Obj.CHKPNT, 28); ObjS57.put(Obj.CGUSTA, 29); ObjS57.put(Obj.COALNE, 30); ObjS57.put(Obj.CONZNE, 31); ObjS57.put(Obj.COSARE, 32);
     43        ObjS57.put(Obj.CTRPNT, 33); ObjS57.put(Obj.CONVYR, 34); ObjS57.put(Obj.CRANES, 35); ObjS57.put(Obj.CURENT, 36); ObjS57.put(Obj.CUSZNE, 37);
     44        ObjS57.put(Obj.DAMCON, 38); ObjS57.put(Obj.DAYMAR, 39); ObjS57.put(Obj.DWRTCL, 40); ObjS57.put(Obj.DWRTPT, 41); ObjS57.put(Obj.DEPARE, 42);
     45        ObjS57.put(Obj.DEPCNT, 43); ObjS57.put(Obj.DISMAR, 44); ObjS57.put(Obj.DOCARE, 45); ObjS57.put(Obj.DRGARE, 46); ObjS57.put(Obj.DRYDOC, 47);
     46        ObjS57.put(Obj.DMPGRD, 48); ObjS57.put(Obj.DYKCON, 49); ObjS57.put(Obj.EXEZNE, 50); ObjS57.put(Obj.FAIRWY, 51); ObjS57.put(Obj.FNCLNE, 52);
     47        ObjS57.put(Obj.FERYRT, 53); ObjS57.put(Obj.FSHZNE, 54); ObjS57.put(Obj.FSHFAC, 55); ObjS57.put(Obj.FSHGRD, 56); ObjS57.put(Obj.FLODOC, 57);
     48        ObjS57.put(Obj.FOGSIG, 58); ObjS57.put(Obj.FORSTC, 59); ObjS57.put(Obj.FRPARE, 60); ObjS57.put(Obj.GATCON, 61); ObjS57.put(Obj.GRIDRN, 62);
     49        ObjS57.put(Obj.HRBARE, 63); ObjS57.put(Obj.HRBFAC, 64); ObjS57.put(Obj.HULKES, 65); ObjS57.put(Obj.ICEARE, 66); ObjS57.put(Obj.ICNARE, 67);
     50        ObjS57.put(Obj.ISTZNE, 68); ObjS57.put(Obj.LAKARE, 69); ObjS57.put(Obj.LNDARE, 71); ObjS57.put(Obj.LNDELV, 72); ObjS57.put(Obj.LNDRGN, 73);
     51        ObjS57.put(Obj.LNDMRK, 74); ObjS57.put(Obj.LIGHTS, 75); ObjS57.put(Obj.LITFLT, 76); ObjS57.put(Obj.LITVES, 77); ObjS57.put(Obj.LOCMAG, 78);
     52        ObjS57.put(Obj.LOKBSN, 79); ObjS57.put(Obj.LOGPON, 80); ObjS57.put(Obj.MAGVAR, 81); ObjS57.put(Obj.MARCUL, 82); ObjS57.put(Obj.MIPARE, 83);
     53        ObjS57.put(Obj.MORFAC, 84); ObjS57.put(Obj.NAVLNE, 85); ObjS57.put(Obj.OBSTRN, 86); ObjS57.put(Obj.OFSPLF, 87); ObjS57.put(Obj.OSPARE, 88);
     54        ObjS57.put(Obj.OILBAR, 89); ObjS57.put(Obj.PILPNT, 90); ObjS57.put(Obj.PILBOP, 91); ObjS57.put(Obj.PIPARE, 92); ObjS57.put(Obj.PIPOHD, 93);
     55        ObjS57.put(Obj.PIPSOL, 94); ObjS57.put(Obj.PONTON, 95); ObjS57.put(Obj.PRCARE, 96); ObjS57.put(Obj.PRDARE, 97); ObjS57.put(Obj.PYLONS, 98);
     56        ObjS57.put(Obj.RADLNE, 99); ObjS57.put(Obj.RADRNG, 100); ObjS57.put(Obj.RADRFL, 101); ObjS57.put(Obj.RADSTA, 102); ObjS57.put(Obj.RTPBCN, 103);
     57        ObjS57.put(Obj.RDOCAL, 104); ObjS57.put(Obj.RDOSTA, 105); ObjS57.put(Obj.RAILWY, 106); ObjS57.put(Obj.RAPIDS, 107); ObjS57.put(Obj.RCRTCL, 108);
     58        ObjS57.put(Obj.RECTRC, 109); ObjS57.put(Obj.RCTLPT, 110); ObjS57.put(Obj.RSCSTA, 111); ObjS57.put(Obj.RESARE, 112); ObjS57.put(Obj.RETRFL, 113);
     59        ObjS57.put(Obj.RIVERS, 114); ObjS57.put(Obj.ROADWY, 116); ObjS57.put(Obj.RUNWAY, 117); ObjS57.put(Obj.SNDWAV, 118); ObjS57.put(Obj.SEAARE, 119);
     60        ObjS57.put(Obj.SPLARE, 120); ObjS57.put(Obj.SBDARE, 121); ObjS57.put(Obj.SLCONS, 122); ObjS57.put(Obj.SISTAT, 123); ObjS57.put(Obj.SISTAW, 124);
     61        ObjS57.put(Obj.SILTNK, 125); ObjS57.put(Obj.SLOTOP, 126); ObjS57.put(Obj.SLOGRD, 127); ObjS57.put(Obj.SMCFAC, 128); ObjS57.put(Obj.SOUNDG, 129);
     62        ObjS57.put(Obj.SPRING, 130); ObjS57.put(Obj.STSLNE, 132); ObjS57.put(Obj.SUBTLN, 133); ObjS57.put(Obj.SWPARE, 134); ObjS57.put(Obj.TESARE, 135);
     63        ObjS57.put(Obj.TS_PRH, 136); ObjS57.put(Obj.TS_PNH, 137); ObjS57.put(Obj.TS_PAD, 138); ObjS57.put(Obj.TS_TIS, 139); ObjS57.put(Obj.T_HMON, 140);
     64        ObjS57.put(Obj.T_NHMN, 141); ObjS57.put(Obj.T_TIMS, 142); ObjS57.put(Obj.TIDEWY, 143); ObjS57.put(Obj.TOPMAR, 144); ObjS57.put(Obj.TSELNE, 145);
     65        ObjS57.put(Obj.TSSBND, 146); ObjS57.put(Obj.TSSCRS, 147); ObjS57.put(Obj.TSSLPT, 148); ObjS57.put(Obj.TSSRON, 149); ObjS57.put(Obj.TSEZNE, 150);
     66        ObjS57.put(Obj.TUNNEL, 151); ObjS57.put(Obj.TWRTPT, 152); ObjS57.put(Obj.UWTROC, 153); ObjS57.put(Obj.UNSARE, 154); ObjS57.put(Obj.VEGATN, 155);
     67        ObjS57.put(Obj.WATTUR, 156); ObjS57.put(Obj.WATFAL, 157); ObjS57.put(Obj.WEDKLP, 158); ObjS57.put(Obj.WRECKS, 159); ObjS57.put(Obj.TS_FEB, 160);
     68        ObjS57.put(Obj.MPAARE, 199); ObjS57.put(Obj.M_COVR, 302); ObjS57.put(Obj.M_NSYS, 306); ObjS57.put(Obj.LITMAJ, 74); ObjS57.put(Obj.LITMIN, 90);
     69    }
    8270
    83         private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
    84         static {
    85                 ObjStr.put(Obj.UNKOBJ, "");     ObjStr.put(Obj.AIRARE, "airfield");     ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
    86                 ObjStr.put(Obj.BCNCAR, "beacon_cardinal");      ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
    87                 ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
    88                 ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
    89                 ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral"); ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
    90                 ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area");   ObjStr.put(Obj.CBLOHD, "cable_overhead");
    91                 ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area");       ObjStr.put(Obj.CAUSWY, "causeway");
    92                 ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station");     ObjStr.put(Obj.COALNE, "coastline");
    93                 ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
    94                 ObjStr.put(Obj.CONVYR, "conveyor");     ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
    95                 ObjStr.put(Obj.DAMCON, "dam"); ObjStr.put(Obj.DAYMAR, "daymark"); ObjStr.put(Obj.DWRTCL, "deep_water_route_centreline"); ObjStr.put(Obj.DWRTPT, "deep_water_route");
    96                 ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
    97                 ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock");     ObjStr.put(Obj.DMPGRD, "dumping_ground");       ObjStr.put(Obj.DYKCON, "dyke");
    98                 ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
    99                 ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility");     ObjStr.put(Obj.FSHGRD, "fishing_ground");       ObjStr.put(Obj.FLODOC, "floating_dock");
    100                 ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
    101                 ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area");     ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
    102                 ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
    103                 ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region");   ObjStr.put(Obj.LNDMRK, "landmark");
    104                 ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float"); ObjStr.put(Obj.LITVES, "light_vessel"); ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
    105                 ObjStr.put(Obj.LOKBSN, "lock_basin");   ObjStr.put(Obj.LOGPON, "log_pond");     ObjStr.put(Obj.MAGVAR, "magnetic_variation");   ObjStr.put(Obj.MARCUL, "marine_farm");
    106                 ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring");     ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
    107                 ObjStr.put(Obj.OFSPLF, "platform");     ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier");       ObjStr.put(Obj.PILPNT, "pile");
    108                 ObjStr.put(Obj.PILBOP, "pilot_boarding");       ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead");   ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
    109                 ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area");ObjStr.put(Obj.PYLONS, "pylon");
    110                 ObjStr.put(Obj.RADLNE, "radar_line");   ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector");       ObjStr.put(Obj.RADSTA, "radar_station");
    111                 ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station");       ObjStr.put(Obj.RAILWY, "railway");
    112                 ObjStr.put(Obj.RAPIDS, "rapids");       ObjStr.put(Obj.RCRTCL, "recommended_route_centreline"); ObjStr.put(Obj.RECTRC, "recommended_track");
    113                 ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane");     ObjStr.put(Obj.RSCSTA, "rescue_station");       ObjStr.put(Obj.RESARE, "restricted_area");
    114                 ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river");     ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
    115                 ObjStr.put(Obj.SNDWAV, "sand_waves");   ObjStr.put(Obj.SEAARE, "sea_area");     ObjStr.put(Obj.SPLARE, "seaplane_landing_area"); ObjStr.put(Obj.SBDARE, "seabed_area");
    116                 ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
    117                 ObjStr.put(Obj.SILTNK, "tank"); ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
    118                 ObjStr.put(Obj.SOUNDG, "sounding");     ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline");       ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
    119                 ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area");       ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
    120                 ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary");       ObjStr.put(Obj.TSSCRS, "separation_crossing");
    121                 ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout");     ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
    122                 ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area");     ObjStr.put(Obj.VEGATN, "vegetation");
    123                 ObjStr.put(Obj.WATTUR, "water_turbulence");     ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
    124                 ObjStr.put(Obj.TS_FEB, "tidal_stream"); ObjStr.put(Obj.NOTMRK, "notice");       ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
    125                 ObjStr.put(Obj.BUNSTA, "bunker_station");       ObjStr.put(Obj.COMARE, "communication_area");   ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
    126                 ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
    127                 ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
    128                 ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
    129                 ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
    130         }
    131        
    132         private static final HashMap<String, Obj> StrObj = new HashMap<>();
    133         static {
    134                 for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
    135                         if (!entry.getValue().isEmpty())
    136                                 StrObj.put(entry.getValue(), entry.getKey());
    137                 }
    138         }
    139        
    140         public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
    141                 for (Obj obj : ObjS57.keySet()) {
    142                         if (ObjS57.get(obj) == objl) return obj;
    143                 }
    144                 for (Obj obj : ObjIENC.keySet()) {
    145                         if (ObjIENC.get(obj) == objl) return obj;
    146                 }
    147                 return Obj.UNKOBJ;
    148         }
     71    private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
     72    static {
     73        ObjIENC.put(Obj.UNKOBJ, 0);
     74        ObjIENC.put(Obj.ACHBRT, 17000); ObjIENC.put(Obj.ACHARE, 17001); ObjIENC.put(Obj.DEPARE, 17003); ObjIENC.put(Obj.DISMAR, 17004); ObjIENC.put(Obj.RESARE, 17005);
     75        ObjIENC.put(Obj.SISTAT, 17007); ObjIENC.put(Obj.SISTAW, 17008); ObjIENC.put(Obj.TOPMAR, 17009); ObjIENC.put(Obj.BERTHS, 17010); ObjIENC.put(Obj.BRIDGE, 17011);
     76        ObjIENC.put(Obj.CBLOHD, 17012); ObjIENC.put(Obj.FERYRT, 17013); ObjIENC.put(Obj.HRBARE, 17014); ObjIENC.put(Obj.HRBFAC, 17015); ObjIENC.put(Obj.LOKBSN, 17016);
     77        ObjIENC.put(Obj.RDOCAL, 17017); ObjIENC.put(Obj.CURENT, 17019); ObjIENC.put(Obj.HULKES, 17020); ObjIENC.put(Obj.PONTON, 17021); ObjIENC.put(Obj.PIPOHD, 17024);
     78        ObjIENC.put(Obj.FLODOC, 17025); ObjIENC.put(Obj.CHKPNT, 17027); ObjIENC.put(Obj.BCNLAT, 17028); ObjIENC.put(Obj.BOYLAT, 17029); ObjIENC.put(Obj.CRANES, 17030);
     79        ObjIENC.put(Obj.GATCON, 17031); ObjIENC.put(Obj.SLCONS, 17032); ObjIENC.put(Obj.UWTROC, 17033); ObjIENC.put(Obj.CONVYR, 17034); ObjIENC.put(Obj.NOTMRK, 17050);
     80        ObjIENC.put(Obj.WTWAXS, 17051); ObjIENC.put(Obj.WTWPRF, 17052); ObjIENC.put(Obj.BUNSTA, 17054); ObjIENC.put(Obj.COMARE, 17055); ObjIENC.put(Obj.HRBBSN, 17056);
     81        ObjIENC.put(Obj.LKBSPT, 17058); ObjIENC.put(Obj.PRTARE, 17059); ObjIENC.put(Obj.REFDMP, 17062); ObjIENC.put(Obj.TERMNL, 17064); ObjIENC.put(Obj.TRNBSN, 17065);
     82        ObjIENC.put(Obj.WTWARE, 17066); ObjIENC.put(Obj.WTWGAG, 17067); ObjIENC.put(Obj.TISDGE, 17068); ObjIENC.put(Obj.VEHTRF, 17069); ObjIENC.put(Obj.EXCNST, 17070);
     83        ObjIENC.put(Obj.LG_SDM, 18001); ObjIENC.put(Obj.LG_VSP, 18002);
     84    }
    14985
    150         public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
    151                 if (ObjS57.containsKey(type))
    152                         return ObjS57.get(type);
    153                 else if (ObjIENC.containsKey(type))
    154                         return ObjIENC.get(type);
    155                 return 0;
    156         }
     86    private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
     87    static {
     88        ObjStr.put(Obj.UNKOBJ, ""); ObjStr.put(Obj.AIRARE, "airfield"); ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
     89        ObjStr.put(Obj.BCNCAR, "beacon_cardinal"); ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
     90        ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
     91        ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
     92        ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral"); ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
     93        ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area"); ObjStr.put(Obj.CBLOHD, "cable_overhead");
     94        ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area"); ObjStr.put(Obj.CAUSWY, "causeway");
     95        ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station"); ObjStr.put(Obj.COALNE, "coastline");
     96        ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
     97        ObjStr.put(Obj.CONVYR, "conveyor"); ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
     98        ObjStr.put(Obj.DAMCON, "dam"); ObjStr.put(Obj.DAYMAR, "daymark"); ObjStr.put(Obj.DWRTCL, "deep_water_route_centreline"); ObjStr.put(Obj.DWRTPT, "deep_water_route");
     99        ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
     100        ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock"); ObjStr.put(Obj.DMPGRD, "dumping_ground"); ObjStr.put(Obj.DYKCON, "dyke");
     101        ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
     102        ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility"); ObjStr.put(Obj.FSHGRD, "fishing_ground"); ObjStr.put(Obj.FLODOC, "floating_dock");
     103        ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
     104        ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area"); ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
     105        ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
     106        ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region"); ObjStr.put(Obj.LNDMRK, "landmark");
     107        ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float"); ObjStr.put(Obj.LITVES, "light_vessel"); ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
     108        ObjStr.put(Obj.LOKBSN, "lock_basin"); ObjStr.put(Obj.LOGPON, "log_pond"); ObjStr.put(Obj.MAGVAR, "magnetic_variation"); ObjStr.put(Obj.MARCUL, "marine_farm");
     109        ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring"); ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
     110        ObjStr.put(Obj.OFSPLF, "platform"); ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier"); ObjStr.put(Obj.PILPNT, "pile");
     111        ObjStr.put(Obj.PILBOP, "pilot_boarding"); ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead"); ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
     112        ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area"); ObjStr.put(Obj.PYLONS, "pylon");
     113        ObjStr.put(Obj.RADLNE, "radar_line"); ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector"); ObjStr.put(Obj.RADSTA, "radar_station");
     114        ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station"); ObjStr.put(Obj.RAILWY, "railway");
     115        ObjStr.put(Obj.RAPIDS, "rapids"); ObjStr.put(Obj.RCRTCL, "recommended_route_centreline"); ObjStr.put(Obj.RECTRC, "recommended_track");
     116        ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane"); ObjStr.put(Obj.RSCSTA, "rescue_station"); ObjStr.put(Obj.RESARE, "restricted_area");
     117        ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river"); ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
     118        ObjStr.put(Obj.SNDWAV, "sand_waves"); ObjStr.put(Obj.SEAARE, "sea_area"); ObjStr.put(Obj.SPLARE, "seaplane_landing_area"); ObjStr.put(Obj.SBDARE, "seabed_area");
     119        ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
     120        ObjStr.put(Obj.SILTNK, "tank"); ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
     121        ObjStr.put(Obj.SOUNDG, "sounding"); ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline"); ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
     122        ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area"); ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
     123        ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary"); ObjStr.put(Obj.TSSCRS, "separation_crossing");
     124        ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout"); ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
     125        ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area"); ObjStr.put(Obj.VEGATN, "vegetation");
     126        ObjStr.put(Obj.WATTUR, "water_turbulence"); ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
     127        ObjStr.put(Obj.TS_FEB, "tidal_stream"); ObjStr.put(Obj.NOTMRK, "notice"); ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
     128        ObjStr.put(Obj.BUNSTA, "bunker_station"); ObjStr.put(Obj.COMARE, "communication_area"); ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
     129        ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
     130        ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
     131        ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
     132        ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
     133    }
    157134
    158         public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
    159                 String str = ObjStr.get(type);
    160                         return str != null ? str : "";
    161         }
     135    private static final HashMap<String, Obj> StrObj = new HashMap<>();
     136    static {
     137        for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
     138            if (!entry.getValue().isEmpty())
     139                StrObj.put(entry.getValue(), entry.getKey());
     140        }
     141    }
    162142
    163         public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
    164                 if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
    165                         return StrObj.get(type);
    166                 else
    167                         return Obj.UNKOBJ;
    168         }
    169        
     143    public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
     144        for (Obj obj : ObjS57.keySet()) {
     145            if (ObjS57.get(obj) == objl) return obj;
     146        }
     147        for (Obj obj : ObjIENC.keySet()) {
     148            if (ObjIENC.get(obj) == objl) return obj;
     149        }
     150        return Obj.UNKOBJ;
     151    }
     152
     153    public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
     154        if (ObjS57.containsKey(type))
     155            return ObjS57.get(type);
     156        else if (ObjIENC.containsKey(type))
     157            return ObjIENC.get(type);
     158        return 0;
     159    }
     160
     161    public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
     162        String str = ObjStr.get(type);
     163        return str != null ? str : "";
     164    }
     165
     166    public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
     167        if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
     168            return StrObj.get(type);
     169        else
     170            return Obj.UNKOBJ;
     171    }
    170172}
  • applications/editors/josm/plugins/seachart/src/s57/S57osm.java

    r32393 r32394  
    1111
    1212import java.io.BufferedReader;
    13 import java.util.*;
    14 
    15 import s57.S57obj.*;
    16 import s57.S57att.*;
    17 import s57.S57val.*;
     13import java.util.ArrayList;
     14import java.util.HashMap;
     15
     16import s57.S57att.Att;
     17import s57.S57obj.Obj;
     18import s57.S57val.CatBUA;
     19import s57.S57val.CatROD;
     20import s57.S57val.Conv;
    1821
    1922public class S57osm { // OSM to S57 Object/Attribute and Object/Primitive conversions
    20        
    21         static class KeyVal<V> {
    22                 Obj obj;
    23                 Att att;
    24                 Conv conv;
    25                 V val;
    26                 KeyVal(Obj o, Att a, Conv c, V v) {
    27                         obj = o;
    28                         att = a;
    29                         conv = c;
    30                         val = v;
    31                 }
    32         }
    33        
    34         private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
    35         static {
    36                 OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
    37                 OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
    38                 OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
    39                 OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
    40                 OSMtags.put("wetland=tidalflat", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, (Double)0.0)); OSMtags.put("tidal=yes", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, (Double)0.0));
    41                 OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
    42                 OSMtags.put("highway=motorway", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MWAY)); OSMtags.put("highway=trunk", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR));
    43                 OSMtags.put("highway=primary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR)); OSMtags.put("highway=secondary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR));
    44                 OSMtags.put("highway=tertiary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR)); OSMtags.put("highway=residential", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null));
    45                 OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
    46                 OSMtags.put("man_made=breakwater", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=groyne", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
    47                 OSMtags.put("man_made=pier", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=jetty", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
    48                 OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
    49                 OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
    50                 OSMtags.put("place=city", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_CITY)); OSMtags.put("place=town", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_TOWN));
    51                 OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
    52                 }
    53        
    54         public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
    55                 KeyVal<?> kv = OSMtags.get(key + "=" + val);
    56                 if (kv != null) {
    57                         if (kv.conv == Conv.E) {
    58                                 ArrayList<Enum<?>> list = new ArrayList<>();
    59                                 list.add((Enum<?>)kv.val);
    60                                 osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
    61                         } else {
    62                                 osm.add(kv);
    63                         }
    64                 }
    65                 KeyVal<?> kvl = null;
    66                 KeyVal<?> kvd = null;
    67                 boolean rc = false;
    68                 boolean rcl = false;
    69                 for (KeyVal<?> kvx : osm) {
    70                         if (kvx.obj == Obj.LAKARE) {
    71                                 kvl = kvx;
    72                         } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
    73                                 rc = true;
    74                         }
    75                         if (kvx.obj == Obj.DEPARE) {
    76                                 kvd = kvx;
    77                         } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
    78                                 rcl = true;
    79                         }
    80                 }
    81                 if (rc && (kvl != null)) {
    82                         osm.remove(kvl);
    83                 }
    84                 if (rcl && (kvd != null)) {
    85                         osm.remove(kvd);
    86                 }
    87                 return;
    88         }
    89        
    90         public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
    91                 String k = "";
    92                 String v = "";
    93 
    94                 double lat = 0;
    95                 double lon = 0;
    96                 long id = 0;
    97 
    98                 boolean inOsm = false;
    99                 boolean inNode = false;
    100                 boolean inWay = false;
    101                 boolean inRel = false;
    102                 map.nodes.put(1l, map.new Snode());
    103                 map.nodes.put(2l, map.new Snode());
    104                 map.nodes.put(3l, map.new Snode());
    105                 map.nodes.put(4l, map.new Snode());
    106 
    107                 String ln;
    108                 while ((ln = in.readLine()) != null) {
    109                         if (inOsm) {
    110                                 if (ln.contains("<bounds") && !bb) {
    111                                         for (String token : ln.split("[ ]+")) {
    112                                                 if (token.matches("^minlat=.+")) {
    113                                                         map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    114                                                         map.nodes.get(2l).lat = map.bounds.minlat;
    115                                                         map.nodes.get(3l).lat = map.bounds.minlat;
    116                                                 } else if (token.matches("^minlon=.+")) {
    117                                                         map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    118                                                         map.nodes.get(1l).lon = map.bounds.minlon;
    119                                                         map.nodes.get(2l).lon = map.bounds.minlon;
    120                                                 } else if (token.matches("^maxlat=.+")) {
    121                                                         map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    122                                                         map.nodes.get(1l).lat = map.bounds.maxlat;
    123                                                         map.nodes.get(4l).lat = map.bounds.maxlat;
    124                                                 } else if (token.matches("^maxlon=.+")) {
    125                                                         map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    126                                                         map.nodes.get(3l).lon = map.bounds.maxlon;
    127                                                         map.nodes.get(4l).lon = map.bounds.maxlon;
    128                                                 }
    129                                         }
    130                                 } else {
    131                                         if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
    132                                                 k = v = "";
    133                                                 String[] token = ln.split("k=");
    134                                                 k = token[1].split("[\"\']")[1];
    135                                                 token = token[1].split("v=");
    136                                                 v = token[1].split("[\"\']")[1];
    137                                                 if (!k.isEmpty() && !v.isEmpty()) {
    138                                                         map.addTag(k, v);
    139                                                 }
    140                                         }
    141                                         if (inNode) {
    142                                                 if (ln.contains("</node")) {
    143                                                         inNode = false;
    144                                                         map.tagsDone(id);
    145                                                 }
    146                                         } else if (ln.contains("<node")) {
    147                                                 for (String token : ln.split("[ ]+")) {
    148                                                         if (token.matches("^id=.+")) {
    149                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    150                                                         } else if (token.matches("^lat=.+")) {
    151                                                                 lat = Double.parseDouble(token.split("[\"\']")[1]);
    152                                                         } else if (token.matches("^lon=.+")) {
    153                                                                 lon = Double.parseDouble(token.split("[\"\']")[1]);
    154                                                         }
    155                                                 }
    156                                                 map.addNode(id, lat, lon);
    157                                                 if (ln.contains("/>")) {
    158                                                         map.tagsDone(id);
    159                                                 } else {
    160                                                         inNode = true;
    161                                                 }
    162                                         } else if (inWay) {
    163                                                 if (ln.contains("<nd")) {
    164                                                         long ref = 0;
    165                                                         for (String token : ln.split("[ ]+")) {
    166                                                                 if (token.matches("^ref=.+")) {
    167                                                                         ref = Long.parseLong(token.split("[\"\']")[1]);
    168                                                                 }
    169                                                         }
    170                                                         try {
    171                                                                 map.addToEdge(ref);
    172                                                         } catch (Exception e) {
    173                                                                 inWay = false;
    174                                                         }
    175                                                 }
    176                                                 if (ln.contains("</way")) {
    177                                                         inWay = false;
    178                                                         map.tagsDone(id);
    179                                                 }
    180                                         } else if (ln.contains("<way")) {
    181                                                 for (String token : ln.split("[ ]+")) {
    182                                                         if (token.matches("^id=.+")) {
    183                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    184                                                         }
    185                                                 }
    186                                                 map.addEdge(id);
    187                                                 if (ln.contains("/>")) {
    188                                                         map.tagsDone(0);
    189                                                 } else {
    190                                                         inWay = true;
    191                                                 }
    192                                         } else if (ln.contains("</osm")) {
    193                                                 map.mapDone();
    194                                                 inOsm = false;
    195                                                 break;
    196                                         } else if (inRel) {
    197                                                 if (ln.contains("<member")) {
    198                                                         String type = "";
    199                                                         String role = "";
    200                                                         long ref = 0;
    201                                                         for (String token : ln.split("[ ]+")) {
    202                                                                 if (token.matches("^ref=.+")) {
    203                                                                         ref = Long.parseLong(token.split("[\"\']")[1]);
    204                                                                 } else if (token.matches("^type=.+")) {
    205                                                                         type = (token.split("[\"\']")[1]);
    206                                                                 } else if (token.matches("^role=.+")) {
    207                                                                         String str[] = token.split("[\"\']");
    208                                                                         if (str.length > 1) {
    209                                                                                 role = (token.split("[\"\']")[1]);
    210                                                                         }
    211                                                                 }
    212                                                         }
    213                                                         if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
    214                                                                 map.addToArea(ref, role.equals("outer"));
    215                                                 }
    216                                                 if (ln.contains("</relation")) {
    217                                                         inRel = false;
    218                                                         map.tagsDone(id);
    219                                                 }
    220                                         } else if (ln.contains("<relation")) {
    221                                                 for (String token : ln.split("[ ]+")) {
    222                                                         if (token.matches("^id=.+")) {
    223                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    224                                                         }
    225                                                 }
    226                                                 map.addArea(id);
    227                                                 if (ln.contains("/>")) {
    228                                                         map.tagsDone(id);
    229                                                 } else {
    230                                                         inRel = true;
    231                                                 }
    232                                         }
    233                                 }
    234                         } else if (ln.contains("<osm")) {
    235                                 inOsm = true;
    236                         }
    237                 }
    238                 return;
    239         }
    240        
    241         public static void OSMmeta(S57map map) {
    242                 map.addEdge(++map.xref);
    243                 for (long ref = 0; ref <= 4; ref++) {
    244                         map.addToEdge((ref == 0) ? 4 : ref);
    245                 }
    246                 map.addTag("seamark:type", "coverage");
    247                 map.addTag("seamark:coverage:category", "coverage");
    248                 map.tagsDone(map.xref);
    249         }
    250        
     23    // CHECKSTYLE.OFF: LineLength
     24
     25    static class KeyVal<V> {
     26        Obj obj;
     27        Att att;
     28        Conv conv;
     29        V val;
     30        KeyVal(Obj o, Att a, Conv c, V v) {
     31            obj = o;
     32            att = a;
     33            conv = c;
     34            val = v;
     35        }
     36    }
     37
     38    private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
     39    static {
     40        OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
     41        OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
     42        OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
     43        OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
     44        OSMtags.put("wetland=tidalflat", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, 0.0)); OSMtags.put("tidal=yes", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, 0.0));
     45        OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
     46        OSMtags.put("highway=motorway", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MWAY)); OSMtags.put("highway=trunk", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR));
     47        OSMtags.put("highway=primary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR)); OSMtags.put("highway=secondary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR));
     48        OSMtags.put("highway=tertiary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR)); OSMtags.put("highway=residential", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null));
     49        OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
     50        OSMtags.put("man_made=breakwater", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=groyne", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
     51        OSMtags.put("man_made=pier", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=jetty", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
     52        OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
     53        OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
     54        OSMtags.put("place=city", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_CITY)); OSMtags.put("place=town", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_TOWN));
     55        OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
     56    }
     57
     58    public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
     59        KeyVal<?> kv = OSMtags.get(key + "=" + val);
     60        if (kv != null) {
     61            if (kv.conv == Conv.E) {
     62                ArrayList<Enum<?>> list = new ArrayList<>();
     63                list.add((Enum<?>) kv.val);
     64                osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
     65            } else {
     66                osm.add(kv);
     67            }
     68        }
     69        KeyVal<?> kvl = null;
     70        KeyVal<?> kvd = null;
     71        boolean rc = false;
     72        boolean rcl = false;
     73        for (KeyVal<?> kvx : osm) {
     74            if (kvx.obj == Obj.LAKARE) {
     75                kvl = kvx;
     76            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
     77                rc = true;
     78            }
     79            if (kvx.obj == Obj.DEPARE) {
     80                kvd = kvx;
     81            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
     82                rcl = true;
     83            }
     84        }
     85        if (rc && (kvl != null)) {
     86            osm.remove(kvl);
     87        }
     88        if (rcl && (kvd != null)) {
     89            osm.remove(kvd);
     90        }
     91        return;
     92    }
     93
     94    public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
     95        String k = "";
     96        String v = "";
     97
     98        double lat = 0;
     99        double lon = 0;
     100        long id = 0;
     101
     102        boolean inOsm = false;
     103        boolean inNode = false;
     104        boolean inWay = false;
     105        boolean inRel = false;
     106        map.nodes.put(1L, map.new Snode());
     107        map.nodes.put(2L, map.new Snode());
     108        map.nodes.put(3L, map.new Snode());
     109        map.nodes.put(4L, map.new Snode());
     110
     111        String ln;
     112        while ((ln = in.readLine()) != null) {
     113            if (inOsm) {
     114                if (ln.contains("<bounds") && !bb) {
     115                    for (String token : ln.split("[ ]+")) {
     116                        if (token.matches("^minlat=.+")) {
     117                            map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     118                            map.nodes.get(2L).lat = map.bounds.minlat;
     119                            map.nodes.get(3L).lat = map.bounds.minlat;
     120                        } else if (token.matches("^minlon=.+")) {
     121                            map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     122                            map.nodes.get(1L).lon = map.bounds.minlon;
     123                            map.nodes.get(2L).lon = map.bounds.minlon;
     124                        } else if (token.matches("^maxlat=.+")) {
     125                            map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     126                            map.nodes.get(1L).lat = map.bounds.maxlat;
     127                            map.nodes.get(4L).lat = map.bounds.maxlat;
     128                        } else if (token.matches("^maxlon=.+")) {
     129                            map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     130                            map.nodes.get(3L).lon = map.bounds.maxlon;
     131                            map.nodes.get(4L).lon = map.bounds.maxlon;
     132                        }
     133                    }
     134                } else {
     135                    if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
     136                        k = v = "";
     137                        String[] token = ln.split("k=");
     138                        k = token[1].split("[\"\']")[1];
     139                        token = token[1].split("v=");
     140                        v = token[1].split("[\"\']")[1];
     141                        if (!k.isEmpty() && !v.isEmpty()) {
     142                            map.addTag(k, v);
     143                        }
     144                    }
     145                    if (inNode) {
     146                        if (ln.contains("</node")) {
     147                            inNode = false;
     148                            map.tagsDone(id);
     149                        }
     150                    } else if (ln.contains("<node")) {
     151                        for (String token : ln.split("[ ]+")) {
     152                            if (token.matches("^id=.+")) {
     153                                id = Long.parseLong(token.split("[\"\']")[1]);
     154                            } else if (token.matches("^lat=.+")) {
     155                                lat = Double.parseDouble(token.split("[\"\']")[1]);
     156                            } else if (token.matches("^lon=.+")) {
     157                                lon = Double.parseDouble(token.split("[\"\']")[1]);
     158                            }
     159                        }
     160                        map.addNode(id, lat, lon);
     161                        if (ln.contains("/>")) {
     162                            map.tagsDone(id);
     163                        } else {
     164                            inNode = true;
     165                        }
     166                    } else if (inWay) {
     167                        if (ln.contains("<nd")) {
     168                            long ref = 0;
     169                            for (String token : ln.split("[ ]+")) {
     170                                if (token.matches("^ref=.+")) {
     171                                    ref = Long.parseLong(token.split("[\"\']")[1]);
     172                                }
     173                            }
     174                            try {
     175                                map.addToEdge(ref);
     176                            } catch (Exception e) {
     177                                inWay = false;
     178                            }
     179                        }
     180                        if (ln.contains("</way")) {
     181                            inWay = false;
     182                            map.tagsDone(id);
     183                        }
     184                    } else if (ln.contains("<way")) {
     185                        for (String token : ln.split("[ ]+")) {
     186                            if (token.matches("^id=.+")) {
     187                                id = Long.parseLong(token.split("[\"\']")[1]);
     188                            }
     189                        }
     190                        map.addEdge(id);
     191                        if (ln.contains("/>")) {
     192                            map.tagsDone(0);
     193                        } else {
     194                            inWay = true;
     195                        }
     196                    } else if (ln.contains("</osm")) {
     197                        map.mapDone();
     198                        inOsm = false;
     199                        break;
     200                    } else if (inRel) {
     201                        if (ln.contains("<member")) {
     202                            String type = "";
     203                            String role = "";
     204                            long ref = 0;
     205                            for (String token : ln.split("[ ]+")) {
     206                                if (token.matches("^ref=.+")) {
     207                                    ref = Long.parseLong(token.split("[\"\']")[1]);
     208                                } else if (token.matches("^type=.+")) {
     209                                    type = (token.split("[\"\']")[1]);
     210                                } else if (token.matches("^role=.+")) {
     211                                    String[] str = token.split("[\"\']");
     212                                    if (str.length > 1) {
     213                                        role = (token.split("[\"\']")[1]);
     214                                    }
     215                                }
     216                            }
     217                            if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
     218                                map.addToArea(ref, role.equals("outer"));
     219                        }
     220                        if (ln.contains("</relation")) {
     221                            inRel = false;
     222                            map.tagsDone(id);
     223                        }
     224                    } else if (ln.contains("<relation")) {
     225                        for (String token : ln.split("[ ]+")) {
     226                            if (token.matches("^id=.+")) {
     227                                id = Long.parseLong(token.split("[\"\']")[1]);
     228                            }
     229                        }
     230                        map.addArea(id);
     231                        if (ln.contains("/>")) {
     232                            map.tagsDone(id);
     233                        } else {
     234                            inRel = true;
     235                        }
     236                    }
     237                }
     238            } else if (ln.contains("<osm")) {
     239                inOsm = true;
     240            }
     241        }
     242        return;
     243    }
     244
     245    public static void OSMmeta(S57map map) {
     246        map.addEdge(++map.xref);
     247        for (long ref = 0; ref <= 4; ref++) {
     248            map.addToEdge((ref == 0) ? 4 : ref);
     249        }
     250        map.addTag("seamark:type", "coverage");
     251        map.addTag("seamark:coverage:category", "coverage");
     252        map.tagsDone(map.xref);
     253    }
     254
    251255}
  • applications/editors/josm/plugins/seachart/src/s57/S57val.java

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57att.*;
     12import java.util.ArrayList;
     13import java.util.EnumMap;
     14
     15import s57.S57att.Att;
    1516
    1617public class S57val { // S57 Attribute values lookup tables & methods
    17 
    18  static class S57enum {
    19   Integer atvl;
    20   String val;
    21   S57enum(Integer a, String v) {
    22    atvl = a; val = v;
    23   }
    24  }
    25  
    26  public enum Conv { S, A, L, E, F, I }
    27  
    28  static class S57key {
    29   Conv conv;
    30   EnumMap<?, ?> map;
    31   S57key(Conv c, EnumMap<?, S57enum> m) {
    32    conv = c; map = m;
    33   }
    34  }
    35  
    36  public static class AttVal<V> {
    37   public Conv conv;
    38   public V val;
    39   AttVal(Conv c, V v) {
    40    conv = c; val = v;
    41   }
    42  }
    43  
    44  public enum BcnSHP { BCN_UNKN, BCN_STAK, BCN_WTHY, BCN_TOWR, BCN_LATT, BCN_PILE, BCN_CARN, BCN_BUOY, BCN_POLE, BCN_PRCH, BCN_POST }
    45  private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class); static { Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
    46   Bcnshp.put(BcnSHP.BCN_STAK, new S57enum(1, "stake")); Bcnshp.put(BcnSHP.BCN_WTHY, new S57enum(2, "withy")); Bcnshp.put(BcnSHP.BCN_TOWR, new S57enum(3, "tower"));
    47   Bcnshp.put(BcnSHP.BCN_LATT, new S57enum(4, "lattice")); Bcnshp.put(BcnSHP.BCN_PILE, new S57enum(5, "pile")); Bcnshp.put(BcnSHP.BCN_CARN, new S57enum(6, "cairn"));
    48   Bcnshp.put(BcnSHP.BCN_BUOY, new S57enum(7, "buoyant")); Bcnshp.put(BcnSHP.BCN_POLE, new S57enum(1, "pole")); Bcnshp.put(BcnSHP.BCN_PRCH, new S57enum(1, "perch"));
    49   Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
    50  }
    51  public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
    52  private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class); static { Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
    53   Buishp.put(BuiSHP.BUI_HIRS, new S57enum(5, "high-rise")); Buishp.put(BuiSHP.BUI_PYRD, new S57enum(6, "pyramid")); Buishp.put(BuiSHP.BUI_CYLR, new S57enum(7, "cylindrical"));
    54   Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
    55  }
    56  public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
    57  private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class); static { Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
    58   Boyshp.put(BoySHP.BOY_CONE, new S57enum(1, "conical")); Boyshp.put(BoySHP.BOY_CAN, new S57enum(2, "can")); Boyshp.put(BoySHP.BOY_SPHR, new S57enum(3, "spherical"));
    59   Boyshp.put(BoySHP.BOY_PILR, new S57enum(4, "pillar")); Boyshp.put(BoySHP.BOY_SPAR, new S57enum(5, "spar")); Boyshp.put(BoySHP.BOY_BARL, new S57enum(6, "barrel"));
    60    Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
    61  }
    62  public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
    63  private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class); static { Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
    64   Catair.put(CatAIR.AIR_MILA, new S57enum(1, "military")); Catair.put(CatAIR.AIR_CIVA, new S57enum(2, "civil")); Catair.put(CatAIR.AIR_MILH, new S57enum(3, "military_heliport"));
    65   Catair.put(CatAIR.AIR_CIVH, new S57enum(4, "civil_heliport")); Catair.put(CatAIR.AIR_GLDR, new S57enum(5, "glider")); Catair.put(CatAIR.AIR_SMLP, new S57enum(6, "small_planes"));
    66   Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
    67  }
    68  public enum CatACH { ACH_UNKN, ACH_UNRD, ACH_DEEP, ACH_TANK, ACH_EXPL, ACH_QUAR, ACH_SEAP, ACH_SMCF, ACH_SMCM, ACH_H24P, ACH_LTPD, ACH_NPSH, ACH_DRYC, ACH_RAFT, ACH_WAIT, ACH_REPT }
    69  private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class); static {Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
    70   Catach.put(CatACH.ACH_UNRD, new S57enum(1, "unrestricted")); Catach.put(CatACH.ACH_DEEP, new S57enum(2, "deep_water")); Catach.put(CatACH.ACH_TANK, new S57enum(3, "tanker"));
    71   Catach.put(CatACH.ACH_EXPL, new S57enum(4, "explosives")); Catach.put(CatACH.ACH_QUAR, new S57enum(5, "quarantine")); Catach.put(CatACH.ACH_SEAP, new S57enum(6, "seaplane"));
    72   Catach.put(CatACH.ACH_SMCF, new S57enum(7, "small_craft")); Catach.put(CatACH.ACH_SMCM, new S57enum(8, "small_craft_mooring")); Catach.put(CatACH.ACH_H24P, new S57enum(9, "24_hour"));
    73   Catach.put(CatACH.ACH_LTPD, new S57enum(10, "limited_period")); Catach.put(CatACH.ACH_NPSH, new S57enum(11, "non_pushing")); Catach.put(CatACH.ACH_DRYC, new S57enum(12, "dry_cargo"));
    74   Catach.put(CatACH.ACH_RAFT, new S57enum(13, "raft")); Catach.put(CatACH.ACH_WAIT, new S57enum(14, "waiting")); Catach.put(CatACH.ACH_REPT, new S57enum(15, "reported"));
    75  }
    76  public enum CatBRG { BRG_UNKN, BRG_FIXD, BRG_OPEN, BRG_SWNG, BRG_LIFT, BRG_BASC, BRG_PONT, BRG_DRAW, BRG_TRNS, BRG_FOOT, BRG_VIAD, BRG_AQUA, BRG_SUSP }
    77  private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
    78   Catbrg.put(CatBRG.BRG_FIXD, new S57enum(1, "fixed")); Catbrg.put(CatBRG.BRG_OPEN, new S57enum(2, "opening")); Catbrg.put(CatBRG.BRG_SWNG, new S57enum(3, "swing"));
    79   Catbrg.put(CatBRG.BRG_LIFT, new S57enum(4, "lifting")); Catbrg.put(CatBRG.BRG_BASC, new S57enum(5, "bascule")); Catbrg.put(CatBRG.BRG_PONT, new S57enum(6, "pontoon"));
    80   Catbrg.put(CatBRG.BRG_DRAW, new S57enum(7, "drawbridge")); Catbrg.put(CatBRG.BRG_TRNS, new S57enum(8, "transporter")); Catbrg.put(CatBRG.BRG_FOOT, new S57enum(9, "footbridge"));
    81   Catbrg.put(CatBRG.BRG_VIAD, new S57enum(10, "viaduct")); Catbrg.put(CatBRG.BRG_AQUA, new S57enum(11, "aqueduct")); Catbrg.put(CatBRG.BRG_SUSP, new S57enum(12, "suspension"));
    82  }
    83  public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
    84  private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static { Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
    85   Catbua.put(CatBUA.BUA_URBN, new S57enum(1, "urban")); Catbua.put(CatBUA.BUA_STTL, new S57enum(2, "settlement")); Catbua.put(CatBUA.BUA_VLLG, new S57enum(3, "village"));
    86   Catbua.put(CatBUA.BUA_TOWN, new S57enum(4, "town")); Catbua.put(CatBUA.BUA_CITY, new S57enum(5, "city")); Catbua.put(CatBUA.BUA_HOLV, new S57enum(6, "holiday_village"));
    87  }
    88  public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY }
    89  private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
    90   Catcbl.put(CatCBL.CBL_POWR, new S57enum(1, "power")); Catcbl.put(CatCBL.CBL_TRNS, new S57enum(3, "transmission")); Catcbl.put(CatCBL.CBL_TELE, new S57enum(4, "telephone"));
    91   Catcbl.put(CatCBL.CBL_TGPH, new S57enum(5, "telegraph")); Catcbl.put(CatCBL.CBL_MOOR, new S57enum(6, "mooring")); Catcbl.put(CatCBL.CBL_OPTC, new S57enum(7, "optical"));
    92   Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
    93  }
    94  public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
    95  private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static { Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
    96   Catcan.put(CatCAN.CAN_TRNS, new S57enum(1, "transportation")); Catcan.put(CatCAN.CAN_DRNG, new S57enum(2, "drainage")); Catcan.put(CatCAN.CAN_IRGN, new S57enum(3, "irrigation"));
    97  }
    98  public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
    99  private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static { Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
    100   Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
    101   Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
    102  }
    103  public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
    104  private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static { Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
    105   Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
    106  }
    107  public enum CatCOA { COA_UNKN, COA_STEP, COA_FLAT, COA_SAND, COA_STON, COA_SHNG, COA_GLCR, COA_MNGV, COA_MRSH, COA_CRRF, COA_ICE, COA_SHEL }
    108  private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static { Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
    109   Catcoa.put(CatCOA.COA_STEP, new S57enum(1, "steep")); Catcoa.put(CatCOA.COA_FLAT, new S57enum(2, "flat")); Catcoa.put(CatCOA.COA_SAND, new S57enum(3, "sandy"));
    110   Catcoa.put(CatCOA.COA_STON, new S57enum(4, "stony")); Catcoa.put(CatCOA.COA_SHNG, new S57enum(5, "shingly")); Catcoa.put(CatCOA.COA_GLCR, new S57enum(6, "glacier"));
    111   Catcoa.put(CatCOA.COA_MNGV, new S57enum(7, "mangrove")); Catcoa.put(CatCOA.COA_MRSH, new S57enum(8, "marshy")); Catcoa.put(CatCOA.COA_CRRF, new S57enum(9, "coral_reef"));
    112   Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
    113  }
    114  public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS }
    115  private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static { Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
    116   Catctr.put(CatCTR.CTR_TRGN, new S57enum(1, "triangulation")); Catctr.put(CatCTR.CTR_OBSV, new S57enum(2, "observation")); Catctr.put(CatCTR.CTR_FIXD, new S57enum(3, "fixed"));
    117   Catctr.put(CatCTR.CTR_BMRK, new S57enum(4, "benchmark")); Catctr.put(CatCTR.CTR_BDRY, new S57enum(5, "boundary")); Catctr.put(CatCTR.CTR_HORM, new S57enum(6, "horizontal_main"));
    118   Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
    119  }
    120  public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
    121  private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static { Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
    122   Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
    123  }
    124  public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH }
    125  private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static { Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
    126   Catcrn.put(CatCRN.CRN_NONS, new S57enum(1, "non-specific")); Catcrn.put(CatCRN.CRN_CONT, new S57enum(2, "container")); Catcrn.put(CatCRN.CRN_SHRL, new S57enum(3, "sheerlegs"));
    127   Catcrn.put(CatCRN.CRN_TRAV, new S57enum(4, "travelling")); Catcrn.put(CatCRN.CRN_AFRM , new S57enum(5, "a-frame")); Catcrn.put(CatCRN.CRN_GLTH , new S57enum(6, "goliath"));
    128  }
    129  public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
    130  private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static { Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
    131   Catdam.put(CatDAM.DAM_WEIR, new S57enum(1, "weir")); Catdam.put(CatDAM.DAM_DAM, new S57enum(2, "dam")); Catdam.put(CatDAM.DAM_FLDB, new S57enum(3, "flood_barrage"));
    132  }
    133  public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
    134  private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static { Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
    135   Catdis.put(CatDIS.DIS_NONI, new S57enum(1, "not_installed")); Catdis.put(CatDIS.DIS_POLE, new S57enum(2, "pole")); Catdis.put(CatDIS.DIS_BORD, new S57enum(3, "board"));
    136   Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
    137  }
    138  public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
    139  private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static { Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
    140   Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
    141  }
    142  public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL }
    143  private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static { Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
    144   Catdpg.put(CatDPG.DPG_GENL, new S57enum(1, "general")); Catdpg.put(CatDPG.DPG_CHEM, new S57enum(2, "chemical")); Catdpg.put(CatDPG.DPG_NCLR, new S57enum(3, "nuclear"));
    145   Catdpg.put(CatDPG.DPG_EXPL, new S57enum(4, "explosives")); Catdpg.put(CatDPG.DPG_SPIL, new S57enum(5, "spoil")); Catdpg.put(CatDPG.DPG_VSSL, new S57enum(6, "vessel"));
    146  }
    147  public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
    148  private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static { Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
    149   Catfnc.put(CatFNC.FNC_FENC, new S57enum(1, "fence")); Catfnc.put(CatFNC.FNC_MUIR, new S57enum(2, "muir")); Catfnc.put(CatFNC.FNC_HEDG, new S57enum(3, "hedge"));
    150   Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
    151  }
    152  public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR }
    153  private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static { Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
    154   Catfry.put(CatFRY.FRY_FREE, new S57enum(1, "free")); Catfry.put(CatFRY.FRY_CABL, new S57enum(2, "cable")); Catfry.put(CatFRY.FRY_ICE, new S57enum(3, "ice"));
    155   Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
    156  }
    157  public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY }
    158  private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static { Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
    159   Catfif.put(CatFIF.FIF_STAK, new S57enum(1, "stake")); Catfif.put(CatFIF.FIF_TRAP, new S57enum(2, "trap")); Catfif.put(CatFIF.FIF_WEIR, new S57enum(3, "weir"));
    160   Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
    161  }
    162  public enum CatFOG { FOG_UNKN, FOG_EXPL, FOG_DIA, FOG_SIRN, FOG_NAUT, FOG_REED, FOG_TYPH, FOG_BELL, FOG_WHIS, FOG_GONG, FOG_HORN }
    163  private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
    164   Catfog.put(CatFOG.FOG_EXPL, new S57enum(1, "explosive")); Catfog.put(CatFOG.FOG_DIA, new S57enum(2, "diaphone")); Catfog.put(CatFOG.FOG_SIRN, new S57enum(3, "siren"));
    165   Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
    166    Catfog.put(CatFOG.FOG_TYPH, new S57enum(6, "tyfon")); Catfog.put(CatFOG.FOG_BELL, new S57enum(7, "bell")); Catfog.put(CatFOG.FOG_WHIS, new S57enum(8, "whistle"));
    167    Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
    168   }
    169  public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT }
    170  private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static { Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
    171   Catfor.put(CatFOR.FOR_CSTL, new S57enum(1, "castle")); Catfor.put(CatFOR.FOR_FORT, new S57enum(2, "fort")); Catfor.put(CatFOR.FOR_BTTY, new S57enum(3, "battery"));
    172   Catfor.put(CatFOR.FOR_BKHS, new S57enum(4, "blockhouse")); Catfor.put(CatFOR.FOR_MTWR, new S57enum(5, "martello_tower")); Catfor.put(CatFOR.FOR_RDBT, new S57enum(6, "redoubt"));
    173  }
    174  public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC }
    175  private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static { Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
    176   Catgat.put(CatGAT.GAT_GNRL, new S57enum(1, "general")); Catgat.put(CatGAT.GAT_FLBG, new S57enum(2, "flood_barrage")); Catgat.put(CatGAT.GAT_CSSN, new S57enum(3, "caisson"));
    177   Catgat.put(CatGAT.GAT_LOCK, new S57enum(4, "lock")); Catgat.put(CatGAT.GAT_DYKE, new S57enum(5, "dyke")); Catgat.put(CatGAT.GAT_SLUC, new S57enum(6, "sluice"));
    178  }
    179  public enum CatHAF { HAF_UNKN, HAF_RORO, HAF_TMBR, HAF_FERY, HAF_FISH, HAF_MRNA, HAF_NAVL, HAF_TNKR, HAF_PSGR, HAF_YARD, HAF_CNTR, HAF_BULK, HAF_SYNC, HAF_STCR, HAF_LUVB,
    180   HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF }
    181  private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static { Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
    182   Cathaf.put(CatHAF.HAF_RORO, new S57enum(1, "roro")); Cathaf.put(CatHAF.HAF_FERY, new S57enum(3, "ferry")); Cathaf.put(CatHAF.HAF_FISH, new S57enum(4, "fishing"));
    183   Cathaf.put(CatHAF.HAF_MRNA, new S57enum(5, "marina")); Cathaf.put(CatHAF.HAF_NAVL, new S57enum(6, "naval")); Cathaf.put(CatHAF.HAF_TNKR, new S57enum(7, "tanker"));
    184   Cathaf.put(CatHAF.HAF_PSGR, new S57enum(8, "passenger")); Cathaf.put(CatHAF.HAF_YARD, new S57enum(9, "shipyard")); Cathaf.put(CatHAF.HAF_CNTR, new S57enum(10, "container"));
    185   Cathaf.put(CatHAF.HAF_BULK, new S57enum(11, "bulk")); Cathaf.put(CatHAF.HAF_SYNC, new S57enum(12, "syncrolift")); Cathaf.put(CatHAF.HAF_STCR, new S57enum(13, "straddle_carrier"));
    186   Cathaf.put(CatHAF.HAF_LUVB, new S57enum(14, "lay_up")); Cathaf.put(CatHAF.HAF_TMBR, new S57enum(15, "timber")); Cathaf.put(CatHAF.HAF_REPR, new S57enum(16, "service_repair"));
    187   Cathaf.put(CatHAF.HAF_QUAR, new S57enum(17, "quarantine")); Cathaf.put(CatHAF.HAF_SPLN, new S57enum(18, "seaplane")); Cathaf.put(CatHAF.HAF_CARG, new S57enum(19, "cargo"));
    188   Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support"));  Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
    189   Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
    190  }
    191  public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO }
    192  private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static { Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
    193   Cathlk.put(CatHLK.HLK_REST, new S57enum(1, "floating_restaurant")); Cathlk.put(CatHLK.HLK_HIST, new S57enum(2, "historic")); Cathlk.put(CatHLK.HLK_MUSM, new S57enum(3, "museum"));
    194   Cathlk.put(CatHLK.HLK_ACCM, new S57enum(4, "accommodation")); Cathlk.put(CatHLK.HLK_BWTR, new S57enum(5, "floating_breakwater")); Cathlk.put(CatHLK.HLK_CSNO, new S57enum(6, "casino_boat"));
    195  }
    196  public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR }
    197  private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static { Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
    198   Catice.put(CatICE.ICE_FAST, new S57enum(1, "fast")); Catice.put(CatICE.ICE_SEA, new S57enum(2, "sea")); Catice.put(CatICE.ICE_GRLR, new S57enum(3, "growler"));
    199   Catice.put(CatICE.ICE_PANK, new S57enum(4, "pancake")); Catice.put(CatICE.ICE_GLAS, new S57enum(5, "glacier")); Catice.put(CatICE.ICE_PEAK, new S57enum(6, "peak"));
    200   Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
    201  }
    202  public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
    203  private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static { Catinb.put(CatINB.INB_UNKN, new S57enum(0, ""));
    204   Catinb.put(CatINB.INB_CALM, new S57enum(1, "calm")); Catinb.put(CatINB.INB_SBM, new S57enum(2, "sbm"));
    205  }
    206  public enum CatLND { LND_UNKN, LND_FEN, LND_MRSH, LND_BOG, LND_HTHL, LND_MNTN, LND_LOWL, LND_CNYN, LND_PDDY, LND_AGRI, LND_SVNA, LND_PARK, LND_SWMP, LND_LSLD, LND_LAVA,
    207   LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
    208  private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static { Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
    209   Catlnd.put(CatLND.LND_FEN, new S57enum(1, "fen")); Catlnd.put(CatLND.LND_MRSH, new S57enum(2, "marsh")); Catlnd.put(CatLND.LND_BOG, new S57enum(3, "bog"));
    210   Catlnd.put(CatLND.LND_HTHL, new S57enum(4, "heathland")); Catlnd.put(CatLND.LND_MNTN, new S57enum(5, "mountain")); Catlnd.put(CatLND.LND_LOWL, new S57enum(6, "lowlands"));
    211   Catlnd.put(CatLND.LND_CNYN, new S57enum(7, "canyon")); Catlnd.put(CatLND.LND_PDDY, new S57enum(8, "paddy")); Catlnd.put(CatLND.LND_AGRI, new S57enum(9, "agricultural"));
    212   Catlnd.put(CatLND.LND_SVNA, new S57enum(10, "savanna")); Catlnd.put(CatLND.LND_PARK, new S57enum(11, "parkland")); Catlnd.put(CatLND.LND_SWMP, new S57enum(12, "swamp"));
    213   Catlnd.put(CatLND.LND_LSLD, new S57enum(13, "landslide")); Catlnd.put(CatLND.LND_LAVA, new S57enum(14, "lava")); Catlnd.put(CatLND.LND_SLTP, new S57enum(15, "salt_pan"));
    214   Catlnd.put(CatLND.LND_MORN, new S57enum(16, "moraine")); Catlnd.put(CatLND.LND_CRTR, new S57enum(17, "crater")); Catlnd.put(CatLND.LND_CAVE, new S57enum(18, "cave"));
    215   Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
    216  }
    217  public enum CatLMK { LMK_UNKN, LMK_CARN, LMK_CMTY, LMK_CHMY, LMK_DISH, LMK_FLAG, LMK_FLAR, LMK_MAST, LMK_WNDS, LMK_MNMT, LMK_CLMN, LMK_MEML, LMK_OBLK, LMK_STAT, LMK_CROS,
    218   LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
    219  private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
    220   Catlmk.put(CatLMK.LMK_CARN, new S57enum(1, "cairn")); Catlmk.put(CatLMK.LMK_CMTY, new S57enum(2, "cemetery")); Catlmk.put(CatLMK.LMK_CHMY, new S57enum(3, "chimney"));
    221   Catlmk.put(CatLMK.LMK_DISH, new S57enum(4, "dish_aerial")); Catlmk.put(CatLMK.LMK_FLAG, new S57enum(5, "flagstaff")); Catlmk.put(CatLMK.LMK_FLAR, new S57enum(6, "flare_stack"));
    222    Catlmk.put(CatLMK.LMK_MAST, new S57enum(7, "mast")); Catlmk.put(CatLMK.LMK_WNDS, new S57enum(8, "windsock")); Catlmk.put(CatLMK.LMK_MNMT, new S57enum(9, "monument"));
    223    Catlmk.put(CatLMK.LMK_CLMN, new S57enum(10, "column")); Catlmk.put(CatLMK.LMK_MEML, new S57enum(11, "memorial")); Catlmk.put(CatLMK.LMK_OBLK, new S57enum(12, "obelisk"));
    224    Catlmk.put(CatLMK.LMK_STAT, new S57enum(13, "statue")); Catlmk.put(CatLMK.LMK_CROS, new S57enum(14, "cross")); Catlmk.put(CatLMK.LMK_DOME, new S57enum(15, "dome"));
    225    Catlmk.put(CatLMK.LMK_RADR, new S57enum(16, "radar_scanner")); Catlmk.put(CatLMK.LMK_TOWR, new S57enum(17, "tower")); Catlmk.put(CatLMK.LMK_WNDM, new S57enum(18, "windmill"));
    226    Catlmk.put(CatLMK.LMK_WNDG, new S57enum(19, "windmotor")); Catlmk.put(CatLMK.LMK_SPIR, new S57enum(20, "spire")); Catlmk.put(CatLMK.LMK_BLDR, new S57enum(21, "boulder"));
    227    Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
    228    Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
    229  }
    230  public enum CatLAM { LAM_UNKN, LAM_PORT, LAM_STBD, LAM_PCST, LAM_PCPT, LAM_WWLT, LAM_WWRT, LAM_CHLT, LAM_CHRT, LAM_WWSN, LAM_CHSN, LAM_CHRB, LAM_CHLB, LAM_CRRT, LAM_CRLT,
    231   LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP }
    232  private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static { Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
    233   Catlam.put(CatLAM.LAM_PORT, new S57enum(1, "port")); Catlam.put(CatLAM.LAM_STBD, new S57enum(2, "starboard")); Catlam.put(CatLAM.LAM_PCST, new S57enum(3, "preferred_channel_starboard"));
    234   Catlam.put(CatLAM.LAM_PCPT, new S57enum(4, "preferred_channel_port")); Catlam.put(CatLAM.LAM_WWRT, new S57enum(5, "waterway_right")); Catlam.put(CatLAM.LAM_WWLT, new S57enum(6, "waterway_left"));
    235   Catlam.put(CatLAM.LAM_CHRT, new S57enum(7, "channel_right")); Catlam.put(CatLAM.LAM_CHLT, new S57enum(8, "channel_left")); Catlam.put(CatLAM.LAM_WWSN, new S57enum(9, "waterway_separation"));
    236   Catlam.put(CatLAM.LAM_CHSN, new S57enum(10, "channel_separation")); Catlam.put(CatLAM.LAM_CHRB, new S57enum(11, "channel_right_bank")); Catlam.put(CatLAM.LAM_CHLB, new S57enum(12, "channel_left_bank"));
    237   Catlam.put(CatLAM.LAM_CRRT, new S57enum(13, "crossover_right")); Catlam.put(CatLAM.LAM_CRLT, new S57enum(14, "crossover_left")); Catlam.put(CatLAM.LAM_DRLT, new S57enum(15, "danger_right"));
    238   Catlam.put(CatLAM.LAM_DRRT, new S57enum(16, "danger_left")); Catlam.put(CatLAM.LAM_TOLT, new S57enum(17, "turnoff_right")); Catlam.put(CatLAM.LAM_TPRT, new S57enum(18, "turnoff_left"));
    239   Catlam.put(CatLAM.LAM_JBRT, new S57enum(19, "junction_right")); Catlam.put(CatLAM.LAM_JNLT, new S57enum(20, "junction_left")); Catlam.put(CatLAM.LAM_HBRT, new S57enum(21, "harbour_right"));
    240   Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
    241  }
    242  public enum CatLIT { LIT_UNKN, LIT_DIR, LIT_LEAD, LIT_AERO, LIT_AIR, LIT_FOG, LIT_FLDL, LIT_STRP, LIT_SUBS, LIT_SPOT, LIT_FRNT, LIT_REAR, LIT_LOWR, LIT_UPPR, LIT_MOIR, LIT_EMRG, LIT_BRNG, LIT_HORI, LIT_VERT }
    243  private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static { Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
    244   Catlit.put(CatLIT.LIT_DIR, new S57enum(1, "directional")); Catlit.put(CatLIT.LIT_LEAD, new S57enum(4, "leading")); Catlit.put(CatLIT.LIT_AERO, new S57enum(5, "aero"));
    245   Catlit.put(CatLIT.LIT_AIR, new S57enum(6, "air_obstruction")); Catlit.put(CatLIT.LIT_FOG, new S57enum(7, "fog_detector")); Catlit.put(CatLIT.LIT_FLDL, new S57enum(8, "floodlight"));
    246   Catlit.put(CatLIT.LIT_STRP, new S57enum(9, "strip_light")); Catlit.put(CatLIT.LIT_SUBS, new S57enum(10, "subsidiary")); Catlit.put(CatLIT.LIT_SPOT, new S57enum(11, "spotlight"));
    247   Catlit.put(CatLIT.LIT_FRNT, new S57enum(12, "front")); Catlit.put(CatLIT.LIT_REAR, new S57enum(13, "rear")); Catlit.put(CatLIT.LIT_LOWR, new S57enum(14, "lower"));
    248   Catlit.put(CatLIT.LIT_UPPR, new S57enum(15, "upper")); Catlit.put(CatLIT.LIT_MOIR, new S57enum(16, "moire")); Catlit.put(CatLIT.LIT_EMRG, new S57enum(17, "emergency"));
    249   Catlit.put(CatLIT.LIT_BRNG, new S57enum(18, "bearing")); Catlit.put(CatLIT.LIT_HORI, new S57enum(19, "horizontal")); Catlit.put(CatLIT.LIT_VERT, new S57enum(20, "vertical"));
    250  }
    251  public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
    252  private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static { Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
    253   Catmfa.put(CatMFA.MFA_CRST, new S57enum(1, "crustaceans")); Catmfa.put(CatMFA.MFA_OYMS, new S57enum(2, "oysters_mussels")); Catmfa.put(CatMFA.MFA_FISH, new S57enum(3, "fish"));
    254   Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
    255  }
    256  public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA }
    257  private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static { Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
    258   Catmpa.put(CatMPA.MPA_PRCT, new S57enum(1, "practice")); Catmpa.put(CatMPA.MPA_TRPD, new S57enum(2, "torpedo")); Catmpa.put(CatMPA.MPA_SUBM, new S57enum(3, "submarine"));
    259   Catmpa.put(CatMPA.MPA_FIRG, new S57enum(4, "firing")); Catmpa.put(CatMPA.MPA_MINL, new S57enum(5, "mine-laying")); Catmpa.put(CatMPA.MPA_SMLA, new S57enum(6, "small_arms"));
    260  }
    261  public enum CatMOR { MOR_UNKN, MOR_DLPN, MOR_DDPN, MOR_BLRD, MOR_WALL, MOR_PILE, MOR_CHAN, MOR_BUOY, MOR_SHRP, MOR_AUTO, MOR_POST, MOR_WIRE, MOR_CABL }
    262  private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static { Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
    263   Catmor.put(CatMOR.MOR_DLPN, new S57enum(1, "dolphin")); Catmor.put(CatMOR.MOR_DDPN, new S57enum(2, "deviation_dolphin")); Catmor.put(CatMOR.MOR_BLRD, new S57enum(3, "bollard"));
    264   Catmor.put(CatMOR.MOR_WALL, new S57enum(4, "wall")); Catmor.put(CatMOR.MOR_PILE, new S57enum(5, "pile")); Catmor.put(CatMOR.MOR_CHAN, new S57enum(6, "chain"));
    265   Catmor.put(CatMOR.MOR_BUOY, new S57enum(7, "buoy")); Catmor.put(CatMOR.MOR_SHRP, new S57enum(8, "shore_ropes")); Catmor.put(CatMOR.MOR_AUTO, new S57enum(9, "automatic"));
    266   Catmor.put(CatMOR.MOR_POST, new S57enum(10, "post")); Catmor.put(CatMOR.MOR_WIRE, new S57enum(11, "wire")); Catmor.put(CatMOR.MOR_CABL, new S57enum(12, "cable"));
    267  }
    268  public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
    269  private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static { Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
    270   Catnav.put(CatNAV.NAV_CLRG, new S57enum(1, "clearing")); Catnav.put(CatNAV.NAV_TRST, new S57enum(2, "transit")); Catnav.put(CatNAV.NAV_LDNG, new S57enum(3, "leading"));
    271  }
    272  public enum CatOBS { OBS_UNKN, OBS_STMP, OBS_WELH, OBS_DIFF, OBS_CRIB, OBS_FHVN, OBS_FLAR, OBS_FLGD, OBS_ICEB, OBS_GTKL, OBS_BOOM, OBS_UWTB, OBS_TPLT, OBS_WEND, OBS_UWAS,
    273          OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII }
    274  private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static { Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
    275   Catobs.put(CatOBS.OBS_STMP, new S57enum(1, "stump")); Catobs.put(CatOBS.OBS_WELH, new S57enum(2, "wellhead")); Catobs.put(CatOBS.OBS_DIFF, new S57enum(3, "diffuser"));
    276   Catobs.put(CatOBS.OBS_CRIB, new S57enum(4, "crib")); Catobs.put(CatOBS.OBS_FHVN, new S57enum(5, "fish_haven")); Catobs.put(CatOBS.OBS_FLAR, new S57enum(6, "foul_area"));
    277   Catobs.put(CatOBS.OBS_FLGD, new S57enum(7, "foul_ground")); Catobs.put(CatOBS.OBS_ICEB, new S57enum(8, "ice_boom")); Catobs.put(CatOBS.OBS_GTKL, new S57enum(9, "ground_tackle"));
    278   Catobs.put(CatOBS.OBS_BOOM, new S57enum(10, "boom")); Catobs.put(CatOBS.OBS_UWTB, new S57enum(11, "underwater_turbine")); Catobs.put(CatOBS.OBS_TPLT, new S57enum(12, "template"));
    279   Catobs.put(CatOBS.OBS_WEND, new S57enum(13, "wave_energy_device")); Catobs.put(CatOBS.OBS_UWAS, new S57enum(14, "subsurface_data")); Catobs.put(CatOBS.OBS_REEF, new S57enum(15, "artificial_reef"));
    280   Catobs.put(CatOBS.OBS_MNFD, new S57enum(16, "manifold")); Catobs.put(CatOBS.OBS_PNGO, new S57enum(17, "submerged_pingo")); Catobs.put(CatOBS.OBS_RPLT, new S57enum(18, "platform_remains"));
    281   Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
    282  }
    283 
    284  public enum CatOFP { OFP_UNKN, OFP_OIL, OFP_PROD, OFP_OBS, OFP_ALP, OFP_SALM, OFP_MOOR, OFP_AISL, OFP_FPSO, OFP_ACCN, OFP_NCCB, OFP_FOTK }
    285  private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static { Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
    286   Catofp.put(CatOFP.OFP_OIL, new S57enum(1, "oil")); Catofp.put(CatOFP.OFP_PROD, new S57enum(2, "production")); Catofp.put(CatOFP.OFP_OBS, new S57enum(3, "observation"));
    287   Catofp.put(CatOFP.OFP_ALP, new S57enum(4, "alp")); Catofp.put(CatOFP.OFP_SALM, new S57enum(5, "salm")); Catofp.put(CatOFP.OFP_MOOR, new S57enum(6, "mooring"));
    288   Catofp.put(CatOFP.OFP_AISL, new S57enum(7, "artificial_island")); Catofp.put(CatOFP.OFP_FPSO, new S57enum(8, "fpso")); Catofp.put(CatOFP.OFP_ACCN, new S57enum(9, "accommodation"));
    289   Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
    290  }
    291  public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
    292  private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static { Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
    293   Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
    294  }
    295  public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
    296  private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static { Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
    297   Catple.put(CatPLE.PLE_STAK, new S57enum(1, "stake")); Catple.put(CatPLE.PLE_POST, new S57enum(3, "post")); Catple.put(CatPLE.PLE_TRIP, new S57enum(4, "tripodal"));
    298   Catple.put(CatPLE.PLE_PLNG, new S57enum(5, "piling")); Catple.put(CatPLE.PLE_PARE, new S57enum(6, "pile_area")); Catple.put(CatPLE.PLE_PIPE, new S57enum(7, "pipe"));
    299  }
    300 
    301  public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
    302  private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static { Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
    303   Catpil.put(CatPIL.PIL_CVSL, new S57enum(1, "cruising_vessel")); Catpil.put(CatPIL.PIL_HELI, new S57enum(2, "helicopter")); Catpil.put(CatPIL.PIL_SHOR, new S57enum(3, "from_shore"));
    304  }
    305  public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
    306  private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static { Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
    307   Catpip.put(CatPIP.PIP_OFAL, new S57enum(2, "outfall")); Catpip.put(CatPIP.PIP_ITAK, new S57enum(3, "intake")); Catpip.put(CatPIP.PIP_SEWR, new S57enum(4, "sewer"));
    308   Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
    309  }
    310  public enum CatPRA { PRA_UNKN, PRA_QRRY, PRA_MINE, PRA_STPL, PRA_PSTN, PRA_RFNY, PRA_TYRD, PRA_FACT, PRA_TFRM, PRA_WFRM, PRA_SLAG, PRA_CURF, PRA_OILF, PRA_GASF, PRA_WAVE }
    311  private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static { Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
    312   Catpra.put(CatPRA.PRA_QRRY, new S57enum(1, "quarry")); Catpra.put(CatPRA.PRA_MINE, new S57enum(2, "mine")); Catpra.put(CatPRA.PRA_STPL, new S57enum(3, "stockpile"));
    313   Catpra.put(CatPRA.PRA_PSTN, new S57enum(4, "power_station")); Catpra.put(CatPRA.PRA_RFNY, new S57enum(5, "refinery")); Catpra.put(CatPRA.PRA_TYRD, new S57enum(6, "timber_yard"));
    314   Catpra.put(CatPRA.PRA_FACT, new S57enum(7, "factory")); Catpra.put(CatPRA.PRA_TFRM, new S57enum(8, "tank_farm")); Catpra.put(CatPRA.PRA_WFRM, new S57enum(9, "wind_farm"));
    315   Catpra.put(CatPRA.PRA_SLAG, new S57enum(10, "slag_heap")); Catpra.put(CatPRA.PRA_CURF, new S57enum(11, "current_farm")); Catpra.put(CatPRA.PRA_OILF, new S57enum(12, "oil"));
    316   Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
    317  }
    318  public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER }
    319  private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static { Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
    320   Catpyl.put(CatPYL.PYL_POWR, new S57enum(1, "power")); Catpyl.put(CatPYL.PYL_TELE, new S57enum(2, "telecom")); Catpyl.put(CatPYL.PYL_AERL, new S57enum(3, "aerial"));
    321   Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
    322  }
    323  public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
    324  private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static { Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
    325   Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
    326  }
    327  public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
    328  private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
    329   Catrtb.put(CatRTB.RTB_RAMK, new S57enum(1, "ramark")); Catrtb.put(CatRTB.RTB_RACN, new S57enum(2, "racon")); Catrtb.put(CatRTB.RTB_LDG, new S57enum(3, "leading"));
    330  }
    331  public enum CatROS { ROS_UNKN, ROS_OMNI, ROS_DIRL, ROS_ROTP, ROS_CNSL, ROS_RDF, ROS_QTA, ROS_AERO, ROS_DECA, ROS_LORN, ROS_DGPS, ROS_TORN, ROS_OMGA, ROS_SYLD, ROS_CHKA,
    332   ROS_PCOM, ROS_COMB, ROS_FACS, ROS_TIME, ROS_PAIS, ROS_SAIS, ROS_VAIS, ROS_VANC, ROS_VASC, ROS_VAEC, ROS_VAWC, ROS_VAPL, ROS_VASL, ROS_VAID, ROS_VASW, ROS_VASP, ROS_VAWK }
    333  private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static { Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
    334   Catros.put(CatROS.ROS_OMNI, new S57enum(1, "omnidirectional")); Catros.put(CatROS.ROS_DIRL, new S57enum(2, "directional")); Catros.put(CatROS.ROS_ROTP, new S57enum(3, "rotating_pattern"));
    335   Catros.put(CatROS.ROS_CNSL, new S57enum(4, "consol")); Catros.put(CatROS.ROS_RDF, new S57enum(5, "rdf")); Catros.put(CatROS.ROS_QTA, new S57enum(6, "qtg"));
    336   Catros.put(CatROS.ROS_AERO, new S57enum(7, "aeronautical")); Catros.put(CatROS.ROS_DECA, new S57enum(8, "decca")); Catros.put(CatROS.ROS_LORN, new S57enum(9, "loran"));
    337   Catros.put(CatROS.ROS_DGPS, new S57enum(10, "dgps")); Catros.put(CatROS.ROS_TORN, new S57enum(11, "toran")); Catros.put(CatROS.ROS_OMGA, new S57enum(12, "omega"));
    338   Catros.put(CatROS.ROS_SYLD, new S57enum(13, "syledis")); Catros.put(CatROS.ROS_CHKA, new S57enum(14, "chiaka")); Catros.put(CatROS.ROS_PCOM, new S57enum(15, "public_communication"));
    339   Catros.put(CatROS.ROS_COMB, new S57enum(16, "commercial_broadcast")); Catros.put(CatROS.ROS_FACS, new S57enum(17, "facsimile")); Catros.put(CatROS.ROS_TIME, new S57enum(18, "time_signal"));
    340   Catros.put(CatROS.ROS_PAIS, new S57enum(19, "ais")); Catros.put(CatROS.ROS_SAIS, new S57enum(20, "s-ais")); Catros.put(CatROS.ROS_VAIS, new S57enum(21, "v-ais"));
    341   Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
    342   Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
    343   Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
    344   Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
    345   Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck"));
    346  }
    347  public enum CatRSC { RSC_UNKN, RSC_LIFB, RSC_ROKT, RSC_LBRK, RSC_RFSW, RSC_RFIT, RSC_LBOM, RSC_RDIO, RSC_FSTA, RSC_SPLN, RSC_ACFT, RSC_STUG }
    348  private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static { Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
    349   Catrsc.put(CatRSC.RSC_LIFB, new S57enum(1, "lifeboat")); Catrsc.put(CatRSC.RSC_ROKT, new S57enum(2, "rocket")); Catrsc.put(CatRSC.RSC_LBRK, new S57enum(3, "lifeboat_rocket"));
    350   Catrsc.put(CatRSC.RSC_RFSW, new S57enum(4, "refuge_shipwrecked")); Catrsc.put(CatRSC.RSC_RFIT, new S57enum(5, "refuge_intertidal")); Catrsc.put(CatRSC.RSC_LBOM, new S57enum(6, "lifeboat_on_mooring"));
    351   Catrsc.put(CatRSC.RSC_RDIO, new S57enum(7, "radio")); Catrsc.put(CatRSC.RSC_FSTA, new S57enum(8, "first_aid")); Catrsc.put(CatRSC.RSC_SPLN, new S57enum(9, "seaplane"));
    352   Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
    353  }
    354  public enum CatREA { REA_UNKN, REA_SFTY, REA_NANC, REA_NFSH, REA_NATR, REA_BRDS, REA_GRSV, REA_SEAL, REA_DEGR, REA_MILY, REA_HIST, REA_INST,
    355   REA_NASF, REA_STRD, REA_MINE, REA_NDIV, REA_TBAV, REA_PROH, REA_SWIM, REA_WAIT, REA_RSCH, REA_DREG, REA_FSNC, REA_ERES, REA_NWAK, REA_SWNG,
    356   REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS }
    357  private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static { Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
    358   Catrea.put(CatREA.REA_SFTY, new S57enum(1, "safety")); Catrea.put(CatREA.REA_NANC, new S57enum(2, "no_anchoring")); Catrea.put(CatREA.REA_NFSH, new S57enum(3, "no_fishing"));
    359   Catrea.put(CatREA.REA_NATR, new S57enum(4, "nature_reserve")); Catrea.put(CatREA.REA_BRDS, new S57enum(5, "bird_sanctuary")); Catrea.put(CatREA.REA_GRSV, new S57enum(6, "game_reserve"));
    360   Catrea.put(CatREA.REA_SEAL, new S57enum(7, "seal_sanctuary")); Catrea.put(CatREA.REA_DEGR, new S57enum(8, "degaussing_range")); Catrea.put(CatREA.REA_MILY, new S57enum(9, "military"));
    361    Catrea.put(CatREA.REA_HIST, new S57enum(10, "historic_wreck")); Catrea.put(CatREA.REA_INST, new S57enum(11, "inshore_traffic")); Catrea.put(CatREA.REA_NASF, new S57enum(12, "navigational_aid_safety"));
    362    Catrea.put(CatREA.REA_STRD, new S57enum(13, "stranding_danger")); Catrea.put(CatREA.REA_MINE, new S57enum(14, "minefield")); Catrea.put(CatREA.REA_NDIV, new S57enum(15, "no_diving"));
    363    Catrea.put(CatREA.REA_TBAV, new S57enum(16, "to_be_avoided")); Catrea.put(CatREA.REA_PROH, new S57enum(17, "prohibited")); Catrea.put(CatREA.REA_SWIM, new S57enum(18, "swimming"));
    364    Catrea.put(CatREA.REA_WAIT, new S57enum(19, "waiting")); Catrea.put(CatREA.REA_RSCH, new S57enum(20, "research")); Catrea.put(CatREA.REA_DREG, new S57enum(21, "dredging"));
    365    Catrea.put(CatREA.REA_FSNC, new S57enum(22, "fish_sanctuary")); Catrea.put(CatREA.REA_ERES, new S57enum(23, "ecological_reserve")); Catrea.put(CatREA.REA_NWAK, new S57enum(24, "no_wake"));
    366    Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
    367    Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
    368    Catrea.put(CatREA.REA_DISA, new S57enum(29, "disengagement")); Catrea.put(CatREA.REA_PSAR, new S57enum(30, "port_security")); Catrea.put(CatREA.REA_CRLS, new S57enum(31, "coral_sactuary"));
    369  }
    370  public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH }
    371  private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static { Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
    372   Catrod.put(CatROD.ROD_MWAY, new S57enum(1, "motorway")); Catrod.put(CatROD.ROD_MAJR, new S57enum(2, "major_road")); Catrod.put(CatROD.ROD_MINR, new S57enum(3, "minor_road"));
    373   Catrod.put(CatROD.ROD_TRAK, new S57enum(4, "track")); Catrod.put(CatROD.ROD_MAJS, new S57enum(5, "major_street")); Catrod.put(CatROD.ROD_MINS, new S57enum(6, "minor_street"));
    374   Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
    375  }
    376  public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
    377  private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static { Catrun.put(CatRUN.RUN_UNKN, new S57enum(0, ""));
    378   Catrun.put(CatRUN.RUN_AERP, new S57enum(1, "aeroplane")); Catrun.put(CatRUN.RUN_HELI, new S57enum(2, "helicopter"));
    379  }
    380  public enum CatSEA { SEA_UNKN, SEA_GENL, SEA_GAT, SEA_BANK, SEA_DEEP, SEA_BAY, SEA_TRCH, SEA_BASN, SEA_MDFT, SEA_REEF, SEA_LEDG, SEA_CNYN, SEA_NRRW, SEA_SHOL,
    381   SEA_KNOL, SEA_RIDG, SEA_SMNT, SEA_PNCL, SEA_APLN, SEA_PLTU, SEA_SPUR, SEA_SHLF, SEA_TRGH, SEA_SDDL, SEA_AHLL, SEA_APRN, SEA_AAPN, SEA_BLND, SEA_CMGN, SEA_CRIS,
    382   SEA_ESCT, SEA_FAN, SEA_FZON, SEA_GAP, SEA_GUYT, SEA_HILL, SEA_HOLE, SEA_LEVE, SEA_MVLY, SEA_MOAT, SEA_MTNS, SEA_PEAK, SEA_PVNC, SEA_RISE, SEA_SCNL, SEA_SCHN,
    383   SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
    384  private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static { Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
    385   Catsea.put(CatSEA.SEA_GENL, new S57enum(1, "general")); Catsea.put(CatSEA.SEA_GAT, new S57enum(2, "gat")); Catsea.put(CatSEA.SEA_BANK, new S57enum(3, "bank"));
    386   Catsea.put(CatSEA.SEA_DEEP, new S57enum(4, "deep")); Catsea.put(CatSEA.SEA_BAY, new S57enum(5, "bay")); Catsea.put(CatSEA.SEA_TRCH, new S57enum(6, "trench"));
    387   Catsea.put(CatSEA.SEA_BASN, new S57enum(7, "basin")); Catsea.put(CatSEA.SEA_MDFT, new S57enum(8, "flat")); Catsea.put(CatSEA.SEA_REEF, new S57enum(9, "reef"));
    388   Catsea.put(CatSEA.SEA_LEDG, new S57enum(10, "ledge")); Catsea.put(CatSEA.SEA_CNYN, new S57enum(11, "canyon")); Catsea.put(CatSEA.SEA_NRRW, new S57enum(12, "narrows"));
    389   Catsea.put(CatSEA.SEA_SHOL, new S57enum(13, "shoal")); Catsea.put(CatSEA.SEA_KNOL, new S57enum(14, "knoll")); Catsea.put(CatSEA.SEA_RIDG, new S57enum(15, "ridge"));
    390   Catsea.put(CatSEA.SEA_SMNT, new S57enum(16, "seamount")); Catsea.put(CatSEA.SEA_PNCL, new S57enum(17, "pinnacle")); Catsea.put(CatSEA.SEA_APLN, new S57enum(18, "abyssal_plain"));
    391   Catsea.put(CatSEA.SEA_PLTU, new S57enum(19, "plateau")); Catsea.put(CatSEA.SEA_SPUR, new S57enum(20, "spur")); Catsea.put(CatSEA.SEA_SHLF, new S57enum(21, "shelf"));
    392   Catsea.put(CatSEA.SEA_TRGH, new S57enum(22, "trough")); Catsea.put(CatSEA.SEA_SDDL, new S57enum(23, "saddle")); Catsea.put(CatSEA.SEA_AHLL, new S57enum(24, "abyssal_hills"));
    393   Catsea.put(CatSEA.SEA_APRN, new S57enum(25, "apron")); Catsea.put(CatSEA.SEA_AAPN, new S57enum(26, "archipelagic_apron")); Catsea.put(CatSEA.SEA_BLND, new S57enum(27, "borderland"));
    394   Catsea.put(CatSEA.SEA_CMGN, new S57enum(28, "continental_margin")); Catsea.put(CatSEA.SEA_CRIS, new S57enum(29, "continental_rise")); Catsea.put(CatSEA.SEA_ESCT, new S57enum(30, "escarpment"));
    395   Catsea.put(CatSEA.SEA_FAN, new S57enum(31, "fan")); Catsea.put(CatSEA.SEA_FZON, new S57enum(32, "fracture_zone")); Catsea.put(CatSEA.SEA_GAP, new S57enum(33, "gap"));
    396   Catsea.put(CatSEA.SEA_GUYT, new S57enum(34, "guyot")); Catsea.put(CatSEA.SEA_HILL, new S57enum(35, "hill")); Catsea.put(CatSEA.SEA_HOLE, new S57enum(36, "hole"));
    397   Catsea.put(CatSEA.SEA_LEVE, new S57enum(37, "levee")); Catsea.put(CatSEA.SEA_MVLY, new S57enum(38, "median_valley")); Catsea.put(CatSEA.SEA_MOAT, new S57enum(39, "moat"));
    398   Catsea.put(CatSEA.SEA_MTNS, new S57enum(40, "mountains")); Catsea.put(CatSEA.SEA_PEAK, new S57enum(41, "peak")); Catsea.put(CatSEA.SEA_PVNC, new S57enum(42, "province"));
    399   Catsea.put(CatSEA.SEA_RISE, new S57enum(43, "rise")); Catsea.put(CatSEA.SEA_SCNL, new S57enum(44, "sea_channel")); Catsea.put(CatSEA.SEA_SCHN, new S57enum(45, "seamount_chain"));
    400   Catsea.put(CatSEA.SEA_SEDG, new S57enum(46, "shelf-edge")); Catsea.put(CatSEA.SEA_SILL, new S57enum(47, "sill")); Catsea.put(CatSEA.SEA_SLOP, new S57enum(48, "slope"));
    401   Catsea.put(CatSEA.SEA_TRRC, new S57enum(49, "terrace")); Catsea.put(CatSEA.SEA_VLLY, new S57enum(50, "valley")); Catsea.put(CatSEA.SEA_CANL, new S57enum(51, "canal"));
    402   Catsea.put(CatSEA.SEA_LAKE, new S57enum(52, "lake")); Catsea.put(CatSEA.SEA_RIVR, new S57enum(53, "river")); Catsea.put(CatSEA.SEA_RECH, new S57enum(54, "reach"));
    403  }
    404  public enum CatSLC { SLC_UNKN, SLC_BWTR, SLC_GRYN, SLC_MOLE, SLC_PIER, SLC_PPER, SLC_WHRF, SLC_TWAL, SLC_RPRP, SLC_RVMT, SLC_SWAL, SLC_LSTP,
    405   SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF,  SLC_OFWF,  SLC_LRMP,  SLC_LWAL, SLC_ICEB }
    406  private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static { Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
    407   Catslc.put(CatSLC.SLC_BWTR, new S57enum(1, "breakwater")); Catslc.put(CatSLC.SLC_GRYN, new S57enum(2, "groyne")); Catslc.put(CatSLC.SLC_MOLE, new S57enum(3, "mole"));
    408   Catslc.put(CatSLC.SLC_PIER, new S57enum(4, "pier")); Catslc.put(CatSLC.SLC_PPER, new S57enum(5, "promenade_pier")); Catslc.put(CatSLC.SLC_WHRF, new S57enum(6, "wharf"));
    409   Catslc.put(CatSLC.SLC_TWAL, new S57enum(7, "training_wall")); Catslc.put(CatSLC.SLC_RPRP, new S57enum(8, "rip_rap")); Catslc.put(CatSLC.SLC_RVMT, new S57enum(9, "revetment"));
    410   Catslc.put(CatSLC.SLC_SWAL, new S57enum(10, "sea_wall")); Catslc.put(CatSLC.SLC_LSTP, new S57enum(11, "landing_steps")); Catslc.put(CatSLC.SLC_RAMP, new S57enum(12, "ramp"));
    411   Catslc.put(CatSLC.SLC_SWAY, new S57enum(13, "slipway")); Catslc.put(CatSLC.SLC_FNDR, new S57enum(14, "fender")); Catslc.put(CatSLC.SLC_SFWF, new S57enum(15, "solid_face_wharf"));
    412   Catslc.put(CatSLC.SLC_OFWF, new S57enum(16, "open_face_wharf")); Catslc.put(CatSLC.SLC_LRMP, new S57enum(17, "log_ramp")); Catslc.put(CatSLC.SLC_LWAL, new S57enum(18, "lock_wall"));
    413   Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
    414  }
    415  public enum CatSIT { SIT_UNKN, SIT_PRTC, SIT_PRTE, SIT_IPT, SIT_BRTH, SIT_DOCK, SIT_LOCK, SIT_FLDB, SIT_BRDG, SIT_DRDG, SIT_TCLT, SIT_SPCL, SIT_PLTG, SIT_ONCT }
    416  private static final EnumMap<CatSIT, S57enum>  Catsit = new EnumMap<>(CatSIT.class); static {Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
    417   Catsit.put(CatSIT.SIT_PRTC, new S57enum(1, "port_control")); Catsit.put(CatSIT.SIT_PRTE, new S57enum(2, "port_entry_departure")); Catsit.put(CatSIT.SIT_IPT, new S57enum(3, "ipt"));
    418   Catsit.put(CatSIT.SIT_BRTH, new S57enum(4, "berthing")); Catsit.put(CatSIT.SIT_DOCK, new S57enum(5, "dock")); Catsit.put(CatSIT.SIT_LOCK, new S57enum(6, "lock"));
    419   Catsit.put(CatSIT.SIT_FLDB, new S57enum(7, "flood_barrage")); Catsit.put(CatSIT.SIT_BRDG, new S57enum(8, "bridge_passage")); Catsit.put(CatSIT.SIT_DRDG, new S57enum(9, "dredging"));
    420   Catsit.put(CatSIT.SIT_TCLT, new S57enum(10, "traffic_control")); Catsit.put(CatSIT.SIT_PLTG, new S57enum(11, "pilotage")); Catsit.put(CatSIT.SIT_SPCL, new S57enum(12, "special"));
    421   Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
    422  }
    423  public enum CatSIW { SIW_UNKN, SIW_DNGR, SIW_OBST, SIW_CABL, SIW_MILY, SIW_DSTR, SIW_WTHR, SIW_STRM, SIW_ICE, SIW_TIME, SIW_TIDE, SIW_TSTR,
    424    SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
    425  private static final EnumMap<CatSIW, S57enum>  Catsiw = new EnumMap<>(CatSIW.class); static {Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
    426   Catsiw.put(CatSIW.SIW_DNGR, new S57enum(1, "danger")); Catsiw.put(CatSIW.SIW_OBST, new S57enum(2, "maritime_obstruction")); Catsiw.put(CatSIW.SIW_CABL, new S57enum(3, "cable"));
    427   Catsiw.put(CatSIW.SIW_MILY, new S57enum(4, "military")); Catsiw.put(CatSIW.SIW_DSTR, new S57enum(5, "distress")); Catsiw.put(CatSIW.SIW_WTHR, new S57enum(6, "weather"));
    428   Catsiw.put(CatSIW.SIW_STRM, new S57enum(7, "storm")); Catsiw.put(CatSIW.SIW_ICE, new S57enum(8, "ice")); Catsiw.put(CatSIW.SIW_TIME, new S57enum(9, "time"));
    429   Catsiw.put(CatSIW.SIW_TIDE, new S57enum(10, "tide")); Catsiw.put(CatSIW.SIW_TSTR, new S57enum(11, "tidal_stream")); Catsiw.put(CatSIW.SIW_TIDG, new S57enum(12, "tide_gauge"));
    430    Catsiw.put(CatSIW.SIW_TIDS, new S57enum(13, "tide_scale")); Catsiw.put(CatSIW.SIW_DIVE, new S57enum(14, "diving")); Catsiw.put(CatSIW.SIW_WTLG, new S57enum(15, "water_level_gauge"));
    431    Catsiw.put(CatSIW.SIW_VRCL, new S57enum(16, "vertical_clearance")); Catsiw.put(CatSIW.SIW_HIWM, new S57enum(17, "high_water")); Catsiw.put(CatSIW.SIW_DPTH, new S57enum(18, "depth"));
    432    Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
    433  }
    434  public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT }
    435  private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static { Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
    436   Catsil.put(CatSIL.SIL_SILO, new S57enum(1, "silo")); Catsil.put(CatSIL.SIL_TANK, new S57enum(2, "tank")); Catsil.put(CatSIL.SIL_GRNE, new S57enum(3, "grain_elevator"));
    437   Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
    438  }
    439  public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE }
    440  private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static { Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
    441   Catslo.put(CatSLO.SLO_CUTG, new S57enum(1, "cutting")); Catslo.put(CatSLO.SLO_EMBK, new S57enum(2, "embankment")); Catslo.put(CatSLO.SLO_DUNE, new S57enum(3, "dune"));
    442   Catslo.put(CatSLO.SLO_HILL, new S57enum(4, "hill")); Catslo.put(CatSLO.SLO_PINO, new S57enum(5, "pingo")); Catslo.put(CatSLO.SLO_CLIF, new S57enum(6, "cliff")); Catslo.put(CatSLO.SLO_SCRE, new S57enum(7, "scree"));
    443  }
    444  public enum CatSCF { SCF_UNKN, SCF_VBTH, SCF_CLUB, SCF_BHST, SCF_SMKR, SCF_BTYD, SCF_INN, SCF_RSRT, SCF_CHDR, SCF_PROV, SCF_DCTR, SCF_PHRM,
    445   SCF_WTRT, SCF_FUEL, SCF_ELEC, SCF_BGAS, SCF_SHWR, SCF_LAUN, SCF_WC, SCF_POST, SCF_TELE, SCF_REFB, SCF_CARP, SCF_BTPK, SCF_CRVN, SCF_CAMP,
    446   SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
    447  private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static { Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
    448   Catscf.put(CatSCF.SCF_VBTH, new S57enum(1, "visitor_berth")); Catscf.put(CatSCF.SCF_CLUB, new S57enum(2, "nautical_club")); Catscf.put(CatSCF.SCF_BHST, new S57enum(3, "boat_hoist"));
    449   Catscf.put(CatSCF.SCF_SMKR, new S57enum(4, "sailmaker")); Catscf.put(CatSCF.SCF_BTYD, new S57enum(5, "boatyard")); Catscf.put(CatSCF.SCF_INN, new S57enum(6, "public_inn"));
    450   Catscf.put(CatSCF.SCF_RSRT, new S57enum(7, "restaurant")); Catscf.put(CatSCF.SCF_CHDR, new S57enum(8, "chandler")); Catscf.put(CatSCF.SCF_PROV, new S57enum(9, "provisions"));
    451   Catscf.put(CatSCF.SCF_DCTR, new S57enum(10, "doctor")); Catscf.put(CatSCF.SCF_PHRM, new S57enum(11, "pharmacy")); Catscf.put(CatSCF.SCF_WTRT, new S57enum(12, "water_tap"));
    452    Catscf.put(CatSCF.SCF_FUEL, new S57enum(13, "fuel_station")); Catscf.put(CatSCF.SCF_ELEC, new S57enum(14, "electricity")); Catscf.put(CatSCF.SCF_BGAS, new S57enum(15, "bottle_gas"));
    453    Catscf.put(CatSCF.SCF_SHWR, new S57enum(16, "showers")); Catscf.put(CatSCF.SCF_LAUN, new S57enum(17, "laundrette")); Catscf.put(CatSCF.SCF_WC, new S57enum(18, "toilets"));
    454    Catscf.put(CatSCF.SCF_POST, new S57enum(19, "post_box")); Catscf.put(CatSCF.SCF_TELE, new S57enum(20, "telephone")); Catscf.put(CatSCF.SCF_REFB, new S57enum(21, "refuse_bin"));
    455    Catscf.put(CatSCF.SCF_CARP, new S57enum(22, "car_park")); Catscf.put(CatSCF.SCF_BTPK, new S57enum(23, "boat_trailers_park")); Catscf.put(CatSCF.SCF_CRVN, new S57enum(24, "caravan_site"));
    456    Catscf.put(CatSCF.SCF_CAMP, new S57enum(25, "camping_site"));  Catscf.put(CatSCF.SCF_PMPO, new S57enum(26, "pump-out")); Catscf.put(CatSCF.SCF_EMRT, new S57enum(27, "emergency_telephone"));
    457    Catscf.put(CatSCF.SCF_SLPW, new S57enum(28, "slipway")); Catscf.put(CatSCF.SCF_VMOR, new S57enum(29, "visitors_mooring")); Catscf.put(CatSCF.SCF_SCRB, new S57enum(30, "scrubbing_berth"));
    458    Catscf.put(CatSCF.SCF_PCNC, new S57enum(31, "picnic_area")); Catscf.put(CatSCF.SCF_MECH, new S57enum(32, "mechanics_workshop")); Catscf.put(CatSCF.SCF_SECS, new S57enum(33, "security_service"));
    459  }
    460  public enum CatSPM { SPM_UNKN, SPM_FDGA, SPM_TRGT, SPM_MSHP, SPM_DGRG, SPM_BARG, SPM_CABL, SPM_SPLG, SPM_OFAL, SPM_ODAS, SPM_RCDG, SPM_SPLA, SPM_RCZN, SPM_PRVT, SPM_MOOR, SPM_LNBY, SPM_LDNG, SPM_MDST,
    461   SPM_NOTC, SPM_TSS, SPM_NANC, SPM_NBRT, SPM_NOTK, SPM_NTWT, SPM_RWAK, SPM_SPDL, SPM_STOP, SPM_WRNG, SPM_SSSN, SPM_RVCL, SPM_MVDT, SPM_RHCL, SPM_SCNT, SPM_BRTH, SPM_OHPC, SPM_CHEG, SPM_TELE, SPM_FCRS,
    462   SPM_MTRL, SPM_PLIN, SPM_ANCH, SPM_CLRG, SPM_CTRL, SPM_DIVG, SPM_RBCN, SPM_FGND, SPM_YCHT, SPM_HPRT, SPM_GPS, SPM_SLDG, SPM_NENT, SPM_WRKP, SPM_UKPP, SPM_WELH, SPM_CHSP, SPM_MFRM, SPM_AREF }
    463  private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static { Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
    464   Catspm.put(CatSPM.SPM_FDGA, new S57enum(1, "firing_danger_area")); Catspm.put(CatSPM.SPM_TRGT, new S57enum(2, "target")); Catspm.put(CatSPM.SPM_MSHP, new S57enum(3, "marker_ship"));
    465   Catspm.put(CatSPM.SPM_DGRG, new S57enum(4, "degaussing_range")); Catspm.put(CatSPM.SPM_BARG, new S57enum(5, "barge")); Catspm.put(CatSPM.SPM_CABL, new S57enum(6, "cable"));
    466   Catspm.put(CatSPM.SPM_SPLG, new S57enum(7, "spoil_ground")); Catspm.put(CatSPM.SPM_OFAL, new S57enum(8, "outfall")); Catspm.put(CatSPM.SPM_ODAS, new S57enum(9, "odas"));
    467   Catspm.put(CatSPM.SPM_RCDG, new S57enum(10, "recording")); Catspm.put(CatSPM.SPM_SPLA, new S57enum(11, "seaplane_anchorage")); Catspm.put(CatSPM.SPM_RCZN, new S57enum(12, "recreation_zone"));
    468   Catspm.put(CatSPM.SPM_PRVT, new S57enum(13, "private")); Catspm.put(CatSPM.SPM_MOOR, new S57enum(14, "mooring")); Catspm.put(CatSPM.SPM_LNBY, new S57enum(15, "lanby"));
    469   Catspm.put(CatSPM.SPM_LDNG, new S57enum(16, "leading")); Catspm.put(CatSPM.SPM_MDST, new S57enum(17, "measured_distance")); Catspm.put(CatSPM.SPM_NOTC, new S57enum(18, "notice"));
    470   Catspm.put(CatSPM.SPM_TSS, new S57enum(19, "tss")); Catspm.put(CatSPM.SPM_NANC, new S57enum(20, "no_anchoring")); Catspm.put(CatSPM.SPM_NBRT, new S57enum(21, "no_berthing"));
    471   Catspm.put(CatSPM.SPM_NOTK, new S57enum(22, "no_overtaking")); Catspm.put(CatSPM.SPM_NTWT, new S57enum(23, "no_two-way_traffic")); Catspm.put(CatSPM.SPM_RWAK, new S57enum(24, "reduced_wake"));
    472   Catspm.put(CatSPM.SPM_SPDL, new S57enum(25, "speed_limit")); Catspm.put(CatSPM.SPM_STOP, new S57enum(26, "stop")); Catspm.put(CatSPM.SPM_WRNG, new S57enum(27, "warning"));
    473   Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
    474   Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
    475   Catspm.put(CatSPM.SPM_SCNT, new S57enum(32, "strong_current")); Catspm.put(CatSPM.SPM_BRTH, new S57enum(33, "berthing")); Catspm.put(CatSPM.SPM_OHPC, new S57enum(34, "overhead_power_cable"));
    476   Catspm.put(CatSPM.SPM_CHEG, new S57enum(35, "channel_edge_gradient")); Catspm.put(CatSPM.SPM_TELE, new S57enum(36, "telephone")); Catspm.put(CatSPM.SPM_FCRS, new S57enum(37, "ferry_crossing"));
    477   Catspm.put(CatSPM.SPM_MTRL, new S57enum(38, "marine_traffic_lights")); Catspm.put(CatSPM.SPM_PLIN, new S57enum(39, "pipeline")); Catspm.put(CatSPM.SPM_ANCH, new S57enum(40, "anchorage"));
    478   Catspm.put(CatSPM.SPM_CLRG, new S57enum(41, "clearing")); Catspm.put(CatSPM.SPM_CTRL, new S57enum(42, "control")); Catspm.put(CatSPM.SPM_DIVG, new S57enum(43, "diving"));
    479   Catspm.put(CatSPM.SPM_RBCN, new S57enum(44, "refuge_beacon")); Catspm.put(CatSPM.SPM_FGND, new S57enum(45, "foul_ground")); Catspm.put(CatSPM.SPM_YCHT, new S57enum(46, "yachting"));
    480   Catspm.put(CatSPM.SPM_HPRT, new S57enum(47, "heliport")); Catspm.put(CatSPM.SPM_GPS, new S57enum(48, "gps")); Catspm.put(CatSPM.SPM_SLDG, new S57enum(49, "seaplane_landing"));
    481    Catspm.put(CatSPM.SPM_NENT, new S57enum(50, "no_entry")); Catspm.put(CatSPM.SPM_WRKP, new S57enum(51, "work_in_progress")); Catspm.put(CatSPM.SPM_UKPP, new S57enum(52, "unknown_purpose"));
    482    Catspm.put(CatSPM.SPM_WELH, new S57enum(53, "wellhead")); Catspm.put(CatSPM.SPM_CHSP, new S57enum(54, "channel_separation")); Catspm.put(CatSPM.SPM_MFRM, new S57enum(55, "marine_farm"));
    483    Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
    484  }
    485  public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
    486  private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static { Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
    487   Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
    488  }
    489  public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
    490  private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static { Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
    491   Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
    492  }
    493  public enum CatVEG { VEG_UNKN, VEG_GRAS, VEG_PDDY, VEG_BUSH, VEG_DCDW, VEG_CONW, VEG_WOOD, VEG_MGRV, VEG_PARK, VEG_PKLD, VEG_MCRP, VEG_REED, VEG_MOSS,
    494   VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
    495  private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static { Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
    496   Catveg.put(CatVEG.VEG_GRAS, new S57enum(1, "grass")); Catveg.put(CatVEG.VEG_PDDY, new S57enum(2, "paddy")); Catveg.put(CatVEG.VEG_BUSH, new S57enum(3, "bush"));
    497   Catveg.put(CatVEG.VEG_DCDW, new S57enum(4, "deciduous_wood")); Catveg.put(CatVEG.VEG_CONW, new S57enum(5, "coniferous_wood")); Catveg.put(CatVEG.VEG_WOOD, new S57enum(6, "wood"));
    498   Catveg.put(CatVEG.VEG_MGRV, new S57enum(7, "mangroves")); Catveg.put(CatVEG.VEG_PARK, new S57enum(8, "park")); Catveg.put(CatVEG.VEG_PKLD, new S57enum(9, "parkland"));
    499   Catveg.put(CatVEG.VEG_MCRP, new S57enum(10, "mixed_crops")); Catveg.put(CatVEG.VEG_REED, new S57enum(11, "reed")); Catveg.put(CatVEG.VEG_MOSS, new S57enum(12, "moss"));
    500   Catveg.put(CatVEG.VEG_TREE, new S57enum(13, "tree")); Catveg.put(CatVEG.VEG_EVGT, new S57enum(14, "evergreen_tree")); Catveg.put(CatVEG.VEG_CONT, new S57enum(15, "coniferous_tree"));
    501   Catveg.put(CatVEG.VEG_PLMT, new S57enum(16, "palm_tree")); Catveg.put(CatVEG.VEG_NPMT, new S57enum(17, "nipa_palm_tree")); Catveg.put(CatVEG.VEG_CSAT, new S57enum(18, "casuarina_tree"));
    502   Catveg.put(CatVEG.VEG_EUCT, new S57enum(19, "eucalypt_tree")); Catveg.put(CatVEG.VEG_DCDT, new S57enum(20, "deciduous_tree")); Catveg.put(CatVEG.VEG_MRVT, new S57enum(21, "mangrove_tree"));
    503   Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
    504  }
    505  public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR }
    506  private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static { Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
    507   Catwat.put(CatWAT.WAT_BKRS, new S57enum(1, "breakers")); Catwat.put(CatWAT.WAT_EDDY, new S57enum(2, "eddies")); Catwat.put(CatWAT.WAT_OVFL, new S57enum(3, "overfalls"));
    508   Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
    509  }
    510  public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO }
    511  private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static { Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
    512   Catwed.put(CatWED.WED_KELP, new S57enum(1, "kelp")); Catwed.put(CatWED.WED_SWED, new S57enum(2, "sea_weed")); Catwed.put(CatWED.WED_SGRS, new S57enum(3, "sea_grass"));
    513   Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
    514  }
    515  public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS }
    516  private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static { Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
    517   Catwrk.put(CatWRK.WRK_NDGR, new S57enum(1, "non-dangerous")); Catwrk.put(CatWRK.WRK_DNGR, new S57enum(2, "dangerous")); Catwrk.put(CatWRK.WRK_DREM, new S57enum(3, "distributed_remains"));
    518   Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
    519  }
    520  public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U }
    521  private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static { Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
    522   Catzoc.put(CatZOC.ZOC_A1, new S57enum(1, "a1")); Catzoc.put(CatZOC.ZOC_A2, new S57enum(2, "a2")); Catzoc.put(CatZOC.ZOC_B, new S57enum(3, "b"));
    523   Catzoc.put(CatZOC.ZOC_C, new S57enum(4, "c")); Catzoc.put(CatZOC.ZOC_D, new S57enum(5, "d")); Catzoc.put(CatZOC.ZOC_U, new S57enum(6, "u"));
    524  }
    525  public enum ColCOL { COL_UNK, COL_WHT, COL_BLK, COL_RED, COL_GRN, COL_BLU, COL_YEL, COL_GRY, COL_BRN, COL_AMB, COL_VIO, COL_ORG, COL_MAG, COL_PNK }
    526  private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static { Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
    527   Colour.put(ColCOL.COL_WHT, new S57enum(1, "white")); Colour.put(ColCOL.COL_BLK, new S57enum(2, "black")); Colour.put(ColCOL.COL_RED, new S57enum(3, "red"));
    528   Colour.put(ColCOL.COL_GRN, new S57enum(4, "green")); Colour.put(ColCOL.COL_BLU, new S57enum(5, "blue")); Colour.put(ColCOL.COL_YEL, new S57enum(6, "yellow"));
    529   Colour.put(ColCOL.COL_GRY, new S57enum(7, "grey")); Colour.put(ColCOL.COL_BRN, new S57enum(8, "brown")); Colour.put(ColCOL.COL_AMB, new S57enum(9, "amber"));
    530   Colour.put(ColCOL.COL_VIO, new S57enum(10, "violet")); Colour.put(ColCOL.COL_ORG, new S57enum(11, "orange")); Colour.put(ColCOL.COL_MAG, new S57enum(12, "magenta"));
    531   Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
    532  }
    533  public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
    534  private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static { Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
    535   Colpat.put(ColPAT.PAT_HORI, new S57enum(1, "horizontal")); Colpat.put(ColPAT.PAT_VERT, new S57enum(2, "vertical")); Colpat.put(ColPAT.PAT_DIAG, new S57enum(3, "diagonal"));
    536   Colpat.put(ColPAT.PAT_SQUR, new S57enum(4, "squared")); Colpat.put(ColPAT.PAT_STRP, new S57enum(5, "stripes")); Colpat.put(ColPAT.PAT_BRDR, new S57enum(6, "border"));
    537   Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
    538  }
    539  public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS }
    540  private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static { Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
    541   Condtn.put(CndCND.CND_UCNS, new S57enum(1, "under_construction")); Condtn.put(CndCND.CND_RUIN, new S57enum(2, "ruined")); Condtn.put(CndCND.CND_URCL, new S57enum(3, "under_reclamation"));
    542   Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
    543  }
    544  public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
    545  private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static { Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
    546   Conrad.put(ConRAD.RAD_CNSP, new S57enum(1, "conspicuous")); Conrad.put(ConRAD.RAD_NCSP, new S57enum(2, "not_conspicuous")); Conrad.put(ConRAD.RAD_REFL, new S57enum(3, "reflector"));
    547  }
    548  public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
    549  private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static { Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
    550   Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
    551  }
    552  public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
    553  private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static { Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
    554   Dunits.put(UniDPU.DPU_METR, new S57enum(1, "metres")); Dunits.put(UniDPU.DPU_FTFT, new S57enum(2, "fathoms_feet")); Dunits.put(UniDPU.DPU_FTHM, new S57enum(3, "fathoms"));
    555   Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
    556  }
    557  public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM }
    558  private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static { Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
    559   Exclit.put(ExcLIT.EXH_24H, new S57enum(1, "24h")); Exclit.put(ExcLIT.EXH_DAY, new S57enum(2, "day")); Exclit.put(ExcLIT.EXH_FOG, new S57enum(3, "fog")); Exclit.put(ExcLIT.EXH_NGHT, new S57enum(4, "night"));
    560   Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
    561  }
    562  public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
    563  private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static { Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
    564   Expsou.put(ExpSOU.EXP_WTHN, new S57enum(1, "within")); Expsou.put(ExpSOU.EXP_SHLR, new S57enum(2, "shoaler")); Expsou.put(ExpSOU.EXP_DEPR, new S57enum(3, "deeper"));
    565  }
    566  public enum FncFNC { FNC_UNKN, FNC_HBRM, FNC_CSTM, FNC_HLTH, FNC_HOSP, FNC_POST, FNC_HOTL, FNC_RAIL, FNC_POLC, FNC_WPOL, FNC_PILO, FNC_PILL, FNC_BANK,
    567   FNC_DIST, FNC_TRNS, FNC_FCTY, FNC_POWR, FNC_ADMIN, FNC_EDUC, FNC_CHCH, FNC_CHPL, FNC_TMPL, FNC_PGDA, FNC_SHSH, FNC_BTMP, FNC_MOSQ, FNC_MRBT,
    568   FNC_LOOK, FNC_COMM, FNC_TV, FNC_RADO, FNC_RADR, FNC_LGHT, FNC_MCWV, FNC_COOL, FNC_OBS, FNC_TMBL, FNC_CLOK, FNC_CTRL, FNC_ASHM, FNC_STAD, FNC_BUSS,
    569   FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
    570  private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
    571   Functn.put(FncFNC.FNC_HBRM, new S57enum(2, "harbour_master")); Functn.put(FncFNC.FNC_CSTM, new S57enum(3, "customs")); Functn.put(FncFNC.FNC_HLTH, new S57enum(4, "health"));
    572   Functn.put(FncFNC.FNC_HOSP, new S57enum(5, "hospital")); Functn.put(FncFNC.FNC_POST, new S57enum(6, "post_office")); Functn.put(FncFNC.FNC_HOTL, new S57enum(7, "hotel"));
    573    Functn.put(FncFNC.FNC_RAIL, new S57enum(8, "railway_station")); Functn.put(FncFNC.FNC_POLC, new S57enum(9, "police_station")); Functn.put(FncFNC.FNC_WPOL, new S57enum(10, "water-police_station"));
    574    Functn.put(FncFNC.FNC_PILO, new S57enum(11, "pilot_office")); Functn.put(FncFNC.FNC_PILL, new S57enum(12, "pilot_lookout")); Functn.put(FncFNC.FNC_BANK, new S57enum(13, "bank"));
    575    Functn.put(FncFNC.FNC_DIST, new S57enum(14, "district_control")); Functn.put(FncFNC.FNC_TRNS, new S57enum(15, "transit_shed")); Functn.put(FncFNC.FNC_FCTY, new S57enum(16, "factory"));
    576    Functn.put(FncFNC.FNC_POWR, new S57enum(17, "power_station")); Functn.put(FncFNC.FNC_ADMIN, new S57enum(18, "administrative")); Functn.put(FncFNC.FNC_EDUC, new S57enum(19, "educational"));
    577    Functn.put(FncFNC.FNC_CHCH, new S57enum(20, "church")); Functn.put(FncFNC.FNC_CHPL, new S57enum(21, "chapel")); Functn.put(FncFNC.FNC_TMPL, new S57enum(22, "temple"));
    578    Functn.put(FncFNC.FNC_PGDA, new S57enum(23, "pagoda")); Functn.put(FncFNC.FNC_SHSH, new S57enum(24, "shinto_shrine")); Functn.put(FncFNC.FNC_BTMP, new S57enum(25, "buddhist_temple"));
    579    Functn.put(FncFNC.FNC_MOSQ, new S57enum(26, "mosque")); Functn.put(FncFNC.FNC_MRBT, new S57enum(27, "marabout")); Functn.put(FncFNC.FNC_LOOK, new S57enum(28, "lookout"));
    580    Functn.put(FncFNC.FNC_COMM, new S57enum(29, "communication")); Functn.put(FncFNC.FNC_TV, new S57enum(30, "television")); Functn.put(FncFNC.FNC_RADO, new S57enum(31, "radio"));
    581    Functn.put(FncFNC.FNC_RADR, new S57enum(32, "radar")); Functn.put(FncFNC.FNC_LGHT, new S57enum(33, "light_support")); Functn.put(FncFNC.FNC_MCWV, new S57enum(34, "microwave"));
    582    Functn.put(FncFNC.FNC_COOL, new S57enum(35, "cooling")); Functn.put(FncFNC.FNC_OBS, new S57enum(36, "observation")); Functn.put(FncFNC.FNC_TMBL, new S57enum(37, "time_ball"));
    583    Functn.put(FncFNC.FNC_CLOK, new S57enum(38, "clock")); Functn.put(FncFNC.FNC_CTRL, new S57enum(39, "control")); Functn.put(FncFNC.FNC_ASHM, new S57enum(40, "airship_mooring"));
    584    Functn.put(FncFNC.FNC_STAD, new S57enum(41, "stadium")); Functn.put(FncFNC.FNC_BUSS, new S57enum(42, "bus_station")); Functn.put(FncFNC.FNC_PTRM, new S57enum(43, "passenger_terminal"));
    585    Functn.put(FncFNC.FNC_SRCT, new S57enum(44, "sea_rescue_control")); Functn.put(FncFNC.FNC_OBSV, new S57enum(45, "observatory")); Functn.put(FncFNC.FNC_OREC, new S57enum(46, "ore_crusher"));
    586    Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
    587  }
    588 
    589  public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
    590  private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static { Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
    591   Hunits.put(UniHLU.HLU_METR, new S57enum(1, "metres")); Hunits.put(UniHLU.HLU_FEET, new S57enum(2, "feet")); Hunits.put(UniHLU.HLU_KMTR, new S57enum(3, "kilometres"));
    592   Hunits.put(UniHLU.HLU_HMTR, new S57enum(4, "hectometres")); Hunits.put(UniHLU.HLU_SMIL, new S57enum(5, "statute_miles")); Hunits.put(UniHLU.HLU_NMIL, new S57enum(6, "nautical_miles"));
    593  }
    594  public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
    595  private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static { Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
    596   Jrsdtn.put(JrsJRS.JRS_INT, new S57enum(1, "international")); Jrsdtn.put(JrsJRS.JRS_NAT, new S57enum(2, "national")); Jrsdtn.put(JrsJRS.JRS_NSD, new S57enum(3, "national_sub-division"));
    597  }
    598  public enum LitCHR { CHR_UNKN, CHR_F, CHR_FL, CHR_LFL, CHR_Q, CHR_VQ, CHR_UQ, CHR_ISO, CHR_OC, CHR_IQ, CHR_IVQ, CHR_IUQ, CHR_MO, CHR_FFL,
    599   CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
    600  private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static { Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
    601   Litchr.put(LitCHR.CHR_F, new S57enum(1, "F")); Litchr.put(LitCHR.CHR_FL, new S57enum(2, "Fl")); Litchr.put(LitCHR.CHR_LFL, new S57enum(3, "LFl")); Litchr.put(LitCHR.CHR_Q, new S57enum(4, "Q"));
    602   Litchr.put(LitCHR.CHR_VQ, new S57enum(5, "VQ")); Litchr.put(LitCHR.CHR_UQ, new S57enum(6, "UQ")); Litchr.put(LitCHR.CHR_ISO, new S57enum(7, "Iso")); Litchr.put(LitCHR.CHR_OC, new S57enum(8, "Oc"));
    603    Litchr.put(LitCHR.CHR_IQ, new S57enum(9, "IQ")); Litchr.put(LitCHR.CHR_IVQ, new S57enum(10, "IVQ")); Litchr.put(LitCHR.CHR_IUQ, new S57enum(11, "IUQ")); Litchr.put(LitCHR.CHR_MO, new S57enum(12, "Mo"));
    604    Litchr.put(LitCHR.CHR_FFL, new S57enum(13, "FFl")); Litchr.put(LitCHR.CHR_FLLFL, new S57enum(14, "FlLFl")); Litchr.put(LitCHR.CHR_OCFL, new S57enum(15, "OcFl"));
    605    Litchr.put(LitCHR.CHR_FLFL, new S57enum(16, "FLFl")); Litchr.put(LitCHR.CHR_ALOC, new S57enum(17, "Al.Oc")); Litchr.put(LitCHR.CHR_ALLFL, new S57enum(18, "Al.LFl"));
    606    Litchr.put(LitCHR.CHR_ALFL, new S57enum(19, "Al.Fl")); Litchr.put(LitCHR.CHR_ALGR, new S57enum(20, "Al.Gr")); Litchr.put(LitCHR.CHR_QLFL, new S57enum(25, "Q+LFl"));
    607    Litchr.put(LitCHR.CHR_VQLFL, new S57enum(26, "VQ+LFl")); Litchr.put(LitCHR.CHR_UQLFL, new S57enum(27, "UQ+LFl")); Litchr.put(LitCHR.CHR_AL, new S57enum(28, "Al"));
    608    Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
    609  }
    610  public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
    611  private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static { Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
    612   Litvis.put(LitVIS.LIT_HIGH, new S57enum(1, "high")); Litvis.put(LitVIS.LIT_LOW, new S57enum(2, "low")); Litvis.put(LitVIS.LIT_FANT, new S57enum(3, "faint"));
    613   Litvis.put(LitVIS.LIT_INTS, new S57enum(4, "intensified")); Litvis.put(LitVIS.LIT_UINT, new S57enum(5, "unintensified")); Litvis.put(LitVIS.LIT_RSTR, new S57enum(6, "restricted"));
    614   Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
    615  }
    616  public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
    617  private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static { Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
    618   Marsys.put(MarSYS.SYS_IALA, new S57enum(1, "iala-a")); Marsys.put(MarSYS.SYS_IALB, new S57enum(2, "iala-b")); Marsys.put(MarSYS.SYS_NONE, new S57enum(9, "none"));
    619   Marsys.put(MarSYS.SYS_OTHR, new S57enum(10, "other")); Marsys.put(MarSYS.SYS_CEVN, new S57enum(11, "cevni")); Marsys.put(MarSYS.SYS_RIWR, new S57enum(12, "riwr"));
    620   Marsys.put(MarSYS.SYS_BWR2, new S57enum(13, "bniwr2")); Marsys.put(MarSYS.SYS_BNWR, new S57enum(14, "bniwr")); Marsys.put(MarSYS.SYS_PPWB, new S57enum(15, "ppwbc"));
    621  }
    622  public enum NatCON { CON_UNKN, CON_MSNY, CON_CONC, CON_BDRS, CON_HSRF, CON_USRF, CON_WOOD, CON_METL, CON_GRP, CON_PNTD, CON_FMWK, CON_LATT, CON_GLAS }
    623  private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static { Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
    624   Natcon.put(NatCON.CON_MSNY, new S57enum(1, "masonry")); Natcon.put(NatCON.CON_CONC, new S57enum(2, "concreted")); Natcon.put(NatCON.CON_BDRS, new S57enum(3, "loose_boulders"));
    625   Natcon.put(NatCON.CON_HSRF, new S57enum(4, "hard-surfaced")); Natcon.put(NatCON.CON_USRF, new S57enum(5, "unsurfaced")); Natcon.put(NatCON.CON_WOOD, new S57enum(6, "wooden"));
    626   Natcon.put(NatCON.CON_METL, new S57enum(7, "metal")); Natcon.put(NatCON.CON_GRP, new S57enum(8, "grp")); Natcon.put(NatCON.CON_PNTD, new S57enum(9, "painted"));
    627   Natcon.put(NatCON.CON_FMWK, new S57enum(10, "framework")); Natcon.put(NatCON.CON_LATT, new S57enum(11, "latticed")); Natcon.put(NatCON.CON_GLAS, new S57enum(12, "glass"));
    628  }
    629  public enum NatSUR { SUR_UNKN, SUR_MUD, SUR_CLAY, SUR_SILT, SUR_SAND, SUR_STON, SUR_GRVL, SUR_PBBL, SUR_CBBL, SUR_ROCK, SUR_LAVA, SUR_CORL, SUR_SHEL, SUR_BLDR }
    630  private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static { Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
    631   Natsur.put(NatSUR.SUR_MUD, new S57enum(1, "mud")); Natsur.put(NatSUR.SUR_CLAY, new S57enum(2, "clay")); Natsur.put(NatSUR.SUR_SILT, new S57enum(3, "silt"));
    632   Natsur.put(NatSUR.SUR_SAND, new S57enum(4, "sand")); Natsur.put(NatSUR.SUR_STON, new S57enum(5, "stones")); Natsur.put(NatSUR.SUR_GRVL, new S57enum(6, "gravel"));
    633   Natsur.put(NatSUR.SUR_PBBL, new S57enum(7, "pebbles")); Natsur.put(NatSUR.SUR_CBBL, new S57enum(8, "cobbles")); Natsur.put(NatSUR.SUR_ROCK, new S57enum(9, "rocky"));
    634   Natsur.put(NatSUR.SUR_LAVA, new S57enum(11, "lava")); Natsur.put(NatSUR.SUR_CORL, new S57enum(14, "coral")); Natsur.put(NatSUR.SUR_SHEL, new S57enum(17, "shells"));
    635   Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
    636  }
    637  public enum NatQUA { QUA_UNKN, QUA_FINE, QUA_MEDM, QUA_CORS, QUA_BRKN, QUA_STKY, QUA_SOFT, QUA_STIF, QUA_VCNC, QUA_CALC, QUA_HARD }
    638  private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static { Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
    639   Natqua.put(NatQUA.QUA_FINE, new S57enum(1, "fine")); Natqua.put(NatQUA.QUA_MEDM, new S57enum(2, "medium")); Natqua.put(NatQUA.QUA_CORS, new S57enum(3, "coarse"));
    640   Natqua.put(NatQUA.QUA_BRKN, new S57enum(4, "broken")); Natqua.put(NatQUA.QUA_STKY, new S57enum(5, "sticky")); Natqua.put(NatQUA.QUA_SOFT, new S57enum(6, "soft"));
    641   Natqua.put(NatQUA.QUA_STIF, new S57enum(7, "stiff")); Natqua.put(NatQUA.QUA_VCNC, new S57enum(8, "volcanic")); Natqua.put(NatQUA.QUA_CALC, new S57enum(9, "calcareous"));
    642   Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
    643  }
    644  public enum PrdPRD { PRD_UNKN, PRD_OIL, PRD_GAS, PRD_WATR, PRD_STON, PRD_COAL, PRD_ORE, PRD_CHEM, PRD_DWTR, PRD_MILK, PRD_BXIT, PRD_COKE, PRD_IIGS, PRD_SALT,
    645   PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
    646  private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static { Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
    647   Prodct.put(PrdPRD.PRD_OIL, new S57enum(1, "oil")); Prodct.put(PrdPRD.PRD_GAS, new S57enum(2, "gas")); Prodct.put(PrdPRD.PRD_WATR, new S57enum(3, "water"));
    648   Prodct.put(PrdPRD.PRD_STON, new S57enum(4, "stone")); Prodct.put(PrdPRD.PRD_COAL, new S57enum(5, "coal")); Prodct.put(PrdPRD.PRD_ORE, new S57enum(6, "ore"));
    649   Prodct.put(PrdPRD.PRD_CHEM, new S57enum(7, "chemicals")); Prodct.put(PrdPRD.PRD_DWTR, new S57enum(8, "drinking_water")); Prodct.put(PrdPRD.PRD_MILK, new S57enum(9, "milk"));
    650   Prodct.put(PrdPRD.PRD_BXIT, new S57enum(10, "bauxite")); Prodct.put(PrdPRD.PRD_COKE, new S57enum(11, "coke")); Prodct.put(PrdPRD.PRD_IIGS, new S57enum(12, "iron_ingots"));
    651   Prodct.put(PrdPRD.PRD_SALT, new S57enum(13, "salt")); Prodct.put(PrdPRD.PRD_SAND, new S57enum(14, "sand")); Prodct.put(PrdPRD.PRD_TMBR, new S57enum(15, "timber"));
    652   Prodct.put(PrdPRD.PRD_SDST, new S57enum(16, "sawdust")); Prodct.put(PrdPRD.PRD_SCRP, new S57enum(17, "scrap")); Prodct.put(PrdPRD.PRD_LNA, new S57enum(18, "lng"));
    653   Prodct.put(PrdPRD.PRD_LPA, new S57enum(19, "lpg")); Prodct.put(PrdPRD.PRD_WINE, new S57enum(20, "wine")); Prodct.put(PrdPRD.PRD_CMNT, new S57enum(21, "cement"));
    654   Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
    655  }
    656  public enum QuaSOU { SOU_UNKN, SOU_KNWN, SOU_UKNN, SOU_DFUL, SOU_UNRL, SOU_NBFD, SOU_LKWN, SOU_LUKN, SOU_NSRV, SOU_NCNF, SOU_MANT, SOU_NMNT }
    657  private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static { Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
    658   Quasou.put(QuaSOU.SOU_KNWN, new S57enum(1, "known")); Quasou.put(QuaSOU.SOU_UKNN, new S57enum(2, "unknown")); Quasou.put(QuaSOU.SOU_DFUL, new S57enum(3, "doubtful"));
    659   Quasou.put(QuaSOU.SOU_UNRL, new S57enum(4, "unreliable")); Quasou.put(QuaSOU.SOU_NBFD, new S57enum(5, "no_bottom_found")); Quasou.put(QuaSOU.SOU_LKWN, new S57enum(6, "least_known"));
    660   Quasou.put(QuaSOU.SOU_LUKN, new S57enum(7, "least_unknown")); Quasou.put(QuaSOU.SOU_NSRV, new S57enum(8, "not_surveyed")); Quasou.put(QuaSOU.SOU_NCNF, new S57enum(9, "not_confirmed"));
    661   Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
    662  }
    663  public enum RstRST { RST_UNKN, RST_NANC, RST_RANC, RST_NFSH, RST_RFSH, RST_NTRL, RST_RTRL, RST_NENT, RST_RENT, RST_NDRG, RST_RDRG, RST_NDVG, RST_RDVG, RST_NWAK, RST_TBAV, RST_NCST, RST_NDSC,
    664   RST_RDSC, RST_NEXD, RST_REXD, RST_NDRL, RST_RDRL, RST_NHAR, RST_NLTG, RST_NDRA, RST_NSTP, RST_NLND, RST_RSPD, RST_NOVT, RST_NCOV, RST_NPOV, RST_NBRT, RST_RBRT, RST_NMFT, RST_RMFT, RST_NTRN,
    665   RST_RFWD, RST_RFWW, RST_NSWM  }
    666  private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static { Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
    667   Restrn.put(RstRST.RST_NANC, new S57enum(1, "no_anchoring")); Restrn.put(RstRST.RST_RANC, new S57enum(2, "restricted_anchoring")); Restrn.put(RstRST.RST_NFSH, new S57enum(3, "no_fishing"));
    668   Restrn.put(RstRST.RST_RFSH, new S57enum(4, "restricted_fishing")); Restrn.put(RstRST.RST_NTRL, new S57enum(5, "no_trawling")); Restrn.put(RstRST.RST_RTRL, new S57enum(6, "restricted_trawling"));
    669   Restrn.put(RstRST.RST_NENT, new S57enum(7, "no_entry")); Restrn.put(RstRST.RST_RENT, new S57enum(8, "restricted_entry")); Restrn.put(RstRST.RST_NDRG, new S57enum(9, "no_dredging"));
    670   Restrn.put(RstRST.RST_RDRG, new S57enum(10, "restricted_dredging")); Restrn.put(RstRST.RST_NDVG, new S57enum(11, "no_diving")); Restrn.put(RstRST.RST_RDVG, new S57enum(12, "restricted_diving"));
    671   Restrn.put(RstRST.RST_NWAK, new S57enum(13, "no_wake")); Restrn.put(RstRST.RST_TBAV, new S57enum(14, "to_be_avoided")); Restrn.put(RstRST.RST_NCST, new S57enum(15, "no_construction"));
    672   Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
    673   Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
    674   Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
    675   Restrn.put(RstRST.RST_NHAR, new S57enum(22, "no_historical_artifacts_removal")); Restrn.put(RstRST.RST_NLTG, new S57enum(23, "no_lightering")); Restrn.put(RstRST.RST_NDRA, new S57enum(24, "no_dragging"));
    676    Restrn.put(RstRST.RST_NSTP, new S57enum(25, "no_stopping")); Restrn.put(RstRST.RST_NLND, new S57enum(26, "no_landing")); Restrn.put(RstRST.RST_RSPD, new S57enum(27, "restricted_speed"));
    677    Restrn.put(RstRST.RST_NOVT, new S57enum(28, "no_overtaking")); Restrn.put(RstRST.RST_NCOV, new S57enum(29, "no_convoy_overtaking")); Restrn.put(RstRST.RST_NPOV, new S57enum(30, "no_passing_overtaking"));
    678    Restrn.put(RstRST.RST_NBRT, new S57enum(31, "no_berthing")); Restrn.put(RstRST.RST_RBRT, new S57enum(32, "restricted_berthing")); Restrn.put(RstRST.RST_NMFT, new S57enum(33, "no_making_fast"));
    679    Restrn.put(RstRST.RST_RMFT, new S57enum(34, "restricted_making_fast")); Restrn.put(RstRST.RST_NTRN, new S57enum(35, "no_turning")); Restrn.put(RstRST.RST_RFWD, new S57enum(36, "restricted_fairway_depth"));
    680    Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
    681  }
    682  public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
    683  private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static { Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
    684   Siggen.put(SigGEN.GEN_AUTO, new S57enum(1, "automatic")); Siggen.put(SigGEN.GEN_WAVE, new S57enum(2, "wave")); Siggen.put(SigGEN.GEN_HAND, new S57enum(3, "hand")); Siggen.put(SigGEN.GEN_WIND, new S57enum(4, "wind"));
    685  }
    686  public enum StsSTS { STS_UNKN, STS_PERM, STS_OCAS, STS_RCMD, STS_NIUS, STS_IMTT, STS_RESV, STS_TEMP, STS_PRIV, STS_MAND, STS_EXTD, STS_ILLD, STS_HIST, STS_PBLC,
    687   STS_SYNC, STS_WCHD, STS_UWCD, STS_EDBT, STS_OREQ, STS_DPAW, STS_RSNG, STS_INCR, STS_DECR, TS_STNG, STS_GOOD, STS_MODY, STS_POOR }
    688  private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static { Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
    689   Status.put(StsSTS.STS_PERM, new S57enum(1, "permanent")); Status.put(StsSTS.STS_OCAS, new S57enum(2, "occasional")); Status.put(StsSTS.STS_RCMD, new S57enum(3, "recommended"));
    690   Status.put(StsSTS.STS_NIUS, new S57enum(4, "not_in_use")); Status.put(StsSTS.STS_IMTT, new S57enum(5, "intermittent")); Status.put(StsSTS.STS_RESV, new S57enum(6, "reserved"));
    691   Status.put(StsSTS.STS_TEMP, new S57enum(7, "temporary")); Status.put(StsSTS.STS_PRIV, new S57enum(8, "private")); Status.put(StsSTS.STS_MAND, new S57enum(9, "mandatory"));
    692   Status.put(StsSTS.STS_EXTD, new S57enum(11, "extinguished")); Status.put(StsSTS.STS_ILLD, new S57enum(12, "illuminated")); Status.put(StsSTS.STS_HIST, new S57enum(13, "historic"));
    693   Status.put(StsSTS.STS_PBLC, new S57enum(14, "public")); Status.put(StsSTS.STS_SYNC, new S57enum(15, "synchronised")); Status.put(StsSTS.STS_WCHD, new S57enum(16, "watched"));
    694   Status.put(StsSTS.STS_UWCD, new S57enum(17, "unwatched")); Status.put(StsSTS.STS_EDBT, new S57enum(18, "existence_doubtful")); Status.put(StsSTS.STS_OREQ, new S57enum(19, "on_request"));
    695   Status.put(StsSTS.STS_DPAW, new S57enum(20, "drop_away")); Status.put(StsSTS.STS_RSNG, new S57enum(21, "rising")); Status.put(StsSTS.STS_INCR, new S57enum(22, "increasing"));
    696   Status.put(StsSTS.STS_DECR, new S57enum(23, "decreasing")); Status.put(StsSTS.TS_STNG, new S57enum(24, "strong")); Status.put(StsSTS.STS_GOOD, new S57enum(25, "good"));
    697   Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
    698  }
    699  public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
    700  private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static { Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
    701   Surtyp.put(SurTYP.TYP_SKCH, new S57enum(1, "sketch")); Surtyp.put(SurTYP.TYP_CTLD, new S57enum(2, "controlled")); Surtyp.put(SurTYP.TYP_PSSG, new S57enum(4, "examination"));
    702   Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
    703  }
    704  public enum TecSOU { SOU_UNKN, SOU_ESND, SOU_FSSN, SOU_MLBM, SOU_DIVR, SOU_LDLN, SOU_WDRG, SOU_LASR, SOU_VACC, SOU_EMAG, SOU_PHGY, SOU_SATL, SOU_LEVL, SOU_SSSN, SOU_COMP }
    705  private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static { Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
    706         Tecsou.put(TecSOU.SOU_ESND, new S57enum(1, "echo-sounder")); Tecsou.put(TecSOU.SOU_FSSN, new S57enum(2, "side-scan_sonar")); Tecsou.put(TecSOU.SOU_MLBM, new S57enum(3, "multi-beam"));
    707   Tecsou.put(TecSOU.SOU_DIVR, new S57enum(4, "diver")); Tecsou.put(TecSOU.SOU_LDLN, new S57enum(5, "lead-line")); Tecsou.put(TecSOU.SOU_WDRG, new S57enum(6, "wire-drag"));
    708   Tecsou.put(TecSOU.SOU_LASR, new S57enum(7, "laser")); Tecsou.put(TecSOU.SOU_VACC, new S57enum(8, "vertical_acoustic")); Tecsou.put(TecSOU.SOU_EMAG, new S57enum(9, "electromagnetic"));
    709   Tecsou.put(TecSOU.SOU_PHGY, new S57enum(10, "photogrammetry")); Tecsou.put(TecSOU.SOU_SATL, new S57enum(11, "satellite")); Tecsou.put(TecSOU.SOU_LEVL, new S57enum(12, "levelling"));
    710   Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
    711  }
    712  public enum TopSHP { TOP_UNKN, TOP_CONE, TOP_ICONE, TOP_SPHR, TOP_ISD, TOP_CAN, TOP_BORD, TOP_SALT, TOP_CROS, TOP_CUBE, TOP_WEST, TOP_EAST, TOP_RHOM,
    713    TOP_NORTH, TOP_SOUTH, TOP_BESM, TOP_IBESM, TOP_FLAG, TOP_SPRH, TOP_SQUR, TOP_HRECT, TOP_VRECT, TOP_TRAP, TOP_ITRAP, TOP_TRI, TOP_ITRI, TOP_CIRC,
    714    TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
    715 
    716         private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static { Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
    717                 Topshp.put(TopSHP.TOP_CONE, new S57enum(1, "cone, point up")); Topshp.put(TopSHP.TOP_ICONE, new S57enum(2, "cone, point down")); Topshp.put(TopSHP.TOP_SPHR, new S57enum(3, "sphere"));
    718                 Topshp.put(TopSHP.TOP_ISD, new S57enum(4, "2 spheres")); Topshp.put(TopSHP.TOP_CAN, new S57enum(5, "cylinder")); Topshp.put(TopSHP.TOP_BORD, new S57enum(6, "board"));
    719                 Topshp.put(TopSHP.TOP_SALT, new S57enum(7, "x-shape")); Topshp.put(TopSHP.TOP_CROS, new S57enum(8, "cross")); Topshp.put(TopSHP.TOP_CUBE, new S57enum(9, "cube, point up"));
    720                 Topshp.put(TopSHP.TOP_WEST, new S57enum(10, "2 cones point together")); Topshp.put(TopSHP.TOP_EAST, new S57enum(11, "2 cones base together")); Topshp.put(TopSHP.TOP_RHOM, new S57enum(12, "rhombus"));
    721                 Topshp.put(TopSHP.TOP_NORTH, new S57enum(13, "2 cones up")); Topshp.put(TopSHP.TOP_SOUTH, new S57enum(14, "2 cones down")); Topshp.put(TopSHP.TOP_BESM, new S57enum(15, "besom, point up"));
    722                 Topshp.put(TopSHP.TOP_IBESM, new S57enum(16, "besom, point down")); Topshp.put(TopSHP.TOP_FLAG, new S57enum(17, "flag")); Topshp.put(TopSHP.TOP_SPRH, new S57enum(18, "sphere over rhombus"));
    723                 Topshp.put(TopSHP.TOP_SQUR, new S57enum(19, "square")); Topshp.put(TopSHP.TOP_HRECT, new S57enum(20, "rectangle, horizontal")); Topshp.put(TopSHP.TOP_VRECT, new S57enum(21, "rectangle, vertical"));
    724                 Topshp.put(TopSHP.TOP_TRAP, new S57enum(22, "trapezium, up")); Topshp.put(TopSHP.TOP_ITRAP, new S57enum(23, "trapezium, down")); Topshp.put(TopSHP.TOP_TRI, new S57enum(24, "triangle, point up"));
    725                 Topshp.put(TopSHP.TOP_ITRI, new S57enum(25, "triangle, point down")); Topshp.put(TopSHP.TOP_CIRC, new S57enum(26, "circle")); Topshp.put(TopSHP.TOP_CRSS, new S57enum(27, "2 upright crosses"));
    726                 Topshp.put(TopSHP.TOP_T, new S57enum(28, "t-shape")); Topshp.put(TopSHP.TOP_TRCL, new S57enum(29, "triangle, point up over circle")); Topshp.put(TopSHP.TOP_CRCL, new S57enum(30, "upright cross over circle"));
    727                 Topshp.put(TopSHP.TOP_RHCL, new S57enum(31, "rhombus over circle")); Topshp.put(TopSHP.TOP_CLTR, new S57enum(32, "circle over triangle, point up")); Topshp.put(TopSHP.TOP_OTHR, new S57enum(33, "other"));
    728                 Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
    729         }
    730  public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
    731  private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static { Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
    732   Trafic.put(TrfTRF.TRF_INBD, new S57enum(1, "inbound")); Trafic.put(TrfTRF.TRF_OBND, new S57enum(2, "outbbound")); Trafic.put(TrfTRF.TRF_ONEW, new S57enum(3, "one-way"));
    733   Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
    734  }
    735  public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
    736  private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static { Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
    737   Watlev.put(WatLEV.LEV_PSUB, new S57enum(1, "part-submerged")); Watlev.put(WatLEV.LEV_DRY, new S57enum(2, "dry")); Watlev.put(WatLEV.LEV_SUBM, new S57enum(3, "submerged"));
    738   Watlev.put(WatLEV.LEV_CVRS, new S57enum(4, "covers")); Watlev.put(WatLEV.LEV_AWSH, new S57enum(5, "awash")); Watlev.put(WatLEV.LEV_FLDS, new S57enum(6, "floods"));
    739   Watlev.put(WatLEV.LEV_FLTG, new S57enum(7, "floating")); Watlev.put(WatLEV.LEV_AMWL, new S57enum(8, "above_mwl")); Watlev.put(WatLEV.LEV_BMWL, new S57enum(9, "below_mwl"));
    740  }
    741  public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
    742  private static final EnumMap<Cat_TS, S57enum> Cat_ts = new EnumMap<>(Cat_TS.class); static { Cat_ts.put(Cat_TS.TS_UNKN, new S57enum(0, ""));
    743   Cat_ts.put(Cat_TS.TS_FLOD, new S57enum(1, "flood")); Cat_ts.put(Cat_TS.TS_EBB, new S57enum(2, "ebb")); Cat_ts.put(Cat_TS.TS_OTHR, new S57enum(3, "other"));
    744  }
    745  public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS }
    746  private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static { Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
    747   Punits.put(UniPAU.PAU_MTRS, new S57enum(1, "metres")); Punits.put(UniPAU.PAU_DGRS, new S57enum(2, "degrees")); Punits.put(UniPAU.PAU_MMTR, new S57enum(3, "millimetres"));
    748   Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
    749  }
    750  public enum QuaPOS { POS_UNKN, POS_SRVD, POS_USRV, POS_PSRV, POS_APRX, POS_DBTF, POS_URLB, POS_RSRV, POS_UCNF, POS_ESTM, POS_PRCS, POS_CALC }
    751  private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static { Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
    752   Quapos.put(QuaPOS.POS_SRVD, new S57enum(1, "surveyed")); Quapos.put(QuaPOS.POS_USRV, new S57enum(2, "unsurveyed")); Quapos.put(QuaPOS.POS_PSRV, new S57enum(3, "part-surveyed"));
    753   Quapos.put(QuaPOS.POS_APRX, new S57enum(4, "approximate")); Quapos.put(QuaPOS.POS_DBTF, new S57enum(5, "doubtful")); Quapos.put(QuaPOS.POS_URLB, new S57enum(6, "unreliable"));
    754   Quapos.put(QuaPOS.POS_RSRV, new S57enum(7, "reported_unsurveyd")); Quapos.put(QuaPOS.POS_UCNF, new S57enum(8, "unconfirmed")); Quapos.put(QuaPOS.POS_ESTM, new S57enum(9, "estimated"));
    755   Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
    756  }
    757  public enum VerDAT { DAT_UNKN, DAT_MLWS, DAT_MLLWS, DAT_MSL, DAT_LLW, DAT_MLW, DAT_LLWS, DAT_AMLWS, DAT_ISLW, DAT_LWS, DAT_ALAT, DAT_NLLW, DAT_MLLW, DAT_LW, DAT_AMLW, DAT_AMLLW,
    758   DAT_MHW, DAT_MHWS, DAT_HW, DAT_AMSL, DAT_HWS, DAT_MHHW, DAT_ESLW, DAT_LAT, DAT_LOCAL, DAT_IGLD, DAT_MWL, DAT_LLWLT, DAT_HHWLT, DAT_NHHW, DAT_HAT, DAT_LLWRL, DAT_LHWRL,
    759   DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO }
    760  private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static { Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
    761   Verdat.put(VerDAT.DAT_MLWS, new S57enum(1, "mlws")); Verdat.put(VerDAT.DAT_MLLWS, new S57enum(2, "mllws")); Verdat.put(VerDAT.DAT_MSL, new S57enum(3, "msl"));
    762   Verdat.put(VerDAT.DAT_LLW, new S57enum(4, "llw")); Verdat.put(VerDAT.DAT_MLW, new S57enum(5, "mlw")); Verdat.put(VerDAT.DAT_LLWS, new S57enum(6, "llws"));
    763   Verdat.put(VerDAT.DAT_AMLWS, new S57enum(7, "amlws")); Verdat.put(VerDAT.DAT_ISLW, new S57enum(8, "islw")); Verdat.put(VerDAT.DAT_LWS, new S57enum(9, "lws"));
    764   Verdat.put(VerDAT.DAT_ALAT, new S57enum(10, "alat"));  Verdat.put(VerDAT.DAT_NLLW, new S57enum(11, "nllw")); Verdat.put(VerDAT.DAT_MLLW, new S57enum(12, "mllw"));
    765   Verdat.put(VerDAT.DAT_LW, new S57enum(13, "lw")); Verdat.put(VerDAT.DAT_AMLW, new S57enum(14, "amlw")); Verdat.put(VerDAT.DAT_AMLLW, new S57enum(15, "amllw"));
    766   Verdat.put(VerDAT.DAT_MHW, new S57enum(16, "mhw")); Verdat.put(VerDAT.DAT_MHWS, new S57enum(17, "mhws")); Verdat.put(VerDAT.DAT_HW, new S57enum(18, "hw"));
    767   Verdat.put(VerDAT.DAT_AMSL, new S57enum(19, "amsl")); Verdat.put(VerDAT.DAT_HWS, new S57enum(20, "hws")); Verdat.put(VerDAT.DAT_MHHW, new S57enum(21, "mhhw"));
    768   Verdat.put(VerDAT.DAT_ESLW, new S57enum(22, "eslw")); Verdat.put(VerDAT.DAT_LAT, new S57enum(23, "lat")); Verdat.put(VerDAT.DAT_LOCAL, new S57enum(24, "local"));
    769   Verdat.put(VerDAT.DAT_IGLD, new S57enum(25, "igld1985")); Verdat.put(VerDAT.DAT_MWL, new S57enum(26, "mwl")); Verdat.put(VerDAT.DAT_LLWLT, new S57enum(27, "llwlt"));
    770   Verdat.put(VerDAT.DAT_HHWLT, new S57enum(28, "hhwlt")); Verdat.put(VerDAT.DAT_NHHW, new S57enum(29, "nhhw")); Verdat.put(VerDAT.DAT_HAT, new S57enum(30, "hat"));
    771   Verdat.put(VerDAT.DAT_LLWRL, new S57enum(31, "llwrl")); Verdat.put(VerDAT.DAT_LHWRL, new S57enum(32, "lhwrl")); Verdat.put(VerDAT.DAT_LMWRL, new S57enum(33, "lmwrl"));
    772   Verdat.put(VerDAT.DAT_EHW, new S57enum(34, "ehw_dglw")); Verdat.put(VerDAT.DAT_HSHW, new S57enum(35, "hshw_dhsw")); Verdat.put(VerDAT.DAT_RLWL, new S57enum(36, "rlwl_donau"));
    773   Verdat.put(VerDAT.DAT_HSHWD, new S57enum(37, "hshw_donau")); Verdat.put(VerDAT.DAT_DRLWRL, new S57enum(38, "drlwrl_olr")); Verdat.put(VerDAT.DAT_RPWL, new S57enum(39, "rpwl"));
    774   Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
    775  }
    776  public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
    777  private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static { Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
    778   Addmrk.put(AddMRK.MRK_TOPB, new S57enum(1, "top_board")); Addmrk.put(AddMRK.MRK_BOTB, new S57enum(2, "bottom_board")); Addmrk.put(AddMRK.MRK_RTRI, new S57enum(3, "right_triangle"));
    779   Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
    780  }
    781  public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
    782  private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static { Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
    783  Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
    784  }
    785  public enum CatNMK { NMK_UNKN, NMK_NENT, NMK_CLSA, NMK_NOVK, NMK_NCOV, NMK_NPAS, NMK_NBRT, NMK_NBLL, NMK_NANK, NMK_NMOR, NMK_NTRN, NMK_NWSH,
    786   NMK_NPSL, NMK_NPSR, NMK_NMTC, NMK_NSPC, NMK_NWSK, NMK_NSLC, NMK_NUPC, NMK_NSLB, NMK_NWBK, NMK_NHSC, NMK_NLBG, NMK_MVTL, NMK_MVTR, NMK_MVTP,
    787   NMK_MVTS, NMK_KPTP, NMK_KPTS, NMK_CSTP, NMK_CSTS, NMK_STOP, NMK_SPDL, NMK_SHRN, NMK_KPLO, NMK_GWJN, NMK_GWCS, NMK_MKRC, NMK_LMDP, NMK_LMHR,
    788   NMK_LMWD, NMK_NAVR, NMK_CHDL, NMK_CHDR, NMK_CHTW, NMK_CHOW, NMK_OPTR, NMK_OPTL, NMK_PRTL, NMK_PRTR, NMK_ENTP, NMK_OVHC, NMK_WEIR, NMK_FERN,
    789   NMK_FERI, NMK_BRTP, NMK_BTLL, NMK_BTLS, NMK_BTRL, NMK_BTUP, NMK_BTP1, NMK_BTP2, NMK_BTP3, NMK_BTUN, NMK_BTN1, NMK_BTN2, NMK_BTN3, NMK_BTUM,
    790   NMK_BTU1, NMK_BTU2, NMK_BTU3, NMK_ANKP, NMK_MORP, NMK_VLBT, NMK_TRNA, NMK_SWWC, NMK_SWWR, NMK_SWWL, NMK_WRSA, NMK_WLSA, NMK_WRSL, NMK_WLSR,
    791   NMK_WRAL, NMK_WLAR, NMK_MWWC, NMK_MWWJ, NMK_MWAR, NMK_MWAL, NMK_WARL, NMK_WALR, NMK_PEND, NMK_DWTR, NMK_TELE, NMK_MTCP, NMK_SPCP, NMK_WSKP,
    792   NMK_SLCP, NMK_UPCP, NMK_SLBP, NMK_RADI, NMK_WTBP, NMK_HSCP, NMK_LBGP, NMK_KTPM, NMK_KTSM, NMK_KTMR, NMK_CRTP, NMK_CRTS, NMK_TRBM, NMK_RSPD,
    793   NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
    794  private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static { Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
    795   Catnmk.put(CatNMK.NMK_NENT, new S57enum(1, "no_entry")); Catnmk.put(CatNMK.NMK_CLSA, new S57enum(2, "closed_area")); Catnmk.put(CatNMK.NMK_NOVK, new S57enum(3, "no_overtaking"));
    796   Catnmk.put(CatNMK.NMK_NCOV, new S57enum(4, "no_convoy_overtaking")); Catnmk.put(CatNMK.NMK_NPAS, new S57enum(5, "no_passing")); Catnmk.put(CatNMK.NMK_NBRT, new S57enum(6, "no_berthing"));
    797   Catnmk.put(CatNMK.NMK_NBLL, new S57enum(7, "no_berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_NANK, new S57enum(8, "no_anchoring")); Catnmk.put(CatNMK.NMK_NMOR, new S57enum(9, "no_mooring"));
    798   Catnmk.put(CatNMK.NMK_NTRN, new S57enum(10, "no_turning")); Catnmk.put(CatNMK.NMK_NWSH, new S57enum(11, "no_wash")); Catnmk.put(CatNMK.NMK_NPSL, new S57enum(12, "no_passage_left"));
    799   Catnmk.put(CatNMK.NMK_NPSR, new S57enum(13, "no_passage_right")); Catnmk.put(CatNMK.NMK_NMTC, new S57enum(14, "no_motor_craft")); Catnmk.put(CatNMK.NMK_NSPC, new S57enum(15, "no_sport_craft"));
    800   Catnmk.put(CatNMK.NMK_NWSK, new S57enum(16, "no_waterskiing")); Catnmk.put(CatNMK.NMK_NSLC, new S57enum(17, "no_sailing_craft")); Catnmk.put(CatNMK.NMK_NUPC, new S57enum(18, "no_unpowered_craft"));
    801   Catnmk.put(CatNMK.NMK_NSLB, new S57enum(19, "no_sailboards")); Catnmk.put(CatNMK.NMK_NWBK, new S57enum(20, "no_waterbikes")); Catnmk.put(CatNMK.NMK_NHSC, new S57enum(21, "no_high_speeds"));
    802   Catnmk.put(CatNMK.NMK_NLBG, new S57enum(22, "no_launching_beaching")); Catnmk.put(CatNMK.NMK_MVTL, new S57enum(23, "move_to_left")); Catnmk.put(CatNMK.NMK_MVTR, new S57enum(24, "move_to_right"));
    803   Catnmk.put(CatNMK.NMK_MVTP, new S57enum(25, "move_to_port")); Catnmk.put(CatNMK.NMK_MVTS, new S57enum(26, "move_to_starboard")); Catnmk.put(CatNMK.NMK_KPTP, new S57enum(27, "keep_to_port"));
    804   Catnmk.put(CatNMK.NMK_KPTS, new S57enum(28, "keep_to_starboard")); Catnmk.put(CatNMK.NMK_CSTP, new S57enum(29, "cross_to_port")); Catnmk.put(CatNMK.NMK_CSTS, new S57enum(30, "cross_to_starboard"));
    805   Catnmk.put(CatNMK.NMK_STOP, new S57enum(31, "stop")); Catnmk.put(CatNMK.NMK_SPDL, new S57enum(32, "speed_limit")); Catnmk.put(CatNMK.NMK_SHRN, new S57enum(33, "sound_horn"));
    806   Catnmk.put(CatNMK.NMK_KPLO, new S57enum(34, "keep_lookout")); Catnmk.put(CatNMK.NMK_GWJN, new S57enum(35, "give_way_junction")); Catnmk.put(CatNMK.NMK_GWCS, new S57enum(36, "give_way_crossing"));
    807   Catnmk.put(CatNMK.NMK_MKRC, new S57enum(37, "make_radio_contact")); Catnmk.put(CatNMK.NMK_LMDP, new S57enum(38, "limited_depth")); Catnmk.put(CatNMK.NMK_LMHR, new S57enum(39, "limited_headroom"));
    808   Catnmk.put(CatNMK.NMK_LMWD, new S57enum(40, "limited_width")); Catnmk.put(CatNMK.NMK_NAVR, new S57enum(41, "navigation_restrictions")); Catnmk.put(CatNMK.NMK_CHDL, new S57enum(42, "channel_distance_left"));
    809   Catnmk.put(CatNMK.NMK_CHDR, new S57enum(43, "channel_distance_right")); Catnmk.put(CatNMK.NMK_CHTW, new S57enum(44, "channel_two_way")); Catnmk.put(CatNMK.NMK_CHOW, new S57enum(45, "channel_one_way"));
    810   Catnmk.put(CatNMK.NMK_OPTR, new S57enum(46, "opening_to_right")); Catnmk.put(CatNMK.NMK_OPTL, new S57enum(47, "opening_to_left")); Catnmk.put(CatNMK.NMK_PRTL, new S57enum(48, "proceed_to_left"));
    811   Catnmk.put(CatNMK.NMK_PRTR, new S57enum(49, "proceed_to_right")); Catnmk.put(CatNMK.NMK_ENTP, new S57enum(50, "entry_permitted")); Catnmk.put(CatNMK.NMK_OVHC, new S57enum(51, "overhead_cable"));
    812   Catnmk.put(CatNMK.NMK_WEIR, new S57enum(52, "weir")); Catnmk.put(CatNMK.NMK_FERN, new S57enum(53, "ferry_non_independent"));  Catnmk.put(CatNMK.NMK_FERI, new S57enum(54, "ferry_independent"));
    813   Catnmk.put(CatNMK.NMK_BRTP, new S57enum(55, "berthing_permitted")); Catnmk.put(CatNMK.NMK_BTLL, new S57enum(56, "berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_BTLS, new S57enum(57, "berthing_lateral_limits"));
    814    Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit"));  Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
    815    Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
    816    Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
    817    Catnmk.put(CatNMK.NMK_BTN1, new S57enum(64, "berthing_marked_non-pushing_1")); Catnmk.put(CatNMK.NMK_BTN2, new S57enum(65, "berthing_marked_non-pushing_2"));
    818    Catnmk.put(CatNMK.NMK_BTN3, new S57enum(66, "berthing_marked_non-pushing_3")); Catnmk.put(CatNMK.NMK_BTUM, new S57enum(67, "berthing_unmarked")); Catnmk.put(CatNMK.NMK_BTU1, new S57enum(68, "berthing_marked_1"));
    819    Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
    820    Catnmk.put(CatNMK.NMK_ANKP, new S57enum(71, "anchoring_permitted"));Catnmk.put(CatNMK.NMK_MORP, new S57enum(72, "mooring_permitted")); Catnmk.put(CatNMK.NMK_VLBT, new S57enum(73, "vehicle_loading_berth"));
    821    Catnmk.put(CatNMK.NMK_TRNA, new S57enum(74, "turning_area")); Catnmk.put(CatNMK.NMK_SWWC, new S57enum(75, "secondary_waterway_crossing")); Catnmk.put(CatNMK.NMK_SWWR, new S57enum(76, "secondary_waterway_right"));
    822    Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
    823    Catnmk.put(CatNMK.NMK_WLSA, new S57enum(79, "main_waterway_left_secondary_ahead")); Catnmk.put(CatNMK.NMK_WRSL, new S57enum(80, "main_waterway_right_secondary_left"));
    824    Catnmk.put(CatNMK.NMK_WLSR, new S57enum(81, "main_waterway_left_secondary_right")); Catnmk.put(CatNMK.NMK_WRAL, new S57enum(82, "main_waterway_right_secondary_ahead_left"));
    825    Catnmk.put(CatNMK.NMK_WLAR, new S57enum(83, "main_waterway_left_secondary_ahead_right")); Catnmk.put(CatNMK.NMK_MWWC, new S57enum(84, "main_waterway_crossing"));
    826    Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
    827    Catnmk.put(CatNMK.NMK_MWAL, new S57enum(87, "main_waterway_ahead_left")); Catnmk.put(CatNMK.NMK_WARL, new S57enum(88, "main_waterway_ahead_right_secondary_left"));
    828    Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
    829    Catnmk.put(CatNMK.NMK_DWTR, new S57enum(91, "drinking_water")); Catnmk.put(CatNMK.NMK_TELE, new S57enum(92, "telephone")); Catnmk.put(CatNMK.NMK_MTCP, new S57enum(93, "motor_craft_permitted"));
    830    Catnmk.put(CatNMK.NMK_SPCP, new S57enum(94, "sport_craft_permitted")); Catnmk.put(CatNMK.NMK_WSKP, new S57enum(95, "waterskiing_permitted")); Catnmk.put(CatNMK.NMK_SLCP, new S57enum(96, "sailing_craft_permitted"));
    831    Catnmk.put(CatNMK.NMK_UPCP, new S57enum(97, "unpowered_craft_permitted")); Catnmk.put(CatNMK.NMK_SLBP, new S57enum(98, "sailboards_permitted")); Catnmk.put(CatNMK.NMK_RADI, new S57enum(99, "radio_information"));
    832    Catnmk.put(CatNMK.NMK_WTBP, new S57enum(100, "waterbikes_permitted")); Catnmk.put(CatNMK.NMK_HSCP, new S57enum(101, "high_speeds_permitted")); Catnmk.put(CatNMK.NMK_LBGP, new S57enum(102, "launching_beaching_permitted"));
    833    Catnmk.put(CatNMK.NMK_KTPM, new S57enum(103, "keep_to_port_margin")); Catnmk.put(CatNMK.NMK_KTSM, new S57enum(104, "keep_to_starboard_margin")); Catnmk.put(CatNMK.NMK_KTMR, new S57enum(105, "keep_to_mid-river"));
    834    Catnmk.put(CatNMK.NMK_CRTP, new S57enum(106, "cross_river_to_port")); Catnmk.put(CatNMK.NMK_CRTS, new S57enum(107, "cross_river_to_starboard")); Catnmk.put(CatNMK.NMK_TRBM, new S57enum(108, "traffic_between_margins"));
    835    Catnmk.put(CatNMK.NMK_RSPD, new S57enum(109, "reduce_speed")); Catnmk.put(CatNMK.NMK_WRKP, new S57enum(110, "wreck_pontoon")); Catnmk.put(CatNMK.NMK_PSBS, new S57enum(111, "pass_both_sides"));
    836    Catnmk.put(CatNMK.NMK_NCPS, new S57enum(112, "no_convoy_passing")); Catnmk.put(CatNMK.NMK_NSMC, new S57enum(113, "no_small_craft")); Catnmk.put(CatNMK.NMK_ATTN, new S57enum(114, "attention"));
    837    Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point"));
    838  }
    839  public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
    840  private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static { Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
    841   Clsdng.put(ClsDNG.DNG_1BLU, new S57enum(1, "one_blue")); Clsdng.put(ClsDNG.DNG_2BLU, new S57enum(2, "two_blue")); Clsdng.put(ClsDNG.DNG_3BLU, new S57enum(3, "three_blue"));
    842   Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
    843  }
    844  public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
    845  private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static { Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
    846   Dirimp.put(DirIMP.IMP_UPST, new S57enum(1, "upstream")); Dirimp.put(DirIMP.IMP_DNST, new S57enum(2, "downstream")); Dirimp.put(DirIMP.IMP_LTBK, new S57enum(3, "left_bank"));
    847   Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
    848  }
    849  public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
    850  private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static { Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
    851   Fnctnm.put(FncFNM.FNM_PRHB, new S57enum(1, "prohibition")); Fnctnm.put(FncFNM.FNM_RGLN, new S57enum(2, "regulation")); Fnctnm.put(FncFNM.FNM_RSTN, new S57enum(3, "restriction"));
    852   Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
    853  }
    854  public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
    855  private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static { Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
    856   Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
    857  }
    858  public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS }
    859  private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static { Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
    860   Catbrt.put(CatBRT.BRT_LODG, new S57enum(1, "loading")); Catbrt.put(CatBRT.BRT_ULDG, new S57enum(2, "unloading")); Catbrt.put(CatBRT.BRT_OVNT, new S57enum(3, "overnight_accommodation"));
    861   Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
    862   Catbrt.put(CatBRT.BRT_FLTG, new S57enum(6, "fleeting")); Catbrt.put(CatBRT.BRT_FCLS, new S57enum(7, "first_class")); Catbrt.put(CatBRT.BRT_SCLS, new S57enum(8, "second_class"));
    863  }
    864  public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
    865  private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static { Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
    866   Catbun.put(CatBUN.BUN_DESL, new S57enum(1, "diesel")); Catbun.put(CatBUN.BUN_WATR, new S57enum(2, "water")); Catbun.put(CatBUN.BUN_BLST, new S57enum(3, "ballast"));
    867  }
    868  public enum CatCCL { CCL_UNKN, CCL_SMLV, CCL_PNCH, CCL_CMPB, CCL_DMEB, CCL_RHNB, CCL_1BPT, CCL_2PTL, CCL_2PTW, CCL_4BPT, CCL_6BPT, CCL_NCCL }
    869  private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static { Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
    870   Catccl.put(CatCCL.CCL_SMLV, new S57enum(1, "small_vessels")); Catccl.put(CatCCL.CCL_PNCH, new S57enum(2, "peniche")); Catccl.put(CatCCL.CCL_CMPB, new S57enum(3, "campine_barge"));
    871   Catccl.put(CatCCL.CCL_DMEB, new S57enum(4, "dortmund-ems_barge")); Catccl.put(CatCCL.CCL_RHNB, new S57enum(5, "rhine-herne_barge")); Catccl.put(CatCCL.CCL_1BPT, new S57enum(6, "1-barge_push-tow"));
    872    Catccl.put(CatCCL.CCL_2PTL, new S57enum(7, "2-barge_push-tow_long")); Catccl.put(CatCCL.CCL_2PTW, new S57enum(8, "2-barge_push-tow_wide")); Catccl.put(CatCCL.CCL_4BPT, new S57enum(9, "4-barge_push-tow"));
    873    Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
    874  }
    875  public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR }
    876  private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static { Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
    877   Catcom.put(CatCOM.COM_VTSC, new S57enum(1, "vts_centre")); Catcom.put(CatCOM.COM_VTSS, new S57enum(2, "vts_sector")); Catcom.put(CatCOM.COM_IVSP, new S57enum(3, "ivs_point"));
    878   Catcom.put(CatCOM.COM_MID, new S57enum(4, "mib")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
    879   Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
    880  }
    881  public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
    882  private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static { Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
    883   Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "customs")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
    884   Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
    885  }
    886  public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF }
    887  private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static { Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
    888   Catrfd.put(CatRFD.RFD_CRSD, new S57enum(1, "cargo_residue")); Catrfd.put(CatRFD.RFD_WOIL, new S57enum(2, "waste_oil")); Catrfd.put(CatRFD.RFD_GBWT, new S57enum(3, "grey_black_water"));
    889   Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
    890  }
    891  public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
    892  private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static { Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
    893   Cattml.put(CatTML.TML_PSGR, new S57enum(1, "passenger")); Cattml.put(CatTML.TML_FERY, new S57enum(2, "ferry")); Cattml.put(CatTML.TML_TSPT, new S57enum(3, "transhipment"));
    894   Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
    895  }
    896  public enum TrsTGD { TGD_UNKN, TGD_CONT, TGD_BULK, TGD_OIL, TGD_FUEL, TGD_CHEM, TGD_LIQD, TGD_EXPL, TGD_FISH, TGD_CARS, TGD_GNRL }
    897  private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static { Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
    898   Trshgd.put(TrsTGD.TGD_CONT, new S57enum(1, "containers")); Trshgd.put(TrsTGD.TGD_BULK, new S57enum(2, "bulk")); Trshgd.put(TrsTGD.TGD_OIL, new S57enum(3, "oil"));
    899   Trshgd.put(TrsTGD.TGD_FUEL, new S57enum(4, "fuel")); Trshgd.put(TrsTGD.TGD_CHEM, new S57enum(5, "chemicals")); Trshgd.put(TrsTGD.TGD_LIQD, new S57enum(6, "liquid"));
    900   Trshgd.put(TrsTGD.TGD_EXPL, new S57enum(7, "explosive")); Trshgd.put(TrsTGD.TGD_FISH, new S57enum(8, "fish")); Trshgd.put(TrsTGD.TGD_CARS, new S57enum(9, "cars"));
    901   Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
    902  }
    903  public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI }
    904  private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static { Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
    905   Catgag.put(CatGAG.GAG_STAF, new S57enum(1, "staff")); Catgag.put(CatGAG.GAG_RCRD, new S57enum(2, "recording")); Catgag.put(CatGAG.GAG_RCRA, new S57enum(3, "recording_remote_access"));
    906   Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
    907  }
    908  public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 }
    909  private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static { Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
    910   Reflev.put(RefLEV.LEV_BALT, new S57enum(1, "baltic")); Reflev.put(RefLEV.LEV_ADRC, new S57enum(2, "adriatic")); Reflev.put(RefLEV.LEV_AMSD, new S57enum(3, "amsterdam"));
    911   Reflev.put(RefLEV.LEV_MSL, new S57enum(4, "msl")); Reflev.put(RefLEV.LEV_OTHR, new S57enum(5, "other")); Reflev.put(RefLEV.LEV_NG29, new S57enum(6, "ngvd29"));
    912   Reflev.put(RefLEV.LEV_NA88, new S57enum(7, "navd88")); Reflev.put(RefLEV.LEV_1912, new S57enum(8, "msl1912")); Reflev.put(RefLEV.LEV_1929, new S57enum(9, "msl1929"));
    913  }
    914  public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
    915  private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static { Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
    916   Catvtr.put(CatVTR.VTR_OFFL, new S57enum(1, "official")); Catvtr.put(CatVTR.VTR_PRIV, new S57enum(2, "private")); Catvtr.put(CatVTR.VTR_CARC, new S57enum(3, "car_cranes"));
    917   Catvtr.put(CatVTR.VTR_CARP, new S57enum(4, "car_planks")); Catvtr.put(CatVTR.VTR_PREQ, new S57enum(5, "permission_required")); Catvtr.put(CatVTR.VTR_LGAT, new S57enum(6, "locked_gate"));
    918  }
    919  public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
    920  private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static { Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
    921   Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
    922  }
    923  public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
    924  private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static { Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
    925   Useshp.put(UseSHP.SHP_LINT, new S57enum(1, "liner_trade")); Useshp.put(UseSHP.SHP_OCSH, new S57enum(2, "occasional_professional_shipping")); Useshp.put(UseSHP.SHP_LESR, new S57enum(3, "leisure"));
    926  }
    927  public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR }
    928  private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static { Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
    929   Catexs.put(CatEXS.EXS_LLOK, new S57enum(1, "lift-lock")); Catexs.put(CatEXS.EXS_AQDT, new S57enum(2, "aqueduct")); Catexs.put(CatEXS.EXS_SPLK, new S57enum(3, "sloping_plane_lock"));
    930   Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
    931  }
    932  public enum CatWWM { WWM_UNKN, WWM_WWRT, WWM_WWLT, WWM_WWSP, WWM_CHRT, WWM_CHLT, WWM_CHSP, WWM_CHRB, WWM_CHLB, WWM_CORT, WWM_COLT, WWM_DGRT, WWM_DGLT,
    933   WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR }
    934  private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static { Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
    935   Catwwm.put(CatWWM.WWM_WWRT, new S57enum(1, "waterway_right")); Catwwm.put(CatWWM.WWM_WWLT, new S57enum(2, "waterway_left")); Catwwm.put(CatWWM.WWM_WWSP, new S57enum(3, "waterway_separation"));
    936   Catwwm.put(CatWWM.WWM_CHRT, new S57enum(4, "channel_right")); Catwwm.put(CatWWM.WWM_CHLT, new S57enum(5, "channel_left")); Catwwm.put(CatWWM.WWM_CHSP, new S57enum(6, "channel_separation"));
    937   Catwwm.put(CatWWM.WWM_CHRB, new S57enum(7, "channel_right_bank")); Catwwm.put(CatWWM.WWM_CHLB, new S57enum(8, "channel_left_bank")); Catwwm.put(CatWWM.WWM_CORT, new S57enum(9, "crossover_right"));
    938   Catwwm.put(CatWWM.WWM_COLT, new S57enum(10, "crossover_left")); Catwwm.put(CatWWM.WWM_DGRT, new S57enum(11, "danger_right")); Catwwm.put(CatWWM.WWM_DGLT, new S57enum(12, "danger_left"));
    939   Catwwm.put(CatWWM.WWM_TORT, new S57enum(13, "turnoff_right")); Catwwm.put(CatWWM.WWM_TOLT, new S57enum(14, "turnoff_left")); Catwwm.put(CatWWM.WWM_JNRT, new S57enum(15, "junction_right"));
    940   Catwwm.put(CatWWM.WWM_JNLT, new S57enum(16, "junction_left")); Catwwm.put(CatWWM.WWM_HBRT, new S57enum(17, "harbour_right")); Catwwm.put(CatWWM.WWM_HBLT, new S57enum(18, "harbour_left"));
    941   Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
    942  }
    943  public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
    944  private static final EnumMap<Lg_SPR, S57enum> Lg_spr = new EnumMap<>(Lg_SPR.class); static { Lg_spr.put(Lg_SPR.SPR_UNKN, new S57enum(0, ""));
    945   Lg_spr.put(Lg_SPR.SPR_OTHR, new S57enum(1, "other")); Lg_spr.put(Lg_SPR.SPR_SPOG, new S57enum(2, "speed_over_ground")); Lg_spr.put(Lg_SPR.SPR_SPTW, new S57enum(3, "speed_through_water"));
    946  }
    947  public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
    948  private static final EnumMap<Lg_WDU, S57enum> Lg_wdu = new EnumMap<>(Lg_WDU.class); static { Lg_wdu.put(Lg_WDU.WDU_UNKN, new S57enum(0, ""));
    949   Lg_wdu.put(Lg_WDU.WDU_OTHR, new S57enum(1, "other")); Lg_wdu.put(Lg_WDU.WDU_CUMT, new S57enum(2, "cubic_metres")); Lg_wdu.put(Lg_WDU.WDU_TONS, new S57enum(3, "tonnes"));
    950  }
    951  public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
    952  private static final EnumMap<Lg_REL, S57enum> Lg_rel = new EnumMap<>(Lg_REL.class); static { Lg_rel.put(Lg_REL.REL_UNKN, new S57enum(0, ""));
    953   Lg_rel.put(Lg_REL.REL_OTHR, new S57enum(1, "other")); Lg_rel.put(Lg_REL.REL_USWW, new S57enum(2, "usage_of_waterway")); Lg_rel.put(Lg_REL.REL_CREQ, new S57enum(3, "carriage_of_equipment"));
    954   Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
    955  }
    956  public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD }
    957  private static final EnumMap<Lg_FNC, S57enum> Lg_fnc = new EnumMap<>(Lg_FNC.class); static { Lg_fnc.put(Lg_FNC.FNC_UNKN, new S57enum(0, ""));
    958   Lg_fnc.put(Lg_FNC.FNC_OTHR, new S57enum(1, "other")); Lg_fnc.put(Lg_FNC.FNC_PRHB, new S57enum(2, "prohibited")); Lg_fnc.put(Lg_FNC.FNC_PRHE, new S57enum(3, "prohibited_with_exceptions"));
    959   Lg_fnc.put(Lg_FNC.FNC_PERM, new S57enum(4, "permitted")); Lg_fnc.put(Lg_FNC.FNC_PERE, new S57enum(5, "permitted_with_exceptions")); Lg_fnc.put(Lg_FNC.FNC_RCMD, new S57enum(6, "recommended"));
    960   Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
    961  }
    962  public enum Lc_CSX { CSX_UNKN, CSX_ALL, CSX_OTHR, CSX_NMOT, CSX_CRFT, CSX_VSSL, CSX_ILWW, CSX_SEAG, CSX_MOTR, CSX_MTNK, CSX_MCGO, CSX_CBRG, CSX_TUG, CSX_PSHR, CSX_BARG, CSX_TNKB,
    963   CSX_DMBB, CSX_LGTR, CSX_TNKL, CSX_CGOL, CSX_SBLR, CSX_PSGR, CSX_PSGS, CSX_DAYT, CSX_CABN, CSX_HSPD, CSX_FLEQ, CSX_WSIT, CSX_RCNL, CSX_DNGY, CSX_FEST, CSX_FOBJ }
    964  private static final EnumMap<Lc_CSX, S57enum> Lc_csi = new EnumMap<>(Lc_CSX.class); static { Lc_csi.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
    965   Lc_csi.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_csi.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_csi.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
    966   Lc_csi.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_csi.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_csi.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
    967   Lc_csi.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_csi.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_csi.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
    968   Lc_csi.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_csi.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_csi.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
    969   Lc_csi.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_csi.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_csi.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
    970   Lc_csi.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_csi.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_csi.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
    971   Lc_csi.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_csi.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_csi.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
    972   Lc_csi.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_csi.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_csi.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
    973   Lc_csi.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_csi.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_csi.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
    974   Lc_csi.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_csi.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_csi.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
    975   Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
    976  }
    977  private static final EnumMap<Lc_CSX, S57enum> Lc_cse = new EnumMap<>(Lc_CSX.class); static { Lc_cse.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
    978   Lc_cse.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_cse.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_cse.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
    979   Lc_cse.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_cse.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_cse.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
    980   Lc_cse.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_cse.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_cse.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
    981   Lc_cse.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_cse.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_cse.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
    982   Lc_cse.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_cse.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_cse.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
    983   Lc_cse.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_cse.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_cse.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
    984   Lc_cse.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_cse.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_cse.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
    985   Lc_cse.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_cse.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_cse.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
    986   Lc_cse.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_cse.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_cse.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
    987   Lc_cse.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_cse.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_cse.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
    988   Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
    989  }
    990  public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV }
    991  private static final EnumMap<Lc_ASX, S57enum> Lc_asi = new EnumMap<>(Lc_ASX.class); static { Lc_asi.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
    992   Lc_asi.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_asi.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_asi.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
    993   Lc_asi.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_asi.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_asi.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
    994   Lc_asi.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_asi.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_asi.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
    995  }
    996  private static final EnumMap<Lc_ASX, S57enum> Lc_ase = new EnumMap<>(Lc_ASX.class); static { Lc_ase.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
    997   Lc_ase.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_ase.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_ase.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
    998   Lc_ase.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_ase.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_ase.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
    999   Lc_ase.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_ase.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_ase.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
    1000  }
    1001  public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS }
    1002  private static final EnumMap<Lc_CCX, S57enum> Lc_cci = new EnumMap<>(Lc_CCX.class); static { Lc_cci.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
    1003   Lc_cci.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cci.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cci.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
    1004   Lc_cci.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cci.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cci.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
    1005   Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
    1006  }
    1007  private static final EnumMap<Lc_CCX, S57enum> Lc_cce = new EnumMap<>(Lc_CCX.class); static { Lc_cce.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
    1008   Lc_cce.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cce.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cce.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
    1009   Lc_cce.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cce.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cce.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
    1010   Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
    1011  }
    1012 
    1013  public enum ShpTYP { TYP_UNKN, TYP_CRGO, TYP_CONT, TYP_TNKR, TYP_SAIL, TYP_FISH, TYP_SPPS, TYP_MOWR, TYP_SUBM, TYP_HSPD, TYP_BCAR, TYP_SPLN, TYP_TUGB, TYP_PSGR, TYP_FERY, TYP_BOAT }
    1014  private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static { Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
    1015   Shptyp.put(ShpTYP.TYP_CRGO, new S57enum(1, "cargo")); Shptyp.put(ShpTYP.TYP_CONT, new S57enum(2, "container")); Shptyp.put(ShpTYP.TYP_TNKR, new S57enum(3, "tanker"));
    1016   Shptyp.put(ShpTYP.TYP_SAIL, new S57enum(4, "sailing")); Shptyp.put(ShpTYP.TYP_FISH, new S57enum(5, "fishing")); Shptyp.put(ShpTYP.TYP_SPPS, new S57enum(6, "special_purpose."));
    1017   Shptyp.put(ShpTYP.TYP_MOWR, new S57enum(7, "man_of_war")); Shptyp.put(ShpTYP.TYP_SUBM, new S57enum(8, "submarine")); Shptyp.put(ShpTYP.TYP_HSPD, new S57enum(9, "high-speed"));
    1018   Shptyp.put(ShpTYP.TYP_BCAR, new S57enum(10, "bulk_carrier")); Shptyp.put(ShpTYP.TYP_SPLN, new S57enum(11, "seaplane")); Shptyp.put(ShpTYP.TYP_TUGB, new S57enum(12, "tugboat"));
    1019   Shptyp.put(ShpTYP.TYP_PSGR, new S57enum(13, "passenger")); Shptyp.put(ShpTYP.TYP_FERY, new S57enum(14, "ferry")); Shptyp.put(ShpTYP.TYP_BOAT, new S57enum(15, "boat"));
    1020  }
    1021 
    1022  public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
    1023  private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static { Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
    1024  Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
    1025  }
    1026 
    1027  private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
    1028  static {
    1029   keys.put(Att.UNKATT, new S57key(Conv.A, null)); keys.put(Att.AGENCY, new S57key(Conv.A, null)); keys.put(Att.BCNSHP, new S57key(Conv.E, Bcnshp));
    1030   keys.put(Att.BUISHP, new S57key(Conv.E, Buishp)); keys.put(Att.BOYSHP, new S57key(Conv.E, Boyshp)); keys.put(Att.BURDEP, new S57key(Conv.F, null));
    1031   keys.put(Att.CALSGN, new S57key(Conv.S, null)); keys.put(Att.CATAIR, new S57key(Conv.L, Catair)); keys.put(Att.CATACH, new S57key(Conv.L, Catach));
    1032   keys.put(Att.CATBRG, new S57key(Conv.L, Catbrg)); keys.put(Att.CATBUA, new S57key(Conv.E, Catbua)); keys.put(Att.CATCBL, new S57key(Conv.E, Catcbl));
    1033   keys.put(Att.CATCAN, new S57key(Conv.E, Catcan)); keys.put(Att.CATCAM, new S57key(Conv.E, Catcam)); keys.put(Att.CATCHP, new S57key(Conv.E, Catchp));
    1034   keys.put(Att.CATCOA, new S57key(Conv.E, Catcoa)); keys.put(Att.CATCTR, new S57key(Conv.E, Catctr)); keys.put(Att.CATCON, new S57key(Conv.E, Catcon));
    1035   keys.put(Att.CATCRN, new S57key(Conv.E, Catcrn)); keys.put(Att.CATDAM, new S57key(Conv.E, Catdam)); keys.put(Att.CATDIS, new S57key(Conv.E, Catdis));
    1036   keys.put(Att.CATDOC, new S57key(Conv.E, Catdoc)); keys.put(Att.CATDPG, new S57key(Conv.L, Catdpg)); keys.put(Att.CATFNC, new S57key(Conv.E, Catfnc));
    1037   keys.put(Att.CATFRY, new S57key(Conv.E, Catfry)); keys.put(Att.CATFIF, new S57key(Conv.E, Catfif)); keys.put(Att.CATFOG, new S57key(Conv.E, Catfog));
    1038   keys.put(Att.CATFOR, new S57key(Conv.E, Catfor)); keys.put(Att.CATGAT, new S57key(Conv.E, Catgat)); keys.put(Att.CATHAF, new S57key(Conv.L, Cathaf));
    1039   keys.put(Att.CATHLK, new S57key(Conv.L, Cathlk)); keys.put(Att.CATICE, new S57key(Conv.E, Catice)); keys.put(Att.CATINB, new S57key(Conv.E, Catinb));
    1040   keys.put(Att.CATLND, new S57key(Conv.L, Catlnd)); keys.put(Att.CATLMK, new S57key(Conv.L, Catlmk)); keys.put(Att.CATLAM, new S57key(Conv.E, Catlam));
    1041   keys.put(Att.CATLIT, new S57key(Conv.L, Catlit)); keys.put(Att.CATMFA, new S57key(Conv.E, Catmfa)); keys.put(Att.CATMPA, new S57key(Conv.L, Catmpa));
    1042   keys.put(Att.CATMOR, new S57key(Conv.E, Catmor)); keys.put(Att.CATNAV, new S57key(Conv.E, Catnav)); keys.put(Att.CATOBS, new S57key(Conv.E, Catobs));
    1043   keys.put(Att.CATOFP, new S57key(Conv.L, Catofp)); keys.put(Att.CATOLB, new S57key(Conv.E, Catolb)); keys.put(Att.CATPLE, new S57key(Conv.E, Catple));
    1044   keys.put(Att.CATPIL, new S57key(Conv.E, Catpil)); keys.put(Att.CATPIP, new S57key(Conv.L, Catpip)); keys.put(Att.CATPRA, new S57key(Conv.E, Catpra));
    1045   keys.put(Att.CATPYL, new S57key(Conv.E, Catpyl)); keys.put(Att.CATRAS, new S57key(Conv.E, Catras)); keys.put(Att.CATRTB, new S57key(Conv.E, Catrtb));
    1046   keys.put(Att.CATROS, new S57key(Conv.L, Catros)); keys.put(Att.CATTRK, new S57key(Conv.E, Cattrk)); keys.put(Att.CATRSC, new S57key(Conv.L, Catrsc));
    1047   keys.put(Att.CATREA, new S57key(Conv.L, Catrea)); keys.put(Att.CATROD, new S57key(Conv.E, Catrod)); keys.put(Att.CATRUN, new S57key(Conv.E, Catrun));
    1048   keys.put(Att.CATSEA, new S57key(Conv.E, Catsea)); keys.put(Att.CATSIL, new S57key(Conv.E, Catsil)); keys.put(Att.CATSLO, new S57key(Conv.E, Catslo));
    1049   keys.put(Att.CATSCF, new S57key(Conv.L, Catscf)); keys.put(Att.CATSLC, new S57key(Conv.E, Catslc)); keys.put(Att.CATSIT, new S57key(Conv.L, Catsit));
    1050   keys.put(Att.CATSIW, new S57key(Conv.L, Catsiw)); keys.put(Att.CATSPM, new S57key(Conv.L, Catspm)); keys.put(Att.CATTSS, new S57key(Conv.E, Cattss));
    1051   keys.put(Att.CATVEG, new S57key(Conv.L, Catveg)); keys.put(Att.CATWAT, new S57key(Conv.E, Catwat)); keys.put(Att.CATWED, new S57key(Conv.E, Catwed));
    1052   keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
    1053   keys.put(Att.COLPAT, new S57key(Conv.L, Colpat)); keys.put(Att.COMCHA, new S57key(Conv.A, null)); keys.put(Att.CPDATE, new S57key(Conv.A, null));
    1054   keys.put(Att.CSCALE, new S57key(Conv.I, null)); keys.put(Att.CONDTN, new S57key(Conv.E, Condtn)); keys.put(Att.CONRAD, new S57key(Conv.E, Conrad));
    1055   keys.put(Att.CONVIS, new S57key(Conv.E, Convis)); keys.put(Att.CURVEL, new S57key(Conv.F, null)); keys.put(Att.DATEND, new S57key(Conv.A, null));
    1056   keys.put(Att.DATSTA, new S57key(Conv.A, null)); keys.put(Att.DRVAL1, new S57key(Conv.F, null)); keys.put(Att.DRVAL2, new S57key(Conv.F, null));
    1057   keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
    1058   keys.put(Att.EXCLIT, new S57key(Conv.E, Exclit)); keys.put(Att.EXPSOU, new S57key(Conv.E, Expsou)); keys.put(Att.FUNCTN, new S57key(Conv.L, Functn));
    1059   keys.put(Att.HEIGHT, new S57key(Conv.F, null)); keys.put(Att.HUNITS, new S57key(Conv.E, Hunits)); keys.put(Att.HORACC, new S57key(Conv.F, null));
    1060   keys.put(Att.HORCLR, new S57key(Conv.F, null)); keys.put(Att.HORLEN, new S57key(Conv.F, null)); keys.put(Att.HORWID, new S57key(Conv.F, null));
    1061   keys.put(Att.ICEFAC, new S57key(Conv.F, null)); keys.put(Att.INFORM, new S57key(Conv.S, null)); keys.put(Att.JRSDTN, new S57key(Conv.E, Jrsdtn));
    1062   keys.put(Att.LIFCAP, new S57key(Conv.F, null)); keys.put(Att.LITCHR, new S57key(Conv.E, Litchr)); keys.put(Att.LITVIS, new S57key(Conv.L, Litvis));
    1063   keys.put(Att.MARSYS, new S57key(Conv.E, Marsys)); keys.put(Att.MLTYLT, new S57key(Conv.I, null)); keys.put(Att.NATION, new S57key(Conv.A, null));
    1064   keys.put(Att.NATCON, new S57key(Conv.L, Natcon)); keys.put(Att.NATSUR, new S57key(Conv.L, Natsur)); keys.put(Att.NATQUA, new S57key(Conv.L, Natqua));
    1065   keys.put(Att.NMDATE, new S57key(Conv.A, null)); keys.put(Att.OBJNAM, new S57key(Conv.S, null)); keys.put(Att.ORIENT, new S57key(Conv.F, null));
    1066   keys.put(Att.PEREND, new S57key(Conv.A, null)); keys.put(Att.PERSTA, new S57key(Conv.A, null)); keys.put(Att.PICREP, new S57key(Conv.S, null));
    1067   keys.put(Att.PILDST, new S57key(Conv.S, null)); keys.put(Att.PRCTRY, new S57key(Conv.A, null)); keys.put(Att.PRODCT, new S57key(Conv.L, Prodct));
    1068   keys.put(Att.PUBREF, new S57key(Conv.S, null)); keys.put(Att.QUASOU, new S57key(Conv.L, Quasou)); keys.put(Att.RADWAL, new S57key(Conv.A, null));
    1069   keys.put(Att.RADIUS, new S57key(Conv.F, null));
    1070   keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
    1071   keys.put(Att.SCAMIN, new S57key(Conv.I, null)); keys.put(Att.SCVAL1, new S57key(Conv.I, null)); keys.put(Att.SCVAL2, new S57key(Conv.I, null));
    1072   keys.put(Att.SECTR1, new S57key(Conv.F, null)); keys.put(Att.SECTR2, new S57key(Conv.F, null)); keys.put(Att.SHIPAM, new S57key(Conv.A, null));
    1073   keys.put(Att.SIGFRQ, new S57key(Conv.I, null)); keys.put(Att.SIGGEN, new S57key(Conv.E, Siggen)); keys.put(Att.SIGGRP, new S57key(Conv.A, null));
    1074   keys.put(Att.SIGPER, new S57key(Conv.F, null)); keys.put(Att.SIGSEQ, new S57key(Conv.A, null)); keys.put(Att.SOUACC, new S57key(Conv.F, null));
    1075   keys.put(Att.SDISMX, new S57key(Conv.I, null)); keys.put(Att.SDISMN, new S57key(Conv.I, null)); keys.put(Att.SORDAT, new S57key(Conv.A, null));
    1076   keys.put(Att.SORIND, new S57key(Conv.A, null)); keys.put(Att.STATUS, new S57key(Conv.L, Status)); keys.put(Att.SURATH, new S57key(Conv.S, null));
    1077   keys.put(Att.SUREND, new S57key(Conv.A, null)); keys.put(Att.SURSTA, new S57key(Conv.A, null)); keys.put(Att.SURTYP, new S57key(Conv.L, Surtyp));
    1078   keys.put(Att.TECSOU, new S57key(Conv.L, Tecsou)); keys.put(Att.TXTDSC, new S57key(Conv.S, null)); keys.put(Att.TS_TSP, new S57key(Conv.A, null));
    1079   keys.put(Att.TS_TSV, new S57key(Conv.A, null)); keys.put(Att.T_ACWL, new S57key(Conv.E, null)); keys.put(Att.T_HWLW, new S57key(Conv.A, null));
    1080   keys.put(Att.T_MTOD, new S57key(Conv.E, null)); keys.put(Att.T_THDF, new S57key(Conv.A, null)); keys.put(Att.T_TINT, new S57key(Conv.I, null));
    1081   keys.put(Att.T_TSVL, new S57key(Conv.A, null)); keys.put(Att.T_VAHC, new S57key(Conv.A, null)); keys.put(Att.TIMEND, new S57key(Conv.A, null));
    1082   keys.put(Att.TIMSTA, new S57key(Conv.A, null)); keys.put(Att.TOPSHP, new S57key(Conv.E, Topshp)); keys.put(Att.TRAFIC, new S57key(Conv.E, Trafic));
    1083   keys.put(Att.VALACM, new S57key(Conv.F, null)); keys.put(Att.VALDCO, new S57key(Conv.F, null)); keys.put(Att.VALLMA, new S57key(Conv.F, null));
    1084   keys.put(Att.VALMAG, new S57key(Conv.F, null)); keys.put(Att.VALMXR, new S57key(Conv.F, null)); keys.put(Att.VALNMR, new S57key(Conv.F, null));
    1085   keys.put(Att.VALSOU, new S57key(Conv.F, null)); keys.put(Att.VERACC, new S57key(Conv.F, null)); keys.put(Att.VERCLR, new S57key(Conv.F, null));
    1086   keys.put(Att.VERCCL, new S57key(Conv.F, null)); keys.put(Att.VERCOP, new S57key(Conv.F, null)); keys.put(Att.VERCSA, new S57key(Conv.F, null));
    1087   keys.put(Att.VERDAT, new S57key(Conv.E, Verdat)); keys.put(Att.VERLEN, new S57key(Conv.F, null)); keys.put(Att.WATLEV, new S57key(Conv.E, Watlev));
    1088   keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
    1089   keys.put(Att.NOBJNM, new S57key(Conv.S, null)); keys.put(Att.NPLDST, new S57key(Conv.S, null)); keys.put(Att.NTXTDS, new S57key(Conv.S, null));
    1090   keys.put(Att.HORDAT, new S57key(Conv.E, null)); keys.put(Att.POSACC, new S57key(Conv.F, null)); keys.put(Att.QUAPOS, new S57key(Conv.E, Quapos));
    1091   keys.put(Att.CLSDNG, new S57key(Conv.E, Clsdng)); keys.put(Att.DIRIMP, new S57key(Conv.L, Dirimp)); keys.put(Att.DISBK1, new S57key(Conv.F, null));
    1092   keys.put(Att.DISBK2, new S57key(Conv.F, null)); keys.put(Att.DISIPU, new S57key(Conv.F, null)); keys.put(Att.DISIPD, new S57key(Conv.F, null));
    1093   keys.put(Att.ELEVA1, new S57key(Conv.F, null)); keys.put(Att.ELEVA2, new S57key(Conv.F, null)); keys.put(Att.FNCTNM, new S57key(Conv.E, Fnctnm));
    1094   keys.put(Att.WTWDIS, new S57key(Conv.F, null)); keys.put(Att.BUNVES, new S57key(Conv.E, Bunves)); keys.put(Att.COMCTN, new S57key(Conv.S, null));
    1095   keys.put(Att.HORCLL, new S57key(Conv.F, null)); keys.put(Att.HORCLW, new S57key(Conv.F, null)); keys.put(Att.TRSHGD, new S57key(Conv.L, Trshgd));
    1096   keys.put(Att.UNLOCD, new S57key(Conv.S, null)); keys.put(Att.HIGWAT, new S57key(Conv.F, null)); keys.put(Att.HIGNAM, new S57key(Conv.S, null));
    1097   keys.put(Att.LOWWAT, new S57key(Conv.F, null)); keys.put(Att.LOWNAM, new S57key(Conv.S, null)); keys.put(Att.MEAWAT, new S57key(Conv.F, null));
    1098   keys.put(Att.MEANAM, new S57key(Conv.S, null)); keys.put(Att.OTHWAT, new S57key(Conv.F, null)); keys.put(Att.OTHNAM, new S57key(Conv.S, null));
    1099   keys.put(Att.REFLEV, new S57key(Conv.E, Reflev)); keys.put(Att.SDRLEV, new S57key(Conv.S, null)); keys.put(Att.VCRLEV, new S57key(Conv.S, null));
    1100   keys.put(Att.SCHREF, new S57key(Conv.S, null)); keys.put(Att.USESHP, new S57key(Conv.E, Useshp)); keys.put(Att.CURVHW, new S57key(Conv.F, null));
    1101   keys.put(Att.CURVLW, new S57key(Conv.F, null)); keys.put(Att.CURVMW, new S57key(Conv.F, null)); keys.put(Att.CURVOW, new S57key(Conv.F, null));
    1102   keys.put(Att.APTREF, new S57key(Conv.S, null)); keys.put(Att.SHPTYP, new S57key(Conv.E, Shptyp)); keys.put(Att.UPDMSG, new S57key(Conv.S, null));
    1103   keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
    1104   keys.put(Att.CATNMK, new S57key(Conv.E, Catnmk)); keys.put(Att.CATBRT, new S57key(Conv.L, Catbrt)); keys.put(Att.CATBUN, new S57key(Conv.L, Catbun));
    1105   keys.put(Att.CATCCL, new S57key(Conv.L, Catccl)); keys.put(Att.CATCOM, new S57key(Conv.L, Catcom)); keys.put(Att.CATHBR, new S57key(Conv.L, Cathbr));
    1106   keys.put(Att.CATRFD, new S57key(Conv.L, Catrfd)); keys.put(Att.CATTML, new S57key(Conv.L, Cattml)); keys.put(Att.CATGAG, new S57key(Conv.L, Catgag));
    1107   keys.put(Att.CATVTR, new S57key(Conv.L, Catvtr)); keys.put(Att.CATTAB, new S57key(Conv.E, Cattab)); keys.put(Att.CATEXS, new S57key(Conv.E, Catexs));
    1108   keys.put(Att.LG_SPD, new S57key(Conv.F, null)); keys.put(Att.LG_SPR, new S57key(Conv.L, Lg_spr)); keys.put(Att.LG_BME, new S57key(Conv.F, null));
    1109   keys.put(Att.LG_LGS, new S57key(Conv.F, null)); keys.put(Att.LG_DRT, new S57key(Conv.F, null)); keys.put(Att.LG_WDP, new S57key(Conv.F, null));
    1110   keys.put(Att.LG_WDU, new S57key(Conv.E, Lg_wdu)); keys.put(Att.LG_REL, new S57key(Conv.L, Lg_rel)); keys.put(Att.LG_FNC, new S57key(Conv.L, Lg_fnc));
    1111   keys.put(Att.LG_DES, new S57key(Conv.S, null)); keys.put(Att.LG_PBR, new S57key(Conv.S, null)); keys.put(Att.LC_CSI, new S57key(Conv.L, Lc_csi));
    1112   keys.put(Att.LC_CSE, new S57key(Conv.L, Lc_cse)); keys.put(Att.LC_ASI, new S57key(Conv.L, Lc_asi)); keys.put(Att.LC_ASE, new S57key(Conv.L, Lc_ase));
    1113   keys.put(Att.LC_CCI, new S57key(Conv.L, Lc_cci)); keys.put(Att.LC_CCE, new S57key(Conv.L, Lc_cce)); keys.put(Att.LC_BM1, new S57key(Conv.F, null));
    1114   keys.put(Att.LC_BM2, new S57key(Conv.F, null)); keys.put(Att.LC_LG1, new S57key(Conv.F, null)); keys.put(Att.LC_LG2, new S57key(Conv.F, null));
    1115   keys.put(Att.LC_DR1, new S57key(Conv.F, null)); keys.put(Att.LC_DR2, new S57key(Conv.F, null)); keys.put(Att.LC_SP1, new S57key(Conv.F, null));
    1116   keys.put(Att.LC_SP2, new S57key(Conv.F, null)); keys.put(Att.LC_WD1, new S57key(Conv.F, null)); keys.put(Att.LC_WD2, new S57key(Conv.F, null));
    1117   keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
    1118  }
    1119  
    1120  public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
    1121   EnumMap<?, ?> map = keys.get(att).map;
    1122   Enum<?> unkn = null;
    1123   int i = 0;
    1124   try {
    1125    i = Integer.parseInt(val);
    1126   } catch (Exception e) {
    1127    return unkn;
    1128   }
    1129   if (map != null) {
    1130    for (Object item : map.keySet()) {
    1131     if (unkn == null)
    1132      unkn = (Enum<?>) item;
    1133     if (((S57enum) map.get(item)).atvl.equals(i))
    1134      return (Enum<?>) item;
    1135    }
    1136   }
    1137   return unkn;
    1138  }
    1139 
    1140  public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
    1141   Conv conv = keys.get(att).conv;
    1142   switch (conv) {
    1143   case A:
    1144   case S:
    1145    return new AttVal<>(conv, val);
    1146   case E:
    1147    ArrayList<Enum<?>> list = new ArrayList<>();
    1148    list.add(s57Enum(val, att));
    1149    return new AttVal<ArrayList<?>>(Conv.E, list);
    1150   case L:
    1151    list = new ArrayList<>();
    1152    for (String item : val.split(",")) {
    1153     list.add(s57Enum(item, att));
    1154    }
    1155    return new AttVal<ArrayList<?>>(Conv.L, list);
    1156   case I:
    1157    try {
    1158     return new AttVal<>(Conv.I, Long.parseLong(val));
    1159    } catch (Exception e) {
    1160     break;
    1161    }
    1162   case F:
    1163    try {
    1164     return new AttVal<>(Conv.F, Double.parseDouble(val));
    1165    } catch (Exception e) {
    1166     break;
    1167    }
    1168   }
    1169   return null;
    1170  }
    1171 
    1172  public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
    1173           if (attval != null) {
    1174                 String str = stringValue(attval, att);
    1175                 if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
    1176                         String[] vals = str.split(";");
    1177                         str = "";
    1178                         for (String val : vals) {
    1179                                 if (!str.isEmpty()) str += ",";
    1180                                 EnumMap<?, ?> map = keys.get(att).map;
    1181                                 for (Object item : map.keySet()) {
    1182                                         if (((S57enum)map.get(item)).val.equals(val))
    1183                         str += ((S57enum)map.get(item)).atvl.toString();
    1184                       }
    1185                         }
    1186                 }
    1187                 return str;
    1188           }
    1189   return "";
    1190  }
    1191 
    1192  public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
    1193   if (attval != null) {
    1194    switch (attval.conv) {
    1195    case A:
    1196    case S:
    1197     return (String) attval.val;
    1198    case E:
    1199     EnumMap<?, ?> map = keys.get(att).map;
    1200     return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
    1201    case L:
    1202     String str = "";
    1203     map = keys.get(att).map;
    1204     for (Object item : (ArrayList<?>) attval.val) {
    1205      if (!str.isEmpty())
    1206       str += ";";
    1207      if (item != null)
    1208       str += ((S57enum) map.get(item)).val;
    1209     }
    1210     return str;
    1211    case I:
    1212     return ((Long) attval.val).toString();
    1213    case F:
    1214     return ((Double) attval.val).toString();
    1215    }
    1216   }
    1217   return "";
    1218  }
    1219 
    1220  public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
    1221   EnumMap<?, ?> map = keys.get(att).map;
    1222   Enum<?> unkn = null;
    1223   if (map != null) {
    1224    for (Object item : map.keySet()) {
    1225     if (unkn == null)
    1226      unkn = (Enum<?>) item;
    1227     if (((S57enum) map.get(item)).val.equals(val))
    1228      return (Enum<?>) item;
    1229    }
    1230   }
    1231   return unkn;
    1232  }
    1233 
    1234  public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
    1235   switch (keys.get(att).conv) {
    1236   case A:
    1237   case S:
    1238    return new AttVal<>(Conv.S, val);
    1239   case E:
    1240    ArrayList<Enum<?>> list = new ArrayList<>();
    1241    list.add(osmEnum(val, att));
    1242    return new AttVal<ArrayList<?>>(Conv.E, list);
    1243   case L:
    1244    list = new ArrayList<>();
    1245    for (String item : val.split(";")) {
    1246     list.add(osmEnum(item, att));
    1247    }
    1248    return new AttVal<ArrayList<?>>(Conv.L, list);
    1249   case I:
    1250    try {
    1251     return new AttVal<>(Conv.I, Long.parseLong(val));
    1252    } catch (Exception e) {
    1253     break;
    1254    }
    1255   case F:
    1256    try {
    1257     return new AttVal<>(Conv.F, Double.parseDouble(val));
    1258    } catch (Exception e) {
    1259     break;
    1260    }
    1261   }
    1262   return new AttVal<>(keys.get(att).conv, null);
    1263  }
    1264  
    1265  public static Enum<?> unknAtt(Att att) {
    1266   return (Enum<?>)(keys.get(att).map.keySet().toArray()[0]);
    1267  }
    1268 
     18    // CHECKSTYLE.OFF: LineLength
     19
     20    static class S57enum {
     21        Integer atvl;
     22        String val;
     23        S57enum(Integer a, String v) {
     24            atvl = a; val = v;
     25        }
     26    }
     27
     28    public enum Conv { S, A, L, E, F, I }
     29
     30    static class S57key {
     31        Conv conv;
     32        EnumMap<?, ?> map;
     33        S57key(Conv c, EnumMap<?, S57enum> m) {
     34            conv = c; map = m;
     35        }
     36    }
     37
     38    public static class AttVal<V> {
     39        public Conv conv;
     40        public V val;
     41        AttVal(Conv c, V v) {
     42            conv = c; val = v;
     43        }
     44    }
     45
     46    public enum BcnSHP { BCN_UNKN, BCN_STAK, BCN_WTHY, BCN_TOWR, BCN_LATT, BCN_PILE, BCN_CARN, BCN_BUOY, BCN_POLE, BCN_PRCH, BCN_POST }
     47
     48    private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class);
     49    static {
     50        Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
     51        Bcnshp.put(BcnSHP.BCN_STAK, new S57enum(1, "stake")); Bcnshp.put(BcnSHP.BCN_WTHY, new S57enum(2, "withy")); Bcnshp.put(BcnSHP.BCN_TOWR, new S57enum(3, "tower"));
     52        Bcnshp.put(BcnSHP.BCN_LATT, new S57enum(4, "lattice")); Bcnshp.put(BcnSHP.BCN_PILE, new S57enum(5, "pile")); Bcnshp.put(BcnSHP.BCN_CARN, new S57enum(6, "cairn"));
     53        Bcnshp.put(BcnSHP.BCN_BUOY, new S57enum(7, "buoyant")); Bcnshp.put(BcnSHP.BCN_POLE, new S57enum(1, "pole")); Bcnshp.put(BcnSHP.BCN_PRCH, new S57enum(1, "perch"));
     54        Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
     55    }
     56
     57    public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
     58
     59    private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class);
     60    static {
     61        Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
     62        Buishp.put(BuiSHP.BUI_HIRS, new S57enum(5, "high-rise")); Buishp.put(BuiSHP.BUI_PYRD, new S57enum(6, "pyramid")); Buishp.put(BuiSHP.BUI_CYLR, new S57enum(7, "cylindrical"));
     63        Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
     64    }
     65
     66    public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
     67
     68    private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class);
     69    static {
     70        Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
     71        Boyshp.put(BoySHP.BOY_CONE, new S57enum(1, "conical")); Boyshp.put(BoySHP.BOY_CAN, new S57enum(2, "can")); Boyshp.put(BoySHP.BOY_SPHR, new S57enum(3, "spherical"));
     72        Boyshp.put(BoySHP.BOY_PILR, new S57enum(4, "pillar")); Boyshp.put(BoySHP.BOY_SPAR, new S57enum(5, "spar")); Boyshp.put(BoySHP.BOY_BARL, new S57enum(6, "barrel"));
     73        Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
     74    }
     75
     76    public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
     77
     78    private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class);
     79    static {
     80        Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
     81        Catair.put(CatAIR.AIR_MILA, new S57enum(1, "military")); Catair.put(CatAIR.AIR_CIVA, new S57enum(2, "civil")); Catair.put(CatAIR.AIR_MILH, new S57enum(3, "military_heliport"));
     82        Catair.put(CatAIR.AIR_CIVH, new S57enum(4, "civil_heliport")); Catair.put(CatAIR.AIR_GLDR, new S57enum(5, "glider")); Catair.put(CatAIR.AIR_SMLP, new S57enum(6, "small_planes"));
     83        Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
     84    }
     85
     86    public enum CatACH { ACH_UNKN, ACH_UNRD, ACH_DEEP, ACH_TANK, ACH_EXPL, ACH_QUAR, ACH_SEAP, ACH_SMCF, ACH_SMCM, ACH_H24P, ACH_LTPD, ACH_NPSH, ACH_DRYC, ACH_RAFT, ACH_WAIT, ACH_REPT }
     87
     88    private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class);
     89    static {
     90        Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
     91        Catach.put(CatACH.ACH_UNRD, new S57enum(1, "unrestricted")); Catach.put(CatACH.ACH_DEEP, new S57enum(2, "deep_water")); Catach.put(CatACH.ACH_TANK, new S57enum(3, "tanker"));
     92        Catach.put(CatACH.ACH_EXPL, new S57enum(4, "explosives")); Catach.put(CatACH.ACH_QUAR, new S57enum(5, "quarantine")); Catach.put(CatACH.ACH_SEAP, new S57enum(6, "seaplane"));
     93        Catach.put(CatACH.ACH_SMCF, new S57enum(7, "small_craft")); Catach.put(CatACH.ACH_SMCM, new S57enum(8, "small_craft_mooring")); Catach.put(CatACH.ACH_H24P, new S57enum(9, "24_hour"));
     94        Catach.put(CatACH.ACH_LTPD, new S57enum(10, "limited_period")); Catach.put(CatACH.ACH_NPSH, new S57enum(11, "non_pushing")); Catach.put(CatACH.ACH_DRYC, new S57enum(12, "dry_cargo"));
     95        Catach.put(CatACH.ACH_RAFT, new S57enum(13, "raft")); Catach.put(CatACH.ACH_WAIT, new S57enum(14, "waiting")); Catach.put(CatACH.ACH_REPT, new S57enum(15, "reported"));
     96    }
     97
     98    public enum CatBRG { BRG_UNKN, BRG_FIXD, BRG_OPEN, BRG_SWNG, BRG_LIFT, BRG_BASC, BRG_PONT, BRG_DRAW, BRG_TRNS, BRG_FOOT, BRG_VIAD, BRG_AQUA, BRG_SUSP }
     99
     100    private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {
     101        Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
     102        Catbrg.put(CatBRG.BRG_FIXD, new S57enum(1, "fixed")); Catbrg.put(CatBRG.BRG_OPEN, new S57enum(2, "opening")); Catbrg.put(CatBRG.BRG_SWNG, new S57enum(3, "swing"));
     103        Catbrg.put(CatBRG.BRG_LIFT, new S57enum(4, "lifting")); Catbrg.put(CatBRG.BRG_BASC, new S57enum(5, "bascule")); Catbrg.put(CatBRG.BRG_PONT, new S57enum(6, "pontoon"));
     104        Catbrg.put(CatBRG.BRG_DRAW, new S57enum(7, "drawbridge")); Catbrg.put(CatBRG.BRG_TRNS, new S57enum(8, "transporter")); Catbrg.put(CatBRG.BRG_FOOT, new S57enum(9, "footbridge"));
     105        Catbrg.put(CatBRG.BRG_VIAD, new S57enum(10, "viaduct")); Catbrg.put(CatBRG.BRG_AQUA, new S57enum(11, "aqueduct")); Catbrg.put(CatBRG.BRG_SUSP, new S57enum(12, "suspension"));
     106    }
     107
     108    public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
     109
     110    private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static {
     111        Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
     112        Catbua.put(CatBUA.BUA_URBN, new S57enum(1, "urban")); Catbua.put(CatBUA.BUA_STTL, new S57enum(2, "settlement")); Catbua.put(CatBUA.BUA_VLLG, new S57enum(3, "village"));
     113        Catbua.put(CatBUA.BUA_TOWN, new S57enum(4, "town")); Catbua.put(CatBUA.BUA_CITY, new S57enum(5, "city")); Catbua.put(CatBUA.BUA_HOLV, new S57enum(6, "holiday_village"));
     114    }
     115
     116    public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY }
     117
     118    private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {
     119        Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
     120        Catcbl.put(CatCBL.CBL_POWR, new S57enum(1, "power")); Catcbl.put(CatCBL.CBL_TRNS, new S57enum(3, "transmission")); Catcbl.put(CatCBL.CBL_TELE, new S57enum(4, "telephone"));
     121        Catcbl.put(CatCBL.CBL_TGPH, new S57enum(5, "telegraph")); Catcbl.put(CatCBL.CBL_MOOR, new S57enum(6, "mooring")); Catcbl.put(CatCBL.CBL_OPTC, new S57enum(7, "optical"));
     122        Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
     123    }
     124
     125    public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
     126
     127    private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static {
     128        Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
     129        Catcan.put(CatCAN.CAN_TRNS, new S57enum(1, "transportation")); Catcan.put(CatCAN.CAN_DRNG, new S57enum(2, "drainage")); Catcan.put(CatCAN.CAN_IRGN, new S57enum(3, "irrigation"));
     130    }
     131
     132    public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
     133
     134    private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static {
     135        Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
     136        Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
     137        Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
     138    }
     139
     140    public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
     141
     142    private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static {
     143        Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
     144        Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
     145    }
     146
     147    public enum CatCOA { COA_UNKN, COA_STEP, COA_FLAT, COA_SAND, COA_STON, COA_SHNG, COA_GLCR, COA_MNGV, COA_MRSH, COA_CRRF, COA_ICE, COA_SHEL }
     148
     149    private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static {
     150        Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
     151        Catcoa.put(CatCOA.COA_STEP, new S57enum(1, "steep")); Catcoa.put(CatCOA.COA_FLAT, new S57enum(2, "flat")); Catcoa.put(CatCOA.COA_SAND, new S57enum(3, "sandy"));
     152        Catcoa.put(CatCOA.COA_STON, new S57enum(4, "stony")); Catcoa.put(CatCOA.COA_SHNG, new S57enum(5, "shingly")); Catcoa.put(CatCOA.COA_GLCR, new S57enum(6, "glacier"));
     153        Catcoa.put(CatCOA.COA_MNGV, new S57enum(7, "mangrove")); Catcoa.put(CatCOA.COA_MRSH, new S57enum(8, "marshy")); Catcoa.put(CatCOA.COA_CRRF, new S57enum(9, "coral_reef"));
     154        Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
     155    }
     156
     157    public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS }
     158
     159    private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static {
     160        Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
     161        Catctr.put(CatCTR.CTR_TRGN, new S57enum(1, "triangulation")); Catctr.put(CatCTR.CTR_OBSV, new S57enum(2, "observation")); Catctr.put(CatCTR.CTR_FIXD, new S57enum(3, "fixed"));
     162        Catctr.put(CatCTR.CTR_BMRK, new S57enum(4, "benchmark")); Catctr.put(CatCTR.CTR_BDRY, new S57enum(5, "boundary")); Catctr.put(CatCTR.CTR_HORM, new S57enum(6, "horizontal_main"));
     163        Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
     164    }
     165
     166    public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
     167
     168    private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static {
     169        Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
     170        Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
     171    }
     172
     173    public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH }
     174
     175    private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static {
     176        Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
     177        Catcrn.put(CatCRN.CRN_NONS, new S57enum(1, "non-specific")); Catcrn.put(CatCRN.CRN_CONT, new S57enum(2, "container")); Catcrn.put(CatCRN.CRN_SHRL, new S57enum(3, "sheerlegs"));
     178        Catcrn.put(CatCRN.CRN_TRAV, new S57enum(4, "travelling")); Catcrn.put(CatCRN.CRN_AFRM, new S57enum(5, "a-frame")); Catcrn.put(CatCRN.CRN_GLTH, new S57enum(6, "goliath"));
     179    }
     180
     181    public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
     182
     183    private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static {
     184        Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
     185        Catdam.put(CatDAM.DAM_WEIR, new S57enum(1, "weir")); Catdam.put(CatDAM.DAM_DAM, new S57enum(2, "dam")); Catdam.put(CatDAM.DAM_FLDB, new S57enum(3, "flood_barrage"));
     186    }
     187
     188    public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
     189
     190    private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static {
     191        Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
     192        Catdis.put(CatDIS.DIS_NONI, new S57enum(1, "not_installed")); Catdis.put(CatDIS.DIS_POLE, new S57enum(2, "pole")); Catdis.put(CatDIS.DIS_BORD, new S57enum(3, "board"));
     193        Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
     194    }
     195
     196    public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
     197
     198    private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static {
     199        Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
     200        Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
     201    }
     202
     203    public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL }
     204
     205    private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static {
     206        Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
     207        Catdpg.put(CatDPG.DPG_GENL, new S57enum(1, "general")); Catdpg.put(CatDPG.DPG_CHEM, new S57enum(2, "chemical")); Catdpg.put(CatDPG.DPG_NCLR, new S57enum(3, "nuclear"));
     208        Catdpg.put(CatDPG.DPG_EXPL, new S57enum(4, "explosives")); Catdpg.put(CatDPG.DPG_SPIL, new S57enum(5, "spoil")); Catdpg.put(CatDPG.DPG_VSSL, new S57enum(6, "vessel"));
     209    }
     210
     211    public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
     212
     213    private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static {
     214        Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
     215        Catfnc.put(CatFNC.FNC_FENC, new S57enum(1, "fence")); Catfnc.put(CatFNC.FNC_MUIR, new S57enum(2, "muir")); Catfnc.put(CatFNC.FNC_HEDG, new S57enum(3, "hedge"));
     216        Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
     217    }
     218
     219    public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR }
     220
     221    private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static {
     222        Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
     223        Catfry.put(CatFRY.FRY_FREE, new S57enum(1, "free")); Catfry.put(CatFRY.FRY_CABL, new S57enum(2, "cable")); Catfry.put(CatFRY.FRY_ICE, new S57enum(3, "ice"));
     224        Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
     225    }
     226
     227    public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY }
     228
     229    private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static {
     230        Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
     231        Catfif.put(CatFIF.FIF_STAK, new S57enum(1, "stake")); Catfif.put(CatFIF.FIF_TRAP, new S57enum(2, "trap")); Catfif.put(CatFIF.FIF_WEIR, new S57enum(3, "weir"));
     232        Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
     233    }
     234
     235    public enum CatFOG { FOG_UNKN, FOG_EXPL, FOG_DIA, FOG_SIRN, FOG_NAUT, FOG_REED, FOG_TYPH, FOG_BELL, FOG_WHIS, FOG_GONG, FOG_HORN }
     236
     237    private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {
     238        Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
     239        Catfog.put(CatFOG.FOG_EXPL, new S57enum(1, "explosive")); Catfog.put(CatFOG.FOG_DIA, new S57enum(2, "diaphone")); Catfog.put(CatFOG.FOG_SIRN, new S57enum(3, "siren"));
     240        Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
     241        Catfog.put(CatFOG.FOG_TYPH, new S57enum(6, "tyfon")); Catfog.put(CatFOG.FOG_BELL, new S57enum(7, "bell")); Catfog.put(CatFOG.FOG_WHIS, new S57enum(8, "whistle"));
     242        Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
     243    }
     244
     245    public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT }
     246
     247    private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static {
     248        Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
     249        Catfor.put(CatFOR.FOR_CSTL, new S57enum(1, "castle")); Catfor.put(CatFOR.FOR_FORT, new S57enum(2, "fort")); Catfor.put(CatFOR.FOR_BTTY, new S57enum(3, "battery"));
     250        Catfor.put(CatFOR.FOR_BKHS, new S57enum(4, "blockhouse")); Catfor.put(CatFOR.FOR_MTWR, new S57enum(5, "martello_tower")); Catfor.put(CatFOR.FOR_RDBT, new S57enum(6, "redoubt"));
     251    }
     252
     253    public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC }
     254
     255    private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static {
     256        Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
     257        Catgat.put(CatGAT.GAT_GNRL, new S57enum(1, "general")); Catgat.put(CatGAT.GAT_FLBG, new S57enum(2, "flood_barrage")); Catgat.put(CatGAT.GAT_CSSN, new S57enum(3, "caisson"));
     258        Catgat.put(CatGAT.GAT_LOCK, new S57enum(4, "lock")); Catgat.put(CatGAT.GAT_DYKE, new S57enum(5, "dyke")); Catgat.put(CatGAT.GAT_SLUC, new S57enum(6, "sluice"));
     259    }
     260
     261    public enum CatHAF { HAF_UNKN, HAF_RORO, HAF_TMBR, HAF_FERY, HAF_FISH, HAF_MRNA, HAF_NAVL, HAF_TNKR, HAF_PSGR, HAF_YARD, HAF_CNTR, HAF_BULK, HAF_SYNC, HAF_STCR, HAF_LUVB,
     262        HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF }
     263
     264    private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static {
     265        Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
     266        Cathaf.put(CatHAF.HAF_RORO, new S57enum(1, "roro")); Cathaf.put(CatHAF.HAF_FERY, new S57enum(3, "ferry")); Cathaf.put(CatHAF.HAF_FISH, new S57enum(4, "fishing"));
     267        Cathaf.put(CatHAF.HAF_MRNA, new S57enum(5, "marina")); Cathaf.put(CatHAF.HAF_NAVL, new S57enum(6, "naval")); Cathaf.put(CatHAF.HAF_TNKR, new S57enum(7, "tanker"));
     268        Cathaf.put(CatHAF.HAF_PSGR, new S57enum(8, "passenger")); Cathaf.put(CatHAF.HAF_YARD, new S57enum(9, "shipyard")); Cathaf.put(CatHAF.HAF_CNTR, new S57enum(10, "container"));
     269        Cathaf.put(CatHAF.HAF_BULK, new S57enum(11, "bulk")); Cathaf.put(CatHAF.HAF_SYNC, new S57enum(12, "syncrolift")); Cathaf.put(CatHAF.HAF_STCR, new S57enum(13, "straddle_carrier"));
     270        Cathaf.put(CatHAF.HAF_LUVB, new S57enum(14, "lay_up")); Cathaf.put(CatHAF.HAF_TMBR, new S57enum(15, "timber")); Cathaf.put(CatHAF.HAF_REPR, new S57enum(16, "service_repair"));
     271        Cathaf.put(CatHAF.HAF_QUAR, new S57enum(17, "quarantine")); Cathaf.put(CatHAF.HAF_SPLN, new S57enum(18, "seaplane")); Cathaf.put(CatHAF.HAF_CARG, new S57enum(19, "cargo"));
     272        Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support")); Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
     273        Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
     274    }
     275
     276    public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO }
     277
     278    private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static {
     279        Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
     280        Cathlk.put(CatHLK.HLK_REST, new S57enum(1, "floating_restaurant")); Cathlk.put(CatHLK.HLK_HIST, new S57enum(2, "historic")); Cathlk.put(CatHLK.HLK_MUSM, new S57enum(3, "museum"));
     281        Cathlk.put(CatHLK.HLK_ACCM, new S57enum(4, "accommodation")); Cathlk.put(CatHLK.HLK_BWTR, new S57enum(5, "floating_breakwater")); Cathlk.put(CatHLK.HLK_CSNO, new S57enum(6, "casino_boat"));
     282    }
     283
     284    public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR }
     285
     286    private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static {
     287        Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
     288        Catice.put(CatICE.ICE_FAST, new S57enum(1, "fast")); Catice.put(CatICE.ICE_SEA, new S57enum(2, "sea")); Catice.put(CatICE.ICE_GRLR, new S57enum(3, "growler"));
     289        Catice.put(CatICE.ICE_PANK, new S57enum(4, "pancake")); Catice.put(CatICE.ICE_GLAS, new S57enum(5, "glacier")); Catice.put(CatICE.ICE_PEAK, new S57enum(6, "peak"));
     290        Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
     291    }
     292
     293    public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
     294
     295    private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static {
     296        Catinb.put(CatINB.INB_UNKN, new S57enum(0, "")); Catinb.put(CatINB.INB_CALM, new S57enum(1, "calm")); Catinb.put(CatINB.INB_SBM, new S57enum(2, "sbm"));
     297    }
     298
     299    public enum CatLND { LND_UNKN, LND_FEN, LND_MRSH, LND_BOG, LND_HTHL, LND_MNTN, LND_LOWL, LND_CNYN, LND_PDDY, LND_AGRI, LND_SVNA, LND_PARK, LND_SWMP, LND_LSLD, LND_LAVA,
     300        LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
     301
     302    private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static {
     303        Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
     304        Catlnd.put(CatLND.LND_FEN, new S57enum(1, "fen")); Catlnd.put(CatLND.LND_MRSH, new S57enum(2, "marsh")); Catlnd.put(CatLND.LND_BOG, new S57enum(3, "bog"));
     305        Catlnd.put(CatLND.LND_HTHL, new S57enum(4, "heathland")); Catlnd.put(CatLND.LND_MNTN, new S57enum(5, "mountain")); Catlnd.put(CatLND.LND_LOWL, new S57enum(6, "lowlands"));
     306        Catlnd.put(CatLND.LND_CNYN, new S57enum(7, "canyon")); Catlnd.put(CatLND.LND_PDDY, new S57enum(8, "paddy")); Catlnd.put(CatLND.LND_AGRI, new S57enum(9, "agricultural"));
     307        Catlnd.put(CatLND.LND_SVNA, new S57enum(10, "savanna")); Catlnd.put(CatLND.LND_PARK, new S57enum(11, "parkland")); Catlnd.put(CatLND.LND_SWMP, new S57enum(12, "swamp"));
     308        Catlnd.put(CatLND.LND_LSLD, new S57enum(13, "landslide")); Catlnd.put(CatLND.LND_LAVA, new S57enum(14, "lava")); Catlnd.put(CatLND.LND_SLTP, new S57enum(15, "salt_pan"));
     309        Catlnd.put(CatLND.LND_MORN, new S57enum(16, "moraine")); Catlnd.put(CatLND.LND_CRTR, new S57enum(17, "crater")); Catlnd.put(CatLND.LND_CAVE, new S57enum(18, "cave"));
     310        Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
     311    }
     312
     313    public enum CatLMK { LMK_UNKN, LMK_CARN, LMK_CMTY, LMK_CHMY, LMK_DISH, LMK_FLAG, LMK_FLAR, LMK_MAST, LMK_WNDS, LMK_MNMT, LMK_CLMN, LMK_MEML, LMK_OBLK, LMK_STAT, LMK_CROS,
     314        LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
     315
     316    private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {
     317        Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
     318        Catlmk.put(CatLMK.LMK_CARN, new S57enum(1, "cairn")); Catlmk.put(CatLMK.LMK_CMTY, new S57enum(2, "cemetery")); Catlmk.put(CatLMK.LMK_CHMY, new S57enum(3, "chimney"));
     319        Catlmk.put(CatLMK.LMK_DISH, new S57enum(4, "dish_aerial")); Catlmk.put(CatLMK.LMK_FLAG, new S57enum(5, "flagstaff")); Catlmk.put(CatLMK.LMK_FLAR, new S57enum(6, "flare_stack"));
     320        Catlmk.put(CatLMK.LMK_MAST, new S57enum(7, "mast")); Catlmk.put(CatLMK.LMK_WNDS, new S57enum(8, "windsock")); Catlmk.put(CatLMK.LMK_MNMT, new S57enum(9, "monument"));
     321        Catlmk.put(CatLMK.LMK_CLMN, new S57enum(10, "column")); Catlmk.put(CatLMK.LMK_MEML, new S57enum(11, "memorial")); Catlmk.put(CatLMK.LMK_OBLK, new S57enum(12, "obelisk"));
     322        Catlmk.put(CatLMK.LMK_STAT, new S57enum(13, "statue")); Catlmk.put(CatLMK.LMK_CROS, new S57enum(14, "cross")); Catlmk.put(CatLMK.LMK_DOME, new S57enum(15, "dome"));
     323        Catlmk.put(CatLMK.LMK_RADR, new S57enum(16, "radar_scanner")); Catlmk.put(CatLMK.LMK_TOWR, new S57enum(17, "tower")); Catlmk.put(CatLMK.LMK_WNDM, new S57enum(18, "windmill"));
     324        Catlmk.put(CatLMK.LMK_WNDG, new S57enum(19, "windmotor")); Catlmk.put(CatLMK.LMK_SPIR, new S57enum(20, "spire")); Catlmk.put(CatLMK.LMK_BLDR, new S57enum(21, "boulder"));
     325        Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
     326        Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
     327    }
     328
     329    public enum CatLAM { LAM_UNKN, LAM_PORT, LAM_STBD, LAM_PCST, LAM_PCPT, LAM_WWLT, LAM_WWRT, LAM_CHLT, LAM_CHRT, LAM_WWSN, LAM_CHSN, LAM_CHRB, LAM_CHLB, LAM_CRRT, LAM_CRLT,
     330        LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP }
     331
     332    private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static {
     333        Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
     334        Catlam.put(CatLAM.LAM_PORT, new S57enum(1, "port")); Catlam.put(CatLAM.LAM_STBD, new S57enum(2, "starboard")); Catlam.put(CatLAM.LAM_PCST, new S57enum(3, "preferred_channel_starboard"));
     335        Catlam.put(CatLAM.LAM_PCPT, new S57enum(4, "preferred_channel_port")); Catlam.put(CatLAM.LAM_WWRT, new S57enum(5, "waterway_right")); Catlam.put(CatLAM.LAM_WWLT, new S57enum(6, "waterway_left"));
     336        Catlam.put(CatLAM.LAM_CHRT, new S57enum(7, "channel_right")); Catlam.put(CatLAM.LAM_CHLT, new S57enum(8, "channel_left")); Catlam.put(CatLAM.LAM_WWSN, new S57enum(9, "waterway_separation"));
     337        Catlam.put(CatLAM.LAM_CHSN, new S57enum(10, "channel_separation")); Catlam.put(CatLAM.LAM_CHRB, new S57enum(11, "channel_right_bank")); Catlam.put(CatLAM.LAM_CHLB, new S57enum(12, "channel_left_bank"));
     338        Catlam.put(CatLAM.LAM_CRRT, new S57enum(13, "crossover_right")); Catlam.put(CatLAM.LAM_CRLT, new S57enum(14, "crossover_left")); Catlam.put(CatLAM.LAM_DRLT, new S57enum(15, "danger_right"));
     339        Catlam.put(CatLAM.LAM_DRRT, new S57enum(16, "danger_left")); Catlam.put(CatLAM.LAM_TOLT, new S57enum(17, "turnoff_right")); Catlam.put(CatLAM.LAM_TPRT, new S57enum(18, "turnoff_left"));
     340        Catlam.put(CatLAM.LAM_JBRT, new S57enum(19, "junction_right")); Catlam.put(CatLAM.LAM_JNLT, new S57enum(20, "junction_left")); Catlam.put(CatLAM.LAM_HBRT, new S57enum(21, "harbour_right"));
     341        Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
     342    }
     343
     344    public enum CatLIT { LIT_UNKN, LIT_DIR, LIT_LEAD, LIT_AERO, LIT_AIR, LIT_FOG, LIT_FLDL, LIT_STRP, LIT_SUBS, LIT_SPOT, LIT_FRNT, LIT_REAR, LIT_LOWR, LIT_UPPR, LIT_MOIR, LIT_EMRG, LIT_BRNG, LIT_HORI, LIT_VERT }
     345
     346    private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static {
     347        Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
     348        Catlit.put(CatLIT.LIT_DIR, new S57enum(1, "directional")); Catlit.put(CatLIT.LIT_LEAD, new S57enum(4, "leading")); Catlit.put(CatLIT.LIT_AERO, new S57enum(5, "aero"));
     349        Catlit.put(CatLIT.LIT_AIR, new S57enum(6, "air_obstruction")); Catlit.put(CatLIT.LIT_FOG, new S57enum(7, "fog_detector")); Catlit.put(CatLIT.LIT_FLDL, new S57enum(8, "floodlight"));
     350        Catlit.put(CatLIT.LIT_STRP, new S57enum(9, "strip_light")); Catlit.put(CatLIT.LIT_SUBS, new S57enum(10, "subsidiary")); Catlit.put(CatLIT.LIT_SPOT, new S57enum(11, "spotlight"));
     351        Catlit.put(CatLIT.LIT_FRNT, new S57enum(12, "front")); Catlit.put(CatLIT.LIT_REAR, new S57enum(13, "rear")); Catlit.put(CatLIT.LIT_LOWR, new S57enum(14, "lower"));
     352        Catlit.put(CatLIT.LIT_UPPR, new S57enum(15, "upper")); Catlit.put(CatLIT.LIT_MOIR, new S57enum(16, "moire")); Catlit.put(CatLIT.LIT_EMRG, new S57enum(17, "emergency"));
     353        Catlit.put(CatLIT.LIT_BRNG, new S57enum(18, "bearing")); Catlit.put(CatLIT.LIT_HORI, new S57enum(19, "horizontal")); Catlit.put(CatLIT.LIT_VERT, new S57enum(20, "vertical"));
     354    }
     355
     356    public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
     357
     358    private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static {
     359        Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
     360        Catmfa.put(CatMFA.MFA_CRST, new S57enum(1, "crustaceans")); Catmfa.put(CatMFA.MFA_OYMS, new S57enum(2, "oysters_mussels")); Catmfa.put(CatMFA.MFA_FISH, new S57enum(3, "fish"));
     361        Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
     362    }
     363
     364    public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA }
     365
     366    private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static {
     367        Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
     368        Catmpa.put(CatMPA.MPA_PRCT, new S57enum(1, "practice")); Catmpa.put(CatMPA.MPA_TRPD, new S57enum(2, "torpedo")); Catmpa.put(CatMPA.MPA_SUBM, new S57enum(3, "submarine"));
     369        Catmpa.put(CatMPA.MPA_FIRG, new S57enum(4, "firing")); Catmpa.put(CatMPA.MPA_MINL, new S57enum(5, "mine-laying")); Catmpa.put(CatMPA.MPA_SMLA, new S57enum(6, "small_arms"));
     370    }
     371
     372    public enum CatMOR { MOR_UNKN, MOR_DLPN, MOR_DDPN, MOR_BLRD, MOR_WALL, MOR_PILE, MOR_CHAN, MOR_BUOY, MOR_SHRP, MOR_AUTO, MOR_POST, MOR_WIRE, MOR_CABL }
     373
     374    private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static {
     375        Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
     376        Catmor.put(CatMOR.MOR_DLPN, new S57enum(1, "dolphin")); Catmor.put(CatMOR.MOR_DDPN, new S57enum(2, "deviation_dolphin")); Catmor.put(CatMOR.MOR_BLRD, new S57enum(3, "bollard"));
     377        Catmor.put(CatMOR.MOR_WALL, new S57enum(4, "wall")); Catmor.put(CatMOR.MOR_PILE, new S57enum(5, "pile")); Catmor.put(CatMOR.MOR_CHAN, new S57enum(6, "chain"));
     378        Catmor.put(CatMOR.MOR_BUOY, new S57enum(7, "buoy")); Catmor.put(CatMOR.MOR_SHRP, new S57enum(8, "shore_ropes")); Catmor.put(CatMOR.MOR_AUTO, new S57enum(9, "automatic"));
     379        Catmor.put(CatMOR.MOR_POST, new S57enum(10, "post")); Catmor.put(CatMOR.MOR_WIRE, new S57enum(11, "wire")); Catmor.put(CatMOR.MOR_CABL, new S57enum(12, "cable"));
     380    }
     381
     382    public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
     383
     384    private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static {
     385        Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
     386        Catnav.put(CatNAV.NAV_CLRG, new S57enum(1, "clearing")); Catnav.put(CatNAV.NAV_TRST, new S57enum(2, "transit")); Catnav.put(CatNAV.NAV_LDNG, new S57enum(3, "leading"));
     387    }
     388
     389    public enum CatOBS { OBS_UNKN, OBS_STMP, OBS_WELH, OBS_DIFF, OBS_CRIB, OBS_FHVN, OBS_FLAR, OBS_FLGD, OBS_ICEB, OBS_GTKL, OBS_BOOM, OBS_UWTB, OBS_TPLT, OBS_WEND, OBS_UWAS,
     390        OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII }
     391
     392    private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static {
     393        Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
     394        Catobs.put(CatOBS.OBS_STMP, new S57enum(1, "stump")); Catobs.put(CatOBS.OBS_WELH, new S57enum(2, "wellhead")); Catobs.put(CatOBS.OBS_DIFF, new S57enum(3, "diffuser"));
     395        Catobs.put(CatOBS.OBS_CRIB, new S57enum(4, "crib")); Catobs.put(CatOBS.OBS_FHVN, new S57enum(5, "fish_haven")); Catobs.put(CatOBS.OBS_FLAR, new S57enum(6, "foul_area"));
     396        Catobs.put(CatOBS.OBS_FLGD, new S57enum(7, "foul_ground")); Catobs.put(CatOBS.OBS_ICEB, new S57enum(8, "ice_boom")); Catobs.put(CatOBS.OBS_GTKL, new S57enum(9, "ground_tackle"));
     397        Catobs.put(CatOBS.OBS_BOOM, new S57enum(10, "boom")); Catobs.put(CatOBS.OBS_UWTB, new S57enum(11, "underwater_turbine")); Catobs.put(CatOBS.OBS_TPLT, new S57enum(12, "template"));
     398        Catobs.put(CatOBS.OBS_WEND, new S57enum(13, "wave_energy_device")); Catobs.put(CatOBS.OBS_UWAS, new S57enum(14, "subsurface_data")); Catobs.put(CatOBS.OBS_REEF, new S57enum(15, "artificial_reef"));
     399        Catobs.put(CatOBS.OBS_MNFD, new S57enum(16, "manifold")); Catobs.put(CatOBS.OBS_PNGO, new S57enum(17, "submerged_pingo")); Catobs.put(CatOBS.OBS_RPLT, new S57enum(18, "platform_remains"));
     400        Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
     401    }
     402
     403    public enum CatOFP { OFP_UNKN, OFP_OIL, OFP_PROD, OFP_OBS, OFP_ALP, OFP_SALM, OFP_MOOR, OFP_AISL, OFP_FPSO, OFP_ACCN, OFP_NCCB, OFP_FOTK }
     404
     405    private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static {
     406        Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
     407        Catofp.put(CatOFP.OFP_OIL, new S57enum(1, "oil")); Catofp.put(CatOFP.OFP_PROD, new S57enum(2, "production")); Catofp.put(CatOFP.OFP_OBS, new S57enum(3, "observation"));
     408        Catofp.put(CatOFP.OFP_ALP, new S57enum(4, "alp")); Catofp.put(CatOFP.OFP_SALM, new S57enum(5, "salm")); Catofp.put(CatOFP.OFP_MOOR, new S57enum(6, "mooring"));
     409        Catofp.put(CatOFP.OFP_AISL, new S57enum(7, "artificial_island")); Catofp.put(CatOFP.OFP_FPSO, new S57enum(8, "fpso")); Catofp.put(CatOFP.OFP_ACCN, new S57enum(9, "accommodation"));
     410        Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
     411    }
     412
     413    public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
     414
     415    private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static {
     416        Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
     417        Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
     418    }
     419
     420    public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
     421
     422    private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static {
     423        Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
     424        Catple.put(CatPLE.PLE_STAK, new S57enum(1, "stake")); Catple.put(CatPLE.PLE_POST, new S57enum(3, "post")); Catple.put(CatPLE.PLE_TRIP, new S57enum(4, "tripodal"));
     425        Catple.put(CatPLE.PLE_PLNG, new S57enum(5, "piling")); Catple.put(CatPLE.PLE_PARE, new S57enum(6, "pile_area")); Catple.put(CatPLE.PLE_PIPE, new S57enum(7, "pipe"));
     426    }
     427
     428    public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
     429
     430    private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static {
     431        Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
     432        Catpil.put(CatPIL.PIL_CVSL, new S57enum(1, "cruising_vessel")); Catpil.put(CatPIL.PIL_HELI, new S57enum(2, "helicopter")); Catpil.put(CatPIL.PIL_SHOR, new S57enum(3, "from_shore"));
     433    }
     434
     435    public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
     436
     437    private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static {
     438        Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
     439        Catpip.put(CatPIP.PIP_OFAL, new S57enum(2, "outfall")); Catpip.put(CatPIP.PIP_ITAK, new S57enum(3, "intake")); Catpip.put(CatPIP.PIP_SEWR, new S57enum(4, "sewer"));
     440        Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
     441    }
     442
     443    public enum CatPRA { PRA_UNKN, PRA_QRRY, PRA_MINE, PRA_STPL, PRA_PSTN, PRA_RFNY, PRA_TYRD, PRA_FACT, PRA_TFRM, PRA_WFRM, PRA_SLAG, PRA_CURF, PRA_OILF, PRA_GASF, PRA_WAVE }
     444
     445    private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static {
     446        Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
     447        Catpra.put(CatPRA.PRA_QRRY, new S57enum(1, "quarry")); Catpra.put(CatPRA.PRA_MINE, new S57enum(2, "mine")); Catpra.put(CatPRA.PRA_STPL, new S57enum(3, "stockpile"));
     448        Catpra.put(CatPRA.PRA_PSTN, new S57enum(4, "power_station")); Catpra.put(CatPRA.PRA_RFNY, new S57enum(5, "refinery")); Catpra.put(CatPRA.PRA_TYRD, new S57enum(6, "timber_yard"));
     449        Catpra.put(CatPRA.PRA_FACT, new S57enum(7, "factory")); Catpra.put(CatPRA.PRA_TFRM, new S57enum(8, "tank_farm")); Catpra.put(CatPRA.PRA_WFRM, new S57enum(9, "wind_farm"));
     450        Catpra.put(CatPRA.PRA_SLAG, new S57enum(10, "slag_heap")); Catpra.put(CatPRA.PRA_CURF, new S57enum(11, "current_farm")); Catpra.put(CatPRA.PRA_OILF, new S57enum(12, "oil"));
     451        Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
     452    }
     453
     454    public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER }
     455
     456    private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static {
     457        Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
     458        Catpyl.put(CatPYL.PYL_POWR, new S57enum(1, "power")); Catpyl.put(CatPYL.PYL_TELE, new S57enum(2, "telecom")); Catpyl.put(CatPYL.PYL_AERL, new S57enum(3, "aerial"));
     459        Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
     460    }
     461
     462    public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
     463
     464    private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static {
     465        Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
     466        Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
     467    }
     468
     469    public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
     470
     471    private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {
     472        Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
     473        Catrtb.put(CatRTB.RTB_RAMK, new S57enum(1, "ramark")); Catrtb.put(CatRTB.RTB_RACN, new S57enum(2, "racon")); Catrtb.put(CatRTB.RTB_LDG, new S57enum(3, "leading"));
     474    }
     475
     476    public enum CatROS { ROS_UNKN, ROS_OMNI, ROS_DIRL, ROS_ROTP, ROS_CNSL, ROS_RDF, ROS_QTA, ROS_AERO, ROS_DECA, ROS_LORN, ROS_DGPS, ROS_TORN, ROS_OMGA, ROS_SYLD, ROS_CHKA,
     477        ROS_PCOM, ROS_COMB, ROS_FACS, ROS_TIME, ROS_PAIS, ROS_SAIS, ROS_VAIS, ROS_VANC, ROS_VASC, ROS_VAEC, ROS_VAWC, ROS_VAPL, ROS_VASL, ROS_VAID, ROS_VASW, ROS_VASP, ROS_VAWK }
     478
     479    private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static {
     480        Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
     481        Catros.put(CatROS.ROS_OMNI, new S57enum(1, "omnidirectional")); Catros.put(CatROS.ROS_DIRL, new S57enum(2, "directional")); Catros.put(CatROS.ROS_ROTP, new S57enum(3, "rotating_pattern"));
     482        Catros.put(CatROS.ROS_CNSL, new S57enum(4, "consol")); Catros.put(CatROS.ROS_RDF, new S57enum(5, "rdf")); Catros.put(CatROS.ROS_QTA, new S57enum(6, "qtg"));
     483        Catros.put(CatROS.ROS_AERO, new S57enum(7, "aeronautical")); Catros.put(CatROS.ROS_DECA, new S57enum(8, "decca")); Catros.put(CatROS.ROS_LORN, new S57enum(9, "loran"));
     484        Catros.put(CatROS.ROS_DGPS, new S57enum(10, "dgps")); Catros.put(CatROS.ROS_TORN, new S57enum(11, "toran")); Catros.put(CatROS.ROS_OMGA, new S57enum(12, "omega"));
     485        Catros.put(CatROS.ROS_SYLD, new S57enum(13, "syledis")); Catros.put(CatROS.ROS_CHKA, new S57enum(14, "chiaka")); Catros.put(CatROS.ROS_PCOM, new S57enum(15, "public_communication"));
     486        Catros.put(CatROS.ROS_COMB, new S57enum(16, "commercial_broadcast")); Catros.put(CatROS.ROS_FACS, new S57enum(17, "facsimile")); Catros.put(CatROS.ROS_TIME, new S57enum(18, "time_signal"));
     487        Catros.put(CatROS.ROS_PAIS, new S57enum(19, "ais")); Catros.put(CatROS.ROS_SAIS, new S57enum(20, "s-ais")); Catros.put(CatROS.ROS_VAIS, new S57enum(21, "v-ais"));
     488        Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
     489        Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
     490        Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
     491        Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
     492        Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck"));
     493    }
     494
     495    public enum CatRSC { RSC_UNKN, RSC_LIFB, RSC_ROKT, RSC_LBRK, RSC_RFSW, RSC_RFIT, RSC_LBOM, RSC_RDIO, RSC_FSTA, RSC_SPLN, RSC_ACFT, RSC_STUG }
     496
     497    private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static {
     498        Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
     499        Catrsc.put(CatRSC.RSC_LIFB, new S57enum(1, "lifeboat")); Catrsc.put(CatRSC.RSC_ROKT, new S57enum(2, "rocket")); Catrsc.put(CatRSC.RSC_LBRK, new S57enum(3, "lifeboat_rocket"));
     500        Catrsc.put(CatRSC.RSC_RFSW, new S57enum(4, "refuge_shipwrecked")); Catrsc.put(CatRSC.RSC_RFIT, new S57enum(5, "refuge_intertidal")); Catrsc.put(CatRSC.RSC_LBOM, new S57enum(6, "lifeboat_on_mooring"));
     501        Catrsc.put(CatRSC.RSC_RDIO, new S57enum(7, "radio")); Catrsc.put(CatRSC.RSC_FSTA, new S57enum(8, "first_aid")); Catrsc.put(CatRSC.RSC_SPLN, new S57enum(9, "seaplane"));
     502        Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
     503    }
     504
     505    public enum CatREA { REA_UNKN, REA_SFTY, REA_NANC, REA_NFSH, REA_NATR, REA_BRDS, REA_GRSV, REA_SEAL, REA_DEGR, REA_MILY, REA_HIST, REA_INST,
     506        REA_NASF, REA_STRD, REA_MINE, REA_NDIV, REA_TBAV, REA_PROH, REA_SWIM, REA_WAIT, REA_RSCH, REA_DREG, REA_FSNC, REA_ERES, REA_NWAK, REA_SWNG,
     507        REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS }
     508
     509    private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static {
     510        Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
     511        Catrea.put(CatREA.REA_SFTY, new S57enum(1, "safety")); Catrea.put(CatREA.REA_NANC, new S57enum(2, "no_anchoring")); Catrea.put(CatREA.REA_NFSH, new S57enum(3, "no_fishing"));
     512        Catrea.put(CatREA.REA_NATR, new S57enum(4, "nature_reserve")); Catrea.put(CatREA.REA_BRDS, new S57enum(5, "bird_sanctuary")); Catrea.put(CatREA.REA_GRSV, new S57enum(6, "game_reserve"));
     513        Catrea.put(CatREA.REA_SEAL, new S57enum(7, "seal_sanctuary")); Catrea.put(CatREA.REA_DEGR, new S57enum(8, "degaussing_range")); Catrea.put(CatREA.REA_MILY, new S57enum(9, "military"));
     514        Catrea.put(CatREA.REA_HIST, new S57enum(10, "historic_wreck")); Catrea.put(CatREA.REA_INST, new S57enum(11, "inshore_traffic")); Catrea.put(CatREA.REA_NASF, new S57enum(12, "navigational_aid_safety"));
     515        Catrea.put(CatREA.REA_STRD, new S57enum(13, "stranding_danger")); Catrea.put(CatREA.REA_MINE, new S57enum(14, "minefield")); Catrea.put(CatREA.REA_NDIV, new S57enum(15, "no_diving"));
     516        Catrea.put(CatREA.REA_TBAV, new S57enum(16, "to_be_avoided")); Catrea.put(CatREA.REA_PROH, new S57enum(17, "prohibited")); Catrea.put(CatREA.REA_SWIM, new S57enum(18, "swimming"));
     517        Catrea.put(CatREA.REA_WAIT, new S57enum(19, "waiting")); Catrea.put(CatREA.REA_RSCH, new S57enum(20, "research")); Catrea.put(CatREA.REA_DREG, new S57enum(21, "dredging"));
     518        Catrea.put(CatREA.REA_FSNC, new S57enum(22, "fish_sanctuary")); Catrea.put(CatREA.REA_ERES, new S57enum(23, "ecological_reserve")); Catrea.put(CatREA.REA_NWAK, new S57enum(24, "no_wake"));
     519        Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
     520        Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
     521        Catrea.put(CatREA.REA_DISA, new S57enum(29, "disengagement")); Catrea.put(CatREA.REA_PSAR, new S57enum(30, "port_security")); Catrea.put(CatREA.REA_CRLS, new S57enum(31, "coral_sactuary"));
     522    }
     523
     524    public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH }
     525
     526    private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static {
     527        Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
     528        Catrod.put(CatROD.ROD_MWAY, new S57enum(1, "motorway")); Catrod.put(CatROD.ROD_MAJR, new S57enum(2, "major_road")); Catrod.put(CatROD.ROD_MINR, new S57enum(3, "minor_road"));
     529        Catrod.put(CatROD.ROD_TRAK, new S57enum(4, "track")); Catrod.put(CatROD.ROD_MAJS, new S57enum(5, "major_street")); Catrod.put(CatROD.ROD_MINS, new S57enum(6, "minor_street"));
     530        Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
     531    }
     532
     533    public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
     534
     535    private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static {
     536        Catrun.put(CatRUN.RUN_UNKN, new S57enum(0, "")); Catrun.put(CatRUN.RUN_AERP, new S57enum(1, "aeroplane")); Catrun.put(CatRUN.RUN_HELI, new S57enum(2, "helicopter"));
     537    }
     538
     539    public enum CatSEA { SEA_UNKN, SEA_GENL, SEA_GAT, SEA_BANK, SEA_DEEP, SEA_BAY, SEA_TRCH, SEA_BASN, SEA_MDFT, SEA_REEF, SEA_LEDG, SEA_CNYN, SEA_NRRW, SEA_SHOL,
     540        SEA_KNOL, SEA_RIDG, SEA_SMNT, SEA_PNCL, SEA_APLN, SEA_PLTU, SEA_SPUR, SEA_SHLF, SEA_TRGH, SEA_SDDL, SEA_AHLL, SEA_APRN, SEA_AAPN, SEA_BLND, SEA_CMGN, SEA_CRIS,
     541        SEA_ESCT, SEA_FAN, SEA_FZON, SEA_GAP, SEA_GUYT, SEA_HILL, SEA_HOLE, SEA_LEVE, SEA_MVLY, SEA_MOAT, SEA_MTNS, SEA_PEAK, SEA_PVNC, SEA_RISE, SEA_SCNL, SEA_SCHN,
     542        SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
     543
     544    private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static {
     545        Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
     546        Catsea.put(CatSEA.SEA_GENL, new S57enum(1, "general")); Catsea.put(CatSEA.SEA_GAT, new S57enum(2, "gat")); Catsea.put(CatSEA.SEA_BANK, new S57enum(3, "bank"));
     547        Catsea.put(CatSEA.SEA_DEEP, new S57enum(4, "deep")); Catsea.put(CatSEA.SEA_BAY, new S57enum(5, "bay")); Catsea.put(CatSEA.SEA_TRCH, new S57enum(6, "trench"));
     548        Catsea.put(CatSEA.SEA_BASN, new S57enum(7, "basin")); Catsea.put(CatSEA.SEA_MDFT, new S57enum(8, "flat")); Catsea.put(CatSEA.SEA_REEF, new S57enum(9, "reef"));
     549        Catsea.put(CatSEA.SEA_LEDG, new S57enum(10, "ledge")); Catsea.put(CatSEA.SEA_CNYN, new S57enum(11, "canyon")); Catsea.put(CatSEA.SEA_NRRW, new S57enum(12, "narrows"));
     550        Catsea.put(CatSEA.SEA_SHOL, new S57enum(13, "shoal")); Catsea.put(CatSEA.SEA_KNOL, new S57enum(14, "knoll")); Catsea.put(CatSEA.SEA_RIDG, new S57enum(15, "ridge"));
     551        Catsea.put(CatSEA.SEA_SMNT, new S57enum(16, "seamount")); Catsea.put(CatSEA.SEA_PNCL, new S57enum(17, "pinnacle")); Catsea.put(CatSEA.SEA_APLN, new S57enum(18, "abyssal_plain"));
     552        Catsea.put(CatSEA.SEA_PLTU, new S57enum(19, "plateau")); Catsea.put(CatSEA.SEA_SPUR, new S57enum(20, "spur")); Catsea.put(CatSEA.SEA_SHLF, new S57enum(21, "shelf"));
     553        Catsea.put(CatSEA.SEA_TRGH, new S57enum(22, "trough")); Catsea.put(CatSEA.SEA_SDDL, new S57enum(23, "saddle")); Catsea.put(CatSEA.SEA_AHLL, new S57enum(24, "abyssal_hills"));
     554        Catsea.put(CatSEA.SEA_APRN, new S57enum(25, "apron")); Catsea.put(CatSEA.SEA_AAPN, new S57enum(26, "archipelagic_apron")); Catsea.put(CatSEA.SEA_BLND, new S57enum(27, "borderland"));
     555        Catsea.put(CatSEA.SEA_CMGN, new S57enum(28, "continental_margin")); Catsea.put(CatSEA.SEA_CRIS, new S57enum(29, "continental_rise")); Catsea.put(CatSEA.SEA_ESCT, new S57enum(30, "escarpment"));
     556        Catsea.put(CatSEA.SEA_FAN, new S57enum(31, "fan")); Catsea.put(CatSEA.SEA_FZON, new S57enum(32, "fracture_zone")); Catsea.put(CatSEA.SEA_GAP, new S57enum(33, "gap"));
     557        Catsea.put(CatSEA.SEA_GUYT, new S57enum(34, "guyot")); Catsea.put(CatSEA.SEA_HILL, new S57enum(35, "hill")); Catsea.put(CatSEA.SEA_HOLE, new S57enum(36, "hole"));
     558        Catsea.put(CatSEA.SEA_LEVE, new S57enum(37, "levee")); Catsea.put(CatSEA.SEA_MVLY, new S57enum(38, "median_valley")); Catsea.put(CatSEA.SEA_MOAT, new S57enum(39, "moat"));
     559        Catsea.put(CatSEA.SEA_MTNS, new S57enum(40, "mountains")); Catsea.put(CatSEA.SEA_PEAK, new S57enum(41, "peak")); Catsea.put(CatSEA.SEA_PVNC, new S57enum(42, "province"));
     560        Catsea.put(CatSEA.SEA_RISE, new S57enum(43, "rise")); Catsea.put(CatSEA.SEA_SCNL, new S57enum(44, "sea_channel")); Catsea.put(CatSEA.SEA_SCHN, new S57enum(45, "seamount_chain"));
     561        Catsea.put(CatSEA.SEA_SEDG, new S57enum(46, "shelf-edge")); Catsea.put(CatSEA.SEA_SILL, new S57enum(47, "sill")); Catsea.put(CatSEA.SEA_SLOP, new S57enum(48, "slope"));
     562        Catsea.put(CatSEA.SEA_TRRC, new S57enum(49, "terrace")); Catsea.put(CatSEA.SEA_VLLY, new S57enum(50, "valley")); Catsea.put(CatSEA.SEA_CANL, new S57enum(51, "canal"));
     563        Catsea.put(CatSEA.SEA_LAKE, new S57enum(52, "lake")); Catsea.put(CatSEA.SEA_RIVR, new S57enum(53, "river")); Catsea.put(CatSEA.SEA_RECH, new S57enum(54, "reach"));
     564    }
     565
     566    public enum CatSLC { SLC_UNKN, SLC_BWTR, SLC_GRYN, SLC_MOLE, SLC_PIER, SLC_PPER, SLC_WHRF, SLC_TWAL, SLC_RPRP, SLC_RVMT, SLC_SWAL, SLC_LSTP,
     567        SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF, SLC_OFWF, SLC_LRMP, SLC_LWAL, SLC_ICEB }
     568
     569    private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static {
     570        Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
     571        Catslc.put(CatSLC.SLC_BWTR, new S57enum(1, "breakwater")); Catslc.put(CatSLC.SLC_GRYN, new S57enum(2, "groyne")); Catslc.put(CatSLC.SLC_MOLE, new S57enum(3, "mole"));
     572        Catslc.put(CatSLC.SLC_PIER, new S57enum(4, "pier")); Catslc.put(CatSLC.SLC_PPER, new S57enum(5, "promenade_pier")); Catslc.put(CatSLC.SLC_WHRF, new S57enum(6, "wharf"));
     573        Catslc.put(CatSLC.SLC_TWAL, new S57enum(7, "training_wall")); Catslc.put(CatSLC.SLC_RPRP, new S57enum(8, "rip_rap")); Catslc.put(CatSLC.SLC_RVMT, new S57enum(9, "revetment"));
     574        Catslc.put(CatSLC.SLC_SWAL, new S57enum(10, "sea_wall")); Catslc.put(CatSLC.SLC_LSTP, new S57enum(11, "landing_steps")); Catslc.put(CatSLC.SLC_RAMP, new S57enum(12, "ramp"));
     575        Catslc.put(CatSLC.SLC_SWAY, new S57enum(13, "slipway")); Catslc.put(CatSLC.SLC_FNDR, new S57enum(14, "fender")); Catslc.put(CatSLC.SLC_SFWF, new S57enum(15, "solid_face_wharf"));
     576        Catslc.put(CatSLC.SLC_OFWF, new S57enum(16, "open_face_wharf")); Catslc.put(CatSLC.SLC_LRMP, new S57enum(17, "log_ramp")); Catslc.put(CatSLC.SLC_LWAL, new S57enum(18, "lock_wall"));
     577        Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
     578    }
     579
     580    public enum CatSIT { SIT_UNKN, SIT_PRTC, SIT_PRTE, SIT_IPT, SIT_BRTH, SIT_DOCK, SIT_LOCK, SIT_FLDB, SIT_BRDG, SIT_DRDG, SIT_TCLT, SIT_SPCL, SIT_PLTG, SIT_ONCT }
     581
     582    private static final EnumMap<CatSIT, S57enum> Catsit = new EnumMap<>(CatSIT.class); static {
     583        Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
     584        Catsit.put(CatSIT.SIT_PRTC, new S57enum(1, "port_control")); Catsit.put(CatSIT.SIT_PRTE, new S57enum(2, "port_entry_departure")); Catsit.put(CatSIT.SIT_IPT, new S57enum(3, "ipt"));
     585        Catsit.put(CatSIT.SIT_BRTH, new S57enum(4, "berthing")); Catsit.put(CatSIT.SIT_DOCK, new S57enum(5, "dock")); Catsit.put(CatSIT.SIT_LOCK, new S57enum(6, "lock"));
     586        Catsit.put(CatSIT.SIT_FLDB, new S57enum(7, "flood_barrage")); Catsit.put(CatSIT.SIT_BRDG, new S57enum(8, "bridge_passage")); Catsit.put(CatSIT.SIT_DRDG, new S57enum(9, "dredging"));
     587        Catsit.put(CatSIT.SIT_TCLT, new S57enum(10, "traffic_control")); Catsit.put(CatSIT.SIT_PLTG, new S57enum(11, "pilotage")); Catsit.put(CatSIT.SIT_SPCL, new S57enum(12, "special"));
     588        Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
     589    }
     590
     591    public enum CatSIW { SIW_UNKN, SIW_DNGR, SIW_OBST, SIW_CABL, SIW_MILY, SIW_DSTR, SIW_WTHR, SIW_STRM, SIW_ICE, SIW_TIME, SIW_TIDE, SIW_TSTR,
     592        SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
     593
     594    private static final EnumMap<CatSIW, S57enum> Catsiw = new EnumMap<>(CatSIW.class); static {
     595        Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
     596        Catsiw.put(CatSIW.SIW_DNGR, new S57enum(1, "danger")); Catsiw.put(CatSIW.SIW_OBST, new S57enum(2, "maritime_obstruction")); Catsiw.put(CatSIW.SIW_CABL, new S57enum(3, "cable"));
     597        Catsiw.put(CatSIW.SIW_MILY, new S57enum(4, "military")); Catsiw.put(CatSIW.SIW_DSTR, new S57enum(5, "distress")); Catsiw.put(CatSIW.SIW_WTHR, new S57enum(6, "weather"));
     598        Catsiw.put(CatSIW.SIW_STRM, new S57enum(7, "storm")); Catsiw.put(CatSIW.SIW_ICE, new S57enum(8, "ice")); Catsiw.put(CatSIW.SIW_TIME, new S57enum(9, "time"));
     599        Catsiw.put(CatSIW.SIW_TIDE, new S57enum(10, "tide")); Catsiw.put(CatSIW.SIW_TSTR, new S57enum(11, "tidal_stream")); Catsiw.put(CatSIW.SIW_TIDG, new S57enum(12, "tide_gauge"));
     600        Catsiw.put(CatSIW.SIW_TIDS, new S57enum(13, "tide_scale")); Catsiw.put(CatSIW.SIW_DIVE, new S57enum(14, "diving")); Catsiw.put(CatSIW.SIW_WTLG, new S57enum(15, "water_level_gauge"));
     601        Catsiw.put(CatSIW.SIW_VRCL, new S57enum(16, "vertical_clearance")); Catsiw.put(CatSIW.SIW_HIWM, new S57enum(17, "high_water")); Catsiw.put(CatSIW.SIW_DPTH, new S57enum(18, "depth"));
     602        Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
     603    }
     604
     605    public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT }
     606
     607    private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static {
     608        Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
     609        Catsil.put(CatSIL.SIL_SILO, new S57enum(1, "silo")); Catsil.put(CatSIL.SIL_TANK, new S57enum(2, "tank")); Catsil.put(CatSIL.SIL_GRNE, new S57enum(3, "grain_elevator"));
     610        Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
     611    }
     612
     613    public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE }
     614
     615    private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static {
     616        Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
     617        Catslo.put(CatSLO.SLO_CUTG, new S57enum(1, "cutting")); Catslo.put(CatSLO.SLO_EMBK, new S57enum(2, "embankment")); Catslo.put(CatSLO.SLO_DUNE, new S57enum(3, "dune"));
     618        Catslo.put(CatSLO.SLO_HILL, new S57enum(4, "hill")); Catslo.put(CatSLO.SLO_PINO, new S57enum(5, "pingo")); Catslo.put(CatSLO.SLO_CLIF, new S57enum(6, "cliff")); Catslo.put(CatSLO.SLO_SCRE, new S57enum(7, "scree"));
     619    }
     620
     621    public enum CatSCF { SCF_UNKN, SCF_VBTH, SCF_CLUB, SCF_BHST, SCF_SMKR, SCF_BTYD, SCF_INN, SCF_RSRT, SCF_CHDR, SCF_PROV, SCF_DCTR, SCF_PHRM,
     622        SCF_WTRT, SCF_FUEL, SCF_ELEC, SCF_BGAS, SCF_SHWR, SCF_LAUN, SCF_WC, SCF_POST, SCF_TELE, SCF_REFB, SCF_CARP, SCF_BTPK, SCF_CRVN, SCF_CAMP,
     623        SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
     624
     625    private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static {
     626        Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
     627        Catscf.put(CatSCF.SCF_VBTH, new S57enum(1, "visitor_berth")); Catscf.put(CatSCF.SCF_CLUB, new S57enum(2, "nautical_club")); Catscf.put(CatSCF.SCF_BHST, new S57enum(3, "boat_hoist"));
     628        Catscf.put(CatSCF.SCF_SMKR, new S57enum(4, "sailmaker")); Catscf.put(CatSCF.SCF_BTYD, new S57enum(5, "boatyard")); Catscf.put(CatSCF.SCF_INN, new S57enum(6, "public_inn"));
     629        Catscf.put(CatSCF.SCF_RSRT, new S57enum(7, "restaurant")); Catscf.put(CatSCF.SCF_CHDR, new S57enum(8, "chandler")); Catscf.put(CatSCF.SCF_PROV, new S57enum(9, "provisions"));
     630        Catscf.put(CatSCF.SCF_DCTR, new S57enum(10, "doctor")); Catscf.put(CatSCF.SCF_PHRM, new S57enum(11, "pharmacy")); Catscf.put(CatSCF.SCF_WTRT, new S57enum(12, "water_tap"));
     631        Catscf.put(CatSCF.SCF_FUEL, new S57enum(13, "fuel_station")); Catscf.put(CatSCF.SCF_ELEC, new S57enum(14, "electricity")); Catscf.put(CatSCF.SCF_BGAS, new S57enum(15, "bottle_gas"));
     632        Catscf.put(CatSCF.SCF_SHWR, new S57enum(16, "showers")); Catscf.put(CatSCF.SCF_LAUN, new S57enum(17, "laundrette")); Catscf.put(CatSCF.SCF_WC, new S57enum(18, "toilets"));
     633        Catscf.put(CatSCF.SCF_POST, new S57enum(19, "post_box")); Catscf.put(CatSCF.SCF_TELE, new S57enum(20, "telephone")); Catscf.put(CatSCF.SCF_REFB, new S57enum(21, "refuse_bin"));
     634        Catscf.put(CatSCF.SCF_CARP, new S57enum(22, "car_park")); Catscf.put(CatSCF.SCF_BTPK, new S57enum(23, "boat_trailers_park")); Catscf.put(CatSCF.SCF_CRVN, new S57enum(24, "caravan_site"));
     635        Catscf.put(CatSCF.SCF_CAMP, new S57enum(25, "camping_site")); Catscf.put(CatSCF.SCF_PMPO, new S57enum(26, "pump-out")); Catscf.put(CatSCF.SCF_EMRT, new S57enum(27, "emergency_telephone"));
     636        Catscf.put(CatSCF.SCF_SLPW, new S57enum(28, "slipway")); Catscf.put(CatSCF.SCF_VMOR, new S57enum(29, "visitors_mooring")); Catscf.put(CatSCF.SCF_SCRB, new S57enum(30, "scrubbing_berth"));
     637        Catscf.put(CatSCF.SCF_PCNC, new S57enum(31, "picnic_area")); Catscf.put(CatSCF.SCF_MECH, new S57enum(32, "mechanics_workshop")); Catscf.put(CatSCF.SCF_SECS, new S57enum(33, "security_service"));
     638    }
     639
     640    public enum CatSPM { SPM_UNKN, SPM_FDGA, SPM_TRGT, SPM_MSHP, SPM_DGRG, SPM_BARG, SPM_CABL, SPM_SPLG, SPM_OFAL, SPM_ODAS, SPM_RCDG, SPM_SPLA, SPM_RCZN, SPM_PRVT, SPM_MOOR, SPM_LNBY, SPM_LDNG, SPM_MDST,
     641        SPM_NOTC, SPM_TSS, SPM_NANC, SPM_NBRT, SPM_NOTK, SPM_NTWT, SPM_RWAK, SPM_SPDL, SPM_STOP, SPM_WRNG, SPM_SSSN, SPM_RVCL, SPM_MVDT, SPM_RHCL, SPM_SCNT, SPM_BRTH, SPM_OHPC, SPM_CHEG, SPM_TELE, SPM_FCRS,
     642        SPM_MTRL, SPM_PLIN, SPM_ANCH, SPM_CLRG, SPM_CTRL, SPM_DIVG, SPM_RBCN, SPM_FGND, SPM_YCHT, SPM_HPRT, SPM_GPS, SPM_SLDG, SPM_NENT, SPM_WRKP, SPM_UKPP, SPM_WELH, SPM_CHSP, SPM_MFRM, SPM_AREF }
     643
     644    private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static {
     645        Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
     646        Catspm.put(CatSPM.SPM_FDGA, new S57enum(1, "firing_danger_area")); Catspm.put(CatSPM.SPM_TRGT, new S57enum(2, "target")); Catspm.put(CatSPM.SPM_MSHP, new S57enum(3, "marker_ship"));
     647        Catspm.put(CatSPM.SPM_DGRG, new S57enum(4, "degaussing_range")); Catspm.put(CatSPM.SPM_BARG, new S57enum(5, "barge")); Catspm.put(CatSPM.SPM_CABL, new S57enum(6, "cable"));
     648        Catspm.put(CatSPM.SPM_SPLG, new S57enum(7, "spoil_ground")); Catspm.put(CatSPM.SPM_OFAL, new S57enum(8, "outfall")); Catspm.put(CatSPM.SPM_ODAS, new S57enum(9, "odas"));
     649        Catspm.put(CatSPM.SPM_RCDG, new S57enum(10, "recording")); Catspm.put(CatSPM.SPM_SPLA, new S57enum(11, "seaplane_anchorage")); Catspm.put(CatSPM.SPM_RCZN, new S57enum(12, "recreation_zone"));
     650        Catspm.put(CatSPM.SPM_PRVT, new S57enum(13, "private")); Catspm.put(CatSPM.SPM_MOOR, new S57enum(14, "mooring")); Catspm.put(CatSPM.SPM_LNBY, new S57enum(15, "lanby"));
     651        Catspm.put(CatSPM.SPM_LDNG, new S57enum(16, "leading")); Catspm.put(CatSPM.SPM_MDST, new S57enum(17, "measured_distance")); Catspm.put(CatSPM.SPM_NOTC, new S57enum(18, "notice"));
     652        Catspm.put(CatSPM.SPM_TSS, new S57enum(19, "tss")); Catspm.put(CatSPM.SPM_NANC, new S57enum(20, "no_anchoring")); Catspm.put(CatSPM.SPM_NBRT, new S57enum(21, "no_berthing"));
     653        Catspm.put(CatSPM.SPM_NOTK, new S57enum(22, "no_overtaking")); Catspm.put(CatSPM.SPM_NTWT, new S57enum(23, "no_two-way_traffic")); Catspm.put(CatSPM.SPM_RWAK, new S57enum(24, "reduced_wake"));
     654        Catspm.put(CatSPM.SPM_SPDL, new S57enum(25, "speed_limit")); Catspm.put(CatSPM.SPM_STOP, new S57enum(26, "stop")); Catspm.put(CatSPM.SPM_WRNG, new S57enum(27, "warning"));
     655        Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
     656        Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
     657        Catspm.put(CatSPM.SPM_SCNT, new S57enum(32, "strong_current")); Catspm.put(CatSPM.SPM_BRTH, new S57enum(33, "berthing")); Catspm.put(CatSPM.SPM_OHPC, new S57enum(34, "overhead_power_cable"));
     658        Catspm.put(CatSPM.SPM_CHEG, new S57enum(35, "channel_edge_gradient")); Catspm.put(CatSPM.SPM_TELE, new S57enum(36, "telephone")); Catspm.put(CatSPM.SPM_FCRS, new S57enum(37, "ferry_crossing"));
     659        Catspm.put(CatSPM.SPM_MTRL, new S57enum(38, "marine_traffic_lights")); Catspm.put(CatSPM.SPM_PLIN, new S57enum(39, "pipeline")); Catspm.put(CatSPM.SPM_ANCH, new S57enum(40, "anchorage"));
     660        Catspm.put(CatSPM.SPM_CLRG, new S57enum(41, "clearing")); Catspm.put(CatSPM.SPM_CTRL, new S57enum(42, "control")); Catspm.put(CatSPM.SPM_DIVG, new S57enum(43, "diving"));
     661        Catspm.put(CatSPM.SPM_RBCN, new S57enum(44, "refuge_beacon")); Catspm.put(CatSPM.SPM_FGND, new S57enum(45, "foul_ground")); Catspm.put(CatSPM.SPM_YCHT, new S57enum(46, "yachting"));
     662        Catspm.put(CatSPM.SPM_HPRT, new S57enum(47, "heliport")); Catspm.put(CatSPM.SPM_GPS, new S57enum(48, "gps")); Catspm.put(CatSPM.SPM_SLDG, new S57enum(49, "seaplane_landing"));
     663        Catspm.put(CatSPM.SPM_NENT, new S57enum(50, "no_entry")); Catspm.put(CatSPM.SPM_WRKP, new S57enum(51, "work_in_progress")); Catspm.put(CatSPM.SPM_UKPP, new S57enum(52, "unknown_purpose"));
     664        Catspm.put(CatSPM.SPM_WELH, new S57enum(53, "wellhead")); Catspm.put(CatSPM.SPM_CHSP, new S57enum(54, "channel_separation")); Catspm.put(CatSPM.SPM_MFRM, new S57enum(55, "marine_farm"));
     665        Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
     666    }
     667
     668    public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
     669
     670    private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static {
     671        Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
     672        Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
     673    }
     674
     675    public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
     676
     677    private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static {
     678        Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
     679        Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
     680    }
     681
     682    public enum CatVEG { VEG_UNKN, VEG_GRAS, VEG_PDDY, VEG_BUSH, VEG_DCDW, VEG_CONW, VEG_WOOD, VEG_MGRV, VEG_PARK, VEG_PKLD, VEG_MCRP, VEG_REED, VEG_MOSS,
     683        VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
     684
     685    private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static {
     686        Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
     687        Catveg.put(CatVEG.VEG_GRAS, new S57enum(1, "grass")); Catveg.put(CatVEG.VEG_PDDY, new S57enum(2, "paddy")); Catveg.put(CatVEG.VEG_BUSH, new S57enum(3, "bush"));
     688        Catveg.put(CatVEG.VEG_DCDW, new S57enum(4, "deciduous_wood")); Catveg.put(CatVEG.VEG_CONW, new S57enum(5, "coniferous_wood")); Catveg.put(CatVEG.VEG_WOOD, new S57enum(6, "wood"));
     689        Catveg.put(CatVEG.VEG_MGRV, new S57enum(7, "mangroves")); Catveg.put(CatVEG.VEG_PARK, new S57enum(8, "park")); Catveg.put(CatVEG.VEG_PKLD, new S57enum(9, "parkland"));
     690        Catveg.put(CatVEG.VEG_MCRP, new S57enum(10, "mixed_crops")); Catveg.put(CatVEG.VEG_REED, new S57enum(11, "reed")); Catveg.put(CatVEG.VEG_MOSS, new S57enum(12, "moss"));
     691        Catveg.put(CatVEG.VEG_TREE, new S57enum(13, "tree")); Catveg.put(CatVEG.VEG_EVGT, new S57enum(14, "evergreen_tree")); Catveg.put(CatVEG.VEG_CONT, new S57enum(15, "coniferous_tree"));
     692        Catveg.put(CatVEG.VEG_PLMT, new S57enum(16, "palm_tree")); Catveg.put(CatVEG.VEG_NPMT, new S57enum(17, "nipa_palm_tree")); Catveg.put(CatVEG.VEG_CSAT, new S57enum(18, "casuarina_tree"));
     693        Catveg.put(CatVEG.VEG_EUCT, new S57enum(19, "eucalypt_tree")); Catveg.put(CatVEG.VEG_DCDT, new S57enum(20, "deciduous_tree")); Catveg.put(CatVEG.VEG_MRVT, new S57enum(21, "mangrove_tree"));
     694        Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
     695    }
     696
     697    public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR }
     698
     699    private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static {
     700        Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
     701        Catwat.put(CatWAT.WAT_BKRS, new S57enum(1, "breakers")); Catwat.put(CatWAT.WAT_EDDY, new S57enum(2, "eddies")); Catwat.put(CatWAT.WAT_OVFL, new S57enum(3, "overfalls"));
     702        Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
     703    }
     704
     705    public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO }
     706
     707    private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static {
     708        Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
     709        Catwed.put(CatWED.WED_KELP, new S57enum(1, "kelp")); Catwed.put(CatWED.WED_SWED, new S57enum(2, "sea_weed")); Catwed.put(CatWED.WED_SGRS, new S57enum(3, "sea_grass"));
     710        Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
     711    }
     712
     713    public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS }
     714
     715    private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static {
     716        Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
     717        Catwrk.put(CatWRK.WRK_NDGR, new S57enum(1, "non-dangerous")); Catwrk.put(CatWRK.WRK_DNGR, new S57enum(2, "dangerous")); Catwrk.put(CatWRK.WRK_DREM, new S57enum(3, "distributed_remains"));
     718        Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
     719    }
     720
     721    public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U }
     722
     723    private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static {
     724        Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
     725        Catzoc.put(CatZOC.ZOC_A1, new S57enum(1, "a1")); Catzoc.put(CatZOC.ZOC_A2, new S57enum(2, "a2")); Catzoc.put(CatZOC.ZOC_B, new S57enum(3, "b"));
     726        Catzoc.put(CatZOC.ZOC_C, new S57enum(4, "c")); Catzoc.put(CatZOC.ZOC_D, new S57enum(5, "d")); Catzoc.put(CatZOC.ZOC_U, new S57enum(6, "u"));
     727    }
     728
     729    public enum ColCOL { COL_UNK, COL_WHT, COL_BLK, COL_RED, COL_GRN, COL_BLU, COL_YEL, COL_GRY, COL_BRN, COL_AMB, COL_VIO, COL_ORG, COL_MAG, COL_PNK }
     730
     731    private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static {
     732        Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
     733        Colour.put(ColCOL.COL_WHT, new S57enum(1, "white")); Colour.put(ColCOL.COL_BLK, new S57enum(2, "black")); Colour.put(ColCOL.COL_RED, new S57enum(3, "red"));
     734        Colour.put(ColCOL.COL_GRN, new S57enum(4, "green")); Colour.put(ColCOL.COL_BLU, new S57enum(5, "blue")); Colour.put(ColCOL.COL_YEL, new S57enum(6, "yellow"));
     735        Colour.put(ColCOL.COL_GRY, new S57enum(7, "grey")); Colour.put(ColCOL.COL_BRN, new S57enum(8, "brown")); Colour.put(ColCOL.COL_AMB, new S57enum(9, "amber"));
     736        Colour.put(ColCOL.COL_VIO, new S57enum(10, "violet")); Colour.put(ColCOL.COL_ORG, new S57enum(11, "orange")); Colour.put(ColCOL.COL_MAG, new S57enum(12, "magenta"));
     737        Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
     738    }
     739
     740    public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
     741
     742    private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static {
     743        Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
     744        Colpat.put(ColPAT.PAT_HORI, new S57enum(1, "horizontal")); Colpat.put(ColPAT.PAT_VERT, new S57enum(2, "vertical")); Colpat.put(ColPAT.PAT_DIAG, new S57enum(3, "diagonal"));
     745        Colpat.put(ColPAT.PAT_SQUR, new S57enum(4, "squared")); Colpat.put(ColPAT.PAT_STRP, new S57enum(5, "stripes")); Colpat.put(ColPAT.PAT_BRDR, new S57enum(6, "border"));
     746        Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
     747    }
     748
     749    public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS }
     750
     751    private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static {
     752        Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
     753        Condtn.put(CndCND.CND_UCNS, new S57enum(1, "under_construction")); Condtn.put(CndCND.CND_RUIN, new S57enum(2, "ruined")); Condtn.put(CndCND.CND_URCL, new S57enum(3, "under_reclamation"));
     754        Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
     755    }
     756
     757    public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
     758
     759    private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static {
     760        Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
     761        Conrad.put(ConRAD.RAD_CNSP, new S57enum(1, "conspicuous")); Conrad.put(ConRAD.RAD_NCSP, new S57enum(2, "not_conspicuous")); Conrad.put(ConRAD.RAD_REFL, new S57enum(3, "reflector"));
     762    }
     763
     764    public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
     765
     766    private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static {
     767        Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
     768        Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
     769    }
     770
     771    public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
     772
     773    private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static {
     774        Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
     775        Dunits.put(UniDPU.DPU_METR, new S57enum(1, "metres")); Dunits.put(UniDPU.DPU_FTFT, new S57enum(2, "fathoms_feet")); Dunits.put(UniDPU.DPU_FTHM, new S57enum(3, "fathoms"));
     776        Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
     777    }
     778
     779    public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM }
     780
     781    private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static {
     782        Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
     783        Exclit.put(ExcLIT.EXH_24H, new S57enum(1, "24h")); Exclit.put(ExcLIT.EXH_DAY, new S57enum(2, "day")); Exclit.put(ExcLIT.EXH_FOG, new S57enum(3, "fog")); Exclit.put(ExcLIT.EXH_NGHT, new S57enum(4, "night"));
     784        Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
     785    }
     786
     787    public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
     788
     789    private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static {
     790        Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
     791        Expsou.put(ExpSOU.EXP_WTHN, new S57enum(1, "within")); Expsou.put(ExpSOU.EXP_SHLR, new S57enum(2, "shoaler")); Expsou.put(ExpSOU.EXP_DEPR, new S57enum(3, "deeper"));
     792    }
     793
     794    public enum FncFNC { FNC_UNKN, FNC_HBRM, FNC_CSTM, FNC_HLTH, FNC_HOSP, FNC_POST, FNC_HOTL, FNC_RAIL, FNC_POLC, FNC_WPOL, FNC_PILO, FNC_PILL, FNC_BANK,
     795        FNC_DIST, FNC_TRNS, FNC_FCTY, FNC_POWR, FNC_ADMIN, FNC_EDUC, FNC_CHCH, FNC_CHPL, FNC_TMPL, FNC_PGDA, FNC_SHSH, FNC_BTMP, FNC_MOSQ, FNC_MRBT,
     796        FNC_LOOK, FNC_COMM, FNC_TV, FNC_RADO, FNC_RADR, FNC_LGHT, FNC_MCWV, FNC_COOL, FNC_OBS, FNC_TMBL, FNC_CLOK, FNC_CTRL, FNC_ASHM, FNC_STAD, FNC_BUSS,
     797        FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
     798
     799    private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {
     800        Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
     801        Functn.put(FncFNC.FNC_HBRM, new S57enum(2, "harbour_master")); Functn.put(FncFNC.FNC_CSTM, new S57enum(3, "customs")); Functn.put(FncFNC.FNC_HLTH, new S57enum(4, "health"));
     802        Functn.put(FncFNC.FNC_HOSP, new S57enum(5, "hospital")); Functn.put(FncFNC.FNC_POST, new S57enum(6, "post_office")); Functn.put(FncFNC.FNC_HOTL, new S57enum(7, "hotel"));
     803        Functn.put(FncFNC.FNC_RAIL, new S57enum(8, "railway_station")); Functn.put(FncFNC.FNC_POLC, new S57enum(9, "police_station")); Functn.put(FncFNC.FNC_WPOL, new S57enum(10, "water-police_station"));
     804        Functn.put(FncFNC.FNC_PILO, new S57enum(11, "pilot_office")); Functn.put(FncFNC.FNC_PILL, new S57enum(12, "pilot_lookout")); Functn.put(FncFNC.FNC_BANK, new S57enum(13, "bank"));
     805        Functn.put(FncFNC.FNC_DIST, new S57enum(14, "district_control")); Functn.put(FncFNC.FNC_TRNS, new S57enum(15, "transit_shed")); Functn.put(FncFNC.FNC_FCTY, new S57enum(16, "factory"));
     806        Functn.put(FncFNC.FNC_POWR, new S57enum(17, "power_station")); Functn.put(FncFNC.FNC_ADMIN, new S57enum(18, "administrative")); Functn.put(FncFNC.FNC_EDUC, new S57enum(19, "educational"));
     807        Functn.put(FncFNC.FNC_CHCH, new S57enum(20, "church")); Functn.put(FncFNC.FNC_CHPL, new S57enum(21, "chapel")); Functn.put(FncFNC.FNC_TMPL, new S57enum(22, "temple"));
     808        Functn.put(FncFNC.FNC_PGDA, new S57enum(23, "pagoda")); Functn.put(FncFNC.FNC_SHSH, new S57enum(24, "shinto_shrine")); Functn.put(FncFNC.FNC_BTMP, new S57enum(25, "buddhist_temple"));
     809        Functn.put(FncFNC.FNC_MOSQ, new S57enum(26, "mosque")); Functn.put(FncFNC.FNC_MRBT, new S57enum(27, "marabout")); Functn.put(FncFNC.FNC_LOOK, new S57enum(28, "lookout"));
     810        Functn.put(FncFNC.FNC_COMM, new S57enum(29, "communication")); Functn.put(FncFNC.FNC_TV, new S57enum(30, "television")); Functn.put(FncFNC.FNC_RADO, new S57enum(31, "radio"));
     811        Functn.put(FncFNC.FNC_RADR, new S57enum(32, "radar")); Functn.put(FncFNC.FNC_LGHT, new S57enum(33, "light_support")); Functn.put(FncFNC.FNC_MCWV, new S57enum(34, "microwave"));
     812        Functn.put(FncFNC.FNC_COOL, new S57enum(35, "cooling")); Functn.put(FncFNC.FNC_OBS, new S57enum(36, "observation")); Functn.put(FncFNC.FNC_TMBL, new S57enum(37, "time_ball"));
     813        Functn.put(FncFNC.FNC_CLOK, new S57enum(38, "clock")); Functn.put(FncFNC.FNC_CTRL, new S57enum(39, "control")); Functn.put(FncFNC.FNC_ASHM, new S57enum(40, "airship_mooring"));
     814        Functn.put(FncFNC.FNC_STAD, new S57enum(41, "stadium")); Functn.put(FncFNC.FNC_BUSS, new S57enum(42, "bus_station")); Functn.put(FncFNC.FNC_PTRM, new S57enum(43, "passenger_terminal"));
     815        Functn.put(FncFNC.FNC_SRCT, new S57enum(44, "sea_rescue_control")); Functn.put(FncFNC.FNC_OBSV, new S57enum(45, "observatory")); Functn.put(FncFNC.FNC_OREC, new S57enum(46, "ore_crusher"));
     816        Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
     817    }
     818
     819    public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
     820
     821    private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static {
     822        Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
     823        Hunits.put(UniHLU.HLU_METR, new S57enum(1, "metres")); Hunits.put(UniHLU.HLU_FEET, new S57enum(2, "feet")); Hunits.put(UniHLU.HLU_KMTR, new S57enum(3, "kilometres"));
     824        Hunits.put(UniHLU.HLU_HMTR, new S57enum(4, "hectometres")); Hunits.put(UniHLU.HLU_SMIL, new S57enum(5, "statute_miles")); Hunits.put(UniHLU.HLU_NMIL, new S57enum(6, "nautical_miles"));
     825    }
     826
     827    public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
     828
     829    private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static {
     830        Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
     831        Jrsdtn.put(JrsJRS.JRS_INT, new S57enum(1, "international")); Jrsdtn.put(JrsJRS.JRS_NAT, new S57enum(2, "national")); Jrsdtn.put(JrsJRS.JRS_NSD, new S57enum(3, "national_sub-division"));
     832    }
     833
     834    public enum LitCHR { CHR_UNKN, CHR_F, CHR_FL, CHR_LFL, CHR_Q, CHR_VQ, CHR_UQ, CHR_ISO, CHR_OC, CHR_IQ, CHR_IVQ, CHR_IUQ, CHR_MO, CHR_FFL,
     835        CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
     836
     837    private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static {
     838        Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
     839        Litchr.put(LitCHR.CHR_F, new S57enum(1, "F")); Litchr.put(LitCHR.CHR_FL, new S57enum(2, "Fl")); Litchr.put(LitCHR.CHR_LFL, new S57enum(3, "LFl")); Litchr.put(LitCHR.CHR_Q, new S57enum(4, "Q"));
     840        Litchr.put(LitCHR.CHR_VQ, new S57enum(5, "VQ")); Litchr.put(LitCHR.CHR_UQ, new S57enum(6, "UQ")); Litchr.put(LitCHR.CHR_ISO, new S57enum(7, "Iso")); Litchr.put(LitCHR.CHR_OC, new S57enum(8, "Oc"));
     841        Litchr.put(LitCHR.CHR_IQ, new S57enum(9, "IQ")); Litchr.put(LitCHR.CHR_IVQ, new S57enum(10, "IVQ")); Litchr.put(LitCHR.CHR_IUQ, new S57enum(11, "IUQ")); Litchr.put(LitCHR.CHR_MO, new S57enum(12, "Mo"));
     842        Litchr.put(LitCHR.CHR_FFL, new S57enum(13, "FFl")); Litchr.put(LitCHR.CHR_FLLFL, new S57enum(14, "FlLFl")); Litchr.put(LitCHR.CHR_OCFL, new S57enum(15, "OcFl"));
     843        Litchr.put(LitCHR.CHR_FLFL, new S57enum(16, "FLFl")); Litchr.put(LitCHR.CHR_ALOC, new S57enum(17, "Al.Oc")); Litchr.put(LitCHR.CHR_ALLFL, new S57enum(18, "Al.LFl"));
     844        Litchr.put(LitCHR.CHR_ALFL, new S57enum(19, "Al.Fl")); Litchr.put(LitCHR.CHR_ALGR, new S57enum(20, "Al.Gr")); Litchr.put(LitCHR.CHR_QLFL, new S57enum(25, "Q+LFl"));
     845        Litchr.put(LitCHR.CHR_VQLFL, new S57enum(26, "VQ+LFl")); Litchr.put(LitCHR.CHR_UQLFL, new S57enum(27, "UQ+LFl")); Litchr.put(LitCHR.CHR_AL, new S57enum(28, "Al"));
     846        Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
     847    }
     848
     849    public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
     850
     851    private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static {
     852        Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
     853        Litvis.put(LitVIS.LIT_HIGH, new S57enum(1, "high")); Litvis.put(LitVIS.LIT_LOW, new S57enum(2, "low")); Litvis.put(LitVIS.LIT_FANT, new S57enum(3, "faint"));
     854        Litvis.put(LitVIS.LIT_INTS, new S57enum(4, "intensified")); Litvis.put(LitVIS.LIT_UINT, new S57enum(5, "unintensified")); Litvis.put(LitVIS.LIT_RSTR, new S57enum(6, "restricted"));
     855        Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
     856    }
     857
     858    public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
     859
     860    private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static {
     861        Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
     862        Marsys.put(MarSYS.SYS_IALA, new S57enum(1, "iala-a")); Marsys.put(MarSYS.SYS_IALB, new S57enum(2, "iala-b")); Marsys.put(MarSYS.SYS_NONE, new S57enum(9, "none"));
     863        Marsys.put(MarSYS.SYS_OTHR, new S57enum(10, "other")); Marsys.put(MarSYS.SYS_CEVN, new S57enum(11, "cevni")); Marsys.put(MarSYS.SYS_RIWR, new S57enum(12, "riwr"));
     864        Marsys.put(MarSYS.SYS_BWR2, new S57enum(13, "bniwr2")); Marsys.put(MarSYS.SYS_BNWR, new S57enum(14, "bniwr")); Marsys.put(MarSYS.SYS_PPWB, new S57enum(15, "ppwbc"));
     865    }
     866
     867    public enum NatCON { CON_UNKN, CON_MSNY, CON_CONC, CON_BDRS, CON_HSRF, CON_USRF, CON_WOOD, CON_METL, CON_GRP, CON_PNTD, CON_FMWK, CON_LATT, CON_GLAS }
     868
     869    private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static {
     870        Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
     871        Natcon.put(NatCON.CON_MSNY, new S57enum(1, "masonry")); Natcon.put(NatCON.CON_CONC, new S57enum(2, "concreted")); Natcon.put(NatCON.CON_BDRS, new S57enum(3, "loose_boulders"));
     872        Natcon.put(NatCON.CON_HSRF, new S57enum(4, "hard-surfaced")); Natcon.put(NatCON.CON_USRF, new S57enum(5, "unsurfaced")); Natcon.put(NatCON.CON_WOOD, new S57enum(6, "wooden"));
     873        Natcon.put(NatCON.CON_METL, new S57enum(7, "metal")); Natcon.put(NatCON.CON_GRP, new S57enum(8, "grp")); Natcon.put(NatCON.CON_PNTD, new S57enum(9, "painted"));
     874        Natcon.put(NatCON.CON_FMWK, new S57enum(10, "framework")); Natcon.put(NatCON.CON_LATT, new S57enum(11, "latticed")); Natcon.put(NatCON.CON_GLAS, new S57enum(12, "glass"));
     875    }
     876
     877    public enum NatSUR { SUR_UNKN, SUR_MUD, SUR_CLAY, SUR_SILT, SUR_SAND, SUR_STON, SUR_GRVL, SUR_PBBL, SUR_CBBL, SUR_ROCK, SUR_LAVA, SUR_CORL, SUR_SHEL, SUR_BLDR }
     878
     879    private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static {
     880        Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
     881        Natsur.put(NatSUR.SUR_MUD, new S57enum(1, "mud")); Natsur.put(NatSUR.SUR_CLAY, new S57enum(2, "clay")); Natsur.put(NatSUR.SUR_SILT, new S57enum(3, "silt"));
     882        Natsur.put(NatSUR.SUR_SAND, new S57enum(4, "sand")); Natsur.put(NatSUR.SUR_STON, new S57enum(5, "stones")); Natsur.put(NatSUR.SUR_GRVL, new S57enum(6, "gravel"));
     883        Natsur.put(NatSUR.SUR_PBBL, new S57enum(7, "pebbles")); Natsur.put(NatSUR.SUR_CBBL, new S57enum(8, "cobbles")); Natsur.put(NatSUR.SUR_ROCK, new S57enum(9, "rocky"));
     884        Natsur.put(NatSUR.SUR_LAVA, new S57enum(11, "lava")); Natsur.put(NatSUR.SUR_CORL, new S57enum(14, "coral")); Natsur.put(NatSUR.SUR_SHEL, new S57enum(17, "shells"));
     885        Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
     886    }
     887
     888    public enum NatQUA { QUA_UNKN, QUA_FINE, QUA_MEDM, QUA_CORS, QUA_BRKN, QUA_STKY, QUA_SOFT, QUA_STIF, QUA_VCNC, QUA_CALC, QUA_HARD }
     889
     890    private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static {
     891        Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
     892        Natqua.put(NatQUA.QUA_FINE, new S57enum(1, "fine")); Natqua.put(NatQUA.QUA_MEDM, new S57enum(2, "medium")); Natqua.put(NatQUA.QUA_CORS, new S57enum(3, "coarse"));
     893        Natqua.put(NatQUA.QUA_BRKN, new S57enum(4, "broken")); Natqua.put(NatQUA.QUA_STKY, new S57enum(5, "sticky")); Natqua.put(NatQUA.QUA_SOFT, new S57enum(6, "soft"));
     894        Natqua.put(NatQUA.QUA_STIF, new S57enum(7, "stiff")); Natqua.put(NatQUA.QUA_VCNC, new S57enum(8, "volcanic")); Natqua.put(NatQUA.QUA_CALC, new S57enum(9, "calcareous"));
     895        Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
     896    }
     897
     898    public enum PrdPRD { PRD_UNKN, PRD_OIL, PRD_GAS, PRD_WATR, PRD_STON, PRD_COAL, PRD_ORE, PRD_CHEM, PRD_DWTR, PRD_MILK, PRD_BXIT, PRD_COKE, PRD_IIGS, PRD_SALT,
     899        PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
     900
     901    private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static {
     902        Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
     903        Prodct.put(PrdPRD.PRD_OIL, new S57enum(1, "oil")); Prodct.put(PrdPRD.PRD_GAS, new S57enum(2, "gas")); Prodct.put(PrdPRD.PRD_WATR, new S57enum(3, "water"));
     904        Prodct.put(PrdPRD.PRD_STON, new S57enum(4, "stone")); Prodct.put(PrdPRD.PRD_COAL, new S57enum(5, "coal")); Prodct.put(PrdPRD.PRD_ORE, new S57enum(6, "ore"));
     905        Prodct.put(PrdPRD.PRD_CHEM, new S57enum(7, "chemicals")); Prodct.put(PrdPRD.PRD_DWTR, new S57enum(8, "drinking_water")); Prodct.put(PrdPRD.PRD_MILK, new S57enum(9, "milk"));
     906        Prodct.put(PrdPRD.PRD_BXIT, new S57enum(10, "bauxite")); Prodct.put(PrdPRD.PRD_COKE, new S57enum(11, "coke")); Prodct.put(PrdPRD.PRD_IIGS, new S57enum(12, "iron_ingots"));
     907        Prodct.put(PrdPRD.PRD_SALT, new S57enum(13, "salt")); Prodct.put(PrdPRD.PRD_SAND, new S57enum(14, "sand")); Prodct.put(PrdPRD.PRD_TMBR, new S57enum(15, "timber"));
     908        Prodct.put(PrdPRD.PRD_SDST, new S57enum(16, "sawdust")); Prodct.put(PrdPRD.PRD_SCRP, new S57enum(17, "scrap")); Prodct.put(PrdPRD.PRD_LNA, new S57enum(18, "lng"));
     909        Prodct.put(PrdPRD.PRD_LPA, new S57enum(19, "lpg")); Prodct.put(PrdPRD.PRD_WINE, new S57enum(20, "wine")); Prodct.put(PrdPRD.PRD_CMNT, new S57enum(21, "cement"));
     910        Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
     911    }
     912
     913    public enum QuaSOU { SOU_UNKN, SOU_KNWN, SOU_UKNN, SOU_DFUL, SOU_UNRL, SOU_NBFD, SOU_LKWN, SOU_LUKN, SOU_NSRV, SOU_NCNF, SOU_MANT, SOU_NMNT }
     914
     915    private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static {
     916        Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
     917        Quasou.put(QuaSOU.SOU_KNWN, new S57enum(1, "known")); Quasou.put(QuaSOU.SOU_UKNN, new S57enum(2, "unknown")); Quasou.put(QuaSOU.SOU_DFUL, new S57enum(3, "doubtful"));
     918        Quasou.put(QuaSOU.SOU_UNRL, new S57enum(4, "unreliable")); Quasou.put(QuaSOU.SOU_NBFD, new S57enum(5, "no_bottom_found")); Quasou.put(QuaSOU.SOU_LKWN, new S57enum(6, "least_known"));
     919        Quasou.put(QuaSOU.SOU_LUKN, new S57enum(7, "least_unknown")); Quasou.put(QuaSOU.SOU_NSRV, new S57enum(8, "not_surveyed")); Quasou.put(QuaSOU.SOU_NCNF, new S57enum(9, "not_confirmed"));
     920        Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
     921    }
     922
     923    public enum RstRST { RST_UNKN, RST_NANC, RST_RANC, RST_NFSH, RST_RFSH, RST_NTRL, RST_RTRL, RST_NENT, RST_RENT, RST_NDRG, RST_RDRG, RST_NDVG, RST_RDVG, RST_NWAK, RST_TBAV, RST_NCST, RST_NDSC,
     924        RST_RDSC, RST_NEXD, RST_REXD, RST_NDRL, RST_RDRL, RST_NHAR, RST_NLTG, RST_NDRA, RST_NSTP, RST_NLND, RST_RSPD, RST_NOVT, RST_NCOV, RST_NPOV, RST_NBRT, RST_RBRT, RST_NMFT, RST_RMFT, RST_NTRN,
     925        RST_RFWD, RST_RFWW, RST_NSWM }
     926
     927    private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static {
     928        Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
     929        Restrn.put(RstRST.RST_NANC, new S57enum(1, "no_anchoring")); Restrn.put(RstRST.RST_RANC, new S57enum(2, "restricted_anchoring")); Restrn.put(RstRST.RST_NFSH, new S57enum(3, "no_fishing"));
     930        Restrn.put(RstRST.RST_RFSH, new S57enum(4, "restricted_fishing")); Restrn.put(RstRST.RST_NTRL, new S57enum(5, "no_trawling")); Restrn.put(RstRST.RST_RTRL, new S57enum(6, "restricted_trawling"));
     931        Restrn.put(RstRST.RST_NENT, new S57enum(7, "no_entry")); Restrn.put(RstRST.RST_RENT, new S57enum(8, "restricted_entry")); Restrn.put(RstRST.RST_NDRG, new S57enum(9, "no_dredging"));
     932        Restrn.put(RstRST.RST_RDRG, new S57enum(10, "restricted_dredging")); Restrn.put(RstRST.RST_NDVG, new S57enum(11, "no_diving")); Restrn.put(RstRST.RST_RDVG, new S57enum(12, "restricted_diving"));
     933        Restrn.put(RstRST.RST_NWAK, new S57enum(13, "no_wake")); Restrn.put(RstRST.RST_TBAV, new S57enum(14, "to_be_avoided")); Restrn.put(RstRST.RST_NCST, new S57enum(15, "no_construction"));
     934        Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
     935        Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
     936        Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
     937        Restrn.put(RstRST.RST_NHAR, new S57enum(22, "no_historical_artifacts_removal")); Restrn.put(RstRST.RST_NLTG, new S57enum(23, "no_lightering")); Restrn.put(RstRST.RST_NDRA, new S57enum(24, "no_dragging"));
     938        Restrn.put(RstRST.RST_NSTP, new S57enum(25, "no_stopping")); Restrn.put(RstRST.RST_NLND, new S57enum(26, "no_landing")); Restrn.put(RstRST.RST_RSPD, new S57enum(27, "restricted_speed"));
     939        Restrn.put(RstRST.RST_NOVT, new S57enum(28, "no_overtaking")); Restrn.put(RstRST.RST_NCOV, new S57enum(29, "no_convoy_overtaking")); Restrn.put(RstRST.RST_NPOV, new S57enum(30, "no_passing_overtaking"));
     940        Restrn.put(RstRST.RST_NBRT, new S57enum(31, "no_berthing")); Restrn.put(RstRST.RST_RBRT, new S57enum(32, "restricted_berthing")); Restrn.put(RstRST.RST_NMFT, new S57enum(33, "no_making_fast"));
     941        Restrn.put(RstRST.RST_RMFT, new S57enum(34, "restricted_making_fast")); Restrn.put(RstRST.RST_NTRN, new S57enum(35, "no_turning")); Restrn.put(RstRST.RST_RFWD, new S57enum(36, "restricted_fairway_depth"));
     942        Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
     943    }
     944
     945    public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
     946
     947    private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static {
     948        Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
     949        Siggen.put(SigGEN.GEN_AUTO, new S57enum(1, "automatic")); Siggen.put(SigGEN.GEN_WAVE, new S57enum(2, "wave")); Siggen.put(SigGEN.GEN_HAND, new S57enum(3, "hand")); Siggen.put(SigGEN.GEN_WIND, new S57enum(4, "wind"));
     950    }
     951
     952    public enum StsSTS { STS_UNKN, STS_PERM, STS_OCAS, STS_RCMD, STS_NIUS, STS_IMTT, STS_RESV, STS_TEMP, STS_PRIV, STS_MAND, STS_EXTD, STS_ILLD, STS_HIST, STS_PBLC,
     953        STS_SYNC, STS_WCHD, STS_UWCD, STS_EDBT, STS_OREQ, STS_DPAW, STS_RSNG, STS_INCR, STS_DECR, TS_STNG, STS_GOOD, STS_MODY, STS_POOR }
     954
     955    private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static {
     956        Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
     957        Status.put(StsSTS.STS_PERM, new S57enum(1, "permanent")); Status.put(StsSTS.STS_OCAS, new S57enum(2, "occasional")); Status.put(StsSTS.STS_RCMD, new S57enum(3, "recommended"));
     958        Status.put(StsSTS.STS_NIUS, new S57enum(4, "not_in_use")); Status.put(StsSTS.STS_IMTT, new S57enum(5, "intermittent")); Status.put(StsSTS.STS_RESV, new S57enum(6, "reserved"));
     959        Status.put(StsSTS.STS_TEMP, new S57enum(7, "temporary")); Status.put(StsSTS.STS_PRIV, new S57enum(8, "private")); Status.put(StsSTS.STS_MAND, new S57enum(9, "mandatory"));
     960        Status.put(StsSTS.STS_EXTD, new S57enum(11, "extinguished")); Status.put(StsSTS.STS_ILLD, new S57enum(12, "illuminated")); Status.put(StsSTS.STS_HIST, new S57enum(13, "historic"));
     961        Status.put(StsSTS.STS_PBLC, new S57enum(14, "public")); Status.put(StsSTS.STS_SYNC, new S57enum(15, "synchronised")); Status.put(StsSTS.STS_WCHD, new S57enum(16, "watched"));
     962        Status.put(StsSTS.STS_UWCD, new S57enum(17, "unwatched")); Status.put(StsSTS.STS_EDBT, new S57enum(18, "existence_doubtful")); Status.put(StsSTS.STS_OREQ, new S57enum(19, "on_request"));
     963        Status.put(StsSTS.STS_DPAW, new S57enum(20, "drop_away")); Status.put(StsSTS.STS_RSNG, new S57enum(21, "rising")); Status.put(StsSTS.STS_INCR, new S57enum(22, "increasing"));
     964        Status.put(StsSTS.STS_DECR, new S57enum(23, "decreasing")); Status.put(StsSTS.TS_STNG, new S57enum(24, "strong")); Status.put(StsSTS.STS_GOOD, new S57enum(25, "good"));
     965        Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
     966    }
     967
     968    public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
     969
     970    private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static {
     971        Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
     972        Surtyp.put(SurTYP.TYP_SKCH, new S57enum(1, "sketch")); Surtyp.put(SurTYP.TYP_CTLD, new S57enum(2, "controlled")); Surtyp.put(SurTYP.TYP_PSSG, new S57enum(4, "examination"));
     973        Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
     974    }
     975
     976    public enum TecSOU { SOU_UNKN, SOU_ESND, SOU_FSSN, SOU_MLBM, SOU_DIVR, SOU_LDLN, SOU_WDRG, SOU_LASR, SOU_VACC, SOU_EMAG, SOU_PHGY, SOU_SATL, SOU_LEVL, SOU_SSSN, SOU_COMP }
     977
     978    private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static {
     979        Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
     980        Tecsou.put(TecSOU.SOU_ESND, new S57enum(1, "echo-sounder")); Tecsou.put(TecSOU.SOU_FSSN, new S57enum(2, "side-scan_sonar")); Tecsou.put(TecSOU.SOU_MLBM, new S57enum(3, "multi-beam"));
     981        Tecsou.put(TecSOU.SOU_DIVR, new S57enum(4, "diver")); Tecsou.put(TecSOU.SOU_LDLN, new S57enum(5, "lead-line")); Tecsou.put(TecSOU.SOU_WDRG, new S57enum(6, "wire-drag"));
     982        Tecsou.put(TecSOU.SOU_LASR, new S57enum(7, "laser")); Tecsou.put(TecSOU.SOU_VACC, new S57enum(8, "vertical_acoustic")); Tecsou.put(TecSOU.SOU_EMAG, new S57enum(9, "electromagnetic"));
     983        Tecsou.put(TecSOU.SOU_PHGY, new S57enum(10, "photogrammetry")); Tecsou.put(TecSOU.SOU_SATL, new S57enum(11, "satellite")); Tecsou.put(TecSOU.SOU_LEVL, new S57enum(12, "levelling"));
     984        Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
     985    }
     986
     987    public enum TopSHP { TOP_UNKN, TOP_CONE, TOP_ICONE, TOP_SPHR, TOP_ISD, TOP_CAN, TOP_BORD, TOP_SALT, TOP_CROS, TOP_CUBE, TOP_WEST, TOP_EAST, TOP_RHOM,
     988        TOP_NORTH, TOP_SOUTH, TOP_BESM, TOP_IBESM, TOP_FLAG, TOP_SPRH, TOP_SQUR, TOP_HRECT, TOP_VRECT, TOP_TRAP, TOP_ITRAP, TOP_TRI, TOP_ITRI, TOP_CIRC,
     989        TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
     990
     991    private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static {
     992        Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
     993        Topshp.put(TopSHP.TOP_CONE, new S57enum(1, "cone, point up")); Topshp.put(TopSHP.TOP_ICONE, new S57enum(2, "cone, point down")); Topshp.put(TopSHP.TOP_SPHR, new S57enum(3, "sphere"));
     994        Topshp.put(TopSHP.TOP_ISD, new S57enum(4, "2 spheres")); Topshp.put(TopSHP.TOP_CAN, new S57enum(5, "cylinder")); Topshp.put(TopSHP.TOP_BORD, new S57enum(6, "board"));
     995        Topshp.put(TopSHP.TOP_SALT, new S57enum(7, "x-shape")); Topshp.put(TopSHP.TOP_CROS, new S57enum(8, "cross")); Topshp.put(TopSHP.TOP_CUBE, new S57enum(9, "cube, point up"));
     996        Topshp.put(TopSHP.TOP_WEST, new S57enum(10, "2 cones point together")); Topshp.put(TopSHP.TOP_EAST, new S57enum(11, "2 cones base together")); Topshp.put(TopSHP.TOP_RHOM, new S57enum(12, "rhombus"));
     997        Topshp.put(TopSHP.TOP_NORTH, new S57enum(13, "2 cones up")); Topshp.put(TopSHP.TOP_SOUTH, new S57enum(14, "2 cones down")); Topshp.put(TopSHP.TOP_BESM, new S57enum(15, "besom, point up"));
     998        Topshp.put(TopSHP.TOP_IBESM, new S57enum(16, "besom, point down")); Topshp.put(TopSHP.TOP_FLAG, new S57enum(17, "flag")); Topshp.put(TopSHP.TOP_SPRH, new S57enum(18, "sphere over rhombus"));
     999        Topshp.put(TopSHP.TOP_SQUR, new S57enum(19, "square")); Topshp.put(TopSHP.TOP_HRECT, new S57enum(20, "rectangle, horizontal")); Topshp.put(TopSHP.TOP_VRECT, new S57enum(21, "rectangle, vertical"));
     1000        Topshp.put(TopSHP.TOP_TRAP, new S57enum(22, "trapezium, up")); Topshp.put(TopSHP.TOP_ITRAP, new S57enum(23, "trapezium, down")); Topshp.put(TopSHP.TOP_TRI, new S57enum(24, "triangle, point up"));
     1001        Topshp.put(TopSHP.TOP_ITRI, new S57enum(25, "triangle, point down")); Topshp.put(TopSHP.TOP_CIRC, new S57enum(26, "circle")); Topshp.put(TopSHP.TOP_CRSS, new S57enum(27, "2 upright crosses"));
     1002        Topshp.put(TopSHP.TOP_T, new S57enum(28, "t-shape")); Topshp.put(TopSHP.TOP_TRCL, new S57enum(29, "triangle, point up over circle")); Topshp.put(TopSHP.TOP_CRCL, new S57enum(30, "upright cross over circle"));
     1003        Topshp.put(TopSHP.TOP_RHCL, new S57enum(31, "rhombus over circle")); Topshp.put(TopSHP.TOP_CLTR, new S57enum(32, "circle over triangle, point up")); Topshp.put(TopSHP.TOP_OTHR, new S57enum(33, "other"));
     1004        Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
     1005    }
     1006
     1007    public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
     1008
     1009    private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static {
     1010        Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
     1011        Trafic.put(TrfTRF.TRF_INBD, new S57enum(1, "inbound")); Trafic.put(TrfTRF.TRF_OBND, new S57enum(2, "outbbound")); Trafic.put(TrfTRF.TRF_ONEW, new S57enum(3, "one-way"));
     1012        Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
     1013    }
     1014
     1015    public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
     1016
     1017    private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static {
     1018        Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
     1019        Watlev.put(WatLEV.LEV_PSUB, new S57enum(1, "part-submerged")); Watlev.put(WatLEV.LEV_DRY, new S57enum(2, "dry")); Watlev.put(WatLEV.LEV_SUBM, new S57enum(3, "submerged"));
     1020        Watlev.put(WatLEV.LEV_CVRS, new S57enum(4, "covers")); Watlev.put(WatLEV.LEV_AWSH, new S57enum(5, "awash")); Watlev.put(WatLEV.LEV_FLDS, new S57enum(6, "floods"));
     1021        Watlev.put(WatLEV.LEV_FLTG, new S57enum(7, "floating")); Watlev.put(WatLEV.LEV_AMWL, new S57enum(8, "above_mwl")); Watlev.put(WatLEV.LEV_BMWL, new S57enum(9, "below_mwl"));
     1022    }
     1023
     1024    public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
     1025
     1026    private static final EnumMap<Cat_TS, S57enum> Cat_ts = new EnumMap<>(Cat_TS.class); static {
     1027        Cat_ts.put(Cat_TS.TS_UNKN, new S57enum(0, ""));
     1028        Cat_ts.put(Cat_TS.TS_FLOD, new S57enum(1, "flood")); Cat_ts.put(Cat_TS.TS_EBB, new S57enum(2, "ebb")); Cat_ts.put(Cat_TS.TS_OTHR, new S57enum(3, "other"));
     1029    }
     1030
     1031    public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS }
     1032
     1033    private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static {
     1034        Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
     1035        Punits.put(UniPAU.PAU_MTRS, new S57enum(1, "metres")); Punits.put(UniPAU.PAU_DGRS, new S57enum(2, "degrees")); Punits.put(UniPAU.PAU_MMTR, new S57enum(3, "millimetres"));
     1036        Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
     1037    }
     1038
     1039    public enum QuaPOS { POS_UNKN, POS_SRVD, POS_USRV, POS_PSRV, POS_APRX, POS_DBTF, POS_URLB, POS_RSRV, POS_UCNF, POS_ESTM, POS_PRCS, POS_CALC }
     1040
     1041    private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static {
     1042        Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
     1043        Quapos.put(QuaPOS.POS_SRVD, new S57enum(1, "surveyed")); Quapos.put(QuaPOS.POS_USRV, new S57enum(2, "unsurveyed")); Quapos.put(QuaPOS.POS_PSRV, new S57enum(3, "part-surveyed"));
     1044        Quapos.put(QuaPOS.POS_APRX, new S57enum(4, "approximate")); Quapos.put(QuaPOS.POS_DBTF, new S57enum(5, "doubtful")); Quapos.put(QuaPOS.POS_URLB, new S57enum(6, "unreliable"));
     1045        Quapos.put(QuaPOS.POS_RSRV, new S57enum(7, "reported_unsurveyd")); Quapos.put(QuaPOS.POS_UCNF, new S57enum(8, "unconfirmed")); Quapos.put(QuaPOS.POS_ESTM, new S57enum(9, "estimated"));
     1046        Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
     1047    }
     1048
     1049    public enum VerDAT { DAT_UNKN, DAT_MLWS, DAT_MLLWS, DAT_MSL, DAT_LLW, DAT_MLW, DAT_LLWS, DAT_AMLWS, DAT_ISLW, DAT_LWS, DAT_ALAT, DAT_NLLW, DAT_MLLW, DAT_LW, DAT_AMLW, DAT_AMLLW,
     1050        DAT_MHW, DAT_MHWS, DAT_HW, DAT_AMSL, DAT_HWS, DAT_MHHW, DAT_ESLW, DAT_LAT, DAT_LOCAL, DAT_IGLD, DAT_MWL, DAT_LLWLT, DAT_HHWLT, DAT_NHHW, DAT_HAT, DAT_LLWRL, DAT_LHWRL,
     1051        DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO }
     1052
     1053    private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static {
     1054        Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
     1055        Verdat.put(VerDAT.DAT_MLWS, new S57enum(1, "mlws")); Verdat.put(VerDAT.DAT_MLLWS, new S57enum(2, "mllws")); Verdat.put(VerDAT.DAT_MSL, new S57enum(3, "msl"));
     1056        Verdat.put(VerDAT.DAT_LLW, new S57enum(4, "llw")); Verdat.put(VerDAT.DAT_MLW, new S57enum(5, "mlw")); Verdat.put(VerDAT.DAT_LLWS, new S57enum(6, "llws"));
     1057        Verdat.put(VerDAT.DAT_AMLWS, new S57enum(7, "amlws")); Verdat.put(VerDAT.DAT_ISLW, new S57enum(8, "islw")); Verdat.put(VerDAT.DAT_LWS, new S57enum(9, "lws"));
     1058        Verdat.put(VerDAT.DAT_ALAT, new S57enum(10, "alat")); Verdat.put(VerDAT.DAT_NLLW, new S57enum(11, "nllw")); Verdat.put(VerDAT.DAT_MLLW, new S57enum(12, "mllw"));
     1059        Verdat.put(VerDAT.DAT_LW, new S57enum(13, "lw")); Verdat.put(VerDAT.DAT_AMLW, new S57enum(14, "amlw")); Verdat.put(VerDAT.DAT_AMLLW, new S57enum(15, "amllw"));
     1060        Verdat.put(VerDAT.DAT_MHW, new S57enum(16, "mhw")); Verdat.put(VerDAT.DAT_MHWS, new S57enum(17, "mhws")); Verdat.put(VerDAT.DAT_HW, new S57enum(18, "hw"));
     1061        Verdat.put(VerDAT.DAT_AMSL, new S57enum(19, "amsl")); Verdat.put(VerDAT.DAT_HWS, new S57enum(20, "hws")); Verdat.put(VerDAT.DAT_MHHW, new S57enum(21, "mhhw"));
     1062        Verdat.put(VerDAT.DAT_ESLW, new S57enum(22, "eslw")); Verdat.put(VerDAT.DAT_LAT, new S57enum(23, "lat")); Verdat.put(VerDAT.DAT_LOCAL, new S57enum(24, "local"));
     1063        Verdat.put(VerDAT.DAT_IGLD, new S57enum(25, "igld1985")); Verdat.put(VerDAT.DAT_MWL, new S57enum(26, "mwl")); Verdat.put(VerDAT.DAT_LLWLT, new S57enum(27, "llwlt"));
     1064        Verdat.put(VerDAT.DAT_HHWLT, new S57enum(28, "hhwlt")); Verdat.put(VerDAT.DAT_NHHW, new S57enum(29, "nhhw")); Verdat.put(VerDAT.DAT_HAT, new S57enum(30, "hat"));
     1065        Verdat.put(VerDAT.DAT_LLWRL, new S57enum(31, "llwrl")); Verdat.put(VerDAT.DAT_LHWRL, new S57enum(32, "lhwrl")); Verdat.put(VerDAT.DAT_LMWRL, new S57enum(33, "lmwrl"));
     1066        Verdat.put(VerDAT.DAT_EHW, new S57enum(34, "ehw_dglw")); Verdat.put(VerDAT.DAT_HSHW, new S57enum(35, "hshw_dhsw")); Verdat.put(VerDAT.DAT_RLWL, new S57enum(36, "rlwl_donau"));
     1067        Verdat.put(VerDAT.DAT_HSHWD, new S57enum(37, "hshw_donau")); Verdat.put(VerDAT.DAT_DRLWRL, new S57enum(38, "drlwrl_olr")); Verdat.put(VerDAT.DAT_RPWL, new S57enum(39, "rpwl"));
     1068        Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
     1069    }
     1070
     1071    public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
     1072
     1073    private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static {
     1074        Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
     1075        Addmrk.put(AddMRK.MRK_TOPB, new S57enum(1, "top_board")); Addmrk.put(AddMRK.MRK_BOTB, new S57enum(2, "bottom_board")); Addmrk.put(AddMRK.MRK_RTRI, new S57enum(3, "right_triangle"));
     1076        Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
     1077    }
     1078
     1079    public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
     1080
     1081    private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static {
     1082        Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
     1083        Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
     1084    }
     1085
     1086    public enum CatNMK { NMK_UNKN, NMK_NENT, NMK_CLSA, NMK_NOVK, NMK_NCOV, NMK_NPAS, NMK_NBRT, NMK_NBLL, NMK_NANK, NMK_NMOR, NMK_NTRN, NMK_NWSH,
     1087        NMK_NPSL, NMK_NPSR, NMK_NMTC, NMK_NSPC, NMK_NWSK, NMK_NSLC, NMK_NUPC, NMK_NSLB, NMK_NWBK, NMK_NHSC, NMK_NLBG, NMK_MVTL, NMK_MVTR, NMK_MVTP,
     1088        NMK_MVTS, NMK_KPTP, NMK_KPTS, NMK_CSTP, NMK_CSTS, NMK_STOP, NMK_SPDL, NMK_SHRN, NMK_KPLO, NMK_GWJN, NMK_GWCS, NMK_MKRC, NMK_LMDP, NMK_LMHR,
     1089        NMK_LMWD, NMK_NAVR, NMK_CHDL, NMK_CHDR, NMK_CHTW, NMK_CHOW, NMK_OPTR, NMK_OPTL, NMK_PRTL, NMK_PRTR, NMK_ENTP, NMK_OVHC, NMK_WEIR, NMK_FERN,
     1090        NMK_FERI, NMK_BRTP, NMK_BTLL, NMK_BTLS, NMK_BTRL, NMK_BTUP, NMK_BTP1, NMK_BTP2, NMK_BTP3, NMK_BTUN, NMK_BTN1, NMK_BTN2, NMK_BTN3, NMK_BTUM,
     1091        NMK_BTU1, NMK_BTU2, NMK_BTU3, NMK_ANKP, NMK_MORP, NMK_VLBT, NMK_TRNA, NMK_SWWC, NMK_SWWR, NMK_SWWL, NMK_WRSA, NMK_WLSA, NMK_WRSL, NMK_WLSR,
     1092        NMK_WRAL, NMK_WLAR, NMK_MWWC, NMK_MWWJ, NMK_MWAR, NMK_MWAL, NMK_WARL, NMK_WALR, NMK_PEND, NMK_DWTR, NMK_TELE, NMK_MTCP, NMK_SPCP, NMK_WSKP,
     1093        NMK_SLCP, NMK_UPCP, NMK_SLBP, NMK_RADI, NMK_WTBP, NMK_HSCP, NMK_LBGP, NMK_KTPM, NMK_KTSM, NMK_KTMR, NMK_CRTP, NMK_CRTS, NMK_TRBM, NMK_RSPD,
     1094        NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
     1095
     1096    private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static {
     1097        Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
     1098        Catnmk.put(CatNMK.NMK_NENT, new S57enum(1, "no_entry")); Catnmk.put(CatNMK.NMK_CLSA, new S57enum(2, "closed_area")); Catnmk.put(CatNMK.NMK_NOVK, new S57enum(3, "no_overtaking"));
     1099        Catnmk.put(CatNMK.NMK_NCOV, new S57enum(4, "no_convoy_overtaking")); Catnmk.put(CatNMK.NMK_NPAS, new S57enum(5, "no_passing")); Catnmk.put(CatNMK.NMK_NBRT, new S57enum(6, "no_berthing"));
     1100        Catnmk.put(CatNMK.NMK_NBLL, new S57enum(7, "no_berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_NANK, new S57enum(8, "no_anchoring")); Catnmk.put(CatNMK.NMK_NMOR, new S57enum(9, "no_mooring"));
     1101        Catnmk.put(CatNMK.NMK_NTRN, new S57enum(10, "no_turning")); Catnmk.put(CatNMK.NMK_NWSH, new S57enum(11, "no_wash")); Catnmk.put(CatNMK.NMK_NPSL, new S57enum(12, "no_passage_left"));
     1102        Catnmk.put(CatNMK.NMK_NPSR, new S57enum(13, "no_passage_right")); Catnmk.put(CatNMK.NMK_NMTC, new S57enum(14, "no_motor_craft")); Catnmk.put(CatNMK.NMK_NSPC, new S57enum(15, "no_sport_craft"));
     1103        Catnmk.put(CatNMK.NMK_NWSK, new S57enum(16, "no_waterskiing")); Catnmk.put(CatNMK.NMK_NSLC, new S57enum(17, "no_sailing_craft")); Catnmk.put(CatNMK.NMK_NUPC, new S57enum(18, "no_unpowered_craft"));
     1104        Catnmk.put(CatNMK.NMK_NSLB, new S57enum(19, "no_sailboards")); Catnmk.put(CatNMK.NMK_NWBK, new S57enum(20, "no_waterbikes")); Catnmk.put(CatNMK.NMK_NHSC, new S57enum(21, "no_high_speeds"));
     1105        Catnmk.put(CatNMK.NMK_NLBG, new S57enum(22, "no_launching_beaching")); Catnmk.put(CatNMK.NMK_MVTL, new S57enum(23, "move_to_left")); Catnmk.put(CatNMK.NMK_MVTR, new S57enum(24, "move_to_right"));
     1106        Catnmk.put(CatNMK.NMK_MVTP, new S57enum(25, "move_to_port")); Catnmk.put(CatNMK.NMK_MVTS, new S57enum(26, "move_to_starboard")); Catnmk.put(CatNMK.NMK_KPTP, new S57enum(27, "keep_to_port"));
     1107        Catnmk.put(CatNMK.NMK_KPTS, new S57enum(28, "keep_to_starboard")); Catnmk.put(CatNMK.NMK_CSTP, new S57enum(29, "cross_to_port")); Catnmk.put(CatNMK.NMK_CSTS, new S57enum(30, "cross_to_starboard"));
     1108        Catnmk.put(CatNMK.NMK_STOP, new S57enum(31, "stop")); Catnmk.put(CatNMK.NMK_SPDL, new S57enum(32, "speed_limit")); Catnmk.put(CatNMK.NMK_SHRN, new S57enum(33, "sound_horn"));
     1109        Catnmk.put(CatNMK.NMK_KPLO, new S57enum(34, "keep_lookout")); Catnmk.put(CatNMK.NMK_GWJN, new S57enum(35, "give_way_junction")); Catnmk.put(CatNMK.NMK_GWCS, new S57enum(36, "give_way_crossing"));
     1110        Catnmk.put(CatNMK.NMK_MKRC, new S57enum(37, "make_radio_contact")); Catnmk.put(CatNMK.NMK_LMDP, new S57enum(38, "limited_depth")); Catnmk.put(CatNMK.NMK_LMHR, new S57enum(39, "limited_headroom"));
     1111        Catnmk.put(CatNMK.NMK_LMWD, new S57enum(40, "limited_width")); Catnmk.put(CatNMK.NMK_NAVR, new S57enum(41, "navigation_restrictions")); Catnmk.put(CatNMK.NMK_CHDL, new S57enum(42, "channel_distance_left"));
     1112        Catnmk.put(CatNMK.NMK_CHDR, new S57enum(43, "channel_distance_right")); Catnmk.put(CatNMK.NMK_CHTW, new S57enum(44, "channel_two_way")); Catnmk.put(CatNMK.NMK_CHOW, new S57enum(45, "channel_one_way"));
     1113        Catnmk.put(CatNMK.NMK_OPTR, new S57enum(46, "opening_to_right")); Catnmk.put(CatNMK.NMK_OPTL, new S57enum(47, "opening_to_left")); Catnmk.put(CatNMK.NMK_PRTL, new S57enum(48, "proceed_to_left"));
     1114        Catnmk.put(CatNMK.NMK_PRTR, new S57enum(49, "proceed_to_right")); Catnmk.put(CatNMK.NMK_ENTP, new S57enum(50, "entry_permitted")); Catnmk.put(CatNMK.NMK_OVHC, new S57enum(51, "overhead_cable"));
     1115        Catnmk.put(CatNMK.NMK_WEIR, new S57enum(52, "weir")); Catnmk.put(CatNMK.NMK_FERN, new S57enum(53, "ferry_non_independent")); Catnmk.put(CatNMK.NMK_FERI, new S57enum(54, "ferry_independent"));
     1116        Catnmk.put(CatNMK.NMK_BRTP, new S57enum(55, "berthing_permitted")); Catnmk.put(CatNMK.NMK_BTLL, new S57enum(56, "berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_BTLS, new S57enum(57, "berthing_lateral_limits"));
     1117        Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit")); Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
     1118        Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
     1119        Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
     1120        Catnmk.put(CatNMK.NMK_BTN1, new S57enum(64, "berthing_marked_non-pushing_1")); Catnmk.put(CatNMK.NMK_BTN2, new S57enum(65, "berthing_marked_non-pushing_2"));
     1121        Catnmk.put(CatNMK.NMK_BTN3, new S57enum(66, "berthing_marked_non-pushing_3")); Catnmk.put(CatNMK.NMK_BTUM, new S57enum(67, "berthing_unmarked")); Catnmk.put(CatNMK.NMK_BTU1, new S57enum(68, "berthing_marked_1"));
     1122        Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
     1123        Catnmk.put(CatNMK.NMK_ANKP, new S57enum(71, "anchoring_permitted")); Catnmk.put(CatNMK.NMK_MORP, new S57enum(72, "mooring_permitted")); Catnmk.put(CatNMK.NMK_VLBT, new S57enum(73, "vehicle_loading_berth"));
     1124        Catnmk.put(CatNMK.NMK_TRNA, new S57enum(74, "turning_area")); Catnmk.put(CatNMK.NMK_SWWC, new S57enum(75, "secondary_waterway_crossing")); Catnmk.put(CatNMK.NMK_SWWR, new S57enum(76, "secondary_waterway_right"));
     1125        Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
     1126        Catnmk.put(CatNMK.NMK_WLSA, new S57enum(79, "main_waterway_left_secondary_ahead")); Catnmk.put(CatNMK.NMK_WRSL, new S57enum(80, "main_waterway_right_secondary_left"));
     1127        Catnmk.put(CatNMK.NMK_WLSR, new S57enum(81, "main_waterway_left_secondary_right")); Catnmk.put(CatNMK.NMK_WRAL, new S57enum(82, "main_waterway_right_secondary_ahead_left"));
     1128        Catnmk.put(CatNMK.NMK_WLAR, new S57enum(83, "main_waterway_left_secondary_ahead_right")); Catnmk.put(CatNMK.NMK_MWWC, new S57enum(84, "main_waterway_crossing"));
     1129        Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
     1130        Catnmk.put(CatNMK.NMK_MWAL, new S57enum(87, "main_waterway_ahead_left")); Catnmk.put(CatNMK.NMK_WARL, new S57enum(88, "main_waterway_ahead_right_secondary_left"));
     1131        Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
     1132        Catnmk.put(CatNMK.NMK_DWTR, new S57enum(91, "drinking_water")); Catnmk.put(CatNMK.NMK_TELE, new S57enum(92, "telephone")); Catnmk.put(CatNMK.NMK_MTCP, new S57enum(93, "motor_craft_permitted"));
     1133        Catnmk.put(CatNMK.NMK_SPCP, new S57enum(94, "sport_craft_permitted")); Catnmk.put(CatNMK.NMK_WSKP, new S57enum(95, "waterskiing_permitted")); Catnmk.put(CatNMK.NMK_SLCP, new S57enum(96, "sailing_craft_permitted"));
     1134        Catnmk.put(CatNMK.NMK_UPCP, new S57enum(97, "unpowered_craft_permitted")); Catnmk.put(CatNMK.NMK_SLBP, new S57enum(98, "sailboards_permitted")); Catnmk.put(CatNMK.NMK_RADI, new S57enum(99, "radio_information"));
     1135        Catnmk.put(CatNMK.NMK_WTBP, new S57enum(100, "waterbikes_permitted")); Catnmk.put(CatNMK.NMK_HSCP, new S57enum(101, "high_speeds_permitted")); Catnmk.put(CatNMK.NMK_LBGP, new S57enum(102, "launching_beaching_permitted"));
     1136        Catnmk.put(CatNMK.NMK_KTPM, new S57enum(103, "keep_to_port_margin")); Catnmk.put(CatNMK.NMK_KTSM, new S57enum(104, "keep_to_starboard_margin")); Catnmk.put(CatNMK.NMK_KTMR, new S57enum(105, "keep_to_mid-river"));
     1137        Catnmk.put(CatNMK.NMK_CRTP, new S57enum(106, "cross_river_to_port")); Catnmk.put(CatNMK.NMK_CRTS, new S57enum(107, "cross_river_to_starboard")); Catnmk.put(CatNMK.NMK_TRBM, new S57enum(108, "traffic_between_margins"));
     1138        Catnmk.put(CatNMK.NMK_RSPD, new S57enum(109, "reduce_speed")); Catnmk.put(CatNMK.NMK_WRKP, new S57enum(110, "wreck_pontoon")); Catnmk.put(CatNMK.NMK_PSBS, new S57enum(111, "pass_both_sides"));
     1139        Catnmk.put(CatNMK.NMK_NCPS, new S57enum(112, "no_convoy_passing")); Catnmk.put(CatNMK.NMK_NSMC, new S57enum(113, "no_small_craft")); Catnmk.put(CatNMK.NMK_ATTN, new S57enum(114, "attention"));
     1140        Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point"));
     1141    }
     1142
     1143    public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
     1144
     1145    private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static {
     1146        Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
     1147        Clsdng.put(ClsDNG.DNG_1BLU, new S57enum(1, "one_blue")); Clsdng.put(ClsDNG.DNG_2BLU, new S57enum(2, "two_blue")); Clsdng.put(ClsDNG.DNG_3BLU, new S57enum(3, "three_blue"));
     1148        Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
     1149    }
     1150
     1151    public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
     1152
     1153    private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static {
     1154        Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
     1155        Dirimp.put(DirIMP.IMP_UPST, new S57enum(1, "upstream")); Dirimp.put(DirIMP.IMP_DNST, new S57enum(2, "downstream")); Dirimp.put(DirIMP.IMP_LTBK, new S57enum(3, "left_bank"));
     1156        Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
     1157    }
     1158
     1159    public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
     1160
     1161    private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static {
     1162        Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
     1163        Fnctnm.put(FncFNM.FNM_PRHB, new S57enum(1, "prohibition")); Fnctnm.put(FncFNM.FNM_RGLN, new S57enum(2, "regulation")); Fnctnm.put(FncFNM.FNM_RSTN, new S57enum(3, "restriction"));
     1164        Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
     1165    }
     1166
     1167    public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
     1168
     1169    private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static {
     1170        Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
     1171        Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
     1172    }
     1173
     1174    public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS }
     1175
     1176    private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static {
     1177        Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
     1178        Catbrt.put(CatBRT.BRT_LODG, new S57enum(1, "loading")); Catbrt.put(CatBRT.BRT_ULDG, new S57enum(2, "unloading")); Catbrt.put(CatBRT.BRT_OVNT, new S57enum(3, "overnight_accommodation"));
     1179        Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
     1180        Catbrt.put(CatBRT.BRT_FLTG, new S57enum(6, "fleeting")); Catbrt.put(CatBRT.BRT_FCLS, new S57enum(7, "first_class")); Catbrt.put(CatBRT.BRT_SCLS, new S57enum(8, "second_class"));
     1181    }
     1182
     1183    public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
     1184
     1185    private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static {
     1186        Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
     1187        Catbun.put(CatBUN.BUN_DESL, new S57enum(1, "diesel")); Catbun.put(CatBUN.BUN_WATR, new S57enum(2, "water")); Catbun.put(CatBUN.BUN_BLST, new S57enum(3, "ballast"));
     1188    }
     1189
     1190    public enum CatCCL { CCL_UNKN, CCL_SMLV, CCL_PNCH, CCL_CMPB, CCL_DMEB, CCL_RHNB, CCL_1BPT, CCL_2PTL, CCL_2PTW, CCL_4BPT, CCL_6BPT, CCL_NCCL }
     1191
     1192    private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static {
     1193        Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
     1194        Catccl.put(CatCCL.CCL_SMLV, new S57enum(1, "small_vessels")); Catccl.put(CatCCL.CCL_PNCH, new S57enum(2, "peniche")); Catccl.put(CatCCL.CCL_CMPB, new S57enum(3, "campine_barge"));
     1195        Catccl.put(CatCCL.CCL_DMEB, new S57enum(4, "dortmund-ems_barge")); Catccl.put(CatCCL.CCL_RHNB, new S57enum(5, "rhine-herne_barge")); Catccl.put(CatCCL.CCL_1BPT, new S57enum(6, "1-barge_push-tow"));
     1196        Catccl.put(CatCCL.CCL_2PTL, new S57enum(7, "2-barge_push-tow_long")); Catccl.put(CatCCL.CCL_2PTW, new S57enum(8, "2-barge_push-tow_wide")); Catccl.put(CatCCL.CCL_4BPT, new S57enum(9, "4-barge_push-tow"));
     1197        Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
     1198    }
     1199
     1200    public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR }
     1201
     1202    private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static {
     1203        Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
     1204        Catcom.put(CatCOM.COM_VTSC, new S57enum(1, "vts_centre")); Catcom.put(CatCOM.COM_VTSS, new S57enum(2, "vts_sector")); Catcom.put(CatCOM.COM_IVSP, new S57enum(3, "ivs_point"));
     1205        Catcom.put(CatCOM.COM_MID, new S57enum(4, "mib")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
     1206        Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
     1207    }
     1208
     1209    public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
     1210
     1211    private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static {
     1212        Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
     1213        Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "customs")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
     1214        Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
     1215    }
     1216
     1217    public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF }
     1218
     1219    private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static {
     1220        Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
     1221        Catrfd.put(CatRFD.RFD_CRSD, new S57enum(1, "cargo_residue")); Catrfd.put(CatRFD.RFD_WOIL, new S57enum(2, "waste_oil")); Catrfd.put(CatRFD.RFD_GBWT, new S57enum(3, "grey_black_water"));
     1222        Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
     1223    }
     1224
     1225    public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
     1226
     1227    private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static {
     1228        Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
     1229        Cattml.put(CatTML.TML_PSGR, new S57enum(1, "passenger")); Cattml.put(CatTML.TML_FERY, new S57enum(2, "ferry")); Cattml.put(CatTML.TML_TSPT, new S57enum(3, "transhipment"));
     1230        Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
     1231    }
     1232
     1233    public enum TrsTGD { TGD_UNKN, TGD_CONT, TGD_BULK, TGD_OIL, TGD_FUEL, TGD_CHEM, TGD_LIQD, TGD_EXPL, TGD_FISH, TGD_CARS, TGD_GNRL }
     1234
     1235    private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static {
     1236        Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
     1237        Trshgd.put(TrsTGD.TGD_CONT, new S57enum(1, "containers")); Trshgd.put(TrsTGD.TGD_BULK, new S57enum(2, "bulk")); Trshgd.put(TrsTGD.TGD_OIL, new S57enum(3, "oil"));
     1238        Trshgd.put(TrsTGD.TGD_FUEL, new S57enum(4, "fuel")); Trshgd.put(TrsTGD.TGD_CHEM, new S57enum(5, "chemicals")); Trshgd.put(TrsTGD.TGD_LIQD, new S57enum(6, "liquid"));
     1239        Trshgd.put(TrsTGD.TGD_EXPL, new S57enum(7, "explosive")); Trshgd.put(TrsTGD.TGD_FISH, new S57enum(8, "fish")); Trshgd.put(TrsTGD.TGD_CARS, new S57enum(9, "cars"));
     1240        Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
     1241    }
     1242
     1243    public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI }
     1244
     1245    private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static {
     1246        Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
     1247        Catgag.put(CatGAG.GAG_STAF, new S57enum(1, "staff")); Catgag.put(CatGAG.GAG_RCRD, new S57enum(2, "recording")); Catgag.put(CatGAG.GAG_RCRA, new S57enum(3, "recording_remote_access"));
     1248        Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
     1249    }
     1250
     1251    public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 }
     1252
     1253    private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static {
     1254        Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
     1255        Reflev.put(RefLEV.LEV_BALT, new S57enum(1, "baltic")); Reflev.put(RefLEV.LEV_ADRC, new S57enum(2, "adriatic")); Reflev.put(RefLEV.LEV_AMSD, new S57enum(3, "amsterdam"));
     1256        Reflev.put(RefLEV.LEV_MSL, new S57enum(4, "msl")); Reflev.put(RefLEV.LEV_OTHR, new S57enum(5, "other")); Reflev.put(RefLEV.LEV_NG29, new S57enum(6, "ngvd29"));
     1257        Reflev.put(RefLEV.LEV_NA88, new S57enum(7, "navd88")); Reflev.put(RefLEV.LEV_1912, new S57enum(8, "msl1912")); Reflev.put(RefLEV.LEV_1929, new S57enum(9, "msl1929"));
     1258    }
     1259
     1260    public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
     1261
     1262    private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static {
     1263        Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
     1264        Catvtr.put(CatVTR.VTR_OFFL, new S57enum(1, "official")); Catvtr.put(CatVTR.VTR_PRIV, new S57enum(2, "private")); Catvtr.put(CatVTR.VTR_CARC, new S57enum(3, "car_cranes"));
     1265        Catvtr.put(CatVTR.VTR_CARP, new S57enum(4, "car_planks")); Catvtr.put(CatVTR.VTR_PREQ, new S57enum(5, "permission_required")); Catvtr.put(CatVTR.VTR_LGAT, new S57enum(6, "locked_gate"));
     1266    }
     1267
     1268    public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
     1269
     1270    private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static {
     1271        Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
     1272        Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
     1273    }
     1274
     1275    public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
     1276
     1277    private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static {
     1278        Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
     1279        Useshp.put(UseSHP.SHP_LINT, new S57enum(1, "liner_trade")); Useshp.put(UseSHP.SHP_OCSH, new S57enum(2, "occasional_professional_shipping")); Useshp.put(UseSHP.SHP_LESR, new S57enum(3, "leisure"));
     1280    }
     1281
     1282    public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR }
     1283
     1284    private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static {
     1285        Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
     1286        Catexs.put(CatEXS.EXS_LLOK, new S57enum(1, "lift-lock")); Catexs.put(CatEXS.EXS_AQDT, new S57enum(2, "aqueduct")); Catexs.put(CatEXS.EXS_SPLK, new S57enum(3, "sloping_plane_lock"));
     1287        Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
     1288    }
     1289
     1290    public enum CatWWM { WWM_UNKN, WWM_WWRT, WWM_WWLT, WWM_WWSP, WWM_CHRT, WWM_CHLT, WWM_CHSP, WWM_CHRB, WWM_CHLB, WWM_CORT, WWM_COLT, WWM_DGRT, WWM_DGLT,
     1291        WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR }
     1292
     1293    private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static {
     1294        Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
     1295        Catwwm.put(CatWWM.WWM_WWRT, new S57enum(1, "waterway_right")); Catwwm.put(CatWWM.WWM_WWLT, new S57enum(2, "waterway_left")); Catwwm.put(CatWWM.WWM_WWSP, new S57enum(3, "waterway_separation"));
     1296        Catwwm.put(CatWWM.WWM_CHRT, new S57enum(4, "channel_right")); Catwwm.put(CatWWM.WWM_CHLT, new S57enum(5, "channel_left")); Catwwm.put(CatWWM.WWM_CHSP, new S57enum(6, "channel_separation"));
     1297        Catwwm.put(CatWWM.WWM_CHRB, new S57enum(7, "channel_right_bank")); Catwwm.put(CatWWM.WWM_CHLB, new S57enum(8, "channel_left_bank")); Catwwm.put(CatWWM.WWM_CORT, new S57enum(9, "crossover_right"));
     1298        Catwwm.put(CatWWM.WWM_COLT, new S57enum(10, "crossover_left")); Catwwm.put(CatWWM.WWM_DGRT, new S57enum(11, "danger_right")); Catwwm.put(CatWWM.WWM_DGLT, new S57enum(12, "danger_left"));
     1299        Catwwm.put(CatWWM.WWM_TORT, new S57enum(13, "turnoff_right")); Catwwm.put(CatWWM.WWM_TOLT, new S57enum(14, "turnoff_left")); Catwwm.put(CatWWM.WWM_JNRT, new S57enum(15, "junction_right"));
     1300        Catwwm.put(CatWWM.WWM_JNLT, new S57enum(16, "junction_left")); Catwwm.put(CatWWM.WWM_HBRT, new S57enum(17, "harbour_right")); Catwwm.put(CatWWM.WWM_HBLT, new S57enum(18, "harbour_left"));
     1301        Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
     1302    }
     1303
     1304    public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
     1305
     1306    private static final EnumMap<Lg_SPR, S57enum> Lg_spr = new EnumMap<>(Lg_SPR.class); static {
     1307        Lg_spr.put(Lg_SPR.SPR_UNKN, new S57enum(0, ""));
     1308        Lg_spr.put(Lg_SPR.SPR_OTHR, new S57enum(1, "other")); Lg_spr.put(Lg_SPR.SPR_SPOG, new S57enum(2, "speed_over_ground")); Lg_spr.put(Lg_SPR.SPR_SPTW, new S57enum(3, "speed_through_water"));
     1309    }
     1310
     1311    public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
     1312
     1313    private static final EnumMap<Lg_WDU, S57enum> Lg_wdu = new EnumMap<>(Lg_WDU.class); static {
     1314        Lg_wdu.put(Lg_WDU.WDU_UNKN, new S57enum(0, ""));
     1315        Lg_wdu.put(Lg_WDU.WDU_OTHR, new S57enum(1, "other")); Lg_wdu.put(Lg_WDU.WDU_CUMT, new S57enum(2, "cubic_metres")); Lg_wdu.put(Lg_WDU.WDU_TONS, new S57enum(3, "tonnes"));
     1316    }
     1317
     1318    public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
     1319
     1320    private static final EnumMap<Lg_REL, S57enum> Lg_rel = new EnumMap<>(Lg_REL.class); static {
     1321        Lg_rel.put(Lg_REL.REL_UNKN, new S57enum(0, ""));
     1322        Lg_rel.put(Lg_REL.REL_OTHR, new S57enum(1, "other")); Lg_rel.put(Lg_REL.REL_USWW, new S57enum(2, "usage_of_waterway")); Lg_rel.put(Lg_REL.REL_CREQ, new S57enum(3, "carriage_of_equipment"));
     1323        Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
     1324    }
     1325
     1326    public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD }
     1327
     1328    private static final EnumMap<Lg_FNC, S57enum> Lg_fnc = new EnumMap<>(Lg_FNC.class); static {
     1329        Lg_fnc.put(Lg_FNC.FNC_UNKN, new S57enum(0, ""));
     1330        Lg_fnc.put(Lg_FNC.FNC_OTHR, new S57enum(1, "other")); Lg_fnc.put(Lg_FNC.FNC_PRHB, new S57enum(2, "prohibited")); Lg_fnc.put(Lg_FNC.FNC_PRHE, new S57enum(3, "prohibited_with_exceptions"));
     1331        Lg_fnc.put(Lg_FNC.FNC_PERM, new S57enum(4, "permitted")); Lg_fnc.put(Lg_FNC.FNC_PERE, new S57enum(5, "permitted_with_exceptions")); Lg_fnc.put(Lg_FNC.FNC_RCMD, new S57enum(6, "recommended"));
     1332        Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
     1333    }
     1334
     1335    public enum Lc_CSX { CSX_UNKN, CSX_ALL, CSX_OTHR, CSX_NMOT, CSX_CRFT, CSX_VSSL, CSX_ILWW, CSX_SEAG, CSX_MOTR, CSX_MTNK, CSX_MCGO, CSX_CBRG, CSX_TUG, CSX_PSHR, CSX_BARG, CSX_TNKB,
     1336        CSX_DMBB, CSX_LGTR, CSX_TNKL, CSX_CGOL, CSX_SBLR, CSX_PSGR, CSX_PSGS, CSX_DAYT, CSX_CABN, CSX_HSPD, CSX_FLEQ, CSX_WSIT, CSX_RCNL, CSX_DNGY, CSX_FEST, CSX_FOBJ }
     1337
     1338    private static final EnumMap<Lc_CSX, S57enum> Lc_csi = new EnumMap<>(Lc_CSX.class); static {
     1339        Lc_csi.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
     1340        Lc_csi.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_csi.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_csi.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
     1341        Lc_csi.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_csi.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_csi.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
     1342        Lc_csi.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_csi.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_csi.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
     1343        Lc_csi.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_csi.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_csi.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
     1344        Lc_csi.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_csi.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_csi.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
     1345        Lc_csi.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_csi.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_csi.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
     1346        Lc_csi.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_csi.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_csi.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
     1347        Lc_csi.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_csi.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_csi.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
     1348        Lc_csi.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_csi.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_csi.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
     1349        Lc_csi.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_csi.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_csi.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
     1350        Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
     1351    }
     1352
     1353    private static final EnumMap<Lc_CSX, S57enum> Lc_cse = new EnumMap<>(Lc_CSX.class); static {
     1354        Lc_cse.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
     1355        Lc_cse.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_cse.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_cse.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
     1356        Lc_cse.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_cse.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_cse.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
     1357        Lc_cse.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_cse.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_cse.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
     1358        Lc_cse.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_cse.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_cse.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
     1359        Lc_cse.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_cse.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_cse.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
     1360        Lc_cse.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_cse.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_cse.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
     1361        Lc_cse.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_cse.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_cse.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
     1362        Lc_cse.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_cse.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_cse.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
     1363        Lc_cse.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_cse.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_cse.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
     1364        Lc_cse.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_cse.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_cse.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
     1365        Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
     1366    }
     1367
     1368    public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV }
     1369
     1370    private static final EnumMap<Lc_ASX, S57enum> Lc_asi = new EnumMap<>(Lc_ASX.class); static {
     1371        Lc_asi.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
     1372        Lc_asi.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_asi.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_asi.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
     1373        Lc_asi.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_asi.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_asi.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
     1374        Lc_asi.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_asi.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_asi.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
     1375    }
     1376
     1377    private static final EnumMap<Lc_ASX, S57enum> Lc_ase = new EnumMap<>(Lc_ASX.class); static {
     1378        Lc_ase.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
     1379        Lc_ase.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_ase.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_ase.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
     1380        Lc_ase.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_ase.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_ase.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
     1381        Lc_ase.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_ase.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_ase.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
     1382    }
     1383
     1384    public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS }
     1385
     1386    private static final EnumMap<Lc_CCX, S57enum> Lc_cci = new EnumMap<>(Lc_CCX.class); static {
     1387        Lc_cci.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
     1388        Lc_cci.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cci.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cci.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
     1389        Lc_cci.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cci.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cci.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
     1390        Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
     1391    }
     1392
     1393    private static final EnumMap<Lc_CCX, S57enum> Lc_cce = new EnumMap<>(Lc_CCX.class); static {
     1394        Lc_cce.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
     1395        Lc_cce.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cce.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cce.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
     1396        Lc_cce.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cce.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cce.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
     1397        Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
     1398    }
     1399
     1400    public enum ShpTYP { TYP_UNKN, TYP_CRGO, TYP_CONT, TYP_TNKR, TYP_SAIL, TYP_FISH, TYP_SPPS, TYP_MOWR, TYP_SUBM, TYP_HSPD, TYP_BCAR, TYP_SPLN, TYP_TUGB, TYP_PSGR, TYP_FERY, TYP_BOAT }
     1401
     1402    private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static {
     1403        Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
     1404        Shptyp.put(ShpTYP.TYP_CRGO, new S57enum(1, "cargo")); Shptyp.put(ShpTYP.TYP_CONT, new S57enum(2, "container")); Shptyp.put(ShpTYP.TYP_TNKR, new S57enum(3, "tanker"));
     1405        Shptyp.put(ShpTYP.TYP_SAIL, new S57enum(4, "sailing")); Shptyp.put(ShpTYP.TYP_FISH, new S57enum(5, "fishing")); Shptyp.put(ShpTYP.TYP_SPPS, new S57enum(6, "special_purpose."));
     1406        Shptyp.put(ShpTYP.TYP_MOWR, new S57enum(7, "man_of_war")); Shptyp.put(ShpTYP.TYP_SUBM, new S57enum(8, "submarine")); Shptyp.put(ShpTYP.TYP_HSPD, new S57enum(9, "high-speed"));
     1407        Shptyp.put(ShpTYP.TYP_BCAR, new S57enum(10, "bulk_carrier")); Shptyp.put(ShpTYP.TYP_SPLN, new S57enum(11, "seaplane")); Shptyp.put(ShpTYP.TYP_TUGB, new S57enum(12, "tugboat"));
     1408        Shptyp.put(ShpTYP.TYP_PSGR, new S57enum(13, "passenger")); Shptyp.put(ShpTYP.TYP_FERY, new S57enum(14, "ferry")); Shptyp.put(ShpTYP.TYP_BOAT, new S57enum(15, "boat"));
     1409    }
     1410
     1411    public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
     1412
     1413    private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static {
     1414        Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
     1415        Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
     1416    }
     1417
     1418    private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
     1419    static {
     1420        keys.put(Att.UNKATT, new S57key(Conv.A, null)); keys.put(Att.AGENCY, new S57key(Conv.A, null)); keys.put(Att.BCNSHP, new S57key(Conv.E, Bcnshp));
     1421        keys.put(Att.BUISHP, new S57key(Conv.E, Buishp)); keys.put(Att.BOYSHP, new S57key(Conv.E, Boyshp)); keys.put(Att.BURDEP, new S57key(Conv.F, null));
     1422        keys.put(Att.CALSGN, new S57key(Conv.S, null)); keys.put(Att.CATAIR, new S57key(Conv.L, Catair)); keys.put(Att.CATACH, new S57key(Conv.L, Catach));
     1423        keys.put(Att.CATBRG, new S57key(Conv.L, Catbrg)); keys.put(Att.CATBUA, new S57key(Conv.E, Catbua)); keys.put(Att.CATCBL, new S57key(Conv.E, Catcbl));
     1424        keys.put(Att.CATCAN, new S57key(Conv.E, Catcan)); keys.put(Att.CATCAM, new S57key(Conv.E, Catcam)); keys.put(Att.CATCHP, new S57key(Conv.E, Catchp));
     1425        keys.put(Att.CATCOA, new S57key(Conv.E, Catcoa)); keys.put(Att.CATCTR, new S57key(Conv.E, Catctr)); keys.put(Att.CATCON, new S57key(Conv.E, Catcon));
     1426        keys.put(Att.CATCRN, new S57key(Conv.E, Catcrn)); keys.put(Att.CATDAM, new S57key(Conv.E, Catdam)); keys.put(Att.CATDIS, new S57key(Conv.E, Catdis));
     1427        keys.put(Att.CATDOC, new S57key(Conv.E, Catdoc)); keys.put(Att.CATDPG, new S57key(Conv.L, Catdpg)); keys.put(Att.CATFNC, new S57key(Conv.E, Catfnc));
     1428        keys.put(Att.CATFRY, new S57key(Conv.E, Catfry)); keys.put(Att.CATFIF, new S57key(Conv.E, Catfif)); keys.put(Att.CATFOG, new S57key(Conv.E, Catfog));
     1429        keys.put(Att.CATFOR, new S57key(Conv.E, Catfor)); keys.put(Att.CATGAT, new S57key(Conv.E, Catgat)); keys.put(Att.CATHAF, new S57key(Conv.L, Cathaf));
     1430        keys.put(Att.CATHLK, new S57key(Conv.L, Cathlk)); keys.put(Att.CATICE, new S57key(Conv.E, Catice)); keys.put(Att.CATINB, new S57key(Conv.E, Catinb));
     1431        keys.put(Att.CATLND, new S57key(Conv.L, Catlnd)); keys.put(Att.CATLMK, new S57key(Conv.L, Catlmk)); keys.put(Att.CATLAM, new S57key(Conv.E, Catlam));
     1432        keys.put(Att.CATLIT, new S57key(Conv.L, Catlit)); keys.put(Att.CATMFA, new S57key(Conv.E, Catmfa)); keys.put(Att.CATMPA, new S57key(Conv.L, Catmpa));
     1433        keys.put(Att.CATMOR, new S57key(Conv.E, Catmor)); keys.put(Att.CATNAV, new S57key(Conv.E, Catnav)); keys.put(Att.CATOBS, new S57key(Conv.E, Catobs));
     1434        keys.put(Att.CATOFP, new S57key(Conv.L, Catofp)); keys.put(Att.CATOLB, new S57key(Conv.E, Catolb)); keys.put(Att.CATPLE, new S57key(Conv.E, Catple));
     1435        keys.put(Att.CATPIL, new S57key(Conv.E, Catpil)); keys.put(Att.CATPIP, new S57key(Conv.L, Catpip)); keys.put(Att.CATPRA, new S57key(Conv.E, Catpra));
     1436        keys.put(Att.CATPYL, new S57key(Conv.E, Catpyl)); keys.put(Att.CATRAS, new S57key(Conv.E, Catras)); keys.put(Att.CATRTB, new S57key(Conv.E, Catrtb));
     1437        keys.put(Att.CATROS, new S57key(Conv.L, Catros)); keys.put(Att.CATTRK, new S57key(Conv.E, Cattrk)); keys.put(Att.CATRSC, new S57key(Conv.L, Catrsc));
     1438        keys.put(Att.CATREA, new S57key(Conv.L, Catrea)); keys.put(Att.CATROD, new S57key(Conv.E, Catrod)); keys.put(Att.CATRUN, new S57key(Conv.E, Catrun));
     1439        keys.put(Att.CATSEA, new S57key(Conv.E, Catsea)); keys.put(Att.CATSIL, new S57key(Conv.E, Catsil)); keys.put(Att.CATSLO, new S57key(Conv.E, Catslo));
     1440        keys.put(Att.CATSCF, new S57key(Conv.L, Catscf)); keys.put(Att.CATSLC, new S57key(Conv.E, Catslc)); keys.put(Att.CATSIT, new S57key(Conv.L, Catsit));
     1441        keys.put(Att.CATSIW, new S57key(Conv.L, Catsiw)); keys.put(Att.CATSPM, new S57key(Conv.L, Catspm)); keys.put(Att.CATTSS, new S57key(Conv.E, Cattss));
     1442        keys.put(Att.CATVEG, new S57key(Conv.L, Catveg)); keys.put(Att.CATWAT, new S57key(Conv.E, Catwat)); keys.put(Att.CATWED, new S57key(Conv.E, Catwed));
     1443        keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
     1444        keys.put(Att.COLPAT, new S57key(Conv.L, Colpat)); keys.put(Att.COMCHA, new S57key(Conv.A, null)); keys.put(Att.CPDATE, new S57key(Conv.A, null));
     1445        keys.put(Att.CSCALE, new S57key(Conv.I, null)); keys.put(Att.CONDTN, new S57key(Conv.E, Condtn)); keys.put(Att.CONRAD, new S57key(Conv.E, Conrad));
     1446        keys.put(Att.CONVIS, new S57key(Conv.E, Convis)); keys.put(Att.CURVEL, new S57key(Conv.F, null)); keys.put(Att.DATEND, new S57key(Conv.A, null));
     1447        keys.put(Att.DATSTA, new S57key(Conv.A, null)); keys.put(Att.DRVAL1, new S57key(Conv.F, null)); keys.put(Att.DRVAL2, new S57key(Conv.F, null));
     1448        keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
     1449        keys.put(Att.EXCLIT, new S57key(Conv.E, Exclit)); keys.put(Att.EXPSOU, new S57key(Conv.E, Expsou)); keys.put(Att.FUNCTN, new S57key(Conv.L, Functn));
     1450        keys.put(Att.HEIGHT, new S57key(Conv.F, null)); keys.put(Att.HUNITS, new S57key(Conv.E, Hunits)); keys.put(Att.HORACC, new S57key(Conv.F, null));
     1451        keys.put(Att.HORCLR, new S57key(Conv.F, null)); keys.put(Att.HORLEN, new S57key(Conv.F, null)); keys.put(Att.HORWID, new S57key(Conv.F, null));
     1452        keys.put(Att.ICEFAC, new S57key(Conv.F, null)); keys.put(Att.INFORM, new S57key(Conv.S, null)); keys.put(Att.JRSDTN, new S57key(Conv.E, Jrsdtn));
     1453        keys.put(Att.LIFCAP, new S57key(Conv.F, null)); keys.put(Att.LITCHR, new S57key(Conv.E, Litchr)); keys.put(Att.LITVIS, new S57key(Conv.L, Litvis));
     1454        keys.put(Att.MARSYS, new S57key(Conv.E, Marsys)); keys.put(Att.MLTYLT, new S57key(Conv.I, null)); keys.put(Att.NATION, new S57key(Conv.A, null));
     1455        keys.put(Att.NATCON, new S57key(Conv.L, Natcon)); keys.put(Att.NATSUR, new S57key(Conv.L, Natsur)); keys.put(Att.NATQUA, new S57key(Conv.L, Natqua));
     1456        keys.put(Att.NMDATE, new S57key(Conv.A, null)); keys.put(Att.OBJNAM, new S57key(Conv.S, null)); keys.put(Att.ORIENT, new S57key(Conv.F, null));
     1457        keys.put(Att.PEREND, new S57key(Conv.A, null)); keys.put(Att.PERSTA, new S57key(Conv.A, null)); keys.put(Att.PICREP, new S57key(Conv.S, null));
     1458        keys.put(Att.PILDST, new S57key(Conv.S, null)); keys.put(Att.PRCTRY, new S57key(Conv.A, null)); keys.put(Att.PRODCT, new S57key(Conv.L, Prodct));
     1459        keys.put(Att.PUBREF, new S57key(Conv.S, null)); keys.put(Att.QUASOU, new S57key(Conv.L, Quasou)); keys.put(Att.RADWAL, new S57key(Conv.A, null));
     1460        keys.put(Att.RADIUS, new S57key(Conv.F, null));
     1461        keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
     1462        keys.put(Att.SCAMIN, new S57key(Conv.I, null)); keys.put(Att.SCVAL1, new S57key(Conv.I, null)); keys.put(Att.SCVAL2, new S57key(Conv.I, null));
     1463        keys.put(Att.SECTR1, new S57key(Conv.F, null)); keys.put(Att.SECTR2, new S57key(Conv.F, null)); keys.put(Att.SHIPAM, new S57key(Conv.A, null));
     1464        keys.put(Att.SIGFRQ, new S57key(Conv.I, null)); keys.put(Att.SIGGEN, new S57key(Conv.E, Siggen)); keys.put(Att.SIGGRP, new S57key(Conv.A, null));
     1465        keys.put(Att.SIGPER, new S57key(Conv.F, null)); keys.put(Att.SIGSEQ, new S57key(Conv.A, null)); keys.put(Att.SOUACC, new S57key(Conv.F, null));
     1466        keys.put(Att.SDISMX, new S57key(Conv.I, null)); keys.put(Att.SDISMN, new S57key(Conv.I, null)); keys.put(Att.SORDAT, new S57key(Conv.A, null));
     1467        keys.put(Att.SORIND, new S57key(Conv.A, null)); keys.put(Att.STATUS, new S57key(Conv.L, Status)); keys.put(Att.SURATH, new S57key(Conv.S, null));
     1468        keys.put(Att.SUREND, new S57key(Conv.A, null)); keys.put(Att.SURSTA, new S57key(Conv.A, null)); keys.put(Att.SURTYP, new S57key(Conv.L, Surtyp));
     1469        keys.put(Att.TECSOU, new S57key(Conv.L, Tecsou)); keys.put(Att.TXTDSC, new S57key(Conv.S, null)); keys.put(Att.TS_TSP, new S57key(Conv.A, null));
     1470        keys.put(Att.TS_TSV, new S57key(Conv.A, null)); keys.put(Att.T_ACWL, new S57key(Conv.E, null)); keys.put(Att.T_HWLW, new S57key(Conv.A, null));
     1471        keys.put(Att.T_MTOD, new S57key(Conv.E, null)); keys.put(Att.T_THDF, new S57key(Conv.A, null)); keys.put(Att.T_TINT, new S57key(Conv.I, null));
     1472        keys.put(Att.T_TSVL, new S57key(Conv.A, null)); keys.put(Att.T_VAHC, new S57key(Conv.A, null)); keys.put(Att.TIMEND, new S57key(Conv.A, null));
     1473        keys.put(Att.TIMSTA, new S57key(Conv.A, null)); keys.put(Att.TOPSHP, new S57key(Conv.E, Topshp)); keys.put(Att.TRAFIC, new S57key(Conv.E, Trafic));
     1474        keys.put(Att.VALACM, new S57key(Conv.F, null)); keys.put(Att.VALDCO, new S57key(Conv.F, null)); keys.put(Att.VALLMA, new S57key(Conv.F, null));
     1475        keys.put(Att.VALMAG, new S57key(Conv.F, null)); keys.put(Att.VALMXR, new S57key(Conv.F, null)); keys.put(Att.VALNMR, new S57key(Conv.F, null));
     1476        keys.put(Att.VALSOU, new S57key(Conv.F, null)); keys.put(Att.VERACC, new S57key(Conv.F, null)); keys.put(Att.VERCLR, new S57key(Conv.F, null));
     1477        keys.put(Att.VERCCL, new S57key(Conv.F, null)); keys.put(Att.VERCOP, new S57key(Conv.F, null)); keys.put(Att.VERCSA, new S57key(Conv.F, null));
     1478        keys.put(Att.VERDAT, new S57key(Conv.E, Verdat)); keys.put(Att.VERLEN, new S57key(Conv.F, null)); keys.put(Att.WATLEV, new S57key(Conv.E, Watlev));
     1479        keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
     1480        keys.put(Att.NOBJNM, new S57key(Conv.S, null)); keys.put(Att.NPLDST, new S57key(Conv.S, null)); keys.put(Att.NTXTDS, new S57key(Conv.S, null));
     1481        keys.put(Att.HORDAT, new S57key(Conv.E, null)); keys.put(Att.POSACC, new S57key(Conv.F, null)); keys.put(Att.QUAPOS, new S57key(Conv.E, Quapos));
     1482        keys.put(Att.CLSDNG, new S57key(Conv.E, Clsdng)); keys.put(Att.DIRIMP, new S57key(Conv.L, Dirimp)); keys.put(Att.DISBK1, new S57key(Conv.F, null));
     1483        keys.put(Att.DISBK2, new S57key(Conv.F, null)); keys.put(Att.DISIPU, new S57key(Conv.F, null)); keys.put(Att.DISIPD, new S57key(Conv.F, null));
     1484        keys.put(Att.ELEVA1, new S57key(Conv.F, null)); keys.put(Att.ELEVA2, new S57key(Conv.F, null)); keys.put(Att.FNCTNM, new S57key(Conv.E, Fnctnm));
     1485        keys.put(Att.WTWDIS, new S57key(Conv.F, null)); keys.put(Att.BUNVES, new S57key(Conv.E, Bunves)); keys.put(Att.COMCTN, new S57key(Conv.S, null));
     1486        keys.put(Att.HORCLL, new S57key(Conv.F, null)); keys.put(Att.HORCLW, new S57key(Conv.F, null)); keys.put(Att.TRSHGD, new S57key(Conv.L, Trshgd));
     1487        keys.put(Att.UNLOCD, new S57key(Conv.S, null)); keys.put(Att.HIGWAT, new S57key(Conv.F, null)); keys.put(Att.HIGNAM, new S57key(Conv.S, null));
     1488        keys.put(Att.LOWWAT, new S57key(Conv.F, null)); keys.put(Att.LOWNAM, new S57key(Conv.S, null)); keys.put(Att.MEAWAT, new S57key(Conv.F, null));
     1489        keys.put(Att.MEANAM, new S57key(Conv.S, null)); keys.put(Att.OTHWAT, new S57key(Conv.F, null)); keys.put(Att.OTHNAM, new S57key(Conv.S, null));
     1490        keys.put(Att.REFLEV, new S57key(Conv.E, Reflev)); keys.put(Att.SDRLEV, new S57key(Conv.S, null)); keys.put(Att.VCRLEV, new S57key(Conv.S, null));
     1491        keys.put(Att.SCHREF, new S57key(Conv.S, null)); keys.put(Att.USESHP, new S57key(Conv.E, Useshp)); keys.put(Att.CURVHW, new S57key(Conv.F, null));
     1492        keys.put(Att.CURVLW, new S57key(Conv.F, null)); keys.put(Att.CURVMW, new S57key(Conv.F, null)); keys.put(Att.CURVOW, new S57key(Conv.F, null));
     1493        keys.put(Att.APTREF, new S57key(Conv.S, null)); keys.put(Att.SHPTYP, new S57key(Conv.E, Shptyp)); keys.put(Att.UPDMSG, new S57key(Conv.S, null));
     1494        keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
     1495        keys.put(Att.CATNMK, new S57key(Conv.E, Catnmk)); keys.put(Att.CATBRT, new S57key(Conv.L, Catbrt)); keys.put(Att.CATBUN, new S57key(Conv.L, Catbun));
     1496        keys.put(Att.CATCCL, new S57key(Conv.L, Catccl)); keys.put(Att.CATCOM, new S57key(Conv.L, Catcom)); keys.put(Att.CATHBR, new S57key(Conv.L, Cathbr));
     1497        keys.put(Att.CATRFD, new S57key(Conv.L, Catrfd)); keys.put(Att.CATTML, new S57key(Conv.L, Cattml)); keys.put(Att.CATGAG, new S57key(Conv.L, Catgag));
     1498        keys.put(Att.CATVTR, new S57key(Conv.L, Catvtr)); keys.put(Att.CATTAB, new S57key(Conv.E, Cattab)); keys.put(Att.CATEXS, new S57key(Conv.E, Catexs));
     1499        keys.put(Att.LG_SPD, new S57key(Conv.F, null)); keys.put(Att.LG_SPR, new S57key(Conv.L, Lg_spr)); keys.put(Att.LG_BME, new S57key(Conv.F, null));
     1500        keys.put(Att.LG_LGS, new S57key(Conv.F, null)); keys.put(Att.LG_DRT, new S57key(Conv.F, null)); keys.put(Att.LG_WDP, new S57key(Conv.F, null));
     1501        keys.put(Att.LG_WDU, new S57key(Conv.E, Lg_wdu)); keys.put(Att.LG_REL, new S57key(Conv.L, Lg_rel)); keys.put(Att.LG_FNC, new S57key(Conv.L, Lg_fnc));
     1502        keys.put(Att.LG_DES, new S57key(Conv.S, null)); keys.put(Att.LG_PBR, new S57key(Conv.S, null)); keys.put(Att.LC_CSI, new S57key(Conv.L, Lc_csi));
     1503        keys.put(Att.LC_CSE, new S57key(Conv.L, Lc_cse)); keys.put(Att.LC_ASI, new S57key(Conv.L, Lc_asi)); keys.put(Att.LC_ASE, new S57key(Conv.L, Lc_ase));
     1504        keys.put(Att.LC_CCI, new S57key(Conv.L, Lc_cci)); keys.put(Att.LC_CCE, new S57key(Conv.L, Lc_cce)); keys.put(Att.LC_BM1, new S57key(Conv.F, null));
     1505        keys.put(Att.LC_BM2, new S57key(Conv.F, null)); keys.put(Att.LC_LG1, new S57key(Conv.F, null)); keys.put(Att.LC_LG2, new S57key(Conv.F, null));
     1506        keys.put(Att.LC_DR1, new S57key(Conv.F, null)); keys.put(Att.LC_DR2, new S57key(Conv.F, null)); keys.put(Att.LC_SP1, new S57key(Conv.F, null));
     1507        keys.put(Att.LC_SP2, new S57key(Conv.F, null)); keys.put(Att.LC_WD1, new S57key(Conv.F, null)); keys.put(Att.LC_WD2, new S57key(Conv.F, null));
     1508        keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
     1509    }
     1510
     1511    public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
     1512        EnumMap<?, ?> map = keys.get(att).map;
     1513        Enum<?> unkn = null;
     1514        int i = 0;
     1515        try {
     1516            i = Integer.parseInt(val);
     1517        } catch (Exception e) {
     1518            return unkn;
     1519        }
     1520        if (map != null) {
     1521            for (Object item : map.keySet()) {
     1522                if (unkn == null)
     1523                    unkn = (Enum<?>) item;
     1524                if (((S57enum) map.get(item)).atvl.equals(i))
     1525                    return (Enum<?>) item;
     1526            }
     1527        }
     1528        return unkn;
     1529    }
     1530
     1531    public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
     1532        Conv conv = keys.get(att).conv;
     1533        switch (conv) {
     1534        case A:
     1535        case S:
     1536            return new AttVal<>(conv, val);
     1537        case E:
     1538            ArrayList<Enum<?>> list = new ArrayList<>();
     1539            list.add(s57Enum(val, att));
     1540            return new AttVal<ArrayList<?>>(Conv.E, list);
     1541        case L:
     1542            list = new ArrayList<>();
     1543            for (String item : val.split(",")) {
     1544                list.add(s57Enum(item, att));
     1545            }
     1546            return new AttVal<ArrayList<?>>(Conv.L, list);
     1547        case I:
     1548            try {
     1549                return new AttVal<>(Conv.I, Long.parseLong(val));
     1550            } catch (Exception e) {
     1551                break;
     1552            }
     1553        case F:
     1554            try {
     1555                return new AttVal<>(Conv.F, Double.parseDouble(val));
     1556            } catch (Exception e) {
     1557                break;
     1558            }
     1559        }
     1560        return null;
     1561    }
     1562
     1563    public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
     1564        if (attval != null) {
     1565            String str = stringValue(attval, att);
     1566            if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
     1567                String[] vals = str.split(";");
     1568                str = "";
     1569                for (String val : vals) {
     1570                    if (!str.isEmpty()) str += ",";
     1571                    EnumMap<?, ?> map = keys.get(att).map;
     1572                    for (Object item : map.keySet()) {
     1573                        if (((S57enum) map.get(item)).val.equals(val))
     1574                            str += ((S57enum) map.get(item)).atvl.toString();
     1575                    }
     1576                }
     1577            }
     1578            return str;
     1579        }
     1580        return "";
     1581    }
     1582
     1583    public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
     1584        if (attval != null) {
     1585            switch (attval.conv) {
     1586            case A:
     1587            case S:
     1588                return (String) attval.val;
     1589            case E:
     1590                EnumMap<?, ?> map = keys.get(att).map;
     1591                return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
     1592            case L:
     1593                String str = "";
     1594                map = keys.get(att).map;
     1595                for (Object item : (ArrayList<?>) attval.val) {
     1596                    if (!str.isEmpty())
     1597                        str += ";";
     1598                    if (item != null)
     1599                        str += ((S57enum) map.get(item)).val;
     1600                }
     1601                return str;
     1602            case I:
     1603                return ((Long) attval.val).toString();
     1604            case F:
     1605                return ((Double) attval.val).toString();
     1606            }
     1607        }
     1608        return "";
     1609    }
     1610
     1611    public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
     1612        EnumMap<?, ?> map = keys.get(att).map;
     1613        Enum<?> unkn = null;
     1614        if (map != null) {
     1615            for (Object item : map.keySet()) {
     1616                if (unkn == null)
     1617                    unkn = (Enum<?>) item;
     1618                if (((S57enum) map.get(item)).val.equals(val))
     1619                    return (Enum<?>) item;
     1620            }
     1621        }
     1622        return unkn;
     1623    }
     1624
     1625    public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
     1626        switch (keys.get(att).conv) {
     1627        case A:
     1628        case S:
     1629            return new AttVal<>(Conv.S, val);
     1630        case E:
     1631            ArrayList<Enum<?>> list = new ArrayList<>();
     1632            list.add(osmEnum(val, att));
     1633            return new AttVal<ArrayList<?>>(Conv.E, list);
     1634        case L:
     1635            list = new ArrayList<>();
     1636            for (String item : val.split(";")) {
     1637                list.add(osmEnum(item, att));
     1638            }
     1639            return new AttVal<ArrayList<?>>(Conv.L, list);
     1640        case I:
     1641            try {
     1642                return new AttVal<>(Conv.I, Long.parseLong(val));
     1643            } catch (Exception e) {
     1644                break;
     1645            }
     1646        case F:
     1647            try {
     1648                return new AttVal<>(Conv.F, Double.parseDouble(val));
     1649            } catch (Exception e) {
     1650                break;
     1651            }
     1652        }
     1653        return new AttVal<>(keys.get(att).conv, null);
     1654    }
     1655
     1656    public static Enum<?> unknAtt(Att att) {
     1657        return (Enum<?>) (keys.get(att).map.keySet().toArray()[0]);
     1658    }
    12691659}
  • applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java

    r32095 r32394  
    3131import render.Renderer;
    3232import s57.S57map;
    33 import s57.S57map.*;
     33import s57.S57map.Feature;
     34import s57.S57map.GeomIterator;
     35import s57.S57map.Pflag;
     36import s57.S57map.Snode;
    3437import s57.S57obj.Obj;
    3538import symbols.Symbols;
     
    3740public class ChartImage extends ImageryLayer implements ZoomChangeListener, ChartContext {
    3841
    39         double top;
    40         double bottom;
    41         double left;
    42         double right;
    43         double width;
    44         double height;
    45         int zoom;
    46        
    47         public ChartImage(ImageryInfo info) {
    48                 super(info);
    49                 MapView.addZoomChangeListener(this);
    50                 zoomChanged();
    51         }
    52        
    53         @Override
    54         public Action[] getMenuEntries() {
    55                 return null;
    56         }
     42    double top;
     43    double bottom;
     44    double left;
     45    double right;
     46    double width;
     47    double height;
     48    int zoom;
    5749
    58         @Override
    59         public String getToolTipText() {
    60                 return null;
    61         }
     50    public ChartImage(ImageryInfo info) {
     51        super(info);
     52        MapView.addZoomChangeListener(this);
     53        zoomChanged();
     54    }
    6255
    63         @Override
    64         public void visitBoundingBox(BoundingXYVisitor arg0) {
    65         }
     56    @Override
     57    public Action[] getMenuEntries() {
     58        return null;
     59    }
    6660
    67         @Override
    68         public void paint(Graphics2D g2, MapView mv, Bounds bb) {
    69                 Rectangle rect = Main.map.mapView.getBounds();
    70                 Renderer.reRender(g2, rect, zoom, Math.pow(2, (zoom-12)), SeachartAction.map, this);
    71                 g2.setPaint(Color.black);
    72                 g2.setFont(new Font("Arial", Font.BOLD, 20));
    73                 Rectangle crect = g2.getClipBounds();
    74                 if ((crect.y + crect.height) < (rect.y + rect.height - 10)) {
    75                         g2.drawString(("Z" + zoom), (crect.x + crect.width - 40), (crect.y + crect.height - 10));
    76                 } else {
    77                         g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
    78                 }
    79         }
     61    @Override
     62    public String getToolTipText() {
     63        return null;
     64    }
    8065
    81         @Override
    82         public void zoomChanged() {
    83                 if ((Main.map != null) && (Main.map.mapView != null)) {
    84                         Bounds bounds = Main.map.mapView.getRealBounds();
    85                         top = bounds.getMax().lat();
    86                         bottom = bounds.getMin().lat();
    87                         left = bounds.getMin().lon();
    88                         right = bounds.getMax().lon();
    89                         width = Main.map.mapView.getBounds().getWidth();
    90                         height = Main.map.mapView.getBounds().getHeight();
    91                         zoom = ((int) Math.min(18, Math.max(9, Math.round(Math.floor(Math.log(1024 / bounds.asRect().height) / Math.log(2))))));
    92                 }
    93         }
     66    @Override
     67    public void visitBoundingBox(BoundingXYVisitor arg0) {
     68    }
    9469
    95         public Point2D.Double getPoint(Snode coord) {
    96                 return (Double) Main.map.mapView.getPoint2D(new LatLon(Math.toDegrees(coord.lat), Math.toDegrees(coord.lon)));
    97         }
     70    @Override
     71    public void paint(Graphics2D g2, MapView mv, Bounds bb) {
     72        Rectangle rect = Main.map.mapView.getBounds();
     73        Renderer.reRender(g2, rect, zoom, Math.pow(2, (zoom-12)), SeachartAction.map, this);
     74        g2.setPaint(Color.black);
     75        g2.setFont(new Font("Arial", Font.BOLD, 20));
     76        Rectangle crect = g2.getClipBounds();
     77        if ((crect.y + crect.height) < (rect.y + rect.height - 10)) {
     78            g2.drawString(("Z" + zoom), (crect.x + crect.width - 40), (crect.y + crect.height - 10));
     79        } else {
     80            g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
     81        }
     82    }
    9883
    99         public double mile(Feature feature) {
    100                 return 185000 / Main.map.mapView.getDist100Pixel();
    101         }
    102        
    103         public boolean clip() {
    104                 return true;
    105         }
    106        
    107         public Color background(S57map map) {
    108                 if (map.features.containsKey(Obj.COALNE)) {
    109                         for (Feature feature : map.features.get(Obj.COALNE)) {
    110                                 if (feature.geom.prim == Pflag.POINT) {
    111                                         break;
    112                                 }
    113                                 GeomIterator git = map.new GeomIterator(feature.geom);
    114                                 git.nextComp();
    115                                 while (git.hasEdge()) {
    116                                         git.nextEdge();
    117                                         while (git.hasNode()) {
    118                                                 Snode node = git.next();
    119                                                 if (node == null)
    120                                                         continue;
    121                                                 if ((node.lat >= map.bounds.minlat) && (node.lat <= map.bounds.maxlat) && (node.lon >= map.bounds.minlon) && (node.lon <= map.bounds.maxlon)) {
    122                                                         return Symbols.Bwater;
    123                                                 }
    124                                         }
    125                                 }
    126                         }
    127                         return Symbols.Yland;
    128                 } else {
    129                         if (map.features.containsKey(Obj.ROADWY) || map.features.containsKey(Obj.RAILWY) || map.features.containsKey(Obj.LAKARE) || map.features.containsKey(Obj.RIVERS) || map.features.containsKey(Obj.CANALS)) {
    130                                 return Symbols.Yland;
    131                         } else {
    132                                 return Symbols.Bwater;
    133                         }
    134                 }
    135         }
     84    @Override
     85    public void zoomChanged() {
     86        if ((Main.map != null) && (Main.map.mapView != null)) {
     87            Bounds bounds = Main.map.mapView.getRealBounds();
     88            top = bounds.getMax().lat();
     89            bottom = bounds.getMin().lat();
     90            left = bounds.getMin().lon();
     91            right = bounds.getMax().lon();
     92            width = Main.map.mapView.getBounds().getWidth();
     93            height = Main.map.mapView.getBounds().getHeight();
     94            zoom = ((int) Math.min(18, Math.max(9, Math.round(Math.floor(Math.log(1024 / bounds.asRect().height) / Math.log(2))))));
     95        }
     96    }
    13697
    137         public RuleSet ruleset() {
    138                 return RuleSet.ALL;
    139         }
     98    @Override
     99    public Point2D.Double getPoint(Snode coord) {
     100        return (Double) Main.map.mapView.getPoint2D(new LatLon(Math.toDegrees(coord.lat), Math.toDegrees(coord.lon)));
     101    }
     102
     103    @Override
     104    public double mile(Feature feature) {
     105        return 185000 / Main.map.mapView.getDist100Pixel();
     106    }
     107
     108    @Override
     109    public boolean clip() {
     110        return true;
     111    }
     112
     113    @Override
     114    public Color background(S57map map) {
     115        if (map.features.containsKey(Obj.COALNE)) {
     116            for (Feature feature : map.features.get(Obj.COALNE)) {
     117                if (feature.geom.prim == Pflag.POINT) {
     118                    break;
     119                }
     120                GeomIterator git = map.new GeomIterator(feature.geom);
     121                git.nextComp();
     122                while (git.hasEdge()) {
     123                    git.nextEdge();
     124                    while (git.hasNode()) {
     125                        Snode node = git.next();
     126                        if (node == null)
     127                            continue;
     128                        if ((node.lat >= map.bounds.minlat) && (node.lat <= map.bounds.maxlat)
     129                                && (node.lon >= map.bounds.minlon) && (node.lon <= map.bounds.maxlon)) {
     130                            return Symbols.Bwater;
     131                        }
     132                    }
     133                }
     134            }
     135            return Symbols.Yland;
     136        } else {
     137            if (map.features.containsKey(Obj.ROADWY) || map.features.containsKey(Obj.RAILWY)
     138                    || map.features.containsKey(Obj.LAKARE) || map.features.containsKey(Obj.RIVERS) || map.features.containsKey(Obj.CANALS)) {
     139                return Symbols.Yland;
     140            } else {
     141                return Symbols.Bwater;
     142            }
     143        }
     144    }
     145
     146    @Override
     147    public RuleSet ruleset() {
     148        return RuleSet.ALL;
     149    }
    140150}
  • applications/editors/josm/plugins/seachart/src/seachart/Seachart.java

    r30894 r32394  
    1717public class Seachart extends Plugin {
    1818
    19         public Seachart(PluginInformation info) {
     19    public Seachart(PluginInformation info) {
    2020        super(info);
    2121        MainMenu.add(Main.main.menu.imageryMenu, new SeachartAction());
  • applications/editors/josm/plugins/seachart/src/seachart/SeachartAction.java

    r32371 r32394  
    4646
    4747public class SeachartAction extends JosmAction implements ActiveLayerChangeListener, LayerChangeListener {
    48         private static String title = "SeaChart";
    49         private boolean isOpen = false;
    50         public static ChartImage rendering;
    51         public static S57map map = null;
    52         public DataSet data = null;
    53 
    54         private final DataSetListener dataSetListener = new DataSetListener() {
    55 
    56                 @Override
    57                 public void dataChanged(DataChangedEvent e) {
    58                         makeChart();
    59                 }
    60 
    61                 @Override
    62                 public void nodeMoved(NodeMovedEvent e) {
    63                         makeChart();
    64                 }
    65 
    66                 @Override
    67                 public void otherDatasetChange(AbstractDatasetChangedEvent e) {
    68                         makeChart();
    69                 }
    70 
    71                 @Override
    72                 public void primitivesAdded(PrimitivesAddedEvent e) {
    73                         makeChart();
    74                 }
    75 
    76                 @Override
    77                 public void primitivesRemoved(PrimitivesRemovedEvent e) {
    78                         makeChart();
    79                 }
    80 
    81                 @Override
    82                 public void relationMembersChanged(RelationMembersChangedEvent e) {
    83                         makeChart();
    84                 }
    85 
    86                 @Override
    87                 public void tagsChanged(TagsChangedEvent e) {
    88                         makeChart();
    89                 }
    90 
    91                 @Override
    92                 public void wayNodesChanged(WayNodesChangedEvent e) {
    93                         makeChart();
    94                 }
    95         };
    96 
    97         public SeachartAction() {
    98                 super(title, "SC", title, null, true);
    99         }
    100 
    101         @Override
    102         public void layerAdded(LayerAddEvent e) {
    103         }
    104 
    105         @Override
    106         public void layerRemoving(LayerRemoveEvent e) {
    107                 if ("SeaChart".equals(e.getRemovedLayer().getName())) {
    108                         closeChartLayer();
    109                 }
    110         }
     48    private static String title = "SeaChart";
     49    private boolean isOpen = false;
     50    public static ChartImage rendering;
     51    public static S57map map = null;
     52    public DataSet data = null;
     53
     54    private final DataSetListener dataSetListener = new DataSetListener() {
     55
     56        @Override
     57        public void dataChanged(DataChangedEvent e) {
     58            makeChart();
     59        }
     60
     61        @Override
     62        public void nodeMoved(NodeMovedEvent e) {
     63            makeChart();
     64        }
     65
     66        @Override
     67        public void otherDatasetChange(AbstractDatasetChangedEvent e) {
     68            makeChart();
     69        }
     70
     71        @Override
     72        public void primitivesAdded(PrimitivesAddedEvent e) {
     73            makeChart();
     74        }
     75
     76        @Override
     77        public void primitivesRemoved(PrimitivesRemovedEvent e) {
     78            makeChart();
     79        }
     80
     81        @Override
     82        public void relationMembersChanged(RelationMembersChangedEvent e) {
     83            makeChart();
     84        }
     85
     86        @Override
     87        public void tagsChanged(TagsChangedEvent e) {
     88            makeChart();
     89        }
     90
     91        @Override
     92        public void wayNodesChanged(WayNodesChangedEvent e) {
     93            makeChart();
     94        }
     95    };
     96
     97    public SeachartAction() {
     98        super(title, "SC", title, null, true);
     99    }
     100
     101    @Override
     102    public void layerAdded(LayerAddEvent e) {
     103    }
     104
     105    @Override
     106    public void layerRemoving(LayerRemoveEvent e) {
     107        if ("SeaChart".equals(e.getRemovedLayer().getName())) {
     108            closeChartLayer();
     109        }
     110    }
    111111
    112112    @Override
     
    115115
    116116    @Override
    117         public void actionPerformed(ActionEvent arg0) {
    118                 SwingUtilities.invokeLater(new Runnable() {
    119                         public void run() {
    120                                 if (!isOpen)
    121                                         createChartLayer();
    122                                 isOpen = true;
    123                         }
    124                 });
    125         }
    126 
    127         protected void createChartLayer() {
    128                 rendering = new ChartImage(new ImageryInfo("SeaChart"));
    129                 rendering.setBackgroundLayer(true);
    130                 Main.getLayerManager().addLayer(rendering);
    131                 Main.getLayerManager().addAndFireActiveLayerChangeListener(this);
    132                 Main.getLayerManager().addLayerChangeListener(this);
    133         }
    134 
    135         public void closeChartLayer() {
    136                 if (isOpen) {
    137                     Main.getLayerManager().removeActiveLayerChangeListener(this);
    138                         Main.getLayerManager().removeLayerChangeListener(this);
    139                         Main.getLayerManager().removeLayer(rendering);
    140                 }
    141                 isOpen = false;
    142         }
    143 
    144         @Override
    145         public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
    146             OsmDataLayer oldLayer = e.getPreviousEditLayer();
    147                 if (oldLayer != null) {
    148                         oldLayer.data.removeDataSetListener(dataSetListener);
    149                 }
    150             OsmDataLayer newLayer = Main.getLayerManager().getEditLayer();
    151                 if (newLayer != null) {
    152                         newLayer.data.addDataSetListener(dataSetListener);
    153                         data = newLayer.data;
    154                         makeChart();
    155                 } else {
    156                         data = null;
    157                         map = null;
    158                 }
    159         }
    160 
    161         void makeChart() {
    162                 map = new S57map(false);
    163                 if (data != null) {
    164                         double minlat = 90;
    165                         double maxlat = -90;
    166                         double minlon = 180;
    167                         double maxlon = -180;
    168                         for (Bounds bounds : data.getDataSourceBounds()) {
    169                                 if (bounds.getMinLat() < minlat) {
    170                                         minlat = bounds.getMinLat();
    171                                 }
    172                                 if (bounds.getMaxLat() > maxlat) {
    173                                         maxlat = bounds.getMaxLat();
    174                                 }
    175                                 if (bounds.getMinLon() < minlon) {
    176                                         minlon = bounds.getMinLon();
    177                                 }
    178                                 if (bounds.getMaxLon() > maxlon) {
    179                                         maxlon = bounds.getMaxLon();
    180                                 }
    181                         }
    182                         map.addNode(1, maxlat, minlon);
    183                         map.addNode(2, minlat, minlon);
    184                         map.addNode(3, minlat, maxlon);
    185                         map.addNode(4, maxlat, maxlon);
    186                         map.bounds.minlat = Math.toRadians(minlat);
    187                         map.bounds.maxlat = Math.toRadians(maxlat);
    188                         map.bounds.minlon = Math.toRadians(minlon);
    189                         map.bounds.maxlon = Math.toRadians(maxlon);
    190                         for (Node node : data.getNodes()) {
    191                                 LatLon coor = node.getCoor();
    192                                 if (coor != null) {
    193                                         map.addNode(node.getUniqueId(), coor.lat(), coor.lon());
    194                                         for (Entry<String, String> entry : node.getKeys().entrySet()) {
    195                                                 map.addTag(entry.getKey(), entry.getValue());
    196                                         }
    197                                         map.tagsDone(node.getUniqueId());
    198                                 }
    199                         }
    200                         for (Way way : data.getWays()) {
    201                                 if (way.getNodesCount() > 0) {
    202                                         map.addEdge(way.getUniqueId());
    203                                         for (Node node : way.getNodes()) {
    204                                                 map.addToEdge((node.getUniqueId()));
    205                                         }
    206                                         for (Entry<String, String> entry : way.getKeys().entrySet()) {
    207                                                 map.addTag(entry.getKey(), entry.getValue());
    208                                         }
    209                                         map.tagsDone(way.getUniqueId());
    210                                 }
    211                         }
    212                         for (Relation rel : data.getRelations()) {
    213                                 if (rel.isMultipolygon() && (rel.getMembersCount() > 0)) {
    214                                         map.addArea(rel.getUniqueId());
    215                                         for (RelationMember mem : rel.getMembers()) {
    216                                                 if (mem.getType() == OsmPrimitiveType.WAY)
    217                                                         map.addToArea(mem.getUniqueId(), (mem.getRole().equals("outer")));
    218                                         }
    219                                         for (Entry<String, String> entry : rel.getKeys().entrySet()) {
    220                                                 map.addTag(entry.getKey(), entry.getValue());
    221                                         }
    222                                         map.tagsDone(rel.getUniqueId());
    223                                 }
    224                         }
    225                         map.mapDone();
    226                         if (rendering != null) rendering.zoomChanged();
    227                 }
    228         }
     117    public void actionPerformed(ActionEvent arg0) {
     118        SwingUtilities.invokeLater(new Runnable() {
     119            public void run() {
     120                if (!isOpen)
     121                    createChartLayer();
     122                isOpen = true;
     123            }
     124        });
     125    }
     126
     127    protected void createChartLayer() {
     128        rendering = new ChartImage(new ImageryInfo("SeaChart"));
     129        rendering.setBackgroundLayer(true);
     130        Main.getLayerManager().addLayer(rendering);
     131        Main.getLayerManager().addAndFireActiveLayerChangeListener(this);
     132        Main.getLayerManager().addLayerChangeListener(this);
     133    }
     134
     135    public void closeChartLayer() {
     136        if (isOpen) {
     137            Main.getLayerManager().removeActiveLayerChangeListener(this);
     138            Main.getLayerManager().removeLayerChangeListener(this);
     139            Main.getLayerManager().removeLayer(rendering);
     140        }
     141        isOpen = false;
     142    }
     143
     144    @Override
     145    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
     146        OsmDataLayer oldLayer = e.getPreviousEditLayer();
     147        if (oldLayer != null) {
     148            oldLayer.data.removeDataSetListener(dataSetListener);
     149        }
     150        OsmDataLayer newLayer = Main.getLayerManager().getEditLayer();
     151        if (newLayer != null) {
     152            newLayer.data.addDataSetListener(dataSetListener);
     153            data = newLayer.data;
     154            makeChart();
     155        } else {
     156            data = null;
     157            map = null;
     158        }
     159    }
     160
     161    void makeChart() {
     162        map = new S57map(false);
     163        if (data != null) {
     164            double minlat = 90;
     165            double maxlat = -90;
     166            double minlon = 180;
     167            double maxlon = -180;
     168            for (Bounds bounds : data.getDataSourceBounds()) {
     169                if (bounds.getMinLat() < minlat) {
     170                    minlat = bounds.getMinLat();
     171                }
     172                if (bounds.getMaxLat() > maxlat) {
     173                    maxlat = bounds.getMaxLat();
     174                }
     175                if (bounds.getMinLon() < minlon) {
     176                    minlon = bounds.getMinLon();
     177                }
     178                if (bounds.getMaxLon() > maxlon) {
     179                    maxlon = bounds.getMaxLon();
     180                }
     181            }
     182            map.addNode(1, maxlat, minlon);
     183            map.addNode(2, minlat, minlon);
     184            map.addNode(3, minlat, maxlon);
     185            map.addNode(4, maxlat, maxlon);
     186            map.bounds.minlat = Math.toRadians(minlat);
     187            map.bounds.maxlat = Math.toRadians(maxlat);
     188            map.bounds.minlon = Math.toRadians(minlon);
     189            map.bounds.maxlon = Math.toRadians(maxlon);
     190            for (Node node : data.getNodes()) {
     191                LatLon coor = node.getCoor();
     192                if (coor != null) {
     193                    map.addNode(node.getUniqueId(), coor.lat(), coor.lon());
     194                    for (Entry<String, String> entry : node.getKeys().entrySet()) {
     195                        map.addTag(entry.getKey(), entry.getValue());
     196                    }
     197                    map.tagsDone(node.getUniqueId());
     198                }
     199            }
     200            for (Way way : data.getWays()) {
     201                if (way.getNodesCount() > 0) {
     202                    map.addEdge(way.getUniqueId());
     203                    for (Node node : way.getNodes()) {
     204                        map.addToEdge((node.getUniqueId()));
     205                    }
     206                    for (Entry<String, String> entry : way.getKeys().entrySet()) {
     207                        map.addTag(entry.getKey(), entry.getValue());
     208                    }
     209                    map.tagsDone(way.getUniqueId());
     210                }
     211            }
     212            for (Relation rel : data.getRelations()) {
     213                if (rel.isMultipolygon() && (rel.getMembersCount() > 0)) {
     214                    map.addArea(rel.getUniqueId());
     215                    for (RelationMember mem : rel.getMembers()) {
     216                        if (mem.getType() == OsmPrimitiveType.WAY)
     217                            map.addToArea(mem.getUniqueId(), (mem.getRole().equals("outer")));
     218                    }
     219                    for (Entry<String, String> entry : rel.getKeys().entrySet()) {
     220                        map.addTag(entry.getKey(), entry.getValue());
     221                    }
     222                    map.tagsDone(rel.getUniqueId());
     223                }
     224            }
     225            map.mapDone();
     226            if (rendering != null) rendering.zoomChanged();
     227        }
     228    }
    229229
    230230}
  • applications/editors/josm/plugins/seachart/src/symbols/Areas.java

    r32101 r32394  
    1010package symbols;
    1111
    12 import java.awt.*;
    13 import java.awt.geom.*;
    14 import java.awt.image.*;
    15 
    16 import symbols.Symbols.*;
     12import java.awt.BasicStroke;
     13import java.awt.Color;
     14import java.awt.Graphics2D;
     15import java.awt.geom.AffineTransform;
     16import java.awt.geom.Ellipse2D;
     17import java.awt.geom.Line2D;
     18import java.awt.geom.Path2D;
     19import java.awt.geom.Rectangle2D;
     20import java.awt.image.BufferedImage;
     21
     22import symbols.Symbols.Delta;
     23import symbols.Symbols.Form;
     24import symbols.Symbols.Handle;
     25import symbols.Symbols.Instr;
     26import symbols.Symbols.Symbol;
    1727
    1828public class Areas {
    19         public static final Symbol Plane = new Symbol();
    20         static {
    21                 Plane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
    22                 Path2D.Double p = new Path2D.Double(); p.moveTo(40,20); p.lineTo(50,10); p.lineTo(27.0,13.3); p.lineTo(23.7,6.8); p.lineTo(40.0,5.0); p.curveTo(55,4,55,-9,40,-10);
    23                 p.quadTo(31,-11,30,-15); p.lineTo(-30,2); p.quadTo(-35,-12,-45,-15); p.quadTo(-56,-3,-50,15); p.lineTo(18.4,7.3); p.lineTo(21.7,14); p.lineTo(-20,20); p.closePath();
    24                 Plane.add(new Instr(Form.PGON, p));
    25         }
    26         public static final Symbol Cable = new Symbol();
    27         static {
    28                 Cable.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
    29                 Cable.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    30                 Cable.add(new Instr(Form.FILL, new Color(0xc480ff)));
    31                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,0); p.curveTo(-13,-13,-13,-17,0,-30); p.curveTo(13,-43,13,-47,0,-60);
    32                 Cable.add(new Instr(Form.PLIN, p));
    33         }
    34         public static final Symbol CableDot = new Symbol();
    35         static {
    36                 CableDot.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
    37                 CableDot.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-40,20,20)));
    38         }
    39         public static final Symbol CableDash = new Symbol();
    40         static {
    41                 CableDash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
    42                 CableDash.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    43                 CableDash.add(new Instr(Form.LINE, new Line2D.Double(0,-15,0,-45)));
    44         }
    45         public static final Symbol CableFlash = new Symbol();
    46         static {
    47                 CableFlash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
    48                 Path2D.Double p = new Path2D.Double(); p.moveTo(-30,-25); p.lineTo(-10,-40); p.lineTo(10,-26); p.lineTo(30,-35); p.lineTo(10,-20); p.lineTo(-10,-34); p.closePath();
    49                 CableFlash.add(new Instr(Form.PGON, p));
    50         }
    51         public static final Symbol LaneArrow = new Symbol();
    52         static {
    53                 LaneArrow.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-240,40,240)));
    54                 LaneArrow.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    55                 LaneArrow.add(new Instr(Form.FILL, Symbols.Mtss));
    56                 Path2D.Double p = new Path2D.Double(); p.moveTo(15,0); p.lineTo(15,-195); p.lineTo(40,-195);
    57                 p.lineTo(0,-240); p.lineTo(-40,-195); p.lineTo(-15,-195); p.lineTo(-15,0); p.closePath();
    58                 LaneArrow.add(new Instr(Form.PLIN, p));
    59         }
    60         public static final Symbol LineAnchor = new Symbol();
    61         static {
    62                 LineAnchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,90)));
    63                 LineAnchor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.5, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(-90.0))))));
    64         }
    65         public static final Symbol LinePlane = new Symbol();
    66         static {
    67                 LinePlane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,90)));
    68                 LinePlane.add(new Instr(Form.FILL, new Color(0xc480ff)));
    69                 LinePlane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 0.5, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(-90.0))))));
    70         }
    71         public static final Symbol MarineFarm = new Symbol();
    72         static {
    73                 MarineFarm.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    74                 Path2D.Double p = new Path2D.Double(); p.moveTo(-23,12); p.lineTo(-23,23); p.lineTo(23,23); p.lineTo(23,12); p.moveTo(-8,15); p.lineTo(-8,23); p.moveTo(8,15); p.lineTo(8,23);
    75                 p.moveTo(-23,-12); p.lineTo(-23,-23); p.lineTo(23,-23); p.lineTo(23,-12); p.moveTo(-8,-15); p.lineTo(-8,-23); p.moveTo(8,-15); p.lineTo(8,-23);
    76                 p.moveTo(-21,8); p.quadTo(-1,-14,21,0); p.quadTo(-1,14,-21,-8); p.moveTo(7,6); p.quadTo(2,0,7,-6);
    77                 MarineFarm.add(new Instr(Form.PLIN, p));
    78                 MarineFarm.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,-2,4,4)));
    79         }
    80         public static final Symbol NoWake = new Symbol();
    81         static {
    82                 NoWake.add(new Instr(Form.STRK, new BasicStroke(12, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    83                 NoWake.add(new Instr(Form.FILL, new Color(0xa30075)));
    84                 Path2D.Double p = new Path2D.Double(); p.moveTo(-60,20); p.curveTo(-28,20,-32,0,0,0); p.curveTo(32,0,28,20,60,20); p.moveTo(-60,0); p.curveTo(-28,0,-32,-20,0,-20); p.curveTo(32,-20,28,0,60,0);
    85                 NoWake.add(new Instr(Form.PLIN, p));
    86                 NoWake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    87                 NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60,60,60,-60)));
    88                 NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60,-60,60,60)));
    89         }
    90         public static final Symbol Pipeline = new Symbol();
    91         static {
    92                 Pipeline.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15,-60,30,60)));
    93                 Pipeline.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    94                 Pipeline.add(new Instr(Form.FILL, new Color(0xc480ff)));
    95                 Pipeline.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-50)));
    96                 Pipeline.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-60,20,20)));
    97         }
    98         public static final Symbol Restricted = new Symbol();
    99         static {
    100                 Restricted.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15,-30,30,30)));
    101                 Restricted.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    102                 Restricted.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-30)));
    103                 Restricted.add(new Instr(Form.LINE, new Line2D.Double(0,-15,17,-15)));
    104         }
    105         public static final Symbol Rock = new Symbol();
    106         static {
    107                 Rock.add(new Instr(Form.FILL, new Color(0x80c0ff)));
    108                 Rock.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
    109                 Rock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
    110                 Rock.add(new Instr(Form.FILL, Color.black));
    111                 Rock.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
    112                 Rock.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    113                 Rock.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
    114                 Rock.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,20)));
    115         }
    116         public static final Symbol RockA = new Symbol();
    117         static {
    118                 RockA.add(new Instr(Form.FILL, new Color(0x80c0ff)));
    119                 RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
    120                 RockA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
    121                 RockA.add(new Instr(Form.FILL, Color.black));
    122                 RockA.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
    123                 RockA.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    124                 RockA.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
    125                 RockA.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,20)));
    126                 RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17,-17,8,8)));
    127                 RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17,9,8,8)));
    128                 RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,-17,8,8)));
    129                 RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,9,8,8)));
    130         }
    131         public static final Symbol RockC = new Symbol();
    132         static {
    133                 RockC.add(new Instr(Form.FILL, new Color(0x80c0ff)));
    134                 RockC.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
    135                 RockC.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
    136                 RockC.add(new Instr(Form.FILL, Color.black));
    137                 RockC.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
    138                 RockC.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    139                 RockC.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
    140                 RockC.add(new Instr(Form.LINE, new Line2D.Double(-10,17.3,10,-17.3)));
    141                 RockC.add(new Instr(Form.LINE, new Line2D.Double(10,17.3,-10,-17.3)));
    142         }
    143         public static final Symbol Seaplane = new Symbol();
    144         static {
    145                 Seaplane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
    146                 Seaplane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    147                 Seaplane.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58,-58,116,116)));
    148                 Seaplane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 1.0, 0, 0, null, null)));
    149         }
    150         public static final Symbol WindFarm = new Symbol();
    151         static {
    152                 WindFarm.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    153                 WindFarm.add(new Instr(Form.ELPS, new Ellipse2D.Double(-100,-100,200,200)));
    154                 WindFarm.add(new Instr(Form.LINE, new Line2D.Double(-35,50,35,50)));
    155                 WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,50,0,-27.5)));
    156                 WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,30,-27.5)));
    157                 WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,-13.8,-3.8)));
    158                 WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,-13.8,-53.6)));
    159         }
    160         public static final Symbol WreckD = new Symbol();
    161         static {
    162                 WreckD.add(new Instr(Form.FILL, new Color(0x80c0ff)));
    163                 WreckD.add(new Instr(Form.RSHP, new Ellipse2D.Double(-50,-40,100,80)));
    164                 WreckD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
    165                 WreckD.add(new Instr(Form.FILL, Color.black));
    166                 WreckD.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50,-40,100,80)));
    167                 WreckD.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    168                 WreckD.add(new Instr(Form.LINE, new Line2D.Double(-40,0,40,0)));
    169                 WreckD.add(new Instr(Form.LINE, new Line2D.Double(0,-30,0,30)));
    170                 WreckD.add(new Instr(Form.LINE, new Line2D.Double(-20,-15,-20,15)));
    171                 WreckD.add(new Instr(Form.LINE, new Line2D.Double(20,-15,20,15)));
    172         }
    173         public static final Symbol WreckND = new Symbol();
    174         static {
    175                 WreckND.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    176                 WreckND.add(new Instr(Form.LINE, new Line2D.Double(-40,0,40,0)));
    177                 WreckND.add(new Instr(Form.LINE, new Line2D.Double(0,-30,0,30)));
    178                 WreckND.add(new Instr(Form.LINE, new Line2D.Double(-20,-15,-20,15)));
    179                 WreckND.add(new Instr(Form.LINE, new Line2D.Double(20,-15,20,15)));
    180         }
    181         public static final Symbol WreckS = new Symbol();
    182         static {
    183                 WreckS.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    184                 WreckS.add(new Instr(Form.ELPS, new Ellipse2D.Double(-6,-6,12,12)));
    185                 WreckS.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-6,0)));
    186                 WreckS.add(new Instr(Form.LINE, new Line2D.Double(40,0,6,0)));
    187                 Path2D.Double p = new Path2D.Double(); p.moveTo(-30,0); p.lineTo(-40,-25); p.lineTo(-0.3,-12.6); p.lineTo(13.7,-37.7); p.lineTo(16.3,-36.3);
    188                 p.lineTo(2.7,-11.6); p.lineTo(37.5,0); p.lineTo(6,0); p.curveTo(5.6,-8,-5.6,-8,-6,0); p.closePath();
    189                 WreckS.add(new Instr(Form.PGON, p));
    190         }
    191         public static final BufferedImage Sandwaves = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
    192         static {
    193                 Graphics2D g2 = Sandwaves.createGraphics();
    194                 g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    195                 g2.setBackground(new Color(0, true));
    196                 g2.clearRect(0,  0, 100, 100);
    197                 g2.setPaint(new Color(0xffd400));
    198                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,34.5); p.lineTo(03.3,30.8); p.lineTo(09.9,19.3); p.lineTo(13.2,16.0); p.lineTo(16.5,16.1); p.lineTo(18.2,19.5);
    199                 p.lineTo(19.9,25.0); p.lineTo(21.6,30.3); p.lineTo(23.3,33.4); p.lineTo(25.0,33.3); p.lineTo(28.3,30.1); p.lineTo(31.6,25.0); p.lineTo(34.9,20.1); p.lineTo(38.2,17.2);
    200                 p.lineTo(41.5,17.3); p.lineTo(43.2,20.3); p.lineTo(44.9,25); p.lineTo(46.6,29.6); p.lineTo(48.3,32.2); p.lineTo(50.0,32.1);
    201                 p.moveTo(50.0,84.5); p.lineTo(53.3,80.8); p.lineTo(56.6,75.0); p.lineTo(59.9,69.3); p.lineTo(63.2,66.0); p.lineTo(66.5,66.1); p.lineTo(68.2,69.5); p.lineTo(69.9,75.0);
    202                 p.lineTo(71.6,80.3); p.lineTo(73.3,83.4); p.lineTo(75.0,83.3); p.lineTo(78.3,80.1); p.lineTo(81.6,75.0); p.lineTo(84.9,70.1); p.lineTo(88.2,67.2); p.lineTo(91.5,67.3);
    203                 p.lineTo(93.2,70.3); p.lineTo(94.9,75.0); p.lineTo(96.6,79.6); p.lineTo(98.3,82.2); p.lineTo(100.0,82.1);
    204                 g2.draw(p);
    205         }
    206         public static final Symbol KelpS = new Symbol();
    207         static {
    208                 KelpS.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    209                 Path2D.Double p = new Path2D.Double(); p.moveTo(-60,0); p.curveTo(-20,-20,-24,40,24,20); p.moveTo(-60,0); p.quadTo(-48,20,-32,12);
    210                 p.moveTo(-36,-4); p.quadTo(-24,-24,-4,-16); p.quadTo(8,-32,20,-24); p.moveTo(-4,-16); p.quadTo(8,0,20,-8);
    211                 p.moveTo(-8,20); p.quadTo(12,0,36,8); p.quadTo(48,24,60,16); p.moveTo(36,8); p.quadTo(48,-8,60,0);
    212                 KelpS.add(new Instr(Form.PLIN, p));
    213         }
    214         public static final BufferedImage KelpA = new BufferedImage(240, 240, BufferedImage.TYPE_INT_ARGB);
    215         static {
    216                 Graphics2D g2 = KelpA.createGraphics();
    217                 g2.setStroke(new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    218                 g2.setBackground(new Color(0, true));
    219                 g2.clearRect(0,  0, 240, 240);
    220                 g2.setPaint(Color.black);
    221                 Path2D.Double p = new Path2D.Double();
    222                         p.moveTo(0,60); p.curveTo(40,40,44,100,84,80); p.moveTo(0,60); p.quadTo(12,80,28,72); p.moveTo(24,56); p.quadTo(36,36,56,44); p.quadTo(68,28,80,36);
    223       p.moveTo(56,44); p.quadTo(68,60,80,52); p.moveTo(52,76); p.quadTo(72,60,96,68); p.quadTo(108,84,120,76); p.moveTo(96,68); p.quadTo(108,52,120,60);
    224       p.moveTo(120,180); p.curveTo(160,160,164,220,204,200); p.moveTo(120,180); p.quadTo(132,200,148,192); p.moveTo(144,176); p.quadTo(156,156,176,164); p.quadTo(188,148,200,156);
    225       p.moveTo(176,164); p.quadTo(188,180,200,172); p.moveTo(172,196); p.quadTo(192,180,216,188); p.quadTo(228,204,240,196); p.moveTo(216,188); p.quadTo(228,172,240,180);
    226                 g2.draw(p);
    227         }
     29    // CHECKSTYLE.OFF: LineLength
     30    public static final Symbol Plane = new Symbol();
     31    static {
     32        Plane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
     33        Path2D.Double p = new Path2D.Double(); p.moveTo(40, 20); p.lineTo(50, 10); p.lineTo(27.0, 13.3); p.lineTo(23.7, 6.8); p.lineTo(40.0, 5.0); p.curveTo(55, 4, 55, -9, 40, -10);
     34        p.quadTo(31, -11, 30, -15); p.lineTo(-30, 2); p.quadTo(-35, -12, -45, -15); p.quadTo(-56, -3, -50, 15); p.lineTo(18.4, 7.3); p.lineTo(21.7, 14); p.lineTo(-20, 20); p.closePath();
     35        Plane.add(new Instr(Form.PGON, p));
     36    }
     37
     38    public static final Symbol Cable = new Symbol();
     39    static {
     40        Cable.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
     41        Cable.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     42        Cable.add(new Instr(Form.FILL, new Color(0xc480ff)));
     43        Path2D.Double p = new Path2D.Double(); p.moveTo(0, 0); p.curveTo(-13, -13, -13, -17, 0, -30); p.curveTo(13, -43, 13, -47, 0, -60);
     44        Cable.add(new Instr(Form.PLIN, p));
     45    }
     46
     47    public static final Symbol CableDot = new Symbol();
     48    static {
     49        CableDot.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
     50        CableDot.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -40, 20, 20)));
     51    }
     52
     53    public static final Symbol CableDash = new Symbol();
     54    static {
     55        CableDash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
     56        CableDash.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     57        CableDash.add(new Instr(Form.LINE, new Line2D.Double(0, -15, 0, -45)));
     58    }
     59
     60    public static final Symbol CableFlash = new Symbol();
     61    static {
     62        CableFlash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
     63        Path2D.Double p = new Path2D.Double(); p.moveTo(-30, -25); p.lineTo(-10, -40); p.lineTo(10, -26); p.lineTo(30, -35); p.lineTo(10, -20); p.lineTo(-10, -34); p.closePath();
     64        CableFlash.add(new Instr(Form.PGON, p));
     65    }
     66
     67    public static final Symbol LaneArrow = new Symbol();
     68    static {
     69        LaneArrow.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -240, 40, 240)));
     70        LaneArrow.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     71        LaneArrow.add(new Instr(Form.FILL, Symbols.Mtss));
     72        Path2D.Double p = new Path2D.Double(); p.moveTo(15, 0); p.lineTo(15, -195); p.lineTo(40, -195);
     73        p.lineTo(0, -240); p.lineTo(-40, -195); p.lineTo(-15, -195); p.lineTo(-15, 0); p.closePath();
     74        LaneArrow.add(new Instr(Form.PLIN, p));
     75    }
     76
     77    public static final Symbol LineAnchor = new Symbol();
     78    static {
     79        LineAnchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 90)));
     80        LineAnchor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.5, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(-90.0))))));
     81    }
     82
     83    public static final Symbol LinePlane = new Symbol();
     84    static {
     85        LinePlane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 90)));
     86        LinePlane.add(new Instr(Form.FILL, new Color(0xc480ff)));
     87        LinePlane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 0.5, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(-90.0))))));
     88    }
     89
     90    public static final Symbol MarineFarm = new Symbol();
     91    static {
     92        MarineFarm.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     93        Path2D.Double p = new Path2D.Double(); p.moveTo(-23, 12); p.lineTo(-23, 23); p.lineTo(23, 23); p.lineTo(23, 12); p.moveTo(-8, 15); p.lineTo(-8, 23); p.moveTo(8, 15); p.lineTo(8, 23);
     94        p.moveTo(-23, -12); p.lineTo(-23, -23); p.lineTo(23, -23); p.lineTo(23, -12); p.moveTo(-8, -15); p.lineTo(-8, -23); p.moveTo(8, -15); p.lineTo(8, -23);
     95        p.moveTo(-21, 8); p.quadTo(-1, -14, 21, 0); p.quadTo(-1, 14, -21, -8); p.moveTo(7, 6); p.quadTo(2, 0, 7, -6);
     96        MarineFarm.add(new Instr(Form.PLIN, p));
     97        MarineFarm.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, -2, 4, 4)));
     98    }
     99
     100    public static final Symbol NoWake = new Symbol();
     101    static {
     102        NoWake.add(new Instr(Form.STRK, new BasicStroke(12, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     103        NoWake.add(new Instr(Form.FILL, new Color(0xa30075)));
     104        Path2D.Double p = new Path2D.Double(); p.moveTo(-60, 20); p.curveTo(-28, 20, -32, 0, 0, 0); p.curveTo(32, 0, 28, 20, 60, 20); p.moveTo(-60, 0); p.curveTo(-28, 0, -32, -20, 0, -20); p.curveTo(32, -20, 28, 0, 60, 0);
     105        NoWake.add(new Instr(Form.PLIN, p));
     106        NoWake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     107        NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60, 60, 60, -60)));
     108        NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60, -60, 60, 60)));
     109    }
     110
     111    public static final Symbol Pipeline = new Symbol();
     112    static {
     113        Pipeline.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15, -60, 30, 60)));
     114        Pipeline.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     115        Pipeline.add(new Instr(Form.FILL, new Color(0xc480ff)));
     116        Pipeline.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -50)));
     117        Pipeline.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -60, 20, 20)));
     118    }
     119
     120    public static final Symbol Restricted = new Symbol();
     121    static {
     122        Restricted.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15, -30, 30, 30)));
     123        Restricted.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     124        Restricted.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -30)));
     125        Restricted.add(new Instr(Form.LINE, new Line2D.Double(0, -15, 17, -15)));
     126    }
     127
     128    public static final Symbol Rock = new Symbol();
     129    static {
     130        Rock.add(new Instr(Form.FILL, new Color(0x80c0ff)));
     131        Rock.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
     132        Rock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
     133        Rock.add(new Instr(Form.FILL, Color.black));
     134        Rock.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
     135        Rock.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     136        Rock.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
     137        Rock.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 20)));
     138    }
     139
     140    public static final Symbol RockA = new Symbol();
     141    static {
     142        RockA.add(new Instr(Form.FILL, new Color(0x80c0ff)));
     143        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
     144        RockA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
     145        RockA.add(new Instr(Form.FILL, Color.black));
     146        RockA.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
     147        RockA.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     148        RockA.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
     149        RockA.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 20)));
     150        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17, -17, 8, 8)));
     151        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17, 9, 8, 8)));
     152        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, -17, 8, 8)));
     153        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, 9, 8, 8)));
     154    }
     155
     156    public static final Symbol RockC = new Symbol();
     157    static {
     158        RockC.add(new Instr(Form.FILL, new Color(0x80c0ff)));
     159        RockC.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
     160        RockC.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
     161        RockC.add(new Instr(Form.FILL, Color.black));
     162        RockC.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
     163        RockC.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     164        RockC.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
     165        RockC.add(new Instr(Form.LINE, new Line2D.Double(-10, 17.3, 10, -17.3)));
     166        RockC.add(new Instr(Form.LINE, new Line2D.Double(10, 17.3, -10, -17.3)));
     167    }
     168
     169    public static final Symbol Seaplane = new Symbol();
     170    static {
     171        Seaplane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
     172        Seaplane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     173        Seaplane.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58, -58, 116, 116)));
     174        Seaplane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 1.0, 0, 0, null, null)));
     175    }
     176
     177    public static final Symbol WindFarm = new Symbol();
     178    static {
     179        WindFarm.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     180        WindFarm.add(new Instr(Form.ELPS, new Ellipse2D.Double(-100, -100, 200, 200)));
     181        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(-35, 50, 35, 50)));
     182        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, 50, 0, -27.5)));
     183        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, 30, -27.5)));
     184        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, -13.8, -3.8)));
     185        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, -13.8, -53.6)));
     186    }
     187
     188    public static final Symbol WreckD = new Symbol();
     189    static {
     190        WreckD.add(new Instr(Form.FILL, new Color(0x80c0ff)));
     191        WreckD.add(new Instr(Form.RSHP, new Ellipse2D.Double(-50, -40, 100, 80)));
     192        WreckD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
     193        WreckD.add(new Instr(Form.FILL, Color.black));
     194        WreckD.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50, -40, 100, 80)));
     195        WreckD.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     196        WreckD.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, 40, 0)));
     197        WreckD.add(new Instr(Form.LINE, new Line2D.Double(0, -30, 0, 30)));
     198        WreckD.add(new Instr(Form.LINE, new Line2D.Double(-20, -15, -20, 15)));
     199        WreckD.add(new Instr(Form.LINE, new Line2D.Double(20, -15, 20, 15)));
     200    }
     201
     202    public static final Symbol WreckND = new Symbol();
     203    static {
     204        WreckND.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     205        WreckND.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, 40, 0)));
     206        WreckND.add(new Instr(Form.LINE, new Line2D.Double(0, -30, 0, 30)));
     207        WreckND.add(new Instr(Form.LINE, new Line2D.Double(-20, -15, -20, 15)));
     208        WreckND.add(new Instr(Form.LINE, new Line2D.Double(20, -15, 20, 15)));
     209    }
     210
     211    public static final Symbol WreckS = new Symbol();
     212    static {
     213        WreckS.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     214        WreckS.add(new Instr(Form.ELPS, new Ellipse2D.Double(-6, -6, 12, 12)));
     215        WreckS.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -6, 0)));
     216        WreckS.add(new Instr(Form.LINE, new Line2D.Double(40, 0, 6, 0)));
     217        Path2D.Double p = new Path2D.Double(); p.moveTo(-30, 0); p.lineTo(-40, -25); p.lineTo(-0.3, -12.6); p.lineTo(13.7, -37.7); p.lineTo(16.3, -36.3);
     218        p.lineTo(2.7, -11.6); p.lineTo(37.5, 0); p.lineTo(6, 0); p.curveTo(5.6, -8, -5.6, -8, -6, 0); p.closePath();
     219        WreckS.add(new Instr(Form.PGON, p));
     220    }
     221
     222    public static final BufferedImage Sandwaves = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
     223    static {
     224        Graphics2D g2 = Sandwaves.createGraphics();
     225        g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     226        g2.setBackground(new Color(0, true));
     227        g2.clearRect(0, 0, 100, 100);
     228        g2.setPaint(new Color(0xffd400));
     229        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, 34.5); p.lineTo(03.3, 30.8); p.lineTo(09.9, 19.3); p.lineTo(13.2, 16.0); p.lineTo(16.5, 16.1); p.lineTo(18.2, 19.5);
     230        p.lineTo(19.9, 25.0); p.lineTo(21.6, 30.3); p.lineTo(23.3, 33.4); p.lineTo(25.0, 33.3); p.lineTo(28.3, 30.1); p.lineTo(31.6, 25.0); p.lineTo(34.9, 20.1); p.lineTo(38.2, 17.2);
     231        p.lineTo(41.5, 17.3); p.lineTo(43.2, 20.3); p.lineTo(44.9, 25); p.lineTo(46.6, 29.6); p.lineTo(48.3, 32.2); p.lineTo(50.0, 32.1);
     232        p.moveTo(50.0, 84.5); p.lineTo(53.3, 80.8); p.lineTo(56.6, 75.0); p.lineTo(59.9, 69.3); p.lineTo(63.2, 66.0); p.lineTo(66.5, 66.1); p.lineTo(68.2, 69.5); p.lineTo(69.9, 75.0);
     233        p.lineTo(71.6, 80.3); p.lineTo(73.3, 83.4); p.lineTo(75.0, 83.3); p.lineTo(78.3, 80.1); p.lineTo(81.6, 75.0); p.lineTo(84.9, 70.1); p.lineTo(88.2, 67.2); p.lineTo(91.5, 67.3);
     234        p.lineTo(93.2, 70.3); p.lineTo(94.9, 75.0); p.lineTo(96.6, 79.6); p.lineTo(98.3, 82.2); p.lineTo(100.0, 82.1);
     235        g2.draw(p);
     236    }
     237
     238    public static final Symbol KelpS = new Symbol();
     239    static {
     240        KelpS.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     241        Path2D.Double p = new Path2D.Double(); p.moveTo(-60, 0); p.curveTo(-20, -20, -24, 40, 24, 20); p.moveTo(-60, 0); p.quadTo(-48, 20, -32, 12);
     242        p.moveTo(-36, -4); p.quadTo(-24, -24, -4, -16); p.quadTo(8, -32, 20, -24); p.moveTo(-4, -16); p.quadTo(8, 0, 20, -8);
     243        p.moveTo(-8, 20); p.quadTo(12, 0, 36, 8); p.quadTo(48, 24, 60, 16); p.moveTo(36, 8); p.quadTo(48, -8, 60, 0);
     244        KelpS.add(new Instr(Form.PLIN, p));
     245    }
     246
     247    public static final BufferedImage KelpA = new BufferedImage(240, 240, BufferedImage.TYPE_INT_ARGB);
     248    static {
     249        Graphics2D g2 = KelpA.createGraphics();
     250        g2.setStroke(new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     251        g2.setBackground(new Color(0, true));
     252        g2.clearRect(0, 0, 240, 240);
     253        g2.setPaint(Color.black);
     254        Path2D.Double p = new Path2D.Double();
     255        p.moveTo(0, 60); p.curveTo(40, 40, 44, 100, 84, 80); p.moveTo(0, 60); p.quadTo(12, 80, 28, 72); p.moveTo(24, 56); p.quadTo(36, 36, 56, 44); p.quadTo(68, 28, 80, 36);
     256        p.moveTo(56, 44); p.quadTo(68, 60, 80, 52); p.moveTo(52, 76); p.quadTo(72, 60, 96, 68); p.quadTo(108, 84, 120, 76); p.moveTo(96, 68); p.quadTo(108, 52, 120, 60);
     257        p.moveTo(120, 180); p.curveTo(160, 160, 164, 220, 204, 200); p.moveTo(120, 180); p.quadTo(132, 200, 148, 192); p.moveTo(144, 176); p.quadTo(156, 156, 176, 164); p.quadTo(188, 148, 200, 156);
     258        p.moveTo(176, 164); p.quadTo(188, 180, 200, 172); p.moveTo(172, 196); p.quadTo(192, 180, 216, 188); p.quadTo(228, 204, 240, 196); p.moveTo(216, 188); p.quadTo(228, 172, 240, 180);
     259        g2.draw(p);
     260    }
    228261}
  • applications/editors/josm/plugins/seachart/src/symbols/Beacons.java

    r32393 r32394  
    1212import java.awt.BasicStroke;
    1313import java.awt.Color;
    14 import java.awt.geom.*;
     14import java.awt.geom.Arc2D;
     15import java.awt.geom.Ellipse2D;
     16import java.awt.geom.GeneralPath;
     17import java.awt.geom.Line2D;
     18import java.awt.geom.Path2D;
     19import java.awt.geom.Rectangle2D;
    1520import java.util.EnumMap;
    1621
    17 import symbols.Symbols.*;
    18 import s57.S57val.*;
     22import s57.S57val.BcnSHP;
     23import symbols.Symbols.Form;
     24import symbols.Symbols.Instr;
     25import symbols.Symbols.Symbol;
    1926
    2027public class Beacons {
    21        
    22         public static final Symbol Beacon = new Symbol();
    23         static {
    24                 Symbol colours = new Symbol();
    25                 Path2D.Double p = new Path2D.Double(); p.moveTo(-6.0,-8.5); p.lineTo(-6.0,-70.0); p.lineTo(6.0,-70.0); p.lineTo(6.0,-8.5); p.curveTo(6.0,-10.0,-6.0,-10.0,-6.0,-8.5); p.closePath();
    26                 colours.add(new Instr(Form.P1, p));
    27                 p = new Path2D.Double(); p.moveTo(-6.0,-8.5); p.lineTo(-6.0,-40.0); p.lineTo(6.0,-40.0); p.lineTo(6.0,-8.5); p.curveTo(6.0,-10.0,-6.0,-10.0,-6.0,-8.5); p.closePath();
    28     colours.add(new Instr(Form.H2, p));
    29                 p = new Path2D.Double(); p.moveTo(-6.0,-30.0); p.lineTo(-6.0,-50.0); p.lineTo(6.0,-50.0); p.lineTo(6.0,-30.0); p.closePath();
    30     colours.add(new Instr(Form.H3, p));
    31                 p = new Path2D.Double(); p.moveTo(-6.0,-40.0); p.lineTo(-6.0,-55.0); p.lineTo(6.0,-55.0); p.lineTo(6.0,-40.0); p.closePath();
    32     colours.add(new Instr(Form.H4, p));
    33                 p = new Path2D.Double(); p.moveTo(-6.0,-25.0); p.lineTo(-6.0,-40.0); p.lineTo(6.0,-40.0); p.lineTo(6.0,-25.0); p.closePath();
    34     colours.add(new Instr(Form.H5, p));
    35                 p = new Path2D.Double(); p.moveTo(0.0,-70.0); p.lineTo(6.0,-70.0); p.lineTo(6.0,-8.5); p.quadTo(3.0,-9.3,0.0,-10.0); p.closePath();
    36     colours.add(new Instr(Form.V2, p));
    37     Beacon.add(new Instr(Form.COLR, colours));
    38     Beacon.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    39     Beacon.add(new Instr(Form.FILL, Color.black));
    40     Beacon.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    41     Beacon.add(new Instr(Form.LINE, new Line2D.Double(-20,0,-10,0)));
    42     Beacon.add(new Instr(Form.LINE, new Line2D.Double(10,0,20,0)));
    43                 p = new Path2D.Double(); p.moveTo(-6.0,-8.5); p.lineTo(-6.0,-70.0); p.lineTo(6.0,-70.0); p.lineTo(6.0,-8.5);
    44                 Beacon.add(new Instr(Form.PLIN, p));
    45         }
    46         public static final Symbol Cairn = new Symbol();
    47         static {
    48                 Cairn.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    49                 Cairn.add(new Instr(Form.FILL, Color.black));
    50                 Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    51                 Cairn.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
    52                 Cairn.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
    53                 Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(3,-40,40,40)));
    54                 Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-43,-40,40,40)));
    55                 Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-18,-70,36,36)));
    56         }
    57         public static final Symbol FogSignal = new Symbol();
    58         static {
    59                 FogSignal.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    60                 FogSignal.add(new Instr(Form.FILL, Color.black));
    61                 FogSignal.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    62                 FogSignal.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    63                 FogSignal.add(new Instr(Form.FILL, new Color(0xd400d4)));
    64                 FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-120.0,-120.0,240.0,240.0,190.0,50.0,Arc2D.OPEN)));
    65                 FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-92.5,-92.5,185.0,185.0,190.0,50.0,Arc2D.OPEN)));
    66                 FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-65.0,-65.0,130.0,130.0,190.0,50.0,Arc2D.OPEN)));
    67         }
    68         public static final Symbol LightFlare = new Symbol();
    69         static {
    70                 LightFlare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-100,40,100)));
    71                 LightFlare.add(new Instr(Form.RSHP, new Ellipse2D.Double(-3,-3,6,6)));
    72                 Path2D.Double p = new Path2D.Double();
    73                 p.moveTo(0.0,-25.0); p.lineTo(15.0,-95.0); p.curveTo(20.0,-123.0,-20.0,-123.0,-15.0,-95.0);
    74                 p.closePath();
    75                 LightFlare.add(new Instr(Form.PGON, p));
    76         }
    77         public static final Symbol LightMajor = new Symbol();
    78         static {
    79                 LightMajor.add(new Instr(Form.FILL, Color.black));
    80                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_NON_ZERO);
    81                 p.moveTo(0.0,-7.0); p.curveTo(-9.3,-6.5,-9.3,6.5,0.0,7.0); p.curveTo(9.3,6.5,9.3,-6.5,0.0,-7.0); p.closePath();
    82                 p.moveTo(0.0,-35.5); p.lineTo(8.0,-11.2); p.lineTo(33.5,-11.2); p.lineTo(12.8,4.0);
    83                 p.lineTo(20.5,28.5); p.lineTo(0.0,13.0); p.lineTo(-20.5,28.5); p.lineTo(-12.8,4.0); p.lineTo(-33.5,-11.2); p.lineTo(-8.0,-11.2); p.closePath();
    84                 LightMajor.add(new Instr(Form.PGON, p));
    85         }
    86         public static final Symbol LightMinor = new Symbol();
    87         static {
    88                 LightMinor.add(new Instr(Form.FILL, Color.black));
    89                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-26.5); p.lineTo(6.0,-8.4); p.lineTo(25.1,-8.4); p.lineTo(9.6,3.0);
    90                 p.lineTo(15.4,21.4); p.lineTo(0.0,9.8); p.lineTo(-15.4,21.4); p.lineTo(-9.6,3.0); p.lineTo(-25.1,-8.4); p.lineTo(-6.0,-8.4); p.closePath();
    91                 LightMinor.add(new Instr(Form.PGON, p));
    92         }
    93         public static final Symbol PerchPort = new Symbol();
    94         static {
    95                 PerchPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    96                 PerchPort.add(new Instr(Form.FILL, Color.black));
    97                 PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
    98                 PerchPort.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-40)));
    99                 PerchPort.add(new Instr(Form.LINE, new Line2D.Double(25,-70,0,-40)));
    100                 PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-25,-70,0,-40)));
    101         }
    102         public static final Symbol PerchStarboard = new Symbol();
    103         static {
    104                 PerchStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    105                 PerchStarboard.add(new Instr(Form.FILL, Color.black));
    106                 PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
    107                 PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
    108                 PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(25,-40,0,-68.7)));
    109                 PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-25,-40,0,-68.7)));
    110         }
    111         public static final Symbol RadarStation = new Symbol();
    112         static {
    113                 RadarStation.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    114                 RadarStation.add(new Instr(Form.FILL, new Color(0xd400d4)));
    115                 RadarStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-125,-125,250,250)));
    116         }
    117         public static final Symbol Stake = new Symbol();
    118         static {
    119                 Stake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    120                 Stake.add(new Instr(Form.FILL, Color.black));
    121                 Stake.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
    122                 Symbol colours = new Symbol();
    123                 Path2D.Double p = new Path2D.Double(); p.moveTo(-2.0,0.0); p.lineTo(-2.0,-70.0); p.lineTo(2.0,-70.0); p.lineTo(2.0,0.0); p.closePath();
    124                 colours.add(new Instr(Form.P1, p));
    125                 p = new Path2D.Double(); p.moveTo(-2.0,0.0); p.lineTo(-2.0,-35.0); p.lineTo(2.0,-35.0); p.lineTo(2.0,0.0); p.closePath();
    126                 colours.add(new Instr(Form.H2, p));
    127                 p = new Path2D.Double(); p.moveTo(-2.0,-23.3); p.lineTo(-2.0,-46.7); p.lineTo(2.0,-46.7); p.lineTo(2.0,-23.3); p.closePath();
    128                 colours.add(new Instr(Form.H3, p));
    129                 p = new Path2D.Double(); p.moveTo(-2.0,-35.0); p.lineTo(-2.0,-52.5); p.lineTo(2.0,-52.5); p.lineTo(2.0,-35.0); p.closePath();
    130                 colours.add(new Instr(Form.H4, p));
    131                 p = new Path2D.Double(); p.moveTo(-2.0,-17.5); p.lineTo(-2.0,-35.0); p.lineTo(2.0,-35.0); p.lineTo(2.0,-17.5); p.closePath();
    132                 colours.add(new Instr(Form.H5, p));
    133                 Stake.add(new Instr(Form.COLR, colours));
    134                 Stake.add(new Instr(Form.FILL, Color.black));
    135                 Stake.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
    136         }
    137         public static final Symbol Tower = new Symbol();
    138         static {
    139                 Symbol colours = new Symbol();
    140                 Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(-20.0,-70.0); p.lineTo(20.0,-70.0); p.lineTo(25.0,0.0); p.lineTo(10.0,0.0); p.curveTo(10.0,-13.3,-10.0,-13.3,-10.0,0.0); p.closePath();
    141                 colours.add(new Instr(Form.P1, p));
    142                 p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(-22.5,-35.0); p.lineTo(22.5,-35.0); p.lineTo(25.0,0.0); p.lineTo(10.0,0.0); p.curveTo(10.0,-13.3,-10.0,-13.3,-10.0,0.0); p.closePath();
    143     colours.add(new Instr(Form.H2, p));
    144                 p = new Path2D.Double(); p.moveTo(-23.3,-23.3); p.lineTo(-21.7,-46.7); p.lineTo(21.7,-46.7); p.lineTo(23.3,-23.3); p.closePath();
    145     colours.add(new Instr(Form.H3, p));
    146                 p = new Path2D.Double(); p.moveTo(-22.5,-35.0); p.lineTo(-21.0,-52.5); p.lineTo(21.0,-52.5); p.lineTo(22.5,-35.0); p.closePath();
    147     colours.add(new Instr(Form.H4, p));
    148                 p = new Path2D.Double(); p.moveTo(-23.6,-17.5); p.lineTo(-22.5,-35.0); p.lineTo(22.5,-35.0); p.lineTo(23.6,-17.5); p.closePath();
    149     colours.add(new Instr(Form.H5, p));
    150                 p = new Path2D.Double(); p.moveTo(0.0,-70.0); p.lineTo(20.0,-70.0); p.lineTo(25.0,0.0); p.lineTo(10.0,0.0); p.quadTo(10.0,-10.0,0.0,-10.0); p.closePath();
    151     colours.add(new Instr(Form.V2, p));
    152     Tower.add(new Instr(Form.COLR, colours));
    153     Tower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    154     Tower.add(new Instr(Form.FILL, Color.black));
    155     Tower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    156     Tower.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
    157     Tower.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
    158                 p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(-20.0,-70.0); p.lineTo(20.0,-70.0); p.lineTo(25.0,0.0);
    159                 Tower.add(new Instr(Form.PLIN, p));
    160         }
    161         public static final Symbol WithyPort = new Symbol();
    162         static {
    163                 WithyPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    164                 WithyPort.add(new Instr(Form.FILL, Color.black));
    165                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
    166                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
    167                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(20,-60,0,-50)));
    168                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-20,-60,0,-50)));
    169                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(30,-35,0,-21)));
    170                 WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-30,-35,0,-21)));
    171         }
    172         public static final Symbol WithyStarboard = new Symbol();
    173         static {
    174                 WithyStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    175                 WithyStarboard.add(new Instr(Form.FILL, Color.black));
    176                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
    177                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
    178                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(20,-50,0,-60)));
    179                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-20,-50,0,-60)));
    180                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(30,-21,0,-35)));
    181                 WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-30,-21,0,-35)));
    182         }
    183        
    184         public static final EnumMap<BcnSHP, Symbol> Shapes = new EnumMap<>(BcnSHP.class);
    185         static {
    186                 Shapes.put(BcnSHP.BCN_UNKN, Beacons.Beacon); Shapes.put(BcnSHP.BCN_STAK, Beacons.Stake); Shapes.put(BcnSHP.BCN_TOWR, Beacons.Tower);
    187                 Shapes.put(BcnSHP.BCN_LATT, Beacons.Beacon); Shapes.put(BcnSHP.BCN_PILE, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POLE, Beacons.Stake);
    188                 Shapes.put(BcnSHP.BCN_CARN, Beacons.Cairn); Shapes.put(BcnSHP.BCN_BUOY, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POST, Beacons.Stake);
    189                 Shapes.put(BcnSHP.BCN_PRCH, Beacons.Stake);
    190         }
     28    // CHECKSTYLE.OFF: LineLength
     29    public static final Symbol Beacon = new Symbol();
     30    static {
     31        Symbol colours = new Symbol();
     32        Path2D.Double p = new Path2D.Double(); p.moveTo(-6.0, -8.5); p.lineTo(-6.0, -70.0); p.lineTo(6.0, -70.0); p.lineTo(6.0, -8.5); p.curveTo(6.0, -10.0, -6.0, -10.0, -6.0, -8.5); p.closePath();
     33        colours.add(new Instr(Form.P1, p));
     34        p = new Path2D.Double(); p.moveTo(-6.0, -8.5); p.lineTo(-6.0, -40.0); p.lineTo(6.0, -40.0); p.lineTo(6.0, -8.5); p.curveTo(6.0, -10.0, -6.0, -10.0, -6.0, -8.5); p.closePath();
     35        colours.add(new Instr(Form.H2, p));
     36        p = new Path2D.Double(); p.moveTo(-6.0, -30.0); p.lineTo(-6.0, -50.0); p.lineTo(6.0, -50.0); p.lineTo(6.0, -30.0); p.closePath();
     37        colours.add(new Instr(Form.H3, p));
     38        p = new Path2D.Double(); p.moveTo(-6.0, -40.0); p.lineTo(-6.0, -55.0); p.lineTo(6.0, -55.0); p.lineTo(6.0, -40.0); p.closePath();
     39        colours.add(new Instr(Form.H4, p));
     40        p = new Path2D.Double(); p.moveTo(-6.0, -25.0); p.lineTo(-6.0, -40.0); p.lineTo(6.0, -40.0); p.lineTo(6.0, -25.0); p.closePath();
     41        colours.add(new Instr(Form.H5, p));
     42        p = new Path2D.Double(); p.moveTo(0.0, -70.0); p.lineTo(6.0, -70.0); p.lineTo(6.0, -8.5); p.quadTo(3.0, -9.3, 0.0, -10.0); p.closePath();
     43        colours.add(new Instr(Form.V2, p));
     44        Beacon.add(new Instr(Form.COLR, colours));
     45        Beacon.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     46        Beacon.add(new Instr(Form.FILL, Color.black));
     47        Beacon.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     48        Beacon.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, -10, 0)));
     49        Beacon.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 20, 0)));
     50        p = new Path2D.Double(); p.moveTo(-6.0, -8.5); p.lineTo(-6.0, -70.0); p.lineTo(6.0, -70.0); p.lineTo(6.0, -8.5);
     51        Beacon.add(new Instr(Form.PLIN, p));
     52    }
     53
     54    public static final Symbol Cairn = new Symbol();
     55    static {
     56        Cairn.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     57        Cairn.add(new Instr(Form.FILL, Color.black));
     58        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     59        Cairn.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
     60        Cairn.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
     61        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(3, -40, 40, 40)));
     62        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-43, -40, 40, 40)));
     63        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-18, -70, 36, 36)));
     64    }
     65
     66    public static final Symbol FogSignal = new Symbol();
     67    static {
     68        FogSignal.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     69        FogSignal.add(new Instr(Form.FILL, Color.black));
     70        FogSignal.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     71        FogSignal.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     72        FogSignal.add(new Instr(Form.FILL, new Color(0xd400d4)));
     73        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-120.0, -120.0, 240.0, 240.0, 190.0, 50.0, Arc2D.OPEN)));
     74        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-92.5, -92.5, 185.0, 185.0, 190.0, 50.0, Arc2D.OPEN)));
     75        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-65.0, -65.0, 130.0, 130.0, 190.0, 50.0, Arc2D.OPEN)));
     76    }
     77
     78    public static final Symbol LightFlare = new Symbol();
     79    static {
     80        LightFlare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -100, 40, 100)));
     81        LightFlare.add(new Instr(Form.RSHP, new Ellipse2D.Double(-3, -3, 6, 6)));
     82        Path2D.Double p = new Path2D.Double();
     83        p.moveTo(0.0, -25.0); p.lineTo(15.0, -95.0); p.curveTo(20.0, -123.0, -20.0, -123.0, -15.0, -95.0);
     84        p.closePath();
     85        LightFlare.add(new Instr(Form.PGON, p));
     86    }
     87
     88    public static final Symbol LightMajor = new Symbol();
     89    static {
     90        LightMajor.add(new Instr(Form.FILL, Color.black));
     91        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_NON_ZERO);
     92        p.moveTo(0.0, -7.0); p.curveTo(-9.3, -6.5, -9.3, 6.5, 0.0, 7.0); p.curveTo(9.3, 6.5, 9.3, -6.5, 0.0, -7.0); p.closePath();
     93        p.moveTo(0.0, -35.5); p.lineTo(8.0, -11.2); p.lineTo(33.5, -11.2); p.lineTo(12.8, 4.0);
     94        p.lineTo(20.5, 28.5); p.lineTo(0.0, 13.0); p.lineTo(-20.5, 28.5); p.lineTo(-12.8, 4.0); p.lineTo(-33.5, -11.2); p.lineTo(-8.0, -11.2); p.closePath();
     95        LightMajor.add(new Instr(Form.PGON, p));
     96    }
     97
     98    public static final Symbol LightMinor = new Symbol();
     99    static {
     100        LightMinor.add(new Instr(Form.FILL, Color.black));
     101        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -26.5); p.lineTo(6.0, -8.4); p.lineTo(25.1, -8.4); p.lineTo(9.6, 3.0);
     102        p.lineTo(15.4, 21.4); p.lineTo(0.0, 9.8); p.lineTo(-15.4, 21.4); p.lineTo(-9.6, 3.0); p.lineTo(-25.1, -8.4); p.lineTo(-6.0, -8.4); p.closePath();
     103        LightMinor.add(new Instr(Form.PGON, p));
     104    }
     105
     106    public static final Symbol PerchPort = new Symbol();
     107    static {
     108        PerchPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     109        PerchPort.add(new Instr(Form.FILL, Color.black));
     110        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
     111        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -40)));
     112        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(25, -70, 0, -40)));
     113        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-25, -70, 0, -40)));
     114    }
     115
     116    public static final Symbol PerchStarboard = new Symbol();
     117    static {
     118        PerchStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     119        PerchStarboard.add(new Instr(Form.FILL, Color.black));
     120        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
     121        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
     122        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(25, -40, 0, -68.7)));
     123        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-25, -40, 0, -68.7)));
     124    }
     125
     126    public static final Symbol RadarStation = new Symbol();
     127    static {
     128        RadarStation.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     129        RadarStation.add(new Instr(Form.FILL, new Color(0xd400d4)));
     130        RadarStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-125, -125, 250, 250)));
     131    }
     132
     133    public static final Symbol Stake = new Symbol();
     134    static {
     135        Stake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     136        Stake.add(new Instr(Form.FILL, Color.black));
     137        Stake.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
     138        Symbol colours = new Symbol();
     139        Path2D.Double p = new Path2D.Double(); p.moveTo(-2.0, 0.0); p.lineTo(-2.0, -70.0); p.lineTo(2.0, -70.0); p.lineTo(2.0, 0.0); p.closePath();
     140        colours.add(new Instr(Form.P1, p));
     141        p = new Path2D.Double(); p.moveTo(-2.0, 0.0); p.lineTo(-2.0, -35.0); p.lineTo(2.0, -35.0); p.lineTo(2.0, 0.0); p.closePath();
     142        colours.add(new Instr(Form.H2, p));
     143        p = new Path2D.Double(); p.moveTo(-2.0, -23.3); p.lineTo(-2.0, -46.7); p.lineTo(2.0, -46.7); p.lineTo(2.0, -23.3); p.closePath();
     144        colours.add(new Instr(Form.H3, p));
     145        p = new Path2D.Double(); p.moveTo(-2.0, -35.0); p.lineTo(-2.0, -52.5); p.lineTo(2.0, -52.5); p.lineTo(2.0, -35.0); p.closePath();
     146        colours.add(new Instr(Form.H4, p));
     147        p = new Path2D.Double(); p.moveTo(-2.0, -17.5); p.lineTo(-2.0, -35.0); p.lineTo(2.0, -35.0); p.lineTo(2.0, -17.5); p.closePath();
     148        colours.add(new Instr(Form.H5, p));
     149        Stake.add(new Instr(Form.COLR, colours));
     150        Stake.add(new Instr(Form.FILL, Color.black));
     151        Stake.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
     152    }
     153
     154    public static final Symbol Tower = new Symbol();
     155    static {
     156        Symbol colours = new Symbol();
     157        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(-20.0, -70.0); p.lineTo(20.0, -70.0); p.lineTo(25.0, 0.0); p.lineTo(10.0, 0.0); p.curveTo(10.0, -13.3, -10.0, -13.3, -10.0, 0.0); p.closePath();
     158        colours.add(new Instr(Form.P1, p));
     159        p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(-22.5, -35.0); p.lineTo(22.5, -35.0); p.lineTo(25.0, 0.0); p.lineTo(10.0, 0.0); p.curveTo(10.0, -13.3, -10.0, -13.3, -10.0, 0.0); p.closePath();
     160        colours.add(new Instr(Form.H2, p));
     161        p = new Path2D.Double(); p.moveTo(-23.3, -23.3); p.lineTo(-21.7, -46.7); p.lineTo(21.7, -46.7); p.lineTo(23.3, -23.3); p.closePath();
     162        colours.add(new Instr(Form.H3, p));
     163        p = new Path2D.Double(); p.moveTo(-22.5, -35.0); p.lineTo(-21.0, -52.5); p.lineTo(21.0, -52.5); p.lineTo(22.5, -35.0); p.closePath();
     164        colours.add(new Instr(Form.H4, p));
     165        p = new Path2D.Double(); p.moveTo(-23.6, -17.5); p.lineTo(-22.5, -35.0); p.lineTo(22.5, -35.0); p.lineTo(23.6, -17.5); p.closePath();
     166        colours.add(new Instr(Form.H5, p));
     167        p = new Path2D.Double(); p.moveTo(0.0, -70.0); p.lineTo(20.0, -70.0); p.lineTo(25.0, 0.0); p.lineTo(10.0, 0.0); p.quadTo(10.0, -10.0, 0.0, -10.0); p.closePath();
     168        colours.add(new Instr(Form.V2, p));
     169        Tower.add(new Instr(Form.COLR, colours));
     170        Tower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     171        Tower.add(new Instr(Form.FILL, Color.black));
     172        Tower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     173        Tower.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
     174        Tower.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
     175        p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(-20.0, -70.0); p.lineTo(20.0, -70.0); p.lineTo(25.0, 0.0);
     176        Tower.add(new Instr(Form.PLIN, p));
     177    }
     178
     179    public static final Symbol WithyPort = new Symbol();
     180    static {
     181        WithyPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     182        WithyPort.add(new Instr(Form.FILL, Color.black));
     183        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
     184        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
     185        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(20, -60, 0, -50)));
     186        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-20, -60, 0, -50)));
     187        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(30, -35, 0, -21)));
     188        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-30, -35, 0, -21)));
     189    }
     190
     191    public static final Symbol WithyStarboard = new Symbol();
     192    static {
     193        WithyStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     194        WithyStarboard.add(new Instr(Form.FILL, Color.black));
     195        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
     196        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
     197        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(20, -50, 0, -60)));
     198        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-20, -50, 0, -60)));
     199        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(30, -21, 0, -35)));
     200        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-30, -21, 0, -35)));
     201    }
     202
     203    public static final EnumMap<BcnSHP, Symbol> Shapes = new EnumMap<>(BcnSHP.class);
     204    static {
     205        Shapes.put(BcnSHP.BCN_UNKN, Beacons.Beacon); Shapes.put(BcnSHP.BCN_STAK, Beacons.Stake); Shapes.put(BcnSHP.BCN_TOWR, Beacons.Tower);
     206        Shapes.put(BcnSHP.BCN_LATT, Beacons.Beacon); Shapes.put(BcnSHP.BCN_PILE, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POLE, Beacons.Stake);
     207        Shapes.put(BcnSHP.BCN_CARN, Beacons.Cairn); Shapes.put(BcnSHP.BCN_BUOY, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POST, Beacons.Stake);
     208        Shapes.put(BcnSHP.BCN_PRCH, Beacons.Stake);
     209    }
    191210}
  • applications/editors/josm/plugins/seachart/src/symbols/Buoys.java

    r32393 r32394  
    1212import java.awt.BasicStroke;
    1313import java.awt.Color;
    14 import java.awt.geom.*;
     14import java.awt.geom.Arc2D;
     15import java.awt.geom.Ellipse2D;
     16import java.awt.geom.Line2D;
     17import java.awt.geom.Path2D;
    1518import java.util.EnumMap;
    1619
    1720import s57.S57val.BoySHP;
    18 import symbols.Symbols.*;
     21import symbols.Symbols.Form;
     22import symbols.Symbols.Instr;
     23import symbols.Symbols.Symbol;
    1924
    2025public class Buoys {
    21 
    22         public static final Symbol Barrel = new Symbol();
    23         static {
    24                 Symbol colours = new Symbol();
    25                 Path2D.Double p = new Path2D.Double(); p.moveTo(-50.0,0); p.curveTo(-50.0,-11.0,-45.0,-32.0,-32.0,-36.0);
    26                 p.curveTo(-18.0,-40.0,12.0,-40.0,25.0,-36.0); p.curveTo(38.0,-32.0,43.0,-11.0,43.0,0);
    27                 p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    28                 colours.add(new Instr(Form.P1, p));
    29                 Barrel.add(new Instr(Form.COLR, colours));
    30     Barrel.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    31                 Barrel.add(new Instr(Form.FILL, Color.black));
    32                 Barrel.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    33                 Barrel.add(new Instr(Form.LINE, new Line2D.Double(-57,0,-10,0)));
    34                 Barrel.add(new Instr(Form.LINE, new Line2D.Double(10,0,50,0)));
    35                 p = new Path2D.Double(); p.moveTo(-50.0,0); p.curveTo(-50.0,-11.0,-45.0,-32.0,-32.0,-36.0); p.curveTo(-18.0,-40.0,12.0,-40.0,25.0,-36.0);
    36                 p.curveTo(38.0,-32.0,43.0,-11.0,43.0,0); p.moveTo(-32.0,-36.0); p.curveTo(-23.0,-25.0,-21.0,-12.0,-21.0,0.0);
    37     Barrel.add(new Instr(Form.PLIN, p));
    38         }
    39         public static final Symbol Can = new Symbol();
    40         static {
    41                 Symbol colours = new Symbol();
    42                 Path2D.Double p = new Path2D.Double(); p.moveTo(-31.6, 0); p.lineTo(-15.7,-47.4); p.lineTo(41.1,-28.4); p.lineTo(31.6,0);
    43                 p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    44                 colours.add(new Instr(Form.P1, p));
    45                 p = new Path2D.Double(); p.moveTo(-31.6,0); p.lineTo(-22.0,-28.4); p.lineTo(34.8,-9.4); p.lineTo(31.6,0);
    46                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    47     colours.add(new Instr(Form.H2, p));
    48                 p = new Path2D.Double(); p.moveTo(-24.2,-22.1); p.lineTo(-19.9,-34.8); p.lineTo(36.9,-15.8); p.lineTo(32.6,-3.1);       p.closePath();
    49     colours.add(new Instr(Form.H3, p));
    50                 p = new Path2D.Double(); p.moveTo(-22.0,-28.4); p.lineTo(-18.9,-37.9); p.lineTo(37.9,-18.9); p.lineTo(34.8,-9.4);       p.closePath();
    51     colours.add(new Instr(Form.H4, p));
    52                 p = new Path2D.Double(); p.moveTo(-25.2,-19.0); p.lineTo(-22.0,-28.4); p.lineTo(34.8,-9.4); p.lineTo(31.6,0.0); p.closePath();
    53     colours.add(new Instr(Form.H5, p));
    54                 p = new Path2D.Double(); p.moveTo(12.7,-37.9); p.lineTo(41.1,-28.4); p.lineTo(31.6,0);  p.lineTo(8.0,0.0); p.quadTo(8.0,-6.0,2.5,-7.6); p.closePath();
    55     colours.add(new Instr(Form.V2, p));
    56                 Can.add(new Instr(Form.COLR, colours));
    57     Can.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    58                 Can.add(new Instr(Form.FILL, Color.black));
    59                 Can.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    60                 Can.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
    61                 Can.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
    62                 p = new Path2D.Double(); p.moveTo(-31.6, 0); p.lineTo(-15.7,-47.4); p.lineTo(41.1,-28.4); p.lineTo(31.6,0);
    63     Can.add(new Instr(Form.PLIN, p));
    64         }
    65         public static final Symbol Cone = new Symbol();
    66         static {
    67                 Symbol colours = new Symbol();
    68                 Path2D.Double p = new Path2D.Double(); p.moveTo(-31.6,0); p.curveTo(-24.9,-32.2, 1.4,-38.7,12.7,-37.9); p.curveTo(21.9,-30.5,32.8,-18.4,32.1,0.0);
    69                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    70                 colours.add(new Instr(Form.P1, p));
    71                 p = new Path2D.Double(); p.moveTo(-31.6,0); p.quadTo(-29.0,-15.5,-17.3,-26.9); p.lineTo(31.5,-10.5); p.quadTo(33.0,-5.0,32.1,0.0);
    72                 p.lineTo(8.0,0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
    73     colours.add(new Instr(Form.H2, p));
    74                 p = new Path2D.Double(); p.moveTo(-22.3,-21.4); p.quadTo(-15.2,-29.8,-10.8,-31.8); p.lineTo(28.8,-18.5); p.quadTo(31.8,-12.5,32.6,-3.1); p.closePath();
    75     colours.add(new Instr(Form.H3, p));
    76                 p = new Path2D.Double(); p.moveTo(-17.3,-27.0); p.quadTo(-13.0,-31.4,-6.9,-33.8); p.lineTo(26.4,-22.7); p.quadTo(30.0,-17.0,31.7,-10.3); p.closePath();
    77     colours.add(new Instr(Form.H4, p));
    78                 p = new Path2D.Double(); p.moveTo(-24.4,-18.7); p.quadTo(-20.3,-25.0,-17.3,-27.0); p.lineTo(31.7,-10.3); p.quadTo(32.7,-4.5,32.1,0.0); p.closePath();
    79     colours.add(new Instr(Form.H5, p));
    80                 p = new Path2D.Double(); p.moveTo(12.7,-37.9); p.curveTo(21.9,-30.5,32.8,-18.4,32.1,0.0);       p.lineTo(8.0,0.0); p.quadTo(8.0,-6.0,2.5,-7.6); p.closePath();
    81     colours.add(new Instr(Form.V2, p));
    82                 Cone.add(new Instr(Form.COLR, colours));
    83     Cone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    84                 Cone.add(new Instr(Form.FILL, Color.black));
    85                 Cone.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    86                 Cone.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
    87                 Cone.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
    88                 p = new Path2D.Double(); p.moveTo(-31.6, 0); p.curveTo(-24.9,-32.2,1.4,-38.7,12.7,-37.9); p.curveTo(21.9,-30.5,32.8,-18.4,32.1,0.0);
    89     Cone.add(new Instr(Form.PLIN, p));
    90         }
    91         public static final Symbol Float = new Symbol();
    92         static {
    93                 Symbol colours = new Symbol();
    94                 Path2D.Double p = new Path2D.Double(); p.moveTo(-36.0,0); p.lineTo(-47.0,-33.0); p.quadTo(-30.0, -25.0, -19.0,-23.0);
    95                 p.lineTo(-12.0,-42.0); p.lineTo(12.0,-42.0); p.lineTo(19.0,-23.0); p.quadTo(30.0,-25.0,47.0,-33.0); p.lineTo(36.0,0);
    96                 p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    97                 colours.add(new Instr(Form.P1, p));
    98                 p = new Path2D.Double(); p.moveTo(-36.0,0); p.lineTo(-43.0,-21.0); p.lineTo(43.0,-21.0); p.lineTo(36.0,0);
    99                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    100     colours.add(new Instr(Form.H2, p));
    101                 p = new Path2D.Double(); p.moveTo(-40.8,-14.0); p.lineTo(-45.4,-28.0); p.lineTo(-35.5,-28.0); p.quadTo(-28.0,-25.0,-19.0,-23.0); p.lineTo(-17.2,-28.0);
    102                 p.lineTo(17.2,-28.0); p.lineTo(19.0,-23.0); p.quadTo(28.0,-25.0,35.5,-28.0); p.lineTo(45.4,-28.0); p.lineTo(40.8,-14.0); p.closePath();
    103     colours.add(new Instr(Form.H3, p));
    104                 p = new Path2D.Double(); p.moveTo(-43.0,-21.0); p.lineTo(-47.0,-33.0); p.quadTo(-29.7,-24.8,-19.0,-23.0); p.lineTo(-15.8,-31.5); p.lineTo(15.8,-31.5);
    105                 p.lineTo(19.0,-23.0); p.quadTo(28.4,-24.3,47.0,-33.0); p.lineTo(43.0,-21.0);    p.closePath();
    106     colours.add(new Instr(Form.H4, p));
    107                 p = new Path2D.Double(); p.moveTo(-39.8,-11.5); p.lineTo(-43.0,-21.0); p.lineTo(43.0,-21.0); p.lineTo(39.8,-11.5);      p.closePath();
    108     colours.add(new Instr(Form.H5, p));
    109                 p = new Path2D.Double(); p.moveTo(0.0,-42.0); p.lineTo(12.0,-42.0); p.lineTo(19.0,-23.0); p.quadTo(28.4,-24.3,47.0,-33.0); p.lineTo(36.0,0.0);
    110                 p.lineTo(8.0,0.0); p.quadTo(7.7,-7.7,0.0,-8.0); p.closePath();
    111     colours.add(new Instr(Form.V2, p));
    112                 Float.add(new Instr(Form.COLR, colours));
    113     Float.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    114                 Float.add(new Instr(Form.FILL, Color.black));
    115                 Float.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    116                 Float.add(new Instr(Form.LINE, new Line2D.Double(-54,0,-10,0)));
    117                 Float.add(new Instr(Form.LINE, new Line2D.Double(10,0,54,0)));
    118                 p = new Path2D.Double(); p.moveTo(-36.0,0); p.lineTo(-47.0,-33.0); p.curveTo(-15.0, -17.0, 15.0, -17.0, 47.0,-33.0); p.lineTo(36.0,0);
    119                 p.moveTo(-19.0, -23.0); p.lineTo(-12.0,-42.0); p.lineTo(12.0,-42.0); p.lineTo(19.0,-23.0);
    120     Float.add(new Instr(Form.PLIN, p));
    121         }
    122         public static final Symbol Ice = new Symbol();
    123         static {
    124                 Symbol colours = new Symbol();
    125                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,0); p.quadTo(-30.0,0.0,-30.0,-15.0); p.lineTo(-30.0,-25.0); p.lineTo(30.0,-25.0); p.lineTo(30.0,-15); p.quadTo(30.0,0.0,15.0,0.0);
    126                 p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    127                 colours.add(new Instr(Form.P1, p));
    128     Ice.add(new Instr(Form.COLR, colours));
    129     Ice.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    130     Ice.add(new Instr(Form.FILL, Color.black));
    131     Ice.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    132     Ice.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
    133     Ice.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
    134                 p = new Path2D.Double(); p.moveTo(-15.0,0); p.quadTo(-30.0,0.0,-30.0,-15.0); p.lineTo(-30.0,-25.0); p.lineTo(30.0,-25.0); p.lineTo(30.0,-15); p.quadTo(30.0,0.0,15.0,0.0);
    135                 Ice.add(new Instr(Form.PLIN, p));
    136                 p = new Path2D.Double(); p.moveTo(-6.0,8.0); p.lineTo(-6.0,40.0); p.lineTo(6.0,40.0); p.lineTo(6.0,8.0);
    137                 Ice.add(new Instr(Form.PLIN, p));
    138         }
    139         public static final Symbol Pillar = new Symbol();
    140         static {
    141                 Symbol colours = new Symbol();
    142                 Path2D.Double p = new Path2D.Double(); p.moveTo(-32.0,0.0); p.lineTo(-2.8,-32.5); p.lineTo(25.6,-96.7); p.lineTo(37.0,-92.9); p.lineTo(21.8,-24.3);
    143                 p.lineTo(25.0,0.0); p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    144                 colours.add(new Instr(Form.P1, p));
    145                 p = new Path2D.Double(); p.moveTo(-32.0,0); p.lineTo(-2.8,-32.5); p.lineTo(5.3,-51.0); p.lineTo(26.3,-43.9); p.lineTo(21.8,-24.3); p.lineTo(25.0,0.0);
    146                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    147     colours.add(new Instr(Form.H2, p));
    148                 p = new Path2D.Double(); p.moveTo(-0.9,-37.1); p.lineTo(11.3,-64.6); p.lineTo(29.6,-58.7); p.lineTo(23.1,-29.3);        p.closePath();
    149     colours.add(new Instr(Form.H3, p));
    150                 p = new Path2D.Double(); p.moveTo(5.3,-51.0); p.lineTo(14.5,-71.5); p.lineTo(31.2,-65.9); p.lineTo(26.3,-43.9); p.closePath();
    151     colours.add(new Instr(Form.H4, p));
    152                 p = new Path2D.Double(); p.moveTo(-5.2,-29.7); p.lineTo(-2.8,-32.5); p.lineTo(5.3,-51.0); p.lineTo(26.3,-43.9); p.lineTo(21.8,-24.3); p.lineTo(22.2,-21.5);     p.closePath();
    153     colours.add(new Instr(Form.H5, p));
    154                 p = new Path2D.Double(); p.moveTo(12.7,-37.9); p.lineTo(31.3,-94.8); p.lineTo(37.0,-92.9); p.lineTo(21.8,-24.3);
    155                 p.lineTo(25.0,0.0); p.lineTo(8.0,0.0); p.quadTo(8.0,-6.0,2.5,-7.6); p.closePath();
    156     colours.add(new Instr(Form.V2, p));
    157                 Pillar.add(new Instr(Form.COLR, colours));
    158                 Pillar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    159                 Pillar.add(new Instr(Form.FILL, Color.black));
    160                 Pillar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    161                 Pillar.add(new Instr(Form.LINE, new Line2D.Double(-42,0,-10,0)));
    162                 Pillar.add(new Instr(Form.LINE, new Line2D.Double(10,0,36,0)));
    163                 p = new Path2D.Double(); p.moveTo(-32.0,0.0); p.lineTo(-2.8,-32.5); p.lineTo(25.6,-96.7); p.lineTo(37.0,-92.9); p.lineTo(21.8,-24.3); p.lineTo(25.0,0.0);
    164                 Pillar.add(new Instr(Form.PLIN, p));
    165         }
    166         public static final Symbol Spar = new Symbol();
    167         static {
    168                 Symbol colours = new Symbol();
    169                 Path2D.Double p = new Path2D.Double(); p.moveTo(-3.2,-9.5); p.lineTo(25.6,-96.7); p.lineTo(37.0,-92.9); p.lineTo(8.2,-5.7); p.closePath();
    170                 colours.add(new Instr(Form.P1, p));
    171                 p = new Path2D.Double(); p.moveTo(-3.2,-9.5); p.lineTo(11.2,-53.1); p.lineTo(22.6,-49.3); p.lineTo(8.2,-5.7); p.closePath();
    172     colours.add(new Instr(Form.H2, p));
    173                 p = new Path2D.Double(); p.moveTo(6.4,-38.6); p.lineTo(16.0,-67.6); p.lineTo(27.4,-63.8); p.lineTo(17.8,-34.8); p.closePath();
    174     colours.add(new Instr(Form.H3, p));
    175                 p = new Path2D.Double(); p.moveTo(11.2,-53.1); p.lineTo(18.4,-74.9); p.lineTo(29.8,-71.1); p.lineTo(22.6,-49.3);        p.closePath();
    176     colours.add(new Instr(Form.H4, p));
    177                 p = new Path2D.Double(); p.moveTo(4.0,-31.3); p.lineTo(11.2,-53.1); p.lineTo(22.6,-49.3); p.lineTo(15.4,-27.5); p.closePath();
    178     colours.add(new Instr(Form.H5, p));
    179                 p = new Path2D.Double(); p.moveTo(2.5,-7.6); p.lineTo(31.3,-94.8); p.lineTo(37.0,-92.9); p.lineTo(8.2,-5.7); p.closePath();
    180     colours.add(new Instr(Form.V2, p));
    181                 Spar.add(new Instr(Form.COLR, colours));
    182                 Spar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    183                 Spar.add(new Instr(Form.FILL, Color.black));
    184                 Spar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    185                 Spar.add(new Instr(Form.LINE, new Line2D.Double(-20,0,-10,0)));
    186                 Spar.add(new Instr(Form.LINE, new Line2D.Double(10,0,20,0)));
    187                 p = new Path2D.Double(); p.moveTo(-3.2,-9.5); p.lineTo(25.6,-96.7); p.lineTo(37.0,-92.9); p.lineTo(8.2,-5.7);
    188                 Spar.add(new Instr(Form.PLIN, p));
    189         }
    190         public static final Symbol Sphere = new Symbol();
    191         static {
    192                 Symbol colours = new Symbol();
    193                 Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0); p.curveTo(-32.0,-21.0,-14.0,-45.5,12.7,-37.9); p.curveTo(27.5,-33.8,37.8,-15.5,32.0,0.0);
    194                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    195                 colours.add(new Instr(Form.P1, p));
    196                 p = new Path2D.Double(); p.moveTo(-25.0,0); p.quadTo(-30.0,-15.0,-20.5,-28.0); p.lineTo(33.8,-10.0); p.quadTo(33.7,-4.0,32.0,0.0);
    197                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    198     colours.add(new Instr(Form.H2, p));
    199                 p = new Path2D.Double(); p.moveTo(-24.2,-22.1); p.quadTo(-21.0,-28.5,-15.2,-33.3); p.lineTo(32.8,-17.2); p.quadTo(34.6,-10.0,33.0,-2.9); p.closePath();
    200     colours.add(new Instr(Form.H3, p));
    201                 p = new Path2D.Double(); p.moveTo(-20.5,-28.0); p.quadTo(-16.5,-33.0,-12.0,-35.5); p.lineTo(31.5,-21.0); p.quadTo(33.5,-17.0,34.0,-9.5); p.closePath();
    202     colours.add(new Instr(Form.H4, p));
    203                 p = new Path2D.Double(); p.moveTo(-25.2,-19.0); p.quadTo(-23.5,-24.0,-20.5,-28.0); p.lineTo(34.0,-9.5); p.quadTo(34.0,-3.0,32.0,0.0);   p.closePath();
    204     colours.add(new Instr(Form.H5, p));
    205                 p = new Path2D.Double(); p.moveTo(12.7,-37.9); p.curveTo(27.5,-33.8,37.8,-15.5,32.0,0.0);       p.lineTo(8.0,0.0); p.quadTo(8.0,-6.0,2.5,-7.6); p.closePath();
    206     colours.add(new Instr(Form.V2, p));
    207     Sphere.add(new Instr(Form.COLR, colours));
    208     Sphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    209     Sphere.add(new Instr(Form.FILL, Color.black));
    210     Sphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    211     Sphere.add(new Instr(Form.LINE, new Line2D.Double(-33,0,-10,0)));
    212     Sphere.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
    213     Sphere.add(new Instr(Form.EARC, new Arc2D.Double(-26.5,-39.4,60.0,60.0,-18.0,216.0,Arc2D.OPEN)));
    214         }
    215         public static final Symbol Storage = new Symbol();
    216         static {
    217                 Storage.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    218                 Storage.add(new Instr(Form.FILL, Color.black));
    219                 Storage.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    220     Path2D.Double p = new Path2D.Double(); p.moveTo(-50.0,0.0); p.lineTo(-40.0,-20.0); p.lineTo(40.0,-20.0); p.lineTo(40.0,-20.0);
    221     p.lineTo(50.0,0.0); p.lineTo(40.0,20.0); p.lineTo(-40.0,20.0); p.closePath();
    222     Storage.add(new Instr(Form.PLIN, p));
    223         }
    224         public static final Symbol Super = new Symbol();
    225         static {
    226                 Symbol colours = new Symbol();
    227                 Path2D.Double p = new Path2D.Double(); p.moveTo(-48.0,0); p.lineTo(-28.0,-42.0); p.lineTo(28.0,-42.0); p.lineTo(48.0,0);
    228                 p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    229                 colours.add(new Instr(Form.P1, p));
    230                 p = new Path2D.Double(); p.moveTo(-48.0,0); p.lineTo(-38.0,-21.0); p.lineTo(38.0,-21.0); p.lineTo(48.0,0);
    231                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    232     colours.add(new Instr(Form.H2, p));
    233                 p = new Path2D.Double(); p.moveTo(-41.3,-14.0); p.lineTo(-34.7,-28.0); p.lineTo(34.7,-28.0); p.lineTo(41.3,-14.0);      p.closePath();
    234     colours.add(new Instr(Form.H3, p));
    235                 p = new Path2D.Double(); p.moveTo(-38.0,-21.0); p.lineTo(-33.0,-31.5); p.lineTo(33.0,-31.5); p.lineTo(38.0,-21.0);      p.closePath();
    236     colours.add(new Instr(Form.H4, p));
    237                 p = new Path2D.Double(); p.moveTo(-43.0,-11.5); p.lineTo(-38.0,-21.0); p.lineTo(38.0,-21.0); p.lineTo(43.0,-11.5);      p.closePath();
    238     colours.add(new Instr(Form.H5, p));
    239                 p = new Path2D.Double(); p.moveTo(0.0,-42.0); p.lineTo(28.0,-42.0); p.lineTo(48.0,0.0); p.lineTo(8.0,0.0); p.quadTo(7.7,-7.7,0.0,-8.0); p.closePath();
    240     colours.add(new Instr(Form.V2, p));
    241                 Super.add(new Instr(Form.COLR, colours));
    242     Super.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    243                 Super.add(new Instr(Form.FILL, Color.black));
    244                 Super.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    245                 Super.add(new Instr(Form.LINE, new Line2D.Double(-54,0,-10,0)));
    246                 Super.add(new Instr(Form.LINE, new Line2D.Double(10,0,54,0)));
    247                 p = new Path2D.Double(); p.moveTo(-48.0,0); p.lineTo(-28.0,-42.0); p.lineTo(28.0,-42.0); p.lineTo(48.0,0);
    248     Super.add(new Instr(Form.PLIN, p));
    249         }
    250        
    251         public static final EnumMap<BoySHP, Symbol> Shapes = new EnumMap<>(BoySHP.class);
    252         static {
    253                 Shapes.put(BoySHP.BOY_UNKN, Buoys.Pillar); Shapes.put(BoySHP.BOY_CONE, Buoys.Cone); Shapes.put(BoySHP.BOY_CAN, Buoys.Can);
    254                 Shapes.put(BoySHP.BOY_SPHR, Buoys.Sphere); Shapes.put(BoySHP.BOY_PILR, Buoys.Pillar); Shapes.put(BoySHP.BOY_SPAR, Buoys.Spar);
    255                 Shapes.put(BoySHP.BOY_BARL, Buoys.Barrel); Shapes.put(BoySHP.BOY_SUPR, Buoys.Super); Shapes.put(BoySHP.BOY_ICE, Buoys.Ice);
    256         }
     26    // CHECKSTYLE.OFF: LineLength
     27    public static final Symbol Barrel = new Symbol();
     28    static {
     29        Symbol colours = new Symbol();
     30        Path2D.Double p = new Path2D.Double(); p.moveTo(-50.0, 0); p.curveTo(-50.0, -11.0, -45.0, -32.0, -32.0, -36.0);
     31        p.curveTo(-18.0, -40.0, 12.0, -40.0, 25.0, -36.0); p.curveTo(38.0, -32.0, 43.0, -11.0, 43.0, 0);
     32        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     33        colours.add(new Instr(Form.P1, p));
     34        Barrel.add(new Instr(Form.COLR, colours));
     35        Barrel.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     36        Barrel.add(new Instr(Form.FILL, Color.black));
     37        Barrel.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     38        Barrel.add(new Instr(Form.LINE, new Line2D.Double(-57, 0, -10, 0)));
     39        Barrel.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 50, 0)));
     40        p = new Path2D.Double(); p.moveTo(-50.0, 0); p.curveTo(-50.0, -11.0, -45.0, -32.0, -32.0, -36.0); p.curveTo(-18.0, -40.0, 12.0, -40.0, 25.0, -36.0);
     41        p.curveTo(38.0, -32.0, 43.0, -11.0, 43.0, 0); p.moveTo(-32.0, -36.0); p.curveTo(-23.0, -25.0, -21.0, -12.0, -21.0, 0.0);
     42        Barrel.add(new Instr(Form.PLIN, p));
     43    }
     44
     45    public static final Symbol Can = new Symbol();
     46    static {
     47        Symbol colours = new Symbol();
     48        Path2D.Double p = new Path2D.Double(); p.moveTo(-31.6, 0); p.lineTo(-15.7, -47.4); p.lineTo(41.1, -28.4); p.lineTo(31.6, 0);
     49        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     50        colours.add(new Instr(Form.P1, p));
     51        p = new Path2D.Double(); p.moveTo(-31.6, 0); p.lineTo(-22.0, -28.4); p.lineTo(34.8, -9.4); p.lineTo(31.6, 0);
     52        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     53        colours.add(new Instr(Form.H2, p));
     54        p = new Path2D.Double(); p.moveTo(-24.2, -22.1); p.lineTo(-19.9, -34.8); p.lineTo(36.9, -15.8); p.lineTo(32.6, -3.1); p.closePath();
     55        colours.add(new Instr(Form.H3, p));
     56        p = new Path2D.Double(); p.moveTo(-22.0, -28.4); p.lineTo(-18.9, -37.9); p.lineTo(37.9, -18.9); p.lineTo(34.8, -9.4); p.closePath();
     57        colours.add(new Instr(Form.H4, p));
     58        p = new Path2D.Double(); p.moveTo(-25.2, -19.0); p.lineTo(-22.0, -28.4); p.lineTo(34.8, -9.4); p.lineTo(31.6, 0.0); p.closePath();
     59        colours.add(new Instr(Form.H5, p));
     60        p = new Path2D.Double(); p.moveTo(12.7, -37.9); p.lineTo(41.1, -28.4); p.lineTo(31.6, 0); p.lineTo(8.0, 0.0); p.quadTo(8.0, -6.0, 2.5, -7.6); p.closePath();
     61        colours.add(new Instr(Form.V2, p));
     62        Can.add(new Instr(Form.COLR, colours));
     63        Can.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     64        Can.add(new Instr(Form.FILL, Color.black));
     65        Can.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     66        Can.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
     67        Can.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
     68        p = new Path2D.Double(); p.moveTo(-31.6, 0); p.lineTo(-15.7, -47.4); p.lineTo(41.1, -28.4); p.lineTo(31.6, 0);
     69        Can.add(new Instr(Form.PLIN, p));
     70    }
     71
     72    public static final Symbol Cone = new Symbol();
     73    static {
     74        Symbol colours = new Symbol();
     75        Path2D.Double p = new Path2D.Double(); p.moveTo(-31.6, 0); p.curveTo(-24.9, -32.2, 1.4, -38.7, 12.7, -37.9); p.curveTo(21.9, -30.5, 32.8, -18.4, 32.1, 0.0);
     76        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     77        colours.add(new Instr(Form.P1, p));
     78        p = new Path2D.Double(); p.moveTo(-31.6, 0); p.quadTo(-29.0, -15.5, -17.3, -26.9); p.lineTo(31.5, -10.5); p.quadTo(33.0, -5.0, 32.1, 0.0);
     79        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     80        colours.add(new Instr(Form.H2, p));
     81        p = new Path2D.Double(); p.moveTo(-22.3, -21.4); p.quadTo(-15.2, -29.8, -10.8, -31.8); p.lineTo(28.8, -18.5); p.quadTo(31.8, -12.5, 32.6, -3.1); p.closePath();
     82        colours.add(new Instr(Form.H3, p));
     83        p = new Path2D.Double(); p.moveTo(-17.3, -27.0); p.quadTo(-13.0, -31.4, -6.9, -33.8); p.lineTo(26.4, -22.7); p.quadTo(30.0, -17.0, 31.7, -10.3); p.closePath();
     84        colours.add(new Instr(Form.H4, p));
     85        p = new Path2D.Double(); p.moveTo(-24.4, -18.7); p.quadTo(-20.3, -25.0, -17.3, -27.0); p.lineTo(31.7, -10.3); p.quadTo(32.7, -4.5, 32.1, 0.0); p.closePath();
     86        colours.add(new Instr(Form.H5, p));
     87        p = new Path2D.Double(); p.moveTo(12.7, -37.9); p.curveTo(21.9, -30.5, 32.8, -18.4, 32.1, 0.0); p.lineTo(8.0, 0.0); p.quadTo(8.0, -6.0, 2.5, -7.6); p.closePath();
     88        colours.add(new Instr(Form.V2, p));
     89        Cone.add(new Instr(Form.COLR, colours));
     90        Cone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     91        Cone.add(new Instr(Form.FILL, Color.black));
     92        Cone.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     93        Cone.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
     94        Cone.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
     95        p = new Path2D.Double(); p.moveTo(-31.6, 0); p.curveTo(-24.9, -32.2, 1.4, -38.7, 12.7, -37.9); p.curveTo(21.9, -30.5, 32.8, -18.4, 32.1, 0.0);
     96        Cone.add(new Instr(Form.PLIN, p));
     97    }
     98
     99    public static final Symbol Float = new Symbol();
     100    static {
     101        Symbol colours = new Symbol();
     102        Path2D.Double p = new Path2D.Double(); p.moveTo(-36.0, 0); p.lineTo(-47.0, -33.0); p.quadTo(-30.0, -25.0, -19.0, -23.0);
     103        p.lineTo(-12.0, -42.0); p.lineTo(12.0, -42.0); p.lineTo(19.0, -23.0); p.quadTo(30.0, -25.0, 47.0, -33.0); p.lineTo(36.0, 0);
     104        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     105        colours.add(new Instr(Form.P1, p));
     106        p = new Path2D.Double(); p.moveTo(-36.0, 0); p.lineTo(-43.0, -21.0); p.lineTo(43.0, -21.0); p.lineTo(36.0, 0);
     107        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     108        colours.add(new Instr(Form.H2, p));
     109        p = new Path2D.Double(); p.moveTo(-40.8, -14.0); p.lineTo(-45.4, -28.0); p.lineTo(-35.5, -28.0); p.quadTo(-28.0, -25.0, -19.0, -23.0); p.lineTo(-17.2, -28.0);
     110        p.lineTo(17.2, -28.0); p.lineTo(19.0, -23.0); p.quadTo(28.0, -25.0, 35.5, -28.0); p.lineTo(45.4, -28.0); p.lineTo(40.8, -14.0); p.closePath();
     111        colours.add(new Instr(Form.H3, p));
     112        p = new Path2D.Double(); p.moveTo(-43.0, -21.0); p.lineTo(-47.0, -33.0); p.quadTo(-29.7, -24.8, -19.0, -23.0); p.lineTo(-15.8, -31.5); p.lineTo(15.8, -31.5);
     113        p.lineTo(19.0, -23.0); p.quadTo(28.4, -24.3, 47.0, -33.0); p.lineTo(43.0, -21.0); p.closePath();
     114        colours.add(new Instr(Form.H4, p));
     115        p = new Path2D.Double(); p.moveTo(-39.8, -11.5); p.lineTo(-43.0, -21.0); p.lineTo(43.0, -21.0); p.lineTo(39.8, -11.5); p.closePath();
     116        colours.add(new Instr(Form.H5, p));
     117        p = new Path2D.Double(); p.moveTo(0.0, -42.0); p.lineTo(12.0, -42.0); p.lineTo(19.0, -23.0); p.quadTo(28.4, -24.3, 47.0, -33.0); p.lineTo(36.0, 0.0);
     118        p.lineTo(8.0, 0.0); p.quadTo(7.7, -7.7, 0.0, -8.0); p.closePath();
     119        colours.add(new Instr(Form.V2, p));
     120        Float.add(new Instr(Form.COLR, colours));
     121        Float.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     122        Float.add(new Instr(Form.FILL, Color.black));
     123        Float.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     124        Float.add(new Instr(Form.LINE, new Line2D.Double(-54, 0, -10, 0)));
     125        Float.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 54, 0)));
     126        p = new Path2D.Double(); p.moveTo(-36.0, 0); p.lineTo(-47.0, -33.0); p.curveTo(-15.0, -17.0, 15.0, -17.0, 47.0, -33.0); p.lineTo(36.0, 0);
     127        p.moveTo(-19.0, -23.0); p.lineTo(-12.0, -42.0); p.lineTo(12.0, -42.0); p.lineTo(19.0, -23.0);
     128        Float.add(new Instr(Form.PLIN, p));
     129    }
     130
     131    public static final Symbol Ice = new Symbol();
     132    static {
     133        Symbol colours = new Symbol();
     134        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, 0); p.quadTo(-30.0, 0.0, -30.0, -15.0); p.lineTo(-30.0, -25.0); p.lineTo(30.0, -25.0); p.lineTo(30.0, -15); p.quadTo(30.0, 0.0, 15.0, 0.0);
     135        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     136        colours.add(new Instr(Form.P1, p));
     137        Ice.add(new Instr(Form.COLR, colours));
     138        Ice.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     139        Ice.add(new Instr(Form.FILL, Color.black));
     140        Ice.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     141        Ice.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
     142        Ice.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
     143        p = new Path2D.Double(); p.moveTo(-15.0, 0); p.quadTo(-30.0, 0.0, -30.0, -15.0); p.lineTo(-30.0, -25.0); p.lineTo(30.0, -25.0); p.lineTo(30.0, -15); p.quadTo(30.0, 0.0, 15.0, 0.0);
     144        Ice.add(new Instr(Form.PLIN, p));
     145        p = new Path2D.Double(); p.moveTo(-6.0, 8.0); p.lineTo(-6.0, 40.0); p.lineTo(6.0, 40.0); p.lineTo(6.0, 8.0);
     146        Ice.add(new Instr(Form.PLIN, p));
     147    }
     148
     149    public static final Symbol Pillar = new Symbol();
     150    static {
     151        Symbol colours = new Symbol();
     152        Path2D.Double p = new Path2D.Double(); p.moveTo(-32.0, 0.0); p.lineTo(-2.8, -32.5); p.lineTo(25.6, -96.7); p.lineTo(37.0, -92.9); p.lineTo(21.8, -24.3);
     153        p.lineTo(25.0, 0.0); p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     154        colours.add(new Instr(Form.P1, p));
     155        p = new Path2D.Double(); p.moveTo(-32.0, 0); p.lineTo(-2.8, -32.5); p.lineTo(5.3, -51.0); p.lineTo(26.3, -43.9); p.lineTo(21.8, -24.3); p.lineTo(25.0, 0.0);
     156        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     157        colours.add(new Instr(Form.H2, p));
     158        p = new Path2D.Double(); p.moveTo(-0.9, -37.1); p.lineTo(11.3, -64.6); p.lineTo(29.6, -58.7); p.lineTo(23.1, -29.3); p.closePath();
     159        colours.add(new Instr(Form.H3, p));
     160        p = new Path2D.Double(); p.moveTo(5.3, -51.0); p.lineTo(14.5, -71.5); p.lineTo(31.2, -65.9); p.lineTo(26.3, -43.9); p.closePath();
     161        colours.add(new Instr(Form.H4, p));
     162        p = new Path2D.Double(); p.moveTo(-5.2, -29.7); p.lineTo(-2.8, -32.5); p.lineTo(5.3, -51.0); p.lineTo(26.3, -43.9); p.lineTo(21.8, -24.3); p.lineTo(22.2, -21.5); p.closePath();
     163        colours.add(new Instr(Form.H5, p));
     164        p = new Path2D.Double(); p.moveTo(12.7, -37.9); p.lineTo(31.3, -94.8); p.lineTo(37.0, -92.9); p.lineTo(21.8, -24.3);
     165        p.lineTo(25.0, 0.0); p.lineTo(8.0, 0.0); p.quadTo(8.0, -6.0, 2.5, -7.6); p.closePath();
     166        colours.add(new Instr(Form.V2, p));
     167        Pillar.add(new Instr(Form.COLR, colours));
     168        Pillar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     169        Pillar.add(new Instr(Form.FILL, Color.black));
     170        Pillar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     171        Pillar.add(new Instr(Form.LINE, new Line2D.Double(-42, 0, -10, 0)));
     172        Pillar.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 36, 0)));
     173        p = new Path2D.Double(); p.moveTo(-32.0, 0.0); p.lineTo(-2.8, -32.5); p.lineTo(25.6, -96.7); p.lineTo(37.0, -92.9); p.lineTo(21.8, -24.3); p.lineTo(25.0, 0.0);
     174        Pillar.add(new Instr(Form.PLIN, p));
     175    }
     176
     177    public static final Symbol Spar = new Symbol();
     178    static {
     179        Symbol colours = new Symbol();
     180        Path2D.Double p = new Path2D.Double(); p.moveTo(-3.2, -9.5); p.lineTo(25.6, -96.7); p.lineTo(37.0, -92.9); p.lineTo(8.2, -5.7); p.closePath();
     181        colours.add(new Instr(Form.P1, p));
     182        p = new Path2D.Double(); p.moveTo(-3.2, -9.5); p.lineTo(11.2, -53.1); p.lineTo(22.6, -49.3); p.lineTo(8.2, -5.7); p.closePath();
     183        colours.add(new Instr(Form.H2, p));
     184        p = new Path2D.Double(); p.moveTo(6.4, -38.6); p.lineTo(16.0, -67.6); p.lineTo(27.4, -63.8); p.lineTo(17.8, -34.8); p.closePath();
     185        colours.add(new Instr(Form.H3, p));
     186        p = new Path2D.Double(); p.moveTo(11.2, -53.1); p.lineTo(18.4, -74.9); p.lineTo(29.8, -71.1); p.lineTo(22.6, -49.3); p.closePath();
     187        colours.add(new Instr(Form.H4, p));
     188        p = new Path2D.Double(); p.moveTo(4.0, -31.3); p.lineTo(11.2, -53.1); p.lineTo(22.6, -49.3); p.lineTo(15.4, -27.5); p.closePath();
     189        colours.add(new Instr(Form.H5, p));
     190        p = new Path2D.Double(); p.moveTo(2.5, -7.6); p.lineTo(31.3, -94.8); p.lineTo(37.0, -92.9); p.lineTo(8.2, -5.7); p.closePath();
     191        colours.add(new Instr(Form.V2, p));
     192        Spar.add(new Instr(Form.COLR, colours));
     193        Spar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     194        Spar.add(new Instr(Form.FILL, Color.black));
     195        Spar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     196        Spar.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, -10, 0)));
     197        Spar.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 20, 0)));
     198        p = new Path2D.Double(); p.moveTo(-3.2, -9.5); p.lineTo(25.6, -96.7); p.lineTo(37.0, -92.9); p.lineTo(8.2, -5.7);
     199        Spar.add(new Instr(Form.PLIN, p));
     200    }
     201
     202    public static final Symbol Sphere = new Symbol();
     203    static {
     204        Symbol colours = new Symbol();
     205        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0); p.curveTo(-32.0, -21.0, -14.0, -45.5, 12.7, -37.9); p.curveTo(27.5, -33.8, 37.8, -15.5, 32.0, 0.0);
     206        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     207        colours.add(new Instr(Form.P1, p));
     208        p = new Path2D.Double(); p.moveTo(-25.0, 0); p.quadTo(-30.0, -15.0, -20.5, -28.0); p.lineTo(33.8, -10.0); p.quadTo(33.7, -4.0, 32.0, 0.0);
     209        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     210        colours.add(new Instr(Form.H2, p));
     211        p = new Path2D.Double(); p.moveTo(-24.2, -22.1); p.quadTo(-21.0, -28.5, -15.2, -33.3); p.lineTo(32.8, -17.2); p.quadTo(34.6, -10.0, 33.0, -2.9); p.closePath();
     212        colours.add(new Instr(Form.H3, p));
     213        p = new Path2D.Double(); p.moveTo(-20.5, -28.0); p.quadTo(-16.5, -33.0, -12.0, -35.5); p.lineTo(31.5, -21.0); p.quadTo(33.5, -17.0, 34.0, -9.5); p.closePath();
     214        colours.add(new Instr(Form.H4, p));
     215        p = new Path2D.Double(); p.moveTo(-25.2, -19.0); p.quadTo(-23.5, -24.0, -20.5, -28.0); p.lineTo(34.0, -9.5); p.quadTo(34.0, -3.0, 32.0, 0.0); p.closePath();
     216        colours.add(new Instr(Form.H5, p));
     217        p = new Path2D.Double(); p.moveTo(12.7, -37.9); p.curveTo(27.5, -33.8, 37.8, -15.5, 32.0, 0.0); p.lineTo(8.0, 0.0); p.quadTo(8.0, -6.0, 2.5, -7.6); p.closePath();
     218        colours.add(new Instr(Form.V2, p));
     219        Sphere.add(new Instr(Form.COLR, colours));
     220        Sphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     221        Sphere.add(new Instr(Form.FILL, Color.black));
     222        Sphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     223        Sphere.add(new Instr(Form.LINE, new Line2D.Double(-33, 0, -10, 0)));
     224        Sphere.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
     225        Sphere.add(new Instr(Form.EARC, new Arc2D.Double(-26.5, -39.4, 60.0, 60.0, -18.0, 216.0, Arc2D.OPEN)));
     226    }
     227
     228    public static final Symbol Storage = new Symbol();
     229    static {
     230        Storage.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     231        Storage.add(new Instr(Form.FILL, Color.black));
     232        Storage.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     233        Path2D.Double p = new Path2D.Double(); p.moveTo(-50.0, 0.0); p.lineTo(-40.0, -20.0); p.lineTo(40.0, -20.0); p.lineTo(40.0, -20.0);
     234        p.lineTo(50.0, 0.0); p.lineTo(40.0, 20.0); p.lineTo(-40.0, 20.0); p.closePath();
     235        Storage.add(new Instr(Form.PLIN, p));
     236    }
     237
     238    public static final Symbol Super = new Symbol();
     239    static {
     240        Symbol colours = new Symbol();
     241        Path2D.Double p = new Path2D.Double(); p.moveTo(-48.0, 0); p.lineTo(-28.0, -42.0); p.lineTo(28.0, -42.0); p.lineTo(48.0, 0);
     242        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     243        colours.add(new Instr(Form.P1, p));
     244        p = new Path2D.Double(); p.moveTo(-48.0, 0); p.lineTo(-38.0, -21.0); p.lineTo(38.0, -21.0); p.lineTo(48.0, 0);
     245        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     246        colours.add(new Instr(Form.H2, p));
     247        p = new Path2D.Double(); p.moveTo(-41.3, -14.0); p.lineTo(-34.7, -28.0); p.lineTo(34.7, -28.0); p.lineTo(41.3, -14.0); p.closePath();
     248        colours.add(new Instr(Form.H3, p));
     249        p = new Path2D.Double(); p.moveTo(-38.0, -21.0); p.lineTo(-33.0, -31.5); p.lineTo(33.0, -31.5); p.lineTo(38.0, -21.0); p.closePath();
     250        colours.add(new Instr(Form.H4, p));
     251        p = new Path2D.Double(); p.moveTo(-43.0, -11.5); p.lineTo(-38.0, -21.0); p.lineTo(38.0, -21.0); p.lineTo(43.0, -11.5); p.closePath();
     252        colours.add(new Instr(Form.H5, p));
     253        p = new Path2D.Double(); p.moveTo(0.0, -42.0); p.lineTo(28.0, -42.0); p.lineTo(48.0, 0.0); p.lineTo(8.0, 0.0); p.quadTo(7.7, -7.7, 0.0, -8.0); p.closePath();
     254        colours.add(new Instr(Form.V2, p));
     255        Super.add(new Instr(Form.COLR, colours));
     256        Super.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     257        Super.add(new Instr(Form.FILL, Color.black));
     258        Super.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     259        Super.add(new Instr(Form.LINE, new Line2D.Double(-54, 0, -10, 0)));
     260        Super.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 54, 0)));
     261        p = new Path2D.Double(); p.moveTo(-48.0, 0); p.lineTo(-28.0, -42.0); p.lineTo(28.0, -42.0); p.lineTo(48.0, 0);
     262        Super.add(new Instr(Form.PLIN, p));
     263    }
     264
     265    public static final EnumMap<BoySHP, Symbol> Shapes = new EnumMap<>(BoySHP.class);
     266    static {
     267        Shapes.put(BoySHP.BOY_UNKN, Buoys.Pillar); Shapes.put(BoySHP.BOY_CONE, Buoys.Cone); Shapes.put(BoySHP.BOY_CAN, Buoys.Can);
     268        Shapes.put(BoySHP.BOY_SPHR, Buoys.Sphere); Shapes.put(BoySHP.BOY_PILR, Buoys.Pillar); Shapes.put(BoySHP.BOY_SPAR, Buoys.Spar);
     269        Shapes.put(BoySHP.BOY_BARL, Buoys.Barrel); Shapes.put(BoySHP.BOY_SUPR, Buoys.Super); Shapes.put(BoySHP.BOY_ICE, Buoys.Ice);
     270    }
    257271}
  • applications/editors/josm/plugins/seachart/src/symbols/Facilities.java

    r32393 r32394  
    1212import java.awt.BasicStroke;
    1313import java.awt.Color;
    14 import java.awt.geom.*;
     14import java.awt.geom.Arc2D;
     15import java.awt.geom.Ellipse2D;
     16import java.awt.geom.GeneralPath;
     17import java.awt.geom.Line2D;
     18import java.awt.geom.Path2D;
     19import java.awt.geom.Rectangle2D;
     20import java.awt.geom.RoundRectangle2D;
    1521import java.util.EnumMap;
    1622
    17 import s57.S57val.*;
    18 import symbols.Symbols.*;
     23import s57.S57val.CatSCF;
     24import symbols.Symbols.Form;
     25import symbols.Symbols.Instr;
     26import symbols.Symbols.Symbol;
    1927
    2028public class Facilities {
    21         private static final Symbol Facility = new Symbol();
    22         static {
    23                 Facility.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    24                 Facility.add(new Instr(Form.FILL, new Color(0x80ffffff, true)));
    25                 RoundRectangle2D.Double s = new RoundRectangle2D.Double(-29,-29,58,58,15,15);
    26                 Facility.add(new Instr(Form.RSHP, s));
    27                 Facility.add(new Instr(Form.FILL, new Color(0xa30075)));
    28                 Facility.add(new Instr(Form.RRCT, s));
    29         }
    30         public static final Symbol Boatlift = new Symbol();//was Crane
    31         static {
    32                 Boatlift.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    33                 Boatlift.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    34                 Boatlift.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    35                 Boatlift.add(new Instr(Form.ELPS, new Ellipse2D.Double(-3.7,-19.7,12,12)));
    36                 Boatlift.add(new Instr(Form.LINE, new Line2D.Double(2.3,-7.7,2.3,-2.0)));
    37                 Boatlift.add(new Instr(Form.EARC, new Arc2D.Double(-10.0,-1.5,20,20,75.0,-260.0,Arc2D.OPEN)));
    38         }
    39         public static final Symbol Boatyard = new Symbol();
    40         static {
    41                 Boatyard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    42                 Boatyard.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    43                 Boatyard.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    44                 Boatyard.add(new Instr(Form.LINE, new Line2D.Double(19,19,-8,-8)));
    45                 Path2D.Double p = new Path2D.Double(); p.moveTo(-11.3,-11.3); p.lineTo(-10.5,-17.5); p.lineTo(-14.8,-21.9); p.lineTo(-11.3,-25.4); p.lineTo(-7.4,-21.5);
    46                 p.curveTo(1.0,-11.5,-11.5,1.0,-21.5,-7.4); p.lineTo(-25.4,-11.3); p.lineTo(-21.9,-14.8); p.lineTo(-17.5,-10.5); p.closePath();
    47                 Boatyard.add(new Instr(Form.PGON, p));
    48         }
    49         public static final Symbol Chandler = new Symbol();
    50         static {
    51                 Chandler.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    52                 Chandler.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    53                 Chandler.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    54                 Chandler.add(new Instr(Form.ELPS, new Ellipse2D.Double(14,7,10,10)));
    55                 Chandler.add(new Instr(Form.LINE, new Line2D.Double(-23.0,12.0,14.0,12.0)));
    56                 Chandler.add(new Instr(Form.LINE, new Line2D.Double(8.0,21.0,8.0,-8.6)));
    57                 Chandler.add(new Instr(Form.LINE, new Line2D.Double(-16.0,21.0,-16.0,-8.6)));
    58                 Chandler.add(new Instr(Form.EARC, new Arc2D.Double(-16.0,-20.5,24,24,0.0,180.0,Arc2D.OPEN)));
    59         }
    60         public static final Symbol Fuel = new Symbol();
    61         static {
    62                 Fuel.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    63                 Fuel.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    64                 Fuel.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    65                 Fuel.add(new Instr(Form.FILL, new Color(0xa30075)));
    66                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    67                 p.moveTo(-15.6,22.1); p.lineTo(-15.6,-19.4); p.quadTo(-15.5,-22.7,-12.2,-22.8); p.lineTo(0.2,-22.8); p.quadTo(3.3,-22.7,3.4,-19.4); p.lineTo(3.4,22.1); p.closePath();
    68                 p.moveTo(-12.8,-19.0); p.quadTo(-12.7,-19.9,-11.8,-20.0); p.lineTo(-0.4,-20.0); p.quadTo(0.5,-19.9,0.6,-19.0); p.lineTo(0.6,-9.4);
    69                 p.quadTo(0.5,-8.5,-0.4,-8.4); p.lineTo(-11.8,-8.4); p.quadTo(-12.7,-8.3,-12.8,-9.4); p.closePath();
    70                 Fuel.add(new Instr(Form.PGON, p));
    71                 p = new Path2D.Double(); p.moveTo(3.0,-3.0); p.lineTo(7.0,-3.0); p.quadTo(9.4,-2.8,9.6,-0.4); p.lineTo(9.6,18.0); p.curveTo(10.1,23.2,18.4,21.5,17.4,17.2);
    72                 p.lineTo(14.9,3.5); p.lineTo(15.1,-10.3); p.quadTo(14.9,-11.9,13.9,-13.1); p.lineTo(7.4,-19.6); p.moveTo(15.1,-7.4); p.lineTo(12.6,-7.4); p.quadTo(11.1,-7.4,11.1,-8.9); p.lineTo(11.1,-16.0);
    73                 Fuel.add(new Instr(Form.PLIN, p));
    74         }
    75         public static final Symbol Laundrette = new Symbol();
    76         static {
    77                 Laundrette.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    78                 Laundrette.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    79                 Laundrette.add(new Instr(Form.STRK, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    80                 Laundrette.add(new Instr(Form.FILL, new Color(0xa30075)));
    81                 Laundrette.add(new Instr(Form.RECT, new Rectangle2D.Double(-15,-15,30,30)));
    82                 Laundrette.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    83                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-15); p.lineTo(-15,-20); p.lineTo(15,-20); p.lineTo(15,-15);
    84                 p.moveTo(-10,15); p.lineTo(-10,20); p.lineTo(10,20); p.lineTo(10,15);
    85                 Laundrette.add(new Instr(Form.PLIN, p));
    86         }
    87         public static final Symbol PumpOut = new Symbol();
    88         static {
    89                 PumpOut.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    90                 PumpOut.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    91                 PumpOut.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    92                 PumpOut.add(new Instr(Form.FILL, new Color(0xa30075)));
    93                 Path2D.Double p = new Path2D.Double(); p.moveTo(3.9,-3.7); p.lineTo(-7.4,-3.7); p.lineTo(-12.0,2.0); p.lineTo(-22.7,2.0);
    94                 p.lineTo(-11.8,14.9); p.lineTo(15.1,14.9); p.lineTo(21.9,10.2); p.lineTo(21.9,3.1); p.lineTo(13.5,3.1);
    95                 PumpOut.add(new Instr(Form.PLIN, p));
    96                 PumpOut.add(new Instr(Form.STRK, new BasicStroke(3.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    97                 p = new Path2D.Double(); p.moveTo(-2.5,3.0); p.lineTo(-2.5,-13.8); p.lineTo(6.9,-13.8); p.lineTo(6.9,-6.7); p.lineTo(14.5,-6.7);
    98                 PumpOut.add(new Instr(Form.PLIN, p));
    99                 p = new Path2D.Double(); p.moveTo(9.7,2.3); p.lineTo(9.7,10.3); p.lineTo(-4.1,10.3); p.lineTo(-4.1,2.3); p.closePath();
    100                 PumpOut.add(new Instr(Form.PGON, p));
    101                 p = new Path2D.Double(); p.moveTo(14.1,-10.6); p.lineTo(23.1,-6.7); p.lineTo(14.1,-2.8); p.closePath();
    102                 PumpOut.add(new Instr(Form.PGON, p));
    103         }
    104         public static final Symbol SailingClub = new Symbol();
    105         static {
    106                 SailingClub.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    107                 SailingClub.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    108                 SailingClub.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    109                 SailingClub.add(new Instr(Form.FILL, new Color(0xa30075)));
    110                 SailingClub.add(new Instr(Form.LINE, new Line2D.Double(-5,20,-5,-20)));
    111                 Path2D.Double p = new Path2D.Double(); p.moveTo(-5,0); p.lineTo(20,-10); p.lineTo(-5,-20); p.closePath();
    112                 SailingClub.add(new Instr(Form.PGON, p));
    113         }
    114         public static final Symbol Shower = new Symbol();
    115         static {
    116                 Shower.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    117                 Shower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    118                 Shower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    119                 Shower.add(new Instr(Form.FILL, new Color(0xa30075)));
    120                 Shower.add(new Instr(Form.LINE, new Line2D.Double(-4.8,-24.5,6.2,-13.5)));
    121                 Shower.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    122                 Shower.add(new Instr(Form.LINE, new Line2D.Double(-18.1,-17.9,-6.1,-21.3)));
    123                 Shower.add(new Instr(Form.LINE, new Line2D.Double(-13.9,-10.2,-3.9,-17.7)));
    124                 Shower.add(new Instr(Form.LINE, new Line2D.Double(-7.8,-4.4,-0.5,-14.3)));
    125                 Shower.add(new Instr(Form.LINE, new Line2D.Double(-0.2,-0.2,3.1,-12.1)));
    126                 Path2D.Double p = new Path2D.Double(); p.moveTo(11.1,24.6); p.lineTo(11.1,-16.0); p.curveTo(11.1,-22.7,3.4,-23.6,0.8,-19.3);
    127                 Shower.add(new Instr(Form.PLIN, p));
    128         }
    129         public static final Symbol Slipway = new Symbol();
    130         static {
    131                 Slipway.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    132                 Slipway.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    133                 Slipway.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    134                 Slipway.add(new Instr(Form.FILL, new Color(0xa30075)));
    135                 Path2D.Double p = new Path2D.Double(); p.moveTo(-24.8,0.1); p.lineTo(-24.8,18.0); p.curveTo(-21.2,18.0,-22.2,16.7,-18.6,16.7); p.curveTo(-15.0,16.7,-16.0,18.0,-12.4,18.0);
    136                 p.curveTo(-8.8,18.0,-9.8,16.7,-6.2,16.7); p.curveTo(-2.6,16.7,-3.6,18.0,0.0,18.0); p.curveTo(3.6,18.0,2.6,16.7,6.2,16.7); p.curveTo(9.8,16.7,8.8,18.0,12.4,18.0);
    137                 p.curveTo(16.0,18.0,15.0,16.7,18.6,16.7); p.curveTo(22.2,16.7,21.2,18.0,24.8,18.0);     p.lineTo(24.8,13.6); p.closePath();
    138                 Slipway.add(new Instr(Form.PGON, p));
    139                 Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.65,-1.9,8,8)));
    140                 Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    141                 Slipway.add(new Instr(Form.LINE, new Line2D.Double(-24.5,-8.3,-3.1,-2.4)));
    142                 Slipway.add(new Instr(Form.LINE, new Line2D.Double(9.3,1.1,22.2,4.6)));
    143                 p = new Path2D.Double(); p.moveTo(22.9,0.6); p.lineTo(25.0,-7.4); p.lineTo(-5.1,-15.8); p.lineTo(0.3,-19.6); p.lineTo(-1.6,-20.1); p.lineTo(-7.2,-16.2);
    144                 p.lineTo(-17.1,-18.9); p.quadTo(-16.8,-11.4,-7.7,-7.7); p.closePath();
    145                 Slipway.add(new Instr(Form.PGON, p));
    146         }
    147         public static final Symbol Toilet = new Symbol();
    148         static {
    149                 Toilet.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    150                 Toilet.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
    151                 Toilet.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    152                 Toilet.add(new Instr(Form.FILL, new Color(0xa30075)));
    153                 Toilet.add(new Instr(Form.LINE, new Line2D.Double(0,20,0,-20)));
    154                 Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(-18.5,-22.5,7.4,7.4)));
    155                 Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(11,-22.5,7.4,7.4)));
    156                 Path2D.Double p = new Path2D.Double(); p.moveTo(-9.8,-12.2); p.lineTo(-4.8,2.7); p.lineTo(-7.3,3.9); p.lineTo(-10.6,-7.0); p.lineTo(-11.7,-6.4); p.lineTo(-7.6,9.0);
    157                 p.lineTo(-11.3,9.0); p.lineTo(-11.6,22.1); p.lineTo(-13.9,22.1); p.lineTo(-14.2,9.0); p.lineTo(-15.8,9.0); p.lineTo(-16.2,22.1); p.lineTo(-18.4,22.1);
    158                 p.lineTo(-18.8,9.0); p.lineTo(-22.3,9.0); p.lineTo(-18.2,-6.4); p.lineTo(-19.1,-7.0); p.lineTo(-22.9,3.9); p.lineTo(-25.1,2.7); p.lineTo(-19.9,-12.2); p.closePath();
    159                 Toilet.add(new Instr(Form.PGON, p));
    160                 p = new Path2D.Double(); p.moveTo(19.2,-12.2); p.lineTo(22.3,-10.1); p.lineTo(22.3,4.4); p.lineTo(20.2,4.4); p.lineTo(20.2,-7.3); p.lineTo(18.3,-7.3); p.lineTo(18.3,22.1);
    161                 p.lineTo(15.8,22.1); p.lineTo(15.8,4.6); p.lineTo(13.8,4.6); p.lineTo(13.4,22.1); p.lineTo(11.0,22.1); p.lineTo(11.0,-7.3); p.lineTo(9.5,-7.3); p.lineTo(9.5,4.4); p.lineTo(6.8,4.4);
    162                 p.lineTo(6.8,-10.1); p.lineTo(9.4,-12.2); p.closePath();
    163                 Toilet.add(new Instr(Form.PGON, p));
    164         }
    165         public static final Symbol VisitorBerth = new Symbol();
    166         static {
    167                 VisitorBerth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    168                 VisitorBerth.add(new Instr(Form.FILL, new Color(0xa30075)));
    169                 VisitorBerth.add(new Instr(Form.RSHP, new Ellipse2D.Double(-25,-25,50,50)));
    170                 VisitorBerth.add(new Instr(Form.FILL, Color.white));
    171                 Path2D.Double p = new Path2D.Double(); p.moveTo(7.9,-13.6); p.lineTo(14.0,-13.6); p.lineTo(3.4,13.6); p.lineTo(-3.4,13.6);
    172                 p.lineTo(-14.0,-13.6); p.lineTo(-7.9,-13.6); p.lineTo(0.0,8.7); p.closePath();
    173                 VisitorBerth.add(new Instr(Form.PGON, p));
    174         }
    175         public static final Symbol VisitorMooring = new Symbol();
    176         static {
    177                 VisitorMooring.add(new Instr(Form.FILL, new Color(0xa30075)));
    178                 Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0); p.curveTo(-32.0,-21.0,-14.0,-45.5,12.7,-37.9); p.curveTo(27.5,-33.8,37.8,-15.5,32.0,0.0);
    179                 p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
    180                 VisitorMooring.add(new Instr(Form.PGON, p));
    181     VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    182     VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    183     VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(-33,0,-10,0)));
    184     VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
    185     VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    186     VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(6.5,-49.5,12,12)));
    187     VisitorMooring.add(new Instr(Form.FILL, Color.white));
    188                 p = new Path2D.Double(); p.moveTo(8.3,-32.8); p.lineTo(12.5,-32.8); p.lineTo(5.4,-12.9); p.lineTo(1.0,-12.9); p.lineTo(-6.1,-32.8);
    189                 p.lineTo(-1.9,-32.8); p.lineTo(3.2,-18.1); p.closePath();
    190                 VisitorMooring.add(new Instr(Form.PGON, p));
    191         }
    192 
    193         public static final EnumMap<CatSCF, Symbol> Cats = new EnumMap<>(CatSCF.class);
    194         static {
    195                 Cats.put(CatSCF.SCF_BHST, Boatlift); Cats.put(CatSCF.SCF_BTYD, Boatyard); Cats.put(CatSCF.SCF_CHDR, Chandler); Cats.put(CatSCF.SCF_FUEL, Fuel); Cats.put(CatSCF.SCF_LAUN, Laundrette);
    196                 Cats.put(CatSCF.SCF_PMPO, PumpOut); Cats.put(CatSCF.SCF_CLUB, SailingClub); Cats.put(CatSCF.SCF_SHWR, Shower); Cats.put(CatSCF.SCF_SLPW, Slipway); Cats.put(CatSCF.SCF_WC, Toilet);
    197                 Cats.put(CatSCF.SCF_VBTH, VisitorBerth); Cats.put(CatSCF.SCF_VMOR, VisitorMooring);
    198         }
     29    // CHECKSTYLE.OFF: LineLength
     30    private static final Symbol Facility = new Symbol();
     31    static {
     32        Facility.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     33        Facility.add(new Instr(Form.FILL, new Color(0x80ffffff, true)));
     34        RoundRectangle2D.Double s = new RoundRectangle2D.Double(-29, -29, 58, 58, 15, 15);
     35        Facility.add(new Instr(Form.RSHP, s));
     36        Facility.add(new Instr(Form.FILL, new Color(0xa30075)));
     37        Facility.add(new Instr(Form.RRCT, s));
     38    }
     39
     40    public static final Symbol Boatlift = new Symbol(); //was Crane
     41    static {
     42        Boatlift.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     43        Boatlift.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     44        Boatlift.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     45        Boatlift.add(new Instr(Form.ELPS, new Ellipse2D.Double(-3.7, -19.7, 12, 12)));
     46        Boatlift.add(new Instr(Form.LINE, new Line2D.Double(2.3, -7.7, 2.3, -2.0)));
     47        Boatlift.add(new Instr(Form.EARC, new Arc2D.Double(-10.0, -1.5, 20, 20, 75.0, -260.0, Arc2D.OPEN)));
     48    }
     49
     50    public static final Symbol Boatyard = new Symbol();
     51    static {
     52        Boatyard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     53        Boatyard.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     54        Boatyard.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     55        Boatyard.add(new Instr(Form.LINE, new Line2D.Double(19, 19, -8, -8)));
     56        Path2D.Double p = new Path2D.Double(); p.moveTo(-11.3, -11.3); p.lineTo(-10.5, -17.5); p.lineTo(-14.8, -21.9); p.lineTo(-11.3, -25.4); p.lineTo(-7.4, -21.5);
     57        p.curveTo(1.0, -11.5, -11.5, 1.0, -21.5, -7.4); p.lineTo(-25.4, -11.3); p.lineTo(-21.9, -14.8); p.lineTo(-17.5, -10.5); p.closePath();
     58        Boatyard.add(new Instr(Form.PGON, p));
     59    }
     60
     61    public static final Symbol Chandler = new Symbol();
     62    static {
     63        Chandler.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     64        Chandler.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     65        Chandler.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     66        Chandler.add(new Instr(Form.ELPS, new Ellipse2D.Double(14, 7, 10, 10)));
     67        Chandler.add(new Instr(Form.LINE, new Line2D.Double(-23.0, 12.0, 14.0, 12.0)));
     68        Chandler.add(new Instr(Form.LINE, new Line2D.Double(8.0, 21.0, 8.0, -8.6)));
     69        Chandler.add(new Instr(Form.LINE, new Line2D.Double(-16.0, 21.0, -16.0, -8.6)));
     70        Chandler.add(new Instr(Form.EARC, new Arc2D.Double(-16.0, -20.5, 24, 24, 0.0, 180.0, Arc2D.OPEN)));
     71    }
     72
     73    public static final Symbol Fuel = new Symbol();
     74    static {
     75        Fuel.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     76        Fuel.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     77        Fuel.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     78        Fuel.add(new Instr(Form.FILL, new Color(0xa30075)));
     79        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     80        p.moveTo(-15.6, 22.1); p.lineTo(-15.6, -19.4); p.quadTo(-15.5, -22.7, -12.2, -22.8); p.lineTo(0.2, -22.8); p.quadTo(3.3, -22.7, 3.4, -19.4); p.lineTo(3.4, 22.1); p.closePath();
     81        p.moveTo(-12.8, -19.0); p.quadTo(-12.7, -19.9, -11.8, -20.0); p.lineTo(-0.4, -20.0); p.quadTo(0.5, -19.9, 0.6, -19.0); p.lineTo(0.6, -9.4);
     82        p.quadTo(0.5, -8.5, -0.4, -8.4); p.lineTo(-11.8, -8.4); p.quadTo(-12.7, -8.3, -12.8, -9.4); p.closePath();
     83        Fuel.add(new Instr(Form.PGON, p));
     84        p = new Path2D.Double(); p.moveTo(3.0, -3.0); p.lineTo(7.0, -3.0); p.quadTo(9.4, -2.8, 9.6, -0.4); p.lineTo(9.6, 18.0); p.curveTo(10.1, 23.2, 18.4, 21.5, 17.4, 17.2);
     85        p.lineTo(14.9, 3.5); p.lineTo(15.1, -10.3); p.quadTo(14.9, -11.9, 13.9, -13.1); p.lineTo(7.4, -19.6); p.moveTo(15.1, -7.4); p.lineTo(12.6, -7.4); p.quadTo(11.1, -7.4, 11.1, -8.9); p.lineTo(11.1, -16.0);
     86        Fuel.add(new Instr(Form.PLIN, p));
     87    }
     88
     89    public static final Symbol Laundrette = new Symbol();
     90    static {
     91        Laundrette.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     92        Laundrette.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     93        Laundrette.add(new Instr(Form.STRK, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     94        Laundrette.add(new Instr(Form.FILL, new Color(0xa30075)));
     95        Laundrette.add(new Instr(Form.RECT, new Rectangle2D.Double(-15, -15, 30, 30)));
     96        Laundrette.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     97        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -15); p.lineTo(-15, -20); p.lineTo(15, -20); p.lineTo(15, -15);
     98        p.moveTo(-10, 15); p.lineTo(-10, 20); p.lineTo(10, 20); p.lineTo(10, 15);
     99        Laundrette.add(new Instr(Form.PLIN, p));
     100    }
     101
     102    public static final Symbol PumpOut = new Symbol();
     103    static {
     104        PumpOut.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     105        PumpOut.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     106        PumpOut.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     107        PumpOut.add(new Instr(Form.FILL, new Color(0xa30075)));
     108        Path2D.Double p = new Path2D.Double(); p.moveTo(3.9, -3.7); p.lineTo(-7.4, -3.7); p.lineTo(-12.0, 2.0); p.lineTo(-22.7, 2.0);
     109        p.lineTo(-11.8, 14.9); p.lineTo(15.1, 14.9); p.lineTo(21.9, 10.2); p.lineTo(21.9, 3.1); p.lineTo(13.5, 3.1);
     110        PumpOut.add(new Instr(Form.PLIN, p));
     111        PumpOut.add(new Instr(Form.STRK, new BasicStroke(3.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     112        p = new Path2D.Double(); p.moveTo(-2.5, 3.0); p.lineTo(-2.5, -13.8); p.lineTo(6.9, -13.8); p.lineTo(6.9, -6.7); p.lineTo(14.5, -6.7);
     113        PumpOut.add(new Instr(Form.PLIN, p));
     114        p = new Path2D.Double(); p.moveTo(9.7, 2.3); p.lineTo(9.7, 10.3); p.lineTo(-4.1, 10.3); p.lineTo(-4.1, 2.3); p.closePath();
     115        PumpOut.add(new Instr(Form.PGON, p));
     116        p = new Path2D.Double(); p.moveTo(14.1, -10.6); p.lineTo(23.1, -6.7); p.lineTo(14.1, -2.8); p.closePath();
     117        PumpOut.add(new Instr(Form.PGON, p));
     118    }
     119
     120    public static final Symbol SailingClub = new Symbol();
     121    static {
     122        SailingClub.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     123        SailingClub.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     124        SailingClub.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     125        SailingClub.add(new Instr(Form.FILL, new Color(0xa30075)));
     126        SailingClub.add(new Instr(Form.LINE, new Line2D.Double(-5, 20, -5, -20)));
     127        Path2D.Double p = new Path2D.Double(); p.moveTo(-5, 0); p.lineTo(20, -10); p.lineTo(-5, -20); p.closePath();
     128        SailingClub.add(new Instr(Form.PGON, p));
     129    }
     130
     131    public static final Symbol Shower = new Symbol();
     132    static {
     133        Shower.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     134        Shower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     135        Shower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     136        Shower.add(new Instr(Form.FILL, new Color(0xa30075)));
     137        Shower.add(new Instr(Form.LINE, new Line2D.Double(-4.8, -24.5, 6.2, -13.5)));
     138        Shower.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     139        Shower.add(new Instr(Form.LINE, new Line2D.Double(-18.1, -17.9, -6.1, -21.3)));
     140        Shower.add(new Instr(Form.LINE, new Line2D.Double(-13.9, -10.2, -3.9, -17.7)));
     141        Shower.add(new Instr(Form.LINE, new Line2D.Double(-7.8, -4.4, -0.5, -14.3)));
     142        Shower.add(new Instr(Form.LINE, new Line2D.Double(-0.2, -0.2, 3.1, -12.1)));
     143        Path2D.Double p = new Path2D.Double(); p.moveTo(11.1, 24.6); p.lineTo(11.1, -16.0); p.curveTo(11.1, -22.7, 3.4, -23.6, 0.8, -19.3);
     144        Shower.add(new Instr(Form.PLIN, p));
     145    }
     146
     147    public static final Symbol Slipway = new Symbol();
     148    static {
     149        Slipway.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     150        Slipway.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     151        Slipway.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     152        Slipway.add(new Instr(Form.FILL, new Color(0xa30075)));
     153        Path2D.Double p = new Path2D.Double(); p.moveTo(-24.8, 0.1); p.lineTo(-24.8, 18.0); p.curveTo(-21.2, 18.0, -22.2, 16.7, -18.6, 16.7); p.curveTo(-15.0, 16.7, -16.0, 18.0, -12.4, 18.0);
     154        p.curveTo(-8.8, 18.0, -9.8, 16.7, -6.2, 16.7); p.curveTo(-2.6, 16.7, -3.6, 18.0, 0.0, 18.0); p.curveTo(3.6, 18.0, 2.6, 16.7, 6.2, 16.7); p.curveTo(9.8, 16.7, 8.8, 18.0, 12.4, 18.0);
     155        p.curveTo(16.0, 18.0, 15.0, 16.7, 18.6, 16.7); p.curveTo(22.2, 16.7, 21.2, 18.0, 24.8, 18.0); p.lineTo(24.8, 13.6); p.closePath();
     156        Slipway.add(new Instr(Form.PGON, p));
     157        Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.65, -1.9, 8, 8)));
     158        Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     159        Slipway.add(new Instr(Form.LINE, new Line2D.Double(-24.5, -8.3, -3.1, -2.4)));
     160        Slipway.add(new Instr(Form.LINE, new Line2D.Double(9.3, 1.1, 22.2, 4.6)));
     161        p = new Path2D.Double(); p.moveTo(22.9, 0.6); p.lineTo(25.0, -7.4); p.lineTo(-5.1, -15.8); p.lineTo(0.3, -19.6); p.lineTo(-1.6, -20.1); p.lineTo(-7.2, -16.2);
     162        p.lineTo(-17.1, -18.9); p.quadTo(-16.8, -11.4, -7.7, -7.7); p.closePath();
     163        Slipway.add(new Instr(Form.PGON, p));
     164    }
     165
     166    public static final Symbol Toilet = new Symbol();
     167    static {
     168        Toilet.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     169        Toilet.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
     170        Toilet.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     171        Toilet.add(new Instr(Form.FILL, new Color(0xa30075)));
     172        Toilet.add(new Instr(Form.LINE, new Line2D.Double(0, 20, 0, -20)));
     173        Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(-18.5, -22.5, 7.4, 7.4)));
     174        Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(11, -22.5, 7.4, 7.4)));
     175        Path2D.Double p = new Path2D.Double(); p.moveTo(-9.8, -12.2); p.lineTo(-4.8, 2.7); p.lineTo(-7.3, 3.9); p.lineTo(-10.6, -7.0); p.lineTo(-11.7, -6.4); p.lineTo(-7.6, 9.0);
     176        p.lineTo(-11.3, 9.0); p.lineTo(-11.6, 22.1); p.lineTo(-13.9, 22.1); p.lineTo(-14.2, 9.0); p.lineTo(-15.8, 9.0); p.lineTo(-16.2, 22.1); p.lineTo(-18.4, 22.1);
     177        p.lineTo(-18.8, 9.0); p.lineTo(-22.3, 9.0); p.lineTo(-18.2, -6.4); p.lineTo(-19.1, -7.0); p.lineTo(-22.9, 3.9); p.lineTo(-25.1, 2.7); p.lineTo(-19.9, -12.2); p.closePath();
     178        Toilet.add(new Instr(Form.PGON, p));
     179        p = new Path2D.Double(); p.moveTo(19.2, -12.2); p.lineTo(22.3, -10.1); p.lineTo(22.3, 4.4); p.lineTo(20.2, 4.4); p.lineTo(20.2, -7.3); p.lineTo(18.3, -7.3); p.lineTo(18.3, 22.1);
     180        p.lineTo(15.8, 22.1); p.lineTo(15.8, 4.6); p.lineTo(13.8, 4.6); p.lineTo(13.4, 22.1); p.lineTo(11.0, 22.1); p.lineTo(11.0, -7.3); p.lineTo(9.5, -7.3); p.lineTo(9.5, 4.4); p.lineTo(6.8, 4.4);
     181        p.lineTo(6.8, -10.1); p.lineTo(9.4, -12.2); p.closePath();
     182        Toilet.add(new Instr(Form.PGON, p));
     183    }
     184
     185    public static final Symbol VisitorBerth = new Symbol();
     186    static {
     187        VisitorBerth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     188        VisitorBerth.add(new Instr(Form.FILL, new Color(0xa30075)));
     189        VisitorBerth.add(new Instr(Form.RSHP, new Ellipse2D.Double(-25, -25, 50, 50)));
     190        VisitorBerth.add(new Instr(Form.FILL, Color.white));
     191        Path2D.Double p = new Path2D.Double(); p.moveTo(7.9, -13.6); p.lineTo(14.0, -13.6); p.lineTo(3.4, 13.6); p.lineTo(-3.4, 13.6);
     192        p.lineTo(-14.0, -13.6); p.lineTo(-7.9, -13.6); p.lineTo(0.0, 8.7); p.closePath();
     193        VisitorBerth.add(new Instr(Form.PGON, p));
     194    }
     195
     196    public static final Symbol VisitorMooring = new Symbol();
     197    static {
     198        VisitorMooring.add(new Instr(Form.FILL, new Color(0xa30075)));
     199        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0); p.curveTo(-32.0, -21.0, -14.0, -45.5, 12.7, -37.9); p.curveTo(27.5, -33.8, 37.8, -15.5, 32.0, 0.0);
     200        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
     201        VisitorMooring.add(new Instr(Form.PGON, p));
     202        VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     203        VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     204        VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(-33, 0, -10, 0)));
     205        VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
     206        VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     207        VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(6.5, -49.5, 12, 12)));
     208        VisitorMooring.add(new Instr(Form.FILL, Color.white));
     209        p = new Path2D.Double(); p.moveTo(8.3, -32.8); p.lineTo(12.5, -32.8); p.lineTo(5.4, -12.9); p.lineTo(1.0, -12.9); p.lineTo(-6.1, -32.8);
     210        p.lineTo(-1.9, -32.8); p.lineTo(3.2, -18.1); p.closePath();
     211        VisitorMooring.add(new Instr(Form.PGON, p));
     212    }
     213
     214    public static final EnumMap<CatSCF, Symbol> Cats = new EnumMap<>(CatSCF.class);
     215    static {
     216        Cats.put(CatSCF.SCF_BHST, Boatlift); Cats.put(CatSCF.SCF_BTYD, Boatyard); Cats.put(CatSCF.SCF_CHDR, Chandler); Cats.put(CatSCF.SCF_FUEL, Fuel); Cats.put(CatSCF.SCF_LAUN, Laundrette);
     217        Cats.put(CatSCF.SCF_PMPO, PumpOut); Cats.put(CatSCF.SCF_CLUB, SailingClub); Cats.put(CatSCF.SCF_SHWR, Shower); Cats.put(CatSCF.SCF_SLPW, Slipway); Cats.put(CatSCF.SCF_WC, Toilet);
     218        Cats.put(CatSCF.SCF_VBTH, VisitorBerth); Cats.put(CatSCF.SCF_VMOR, VisitorMooring);
     219    }
    199220}
  • applications/editors/josm/plugins/seachart/src/symbols/Harbours.java

    r32101 r32394  
    1212import java.awt.BasicStroke;
    1313import java.awt.Color;
    14 import java.awt.geom.*;
    15 
    16 import symbols.Symbols.*;
     14import java.awt.geom.Arc2D;
     15import java.awt.geom.Ellipse2D;
     16import java.awt.geom.GeneralPath;
     17import java.awt.geom.Line2D;
     18import java.awt.geom.Path2D;
     19import java.awt.geom.Rectangle2D;
     20
     21import symbols.Symbols.Form;
     22import symbols.Symbols.Instr;
     23import symbols.Symbols.Scheme;
     24import symbols.Symbols.Symbol;
    1725
    1826public class Harbours {
    19         public static final Symbol Anchor = new Symbol();
    20         static {
    21                 Anchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
    22                 Anchor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    23                 Anchor.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-59,20,20)));
    24                 Path2D.Double p = new Path2D.Double(); p.moveTo(23.0,-40.0); p.lineTo(23.0,-30.0); p.lineTo(6.0,-30.0); p.lineTo(7.0,31.0); p.quadTo(21.0,29.0,31.0,22.0);
    25                 p.lineTo(27.0,18.0); p.lineTo(52.0,0.0); p.lineTo(45.0,35.0); p.lineTo(37.0,28.0);      p.quadTo(25.0,39.0,7.0,43.0); p.lineTo(6.0,51.0);
    26                 p.lineTo(-6.0,51.0); p.lineTo(-7.0,43.0);       p.quadTo(-25.0,39.0,-37.0,28.0); p.lineTo(-45.0,35.0); p.lineTo(-52.0,0.0); p.lineTo(-27.0,18.0);
    27                 p.lineTo(-31.0,22.0); p.quadTo(-21.0,29.0,-7.0,31.0); p.lineTo(-6.0,-30.0); p.lineTo(-23.0,-30.0); p.lineTo(-23.0,-40.0); p.closePath();
    28                 Anchor.add(new Instr(Form.PGON, p));
    29         }
    30         public static final Symbol Yacht = new Symbol();
    31         static {
    32                 Yacht.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    33                 Path2D.Double p = new Path2D.Double(); p.moveTo(-65.0,50.0); p.curveTo(-36.0,97.0,36.0,97.0,65.0,50.0); p.lineTo(3.0,50.0); p.lineTo(3.0,40.0); p.lineTo(55.0,30.0);
    34                 p.curveTo(32.0,4.0,25.0,-15.0,26.0,-52.0); p.lineTo(1.5,-40.0); p.lineTo(1.0,-64.0); p.lineTo(-2.0,-64.0); p.lineTo(-4.0,50.0); p.closePath();
    35                 p.moveTo(-50.0,45.0); p.curveTo(-55.0,3.0,-37.0,-28.5,-7.0,-46.0); p.curveTo(-28.0,-15.0,-26.0,11.0,-20.5,30.0); p.closePath();
    36                 Yacht.add(new Instr(Form.PGON, p));
    37         }
    38         public static final Symbol Anchorage = new Symbol();
    39         static {
    40                 Anchorage.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.67, 0, 0, new Scheme(Symbols.Msymb), null)));
    41         }
    42         public static final Symbol Bollard = new Symbol();
    43         static {
    44                 Bollard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    45                 Bollard.add(new Instr(Form.FILL, Color.white));
    46                 Ellipse2D.Double s = new Ellipse2D.Double(-10,-10,20,20);
    47                 Bollard.add(new Instr(Form.RSHP, s));
    48                 Bollard.add(new Instr(Form.FILL, Color.black));
    49                 Bollard.add(new Instr(Form.ELPS, s));
    50         }
    51         public static final Symbol CallPoint1 = new Symbol();
    52         static {
    53                 CallPoint1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-50,100,100)));
    54                 CallPoint1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    55                 CallPoint1.add(new Instr(Form.FILL, Symbols.Msymb));
    56                 CallPoint1.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
    57                 Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0,-20.0); p.lineTo(0.0,-50.0); p.lineTo(16.0,-20.0);
    58                 CallPoint1.add(new Instr(Form.PLIN, p));
    59         }
    60         public static final Symbol CallPoint2 = new Symbol();
    61         static {
    62                 CallPoint2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-50,100,100)));
    63                 CallPoint2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(CallPoint1, 1.0, 0, 0, null, null)));
    64                 Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0,20.0); p.lineTo(0.0,50.0); p.lineTo(16.0,20.0);
    65                 CallPoint2.add(new Instr(Form.PLIN, p));
    66         }
    67         public static final Symbol ContainerCrane = new Symbol();
    68         static {
    69                 ContainerCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    70                 ContainerCrane.add(new Instr(Form.RSHP, new Rectangle2D.Double(-15,-65,30,100)));
    71                 ContainerCrane.add(new Instr(Form.RECT, new Rectangle2D.Double(-40,-12.5,80,25)));
    72         }
    73         public static final Symbol Customs = new Symbol();
    74         static {
    75                 Customs.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    76                 Customs.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    77                 Customs.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28,-28,56,56)));
    78                 Customs.add(new Instr(Form.LINE, new Line2D.Double(-25,5,25,5)));
    79                 Customs.add(new Instr(Form.LINE, new Line2D.Double(-25,-5,25,-5)));
    80         }
    81         public static final Symbol DeviationDolphin = new Symbol();
    82         static {
    83                 DeviationDolphin.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    84                 Path2D.Double p = new Path2D.Double(); p.moveTo(-30.0,0.0); p.lineTo(30.0,0.0); p.moveTo(0.0,0.0); p.lineTo(0.0,-40.0);
    85                 p.moveTo(-20.0,0.0); p.lineTo(-15.0,-32.0); p.lineTo(15.0,-32.0); p.lineTo(20.0,0.0);
    86                 DeviationDolphin.add(new Instr(Form.PLIN, p));
    87         }
    88         public static final Symbol DistanceI = new Symbol();
    89         static {
    90                 DistanceI.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    91                 DistanceI.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11,-11,22,22)));
    92         }
    93         public static final Symbol DistanceU = new Symbol();
    94         static {
    95                 DistanceU.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    96                 DistanceU.add(new Instr(Form.FILL, Symbols.Msymb));
    97                 DistanceU.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11,-11,22,22)));
    98         }
    99         public static final Symbol Dolphin = new Symbol();
    100         static {
    101                 Dolphin.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    102                 Dolphin.add(new Instr(Form.FILL, new Color(0xffd400)));
    103                 Path2D.Double p = new Path2D.Double(); p.moveTo(3.8,-9.2); p.lineTo(9.2,-3.8); p.lineTo(9.2,3.8); p.lineTo(3.8,9.2);
    104                 p.lineTo(-3.8,9.2); p.lineTo(-9.2,3.8); p.lineTo(-9.2,-3.8); p.lineTo(-3.8,-9.2); p.closePath();
    105                 Dolphin.add(new Instr(Form.PGON, p));
    106                 Dolphin.add(new Instr(Form.FILL, Color.black));
    107                 Dolphin.add(new Instr(Form.PLIN, p));
    108         }
    109         public static final Symbol Explosives = new Symbol();
    110         static {
    111                 Explosives.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    112                 Explosives.add(new Instr(Form.RSHP, new Ellipse2D.Double(-5,25,10,10)));
    113                 Explosives.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    114                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,20); p.lineTo(-13,17); p.lineTo(-13,8);
    115                 p.moveTo(0,10); p.lineTo(0,0); p.lineTo(-8,-10);
    116                 p.moveTo(10,17); p.lineTo(18,-10); p.lineTo(10,-20);
    117                 Explosives.add(new Instr(Form.PLIN, p));
    118         }
    119         public static final Symbol Fishing = new Symbol();
    120         static {
    121                 Fishing.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    122                 Fishing.add(new Instr(Form.FILL, Symbols.Msymb));
    123                 Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50,-50,100,100,15,140,Arc2D.OPEN)));
    124                 Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50,-50,100,100,-15,-140,Arc2D.OPEN)));
    125                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    126                 p.moveTo(-24,3); p.curveTo(12,24,30,15,48,0); p.curveTo(30,-15,12,-24,-24,-3);
    127                 p.lineTo(-45,-15); p.quadTo(-48, 0, -45, 15); p.closePath();
    128                 p.moveTo(25, 0); p.curveTo(25, 6, 34, 6, 34, 0); p.curveTo(34, -6, 25, -6, 25, 0); p.closePath();
    129                 Fishing.add(new Instr(Form.PGON, p));
    130         }
    131         public static final Symbol Harbour = new Symbol();
    132         static {
    133                 Harbour.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    134                 Harbour.add(new Instr(Form.FILL, Symbols.Msymb));
    135                 Harbour.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50,-50,100,100)));
    136                 Harbour.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
    137         }
    138         public static final Symbol HarbourMaster = new Symbol();
    139         static {
    140                 HarbourMaster.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    141                 HarbourMaster.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    142                 HarbourMaster.add(new Instr(Form.ELPS, new Ellipse2D.Double(-24,-28,48,56)));
    143                 HarbourMaster.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
    144         }
    145         public static final Symbol Hospital = new Symbol();
    146         static {
    147                 Hospital.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    148                 Hospital.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    149                 Hospital.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28,-28,56,56)));
    150                 Path2D.Double p = new Path2D.Double(); p.moveTo(-26,-5); p.lineTo(-5,-5); p.lineTo(-5,-25); p.moveTo(5,-25); p.lineTo(5,-5); p.lineTo(25,-5);
    151                 p.moveTo(-25,5); p.lineTo(-5,5); p.lineTo(-5,25); p.moveTo(5,25); p.lineTo(5,5); p.lineTo(25,5);
    152                 Hospital.add(new Instr(Form.PLIN, p));
    153         }
    154         public static final Symbol LandingSteps = new Symbol();
    155         static {
    156                 LandingSteps.add(new Instr(Form.FILL, Symbols.Msymb));
    157                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,-10); p.lineTo(10,20); p.lineTo(20,20); p.lineTo(20,10);
    158                 p.lineTo(10,10); p.lineTo(10,0); p.lineTo(0,0); p.lineTo(0,-10); p.lineTo(-10,-10); p.lineTo(-10,-20); p.lineTo(-20,-20); p.closePath();
    159                 LandingSteps.add(new Instr(Form.PGON, p));
    160         }
    161         public static final Symbol Marina = new Symbol();
    162         static {
    163                 Marina.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    164                 Marina.add(new Instr(Form.FILL, Symbols.Msymb));
    165                 Marina.add(new Instr(Form.EARC, new Arc2D.Double(-50.0,-50.0,100.0,100.0,215.0,-250.0,Arc2D.OPEN)));
    166                 Marina.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
    167         }
    168         public static final Symbol MarinaNF = new Symbol();
    169         static {
    170                 MarinaNF.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
    171         }
    172         public static final Symbol Pilot = new Symbol();
    173         static{
    174                 Pilot.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    175                 Pilot.add(new Instr(Form.FILL, new Color(0xd400d4)));
    176                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,0); p.lineTo(0,-56); p.lineTo(15,0); p.lineTo(0,56); p.closePath();
    177                 Pilot.add(new Instr(Form.PGON, p));
    178                 Pilot.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58,-58,116,116)));
    179         }
    180         public static final Symbol PortCrane = new Symbol();
    181         static {
    182                 PortCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    183                 PortCrane.add(new Instr(Form.EARC, new Arc2D.Double(-36.0,-36.0,72.0,72.0,70.0,-320.0,Arc2D.OPEN)));
    184                 PortCrane.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-60)));
    185         }
    186         public static final Symbol Post = new Symbol();
    187         static {
    188                 Post.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-10,20,20)));
    189         }
    190         public static final Symbol Rescue = new Symbol();
    191         static{
    192                 Rescue.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-50,40,100)));
    193                 Rescue.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    194                 Path2D.Double p = new Path2D.Double(); p.moveTo(-11,0); p.lineTo(0,-43); p.lineTo(11,0); p.lineTo(0,43); p.closePath();
    195                 Rescue.add(new Instr(Form.PGON, p));
    196                 Rescue.add(new Instr(Form.LINE, new Line2D.Double(-15,0,15,0)));
    197         }
    198         public static final Symbol SignalStation = new Symbol();
    199         static {
    200                 SignalStation.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    201                 SignalStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
    202                 SignalStation.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
    203         }
    204         public static final Symbol TideGauge = new Symbol();
    205         static {
    206                 TideGauge.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    207                 TideGauge.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    208                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-10,0,-30,0)));
    209                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(10,0,30,0)));
    210                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-80)));
    211                 TideGauge.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    212                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15,-25,15,-25)));
    213                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-25,-45,25,-45)));
    214                 TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15,-65,15,-65)));
    215         }
     27    // CHECKSTYLE.OFF: LineLength
     28    public static final Symbol Anchor = new Symbol();
     29    static {
     30        Anchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
     31        Anchor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     32        Anchor.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -59, 20, 20)));
     33        Path2D.Double p = new Path2D.Double(); p.moveTo(23.0, -40.0); p.lineTo(23.0, -30.0); p.lineTo(6.0, -30.0); p.lineTo(7.0, 31.0); p.quadTo(21.0, 29.0, 31.0, 22.0);
     34        p.lineTo(27.0, 18.0); p.lineTo(52.0, 0.0); p.lineTo(45.0, 35.0); p.lineTo(37.0, 28.0); p.quadTo(25.0, 39.0, 7.0, 43.0); p.lineTo(6.0, 51.0);
     35        p.lineTo(-6.0, 51.0); p.lineTo(-7.0, 43.0); p.quadTo(-25.0, 39.0, -37.0, 28.0); p.lineTo(-45.0, 35.0); p.lineTo(-52.0, 0.0); p.lineTo(-27.0, 18.0);
     36        p.lineTo(-31.0, 22.0); p.quadTo(-21.0, 29.0, -7.0, 31.0); p.lineTo(-6.0, -30.0); p.lineTo(-23.0, -30.0); p.lineTo(-23.0, -40.0); p.closePath();
     37        Anchor.add(new Instr(Form.PGON, p));
     38    }
     39
     40    public static final Symbol Yacht = new Symbol();
     41    static {
     42        Yacht.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     43        Path2D.Double p = new Path2D.Double(); p.moveTo(-65.0, 50.0); p.curveTo(-36.0, 97.0, 36.0, 97.0, 65.0, 50.0); p.lineTo(3.0, 50.0); p.lineTo(3.0, 40.0); p.lineTo(55.0, 30.0);
     44        p.curveTo(32.0, 4.0, 25.0, -15.0, 26.0, -52.0); p.lineTo(1.5, -40.0); p.lineTo(1.0, -64.0); p.lineTo(-2.0, -64.0); p.lineTo(-4.0, 50.0); p.closePath();
     45        p.moveTo(-50.0, 45.0); p.curveTo(-55.0, 3.0, -37.0, -28.5, -7.0, -46.0); p.curveTo(-28.0, -15.0, -26.0, 11.0, -20.5, 30.0); p.closePath();
     46        Yacht.add(new Instr(Form.PGON, p));
     47    }
     48
     49    public static final Symbol Anchorage = new Symbol();
     50    static {
     51        Anchorage.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.67, 0, 0, new Scheme(Symbols.Msymb), null)));
     52    }
     53
     54    public static final Symbol Bollard = new Symbol();
     55    static {
     56        Bollard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     57        Bollard.add(new Instr(Form.FILL, Color.white));
     58        Ellipse2D.Double s = new Ellipse2D.Double(-10, -10, 20, 20);
     59        Bollard.add(new Instr(Form.RSHP, s));
     60        Bollard.add(new Instr(Form.FILL, Color.black));
     61        Bollard.add(new Instr(Form.ELPS, s));
     62    }
     63
     64    public static final Symbol CallPoint1 = new Symbol();
     65    static {
     66        CallPoint1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -50, 100, 100)));
     67        CallPoint1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     68        CallPoint1.add(new Instr(Form.FILL, Symbols.Msymb));
     69        CallPoint1.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
     70        Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0, -20.0); p.lineTo(0.0, -50.0); p.lineTo(16.0, -20.0);
     71        CallPoint1.add(new Instr(Form.PLIN, p));
     72    }
     73
     74    public static final Symbol CallPoint2 = new Symbol();
     75    static {
     76        CallPoint2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -50, 100, 100)));
     77        CallPoint2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(CallPoint1, 1.0, 0, 0, null, null)));
     78        Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0, 20.0); p.lineTo(0.0, 50.0); p.lineTo(16.0, 20.0);
     79        CallPoint2.add(new Instr(Form.PLIN, p));
     80    }
     81
     82    public static final Symbol ContainerCrane = new Symbol();
     83    static {
     84        ContainerCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     85        ContainerCrane.add(new Instr(Form.RSHP, new Rectangle2D.Double(-15, -65, 30, 100)));
     86        ContainerCrane.add(new Instr(Form.RECT, new Rectangle2D.Double(-40, -12.5, 80, 25)));
     87    }
     88
     89    public static final Symbol Customs = new Symbol();
     90    static {
     91        Customs.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     92        Customs.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     93        Customs.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28, -28, 56, 56)));
     94        Customs.add(new Instr(Form.LINE, new Line2D.Double(-25, 5, 25, 5)));
     95        Customs.add(new Instr(Form.LINE, new Line2D.Double(-25, -5, 25, -5)));
     96    }
     97
     98    public static final Symbol DeviationDolphin = new Symbol();
     99    static {
     100        DeviationDolphin.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     101        Path2D.Double p = new Path2D.Double(); p.moveTo(-30.0, 0.0); p.lineTo(30.0, 0.0); p.moveTo(0.0, 0.0); p.lineTo(0.0, -40.0);
     102        p.moveTo(-20.0, 0.0); p.lineTo(-15.0, -32.0); p.lineTo(15.0, -32.0); p.lineTo(20.0, 0.0);
     103        DeviationDolphin.add(new Instr(Form.PLIN, p));
     104    }
     105
     106    public static final Symbol DistanceI = new Symbol();
     107    static {
     108        DistanceI.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     109        DistanceI.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11, -11, 22, 22)));
     110    }
     111
     112    public static final Symbol DistanceU = new Symbol();
     113    static {
     114        DistanceU.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     115        DistanceU.add(new Instr(Form.FILL, Symbols.Msymb));
     116        DistanceU.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11, -11, 22, 22)));
     117    }
     118
     119    public static final Symbol Dolphin = new Symbol();
     120    static {
     121        Dolphin.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     122        Dolphin.add(new Instr(Form.FILL, new Color(0xffd400)));
     123        Path2D.Double p = new Path2D.Double(); p.moveTo(3.8, -9.2); p.lineTo(9.2, -3.8); p.lineTo(9.2, 3.8); p.lineTo(3.8, 9.2);
     124        p.lineTo(-3.8, 9.2); p.lineTo(-9.2, 3.8); p.lineTo(-9.2, -3.8); p.lineTo(-3.8, -9.2); p.closePath();
     125        Dolphin.add(new Instr(Form.PGON, p));
     126        Dolphin.add(new Instr(Form.FILL, Color.black));
     127        Dolphin.add(new Instr(Form.PLIN, p));
     128    }
     129
     130    public static final Symbol Explosives = new Symbol();
     131    static {
     132        Explosives.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     133        Explosives.add(new Instr(Form.RSHP, new Ellipse2D.Double(-5, 25, 10, 10)));
     134        Explosives.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     135        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 20); p.lineTo(-13, 17); p.lineTo(-13, 8);
     136        p.moveTo(0, 10); p.lineTo(0, 0); p.lineTo(-8, -10);
     137        p.moveTo(10, 17); p.lineTo(18, -10); p.lineTo(10, -20);
     138        Explosives.add(new Instr(Form.PLIN, p));
     139    }
     140
     141    public static final Symbol Fishing = new Symbol();
     142    static {
     143        Fishing.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     144        Fishing.add(new Instr(Form.FILL, Symbols.Msymb));
     145        Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50, -50, 100, 100, 15, 140, Arc2D.OPEN)));
     146        Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50, -50, 100, 100, -15, -140, Arc2D.OPEN)));
     147        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     148        p.moveTo(-24, 3); p.curveTo(12, 24, 30, 15, 48, 0); p.curveTo(30, -15, 12, -24, -24, -3);
     149        p.lineTo(-45, -15); p.quadTo(-48, 0, -45, 15); p.closePath();
     150        p.moveTo(25, 0); p.curveTo(25, 6, 34, 6, 34, 0); p.curveTo(34, -6, 25, -6, 25, 0); p.closePath();
     151        Fishing.add(new Instr(Form.PGON, p));
     152    }
     153
     154    public static final Symbol Harbour = new Symbol();
     155    static {
     156        Harbour.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     157        Harbour.add(new Instr(Form.FILL, Symbols.Msymb));
     158        Harbour.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50, -50, 100, 100)));
     159        Harbour.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
     160    }
     161
     162    public static final Symbol HarbourMaster = new Symbol();
     163    static {
     164        HarbourMaster.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     165        HarbourMaster.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     166        HarbourMaster.add(new Instr(Form.ELPS, new Ellipse2D.Double(-24, -28, 48, 56)));
     167        HarbourMaster.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
     168    }
     169
     170    public static final Symbol Hospital = new Symbol();
     171    static {
     172        Hospital.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     173        Hospital.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     174        Hospital.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28, -28, 56, 56)));
     175        Path2D.Double p = new Path2D.Double(); p.moveTo(-26, -5); p.lineTo(-5, -5); p.lineTo(-5, -25); p.moveTo(5, -25); p.lineTo(5, -5); p.lineTo(25, -5);
     176        p.moveTo(-25, 5); p.lineTo(-5, 5); p.lineTo(-5, 25); p.moveTo(5, 25); p.lineTo(5, 5); p.lineTo(25, 5);
     177        Hospital.add(new Instr(Form.PLIN, p));
     178    }
     179
     180    public static final Symbol LandingSteps = new Symbol();
     181    static {
     182        LandingSteps.add(new Instr(Form.FILL, Symbols.Msymb));
     183        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, -10); p.lineTo(10, 20); p.lineTo(20, 20); p.lineTo(20, 10);
     184        p.lineTo(10, 10); p.lineTo(10, 0); p.lineTo(0, 0); p.lineTo(0, -10); p.lineTo(-10, -10); p.lineTo(-10, -20); p.lineTo(-20, -20); p.closePath();
     185        LandingSteps.add(new Instr(Form.PGON, p));
     186    }
     187
     188    public static final Symbol Marina = new Symbol();
     189    static {
     190        Marina.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     191        Marina.add(new Instr(Form.FILL, Symbols.Msymb));
     192        Marina.add(new Instr(Form.EARC, new Arc2D.Double(-50.0, -50.0, 100.0, 100.0, 215.0, -250.0, Arc2D.OPEN)));
     193        Marina.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
     194    }
     195
     196    public static final Symbol MarinaNF = new Symbol();
     197    static {
     198        MarinaNF.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
     199    }
     200
     201    public static final Symbol Pilot = new Symbol();
     202    static {
     203        Pilot.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     204        Pilot.add(new Instr(Form.FILL, new Color(0xd400d4)));
     205        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, 0); p.lineTo(0, -56); p.lineTo(15, 0); p.lineTo(0, 56); p.closePath();
     206        Pilot.add(new Instr(Form.PGON, p));
     207        Pilot.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58, -58, 116, 116)));
     208    }
     209
     210    public static final Symbol PortCrane = new Symbol();
     211    static {
     212        PortCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     213        PortCrane.add(new Instr(Form.EARC, new Arc2D.Double(-36.0, -36.0, 72.0, 72.0, 70.0, -320.0, Arc2D.OPEN)));
     214        PortCrane.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -60)));
     215    }
     216
     217    public static final Symbol Post = new Symbol();
     218    static {
     219        Post.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -10, 20, 20)));
     220    }
     221
     222    public static final Symbol Rescue = new Symbol();
     223    static {
     224        Rescue.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -50, 40, 100)));
     225        Rescue.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     226        Path2D.Double p = new Path2D.Double(); p.moveTo(-11, 0); p.lineTo(0, -43); p.lineTo(11, 0); p.lineTo(0, 43); p.closePath();
     227        Rescue.add(new Instr(Form.PGON, p));
     228        Rescue.add(new Instr(Form.LINE, new Line2D.Double(-15, 0, 15, 0)));
     229    }
     230
     231    public static final Symbol SignalStation = new Symbol();
     232    static {
     233        SignalStation.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     234        SignalStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
     235        SignalStation.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
     236    }
     237
     238    public static final Symbol TideGauge = new Symbol();
     239    static {
     240        TideGauge.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     241        TideGauge.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     242        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, -30, 0)));
     243        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 30, 0)));
     244        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -80)));
     245        TideGauge.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     246        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15, -25, 15, -25)));
     247        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-25, -45, 25, -45)));
     248        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15, -65, 15, -65)));
     249    }
    216250}
  • applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java

    r32393 r32394  
    1111
    1212import java.awt.BasicStroke;
    13 import java.awt.geom.*;
     13import java.awt.geom.Arc2D;
     14import java.awt.geom.Ellipse2D;
     15import java.awt.geom.Line2D;
     16import java.awt.geom.Path2D;
     17import java.awt.geom.Rectangle2D;
    1418import java.util.EnumMap;
    1519
    16 import s57.S57val.*;
    17 import symbols.Symbols.*;
    18 
     20import s57.S57val.CatLMK;
     21import s57.S57val.FncFNC;
     22import symbols.Symbols.Form;
     23import symbols.Symbols.Instr;
     24import symbols.Symbols.Symbol;
    1925
    2026public class Landmarks {
    21         private static final Symbol Base = new Symbol();
    22         static {
    23                 Base.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    24                 Base.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
    25                 Base.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
    26                 Base.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
    27         }
    28        
    29         public static final Symbol Chimney = new Symbol();
    30         static {
    31                 Chimney.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    32                 Chimney.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    33                 Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(-10.0,-120.0); p.lineTo(10.0,-120.0); p.lineTo(25.0,0.0);
    34                 p.moveTo(-10.0,-128.0); p.curveTo(-13.0,-147.0,15.0,-159.0,20.0,-148.0);
    35                 p.moveTo(16.0,-152.3); p.curveTo(58.0,-194.0,98.0,-87.0,16.0,-132.0);
    36                 p.moveTo(11.0,-128.0); p.curveTo(13.4,-132.0,20.0,-132.0,20.0,-136.0);
    37                 Chimney.add(new Instr(Form.PLIN, p));
    38         }
    39         public static final Symbol Church = new Symbol();
    40         static {
    41                 Path2D.Double p = new Path2D.Double(); p.moveTo(10.0,-10.0); p.lineTo(37.0,-10.0); p.quadTo(48.0,-10.0,48.0,-21.0); p.lineTo(50.0,-21.0); p.lineTo(50.0,21.0);
    42                 p.lineTo(48.0,21.0); p.quadTo(48.0,10.0,37.0,10.0); p.lineTo(10.0,10.0); p.lineTo(10.0,37.0); p.quadTo(10.0,48.0,21.0,48.0); p.lineTo(21.0,50.0);
    43                 p.lineTo(-21.0,50.0); p.lineTo(-21.0,48.0); p.quadTo(-10.0,48.0,-10.0,37.0); p.lineTo(-10.0,10.0); p.lineTo(-37.0,10.0); p.quadTo(-48.0,10.0,-48.0,21.0);
    44                 p.lineTo(-50.0,21.0); p.lineTo(-50.0,-21.0); p.lineTo(-48.0,-21.0); p.quadTo(-48.0,-10.0,-37.0,-10.0); p.lineTo(-10.0,-10.0); p.lineTo(-10.0,-37.0);
    45                 p.quadTo(-10.0,-48.0,-21.0,-48.0); p.lineTo(-21.0,-50.0); p.lineTo(21.0,-50.0); p.lineTo(21.0,-48.0); p.quadTo(10.0,-48.0,10.0,-37.0); p.closePath();
    46                 Church.add(new Instr(Form.PGON, p));
    47         }
    48         public static final Symbol ChurchTower = new Symbol();
    49         static {
    50                 ChurchTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    51                 ChurchTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-36,-36,72,72)));
    52                 ChurchTower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-2,-2,4,4)));
    53         }
    54         public static final Symbol Cross = new Symbol();
    55         static {
    56                 Cross.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    57                 Cross.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    58                 Cross.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-150)));
    59                 Cross.add(new Instr(Form.LINE, new Line2D.Double(-30,-115,30,-115)));
    60         }
    61         public static final Symbol DishAerial = new Symbol();
    62         static {
    63                 DishAerial.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    64                 DishAerial.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
    65                 Path2D.Double p = new Path2D.Double(); p.moveTo(-7.8,-6.0); p.lineTo(0.0,-62.0); p.lineTo(7.8,-6.0); p.moveTo(18.0,-109.0); p.lineTo(25.0,-113.0);
    66                 p.moveTo(-9.5,-157.0); p.curveTo(-60.7,-125.5,-16.5,-33.9,44.9,-61.7); p.closePath();
    67                 DishAerial.add(new Instr(Form.PLIN, p));
    68         }
    69         public static final Symbol Dome = new Symbol();
    70         static {
    71                 Dome.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    72                 Dome.add(new Instr(Form.ELPS, new Ellipse2D.Double(-36,-36,72,72)));
    73                 Dome.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
    74         }
    75         public static final Symbol Flagstaff = new Symbol();
    76         static {
    77                 Flagstaff.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    78                 Flagstaff.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    79                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(0.0,-150.0); p.moveTo(0.0,-140.0); p.lineTo(40.0,-140.0); p.lineTo(40.0,-100.0); p.lineTo(0.0,-100.0);
    80                 Flagstaff.add(new Instr(Form.PLIN, p));
    81         }
    82         public static final Symbol FlareStack = new Symbol();
    83         static {
    84                 FlareStack.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    85                 FlareStack.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    86                 Path2D.Double p = new Path2D.Double(); p.moveTo(-7.8,-6.0); p.lineTo(-7.8,-100.0); p.lineTo(7.8,-100.0); p.lineTo(7.8,-6.0);
    87                 FlareStack.add(new Instr(Form.PLIN, p));
    88                 FlareStack.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    89                 p = new Path2D.Double(); p.moveTo(21.6,-169.6); p.curveTo(-22.0,-132.4,-27.4,-103.5,3.0,-100.0); p.curveTo(39.0,-118.0,-4.0,-141.0,21.6,-169.6);
    90                 FlareStack.add(new Instr(Form.PLIN, p));
    91         }
    92         public static final Symbol LandTower = new Symbol();
    93         static {
    94                 LandTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    95                 LandTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    96                 LandTower.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-120)));
    97                 LandTower.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-120)));
    98                 LandTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-15,-150,30,30)));
    99         }
    100         public static final Symbol Mast = new Symbol();
    101         static {
    102                 Mast.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    103                 Mast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
    104                 Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(0.0,-150.0); p.lineTo(25.0,0.0);
    105                 Mast.add(new Instr(Form.PLIN, p));
    106         }
    107         public static final Symbol Monument = new Symbol();
    108         static {
    109                 Monument.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    110                 Monument.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    111                 Monument.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-105)));
    112                 Monument.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-105)));
    113                 Monument.add(new Instr(Form.EARC, new Arc2D.Double(-25.0,-150.0,50.0,50.0,233.0,-285.0,Arc2D.OPEN)));
    114         }
    115         public static final Symbol Platform = new Symbol();
    116         static {
    117                 Platform.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    118                 Platform.add(new Instr(Form.RECT, new Rectangle2D.Double(-48,-48,96,96)));
    119                 Platform.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
    120         }
    121         public static final Symbol RadioTV = new Symbol();
    122         static {
    123                 RadioTV.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)));
    124                 RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0,-180.0,60.0,60.0,45.0,-90.0,Arc2D.OPEN)));
    125                 RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0,-195.0,90.0,90.0,45.0,-90.0,Arc2D.OPEN)));
    126                 RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0,-180.0,60.0,60.0,225.0,-90.0,Arc2D.OPEN)));
    127                 RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0,-195.0,90.0,90.0,225.0,-90.0,Arc2D.OPEN)));
    128         }
    129         public static final Symbol Spire = new Symbol();
    130         static {
    131                 Spire.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    132                 Spire.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
    133                 Spire.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
    134         }
    135         public static final Symbol Minaret = new Symbol();
    136         static {
    137                 Minaret.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Spire, 1.0, 0, 0, null, null)));
    138                 Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    139                 Minaret.add(new Instr(Form.LINE, new Line2D.Double(0,-25,0,-50)));
    140                 Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    141                 Minaret.add(new Instr(Form.EARC, new Arc2D.Double(-40.0,-110.0,80.0,60.0,180.0,180.0,Arc2D.OPEN)));
    142         }
    143         public static final Symbol Temple = new Symbol();
    144         static {
    145                 Temple.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    146                 Temple.add(new Instr(Form.RECT, new Rectangle2D.Double(-25,-15,50,30)));
    147                 Temple.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    148                 Temple.add(new Instr(Form.LINE, new Line2D.Double(-35,-21,35,21)));
    149                 Temple.add(new Instr(Form.LINE, new Line2D.Double(-35,21,35,-21)));
    150         }
    151         public static final Symbol WaterTower = new Symbol();
    152         static {
    153                 WaterTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    154                 WaterTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    155                 WaterTower.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-120)));
    156                 WaterTower.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-120)));
    157                 WaterTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-25,-150,50,30)));
    158         }
    159         public static final Symbol WindMotor = new Symbol();
    160         static {
    161                 WindMotor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    162                 WindMotor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    163                 WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-90)));
    164                 WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,30,-90)));
    165                 WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,-14,-116.6)));
    166                 WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,-14.3,-66.7)));
    167         }
    168         public static final Symbol Windmill = new Symbol();
    169         static {
    170                 Windmill.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    171                 Windmill.add(new Instr(Form.ELPS, new Ellipse2D.Double(-12,-12,24,24)));
    172                 Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30,-42,30,10)));
    173                 Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30,10,30,-42)));
    174         }
    175         public static final Symbol Windsock = new Symbol();
    176         static {
    177                 Windsock.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
    178                 Windsock.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    179                 Windsock.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-100)));
    180                 Windsock.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    181                 Windsock.add(new Instr(Form.LINE, new Line2D.Double(0,-100,0,-150)));
    182                 Windsock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    183                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-100.0); p.lineTo(10.0,-100.0); p.lineTo(10.0,-150.0); p.lineTo(0.0,-150.0);
    184                 p.moveTo(10.0,-150.0); p.lineTo(50.0,-145.0); p.lineTo(120.0,-70.0); p.quadTo(120.0,-55.0,105.0,-55.0);
    185                 p.lineTo(55,-95); p.lineTo(40,-102); p.lineTo(10,-100); p.moveTo(40,-102); p.lineTo(50,-120); p.moveTo(55,-95); p.lineTo(75,-97);
    186                 Windsock.add(new Instr(Form.PLIN, p));
    187         }
    188        
    189         public static final EnumMap<CatLMK, Symbol> Shapes = new EnumMap<>(CatLMK.class);
    190         static {
    191                 Shapes.put(CatLMK.LMK_CARN, Beacons.Cairn); Shapes.put(CatLMK.LMK_CHMY, Landmarks.Chimney);
    192                 Shapes.put(CatLMK.LMK_DISH, Landmarks.DishAerial); Shapes.put(CatLMK.LMK_FLAG, Landmarks.Flagstaff); Shapes.put(CatLMK.LMK_FLAR, Landmarks.FlareStack);
    193                 Shapes.put(CatLMK.LMK_MAST, Landmarks.Mast); Shapes.put(CatLMK.LMK_WNDS, Landmarks.Windsock); Shapes.put(CatLMK.LMK_MNMT, Landmarks.Monument);
    194                 Shapes.put(CatLMK.LMK_CLMN, Landmarks.Monument); Shapes.put(CatLMK.LMK_MEML, Landmarks.Monument); Shapes.put(CatLMK.LMK_OBLK, Landmarks.Monument);
    195                 Shapes.put(CatLMK.LMK_STAT, Landmarks.Monument); Shapes.put(CatLMK.LMK_CROS, Landmarks.Cross); Shapes.put(CatLMK.LMK_DOME, Landmarks.Dome);
    196                 Shapes.put(CatLMK.LMK_RADR, Landmarks.Mast); Shapes.put(CatLMK.LMK_TOWR, Landmarks.LandTower); Shapes.put(CatLMK.LMK_WNDM, Landmarks.Windmill);
    197                 Shapes.put(CatLMK.LMK_WNDG, Landmarks.WindMotor); Shapes.put(CatLMK.LMK_SPIR, Landmarks.Spire); Shapes.put(CatLMK.LMK_BLDR, Beacons.Cairn);
    198         }
    199 
    200         public static final EnumMap<FncFNC, Symbol> Funcs = new EnumMap<>(FncFNC.class);
    201         static {
    202                 Funcs.put(FncFNC.FNC_CHCH, Landmarks.Church); Funcs.put(FncFNC.FNC_CHPL, Landmarks.Church); Funcs.put(FncFNC.FNC_TMPL, Landmarks.Temple);
    203                 Funcs.put(FncFNC.FNC_PGDA, Landmarks.Temple); Funcs.put(FncFNC.FNC_SHSH, Landmarks.Temple); Funcs.put(FncFNC.FNC_BTMP, Landmarks.Temple);
    204                 Funcs.put(FncFNC.FNC_MOSQ, Landmarks.Minaret); Funcs.put(FncFNC.FNC_MRBT, Landmarks.Spire); Funcs.put(FncFNC.FNC_COMM, Landmarks.RadioTV);
    205                 Funcs.put(FncFNC.FNC_TV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADO, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADR, Landmarks.RadioTV);
    206                 Funcs.put(FncFNC.FNC_LGHT, Beacons.LightMajor); Funcs.put(FncFNC.FNC_MCWV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_HBRM, Harbours.HarbourMaster);
    207                 Funcs.put(FncFNC.FNC_CSTM, Harbours.Customs); Funcs.put(FncFNC.FNC_HLTH, Harbours.Hospital); Funcs.put(FncFNC.FNC_HOSP, Harbours.Hospital);
    208         }
     27    // CHECKSTYLE.OFF: LineLength
     28    private static final Symbol Base = new Symbol();
     29    static {
     30        Base.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     31        Base.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
     32        Base.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
     33        Base.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
     34    }
     35
     36    public static final Symbol Chimney = new Symbol();
     37    static {
     38        Chimney.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     39        Chimney.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     40        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(-10.0, -120.0); p.lineTo(10.0, -120.0); p.lineTo(25.0, 0.0);
     41        p.moveTo(-10.0, -128.0); p.curveTo(-13.0, -147.0, 15.0, -159.0, 20.0, -148.0);
     42        p.moveTo(16.0, -152.3); p.curveTo(58.0, -194.0, 98.0, -87.0, 16.0, -132.0);
     43        p.moveTo(11.0, -128.0); p.curveTo(13.4, -132.0, 20.0, -132.0, 20.0, -136.0);
     44        Chimney.add(new Instr(Form.PLIN, p));
     45    }
     46
     47    public static final Symbol Church = new Symbol();
     48    static {
     49        Path2D.Double p = new Path2D.Double(); p.moveTo(10.0, -10.0); p.lineTo(37.0, -10.0); p.quadTo(48.0, -10.0, 48.0, -21.0); p.lineTo(50.0, -21.0); p.lineTo(50.0, 21.0);
     50        p.lineTo(48.0, 21.0); p.quadTo(48.0, 10.0, 37.0, 10.0); p.lineTo(10.0, 10.0); p.lineTo(10.0, 37.0); p.quadTo(10.0, 48.0, 21.0, 48.0); p.lineTo(21.0, 50.0);
     51        p.lineTo(-21.0, 50.0); p.lineTo(-21.0, 48.0); p.quadTo(-10.0, 48.0, -10.0, 37.0); p.lineTo(-10.0, 10.0); p.lineTo(-37.0, 10.0); p.quadTo(-48.0, 10.0, -48.0, 21.0);
     52        p.lineTo(-50.0, 21.0); p.lineTo(-50.0, -21.0); p.lineTo(-48.0, -21.0); p.quadTo(-48.0, -10.0, -37.0, -10.0); p.lineTo(-10.0, -10.0); p.lineTo(-10.0, -37.0);
     53        p.quadTo(-10.0, -48.0, -21.0, -48.0); p.lineTo(-21.0, -50.0); p.lineTo(21.0, -50.0); p.lineTo(21.0, -48.0); p.quadTo(10.0, -48.0, 10.0, -37.0); p.closePath();
     54        Church.add(new Instr(Form.PGON, p));
     55    }
     56
     57    public static final Symbol ChurchTower = new Symbol();
     58    static {
     59        ChurchTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     60        ChurchTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-36, -36, 72, 72)));
     61        ChurchTower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-2, -2, 4, 4)));
     62    }
     63
     64    public static final Symbol Cross = new Symbol();
     65    static {
     66        Cross.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     67        Cross.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     68        Cross.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -150)));
     69        Cross.add(new Instr(Form.LINE, new Line2D.Double(-30, -115, 30, -115)));
     70    }
     71
     72    public static final Symbol DishAerial = new Symbol();
     73    static {
     74        DishAerial.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     75        DishAerial.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
     76        Path2D.Double p = new Path2D.Double(); p.moveTo(-7.8, -6.0); p.lineTo(0.0, -62.0); p.lineTo(7.8, -6.0); p.moveTo(18.0, -109.0); p.lineTo(25.0, -113.0);
     77        p.moveTo(-9.5, -157.0); p.curveTo(-60.7, -125.5, -16.5, -33.9, 44.9, -61.7); p.closePath();
     78        DishAerial.add(new Instr(Form.PLIN, p));
     79    }
     80
     81    public static final Symbol Dome = new Symbol();
     82    static {
     83        Dome.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     84        Dome.add(new Instr(Form.ELPS, new Ellipse2D.Double(-36, -36, 72, 72)));
     85        Dome.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
     86    }
     87
     88    public static final Symbol Flagstaff = new Symbol();
     89    static {
     90        Flagstaff.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     91        Flagstaff.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     92        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(0.0, -150.0); p.moveTo(0.0, -140.0); p.lineTo(40.0, -140.0); p.lineTo(40.0, -100.0); p.lineTo(0.0, -100.0);
     93        Flagstaff.add(new Instr(Form.PLIN, p));
     94    }
     95
     96    public static final Symbol FlareStack = new Symbol();
     97    static {
     98        FlareStack.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     99        FlareStack.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     100        Path2D.Double p = new Path2D.Double(); p.moveTo(-7.8, -6.0); p.lineTo(-7.8, -100.0); p.lineTo(7.8, -100.0); p.lineTo(7.8, -6.0);
     101        FlareStack.add(new Instr(Form.PLIN, p));
     102        FlareStack.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     103        p = new Path2D.Double(); p.moveTo(21.6, -169.6); p.curveTo(-22.0, -132.4, -27.4, -103.5, 3.0, -100.0); p.curveTo(39.0, -118.0, -4.0, -141.0, 21.6, -169.6);
     104        FlareStack.add(new Instr(Form.PLIN, p));
     105    }
     106
     107    public static final Symbol LandTower = new Symbol();
     108    static {
     109        LandTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     110        LandTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     111        LandTower.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -120)));
     112        LandTower.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -120)));
     113        LandTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-15, -150, 30, 30)));
     114    }
     115
     116    public static final Symbol Mast = new Symbol();
     117    static {
     118        Mast.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     119        Mast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
     120        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(0.0, -150.0); p.lineTo(25.0, 0.0);
     121        Mast.add(new Instr(Form.PLIN, p));
     122    }
     123
     124    public static final Symbol Monument = new Symbol();
     125    static {
     126        Monument.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     127        Monument.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     128        Monument.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -105)));
     129        Monument.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -105)));
     130        Monument.add(new Instr(Form.EARC, new Arc2D.Double(-25.0, -150.0, 50.0, 50.0, 233.0, -285.0, Arc2D.OPEN)));
     131    }
     132
     133    public static final Symbol Platform = new Symbol();
     134    static {
     135        Platform.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     136        Platform.add(new Instr(Form.RECT, new Rectangle2D.Double(-48, -48, 96, 96)));
     137        Platform.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
     138    }
     139
     140    public static final Symbol RadioTV = new Symbol();
     141    static {
     142        RadioTV.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)));
     143        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0, -180.0, 60.0, 60.0, 45.0, -90.0, Arc2D.OPEN)));
     144        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0, -195.0, 90.0, 90.0, 45.0, -90.0, Arc2D.OPEN)));
     145        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0, -180.0, 60.0, 60.0, 225.0, -90.0, Arc2D.OPEN)));
     146        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0, -195.0, 90.0, 90.0, 225.0, -90.0, Arc2D.OPEN)));
     147    }
     148
     149    public static final Symbol Spire = new Symbol();
     150    static {
     151        Spire.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     152        Spire.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
     153        Spire.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
     154    }
     155
     156    public static final Symbol Minaret = new Symbol();
     157    static {
     158        Minaret.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Spire, 1.0, 0, 0, null, null)));
     159        Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     160        Minaret.add(new Instr(Form.LINE, new Line2D.Double(0, -25, 0, -50)));
     161        Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     162        Minaret.add(new Instr(Form.EARC, new Arc2D.Double(-40.0, -110.0, 80.0, 60.0, 180.0, 180.0, Arc2D.OPEN)));
     163    }
     164
     165    public static final Symbol Temple = new Symbol();
     166    static {
     167        Temple.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     168        Temple.add(new Instr(Form.RECT, new Rectangle2D.Double(-25, -15, 50, 30)));
     169        Temple.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     170        Temple.add(new Instr(Form.LINE, new Line2D.Double(-35, -21, 35, 21)));
     171        Temple.add(new Instr(Form.LINE, new Line2D.Double(-35, 21, 35, -21)));
     172    }
     173
     174    public static final Symbol WaterTower = new Symbol();
     175    static {
     176        WaterTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     177        WaterTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     178        WaterTower.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -120)));
     179        WaterTower.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -120)));
     180        WaterTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-25, -150, 50, 30)));
     181    }
     182
     183    public static final Symbol WindMotor = new Symbol();
     184    static {
     185        WindMotor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     186        WindMotor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     187        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -90)));
     188        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, 30, -90)));
     189        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, -14, -116.6)));
     190        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, -14.3, -66.7)));
     191    }
     192
     193    public static final Symbol Windmill = new Symbol();
     194    static {
     195        Windmill.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     196        Windmill.add(new Instr(Form.ELPS, new Ellipse2D.Double(-12, -12, 24, 24)));
     197        Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30, -42, 30, 10)));
     198        Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30, 10, 30, -42)));
     199    }
     200
     201    public static final Symbol Windsock = new Symbol();
     202    static {
     203        Windsock.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
     204        Windsock.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     205        Windsock.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -100)));
     206        Windsock.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     207        Windsock.add(new Instr(Form.LINE, new Line2D.Double(0, -100, 0, -150)));
     208        Windsock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     209        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -100.0); p.lineTo(10.0, -100.0); p.lineTo(10.0, -150.0); p.lineTo(0.0, -150.0);
     210        p.moveTo(10.0, -150.0); p.lineTo(50.0, -145.0); p.lineTo(120.0, -70.0); p.quadTo(120.0, -55.0, 105.0, -55.0);
     211        p.lineTo(55, -95); p.lineTo(40, -102); p.lineTo(10, -100); p.moveTo(40, -102); p.lineTo(50, -120); p.moveTo(55, -95); p.lineTo(75, -97);
     212        Windsock.add(new Instr(Form.PLIN, p));
     213    }
     214
     215    public static final EnumMap<CatLMK, Symbol> Shapes = new EnumMap<>(CatLMK.class);
     216    static {
     217        Shapes.put(CatLMK.LMK_CARN, Beacons.Cairn); Shapes.put(CatLMK.LMK_CHMY, Landmarks.Chimney);
     218        Shapes.put(CatLMK.LMK_DISH, Landmarks.DishAerial); Shapes.put(CatLMK.LMK_FLAG, Landmarks.Flagstaff); Shapes.put(CatLMK.LMK_FLAR, Landmarks.FlareStack);
     219        Shapes.put(CatLMK.LMK_MAST, Landmarks.Mast); Shapes.put(CatLMK.LMK_WNDS, Landmarks.Windsock); Shapes.put(CatLMK.LMK_MNMT, Landmarks.Monument);
     220        Shapes.put(CatLMK.LMK_CLMN, Landmarks.Monument); Shapes.put(CatLMK.LMK_MEML, Landmarks.Monument); Shapes.put(CatLMK.LMK_OBLK, Landmarks.Monument);
     221        Shapes.put(CatLMK.LMK_STAT, Landmarks.Monument); Shapes.put(CatLMK.LMK_CROS, Landmarks.Cross); Shapes.put(CatLMK.LMK_DOME, Landmarks.Dome);
     222        Shapes.put(CatLMK.LMK_RADR, Landmarks.Mast); Shapes.put(CatLMK.LMK_TOWR, Landmarks.LandTower); Shapes.put(CatLMK.LMK_WNDM, Landmarks.Windmill);
     223        Shapes.put(CatLMK.LMK_WNDG, Landmarks.WindMotor); Shapes.put(CatLMK.LMK_SPIR, Landmarks.Spire); Shapes.put(CatLMK.LMK_BLDR, Beacons.Cairn);
     224    }
     225
     226    public static final EnumMap<FncFNC, Symbol> Funcs = new EnumMap<>(FncFNC.class);
     227    static {
     228        Funcs.put(FncFNC.FNC_CHCH, Landmarks.Church); Funcs.put(FncFNC.FNC_CHPL, Landmarks.Church); Funcs.put(FncFNC.FNC_TMPL, Landmarks.Temple);
     229        Funcs.put(FncFNC.FNC_PGDA, Landmarks.Temple); Funcs.put(FncFNC.FNC_SHSH, Landmarks.Temple); Funcs.put(FncFNC.FNC_BTMP, Landmarks.Temple);
     230        Funcs.put(FncFNC.FNC_MOSQ, Landmarks.Minaret); Funcs.put(FncFNC.FNC_MRBT, Landmarks.Spire); Funcs.put(FncFNC.FNC_COMM, Landmarks.RadioTV);
     231        Funcs.put(FncFNC.FNC_TV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADO, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADR, Landmarks.RadioTV);
     232        Funcs.put(FncFNC.FNC_LGHT, Beacons.LightMajor); Funcs.put(FncFNC.FNC_MCWV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_HBRM, Harbours.HarbourMaster);
     233        Funcs.put(FncFNC.FNC_CSTM, Harbours.Customs); Funcs.put(FncFNC.FNC_HLTH, Harbours.Hospital); Funcs.put(FncFNC.FNC_HOSP, Harbours.Hospital);
     234    }
    209235}
  • applications/editors/josm/plugins/seachart/src/symbols/Notices.java

    r32393 r32394  
    1313import java.awt.Color;
    1414import java.awt.Font;
    15 import java.awt.geom.*;
     15import java.awt.geom.AffineTransform;
     16import java.awt.geom.Arc2D;
     17import java.awt.geom.Ellipse2D;
     18import java.awt.geom.GeneralPath;
     19import java.awt.geom.Line2D;
     20import java.awt.geom.Path2D;
     21import java.awt.geom.Rectangle2D;
     22import java.awt.geom.RoundRectangle2D;
    1623import java.util.ArrayList;
    1724import java.util.EnumMap;
    1825
    19 import s57.S57val.*;
    20 import symbols.Symbols.*;
     26import s57.S57val.BnkWTW;
     27import s57.S57val.CatNMK;
     28import s57.S57val.MarSYS;
     29import symbols.Symbols.Caption;
     30import symbols.Symbols.Delta;
     31import symbols.Symbols.Form;
     32import symbols.Symbols.Handle;
     33import symbols.Symbols.Instr;
     34import symbols.Symbols.Scheme;
     35import symbols.Symbols.Symbol;
    2136
    2237public class Notices {
    23         private static final Symbol Bollard = new Symbol();
    24         static {
    25                 Path2D.Double p = new Path2D.Double(); p.moveTo(20,21); p.lineTo(20,16.5); p.lineTo(11.6,16.5); p.quadTo(9.1,9.6,8.3,2.0); p.lineTo(-8.0,-0.3); p.quadTo(-8.6,9.0,-11.3,16.5);
    26                 p.lineTo(-23.5,16.5); p.lineTo(-23.5,21.0); p.closePath(); p.moveTo(23.8,3.0); p.lineTo(-10.7,-1.8); p.curveTo(-13.1,-2.2,-12.8,-6.0,-10.2,-5.8); p.lineTo(23.8,-1.1);
    27                 p.closePath(); p.moveTo(8.4,-4.3); p.curveTo(9.0,-9.3,9.0,-11.4,11.2,-13.0); p.curveTo(12.8,-15.0,12.8,-16.7,11.0,-18.6); p.curveTo(4.0,-22.2,-4.0,-22.2,-11.0,-18.6);
    28                 p.curveTo(-12.8,-16.7,-12.8,-15.0,-11.2,-13.0); p.curveTo(-9.0,-11.3,-8.7,-9.5,-8.4,-6.5); p.closePath();
    29                 Bollard.add(new Instr(Form.PGON, p));
    30         }
    31         private static final Symbol Motor = new Symbol();
    32         static {
    33                 Path2D.Double p = new Path2D.Double(); p.moveTo(-5.0,4.3); p.curveTo(-3.7,5.5,-1.8,5.7,-0.2,4.9); p.curveTo(1.3,8.7,4.6,10.9,8.4,10.9); p.curveTo(14.0,10.9,17.5,6.3,17.5,2.0);
    34                 p.curveTo(17.5,-0.7,16.1,-3.2,14.5,-3.2); p.curveTo(12.5,-3.2,11.7,0.8,2.5,1.1); p.curveTo(2.5,-1.2,1.6,-2.2,0.6,-3.0); p.curveTo(3.2,-5.6,4.0,-12.6,-1.0,-16.1);
    35                 p.curveTo(-5.3,-19.2,-11.6,-18.3,-13.7,-13.7); p.curveTo(-14.3,-12.2,-14.0,-11.2,-12.5,-10.6); p.curveTo(-8.6,-9.6,-5.3,-6.0,-4.0,-3.4); p.curveTo(-5.4,-2.6,-6.2,-2.0,-6.2,0.2);
    36                 p.curveTo(-12.8,-1.0,-17.5,3.7,-17.5,9.3); p.curveTo(-17.5,14.7,-12.6,18.8,-8.0,17.6); p.curveTo(-7.0,17.2,-6.6,16.2,-7.2,14.6); p.curveTo(-7.7,12.4,-7.0,7.7,-5.0,4.3); p.closePath();
    37                 Motor.add(new Instr(Form.PGON, p));
    38         }
    39         private static final Symbol Rowboat = new Symbol();
    40         static {
    41                 Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5,-2.0); p.lineTo(17.5,-2.0); p.lineTo(15.0,6.0); p.lineTo(-11.0,6.0); p.closePath();
    42                 Rowboat.add(new Instr(Form.PGON, p));
    43                 Rowboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-6,-17.5,6,6)));
    44                 Rowboat.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    45                 Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5,-9,-8,0)));
    46                 Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.0,10.0,-7.5,14.0)));
    47                 Rowboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    48                 Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5,-9,7,-6.5)));
    49                 Rowboat.add(new Instr(Form.LINE, new Line2D.Double(7.3,-7.8,-5.0,10.0)));
    50         }
    51         private static final Symbol Sailboard = new Symbol();
    52         static {
    53                 Path2D.Double p = new Path2D.Double(); p.moveTo(-6.0,19.0); p.quadTo(-4.0,-5,1.5,-20.0); p.quadTo(14,-7,15.5,6.5); p.quadTo(7,17,-6.0,19.0); p.closePath();
    54                 Sailboard.add(new Instr(Form.PGON, p));
    55                 Sailboard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    56                 Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-2,20,-10,20)));
    57                 Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-13,2.5,-3,2.5)));
    58                 Sailboard.add(new Instr(Form.RSHP, new Ellipse2D.Double(-15,-4,5,5)));
    59                 Sailboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    60                 p = new Path2D.Double(); p.moveTo(-13,2.5); p.lineTo(-12,6.0); p.lineTo(-12,9.5);
    61                 Sailboard.add(new Instr(Form.PLIN, p));
    62                 Sailboard.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    63                 p = new Path2D.Double(); p.moveTo(-12,9.5); p.lineTo(-7.5,13.0); p.lineTo(-6.0,19.0);
    64                 Sailboard.add(new Instr(Form.PLIN, p));
    65         }
    66         private static final Symbol Sailboat = new Symbol();
    67         static {
    68                 Path2D.Double p = new Path2D.Double(); p.moveTo(3.75,-20.5); p.lineTo(3.75,8.5); p.lineTo(-19.5,8.5); p.closePath();
    69                 Sailboat.add(new Instr(Form.PGON, p));
    70                 p = new Path2D.Double(); p.moveTo(-19.5,12.0); p.lineTo(19.5,12.0); p.lineTo(13.0,20.5); p.lineTo(-16.0,20.5); p.closePath();
    71                 Sailboat.add(new Instr(Form.PGON, p));
    72         }
    73         private static final Symbol Slipway = new Symbol();
    74         static {
    75                 Path2D.Double p = new Path2D.Double(); p.moveTo(-17,-5.5); p.lineTo(-13.5,0); p.lineTo(4,-1.5); p.quadTo(18,-5,20,-13.5); p.closePath();
    76                 p.moveTo(-14,7); p.lineTo(-14,11); p.lineTo(20,11); p.lineTo(20,2); p.closePath();
    77                 Slipway.add(new Instr(Form.PGON, p));
    78                 Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    79                 Slipway.add(new Instr(Form.LINE, new Line2D.Double(-14,3,20,-2.5)));
    80                 Slipway.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    81                 Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(1,1.5,3,3)));
    82                 p = new Path2D.Double(); p.moveTo(-21,8.5); p.curveTo(-17.5, 5, -17.5, 12, -13, 7.2);
    83                 Slipway.add(new Instr(Form.PLIN, p));
    84         }
    85         private static final Symbol Speedboat = new Symbol();
    86         static {
    87                 Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    88                 Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-21,0,-17,-1)));
    89                 Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5,8.5); p.curveTo(-10.5,13,-2.5,2,4,6); p.curveTo(12,2,11.5,9.5,20,6);
    90                 Speedboat.add(new Instr(Form.PLIN, p));
    91                 p = new Path2D.Double(); p.moveTo(-18.5,1.5); p.lineTo(-16,6); p.curveTo(-9, 9.0, -3.5, -2.0, 4.5, 3.5); p.lineTo(14.5,0); p.quadTo(19, -3, 19.5, -9);
    92                 p.lineTo(9.5,-6); p.lineTo(6.5,-8); p.lineTo(2.5,-4); p.closePath();
    93                 Speedboat.add(new Instr(Form.PGON, p));
    94                 Speedboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-1.5,-13,5,5)));
    95                 Speedboat.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    96                 Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2,-7,-5,0)));
    97                 Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    98                 Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2,-7,5,-5)));
    99         }
    100         private static final Symbol Turn = new Symbol();
    101         static {
    102                 Turn.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    103                 Turn.add(new Instr(Form.EARC, new Arc2D.Double(-9.0,-9.0,18.0,18.0,270.0,230.0,Arc2D.OPEN)));
    104                 Turn.add(new Instr(Form.EARC, new Arc2D.Double(-20.0,-20.0,40.0,40.0,315.0,-280.0,Arc2D.OPEN)));
    105                 Path2D.Double p = new Path2D.Double(); p.moveTo(21.8,-7.0); p.lineTo(18.8,-18.2); p.lineTo(10.5,-10.0); p.closePath();
    106                 p.moveTo(-12.9,0.7); p.lineTo(-1.7,-2.3); p.lineTo(-9.9,-10.5); p.closePath();
    107                 Turn.add(new Instr(Form.PGON, p));
    108         }
    109         private static final Symbol Waterbike = new Symbol();
    110         static {
    111                 Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5,13); p.curveTo(-10.5,17.5,-2.5,6.5,4,10.5); p.curveTo(12,6.5,11.5,14,20,10.5);
    112                 Waterbike.add(new Instr(Form.PLIN, p));
    113                 p = new Path2D.Double(); p.moveTo(-16.5,9.5); p.lineTo(-16,10.5); p.curveTo(-9, 13.5, -3.5, 2.5, 4.5, 8); p.quadTo(15, 4, 19.5, -4); p.closePath();
    114                 p.moveTo(19.5,-5); p.lineTo(1, -5); p.lineTo(-4.5, -10); p.lineTo(-5.5, -10); p.lineTo(2, -2); p.lineTo(-15, 4); p.lineTo(-16, 8); p.closePath();
    115                 Waterbike.add(new Instr(Form.PGON, p));
    116                 Waterbike.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    117                 p = new Path2D.Double(); p.moveTo(-7,1); p.lineTo(-7.5,-1.5); p.lineTo(-12.5,-3.5); p.lineTo(-11.5,-10.5);
    118                 Waterbike.add(new Instr(Form.PLIN, p));
    119                 Waterbike.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    120                 Waterbike.add(new Instr(Form.LINE, new Line2D.Double(-11.5,-10.5,-3,-8.5)));
    121                 Waterbike.add(new Instr(Form.RSHP, new Ellipse2D.Double(-11.5,-18,5,5)));
    122         }
    123         private static final Symbol Waterski = new Symbol();
    124         static {
    125                 Waterski.add(new Instr(Form.RSHP, new Ellipse2D.Double(12,-18,6,6)));
    126                 Waterski.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    127                 Waterski.add(new Instr(Form.LINE, new Line2D.Double(-18,-6,0,-6)));
    128                 Waterski.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    129                 Path2D.Double p = new Path2D.Double(); p.moveTo(6.5,17.5); p.lineTo(-13,14.5); p.curveTo(-15,14.25,-16.0,13.6,-17.5,12.0);
    130                 Waterski.add(new Instr(Form.PLIN, p));
    131                 Waterski.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
    132                 p = new Path2D.Double(); p.moveTo(-1.5,-4.0); p.lineTo(14,-7.5); p.lineTo(9.5,3.5); p.lineTo(2.0,6.0); p.lineTo(-4.4,15.8);
    133                 Waterski.add(new Instr(Form.PLIN, p));
    134         }
    135         private static final Symbol NoticeA = new Symbol();
    136         static {
    137                 NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
    138                 NoticeA.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    139                 NoticeA.add(new Instr(Form.FILL, Color.white));
    140                 NoticeA.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
    141                 NoticeA.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    142                 NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
    143                 NoticeA.add(new Instr(Form.LINE, new Line2D.Double(-25,-25,25,25)));
    144                 NoticeA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    145                 NoticeA.add(new Instr(Form.FILL, Color.black));
    146                 NoticeA.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    147         }
    148         private static final Symbol NoticeB = new Symbol();
    149         static {
    150                 NoticeB.add(new Instr(Form.FILL, new Color(0xe80000)));
    151                 NoticeB.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    152                 NoticeB.add(new Instr(Form.FILL, Color.white));
    153                 NoticeB.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
    154                 NoticeB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    155                 NoticeB.add(new Instr(Form.FILL, Color.black));
    156                 NoticeB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    157         }
    158         private static final Symbol NoticeE = new Symbol();
    159         static {
    160                 NoticeE.add(new Instr(Form.FILL, new Color(0x0000a0)));
    161                 NoticeE.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    162                 NoticeE.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    163                 NoticeE.add(new Instr(Form.FILL, Color.black));
    164                 NoticeE.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    165                 NoticeE.add(new Instr(Form.FILL, Color.white));
    166         }
    167         public static final Symbol Notice = new Symbol();
    168         static {
    169                 Notice.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    170                 Notice.add(new Instr(Form.FILL, new Color(0xe80000)));
    171                 Notice.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    172                 Notice.add(new Instr(Form.FILL, new Color(0x0000a0)));
    173                 Notice.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
    174                 Notice.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    175                 Notice.add(new Instr(Form.FILL, Color.black));
    176                 Notice.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    177         }
    178         public static final Symbol NoticeA1 = new Symbol();
    179         static {
    180                 NoticeA1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    181                 NoticeA1.add(new Instr(Form.FILL, new Color(0xe80000)));
    182                 NoticeA1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    183                 NoticeA1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    184                 NoticeA1.add(new Instr(Form.FILL, Color.white));
    185                 NoticeA1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-30,-10,60,20)));
    186                 NoticeA1.add(new Instr(Form.FILL, Color.black));
    187                 NoticeA1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    188         }
    189         public static final Symbol NoticeA1a = new Symbol();
    190         static {
    191                 NoticeA1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    192                 NoticeA1a.add(new Instr(Form.FILL, new Color(0xe80000)));
    193                 NoticeA1a.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
    194                 NoticeA1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    195                 NoticeA1a.add(new Instr(Form.FILL, Color.white));
    196                 NoticeA1a.add(new Instr(Form.RSHP, new Rectangle2D.Double(-29,-10,58,20)));
    197                 NoticeA1a.add(new Instr(Form.FILL, Color.black));
    198                 NoticeA1a.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
    199         }
    200         public static final Symbol NoticeA2 = new Symbol();
    201         static {
    202                 NoticeA2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    203                 NoticeA2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    204                 NoticeA2.add(new Instr(Form.FILL, Color.black));
    205                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,23); p.lineTo(-10,0); p.lineTo(-6,0); p.lineTo(-12.5,-8); p.lineTo(-19,0); p.lineTo(-15,0); p.lineTo(-15,23);
    206                 p.closePath(); p.moveTo(10,8); p.lineTo(10,-15); p.lineTo(6,-15); p.lineTo(12.5,-23); p.lineTo(19,-15); p.lineTo(15,-15); p.lineTo(15,8); p.closePath();
    207                 NoticeA2.add(new Instr(Form.PGON, p));
    208         }
    209         public static final Symbol NoticeA3 = new Symbol();
    210         static {
    211                 NoticeA3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    212                 NoticeA3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA2, 1.0, 0, 0, null, null)));
    213                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,12); p.lineTo(-6,12); p.lineTo(-12.5,4); p.lineTo(-19,12);
    214                 p.closePath(); p.moveTo(10,-3); p.lineTo(6,-3); p.lineTo(12.5,-11); p.lineTo(19,-3); p.closePath();
    215                 NoticeA3.add(new Instr(Form.PGON, p));
    216         }
    217         public static final Symbol NoticeA4 = new Symbol();
    218         static {
    219                 NoticeA4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    220                 NoticeA4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    221                 NoticeA4.add(new Instr(Form.FILL, Color.black));
    222                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,-15); p.lineTo(-10,8); p.lineTo(-6,8); p.lineTo(-12.5,16); p.lineTo(-19,8); p.lineTo(-15,8); p.lineTo(-15,-15);
    223                 p.closePath(); p.moveTo(10,15); p.lineTo(10,-8); p.lineTo(6,-8); p.lineTo(12.5,-16); p.lineTo(19,-8); p.lineTo(15,-8); p.lineTo(15,15); p.closePath();
    224                 NoticeA4.add(new Instr(Form.PGON, p));
    225         }
    226         public static final Symbol NoticeA4_1 = new Symbol();
    227         static {
    228                 NoticeA4_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    229                 NoticeA4_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA4, 1.0, 0, 0, null, null)));
    230                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,-4); p.lineTo(-6,-4); p.lineTo(-12.5,4); p.lineTo(-19,-4);
    231                 p.closePath(); p.moveTo(10,5); p.lineTo(6,5); p.lineTo(12.5,-3); p.lineTo(19,5); p.closePath();
    232                 NoticeA4_1.add(new Instr(Form.PGON, p));
    233         }
    234         public static final Symbol NoticeA5 = new Symbol();
    235         static {
    236                 NoticeA5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    237                 NoticeA5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    238                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD); p.moveTo(-5.3,14.6); p.lineTo(-5.3,4.0); p.lineTo(0.0,4.0); p.curveTo(4.2,4.0,7.4,3.5,9.4,0.0);
    239                 p.curveTo(11.4,-2.8,11.4,-7.2,9.4,-10.5); p.curveTo(7.4,-13.6,4.2,-14.0,0.0,-14.0); p.lineTo(-11.0,-14.0); p.lineTo(-11.0,14.6); p.closePath();
    240                 p.moveTo(-5.3,-1.0); p.lineTo(0.0,-1.0); p.curveTo(6.5,-1.0,6.5,-9.0,0.0,-9.0); p.lineTo(-5.3,-9.0); p.closePath();
    241                 NoticeA5.add(new Instr(Form.PGON, p));
    242         }
    243         public static final Symbol NoticeA5_1 = new Symbol();
    244         static {
    245                 NoticeA5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    246                 NoticeA5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    247         }
    248         public static final Symbol NoticeA6 = new Symbol();
    249         static {
    250                 NoticeA6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    251                 NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    252                 NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
    253         }
    254         public static final Symbol NoticeA7 = new Symbol();
    255         static {
    256                 NoticeA7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    257                 NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    258                 NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.black), null)));
    259         }
    260         public static final Symbol NoticeA8 = new Symbol();
    261         static {
    262                 NoticeA8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    263                 NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    264                 NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.black), null)));
    265         }
    266         public static final Symbol NoticeA9 = new Symbol();
    267         static {
    268                 NoticeA9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    269                 NoticeA9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    270                 NoticeA9.add(new Instr(Form.STRK, new BasicStroke(7, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    271                 NoticeA9.add(new Instr(Form.FILL, Color.black));
    272                 Path2D.Double p = new Path2D.Double(); p.moveTo(-23,10); p.curveTo(-11,10,-12,4,0,4); p.curveTo(12,4,11,10,23,10);
    273                 p.moveTo(-23,-3); p.curveTo(-11,-3,-12,-9,0,-9); p.curveTo(12,-9,11,-3,23,-3);
    274                 NoticeA9.add(new Instr(Form.PLIN, p));
    275         }
    276         public static final Symbol NoticeA10a = new Symbol();
    277         static {
    278                 NoticeA10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    279                 NoticeA10a.add(new Instr(Form.FILL, Color.white));
    280                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(30,0); p.lineTo(0,30); p.closePath();
    281                 NoticeA10a.add(new Instr(Form.PGON, p));
    282                 NoticeA10a.add(new Instr(Form.FILL, new Color(0xe80000)));
    283                 p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.closePath();
    284                 NoticeA10a.add(new Instr(Form.PGON, p));
    285                 NoticeA10a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    286                 NoticeA10a.add(new Instr(Form.FILL, Color.black));
    287                 p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
    288                 NoticeA10a.add(new Instr(Form.PLIN, p));
    289         }
    290         public static final Symbol NoticeA10b = new Symbol();
    291         static {
    292                 NoticeA10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    293                 NoticeA10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA10a, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
    294         }
    295         public static final Symbol NoticeA12 = new Symbol();
    296         static {
    297                 NoticeA12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    298                 NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    299                 NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.black), null)));
    300         }
    301         public static final Symbol NoticeA13 = new Symbol();
    302         static {
    303                 NoticeA13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    304                 NoticeA13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    305                 NoticeA13.add(new Instr(Form.TEXT, new Caption("SPORT", new Font("Arial", Font.BOLD, 15), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 5)))));
    306         }
    307         public static final Symbol NoticeA14 = new Symbol();
    308         static {
    309                 NoticeA14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    310                 NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    311                 NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.black), null)));
    312         }
    313         public static final Symbol NoticeA15 = new Symbol();
    314         static {
    315                 NoticeA15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    316                 NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    317                 NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.black), null)));
    318         }
    319         public static final Symbol NoticeA16 = new Symbol();
    320         static {
    321                 NoticeA16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    322                 NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    323                 NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.black), null)));
    324         }
    325         public static final Symbol NoticeA17 = new Symbol();
    326         static {
    327                 NoticeA17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    328                 NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    329                 NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.black), null)));
    330         }
    331         public static final Symbol NoticeA18 = new Symbol();
    332         static {
    333                 NoticeA18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    334                 NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    335                 NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.black), null)));
    336         }
    337         public static final Symbol NoticeA19 = new Symbol();
    338         static {
    339                 NoticeA19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    340                 NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    341                 NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.black), null)));
    342         }
    343         public static final Symbol NoticeA20 = new Symbol();
    344         static {
    345                 NoticeA20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    346                 NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
    347                 NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.black), null)));
    348         }
    349         public static final Symbol NoticeB1a = new Symbol();
    350         static {
    351                 NoticeB1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    352                 NoticeB1a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    353                 Path2D.Double p = new Path2D.Double(); p.moveTo(21,8); p.lineTo(-8,8); p.lineTo(-8,18); p.lineTo(-21,0);
    354                 p.lineTo(-8,-18); p.lineTo(-8,-8); p.lineTo(21,-8); p.closePath();
    355                 NoticeB1a.add(new Instr(Form.PGON, p));
    356         }
    357         public static final Symbol NoticeB1b = new Symbol();
    358         static {
    359                 NoticeB1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    360                 NoticeB1b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    361                 Path2D.Double p = new Path2D.Double(); p.moveTo(-21,8); p.lineTo(8,8); p.lineTo(8,18); p.lineTo(21,0);
    362                 p.lineTo(8,-18); p.lineTo(8,-8); p.lineTo(-21,-8); p.closePath();
    363                 NoticeB1b.add(new Instr(Form.PGON, p));
    364         }
    365         public static final Symbol NoticeB2a = new Symbol();
    366         static {
    367                 NoticeB2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    368                 NoticeB2a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    369                 NoticeB2a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    370                 Path2D.Double p = new Path2D.Double(); p.moveTo(18,21); p.lineTo(18,10); p.lineTo(-15,-10); p.lineTo(-15,-15);
    371                 NoticeB2a.add(new Instr(Form.PLIN, p));
    372                 p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(-21,-15); p.lineTo(-9,-15); p.closePath();
    373                 NoticeB2a.add(new Instr(Form.PGON, p));
    374         }
    375         public static final Symbol NoticeB2b = new Symbol();
    376         static {
    377                 NoticeB2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    378                 NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    379                 NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    380                 NoticeB2b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    381                 Path2D.Double p = new Path2D.Double(); p.moveTo(-18,21); p.lineTo(-18,10); p.lineTo(15,-10); p.lineTo(15,-15);
    382                 NoticeB2b.add(new Instr(Form.PLIN, p));
    383                 p = new Path2D.Double(); p.moveTo(15,-21); p.lineTo(21,-15); p.lineTo(9,-15); p.closePath();
    384                 NoticeB2b.add(new Instr(Form.PGON, p));
    385         }
    386         public static final Symbol NoticeB3a = new Symbol();
    387         static {
    388                 NoticeB3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    389                 NoticeB3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    390                 NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    391                 NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(-15,21,-15,-15)));
    392                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(-21,-15); p.lineTo(-9,-15); p.closePath();
    393                 NoticeB3a.add(new Instr(Form.PGON, p));
    394                 NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 5.5f, 2.4f }, 0.0f)));
    395                 NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(15,-21,15,15)));
    396                 p = new Path2D.Double(); p.moveTo(15,21); p.lineTo(21,15); p.lineTo(9,15); p.closePath();
    397                 NoticeB3a.add(new Instr(Form.PGON, p));
    398         }
    399         public static final Symbol NoticeB3b = new Symbol();
    400         static {
    401                 NoticeB3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    402                 NoticeB3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    403                 NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    404                 NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(15,21,15,-15)));
    405                 Path2D.Double p = new Path2D.Double(); p.moveTo(15,-21); p.lineTo(21,-15); p.lineTo(9,-15); p.closePath();
    406                 NoticeB3b.add(new Instr(Form.PGON, p));
    407                 NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 5.5f, 2.4f }, 0.0f)));
    408                 NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(-15,-21,-15,15)));
    409                 p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(-21,15); p.lineTo(-9,15); p.closePath();
    410                 NoticeB3b.add(new Instr(Form.PGON, p));
    411         }
    412         public static final Symbol NoticeB4a = new Symbol();
    413         static {
    414                 NoticeB4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    415                 NoticeB4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2a, 1.0, 0, 0, null, null)));
    416                 NoticeB4a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 5.5f, 2.4f }, 0.0f)));
    417                 Path2D.Double p = new Path2D.Double(); p.moveTo(18,-21); p.lineTo(18,-10); p.lineTo(-15,10); p.lineTo(-15,15);
    418                 NoticeB4a.add(new Instr(Form.PLIN, p));
    419                 p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(-21,15); p.lineTo(-9,15); p.closePath();
    420                 NoticeB4a.add(new Instr(Form.PGON, p));
    421         }
    422         public static final Symbol NoticeB4b = new Symbol();
    423         static {
    424                 NoticeB4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    425                 NoticeB4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2b, 1.0, 0, 0, null, null)));
    426                 NoticeB4b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 5.5f, 2.4f }, 0.0f)));
    427                 Path2D.Double p = new Path2D.Double(); p.moveTo(-18,-21); p.lineTo(-18,-10); p.lineTo(15,10); p.lineTo(15,15);
    428                 NoticeB4b.add(new Instr(Form.PLIN, p));
    429                 p = new Path2D.Double(); p.moveTo(15,21); p.lineTo(21,15); p.lineTo(9,15); p.closePath();
    430                 NoticeB4b.add(new Instr(Form.PGON, p));
    431         }
    432         public static final Symbol NoticeB5 = new Symbol();
    433         static {
    434                 NoticeB5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    435                 NoticeB5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    436                 NoticeB5.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    437                 NoticeB5.add(new Instr(Form.LINE, new Line2D.Double(15,0,-15,0)));
    438         }
    439         public static final Symbol NoticeB6 = new Symbol();
    440         static {
    441                 NoticeB6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    442                 NoticeB6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    443         }
    444         public static final Symbol NoticeB7 = new Symbol();
    445         static {
    446                 NoticeB7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    447                 NoticeB7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    448                 NoticeB7.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-10,20,20)));
    449         }
    450         public static final Symbol NoticeB8 = new Symbol();
    451         static {
    452                 NoticeB8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    453                 NoticeB8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    454                 NoticeB8.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    455                 NoticeB8.add(new Instr(Form.LINE, new Line2D.Double(0,15,0,-15)));
    456         }
    457         public static final Symbol NoticeB9a = new Symbol();
    458         static {
    459                 NoticeB9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    460                 NoticeB9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    461                 NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    462                 NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(-21,0,21,0)));
    463                 NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    464                 NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(0,21,0,0)));
    465         }
    466         public static final Symbol NoticeB9b = new Symbol();
    467         static {
    468                 NoticeB9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    469                 NoticeB9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    470                 NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    471                 NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(-21,0,21,0)));
    472                 NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    473                 NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(0,21,0,-21)));
    474         }
    475         public static final Symbol NoticeB11 = new Symbol();
    476         static {
    477                 NoticeB11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    478                 NoticeB11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    479                 NoticeB11.add(new Instr(Form.TEXT, new Caption("VHF", new Font("Arial", Font.BOLD, 20), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 0)))));
    480         }
    481         public static final Symbol NoticeC1 = new Symbol();
    482         static {
    483                 NoticeC1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    484                 NoticeC1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    485                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(0,12); p.lineTo(15,21); p.closePath();
    486                 NoticeC1.add(new Instr(Form.PGON, p));
    487         }
    488         public static final Symbol NoticeC2 = new Symbol();
    489         static {
    490                 NoticeC2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    491                 NoticeC2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    492                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(0,-12); p.lineTo(15,-21); p.closePath();
    493                 NoticeC2.add(new Instr(Form.PGON, p));
    494         }
    495         public static final Symbol NoticeC3 = new Symbol();
    496         static {
    497                 NoticeC3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    498                 NoticeC3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    499                 Path2D.Double p = new Path2D.Double(); p.moveTo(21,-15); p.lineTo(12,0); p.lineTo(21,15); p.closePath();
    500                 p.moveTo(-21,-15); p.lineTo(-12,0); p.lineTo(-21,15); p.closePath();
    501                 NoticeC3.add(new Instr(Form.PGON, p));
    502         }
    503         public static final Symbol NoticeC4 = new Symbol();
    504         static {
    505                 NoticeC4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    506                 NoticeC4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    507         }
    508         public static final Symbol NoticeC5a = new Symbol();
    509         static {
    510                 NoticeC5a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    511                 NoticeC5a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    512                 Path2D.Double p = new Path2D.Double(); p.moveTo(-21,-21); p.lineTo(10,-21); p.lineTo(21,0);     p.lineTo(10,21);        p.lineTo(-21,21); p.closePath();
    513                 NoticeC5a.add(new Instr(Form.PGON, p));
    514         }
    515         public static final Symbol NoticeC5b = new Symbol();
    516         static {
    517                 NoticeC5b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    518                 NoticeC5b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
    519                 Path2D.Double p = new Path2D.Double(); p.moveTo(21,-21); p.lineTo(-10,-21); p.lineTo(-21,0);    p.lineTo(-10,21);       p.lineTo(21,21); p.closePath();
    520                 NoticeC5b.add(new Instr(Form.PGON, p));
    521         }
    522         public static final Symbol NoticeD1a = new Symbol();
    523         static {
    524                 NoticeD1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    525                 NoticeD1a.add(new Instr(Form.FILL, Color.yellow));
    526                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
    527                 NoticeD1a.add(new Instr(Form.PGON, p));
    528                 NoticeD1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    529                 NoticeD1a.add(new Instr(Form.FILL, Color.black));
    530                 NoticeD1a.add(new Instr(Form.PLIN, p));
    531         }
    532         public static final Symbol NoticeD1b = new Symbol();
    533         static {
    534                 NoticeD1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    535                 NoticeD1b.add(new Instr(Form.FILL, Color.yellow));
    536                 Path2D.Double p = new Path2D.Double(); p.moveTo(-30,0); p.lineTo(-15,25); p.lineTo(15,-25); p.lineTo(30,0);     p.lineTo(15,25); p.lineTo(-15,-25); p.closePath();
    537                 NoticeD1b.add(new Instr(Form.PGON, p));
    538                 NoticeD1b.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    539                 NoticeD1b.add(new Instr(Form.FILL, Color.black));
    540                 NoticeD1b.add(new Instr(Form.PLIN, p));
    541         }
    542         public static final Symbol NoticeD2a = new Symbol();
    543         static {
    544                 NoticeD2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    545                 NoticeD2a.add(new Instr(Form.FILL, Color.white));
    546                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.closePath();
    547                 NoticeD2a.add(new Instr(Form.PGON, p));
    548                 NoticeD2a.add(new Instr(Form.FILL, new Color(0x00e800)));
    549                 p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(30,0); p.lineTo(0,30); p.closePath();
    550                 NoticeD2a.add(new Instr(Form.PGON, p));
    551                 NoticeD2a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    552                 NoticeD2a.add(new Instr(Form.FILL, Color.black));
    553                 p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
    554                 NoticeD2a.add(new Instr(Form.PLIN, p));
    555         }
    556         public static final Symbol NoticeD2b = new Symbol();
    557         static {
    558                 NoticeD2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    559                 NoticeD2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeD2a, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
    560         }
    561         public static final Symbol NoticeD3a = new Symbol();
    562         static {
    563                 NoticeD3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    564                 NoticeD3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    565                 Path2D.Double p = new Path2D.Double(); p.moveTo(28,10); p.lineTo(-10,10); p.lineTo(-10,20); p.lineTo(-28,0);
    566                 p.lineTo(-10,-20); p.lineTo(-10,-10); p.lineTo(28,-10); p.closePath();
    567                 NoticeD3a.add(new Instr(Form.PGON, p));
    568         }
    569         public static final Symbol NoticeD3b = new Symbol();
    570         static {
    571                 NoticeD3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    572                 NoticeD3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    573                 Path2D.Double p = new Path2D.Double(); p.moveTo(-28,10); p.lineTo(10,10); p.lineTo(10,20); p.lineTo(28,0);
    574                 p.lineTo(10,-20); p.lineTo(10,-10); p.lineTo(-28,-10); p.closePath();
    575                 NoticeD3b.add(new Instr(Form.PGON, p));
    576         }
    577         public static final Symbol NoticeE1 = new Symbol();
    578         static {
    579                 NoticeE1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    580                 NoticeE1.add(new Instr(Form.FILL, new Color(0x00e800)));
    581                 NoticeE1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    582                 NoticeE1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    583                 NoticeE1.add(new Instr(Form.FILL, Color.white));
    584                 NoticeE1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-10,-30,20,60)));
    585                 NoticeE1.add(new Instr(Form.FILL, Color.black));
    586                 NoticeE1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    587         }
    588         public static final Symbol NoticeE2 = new Symbol();
    589         static {
    590                 NoticeE2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    591                 NoticeE2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    592                 Path2D.Double p = new Path2D.Double(); p.moveTo(5,-25); p.lineTo(-10,-1); p.lineTo(10,-1); p.lineTo(-10,20);
    593                 p.lineTo(-7,20); p.lineTo(-12,25); p.lineTo(-16,20); p.lineTo(-13,20); p.lineTo(4,1); p.lineTo(-14,1);
    594                 p.lineTo(2,-25); p.closePath();
    595                 NoticeE2.add(new Instr(Form.PGON, p));
    596         }
    597         public static final Symbol NoticeE3 = new Symbol();
    598         static {
    599                 NoticeE3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    600                 NoticeE3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    601                 NoticeE3.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    602                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(25,-20,25,20)));
    603                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-25,-20,-25,20)));
    604                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-15,-15,-15,20)));
    605                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-5,-15,-5,20)));
    606                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(5,-15,5,20)));
    607                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(15,-15,15,20)));
    608                 NoticeE3.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    609                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26,18.5,26,18.5)));
    610                 NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26,-15,26,-15)));
    611         }
    612         public static final Symbol NoticeE4a = new Symbol();
    613         static {
    614                 NoticeE4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    615                 NoticeE4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    616                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,-10); p.lineTo(-5,-10); p.lineTo(-5,-20); p.lineTo(5,-20); p.lineTo(5,-10);
    617                 p.lineTo(20,-10); p.lineTo(15,0); p.lineTo(-15,0); p.closePath();
    618                 p.moveTo(-25,5); p.lineTo(25,5); p.lineTo(25,10); p.lineTo(-25,10); p.closePath();
    619                 NoticeE4a.add(new Instr(Form.PGON, p));
    620         }
    621         public static final Symbol NoticeE4b = new Symbol();
    622         static {
    623                 NoticeE4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    624                 NoticeE4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    625                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,0); p.lineTo(-5,0); p.lineTo(-5,-10); p.lineTo(5,-10); p.lineTo(5,0);
    626                 p.lineTo(20,0); p.lineTo(15,10); p.lineTo(-15,10); p.closePath();
    627                 NoticeE4b.add(new Instr(Form.PGON, p));
    628         }
    629         public static final Symbol NoticeE5 = new Symbol();
    630         static {
    631                 NoticeE5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    632                 NoticeE5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    633                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD); p.moveTo(-5.3,14.6); p.lineTo(-5.3,4.0); p.lineTo(0.0,4.0); p.curveTo(4.2,4.0,7.4,3.5,9.4,0.0);
    634                 p.curveTo(11.4,-2.8,11.4,-7.2,9.4,-10.5); p.curveTo(7.4,-13.6,4.2,-14.0,0.0,-14.0); p.lineTo(-11.0,-14.0); p.lineTo(-11.0,14.6); p.closePath();
    635                 p.moveTo(-5.3,-1.0); p.lineTo(0.0,-1.0); p.curveTo(6.5,-1.0,6.5,-9.0,0.0,-9.0); p.lineTo(-5.3,-9.0); p.closePath();
    636                 NoticeE5.add(new Instr(Form.PGON, p));
    637         }
    638         public static final Symbol NoticeE5_1 = new Symbol();
    639         static {
    640                 NoticeE5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    641                 NoticeE5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    642         }
    643         public static final Symbol NoticeE5_2 = new Symbol();
    644         static {
    645                 NoticeE5_2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    646                 NoticeE5_2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    647         }
    648         public static final Symbol NoticeE5_3 = new Symbol();
    649         static {
    650                 NoticeE5_3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    651                 NoticeE5_3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    652         }
    653         public static final Symbol NoticeE5_4 = new Symbol();
    654         static {
    655                 NoticeE5_4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    656                 NoticeE5_4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    657                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    658                 p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
    659                 NoticeE5_4.add(new Instr(Form.PGON, p));
    660         }
    661         public static final Symbol NoticeE5_5 = new Symbol();
    662         static {
    663                 NoticeE5_5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    664                 NoticeE5_5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    665                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    666                 p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
    667                 p.moveTo(0,24); p.lineTo(-15,2); p.lineTo(15,2); p.closePath();
    668                 NoticeE5_5.add(new Instr(Form.PGON, p));
    669         }
    670         public static final Symbol NoticeE5_6 = new Symbol();
    671         static {
    672                 NoticeE5_6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    673                 NoticeE5_6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    674                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    675                 p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
    676                 p.moveTo(0,7); p.lineTo(-10,-8); p.lineTo(10,-8); p.closePath();
    677                 p.moveTo(0,24); p.lineTo(-10,9); p.lineTo(10,9); p.closePath();
    678                 NoticeE5_6.add(new Instr(Form.PGON, p));
    679         }
    680         public static final Symbol NoticeE5_7 = new Symbol();
    681         static {
    682                 NoticeE5_7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    683                 NoticeE5_7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    684                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    685                 p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
    686                 p.moveTo(0,-1); p.lineTo(-8,-11); p.lineTo(8,-11); p.closePath();
    687                 p.moveTo(0,11); p.lineTo(-8,1); p.lineTo(8,1); p.closePath();
    688                 p.moveTo(0,23); p.lineTo(-8,13); p.lineTo(8,13); p.closePath();
    689                 NoticeE5_7.add(new Instr(Form.PGON, p));
    690         }
    691         public static final Symbol NoticeE5_8 = new Symbol();
    692         static {
    693                 NoticeE5_8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    694                 NoticeE5_8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    695                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    696                 p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
    697                 NoticeE5_8.add(new Instr(Form.PGON, p));
    698         }
    699         public static final Symbol NoticeE5_9 = new Symbol();
    700         static {
    701                 NoticeE5_9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    702                 NoticeE5_9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    703                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    704                 p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
    705                 p.moveTo(0,8); p.lineTo(-15,-14); p.lineTo(15,-14); p.closePath();
    706                 NoticeE5_9.add(new Instr(Form.PGON, p));
    707         }
    708         public static final Symbol NoticeE5_10 = new Symbol();
    709         static {
    710                 NoticeE5_10.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    711                 NoticeE5_10.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    712                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    713                 p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
    714                 p.moveTo(0,-5); p.lineTo(-10,-20); p.lineTo(10,-20); p.closePath();
    715                 p.moveTo(0,15); p.lineTo(-10,0); p.lineTo(10,0); p.closePath();
    716                 NoticeE5_10.add(new Instr(Form.PGON, p));
    717         }
    718         public static final Symbol NoticeE5_11 = new Symbol();
    719         static {
    720                 NoticeE5_11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    721                 NoticeE5_11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    722                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    723                 p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
    724                 p.moveTo(0,-12); p.lineTo(-8,-22); p.lineTo(8,-22); p.closePath();
    725                 p.moveTo(0,3); p.lineTo(-8,-7); p.lineTo(8,-7); p.closePath();
    726                 p.moveTo(0,18); p.lineTo(-8,8); p.lineTo(8,8); p.closePath();
    727                 NoticeE5_11.add(new Instr(Form.PGON, p));
    728         }
    729         public static final Symbol NoticeE5_12 = new Symbol();
    730         static {
    731                 NoticeE5_12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    732                 NoticeE5_12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    733                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    734                 p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
    735                 NoticeE5_12.add(new Instr(Form.PGON, p));
    736         }
    737         public static final Symbol NoticeE5_13 = new Symbol();
    738         static {
    739                 NoticeE5_13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    740                 NoticeE5_13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    741                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    742                 p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
    743                 p.moveTo(0,15); p.lineTo(-15,-7); p.lineTo(15,-7); p.closePath();
    744                 NoticeE5_13.add(new Instr(Form.PGON, p));
    745         }
    746         public static final Symbol NoticeE5_14 = new Symbol();
    747         static {
    748                 NoticeE5_14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    749                 NoticeE5_14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    750                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    751                 p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
    752                 p.moveTo(0,0); p.lineTo(-10,-15); p.lineTo(10,-15); p.closePath();
    753                 p.moveTo(0,20); p.lineTo(-10,5); p.lineTo(10,5); p.closePath();
    754                 NoticeE5_14.add(new Instr(Form.PGON, p));
    755         }
    756         public static final Symbol NoticeE5_15 = new Symbol();
    757         static {
    758                 NoticeE5_15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    759                 NoticeE5_15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    760                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    761                 p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
    762                 p.moveTo(0,-7); p.lineTo(-8,-17); p.lineTo(8,-17); p.closePath();
    763                 p.moveTo(0,8); p.lineTo(-8,-2); p.lineTo(8,-2); p.closePath();
    764                 p.moveTo(0,23); p.lineTo(-8,13); p.lineTo(8,13); p.closePath();
    765                 NoticeE5_15.add(new Instr(Form.PGON, p));
    766         }
    767         public static final Symbol NoticeE6 = new Symbol();
    768         static {
    769                 NoticeE6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    770                 NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    771                 NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.white), null)));
    772         }
    773         public static final Symbol NoticeE7 = new Symbol();
    774         static {
    775                 NoticeE7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    776                 NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    777                 NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.white), null)));
    778         }
    779         public static final Symbol NoticeE7_1 = new Symbol();
    780         static {
    781                 NoticeE7_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    782                 NoticeE7_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    783                 NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    784                 NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20,25,20,-10)));
    785                 NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(22,-8,-15,-20)));
    786                 NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    787                 NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20,8,0,-15)));
    788                 Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    789                 p.moveTo(-17,2); p.quadTo(-5,0,7,2); p.lineTo(9,12); p.lineTo(7,20); p.lineTo(6,20); p.lineTo(6,23); p.lineTo(3,23); p.lineTo(3,20);
    790                 p.quadTo(-5,22,-13,20); p.lineTo(-13,23); p.lineTo(-16,23); p.lineTo(-16,20); p.lineTo(-17,20); p.lineTo(-19,12); p.closePath();
    791                 p.moveTo(-15,4); p.quadTo(-3,2,5,4); p.lineTo(6,11); p.quadTo(-5,9,-16,11); p.closePath();
    792                 NoticeE7_1.add(new Instr(Form.PGON, p));
    793                 NoticeE7_1.add(new Instr(Form.FILL, new Color(0x0000a0)));
    794                 NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(-16,13,4,4)));
    795                 NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(2,13,4,4)));
    796         }
    797         public static final Symbol NoticeE8 = new Symbol();
    798         static {
    799                 NoticeE8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    800                 NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    801                 NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.white), null)));
    802         }
    803         public static final Symbol NoticeE9a = new Symbol();
    804         static {
    805                 NoticeE9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    806                 NoticeE9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    807                 NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    808                 NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
    809                 NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    810                 NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
    811         }
    812         public static final Symbol NoticeE9b = new Symbol();
    813         static {
    814                 NoticeE9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    815                 NoticeE9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    816                 NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    817                 NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
    818                 NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    819                 NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
    820         }
    821         public static final Symbol NoticeE9c = new Symbol();
    822         static {
    823                 NoticeE9c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    824                 NoticeE9c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    825                 NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    826                 NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
    827                 NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    828                 NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
    829         }
    830         public static final Symbol NoticeE9d = new Symbol();
    831         static {
    832                 NoticeE9d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    833                 NoticeE9d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    834                 NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    835                 NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    836                 NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
    837                 NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    838                 NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
    839         }
    840         public static final Symbol NoticeE9e = new Symbol();
    841         static {
    842                 NoticeE9e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    843                 NoticeE9e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    844                 NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    845                 NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    846                 NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
    847                 NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    848                 NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
    849         }
    850         public static final Symbol NoticeE9f = new Symbol();
    851         static {
    852                 NoticeE9f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    853                 NoticeE9f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    854                 NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    855                 NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    856                 NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
    857                 NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    858                 NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
    859         }
    860         public static final Symbol NoticeE9g = new Symbol();
    861         static {
    862                 NoticeE9g.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    863                 NoticeE9g.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    864                 NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    865                 NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    866                 NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
    867                 NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    868                 NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
    869         }
    870         public static final Symbol NoticeE9h = new Symbol();
    871         static {
    872                 NoticeE9h.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    873                 NoticeE9h.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    874                 NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    875                 NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    876                 NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
    877                 NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    878                 NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
    879                 NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
    880         }
    881         public static final Symbol NoticeE9i = new Symbol();
    882         static {
    883                 NoticeE9i.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    884                 NoticeE9i.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    885                 NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    886                 NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
    887                 NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
    888                 NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    889                 NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
    890                 NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
    891         }
    892         public static final Symbol NoticeE10a = new Symbol();
    893         static {
    894                 NoticeE10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    895                 NoticeE10a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    896                 NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    897                 NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
    898                 NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    899                 NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
    900         }
    901         public static final Symbol NoticeE10b = new Symbol();
    902         static {
    903                 NoticeE10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    904                 NoticeE10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    905                 NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    906                 NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
    907                 NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    908                 NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
    909         }
    910         public static final Symbol NoticeE10c = new Symbol();
    911         static {
    912                 NoticeE10c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    913                 NoticeE10c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    914                 NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    915                 NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
    916                 NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
    917                 NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    918                 NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
    919         }
    920         public static final Symbol NoticeE10d = new Symbol();
    921         static {
    922                 NoticeE10d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    923                 NoticeE10d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    924                 NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    925                 NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
    926                 NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
    927                 NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    928                 NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
    929         }
    930         public static final Symbol NoticeE10e = new Symbol();
    931         static {
    932         NoticeE10e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    933         NoticeE10e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    934         NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    935         NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
    936         NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
    937         NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    938         NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
    939         NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
    940         }
    941         public static final Symbol NoticeE10f = new Symbol();
    942         static {
    943                 NoticeE10f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    944                 NoticeE10f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    945                 NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    946                 NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
    947                 NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
    948                 NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    949                 NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
    950                 NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
    951         }
    952         public static final Symbol NoticeE11 = new Symbol();
    953         static {
    954                 NoticeE11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    955                 NoticeE11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    956                 NoticeE11.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
    957                 NoticeE11.add(new Instr(Form.LINE, new Line2D.Double(-27,-27,27,27)));
    958         }
    959         public static final Symbol NoticeE13 = new Symbol();
    960         static {
    961                 NoticeE13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    962                 NoticeE13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    963                 Path2D.Double p = new Path2D.Double(); p.moveTo(-4,-16); p.lineTo(9,-16); p.lineTo(9,-14); p.lineTo(3.5,-14); p.lineTo(3.5,-7); p.lineTo(5,-7);
    964                 p.lineTo(5,1); p.lineTo(6.5,1); p.lineTo(6.5,5); p.lineTo(17.5,5); p.lineTo(17.5,1); p.lineTo(19,1); p.lineTo(19,15); p.lineTo(17.5,15);
    965                 p.lineTo(17.5,10); p.lineTo(17.5,10); p.lineTo(6.5,10); p.lineTo(6.5,13); p.lineTo(-2,13); p.lineTo(-2,10); p.lineTo(-9,10);
    966                 p.quadTo(-13.5,10,-13.5,16); p.lineTo(-19,16); p.quadTo(-19,5,-9,5); p.lineTo(-2,5); p.lineTo(-2,1); p.lineTo(0,1); p.lineTo(0,-7);
    967                 p.lineTo(1.5,-7); p.lineTo(1.5,-14); p.lineTo(-4,-14); p.closePath();
    968                 NoticeE13.add(new Instr(Form.PGON, p));
    969         }
    970         public static final Symbol NoticeE14 = new Symbol();
    971         static {
    972                 NoticeE14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    973                 NoticeE14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    974                 Path2D.Double p = new Path2D.Double(); p.moveTo(-18,-18); p.lineTo(-11,-7); p.lineTo(-9,-10); p.lineTo(-14,-18); p.closePath();
    975                 p.moveTo(9.5,7); p.lineTo(22.5,9); p.lineTo(21.5,5.5); p.lineTo(12,4); p.closePath();
    976                 p.moveTo(-19,-16.5); p.lineTo(-13,-6.5); p.quadTo(-15.5,-2,-12.5,0); p.lineTo(4,11); p.quadTo(7,13,10,9); p.lineTo(21.5,11);
    977                 p.curveTo(15.5,23,1,18.5,-9,12); p.curveTo(-18,6,-28.5,-7,-19,-16.5); p.closePath();
    978                 NoticeE14.add(new Instr(Form.PGON, p));
    979         }
    980         public static final Symbol NoticeE15 = new Symbol();
    981         static {
    982                 NoticeE15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    983                 NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    984                 NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.white), null)));
    985         }
    986         public static final Symbol NoticeE16 = new Symbol();
    987         static {
    988                 NoticeE16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    989                 NoticeE16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    990                 NoticeE16.add(new Instr(Form.TEXT, new Caption("SPORT", new Font("Arial", Font.BOLD, 15), Color.white, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 5)))));
    991         }
    992         public static final Symbol NoticeE17 = new Symbol();
    993         static {
    994                 NoticeE17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    995                 NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    996                 NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.white), null)));
    997         }
    998         public static final Symbol NoticeE18 = new Symbol();
    999         static {
    1000                 NoticeE18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1001                 NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1002                 NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.white), null)));
    1003         }
    1004         public static final Symbol NoticeE19 = new Symbol();
    1005         static {
    1006                 NoticeE19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1007                 NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1008                 NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.white), null)));
    1009         }
    1010         public static final Symbol NoticeE20 = new Symbol();
    1011         static {
    1012                 NoticeE20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1013                 NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1014                 NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.white), null)));
    1015         }
    1016         public static final Symbol NoticeE21 = new Symbol();
    1017         static {
    1018                 NoticeE21.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1019                 NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1020                 NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.white), null)));
    1021         }
    1022         public static final Symbol NoticeE22 = new Symbol();
    1023         static {
    1024                 NoticeE22.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1025                 NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1026                 NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.white), null)));
    1027         }
    1028         public static final Symbol NoticeE23 = new Symbol();
    1029         static {
    1030                 NoticeE23.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1031                 NoticeE23.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1032                 NoticeE23.add(new Instr(Form.TEXT, new Caption("VHF", new Font("Arial", Font.BOLD, 20), Color.white, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 0)))));
    1033         }
    1034         public static final Symbol NoticeE24 = new Symbol();
    1035         static {
    1036                 NoticeE24.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1037                 NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
    1038                 NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.white), null)));
    1039         }
    1040 
    1041         public static final Symbol NoticeBoard = new Symbol();
    1042         static {
    1043                 NoticeBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,30)));
    1044                 NoticeBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1045                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,0); p.lineTo(20,0); p.lineTo(20,-15); p.lineTo(-20,-15); p.closePath();
    1046                 NoticeBoard.add(new Instr(Form.FILL, Color.white));
    1047                 NoticeBoard.add(new Instr(Form.PGON, p));
    1048                 NoticeBoard.add(new Instr(Form.FILL, Color.black));
    1049                 NoticeBoard.add(new Instr(Form.PLIN, p));
    1050         }
    1051         public static final Symbol NoticeTriangle = new Symbol();
    1052         static {
    1053                 NoticeTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,30)));
    1054                 NoticeTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1055                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,0); p.lineTo(20,0); p.lineTo(0,-15); p.closePath();
    1056                 NoticeTriangle.add(new Instr(Form.FILL, Color.white));
    1057                 NoticeTriangle.add(new Instr(Form.PGON, p));
    1058                 NoticeTriangle.add(new Instr(Form.FILL, Color.black));
    1059                 NoticeTriangle.add(new Instr(Form.PLIN, p));
    1060         }
    1061 
    1062         public static final EnumMap<CatNMK, Symbol> NmkCevni = new EnumMap<>(CatNMK.class);
    1063         static {
    1064                 NmkCevni.put(CatNMK.NMK_UNKN, Notice); NmkCevni.put(CatNMK.NMK_NENT, NoticeA1); NmkCevni.put(CatNMK.NMK_CLSA, NoticeA1a); NmkCevni.put(CatNMK.NMK_NOVK, NoticeA2);
    1065                 NmkCevni.put(CatNMK.NMK_NCOV, NoticeA3); NmkCevni.put(CatNMK.NMK_NPAS, NoticeA4); NmkCevni.put(CatNMK.NMK_NCPS, NoticeA4_1); NmkCevni.put(CatNMK.NMK_NBRT, NoticeA5);
    1066                 NmkCevni.put(CatNMK.NMK_NBLL, NoticeA5_1); NmkCevni.put(CatNMK.NMK_NANK, NoticeA6); NmkCevni.put(CatNMK.NMK_NMOR, NoticeA7); NmkCevni.put(CatNMK.NMK_NTRN, NoticeA8);
    1067                 NmkCevni.put(CatNMK.NMK_NWSH, NoticeA9); NmkCevni.put(CatNMK.NMK_NPSL, NoticeA10a); NmkCevni.put(CatNMK.NMK_NPSR, NoticeA10b); NmkCevni.put(CatNMK.NMK_NMTC, NoticeA12);
    1068                 NmkCevni.put(CatNMK.NMK_NSPC, NoticeA13); NmkCevni.put(CatNMK.NMK_NWSK, NoticeA14); NmkCevni.put(CatNMK.NMK_NSLC, NoticeA15); NmkCevni.put(CatNMK.NMK_NUPC, NoticeA16);
    1069                 NmkCevni.put(CatNMK.NMK_NSLB, NoticeA17); NmkCevni.put(CatNMK.NMK_NWBK, NoticeA20); NmkCevni.put(CatNMK.NMK_NHSC, NoticeA18); NmkCevni.put(CatNMK.NMK_NLBG, NoticeA19);
    1070                 NmkCevni.put(CatNMK.NMK_MVTL, NoticeB1a); NmkCevni.put(CatNMK.NMK_MVTR, NoticeB1b); NmkCevni.put(CatNMK.NMK_MVTP, NoticeB2a); NmkCevni.put(CatNMK.NMK_MVTS, NoticeB2b);
    1071                 NmkCevni.put(CatNMK.NMK_KPTP, NoticeB3a); NmkCevni.put(CatNMK.NMK_KPTS, NoticeB3b); NmkCevni.put(CatNMK.NMK_CSTP, NoticeB4a); NmkCevni.put(CatNMK.NMK_CSTS, NoticeB4b);
    1072                 NmkCevni.put(CatNMK.NMK_STOP, NoticeB5); NmkCevni.put(CatNMK.NMK_SPDL, NoticeB6); NmkCevni.put(CatNMK.NMK_SHRN, NoticeB7); NmkCevni.put(CatNMK.NMK_KPLO, NoticeB8);
    1073                 NmkCevni.put(CatNMK.NMK_GWJN, NoticeB9a); NmkCevni.put(CatNMK.NMK_GWCS, NoticeB9b); NmkCevni.put(CatNMK.NMK_MKRC, NoticeB11);
    1074                 NmkCevni.put(CatNMK.NMK_LMDP, NoticeC1); NmkCevni.put(CatNMK.NMK_LMHR, NoticeC2);       NmkCevni.put(CatNMK.NMK_LMWD, NoticeC3); NmkCevni.put(CatNMK.NMK_NAVR, NoticeC4);
    1075                 NmkCevni.put(CatNMK.NMK_CHDL, NoticeC5a); NmkCevni.put(CatNMK.NMK_CHDR, NoticeC5b);
    1076                 NmkCevni.put(CatNMK.NMK_CHTW, NoticeD1a); NmkCevni.put(CatNMK.NMK_CHOW, NoticeD1b); NmkCevni.put(CatNMK.NMK_OPTR, NoticeD2a); NmkCevni.put(CatNMK.NMK_OPTL, NoticeD2b);
    1077                 NmkCevni.put(CatNMK.NMK_PRTL, NoticeD3a); NmkCevni.put(CatNMK.NMK_PRTR, NoticeD3b);
    1078                 NmkCevni.put(CatNMK.NMK_ENTP, NoticeE1); NmkCevni.put(CatNMK.NMK_OVHC, NoticeE2);       NmkCevni.put(CatNMK.NMK_WEIR, NoticeE3); NmkCevni.put(CatNMK.NMK_FERN, NoticeE4a);
    1079                 NmkCevni.put(CatNMK.NMK_FERI, NoticeE4b); NmkCevni.put(CatNMK.NMK_BRTP, NoticeE5);      NmkCevni.put(CatNMK.NMK_BTLL, NoticeE5_1); NmkCevni.put(CatNMK.NMK_BTLS, NoticeE5_2);
    1080                 NmkCevni.put(CatNMK.NMK_BTRL, NoticeE5_3); NmkCevni.put(CatNMK.NMK_BTUP, NoticeE5_4);   NmkCevni.put(CatNMK.NMK_BTP1, NoticeE5_5); NmkCevni.put(CatNMK.NMK_BTP2, NoticeE5_6);
    1081                 NmkCevni.put(CatNMK.NMK_BTP3, NoticeE5_7); NmkCevni.put(CatNMK.NMK_BTUN, NoticeE5_8);   NmkCevni.put(CatNMK.NMK_BTN1, NoticeE5_9); NmkCevni.put(CatNMK.NMK_BTN2, NoticeE5_10);
    1082                 NmkCevni.put(CatNMK.NMK_BTN3, NoticeE5_11); NmkCevni.put(CatNMK.NMK_BTUM, NoticeE5_12); NmkCevni.put(CatNMK.NMK_BTU1, NoticeE5_13); NmkCevni.put(CatNMK.NMK_BTU2, NoticeE5_14);
    1083                 NmkCevni.put(CatNMK.NMK_BTU3, NoticeE5_15); NmkCevni.put(CatNMK.NMK_ANKP, NoticeE6);    NmkCevni.put(CatNMK.NMK_MORP, NoticeE7); NmkCevni.put(CatNMK.NMK_VLBT, NoticeE7_1);
    1084                 NmkCevni.put(CatNMK.NMK_TRNA, NoticeE8); NmkCevni.put(CatNMK.NMK_SWWC, NoticeE9a);      NmkCevni.put(CatNMK.NMK_SWWR, NoticeE9b); NmkCevni.put(CatNMK.NMK_SWWL, NoticeE9c);
    1085                 NmkCevni.put(CatNMK.NMK_WRSA, NoticeE9d); NmkCevni.put(CatNMK.NMK_WLSA, NoticeE9e);     NmkCevni.put(CatNMK.NMK_WRSL, NoticeE9f); NmkCevni.put(CatNMK.NMK_WLSR, NoticeE9g);
    1086                 NmkCevni.put(CatNMK.NMK_WRAL, NoticeE9h); NmkCevni.put(CatNMK.NMK_WLAR, NoticeE9i);     NmkCevni.put(CatNMK.NMK_MWWC, NoticeE10a); NmkCevni.put(CatNMK.NMK_MWWJ, NoticeE10b);
    1087                 NmkCevni.put(CatNMK.NMK_MWAR, NoticeE10c); NmkCevni.put(CatNMK.NMK_MWAL, NoticeE10d);   NmkCevni.put(CatNMK.NMK_WARL, NoticeE10e); NmkCevni.put(CatNMK.NMK_WALR, NoticeE10f);
    1088                 NmkCevni.put(CatNMK.NMK_PEND, NoticeE11); NmkCevni.put(CatNMK.NMK_DWTR, NoticeE13);     NmkCevni.put(CatNMK.NMK_TELE, NoticeE14); NmkCevni.put(CatNMK.NMK_MTCP, NoticeE15);
    1089                 NmkCevni.put(CatNMK.NMK_SPCP, NoticeE16); NmkCevni.put(CatNMK.NMK_WSKP, NoticeE17);     NmkCevni.put(CatNMK.NMK_SLCP, NoticeE18); NmkCevni.put(CatNMK.NMK_UPCP, NoticeE19);
    1090                 NmkCevni.put(CatNMK.NMK_SLBP, NoticeE20); NmkCevni.put(CatNMK.NMK_RADI, NoticeE23);     NmkCevni.put(CatNMK.NMK_WTBP, NoticeE24); NmkCevni.put(CatNMK.NMK_HSCP, NoticeE21);
    1091                 NmkCevni.put(CatNMK.NMK_LBGP, NoticeE22);
    1092   };
    1093 
    1094   private static final Symbol NoticeBB = new Symbol();
    1095   static {
    1096         NoticeBB.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1097         NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(-29,-29,-29,29)));
    1098         NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(29,-29,29,29)));
    1099         NoticeBB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1100         NoticeBB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1101   }
    1102  
    1103   private static final Symbol NoticeBP = new Symbol();
    1104         static {
    1105                 NoticeBP.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1106                 NoticeBP.add(new Instr(Form.FILL, Color.white));
    1107                 NoticeBP.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1108                 NoticeBP.add(new Instr(Form.FILL, Color.black));
    1109                 NoticeBP.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1110         }
    1111 
    1112   private static final Symbol NoticeCR = new Symbol();
    1113         static {
    1114                 NoticeCR.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1115                 NoticeCR.add(new Instr(Form.FILL, Color.white));
    1116                 Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
    1117                 NoticeCR.add(new Instr(Form.PGON, p));
    1118                 NoticeCR.add(new Instr(Form.FILL, Color.black));
    1119                 NoticeCR.add(new Instr(Form.PLIN, p));
    1120         }
    1121 
    1122   private static final Symbol NoticeKT = new Symbol();
    1123         static {
    1124                 NoticeKT.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1125                 NoticeKT.add(new Instr(Form.FILL, Color.white));
    1126                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
    1127                 NoticeKT.add(new Instr(Form.PGON, p));
    1128                 NoticeKT.add(new Instr(Form.FILL, Color.black));
    1129                 NoticeKT.add(new Instr(Form.PLIN, p));
    1130         }
    1131 
    1132         public static final Symbol NoticeBnank = new Symbol();
    1133         static {
    1134                 NoticeBnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1135                 Symbol colours = new Symbol();
    1136                 Symbol ss = new Symbol();
    1137                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1138                 colours.add(new Instr(Form.N1, ss));
    1139                 ss = new Symbol();
    1140                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
    1141                 ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    1142                 ss.add(new Instr(Form.LINE, new Line2D.Double(-27,-27,27,27)));
    1143                 ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1144                 ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1145                 colours.add(new Instr(Form.N2, ss));
    1146                 NoticeBnank.add(new Instr(Form.COLR, colours));
    1147         }
    1148         public static final Symbol NoticeBlmhr = new Symbol();
    1149         static {
    1150                 NoticeBlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1151                 Symbol colours = new Symbol();
    1152                 Symbol ss = new Symbol();
    1153                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1154                 colours.add(new Instr(Form.N1, ss));
    1155                 ss = new Symbol();
    1156                 ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    1157                 Path2D.Double p = new Path2D.Double(); p.moveTo(-29,-29); p.lineTo(29,-29); p.lineTo(0,0); p.closePath();
    1158                 ss.add(new Instr(Form.PGON, p));
    1159                 ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1160                 ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1161                 colours.add(new Instr(Form.N2, ss));
    1162                 NoticeBlmhr.add(new Instr(Form.COLR, colours));
    1163         }
    1164         public static final Symbol NoticeBktpm = new Symbol();
    1165         static {
    1166                 NoticeBktpm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1167                 Symbol colours = new Symbol();
    1168                 Symbol ss = new Symbol();
    1169                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1170                 colours.add(new Instr(Form.N1, ss));
    1171                 ss = new Symbol();
    1172                 Path2D.Double p = new Path2D.Double(); p.moveTo(-14,-26); p.lineTo(-20,-12); p.lineTo(-8,-12); p.closePath();
    1173                 ss.add(new Instr(Form.PGON, p));
    1174         ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1175         ss.add(new Instr(Form.LINE, new Line2D.Double(-14,-16,-14,25)));
    1176                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1177                 colours.add(new Instr(Form.N2, ss));
    1178                 NoticeBktpm.add(new Instr(Form.COLR, colours));
    1179         }
    1180         public static final Symbol NoticeBktsm = new Symbol();
    1181         static {
    1182                 NoticeBktsm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1183                 Symbol colours = new Symbol();
    1184                 Symbol ss = new Symbol();
    1185                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1186                 colours.add(new Instr(Form.N1, ss));
    1187                 ss = new Symbol();
    1188                 Path2D.Double p = new Path2D.Double(); p.moveTo(14,-26); p.lineTo(20,-12); p.lineTo(8,-12); p.closePath();
    1189                 ss.add(new Instr(Form.PGON, p));
    1190         ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1191         ss.add(new Instr(Form.LINE, new Line2D.Double(14,-16,14,25)));
    1192                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1193                 colours.add(new Instr(Form.N2, ss));
    1194                 NoticeBktsm.add(new Instr(Form.COLR, colours));
    1195         }
    1196         public static final Symbol NoticeBktmr = new Symbol();
    1197         static {
    1198                 NoticeBktmr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1199                 Symbol colours = new Symbol();
    1200                 Symbol ss = new Symbol();
    1201                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1202                 colours.add(new Instr(Form.N1, ss));
    1203                 ss = new Symbol();
    1204                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-26); p.lineTo(-6,-12); p.lineTo(6,-12); p.closePath();
    1205                 ss.add(new Instr(Form.PGON, p));
    1206         ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1207         ss.add(new Instr(Form.LINE, new Line2D.Double(0,-16,0,25)));
    1208                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1209                 colours.add(new Instr(Form.N2, ss));
    1210                 NoticeBktmr.add(new Instr(Form.COLR, colours));
    1211         }
    1212         public static final Symbol NoticeBcrtp = new Symbol();
    1213         static {
    1214                 NoticeBcrtp.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1215                 Symbol colours = new Symbol();
    1216                 Symbol ss = new Symbol();
    1217                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1218                 colours.add(new Instr(Form.N1, ss));
    1219                 ss = new Symbol();
    1220                 Path2D.Double p = new Path2D.Double(); p.moveTo(-14,-26); p.lineTo(-20,-12); p.lineTo(-8,-12); p.closePath();
    1221                 ss.add(new Instr(Form.PGON, p));
    1222         ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1223                 p = new Path2D.Double(); p.moveTo(-14,-16); p.lineTo(-14,0); p.lineTo(14,10); p.lineTo(14,25);
    1224                 ss.add(new Instr(Form.PLIN, p));
    1225                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1226                 colours.add(new Instr(Form.N2, ss));
    1227                 NoticeBcrtp.add(new Instr(Form.COLR, colours));
    1228         }
    1229         public static final Symbol NoticeBcrts = new Symbol();
    1230         static {
    1231                 NoticeBcrts.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1232                 Symbol colours = new Symbol();
    1233                 Symbol ss = new Symbol();
    1234                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1235                 colours.add(new Instr(Form.N1, ss));
    1236                 ss = new Symbol();
    1237                 Path2D.Double p = new Path2D.Double(); p.moveTo(14,-26); p.lineTo(20,-12); p.lineTo(8,-12); p.closePath();
    1238                 ss.add(new Instr(Form.PGON, p));
    1239         ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1240                 p = new Path2D.Double(); p.moveTo(14,-16); p.lineTo(14,0); p.lineTo(-14,10); p.lineTo(-14,25);
    1241                 ss.add(new Instr(Form.PLIN, p));
    1242                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1243                 colours.add(new Instr(Form.N2, ss));
    1244                 NoticeBcrts.add(new Instr(Form.COLR, colours));
    1245         }
    1246         public static final Symbol NoticeBtrbm = new Symbol();
    1247         static {
    1248                 NoticeBtrbm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1249                 Symbol colours = new Symbol();
    1250                 Symbol ss = new Symbol();
    1251                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1252                 colours.add(new Instr(Form.N1, ss));
    1253                 ss = new Symbol();
    1254         ss.add(new Instr(Form.STRK, new BasicStroke(15, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1255         ss.add(new Instr(Form.LINE, new Line2D.Double(0,-25,0,25)));
    1256         ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1257         ss.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
    1258                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1259                 colours.add(new Instr(Form.N2, ss));
    1260                 NoticeBtrbm.add(new Instr(Form.COLR, colours));
    1261         }
    1262         public static final Symbol NoticeBrspd = new Symbol();
    1263         static {
    1264                 NoticeBrspd.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1265                 Symbol colours = new Symbol();
    1266                 Symbol ss = new Symbol();
    1267                 ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1268                 colours.add(new Instr(Form.N1, ss));
    1269                 ss = new Symbol();
    1270                 ss.add(new Instr(Form.TEXT, new Caption("R", new Font("Arial", Font.BOLD, 60), null, new Delta(Handle.CC, null))));
    1271                 ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
    1272                 colours.add(new Instr(Form.N2, ss));
    1273                 NoticeBrspd.add(new Instr(Form.COLR, colours));
    1274         }
    1275         static final Symbol NoticePBwral = new Symbol();
    1276         static {
    1277                 NoticePBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1278                 NoticePBwral.add(new Instr(Form.FILL, new Color(0xffff00)));
    1279                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20,-25); p.lineTo(-8,-5); p.lineTo(-8,25); p.lineTo(8,25); p.lineTo(8,-5);
    1280                 p.lineTo(20,-25); p.lineTo(5,-25); p.lineTo(-5,-10); p.lineTo(-15,-25); p.closePath();
    1281                 NoticePBwral.add(new Instr(Form.PGON, p));
    1282         }
    1283         public static final Symbol NoticeBwral = new Symbol();
    1284         static {
    1285                 NoticeBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1286                 NoticeBwral.add(new Instr(Form.FILL, Color.black));
    1287                 NoticeBwral.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1288                 NoticeBwral.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, null)));
    1289         }
    1290         public static final Symbol NoticeBwlar = new Symbol();
    1291         static {
    1292                 NoticeBwlar.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1293                 NoticeBwlar.add(new Instr(Form.FILL, Color.black));
    1294                 NoticeBwlar.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
    1295                 NoticeBwlar.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getScaleInstance(-1, 1)))));
    1296         }
    1297         public static final Symbol NoticeBoptr = new Symbol();
    1298         static {
    1299                 NoticeBoptr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1300                 NoticeBoptr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
    1301                 NoticeBoptr.add(new Instr(Form.FILL, new Color(0x00a000)));
    1302                 NoticeBoptr.add(new Instr(Form.RSHP, new Rectangle2D.Double(-20,-20,40,40)));
    1303         }
    1304         public static final Symbol NoticeBoptl = new Symbol();
    1305         static {
    1306                 NoticeBoptl.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1307                 NoticeBoptl.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
    1308                 NoticeBoptl.add(new Instr(Form.FILL, new Color(0xf00000)));
    1309                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-20); p.lineTo(-20,20); p.lineTo(20,20); p.closePath();
    1310                 NoticeBoptl.add(new Instr(Form.PGON, p));
    1311         }
    1312         public static final EnumMap<CatNMK, Symbol> NmkBniwr = new EnumMap<>(CatNMK.class);
    1313         static {
    1314                 NmkBniwr.put(CatNMK.NMK_NANK, NoticeBnank); NmkBniwr.put(CatNMK.NMK_LMHR, NoticeBlmhr); NmkBniwr.put(CatNMK.NMK_OPTR, NoticeBoptr); NmkBniwr.put(CatNMK.NMK_OPTL, NoticeBoptl);
    1315                 NmkBniwr.put(CatNMK.NMK_WRAL, NoticeBwral); NmkBniwr.put(CatNMK.NMK_WLAR, NoticeBwlar); NmkBniwr.put(CatNMK.NMK_KTPM, NoticeBktpm); NmkBniwr.put(CatNMK.NMK_KTSM, NoticeBktsm);
    1316                 NmkBniwr.put(CatNMK.NMK_KTMR, NoticeBktmr); NmkBniwr.put(CatNMK.NMK_CRTP, NoticeBcrtp); NmkBniwr.put(CatNMK.NMK_CRTS, NoticeBcrts); NmkBniwr.put(CatNMK.NMK_TRBM, NoticeBtrbm);
    1317                 NmkBniwr.put(CatNMK.NMK_RSPD, NoticeBrspd);
    1318         }
    1319         public static final Symbol NoticePwralL = new Symbol();
    1320         static {
    1321                 NoticePwralL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1322                 NoticePwralL.add(new Instr(Form.FILL, Color.black));
    1323                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
    1324                 NoticePwralL.add(new Instr(Form.PGON, p));
    1325                 NoticePwralL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.TC, AffineTransform.getScaleInstance(0.5, 0.5)))));
    1326         }
    1327         public static final Symbol NoticePwralR = new Symbol();
    1328         static {
    1329                 NoticePwralR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1330                 NoticePwralR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwral, 1.0, 0, 0, null, null)));
    1331         }
    1332         public static final Symbol NoticePwlarL = new Symbol();
    1333         static {
    1334                 NoticePwlarL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1335                 NoticePwlarL.add(new Instr(Form.FILL, Color.black));
    1336                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
    1337                 NoticePwlarL.add(new Instr(Form.PGON, p));
    1338                 NoticePwlarL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.TC, AffineTransform.getScaleInstance(-0.5, 0.5)))));
    1339         }
    1340         public static final Symbol NoticePwlarR = new Symbol();
    1341         static {
    1342                 NoticePwlarR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1343                 NoticePwlarR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwlar, 1.0, 0, 0, null, null)));
    1344         }
    1345         public static final Symbol NoticePktmR = new Symbol();
    1346         static {
    1347                 NoticePktmR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1348                 NoticePktmR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
    1349                 NoticePktmR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1350                 NoticePktmR.add(new Instr(Form.FILL, new Color(0x00d400)));
    1351                 NoticePktmR.add(new Instr(Form.RECT, new Rectangle2D.Double(-20,-20,40,40)));
    1352         }
    1353         public static final Symbol NoticePktmL = new Symbol();
    1354         static {
    1355                 NoticePktmL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1356                 NoticePktmL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
    1357                 NoticePktmL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1358                 NoticePktmL.add(new Instr(Form.FILL, new Color(0xd40000)));
    1359                 NoticePktmL.add(new Instr(Form.RECT, new Rectangle2D.Double(-12,2,24,24)));
    1360         }
    1361         public static final Symbol NoticePktmrL = new Symbol();
    1362         static {
    1363                 NoticePktmrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1364                 NoticePktmrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
    1365                 NoticePktmrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1366                 NoticePktmrL.add(new Instr(Form.FILL, new Color(0xd40000)));
    1367                 NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12,2,-12,28)));
    1368                 NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(12,2,12,28)));
    1369                 NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12,15,12,15)));
    1370         }
    1371         public static final Symbol NoticePktmrR = new Symbol();
    1372         static {
    1373                 NoticePktmrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1374                 NoticePktmrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
    1375                 NoticePktmrR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1376                 NoticePktmrR.add(new Instr(Form.FILL, new Color(0x00d400)));
    1377                 NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15,-20,-15,20)));
    1378                 NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(15,-20,15,20)));
    1379                 NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15,0,15,0)));
    1380         }
    1381         public static final Symbol NoticePcrL = new Symbol();
    1382         static {
    1383                 NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1384                 NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1385                 NoticePcrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
    1386                 NoticePcrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1387                 NoticePcrL.add(new Instr(Form.FILL, new Color(0xd40000)));
    1388                 NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,12,12)));
    1389                 NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12,12,12,-12)));
    1390         }
    1391         public static final Symbol NoticePcrR = new Symbol();
    1392         static {
    1393                 NoticePcrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1394                 NoticePcrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
    1395                 NoticePcrR.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1396                 NoticePcrR.add(new Instr(Form.FILL, new Color(0x00d400)));
    1397                 NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,12,12)));
    1398                 NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12,12,12,-12)));
    1399         }
    1400         static final Symbol NoticeRphib = new Symbol();
    1401         static {
    1402                 NoticeRphib.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1403                 NoticeRphib.add(new Instr(Form.FILL, new Color(0xd40000)));
    1404                 NoticeRphib.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
    1405                 NoticeRphib.add(new Instr(Form.LINE, new Line2D.Double(-20,-20,20,20)));
    1406         }
    1407         static final Symbol NoticeRinfo = new Symbol();
    1408         static {
    1409                 NoticeRinfo.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1410                 NoticeRinfo.add(new Instr(Form.FILL, new Color(0xd40000)));
    1411                 NoticeRinfo.add(new Instr(Form.RECT, new Rectangle2D.Double(-30,-30,60,60)));
    1412         }
    1413         public static final Symbol NoticeRnpas = new Symbol();
    1414         static {
    1415                 NoticeRnpas.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1416                 NoticeRnpas.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
    1417                 NoticeRnpas.add(new Instr(Form.FILL, Color.black));
    1418                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,-15); p.lineTo(-10,8); p.lineTo(-6,8); p.lineTo(-12.5,16); p.lineTo(-19,8); p.lineTo(-15,8); p.lineTo(-15,-15);
    1419                 p.closePath(); p.moveTo(10,15); p.lineTo(10,-8); p.lineTo(6,-8); p.lineTo(12.5,-16); p.lineTo(19,-8); p.lineTo(15,-8); p.lineTo(15,15); p.closePath();
    1420                 NoticeRnpas.add(new Instr(Form.PGON, p));
    1421         }
    1422         public static final Symbol NoticeRnank = new Symbol();
    1423         static {
    1424                 NoticeRnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1425                 NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
    1426                 NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), null)));
    1427         }
    1428         public static final Symbol NoticeRnwsh = new Symbol();
    1429         static {
    1430                 NoticeRnwsh.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1431                 NoticeRnwsh.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
    1432                 NoticeRnwsh.add(new Instr(Form.FILL, Color.black));
    1433                 Path2D.Double p = new Path2D.Double(); p.moveTo(-23,10); p.curveTo(-11,10,-12,4,0,4); p.curveTo(12,4,11,10,23,10);
    1434                 p.moveTo(-23,-3); p.curveTo(-11,-3,-12,-9,0,-9); p.curveTo(12,-9,11,-3,23,-3);
    1435                 NoticeRnwsh.add(new Instr(Form.PLIN, p));
    1436         }
    1437         public static final Symbol NoticeRlmhr = new Symbol();
    1438         static {
    1439                 NoticeRlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1440                 NoticeRlmhr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
    1441                 NoticeRlmhr.add(new Instr(Form.FILL, Color.black));
    1442                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-10); p.lineTo(27,-27); p.lineTo(-27,-27); p.closePath();
    1443                 NoticeRlmhr.add(new Instr(Form.PGON, p));
    1444         }
    1445         public static final Symbol NoticeRtrna = new Symbol();
    1446         static {
    1447                 NoticeRtrna.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1448                 NoticeRtrna.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
    1449                 NoticeRtrna.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1450                 NoticeRtrna.add(new Instr(Form.EARC, new Arc2D.Double(-15.0,-15.0,30.0,30.0,315.0,-280.0,Arc2D.OPEN)));
    1451                 Path2D.Double p = new Path2D.Double(); p.moveTo(18.8,-2.0); p.lineTo(15.8,-13.2); p.lineTo(7.5,-5.0); p.closePath();
    1452                 NoticeRtrna.add(new Instr(Form.PGON, p));
    1453         }
    1454         public static final Symbol NoticeRncps = new Symbol();
    1455         static {
    1456                 NoticeRncps.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1457                 NoticeRncps.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
    1458                 NoticeRncps.add(new Instr(Form.FILL, Color.black));
    1459                 Path2D.Double p = new Path2D.Double(); p.moveTo(-10,0); p.lineTo(-10,8); p.lineTo(-6,8); p.lineTo(-12.5,16); p.lineTo(-19,8); p.lineTo(-15,8); p.lineTo(-15,0);
    1460                 p.closePath(); p.moveTo(10,0); p.lineTo(10,-8); p.lineTo(6,-8); p.lineTo(12.5,-16); p.lineTo(19,-8); p.lineTo(15,-8); p.lineTo(15,0); p.closePath();
    1461                 NoticeRncps.add(new Instr(Form.PGON, p));
    1462         }
    1463         public static final Symbol NoticeRnsmc = new Symbol();
    1464         static {
    1465                 NoticeRnsmc.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1466                 NoticeRnsmc.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
    1467                 NoticeRnsmc.add(new Instr(Form.FILL, Color.black));
    1468                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15,5); p.lineTo(15,5); p.lineTo(25,-10); p.lineTo(12,-5); p.lineTo(-18,-1); p.closePath();
    1469                 p.moveTo(-23,2); p.lineTo(-21,10); p.lineTo(-18,8); p.lineTo(-20,0); p.closePath();
    1470                 NoticeRnsmc.add(new Instr(Form.PGON, p));
    1471         }
    1472         public static final Symbol NoticeRattn = new Symbol();
    1473         static {
    1474                 NoticeRattn.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1475                 NoticeRattn.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
    1476                 NoticeRattn.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    1477                 NoticeRattn.add(new Instr(Form.FILL, Color.black));
    1478                 NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,10)));
    1479                 NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0,15,0,20)));
    1480         }
    1481         public static final Symbol NoticeRfwcr = new Symbol();
    1482         static {
    1483                 NoticeRfwcr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1484                 NoticeRfwcr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
    1485                 NoticeRfwcr.add(new Instr(Form.FILL, Color.black));
    1486                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(-8,-15); p.lineTo(-8,5); p.lineTo(-20,5); p.lineTo(-20,15); p.lineTo(-8,15); p.lineTo(-8,25);
    1487                 p.lineTo(8,25); p.lineTo(8,15); p.lineTo(20,15); p.lineTo(20,5); p.lineTo(8,5); p.lineTo(8,-15); p.closePath();
    1488                 NoticeRfwcr.add(new Instr(Form.PGON, p));
    1489         }
    1490         public static final Symbol NoticeRship = new Symbol();
    1491         static {
    1492                 NoticeRship.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
    1493                 NoticeRship.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
    1494                 NoticeRship.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
    1495                 NoticeRship.add(new Instr(Form.FILL, Color.black));
    1496                 NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,10,10)));
    1497                 NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12,-8,-8,-12)));
    1498                 NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12,-12,-10,10)));
    1499                 NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12,-8,8,-12)));
    1500                 NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-17,-13,30,30,185,80,Arc2D.OPEN)));
    1501                 NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-13,-13,30,30,275,80,Arc2D.OPEN)));
    1502         }
    1503 
    1504         public static final EnumMap<CatNMK, Symbol> NmkPpwbcl = new EnumMap<>(CatNMK.class);
    1505         static {
    1506                 NmkPpwbcl.put(CatNMK.NMK_WRAL, NoticePwralL); NmkPpwbcl.put(CatNMK.NMK_WLAR, NoticePwlarL); NmkPpwbcl.put(CatNMK.NMK_KTPM, NoticePktmL); NmkPpwbcl.put(CatNMK.NMK_KTSM, NoticePktmL);
    1507                 NmkPpwbcl.put(CatNMK.NMK_KTMR, NoticePktmrL); NmkPpwbcl.put(CatNMK.NMK_CRTP, NoticePcrL); NmkPpwbcl.put(CatNMK.NMK_CRTS, NoticePcrL);
    1508         }
    1509        
    1510         public static final EnumMap<CatNMK, Symbol> NmkPpwbcr = new EnumMap<>(CatNMK.class);
    1511         static {
    1512                 NmkPpwbcr.put(CatNMK.NMK_WRAL, NoticePwralR); NmkPpwbcr.put(CatNMK.NMK_WLAR, NoticePwlarR); NmkPpwbcr.put(CatNMK.NMK_KTPM, NoticePktmR); NmkPpwbcr.put(CatNMK.NMK_KTSM, NoticePktmR);
    1513                 NmkPpwbcr.put(CatNMK.NMK_KTMR, NoticePktmrR); NmkPpwbcr.put(CatNMK.NMK_CRTP, NoticePcrR); NmkPpwbcr.put(CatNMK.NMK_CRTS, NoticePcrR);
    1514         }
    1515        
    1516         public static final EnumMap<CatNMK, Symbol> NmkRiwr = new EnumMap<>(CatNMK.class);
    1517         static {
    1518                 NmkRiwr.put(CatNMK.NMK_NPAS, NoticeRnpas); NmkRiwr.put(CatNMK.NMK_NANK, NoticeRnank); NmkRiwr.put(CatNMK.NMK_NWSH, NoticeRnwsh); NmkRiwr.put(CatNMK.NMK_LMHR, NoticeRlmhr); NmkRiwr.put(CatNMK.NMK_TRNA, NoticeRtrna);
    1519                 NmkRiwr.put(CatNMK.NMK_NCPS, NoticeRncps); NmkRiwr.put(CatNMK.NMK_NSMC, NoticeRnsmc); NmkRiwr.put(CatNMK.NMK_ATTN, NoticeRattn); NmkRiwr.put(CatNMK.NMK_FWCR, NoticeRfwcr); NmkRiwr.put(CatNMK.NMK_SHIP, NoticeRship);
    1520         }
    1521        
    1522         public static Scheme getScheme(MarSYS sys, BnkWTW bank) {
    1523                 ArrayList<Color> colours = new ArrayList<>();
    1524                 Scheme scheme = new Scheme(colours);
    1525                 switch (sys) {
    1526                 case SYS_BNWR:
    1527                 case SYS_BWR2:
    1528                         switch (bank) {
    1529                         case BWW_LEFT:
    1530                                 colours.add(Color.white);
    1531                                 colours.add(new Color(0xf00000));
    1532                                 break;
    1533                         case BWW_RGHT:
    1534                                 colours.add(Color.white);
    1535                                 colours.add(new Color(0x00a000));
    1536                                 break;
    1537                         default:
    1538                                 colours.add(new Color(0xff8040));
    1539                                 colours.add(Color.black);
    1540                                 break;
    1541                         }
    1542                         break;
    1543                 default:
    1544                         break;
    1545                 }
    1546                 return scheme;
    1547         }
    1548        
    1549         public static Symbol getNotice(CatNMK cat, MarSYS sys, BnkWTW bank) {
    1550                 Symbol symbol = null;
    1551                 switch (sys) {
    1552                 case SYS_CEVN:
    1553                         symbol = NmkCevni.get(cat);
    1554                         break;
    1555                 case SYS_BNWR:
    1556                 case SYS_BWR2:
    1557                         symbol = NmkBniwr.get(cat);
    1558                         break;
    1559                 case SYS_PPWB:
    1560                         switch (bank) {
    1561                         case BWW_LEFT:
    1562                                 symbol = NmkPpwbcl.get(cat);
    1563                                 break;
    1564                         case BWW_RGHT:
    1565                                 symbol = NmkPpwbcr.get(cat);
    1566                                 break;
    1567                         default:
    1568                                 break;
    1569                         }
    1570                         break;
    1571                 case SYS_RIWR:
    1572                         symbol = NmkRiwr.get(cat);
    1573                         break;
    1574                 default:
    1575                         break;
    1576                 }
    1577                 return symbol;
    1578         }
     38    // CHECKSTYLE.OFF: LineLength
     39    private static final Symbol Bollard = new Symbol();
     40    static {
     41        Path2D.Double p = new Path2D.Double(); p.moveTo(20, 21); p.lineTo(20, 16.5); p.lineTo(11.6, 16.5); p.quadTo(9.1, 9.6, 8.3, 2.0); p.lineTo(-8.0, -0.3); p.quadTo(-8.6, 9.0, -11.3, 16.5);
     42        p.lineTo(-23.5, 16.5); p.lineTo(-23.5, 21.0); p.closePath(); p.moveTo(23.8, 3.0); p.lineTo(-10.7, -1.8); p.curveTo(-13.1, -2.2, -12.8, -6.0, -10.2, -5.8); p.lineTo(23.8, -1.1);
     43        p.closePath(); p.moveTo(8.4, -4.3); p.curveTo(9.0, -9.3, 9.0, -11.4, 11.2, -13.0); p.curveTo(12.8, -15.0, 12.8, -16.7, 11.0, -18.6); p.curveTo(4.0, -22.2, -4.0, -22.2, -11.0, -18.6);
     44        p.curveTo(-12.8, -16.7, -12.8, -15.0, -11.2, -13.0); p.curveTo(-9.0, -11.3, -8.7, -9.5, -8.4, -6.5); p.closePath();
     45        Bollard.add(new Instr(Form.PGON, p));
     46    }
     47
     48    private static final Symbol Motor = new Symbol();
     49    static {
     50        Path2D.Double p = new Path2D.Double(); p.moveTo(-5.0, 4.3); p.curveTo(-3.7, 5.5, -1.8, 5.7, -0.2, 4.9); p.curveTo(1.3, 8.7, 4.6, 10.9, 8.4, 10.9); p.curveTo(14.0, 10.9, 17.5, 6.3, 17.5, 2.0);
     51        p.curveTo(17.5, -0.7, 16.1, -3.2, 14.5, -3.2); p.curveTo(12.5, -3.2, 11.7, 0.8, 2.5, 1.1); p.curveTo(2.5, -1.2, 1.6, -2.2, 0.6, -3.0); p.curveTo(3.2, -5.6, 4.0, -12.6, -1.0, -16.1);
     52        p.curveTo(-5.3, -19.2, -11.6, -18.3, -13.7, -13.7); p.curveTo(-14.3, -12.2, -14.0, -11.2, -12.5, -10.6); p.curveTo(-8.6, -9.6, -5.3, -6.0, -4.0, -3.4); p.curveTo(-5.4, -2.6, -6.2, -2.0, -6.2, 0.2);
     53        p.curveTo(-12.8, -1.0, -17.5, 3.7, -17.5, 9.3); p.curveTo(-17.5, 14.7, -12.6, 18.8, -8.0, 17.6); p.curveTo(-7.0, 17.2, -6.6, 16.2, -7.2, 14.6); p.curveTo(-7.7, 12.4, -7.0, 7.7, -5.0, 4.3); p.closePath();
     54        Motor.add(new Instr(Form.PGON, p));
     55    }
     56
     57    private static final Symbol Rowboat = new Symbol();
     58    static {
     59        Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5, -2.0); p.lineTo(17.5, -2.0); p.lineTo(15.0, 6.0); p.lineTo(-11.0, 6.0); p.closePath();
     60        Rowboat.add(new Instr(Form.PGON, p));
     61        Rowboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-6, -17.5, 6, 6)));
     62        Rowboat.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     63        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5, -9, -8, 0)));
     64        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.0, 10.0, -7.5, 14.0)));
     65        Rowboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     66        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5, -9, 7, -6.5)));
     67        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(7.3, -7.8, -5.0, 10.0)));
     68    }
     69
     70    private static final Symbol Sailboard = new Symbol();
     71    static {
     72        Path2D.Double p = new Path2D.Double(); p.moveTo(-6.0, 19.0); p.quadTo(-4.0, -5, 1.5, -20.0); p.quadTo(14, -7, 15.5, 6.5); p.quadTo(7, 17, -6.0, 19.0); p.closePath();
     73        Sailboard.add(new Instr(Form.PGON, p));
     74        Sailboard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     75        Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-2, 20, -10, 20)));
     76        Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-13, 2.5, -3, 2.5)));
     77        Sailboard.add(new Instr(Form.RSHP, new Ellipse2D.Double(-15, -4, 5, 5)));
     78        Sailboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     79        p = new Path2D.Double(); p.moveTo(-13, 2.5); p.lineTo(-12, 6.0); p.lineTo(-12, 9.5);
     80        Sailboard.add(new Instr(Form.PLIN, p));
     81        Sailboard.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     82        p = new Path2D.Double(); p.moveTo(-12, 9.5); p.lineTo(-7.5, 13.0); p.lineTo(-6.0, 19.0);
     83        Sailboard.add(new Instr(Form.PLIN, p));
     84    }
     85
     86    private static final Symbol Sailboat = new Symbol();
     87    static {
     88        Path2D.Double p = new Path2D.Double(); p.moveTo(3.75, -20.5); p.lineTo(3.75, 8.5); p.lineTo(-19.5, 8.5); p.closePath();
     89        Sailboat.add(new Instr(Form.PGON, p));
     90        p = new Path2D.Double(); p.moveTo(-19.5, 12.0); p.lineTo(19.5, 12.0); p.lineTo(13.0, 20.5); p.lineTo(-16.0, 20.5); p.closePath();
     91        Sailboat.add(new Instr(Form.PGON, p));
     92    }
     93
     94    private static final Symbol Slipway = new Symbol();
     95    static {
     96        Path2D.Double p = new Path2D.Double(); p.moveTo(-17, -5.5); p.lineTo(-13.5, 0); p.lineTo(4, -1.5); p.quadTo(18, -5, 20, -13.5); p.closePath();
     97        p.moveTo(-14, 7); p.lineTo(-14, 11); p.lineTo(20, 11); p.lineTo(20, 2); p.closePath();
     98        Slipway.add(new Instr(Form.PGON, p));
     99        Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     100        Slipway.add(new Instr(Form.LINE, new Line2D.Double(-14, 3, 20, -2.5)));
     101        Slipway.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     102        Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(1, 1.5, 3, 3)));
     103        p = new Path2D.Double(); p.moveTo(-21, 8.5); p.curveTo(-17.5, 5, -17.5, 12, -13, 7.2);
     104        Slipway.add(new Instr(Form.PLIN, p));
     105    }
     106
     107    private static final Symbol Speedboat = new Symbol();
     108    static {
     109        Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     110        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, -17, -1)));
     111        Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5, 8.5); p.curveTo(-10.5, 13, -2.5, 2, 4, 6); p.curveTo(12, 2, 11.5, 9.5, 20, 6);
     112        Speedboat.add(new Instr(Form.PLIN, p));
     113        p = new Path2D.Double(); p.moveTo(-18.5, 1.5); p.lineTo(-16, 6); p.curveTo(-9, 9.0, -3.5, -2.0, 4.5, 3.5); p.lineTo(14.5, 0); p.quadTo(19, -3, 19.5, -9);
     114        p.lineTo(9.5, -6); p.lineTo(6.5, -8); p.lineTo(2.5, -4); p.closePath();
     115        Speedboat.add(new Instr(Form.PGON, p));
     116        Speedboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-1.5, -13, 5, 5)));
     117        Speedboat.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     118        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2, -7, -5, 0)));
     119        Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     120        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2, -7, 5, -5)));
     121    }
     122
     123    private static final Symbol Turn = new Symbol();
     124    static {
     125        Turn.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     126        Turn.add(new Instr(Form.EARC, new Arc2D.Double(-9.0, -9.0, 18.0, 18.0, 270.0, 230.0, Arc2D.OPEN)));
     127        Turn.add(new Instr(Form.EARC, new Arc2D.Double(-20.0, -20.0, 40.0, 40.0, 315.0, -280.0, Arc2D.OPEN)));
     128        Path2D.Double p = new Path2D.Double(); p.moveTo(21.8, -7.0); p.lineTo(18.8, -18.2); p.lineTo(10.5, -10.0); p.closePath();
     129        p.moveTo(-12.9, 0.7); p.lineTo(-1.7, -2.3); p.lineTo(-9.9, -10.5); p.closePath();
     130        Turn.add(new Instr(Form.PGON, p));
     131    }
     132
     133    private static final Symbol Waterbike = new Symbol();
     134    static {
     135        Path2D.Double p = new Path2D.Double(); p.moveTo(-17.5, 13); p.curveTo(-10.5, 17.5, -2.5, 6.5, 4, 10.5); p.curveTo(12, 6.5, 11.5, 14, 20, 10.5);
     136        Waterbike.add(new Instr(Form.PLIN, p));
     137        p = new Path2D.Double(); p.moveTo(-16.5, 9.5); p.lineTo(-16, 10.5); p.curveTo(-9, 13.5, -3.5, 2.5, 4.5, 8); p.quadTo(15, 4, 19.5, -4); p.closePath();
     138        p.moveTo(19.5, -5); p.lineTo(1, -5); p.lineTo(-4.5, -10); p.lineTo(-5.5, -10); p.lineTo(2, -2); p.lineTo(-15, 4); p.lineTo(-16, 8); p.closePath();
     139        Waterbike.add(new Instr(Form.PGON, p));
     140        Waterbike.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     141        p = new Path2D.Double(); p.moveTo(-7, 1); p.lineTo(-7.5, -1.5); p.lineTo(-12.5, -3.5); p.lineTo(-11.5, -10.5);
     142        Waterbike.add(new Instr(Form.PLIN, p));
     143        Waterbike.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     144        Waterbike.add(new Instr(Form.LINE, new Line2D.Double(-11.5, -10.5, -3, -8.5)));
     145        Waterbike.add(new Instr(Form.RSHP, new Ellipse2D.Double(-11.5, -18, 5, 5)));
     146    }
     147
     148    private static final Symbol Waterski = new Symbol();
     149    static {
     150        Waterski.add(new Instr(Form.RSHP, new Ellipse2D.Double(12, -18, 6, 6)));
     151        Waterski.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     152        Waterski.add(new Instr(Form.LINE, new Line2D.Double(-18, -6, 0, -6)));
     153        Waterski.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     154        Path2D.Double p = new Path2D.Double(); p.moveTo(6.5, 17.5); p.lineTo(-13, 14.5); p.curveTo(-15, 14.25, -16.0, 13.6, -17.5, 12.0);
     155        Waterski.add(new Instr(Form.PLIN, p));
     156        Waterski.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
     157        p = new Path2D.Double(); p.moveTo(-1.5, -4.0); p.lineTo(14, -7.5); p.lineTo(9.5, 3.5); p.lineTo(2.0, 6.0); p.lineTo(-4.4, 15.8);
     158        Waterski.add(new Instr(Form.PLIN, p));
     159    }
     160
     161    private static final Symbol NoticeA = new Symbol();
     162    static {
     163        NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
     164        NoticeA.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     165        NoticeA.add(new Instr(Form.FILL, Color.white));
     166        NoticeA.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
     167        NoticeA.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     168        NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
     169        NoticeA.add(new Instr(Form.LINE, new Line2D.Double(-25, -25, 25, 25)));
     170        NoticeA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     171        NoticeA.add(new Instr(Form.FILL, Color.black));
     172        NoticeA.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     173    }
     174
     175    private static final Symbol NoticeB = new Symbol();
     176    static {
     177        NoticeB.add(new Instr(Form.FILL, new Color(0xe80000)));
     178        NoticeB.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     179        NoticeB.add(new Instr(Form.FILL, Color.white));
     180        NoticeB.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
     181        NoticeB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     182        NoticeB.add(new Instr(Form.FILL, Color.black));
     183        NoticeB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     184    }
     185
     186    private static final Symbol NoticeE = new Symbol();
     187    static {
     188        NoticeE.add(new Instr(Form.FILL, new Color(0x0000a0)));
     189        NoticeE.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     190        NoticeE.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     191        NoticeE.add(new Instr(Form.FILL, Color.black));
     192        NoticeE.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     193        NoticeE.add(new Instr(Form.FILL, Color.white));
     194    }
     195
     196    public static final Symbol Notice = new Symbol();
     197    static {
     198        Notice.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     199        Notice.add(new Instr(Form.FILL, new Color(0xe80000)));
     200        Notice.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     201        Notice.add(new Instr(Form.FILL, new Color(0x0000a0)));
     202        Notice.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
     203        Notice.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     204        Notice.add(new Instr(Form.FILL, Color.black));
     205        Notice.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     206    }
     207
     208    public static final Symbol NoticeA1 = new Symbol();
     209    static {
     210        NoticeA1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     211        NoticeA1.add(new Instr(Form.FILL, new Color(0xe80000)));
     212        NoticeA1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     213        NoticeA1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     214        NoticeA1.add(new Instr(Form.FILL, Color.white));
     215        NoticeA1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-30, -10, 60, 20)));
     216        NoticeA1.add(new Instr(Form.FILL, Color.black));
     217        NoticeA1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     218    }
     219
     220    public static final Symbol NoticeA1a = new Symbol();
     221    static {
     222        NoticeA1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     223        NoticeA1a.add(new Instr(Form.FILL, new Color(0xe80000)));
     224        NoticeA1a.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
     225        NoticeA1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     226        NoticeA1a.add(new Instr(Form.FILL, Color.white));
     227        NoticeA1a.add(new Instr(Form.RSHP, new Rectangle2D.Double(-29, -10, 58, 20)));
     228        NoticeA1a.add(new Instr(Form.FILL, Color.black));
     229        NoticeA1a.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
     230    }
     231
     232    public static final Symbol NoticeA2 = new Symbol();
     233    static {
     234        NoticeA2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     235        NoticeA2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     236        NoticeA2.add(new Instr(Form.FILL, Color.black));
     237        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 23); p.lineTo(-10, 0); p.lineTo(-6, 0); p.lineTo(-12.5, -8); p.lineTo(-19, 0); p.lineTo(-15, 0); p.lineTo(-15, 23);
     238        p.closePath(); p.moveTo(10, 8); p.lineTo(10, -15); p.lineTo(6, -15); p.lineTo(12.5, -23); p.lineTo(19, -15); p.lineTo(15, -15); p.lineTo(15, 8); p.closePath();
     239        NoticeA2.add(new Instr(Form.PGON, p));
     240    }
     241
     242    public static final Symbol NoticeA3 = new Symbol();
     243    static {
     244        NoticeA3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     245        NoticeA3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA2, 1.0, 0, 0, null, null)));
     246        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 12); p.lineTo(-6, 12); p.lineTo(-12.5, 4); p.lineTo(-19, 12);
     247        p.closePath(); p.moveTo(10, -3); p.lineTo(6, -3); p.lineTo(12.5, -11); p.lineTo(19, -3); p.closePath();
     248        NoticeA3.add(new Instr(Form.PGON, p));
     249    }
     250
     251    public static final Symbol NoticeA4 = new Symbol();
     252    static {
     253        NoticeA4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     254        NoticeA4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     255        NoticeA4.add(new Instr(Form.FILL, Color.black));
     256        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, -15); p.lineTo(-10, 8); p.lineTo(-6, 8); p.lineTo(-12.5, 16); p.lineTo(-19, 8); p.lineTo(-15, 8); p.lineTo(-15, -15);
     257        p.closePath(); p.moveTo(10, 15); p.lineTo(10, -8); p.lineTo(6, -8); p.lineTo(12.5, -16); p.lineTo(19, -8); p.lineTo(15, -8); p.lineTo(15, 15); p.closePath();
     258        NoticeA4.add(new Instr(Form.PGON, p));
     259    }
     260
     261    public static final Symbol NoticeA4_1 = new Symbol();
     262    static {
     263        NoticeA4_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     264        NoticeA4_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA4, 1.0, 0, 0, null, null)));
     265        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, -4); p.lineTo(-6, -4); p.lineTo(-12.5, 4); p.lineTo(-19, -4);
     266        p.closePath(); p.moveTo(10, 5); p.lineTo(6, 5); p.lineTo(12.5, -3); p.lineTo(19, 5); p.closePath();
     267        NoticeA4_1.add(new Instr(Form.PGON, p));
     268    }
     269
     270    public static final Symbol NoticeA5 = new Symbol();
     271    static {
     272        NoticeA5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     273        NoticeA5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     274        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD); p.moveTo(-5.3, 14.6); p.lineTo(-5.3, 4.0); p.lineTo(0.0, 4.0); p.curveTo(4.2, 4.0, 7.4, 3.5, 9.4, 0.0);
     275        p.curveTo(11.4, -2.8, 11.4, -7.2, 9.4, -10.5); p.curveTo(7.4, -13.6, 4.2, -14.0, 0.0, -14.0); p.lineTo(-11.0, -14.0); p.lineTo(-11.0, 14.6); p.closePath();
     276        p.moveTo(-5.3, -1.0); p.lineTo(0.0, -1.0); p.curveTo(6.5, -1.0, 6.5, -9.0, 0.0, -9.0); p.lineTo(-5.3, -9.0); p.closePath();
     277        NoticeA5.add(new Instr(Form.PGON, p));
     278    }
     279
     280    public static final Symbol NoticeA5_1 = new Symbol();
     281    static {
     282        NoticeA5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     283        NoticeA5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     284    }
     285
     286    public static final Symbol NoticeA6 = new Symbol();
     287    static {
     288        NoticeA6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     289        NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     290        NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
     291    }
     292
     293    public static final Symbol NoticeA7 = new Symbol();
     294    static {
     295        NoticeA7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     296        NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     297        NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.black), null)));
     298    }
     299
     300    public static final Symbol NoticeA8 = new Symbol();
     301    static {
     302        NoticeA8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     303        NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     304        NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.black), null)));
     305    }
     306
     307    public static final Symbol NoticeA9 = new Symbol();
     308    static {
     309        NoticeA9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     310        NoticeA9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     311        NoticeA9.add(new Instr(Form.STRK, new BasicStroke(7, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     312        NoticeA9.add(new Instr(Form.FILL, Color.black));
     313        Path2D.Double p = new Path2D.Double(); p.moveTo(-23, 10); p.curveTo(-11, 10, -12, 4, 0, 4); p.curveTo(12, 4, 11, 10, 23, 10);
     314        p.moveTo(-23, -3); p.curveTo(-11, -3, -12, -9, 0, -9); p.curveTo(12, -9, 11, -3, 23, -3);
     315        NoticeA9.add(new Instr(Form.PLIN, p));
     316    }
     317
     318    public static final Symbol NoticeA10a = new Symbol();
     319    static {
     320        NoticeA10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     321        NoticeA10a.add(new Instr(Form.FILL, Color.white));
     322        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(30, 0); p.lineTo(0, 30); p.closePath();
     323        NoticeA10a.add(new Instr(Form.PGON, p));
     324        NoticeA10a.add(new Instr(Form.FILL, new Color(0xe80000)));
     325        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.closePath();
     326        NoticeA10a.add(new Instr(Form.PGON, p));
     327        NoticeA10a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     328        NoticeA10a.add(new Instr(Form.FILL, Color.black));
     329        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
     330        NoticeA10a.add(new Instr(Form.PLIN, p));
     331    }
     332
     333    public static final Symbol NoticeA10b = new Symbol();
     334    static {
     335        NoticeA10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     336        NoticeA10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA10a, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
     337    }
     338
     339    public static final Symbol NoticeA12 = new Symbol();
     340    static {
     341        NoticeA12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     342        NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     343        NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.black), null)));
     344    }
     345
     346    public static final Symbol NoticeA13 = new Symbol();
     347    static {
     348        NoticeA13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     349        NoticeA13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     350        NoticeA13.add(new Instr(Form.TEXT, new Caption("SPORT", new Font("Arial", Font.BOLD, 15), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 5)))));
     351    }
     352
     353    public static final Symbol NoticeA14 = new Symbol();
     354    static {
     355        NoticeA14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     356        NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     357        NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.black), null)));
     358    }
     359
     360    public static final Symbol NoticeA15 = new Symbol();
     361    static {
     362        NoticeA15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     363        NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     364        NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.black), null)));
     365    }
     366
     367    public static final Symbol NoticeA16 = new Symbol();
     368    static {
     369        NoticeA16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     370        NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     371        NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.black), null)));
     372    }
     373
     374    public static final Symbol NoticeA17 = new Symbol();
     375    static {
     376        NoticeA17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     377        NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     378        NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.black), null)));
     379    }
     380
     381    public static final Symbol NoticeA18 = new Symbol();
     382    static {
     383        NoticeA18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     384        NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     385        NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.black), null)));
     386    }
     387
     388    public static final Symbol NoticeA19 = new Symbol();
     389    static {
     390        NoticeA19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     391        NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     392        NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.black), null)));
     393    }
     394
     395    public static final Symbol NoticeA20 = new Symbol();
     396    static {
     397        NoticeA20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     398        NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
     399        NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.black), null)));
     400    }
     401
     402    public static final Symbol NoticeB1a = new Symbol();
     403    static {
     404        NoticeB1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     405        NoticeB1a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     406        Path2D.Double p = new Path2D.Double(); p.moveTo(21, 8); p.lineTo(-8, 8); p.lineTo(-8, 18); p.lineTo(-21, 0);
     407        p.lineTo(-8, -18); p.lineTo(-8, -8); p.lineTo(21, -8); p.closePath();
     408        NoticeB1a.add(new Instr(Form.PGON, p));
     409    }
     410
     411    public static final Symbol NoticeB1b = new Symbol();
     412    static {
     413        NoticeB1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     414        NoticeB1b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     415        Path2D.Double p = new Path2D.Double(); p.moveTo(-21, 8); p.lineTo(8, 8); p.lineTo(8, 18); p.lineTo(21, 0);
     416        p.lineTo(8, -18); p.lineTo(8, -8); p.lineTo(-21, -8); p.closePath();
     417        NoticeB1b.add(new Instr(Form.PGON, p));
     418    }
     419
     420    public static final Symbol NoticeB2a = new Symbol();
     421    static {
     422        NoticeB2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     423        NoticeB2a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     424        NoticeB2a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     425        Path2D.Double p = new Path2D.Double(); p.moveTo(18, 21); p.lineTo(18, 10); p.lineTo(-15, -10); p.lineTo(-15, -15);
     426        NoticeB2a.add(new Instr(Form.PLIN, p));
     427        p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(-21, -15); p.lineTo(-9, -15); p.closePath();
     428        NoticeB2a.add(new Instr(Form.PGON, p));
     429    }
     430
     431    public static final Symbol NoticeB2b = new Symbol();
     432    static {
     433        NoticeB2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     434        NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     435        NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     436        NoticeB2b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     437        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, 21); p.lineTo(-18, 10); p.lineTo(15, -10); p.lineTo(15, -15);
     438        NoticeB2b.add(new Instr(Form.PLIN, p));
     439        p = new Path2D.Double(); p.moveTo(15, -21); p.lineTo(21, -15); p.lineTo(9, -15); p.closePath();
     440        NoticeB2b.add(new Instr(Form.PGON, p));
     441    }
     442
     443    public static final Symbol NoticeB3a = new Symbol();
     444    static {
     445        NoticeB3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     446        NoticeB3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     447        NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     448        NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(-15, 21, -15, -15)));
     449        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(-21, -15); p.lineTo(-9, -15); p.closePath();
     450        NoticeB3a.add(new Instr(Form.PGON, p));
     451        NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] {5.5f, 2.4f}, 0.0f)));
     452        NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(15, -21, 15, 15)));
     453        p = new Path2D.Double(); p.moveTo(15, 21); p.lineTo(21, 15); p.lineTo(9, 15); p.closePath();
     454        NoticeB3a.add(new Instr(Form.PGON, p));
     455    }
     456
     457    public static final Symbol NoticeB3b = new Symbol();
     458    static {
     459        NoticeB3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     460        NoticeB3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     461        NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     462        NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(15, 21, 15, -15)));
     463        Path2D.Double p = new Path2D.Double(); p.moveTo(15, -21); p.lineTo(21, -15); p.lineTo(9, -15); p.closePath();
     464        NoticeB3b.add(new Instr(Form.PGON, p));
     465        NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] {5.5f, 2.4f}, 0.0f)));
     466        NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(-15, -21, -15, 15)));
     467        p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(-21, 15); p.lineTo(-9, 15); p.closePath();
     468        NoticeB3b.add(new Instr(Form.PGON, p));
     469    }
     470
     471    public static final Symbol NoticeB4a = new Symbol();
     472    static {
     473        NoticeB4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     474        NoticeB4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2a, 1.0, 0, 0, null, null)));
     475        NoticeB4a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] {5.5f, 2.4f}, 0.0f)));
     476        Path2D.Double p = new Path2D.Double(); p.moveTo(18, -21); p.lineTo(18, -10); p.lineTo(-15, 10); p.lineTo(-15, 15);
     477        NoticeB4a.add(new Instr(Form.PLIN, p));
     478        p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(-21, 15); p.lineTo(-9, 15); p.closePath();
     479        NoticeB4a.add(new Instr(Form.PGON, p));
     480    }
     481
     482    public static final Symbol NoticeB4b = new Symbol();
     483    static {
     484        NoticeB4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     485        NoticeB4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2b, 1.0, 0, 0, null, null)));
     486        NoticeB4b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] {5.5f, 2.4f}, 0.0f)));
     487        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, -21); p.lineTo(-18, -10); p.lineTo(15, 10); p.lineTo(15, 15);
     488        NoticeB4b.add(new Instr(Form.PLIN, p));
     489        p = new Path2D.Double(); p.moveTo(15, 21); p.lineTo(21, 15); p.lineTo(9, 15); p.closePath();
     490        NoticeB4b.add(new Instr(Form.PGON, p));
     491    }
     492
     493    public static final Symbol NoticeB5 = new Symbol();
     494    static {
     495        NoticeB5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     496        NoticeB5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     497        NoticeB5.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     498        NoticeB5.add(new Instr(Form.LINE, new Line2D.Double(15, 0, -15, 0)));
     499    }
     500
     501    public static final Symbol NoticeB6 = new Symbol();
     502    static {
     503        NoticeB6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     504        NoticeB6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     505    }
     506
     507    public static final Symbol NoticeB7 = new Symbol();
     508    static {
     509        NoticeB7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     510        NoticeB7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     511        NoticeB7.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -10, 20, 20)));
     512    }
     513
     514    public static final Symbol NoticeB8 = new Symbol();
     515    static {
     516        NoticeB8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     517        NoticeB8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     518        NoticeB8.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     519        NoticeB8.add(new Instr(Form.LINE, new Line2D.Double(0, 15, 0, -15)));
     520    }
     521
     522    public static final Symbol NoticeB9a = new Symbol();
     523    static {
     524        NoticeB9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     525        NoticeB9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     526        NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     527        NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, 21, 0)));
     528        NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     529        NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(0, 21, 0, 0)));
     530    }
     531
     532    public static final Symbol NoticeB9b = new Symbol();
     533    static {
     534        NoticeB9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     535        NoticeB9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     536        NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     537        NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, 21, 0)));
     538        NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     539        NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(0, 21, 0, -21)));
     540    }
     541
     542    public static final Symbol NoticeB11 = new Symbol();
     543    static {
     544        NoticeB11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     545        NoticeB11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     546        NoticeB11.add(new Instr(Form.TEXT, new Caption("VHF", new Font("Arial", Font.BOLD, 20), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 0)))));
     547    }
     548
     549    public static final Symbol NoticeC1 = new Symbol();
     550    static {
     551        NoticeC1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     552        NoticeC1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     553        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(0, 12); p.lineTo(15, 21); p.closePath();
     554        NoticeC1.add(new Instr(Form.PGON, p));
     555    }
     556
     557    public static final Symbol NoticeC2 = new Symbol();
     558    static {
     559        NoticeC2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     560        NoticeC2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     561        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(0, -12); p.lineTo(15, -21); p.closePath();
     562        NoticeC2.add(new Instr(Form.PGON, p));
     563    }
     564
     565    public static final Symbol NoticeC3 = new Symbol();
     566    static {
     567        NoticeC3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     568        NoticeC3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     569        Path2D.Double p = new Path2D.Double(); p.moveTo(21, -15); p.lineTo(12, 0); p.lineTo(21, 15); p.closePath();
     570        p.moveTo(-21, -15); p.lineTo(-12, 0); p.lineTo(-21, 15); p.closePath();
     571        NoticeC3.add(new Instr(Form.PGON, p));
     572    }
     573
     574    public static final Symbol NoticeC4 = new Symbol();
     575    static {
     576        NoticeC4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     577        NoticeC4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     578    }
     579
     580    public static final Symbol NoticeC5a = new Symbol();
     581    static {
     582        NoticeC5a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     583        NoticeC5a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     584        Path2D.Double p = new Path2D.Double(); p.moveTo(-21, -21); p.lineTo(10, -21); p.lineTo(21, 0); p.lineTo(10, 21); p.lineTo(-21, 21); p.closePath();
     585        NoticeC5a.add(new Instr(Form.PGON, p));
     586    }
     587
     588    public static final Symbol NoticeC5b = new Symbol();
     589    static {
     590        NoticeC5b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     591        NoticeC5b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
     592        Path2D.Double p = new Path2D.Double(); p.moveTo(21, -21); p.lineTo(-10, -21); p.lineTo(-21, 0); p.lineTo(-10, 21); p.lineTo(21, 21); p.closePath();
     593        NoticeC5b.add(new Instr(Form.PGON, p));
     594    }
     595
     596    public static final Symbol NoticeD1a = new Symbol();
     597    static {
     598        NoticeD1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     599        NoticeD1a.add(new Instr(Form.FILL, Color.yellow));
     600        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
     601        NoticeD1a.add(new Instr(Form.PGON, p));
     602        NoticeD1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     603        NoticeD1a.add(new Instr(Form.FILL, Color.black));
     604        NoticeD1a.add(new Instr(Form.PLIN, p));
     605    }
     606
     607    public static final Symbol NoticeD1b = new Symbol();
     608    static {
     609        NoticeD1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     610        NoticeD1b.add(new Instr(Form.FILL, Color.yellow));
     611        Path2D.Double p = new Path2D.Double(); p.moveTo(-30, 0); p.lineTo(-15, 25); p.lineTo(15, -25); p.lineTo(30, 0); p.lineTo(15, 25); p.lineTo(-15, -25); p.closePath();
     612        NoticeD1b.add(new Instr(Form.PGON, p));
     613        NoticeD1b.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     614        NoticeD1b.add(new Instr(Form.FILL, Color.black));
     615        NoticeD1b.add(new Instr(Form.PLIN, p));
     616    }
     617
     618    public static final Symbol NoticeD2a = new Symbol();
     619    static {
     620        NoticeD2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     621        NoticeD2a.add(new Instr(Form.FILL, Color.white));
     622        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.closePath();
     623        NoticeD2a.add(new Instr(Form.PGON, p));
     624        NoticeD2a.add(new Instr(Form.FILL, new Color(0x00e800)));
     625        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(30, 0); p.lineTo(0, 30); p.closePath();
     626        NoticeD2a.add(new Instr(Form.PGON, p));
     627        NoticeD2a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     628        NoticeD2a.add(new Instr(Form.FILL, Color.black));
     629        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
     630        NoticeD2a.add(new Instr(Form.PLIN, p));
     631    }
     632
     633    public static final Symbol NoticeD2b = new Symbol();
     634    static {
     635        NoticeD2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     636        NoticeD2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeD2a, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(180.0))))));
     637    }
     638
     639    public static final Symbol NoticeD3a = new Symbol();
     640    static {
     641        NoticeD3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     642        NoticeD3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     643        Path2D.Double p = new Path2D.Double(); p.moveTo(28, 10); p.lineTo(-10, 10); p.lineTo(-10, 20); p.lineTo(-28, 0);
     644        p.lineTo(-10, -20); p.lineTo(-10, -10); p.lineTo(28, -10); p.closePath();
     645        NoticeD3a.add(new Instr(Form.PGON, p));
     646    }
     647
     648    public static final Symbol NoticeD3b = new Symbol();
     649    static {
     650        NoticeD3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     651        NoticeD3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     652        Path2D.Double p = new Path2D.Double(); p.moveTo(-28, 10); p.lineTo(10, 10); p.lineTo(10, 20); p.lineTo(28, 0);
     653        p.lineTo(10, -20); p.lineTo(10, -10); p.lineTo(-28, -10); p.closePath();
     654        NoticeD3b.add(new Instr(Form.PGON, p));
     655    }
     656
     657    public static final Symbol NoticeE1 = new Symbol();
     658    static {
     659        NoticeE1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     660        NoticeE1.add(new Instr(Form.FILL, new Color(0x00e800)));
     661        NoticeE1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     662        NoticeE1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     663        NoticeE1.add(new Instr(Form.FILL, Color.white));
     664        NoticeE1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-10, -30, 20, 60)));
     665        NoticeE1.add(new Instr(Form.FILL, Color.black));
     666        NoticeE1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     667    }
     668
     669    public static final Symbol NoticeE2 = new Symbol();
     670    static {
     671        NoticeE2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     672        NoticeE2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     673        Path2D.Double p = new Path2D.Double(); p.moveTo(5, -25); p.lineTo(-10, -1); p.lineTo(10, -1); p.lineTo(-10, 20);
     674        p.lineTo(-7, 20); p.lineTo(-12, 25); p.lineTo(-16, 20); p.lineTo(-13, 20); p.lineTo(4, 1); p.lineTo(-14, 1);
     675        p.lineTo(2, -25); p.closePath();
     676        NoticeE2.add(new Instr(Form.PGON, p));
     677    }
     678
     679    public static final Symbol NoticeE3 = new Symbol();
     680    static {
     681        NoticeE3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     682        NoticeE3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     683        NoticeE3.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     684        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(25, -20, 25, 20)));
     685        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-25, -20, -25, 20)));
     686        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-15, -15, -15, 20)));
     687        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-5, -15, -5, 20)));
     688        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(5, -15, 5, 20)));
     689        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(15, -15, 15, 20)));
     690        NoticeE3.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     691        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26, 18.5, 26, 18.5)));
     692        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26, -15, 26, -15)));
     693    }
     694
     695    public static final Symbol NoticeE4a = new Symbol();
     696    static {
     697        NoticeE4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     698        NoticeE4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     699        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, -10); p.lineTo(-5, -10); p.lineTo(-5, -20); p.lineTo(5, -20); p.lineTo(5, -10);
     700        p.lineTo(20, -10); p.lineTo(15, 0); p.lineTo(-15, 0); p.closePath();
     701        p.moveTo(-25, 5); p.lineTo(25, 5); p.lineTo(25, 10); p.lineTo(-25, 10); p.closePath();
     702        NoticeE4a.add(new Instr(Form.PGON, p));
     703    }
     704
     705    public static final Symbol NoticeE4b = new Symbol();
     706    static {
     707        NoticeE4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     708        NoticeE4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     709        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, 0); p.lineTo(-5, 0); p.lineTo(-5, -10); p.lineTo(5, -10); p.lineTo(5, 0);
     710        p.lineTo(20, 0); p.lineTo(15, 10); p.lineTo(-15, 10); p.closePath();
     711        NoticeE4b.add(new Instr(Form.PGON, p));
     712    }
     713
     714    public static final Symbol NoticeE5 = new Symbol();
     715    static {
     716        NoticeE5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     717        NoticeE5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     718        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD); p.moveTo(-5.3, 14.6); p.lineTo(-5.3, 4.0); p.lineTo(0.0, 4.0); p.curveTo(4.2, 4.0, 7.4, 3.5, 9.4, 0.0);
     719        p.curveTo(11.4, -2.8, 11.4, -7.2, 9.4, -10.5); p.curveTo(7.4, -13.6, 4.2, -14.0, 0.0, -14.0); p.lineTo(-11.0, -14.0); p.lineTo(-11.0, 14.6); p.closePath();
     720        p.moveTo(-5.3, -1.0); p.lineTo(0.0, -1.0); p.curveTo(6.5, -1.0, 6.5, -9.0, 0.0, -9.0); p.lineTo(-5.3, -9.0); p.closePath();
     721        NoticeE5.add(new Instr(Form.PGON, p));
     722    }
     723
     724    public static final Symbol NoticeE5_1 = new Symbol();
     725    static {
     726        NoticeE5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     727        NoticeE5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     728    }
     729
     730    public static final Symbol NoticeE5_2 = new Symbol();
     731    static {
     732        NoticeE5_2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     733        NoticeE5_2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     734    }
     735
     736    public static final Symbol NoticeE5_3 = new Symbol();
     737    static {
     738        NoticeE5_3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     739        NoticeE5_3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     740    }
     741
     742    public static final Symbol NoticeE5_4 = new Symbol();
     743    static {
     744        NoticeE5_4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     745        NoticeE5_4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     746        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     747        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
     748        NoticeE5_4.add(new Instr(Form.PGON, p));
     749    }
     750
     751    public static final Symbol NoticeE5_5 = new Symbol();
     752    static {
     753        NoticeE5_5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     754        NoticeE5_5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     755        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     756        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
     757        p.moveTo(0, 24); p.lineTo(-15, 2); p.lineTo(15, 2); p.closePath();
     758        NoticeE5_5.add(new Instr(Form.PGON, p));
     759    }
     760
     761    public static final Symbol NoticeE5_6 = new Symbol();
     762    static {
     763        NoticeE5_6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     764        NoticeE5_6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     765        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     766        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
     767        p.moveTo(0, 7); p.lineTo(-10, -8); p.lineTo(10, -8); p.closePath();
     768        p.moveTo(0, 24); p.lineTo(-10, 9); p.lineTo(10, 9); p.closePath();
     769        NoticeE5_6.add(new Instr(Form.PGON, p));
     770    }
     771
     772    public static final Symbol NoticeE5_7 = new Symbol();
     773    static {
     774        NoticeE5_7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     775        NoticeE5_7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     776        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     777        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
     778        p.moveTo(0, -1); p.lineTo(-8, -11); p.lineTo(8, -11); p.closePath();
     779        p.moveTo(0, 11); p.lineTo(-8, 1); p.lineTo(8, 1); p.closePath();
     780        p.moveTo(0, 23); p.lineTo(-8, 13); p.lineTo(8, 13); p.closePath();
     781        NoticeE5_7.add(new Instr(Form.PGON, p));
     782    }
     783
     784    public static final Symbol NoticeE5_8 = new Symbol();
     785    static {
     786        NoticeE5_8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     787        NoticeE5_8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     788        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     789        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
     790        NoticeE5_8.add(new Instr(Form.PGON, p));
     791    }
     792
     793    public static final Symbol NoticeE5_9 = new Symbol();
     794    static {
     795        NoticeE5_9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     796        NoticeE5_9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     797        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     798        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
     799        p.moveTo(0, 8); p.lineTo(-15, -14); p.lineTo(15, -14); p.closePath();
     800        NoticeE5_9.add(new Instr(Form.PGON, p));
     801    }
     802
     803    public static final Symbol NoticeE5_10 = new Symbol();
     804    static {
     805        NoticeE5_10.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     806        NoticeE5_10.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     807        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     808        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
     809        p.moveTo(0, -5); p.lineTo(-10, -20); p.lineTo(10, -20); p.closePath();
     810        p.moveTo(0, 15); p.lineTo(-10, 0); p.lineTo(10, 0); p.closePath();
     811        NoticeE5_10.add(new Instr(Form.PGON, p));
     812    }
     813
     814    public static final Symbol NoticeE5_11 = new Symbol();
     815    static {
     816        NoticeE5_11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     817        NoticeE5_11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     818        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     819        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
     820        p.moveTo(0, -12); p.lineTo(-8, -22); p.lineTo(8, -22); p.closePath();
     821        p.moveTo(0, 3); p.lineTo(-8, -7); p.lineTo(8, -7); p.closePath();
     822        p.moveTo(0, 18); p.lineTo(-8, 8); p.lineTo(8, 8); p.closePath();
     823        NoticeE5_11.add(new Instr(Form.PGON, p));
     824    }
     825
     826    public static final Symbol NoticeE5_12 = new Symbol();
     827    static {
     828        NoticeE5_12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     829        NoticeE5_12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     830        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     831        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
     832        NoticeE5_12.add(new Instr(Form.PGON, p));
     833    }
     834
     835    public static final Symbol NoticeE5_13 = new Symbol();
     836    static {
     837        NoticeE5_13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     838        NoticeE5_13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     839        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     840        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
     841        p.moveTo(0, 15); p.lineTo(-15, -7); p.lineTo(15, -7); p.closePath();
     842        NoticeE5_13.add(new Instr(Form.PGON, p));
     843    }
     844
     845    public static final Symbol NoticeE5_14 = new Symbol();
     846    static {
     847        NoticeE5_14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     848        NoticeE5_14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     849        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     850        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
     851        p.moveTo(0, 0); p.lineTo(-10, -15); p.lineTo(10, -15); p.closePath();
     852        p.moveTo(0, 20); p.lineTo(-10, 5); p.lineTo(10, 5); p.closePath();
     853        NoticeE5_14.add(new Instr(Form.PGON, p));
     854    }
     855
     856    public static final Symbol NoticeE5_15 = new Symbol();
     857    static {
     858        NoticeE5_15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     859        NoticeE5_15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     860        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     861        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
     862        p.moveTo(0, -7); p.lineTo(-8, -17); p.lineTo(8, -17); p.closePath();
     863        p.moveTo(0, 8); p.lineTo(-8, -2); p.lineTo(8, -2); p.closePath();
     864        p.moveTo(0, 23); p.lineTo(-8, 13); p.lineTo(8, 13); p.closePath();
     865        NoticeE5_15.add(new Instr(Form.PGON, p));
     866    }
     867
     868    public static final Symbol NoticeE6 = new Symbol();
     869    static {
     870        NoticeE6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     871        NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     872        NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.white), null)));
     873    }
     874
     875    public static final Symbol NoticeE7 = new Symbol();
     876    static {
     877        NoticeE7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     878        NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     879        NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.white), null)));
     880    }
     881
     882    public static final Symbol NoticeE7_1 = new Symbol();
     883    static {
     884        NoticeE7_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     885        NoticeE7_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     886        NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     887        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20, 25, 20, -10)));
     888        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(22, -8, -15, -20)));
     889        NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     890        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20, 8, 0, -15)));
     891        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     892        p.moveTo(-17, 2); p.quadTo(-5, 0, 7, 2); p.lineTo(9, 12); p.lineTo(7, 20); p.lineTo(6, 20); p.lineTo(6, 23); p.lineTo(3, 23); p.lineTo(3, 20);
     893        p.quadTo(-5, 22, -13, 20); p.lineTo(-13, 23); p.lineTo(-16, 23); p.lineTo(-16, 20); p.lineTo(-17, 20); p.lineTo(-19, 12); p.closePath();
     894        p.moveTo(-15, 4); p.quadTo(-3, 2, 5, 4); p.lineTo(6, 11); p.quadTo(-5, 9, -16, 11); p.closePath();
     895        NoticeE7_1.add(new Instr(Form.PGON, p));
     896        NoticeE7_1.add(new Instr(Form.FILL, new Color(0x0000a0)));
     897        NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(-16, 13, 4, 4)));
     898        NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(2, 13, 4, 4)));
     899    }
     900
     901    public static final Symbol NoticeE8 = new Symbol();
     902    static {
     903        NoticeE8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     904        NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     905        NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.white), null)));
     906    }
     907
     908    public static final Symbol NoticeE9a = new Symbol();
     909    static {
     910        NoticeE9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     911        NoticeE9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     912        NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     913        NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
     914        NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     915        NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
     916    }
     917
     918    public static final Symbol NoticeE9b = new Symbol();
     919    static {
     920        NoticeE9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     921        NoticeE9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     922        NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     923        NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
     924        NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     925        NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
     926    }
     927
     928    public static final Symbol NoticeE9c = new Symbol();
     929    static {
     930        NoticeE9c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     931        NoticeE9c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     932        NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     933        NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
     934        NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     935        NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
     936    }
     937
     938    public static final Symbol NoticeE9d = new Symbol();
     939    static {
     940        NoticeE9d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     941        NoticeE9d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     942        NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     943        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     944        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
     945        NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     946        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
     947    }
     948
     949    public static final Symbol NoticeE9e = new Symbol();
     950    static {
     951        NoticeE9e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     952        NoticeE9e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     953        NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     954        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     955        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
     956        NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     957        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
     958    }
     959
     960    public static final Symbol NoticeE9f = new Symbol();
     961    static {
     962        NoticeE9f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     963        NoticeE9f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     964        NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     965        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     966        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
     967        NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     968        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
     969    }
     970
     971    public static final Symbol NoticeE9g = new Symbol();
     972    static {
     973        NoticeE9g.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     974        NoticeE9g.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     975        NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     976        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     977        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
     978        NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     979        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
     980    }
     981
     982    public static final Symbol NoticeE9h = new Symbol();
     983    static {
     984        NoticeE9h.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     985        NoticeE9h.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     986        NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     987        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     988        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
     989        NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     990        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
     991        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
     992    }
     993
     994    public static final Symbol NoticeE9i = new Symbol();
     995    static {
     996        NoticeE9i.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     997        NoticeE9i.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     998        NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     999        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
     1000        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
     1001        NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1002        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
     1003        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
     1004    }
     1005
     1006    public static final Symbol NoticeE10a = new Symbol();
     1007    static {
     1008        NoticeE10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1009        NoticeE10a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1010        NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1011        NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
     1012        NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1013        NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
     1014    }
     1015
     1016    public static final Symbol NoticeE10b = new Symbol();
     1017    static {
     1018        NoticeE10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1019        NoticeE10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1020        NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1021        NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
     1022        NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1023        NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
     1024    }
     1025
     1026    public static final Symbol NoticeE10c = new Symbol();
     1027    static {
     1028        NoticeE10c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1029        NoticeE10c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1030        NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1031        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
     1032        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
     1033        NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1034        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
     1035    }
     1036
     1037    public static final Symbol NoticeE10d = new Symbol();
     1038    static {
     1039        NoticeE10d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1040        NoticeE10d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1041        NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1042        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
     1043        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
     1044        NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1045        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
     1046    }
     1047
     1048    public static final Symbol NoticeE10e = new Symbol();
     1049    static {
     1050        NoticeE10e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1051        NoticeE10e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1052        NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1053        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
     1054        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
     1055        NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1056        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
     1057        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
     1058    }
     1059
     1060    public static final Symbol NoticeE10f = new Symbol();
     1061    static {
     1062        NoticeE10f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1063        NoticeE10f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1064        NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1065        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
     1066        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
     1067        NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1068        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
     1069        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
     1070    }
     1071
     1072    public static final Symbol NoticeE11 = new Symbol();
     1073    static {
     1074        NoticeE11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1075        NoticeE11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1076        NoticeE11.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
     1077        NoticeE11.add(new Instr(Form.LINE, new Line2D.Double(-27, -27, 27, 27)));
     1078    }
     1079
     1080    public static final Symbol NoticeE13 = new Symbol();
     1081    static {
     1082        NoticeE13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1083        NoticeE13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1084        Path2D.Double p = new Path2D.Double(); p.moveTo(-4, -16); p.lineTo(9, -16); p.lineTo(9, -14); p.lineTo(3.5, -14); p.lineTo(3.5, -7); p.lineTo(5, -7);
     1085        p.lineTo(5, 1); p.lineTo(6.5, 1); p.lineTo(6.5, 5); p.lineTo(17.5, 5); p.lineTo(17.5, 1); p.lineTo(19, 1); p.lineTo(19, 15); p.lineTo(17.5, 15);
     1086        p.lineTo(17.5, 10); p.lineTo(17.5, 10); p.lineTo(6.5, 10); p.lineTo(6.5, 13); p.lineTo(-2, 13); p.lineTo(-2, 10); p.lineTo(-9, 10);
     1087        p.quadTo(-13.5, 10, -13.5, 16); p.lineTo(-19, 16); p.quadTo(-19, 5, -9, 5); p.lineTo(-2, 5); p.lineTo(-2, 1); p.lineTo(0, 1); p.lineTo(0, -7);
     1088        p.lineTo(1.5, -7); p.lineTo(1.5, -14); p.lineTo(-4, -14); p.closePath();
     1089        NoticeE13.add(new Instr(Form.PGON, p));
     1090    }
     1091
     1092    public static final Symbol NoticeE14 = new Symbol();
     1093    static {
     1094        NoticeE14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1095        NoticeE14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1096        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, -18); p.lineTo(-11, -7); p.lineTo(-9, -10); p.lineTo(-14, -18); p.closePath();
     1097        p.moveTo(9.5, 7); p.lineTo(22.5, 9); p.lineTo(21.5, 5.5); p.lineTo(12, 4); p.closePath();
     1098        p.moveTo(-19, -16.5); p.lineTo(-13, -6.5); p.quadTo(-15.5, -2, -12.5, 0); p.lineTo(4, 11); p.quadTo(7, 13, 10, 9); p.lineTo(21.5, 11);
     1099        p.curveTo(15.5, 23, 1, 18.5, -9, 12); p.curveTo(-18, 6, -28.5, -7, -19, -16.5); p.closePath();
     1100        NoticeE14.add(new Instr(Form.PGON, p));
     1101    }
     1102
     1103    public static final Symbol NoticeE15 = new Symbol();
     1104    static {
     1105        NoticeE15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1106        NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1107        NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.white), null)));
     1108    }
     1109
     1110    public static final Symbol NoticeE16 = new Symbol();
     1111    static {
     1112        NoticeE16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1113        NoticeE16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1114        NoticeE16.add(new Instr(Form.TEXT, new Caption("SPORT", new Font("Arial", Font.BOLD, 15), Color.white, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 5)))));
     1115    }
     1116
     1117    public static final Symbol NoticeE17 = new Symbol();
     1118    static {
     1119        NoticeE17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1120        NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1121        NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.white), null)));
     1122    }
     1123
     1124    public static final Symbol NoticeE18 = new Symbol();
     1125    static {
     1126        NoticeE18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1127        NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1128        NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.white), null)));
     1129    }
     1130
     1131    public static final Symbol NoticeE19 = new Symbol();
     1132    static {
     1133        NoticeE19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1134        NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1135        NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.white), null)));
     1136    }
     1137
     1138    public static final Symbol NoticeE20 = new Symbol();
     1139    static {
     1140        NoticeE20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1141        NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1142        NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.white), null)));
     1143    }
     1144
     1145    public static final Symbol NoticeE21 = new Symbol();
     1146    static {
     1147        NoticeE21.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1148        NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1149        NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.white), null)));
     1150    }
     1151
     1152    public static final Symbol NoticeE22 = new Symbol();
     1153    static {
     1154        NoticeE22.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1155        NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1156        NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.white), null)));
     1157    }
     1158
     1159    public static final Symbol NoticeE23 = new Symbol();
     1160    static {
     1161        NoticeE23.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1162        NoticeE23.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1163        NoticeE23.add(new Instr(Form.TEXT, new Caption("VHF", new Font("Arial", Font.BOLD, 20), Color.white, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 0)))));
     1164    }
     1165
     1166    public static final Symbol NoticeE24 = new Symbol();
     1167    static {
     1168        NoticeE24.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1169        NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
     1170        NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.white), null)));
     1171    }
     1172
     1173    public static final Symbol NoticeBoard = new Symbol();
     1174    static {
     1175        NoticeBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 30)));
     1176        NoticeBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1177        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, 0); p.lineTo(20, 0); p.lineTo(20, -15); p.lineTo(-20, -15); p.closePath();
     1178        NoticeBoard.add(new Instr(Form.FILL, Color.white));
     1179        NoticeBoard.add(new Instr(Form.PGON, p));
     1180        NoticeBoard.add(new Instr(Form.FILL, Color.black));
     1181        NoticeBoard.add(new Instr(Form.PLIN, p));
     1182    }
     1183
     1184    public static final Symbol NoticeTriangle = new Symbol();
     1185    static {
     1186        NoticeTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 30)));
     1187        NoticeTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1188        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, 0); p.lineTo(20, 0); p.lineTo(0, -15); p.closePath();
     1189        NoticeTriangle.add(new Instr(Form.FILL, Color.white));
     1190        NoticeTriangle.add(new Instr(Form.PGON, p));
     1191        NoticeTriangle.add(new Instr(Form.FILL, Color.black));
     1192        NoticeTriangle.add(new Instr(Form.PLIN, p));
     1193    }
     1194
     1195    // CHECKSTYLE.OFF: SingleSpaceSeparator
     1196    public static final EnumMap<CatNMK, Symbol> NmkCevni = new EnumMap<>(CatNMK.class);
     1197    static {
     1198        NmkCevni.put(CatNMK.NMK_UNKN, Notice);      NmkCevni.put(CatNMK.NMK_NENT, NoticeA1);    NmkCevni.put(CatNMK.NMK_CLSA, NoticeA1a);   NmkCevni.put(CatNMK.NMK_NOVK, NoticeA2);
     1199        NmkCevni.put(CatNMK.NMK_NCOV, NoticeA3);    NmkCevni.put(CatNMK.NMK_NPAS, NoticeA4);    NmkCevni.put(CatNMK.NMK_NCPS, NoticeA4_1);  NmkCevni.put(CatNMK.NMK_NBRT, NoticeA5);
     1200        NmkCevni.put(CatNMK.NMK_NBLL, NoticeA5_1);  NmkCevni.put(CatNMK.NMK_NANK, NoticeA6);    NmkCevni.put(CatNMK.NMK_NMOR, NoticeA7);    NmkCevni.put(CatNMK.NMK_NTRN, NoticeA8);
     1201        NmkCevni.put(CatNMK.NMK_NWSH, NoticeA9);    NmkCevni.put(CatNMK.NMK_NPSL, NoticeA10a);  NmkCevni.put(CatNMK.NMK_NPSR, NoticeA10b);  NmkCevni.put(CatNMK.NMK_NMTC, NoticeA12);
     1202        NmkCevni.put(CatNMK.NMK_NSPC, NoticeA13);   NmkCevni.put(CatNMK.NMK_NWSK, NoticeA14);   NmkCevni.put(CatNMK.NMK_NSLC, NoticeA15);   NmkCevni.put(CatNMK.NMK_NUPC, NoticeA16);
     1203        NmkCevni.put(CatNMK.NMK_NSLB, NoticeA17);   NmkCevni.put(CatNMK.NMK_NWBK, NoticeA20);   NmkCevni.put(CatNMK.NMK_NHSC, NoticeA18);   NmkCevni.put(CatNMK.NMK_NLBG, NoticeA19);
     1204        NmkCevni.put(CatNMK.NMK_MVTL, NoticeB1a);   NmkCevni.put(CatNMK.NMK_MVTR, NoticeB1b);   NmkCevni.put(CatNMK.NMK_MVTP, NoticeB2a);   NmkCevni.put(CatNMK.NMK_MVTS, NoticeB2b);
     1205        NmkCevni.put(CatNMK.NMK_KPTP, NoticeB3a);   NmkCevni.put(CatNMK.NMK_KPTS, NoticeB3b);   NmkCevni.put(CatNMK.NMK_CSTP, NoticeB4a);   NmkCevni.put(CatNMK.NMK_CSTS, NoticeB4b);
     1206        NmkCevni.put(CatNMK.NMK_STOP, NoticeB5);    NmkCevni.put(CatNMK.NMK_SPDL, NoticeB6);    NmkCevni.put(CatNMK.NMK_SHRN, NoticeB7);    NmkCevni.put(CatNMK.NMK_KPLO, NoticeB8);
     1207        NmkCevni.put(CatNMK.NMK_GWJN, NoticeB9a);   NmkCevni.put(CatNMK.NMK_GWCS, NoticeB9b);   NmkCevni.put(CatNMK.NMK_MKRC, NoticeB11);
     1208        NmkCevni.put(CatNMK.NMK_LMDP, NoticeC1);    NmkCevni.put(CatNMK.NMK_LMHR, NoticeC2);    NmkCevni.put(CatNMK.NMK_LMWD, NoticeC3);    NmkCevni.put(CatNMK.NMK_NAVR, NoticeC4);
     1209        NmkCevni.put(CatNMK.NMK_CHDL, NoticeC5a);   NmkCevni.put(CatNMK.NMK_CHDR, NoticeC5b);
     1210        NmkCevni.put(CatNMK.NMK_CHTW, NoticeD1a);   NmkCevni.put(CatNMK.NMK_CHOW, NoticeD1b);   NmkCevni.put(CatNMK.NMK_OPTR, NoticeD2a);   NmkCevni.put(CatNMK.NMK_OPTL, NoticeD2b);
     1211        NmkCevni.put(CatNMK.NMK_PRTL, NoticeD3a);   NmkCevni.put(CatNMK.NMK_PRTR, NoticeD3b);
     1212        NmkCevni.put(CatNMK.NMK_ENTP, NoticeE1);    NmkCevni.put(CatNMK.NMK_OVHC, NoticeE2);    NmkCevni.put(CatNMK.NMK_WEIR, NoticeE3);    NmkCevni.put(CatNMK.NMK_FERN, NoticeE4a);
     1213        NmkCevni.put(CatNMK.NMK_FERI, NoticeE4b);   NmkCevni.put(CatNMK.NMK_BRTP, NoticeE5);    NmkCevni.put(CatNMK.NMK_BTLL, NoticeE5_1);  NmkCevni.put(CatNMK.NMK_BTLS, NoticeE5_2);
     1214        NmkCevni.put(CatNMK.NMK_BTRL, NoticeE5_3);  NmkCevni.put(CatNMK.NMK_BTUP, NoticeE5_4);  NmkCevni.put(CatNMK.NMK_BTP1, NoticeE5_5);  NmkCevni.put(CatNMK.NMK_BTP2, NoticeE5_6);
     1215        NmkCevni.put(CatNMK.NMK_BTP3, NoticeE5_7);  NmkCevni.put(CatNMK.NMK_BTUN, NoticeE5_8);  NmkCevni.put(CatNMK.NMK_BTN1, NoticeE5_9);  NmkCevni.put(CatNMK.NMK_BTN2, NoticeE5_10);
     1216        NmkCevni.put(CatNMK.NMK_BTN3, NoticeE5_11); NmkCevni.put(CatNMK.NMK_BTUM, NoticeE5_12); NmkCevni.put(CatNMK.NMK_BTU1, NoticeE5_13); NmkCevni.put(CatNMK.NMK_BTU2, NoticeE5_14);
     1217        NmkCevni.put(CatNMK.NMK_BTU3, NoticeE5_15); NmkCevni.put(CatNMK.NMK_ANKP, NoticeE6);    NmkCevni.put(CatNMK.NMK_MORP, NoticeE7);    NmkCevni.put(CatNMK.NMK_VLBT, NoticeE7_1);
     1218        NmkCevni.put(CatNMK.NMK_TRNA, NoticeE8);    NmkCevni.put(CatNMK.NMK_SWWC, NoticeE9a);   NmkCevni.put(CatNMK.NMK_SWWR, NoticeE9b);   NmkCevni.put(CatNMK.NMK_SWWL, NoticeE9c);
     1219        NmkCevni.put(CatNMK.NMK_WRSA, NoticeE9d);   NmkCevni.put(CatNMK.NMK_WLSA, NoticeE9e);   NmkCevni.put(CatNMK.NMK_WRSL, NoticeE9f);   NmkCevni.put(CatNMK.NMK_WLSR, NoticeE9g);
     1220        NmkCevni.put(CatNMK.NMK_WRAL, NoticeE9h);   NmkCevni.put(CatNMK.NMK_WLAR, NoticeE9i);   NmkCevni.put(CatNMK.NMK_MWWC, NoticeE10a);  NmkCevni.put(CatNMK.NMK_MWWJ, NoticeE10b);
     1221        NmkCevni.put(CatNMK.NMK_MWAR, NoticeE10c);  NmkCevni.put(CatNMK.NMK_MWAL, NoticeE10d);  NmkCevni.put(CatNMK.NMK_WARL, NoticeE10e);  NmkCevni.put(CatNMK.NMK_WALR, NoticeE10f);
     1222        NmkCevni.put(CatNMK.NMK_PEND, NoticeE11);   NmkCevni.put(CatNMK.NMK_DWTR, NoticeE13);   NmkCevni.put(CatNMK.NMK_TELE, NoticeE14);   NmkCevni.put(CatNMK.NMK_MTCP, NoticeE15);
     1223        NmkCevni.put(CatNMK.NMK_SPCP, NoticeE16);   NmkCevni.put(CatNMK.NMK_WSKP, NoticeE17);   NmkCevni.put(CatNMK.NMK_SLCP, NoticeE18);   NmkCevni.put(CatNMK.NMK_UPCP, NoticeE19);
     1224        NmkCevni.put(CatNMK.NMK_SLBP, NoticeE20);   NmkCevni.put(CatNMK.NMK_RADI, NoticeE23);   NmkCevni.put(CatNMK.NMK_WTBP, NoticeE24);   NmkCevni.put(CatNMK.NMK_HSCP, NoticeE21);
     1225        NmkCevni.put(CatNMK.NMK_LBGP, NoticeE22);
     1226    }
     1227    // CHECKSTYLE.ON: SingleSpaceSeparator
     1228
     1229    private static final Symbol NoticeBB = new Symbol();
     1230    static {
     1231        NoticeBB.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1232        NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(-29, -29, -29, 29)));
     1233        NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(29, -29, 29, 29)));
     1234        NoticeBB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1235        NoticeBB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1236    }
     1237
     1238    private static final Symbol NoticeBP = new Symbol();
     1239    static {
     1240        NoticeBP.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1241        NoticeBP.add(new Instr(Form.FILL, Color.white));
     1242        NoticeBP.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1243        NoticeBP.add(new Instr(Form.FILL, Color.black));
     1244        NoticeBP.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1245    }
     1246
     1247    private static final Symbol NoticeCR = new Symbol();
     1248    static {
     1249        NoticeCR.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1250        NoticeCR.add(new Instr(Form.FILL, Color.white));
     1251        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
     1252        NoticeCR.add(new Instr(Form.PGON, p));
     1253        NoticeCR.add(new Instr(Form.FILL, Color.black));
     1254        NoticeCR.add(new Instr(Form.PLIN, p));
     1255    }
     1256
     1257    private static final Symbol NoticeKT = new Symbol();
     1258    static {
     1259        NoticeKT.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1260        NoticeKT.add(new Instr(Form.FILL, Color.white));
     1261        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
     1262        NoticeKT.add(new Instr(Form.PGON, p));
     1263        NoticeKT.add(new Instr(Form.FILL, Color.black));
     1264        NoticeKT.add(new Instr(Form.PLIN, p));
     1265    }
     1266
     1267    public static final Symbol NoticeBnank = new Symbol();
     1268    static {
     1269        NoticeBnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1270        Symbol colours = new Symbol();
     1271        Symbol ss = new Symbol();
     1272        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1273        colours.add(new Instr(Form.N1, ss));
     1274        ss = new Symbol();
     1275        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
     1276        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     1277        ss.add(new Instr(Form.LINE, new Line2D.Double(-27, -27, 27, 27)));
     1278        ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1279        ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1280        colours.add(new Instr(Form.N2, ss));
     1281        NoticeBnank.add(new Instr(Form.COLR, colours));
     1282    }
     1283
     1284    public static final Symbol NoticeBlmhr = new Symbol();
     1285    static {
     1286        NoticeBlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1287        Symbol colours = new Symbol();
     1288        Symbol ss = new Symbol();
     1289        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1290        colours.add(new Instr(Form.N1, ss));
     1291        ss = new Symbol();
     1292        ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     1293        Path2D.Double p = new Path2D.Double(); p.moveTo(-29, -29); p.lineTo(29, -29); p.lineTo(0, 0); p.closePath();
     1294        ss.add(new Instr(Form.PGON, p));
     1295        ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1296        ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1297        colours.add(new Instr(Form.N2, ss));
     1298        NoticeBlmhr.add(new Instr(Form.COLR, colours));
     1299    }
     1300
     1301    public static final Symbol NoticeBktpm = new Symbol();
     1302    static {
     1303        NoticeBktpm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1304        Symbol colours = new Symbol();
     1305        Symbol ss = new Symbol();
     1306        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1307        colours.add(new Instr(Form.N1, ss));
     1308        ss = new Symbol();
     1309        Path2D.Double p = new Path2D.Double(); p.moveTo(-14, -26); p.lineTo(-20, -12); p.lineTo(-8, -12); p.closePath();
     1310        ss.add(new Instr(Form.PGON, p));
     1311        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1312        ss.add(new Instr(Form.LINE, new Line2D.Double(-14, -16, -14, 25)));
     1313        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1314        colours.add(new Instr(Form.N2, ss));
     1315        NoticeBktpm.add(new Instr(Form.COLR, colours));
     1316    }
     1317
     1318    public static final Symbol NoticeBktsm = new Symbol();
     1319    static {
     1320        NoticeBktsm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1321        Symbol colours = new Symbol();
     1322        Symbol ss = new Symbol();
     1323        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1324        colours.add(new Instr(Form.N1, ss));
     1325        ss = new Symbol();
     1326        Path2D.Double p = new Path2D.Double(); p.moveTo(14, -26); p.lineTo(20, -12); p.lineTo(8, -12); p.closePath();
     1327        ss.add(new Instr(Form.PGON, p));
     1328        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1329        ss.add(new Instr(Form.LINE, new Line2D.Double(14, -16, 14, 25)));
     1330        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1331        colours.add(new Instr(Form.N2, ss));
     1332        NoticeBktsm.add(new Instr(Form.COLR, colours));
     1333    }
     1334
     1335    public static final Symbol NoticeBktmr = new Symbol();
     1336    static {
     1337        NoticeBktmr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1338        Symbol colours = new Symbol();
     1339        Symbol ss = new Symbol();
     1340        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1341        colours.add(new Instr(Form.N1, ss));
     1342        ss = new Symbol();
     1343        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -26); p.lineTo(-6, -12); p.lineTo(6, -12); p.closePath();
     1344        ss.add(new Instr(Form.PGON, p));
     1345        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1346        ss.add(new Instr(Form.LINE, new Line2D.Double(0, -16, 0, 25)));
     1347        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1348        colours.add(new Instr(Form.N2, ss));
     1349        NoticeBktmr.add(new Instr(Form.COLR, colours));
     1350    }
     1351
     1352    public static final Symbol NoticeBcrtp = new Symbol();
     1353    static {
     1354        NoticeBcrtp.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1355        Symbol colours = new Symbol();
     1356        Symbol ss = new Symbol();
     1357        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1358        colours.add(new Instr(Form.N1, ss));
     1359        ss = new Symbol();
     1360        Path2D.Double p = new Path2D.Double(); p.moveTo(-14, -26); p.lineTo(-20, -12); p.lineTo(-8, -12); p.closePath();
     1361        ss.add(new Instr(Form.PGON, p));
     1362        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1363        p = new Path2D.Double(); p.moveTo(-14, -16); p.lineTo(-14, 0); p.lineTo(14, 10); p.lineTo(14, 25);
     1364        ss.add(new Instr(Form.PLIN, p));
     1365        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1366        colours.add(new Instr(Form.N2, ss));
     1367        NoticeBcrtp.add(new Instr(Form.COLR, colours));
     1368    }
     1369
     1370    public static final Symbol NoticeBcrts = new Symbol();
     1371    static {
     1372        NoticeBcrts.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1373        Symbol colours = new Symbol();
     1374        Symbol ss = new Symbol();
     1375        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1376        colours.add(new Instr(Form.N1, ss));
     1377        ss = new Symbol();
     1378        Path2D.Double p = new Path2D.Double(); p.moveTo(14, -26); p.lineTo(20, -12); p.lineTo(8, -12); p.closePath();
     1379        ss.add(new Instr(Form.PGON, p));
     1380        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1381        p = new Path2D.Double(); p.moveTo(14, -16); p.lineTo(14, 0); p.lineTo(-14, 10); p.lineTo(-14, 25);
     1382        ss.add(new Instr(Form.PLIN, p));
     1383        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1384        colours.add(new Instr(Form.N2, ss));
     1385        NoticeBcrts.add(new Instr(Form.COLR, colours));
     1386    }
     1387
     1388    public static final Symbol NoticeBtrbm = new Symbol();
     1389    static {
     1390        NoticeBtrbm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1391        Symbol colours = new Symbol();
     1392        Symbol ss = new Symbol();
     1393        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1394        colours.add(new Instr(Form.N1, ss));
     1395        ss = new Symbol();
     1396        ss.add(new Instr(Form.STRK, new BasicStroke(15, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1397        ss.add(new Instr(Form.LINE, new Line2D.Double(0, -25, 0, 25)));
     1398        ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1399        ss.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
     1400        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1401        colours.add(new Instr(Form.N2, ss));
     1402        NoticeBtrbm.add(new Instr(Form.COLR, colours));
     1403    }
     1404
     1405    public static final Symbol NoticeBrspd = new Symbol();
     1406    static {
     1407        NoticeBrspd.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1408        Symbol colours = new Symbol();
     1409        Symbol ss = new Symbol();
     1410        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1411        colours.add(new Instr(Form.N1, ss));
     1412        ss = new Symbol();
     1413        ss.add(new Instr(Form.TEXT, new Caption("R", new Font("Arial", Font.BOLD, 60), null, new Delta(Handle.CC, null))));
     1414        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
     1415        colours.add(new Instr(Form.N2, ss));
     1416        NoticeBrspd.add(new Instr(Form.COLR, colours));
     1417    }
     1418
     1419    static final Symbol NoticePBwral = new Symbol();
     1420    static {
     1421        NoticePBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1422        NoticePBwral.add(new Instr(Form.FILL, new Color(0xffff00)));
     1423        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, -25); p.lineTo(-8, -5); p.lineTo(-8, 25); p.lineTo(8, 25); p.lineTo(8, -5);
     1424        p.lineTo(20, -25); p.lineTo(5, -25); p.lineTo(-5, -10); p.lineTo(-15, -25); p.closePath();
     1425        NoticePBwral.add(new Instr(Form.PGON, p));
     1426    }
     1427
     1428    public static final Symbol NoticeBwral = new Symbol();
     1429    static {
     1430        NoticeBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1431        NoticeBwral.add(new Instr(Form.FILL, Color.black));
     1432        NoticeBwral.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1433        NoticeBwral.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, null)));
     1434    }
     1435
     1436    public static final Symbol NoticeBwlar = new Symbol();
     1437    static {
     1438        NoticeBwlar.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1439        NoticeBwlar.add(new Instr(Form.FILL, Color.black));
     1440        NoticeBwlar.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
     1441        NoticeBwlar.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getScaleInstance(-1, 1)))));
     1442    }
     1443
     1444    public static final Symbol NoticeBoptr = new Symbol();
     1445    static {
     1446        NoticeBoptr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1447        NoticeBoptr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
     1448        NoticeBoptr.add(new Instr(Form.FILL, new Color(0x00a000)));
     1449        NoticeBoptr.add(new Instr(Form.RSHP, new Rectangle2D.Double(-20, -20, 40, 40)));
     1450    }
     1451
     1452    public static final Symbol NoticeBoptl = new Symbol();
     1453    static {
     1454        NoticeBoptl.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1455        NoticeBoptl.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
     1456        NoticeBoptl.add(new Instr(Form.FILL, new Color(0xf00000)));
     1457        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -20); p.lineTo(-20, 20); p.lineTo(20, 20); p.closePath();
     1458        NoticeBoptl.add(new Instr(Form.PGON, p));
     1459    }
     1460
     1461    public static final EnumMap<CatNMK, Symbol> NmkBniwr = new EnumMap<>(CatNMK.class);
     1462    static {
     1463        NmkBniwr.put(CatNMK.NMK_NANK, NoticeBnank); NmkBniwr.put(CatNMK.NMK_LMHR, NoticeBlmhr); NmkBniwr.put(CatNMK.NMK_OPTR, NoticeBoptr); NmkBniwr.put(CatNMK.NMK_OPTL, NoticeBoptl);
     1464        NmkBniwr.put(CatNMK.NMK_WRAL, NoticeBwral); NmkBniwr.put(CatNMK.NMK_WLAR, NoticeBwlar); NmkBniwr.put(CatNMK.NMK_KTPM, NoticeBktpm); NmkBniwr.put(CatNMK.NMK_KTSM, NoticeBktsm);
     1465        NmkBniwr.put(CatNMK.NMK_KTMR, NoticeBktmr); NmkBniwr.put(CatNMK.NMK_CRTP, NoticeBcrtp); NmkBniwr.put(CatNMK.NMK_CRTS, NoticeBcrts); NmkBniwr.put(CatNMK.NMK_TRBM, NoticeBtrbm);
     1466        NmkBniwr.put(CatNMK.NMK_RSPD, NoticeBrspd);
     1467    }
     1468
     1469    public static final Symbol NoticePwralL = new Symbol();
     1470    static {
     1471        NoticePwralL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1472        NoticePwralL.add(new Instr(Form.FILL, Color.black));
     1473        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
     1474        NoticePwralL.add(new Instr(Form.PGON, p));
     1475        NoticePwralL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.TC, AffineTransform.getScaleInstance(0.5, 0.5)))));
     1476    }
     1477
     1478    public static final Symbol NoticePwralR = new Symbol();
     1479    static {
     1480        NoticePwralR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1481        NoticePwralR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwral, 1.0, 0, 0, null, null)));
     1482    }
     1483
     1484    public static final Symbol NoticePwlarL = new Symbol();
     1485    static {
     1486        NoticePwlarL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1487        NoticePwlarL.add(new Instr(Form.FILL, Color.black));
     1488        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
     1489        NoticePwlarL.add(new Instr(Form.PGON, p));
     1490        NoticePwlarL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.TC, AffineTransform.getScaleInstance(-0.5, 0.5)))));
     1491    }
     1492
     1493    public static final Symbol NoticePwlarR = new Symbol();
     1494    static {
     1495        NoticePwlarR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1496        NoticePwlarR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwlar, 1.0, 0, 0, null, null)));
     1497    }
     1498
     1499    public static final Symbol NoticePktmR = new Symbol();
     1500    static {
     1501        NoticePktmR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1502        NoticePktmR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
     1503        NoticePktmR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1504        NoticePktmR.add(new Instr(Form.FILL, new Color(0x00d400)));
     1505        NoticePktmR.add(new Instr(Form.RECT, new Rectangle2D.Double(-20, -20, 40, 40)));
     1506    }
     1507
     1508    public static final Symbol NoticePktmL = new Symbol();
     1509    static {
     1510        NoticePktmL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1511        NoticePktmL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
     1512        NoticePktmL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1513        NoticePktmL.add(new Instr(Form.FILL, new Color(0xd40000)));
     1514        NoticePktmL.add(new Instr(Form.RECT, new Rectangle2D.Double(-12, 2, 24, 24)));
     1515    }
     1516
     1517    public static final Symbol NoticePktmrL = new Symbol();
     1518    static {
     1519        NoticePktmrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1520        NoticePktmrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
     1521        NoticePktmrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1522        NoticePktmrL.add(new Instr(Form.FILL, new Color(0xd40000)));
     1523        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 2, -12, 28)));
     1524        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(12, 2, 12, 28)));
     1525        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 15, 12, 15)));
     1526    }
     1527
     1528    public static final Symbol NoticePktmrR = new Symbol();
     1529    static {
     1530        NoticePktmrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1531        NoticePktmrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
     1532        NoticePktmrR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1533        NoticePktmrR.add(new Instr(Form.FILL, new Color(0x00d400)));
     1534        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15, -20, -15, 20)));
     1535        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(15, -20, 15, 20)));
     1536        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15, 0, 15, 0)));
     1537    }
     1538
     1539    public static final Symbol NoticePcrL = new Symbol();
     1540    static {
     1541        NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1542        NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1543        NoticePcrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
     1544        NoticePcrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1545        NoticePcrL.add(new Instr(Form.FILL, new Color(0xd40000)));
     1546        NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 12, 12)));
     1547        NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 12, 12, -12)));
     1548    }
     1549
     1550    public static final Symbol NoticePcrR = new Symbol();
     1551    static {
     1552        NoticePcrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1553        NoticePcrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
     1554        NoticePcrR.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1555        NoticePcrR.add(new Instr(Form.FILL, new Color(0x00d400)));
     1556        NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 12, 12)));
     1557        NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12, 12, 12, -12)));
     1558    }
     1559
     1560    static final Symbol NoticeRphib = new Symbol();
     1561    static {
     1562        NoticeRphib.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1563        NoticeRphib.add(new Instr(Form.FILL, new Color(0xd40000)));
     1564        NoticeRphib.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
     1565        NoticeRphib.add(new Instr(Form.LINE, new Line2D.Double(-20, -20, 20, 20)));
     1566    }
     1567
     1568    static final Symbol NoticeRinfo = new Symbol();
     1569    static {
     1570        NoticeRinfo.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1571        NoticeRinfo.add(new Instr(Form.FILL, new Color(0xd40000)));
     1572        NoticeRinfo.add(new Instr(Form.RECT, new Rectangle2D.Double(-30, -30, 60, 60)));
     1573    }
     1574
     1575    public static final Symbol NoticeRnpas = new Symbol();
     1576    static {
     1577        NoticeRnpas.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1578        NoticeRnpas.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
     1579        NoticeRnpas.add(new Instr(Form.FILL, Color.black));
     1580        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, -15); p.lineTo(-10, 8); p.lineTo(-6, 8); p.lineTo(-12.5, 16); p.lineTo(-19, 8); p.lineTo(-15, 8); p.lineTo(-15, -15);
     1581        p.closePath(); p.moveTo(10, 15); p.lineTo(10, -8); p.lineTo(6, -8); p.lineTo(12.5, -16); p.lineTo(19, -8); p.lineTo(15, -8); p.lineTo(15, 15); p.closePath();
     1582        NoticeRnpas.add(new Instr(Form.PGON, p));
     1583    }
     1584
     1585    public static final Symbol NoticeRnank = new Symbol();
     1586    static {
     1587        NoticeRnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1588        NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
     1589        NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), null)));
     1590    }
     1591
     1592    public static final Symbol NoticeRnwsh = new Symbol();
     1593    static {
     1594        NoticeRnwsh.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1595        NoticeRnwsh.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
     1596        NoticeRnwsh.add(new Instr(Form.FILL, Color.black));
     1597        Path2D.Double p = new Path2D.Double(); p.moveTo(-23, 10); p.curveTo(-11, 10, -12, 4, 0, 4); p.curveTo(12, 4, 11, 10, 23, 10);
     1598        p.moveTo(-23, -3); p.curveTo(-11, -3, -12, -9, 0, -9); p.curveTo(12, -9, 11, -3, 23, -3);
     1599        NoticeRnwsh.add(new Instr(Form.PLIN, p));
     1600    }
     1601
     1602    public static final Symbol NoticeRlmhr = new Symbol();
     1603    static {
     1604        NoticeRlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1605        NoticeRlmhr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
     1606        NoticeRlmhr.add(new Instr(Form.FILL, Color.black));
     1607        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -10); p.lineTo(27, -27); p.lineTo(-27, -27); p.closePath();
     1608        NoticeRlmhr.add(new Instr(Form.PGON, p));
     1609    }
     1610
     1611    public static final Symbol NoticeRtrna = new Symbol();
     1612    static {
     1613        NoticeRtrna.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1614        NoticeRtrna.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
     1615        NoticeRtrna.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1616        NoticeRtrna.add(new Instr(Form.EARC, new Arc2D.Double(-15.0, -15.0, 30.0, 30.0, 315.0, -280.0, Arc2D.OPEN)));
     1617        Path2D.Double p = new Path2D.Double(); p.moveTo(18.8, -2.0); p.lineTo(15.8, -13.2); p.lineTo(7.5, -5.0); p.closePath();
     1618        NoticeRtrna.add(new Instr(Form.PGON, p));
     1619    }
     1620
     1621    public static final Symbol NoticeRncps = new Symbol();
     1622    static {
     1623        NoticeRncps.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1624        NoticeRncps.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
     1625        NoticeRncps.add(new Instr(Form.FILL, Color.black));
     1626        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 0); p.lineTo(-10, 8); p.lineTo(-6, 8); p.lineTo(-12.5, 16); p.lineTo(-19, 8); p.lineTo(-15, 8); p.lineTo(-15, 0);
     1627        p.closePath(); p.moveTo(10, 0); p.lineTo(10, -8); p.lineTo(6, -8); p.lineTo(12.5, -16); p.lineTo(19, -8); p.lineTo(15, -8); p.lineTo(15, 0); p.closePath();
     1628        NoticeRncps.add(new Instr(Form.PGON, p));
     1629    }
     1630
     1631    public static final Symbol NoticeRnsmc = new Symbol();
     1632    static {
     1633        NoticeRnsmc.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1634        NoticeRnsmc.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
     1635        NoticeRnsmc.add(new Instr(Form.FILL, Color.black));
     1636        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, 5); p.lineTo(15, 5); p.lineTo(25, -10); p.lineTo(12, -5); p.lineTo(-18, -1); p.closePath();
     1637        p.moveTo(-23, 2); p.lineTo(-21, 10); p.lineTo(-18, 8); p.lineTo(-20, 0); p.closePath();
     1638        NoticeRnsmc.add(new Instr(Form.PGON, p));
     1639    }
     1640
     1641    public static final Symbol NoticeRattn = new Symbol();
     1642    static {
     1643        NoticeRattn.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1644        NoticeRattn.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
     1645        NoticeRattn.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     1646        NoticeRattn.add(new Instr(Form.FILL, Color.black));
     1647        NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 10)));
     1648        NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0, 15, 0, 20)));
     1649    }
     1650
     1651    public static final Symbol NoticeRfwcr = new Symbol();
     1652    static {
     1653        NoticeRfwcr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1654        NoticeRfwcr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
     1655        NoticeRfwcr.add(new Instr(Form.FILL, Color.black));
     1656        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(-8, -15); p.lineTo(-8, 5); p.lineTo(-20, 5); p.lineTo(-20, 15); p.lineTo(-8, 15); p.lineTo(-8, 25);
     1657        p.lineTo(8, 25); p.lineTo(8, 15); p.lineTo(20, 15); p.lineTo(20, 5); p.lineTo(8, 5); p.lineTo(8, -15); p.closePath();
     1658        NoticeRfwcr.add(new Instr(Form.PGON, p));
     1659    }
     1660
     1661    public static final Symbol NoticeRship = new Symbol();
     1662    static {
     1663        NoticeRship.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
     1664        NoticeRship.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
     1665        NoticeRship.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
     1666        NoticeRship.add(new Instr(Form.FILL, Color.black));
     1667        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 10, 10)));
     1668        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12, -8, -8, -12)));
     1669        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12, -12, -10, 10)));
     1670        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12, -8, 8, -12)));
     1671        NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-17, -13, 30, 30, 185, 80, Arc2D.OPEN)));
     1672        NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-13, -13, 30, 30, 275, 80, Arc2D.OPEN)));
     1673    }
     1674
     1675    public static final EnumMap<CatNMK, Symbol> NmkPpwbcl = new EnumMap<>(CatNMK.class);
     1676    static {
     1677        NmkPpwbcl.put(CatNMK.NMK_WRAL, NoticePwralL); NmkPpwbcl.put(CatNMK.NMK_WLAR, NoticePwlarL); NmkPpwbcl.put(CatNMK.NMK_KTPM, NoticePktmL); NmkPpwbcl.put(CatNMK.NMK_KTSM, NoticePktmL);
     1678        NmkPpwbcl.put(CatNMK.NMK_KTMR, NoticePktmrL); NmkPpwbcl.put(CatNMK.NMK_CRTP, NoticePcrL); NmkPpwbcl.put(CatNMK.NMK_CRTS, NoticePcrL);
     1679    }
     1680
     1681    public static final EnumMap<CatNMK, Symbol> NmkPpwbcr = new EnumMap<>(CatNMK.class);
     1682    static {
     1683        NmkPpwbcr.put(CatNMK.NMK_WRAL, NoticePwralR); NmkPpwbcr.put(CatNMK.NMK_WLAR, NoticePwlarR); NmkPpwbcr.put(CatNMK.NMK_KTPM, NoticePktmR); NmkPpwbcr.put(CatNMK.NMK_KTSM, NoticePktmR);
     1684        NmkPpwbcr.put(CatNMK.NMK_KTMR, NoticePktmrR); NmkPpwbcr.put(CatNMK.NMK_CRTP, NoticePcrR); NmkPpwbcr.put(CatNMK.NMK_CRTS, NoticePcrR);
     1685    }
     1686
     1687    public static final EnumMap<CatNMK, Symbol> NmkRiwr = new EnumMap<>(CatNMK.class);
     1688    static {
     1689        NmkRiwr.put(CatNMK.NMK_NPAS, NoticeRnpas); NmkRiwr.put(CatNMK.NMK_NANK, NoticeRnank); NmkRiwr.put(CatNMK.NMK_NWSH, NoticeRnwsh); NmkRiwr.put(CatNMK.NMK_LMHR, NoticeRlmhr); NmkRiwr.put(CatNMK.NMK_TRNA, NoticeRtrna);
     1690        NmkRiwr.put(CatNMK.NMK_NCPS, NoticeRncps); NmkRiwr.put(CatNMK.NMK_NSMC, NoticeRnsmc); NmkRiwr.put(CatNMK.NMK_ATTN, NoticeRattn); NmkRiwr.put(CatNMK.NMK_FWCR, NoticeRfwcr); NmkRiwr.put(CatNMK.NMK_SHIP, NoticeRship);
     1691    }
     1692
     1693    public static Scheme getScheme(MarSYS sys, BnkWTW bank) {
     1694        ArrayList<Color> colours = new ArrayList<>();
     1695        Scheme scheme = new Scheme(colours);
     1696        switch (sys) {
     1697        case SYS_BNWR:
     1698        case SYS_BWR2:
     1699            switch (bank) {
     1700            case BWW_LEFT:
     1701                colours.add(Color.white);
     1702                colours.add(new Color(0xf00000));
     1703                break;
     1704            case BWW_RGHT:
     1705                colours.add(Color.white);
     1706                colours.add(new Color(0x00a000));
     1707                break;
     1708            default:
     1709                colours.add(new Color(0xff8040));
     1710                colours.add(Color.black);
     1711                break;
     1712            }
     1713            break;
     1714        default:
     1715            break;
     1716        }
     1717        return scheme;
     1718    }
     1719
     1720    public static Symbol getNotice(CatNMK cat, MarSYS sys, BnkWTW bank) {
     1721        Symbol symbol = null;
     1722        switch (sys) {
     1723        case SYS_CEVN:
     1724            symbol = NmkCevni.get(cat);
     1725            break;
     1726        case SYS_BNWR:
     1727        case SYS_BWR2:
     1728            symbol = NmkBniwr.get(cat);
     1729            break;
     1730        case SYS_PPWB:
     1731            switch (bank) {
     1732            case BWW_LEFT:
     1733                symbol = NmkPpwbcl.get(cat);
     1734                break;
     1735            case BWW_RGHT:
     1736                symbol = NmkPpwbcr.get(cat);
     1737                break;
     1738            default:
     1739                break;
     1740            }
     1741            break;
     1742        case SYS_RIWR:
     1743            symbol = NmkRiwr.get(cat);
     1744            break;
     1745        default:
     1746            break;
     1747        }
     1748        return symbol;
     1749    }
    15791750}
  • applications/editors/josm/plugins/seachart/src/symbols/Symbols.java

    r32393 r32394  
    1515import java.awt.Graphics2D;
    1616import java.awt.font.TextLayout;
    17 import java.awt.geom.*;
     17import java.awt.geom.AffineTransform;
     18import java.awt.geom.Arc2D;
     19import java.awt.geom.Ellipse2D;
     20import java.awt.geom.Line2D;
     21import java.awt.geom.Path2D;
     22import java.awt.geom.Rectangle2D;
     23import java.awt.geom.RectangularShape;
     24import java.awt.geom.RoundRectangle2D;
    1825import java.util.ArrayList;
    1926
    2027public class Symbols {
    21 
    22         public static final Color Yland = new Color(0xedbc0c);
    23 //      public static final Color Bwater = new Color(0x78acd2);
    24         public static final Color Bwater = new Color(0x9bc5e3);
    25         public static final Color Gdries = new Color(0x689868);
    26         public static final Color Mline = new Color(0x9a6078);
    27         public static final Color Msymb = new Color(0xa30075);
    28         public static final Color Mtss = new Color(0xc0c480ff, true);
    29        
    30         public enum Form {
    31                 BBOX, STRK, COLR, FILL, LINE, RECT, RRCT, ELPS, EARC, PLIN, PGON, RSHP, TEXT, SYMB, N1, N2, P1, P2, H2, H3, H4, H5, V2, V3, D2, D3, D4, B1, S2, S3, S4, C2, X2
    32         }
    33 
    34         public enum Patt {
    35                 Z, H, V, D, B, S, C, X
    36         }
    37 
    38         public enum Handle {
    39                 CC, TL, TR, TC, LC, RC, BL, BR, BC
    40         }
    41 
    42         public static class Instr {
    43                 public Form type;
    44                 public Object params;
    45 
    46                 public Instr(Form itype, Object iparams) {
    47                         type = itype;
    48                         params = iparams;
    49                 }
    50         }
    51 
    52         public static class Delta {
    53                 public Handle h;
    54                 public AffineTransform t;
    55 
    56                 public Delta(Handle ih, AffineTransform it) {
    57                         h = ih;
    58                         t = it;
    59                 }
    60                 public Delta(Handle ih) {
    61                         h = ih;
    62                         t = new AffineTransform();
    63                 }
    64         }
    65 
    66         public static class Scheme {
    67                 public ArrayList<Patt> pat;
    68                 public ArrayList<Color> col;
    69 
    70                 public Scheme(ArrayList<Color> icol) {
    71                         pat = new ArrayList<>();
    72                         col = icol;
    73                 }
    74                 public Scheme(ArrayList<Patt> ipat, ArrayList<Color> icol) {
    75                         pat = ipat;
    76                         col = icol;
    77                 }
    78                 public Scheme(Color icol) {
    79                         pat = new ArrayList<>();
    80                         col = new ArrayList<>();
    81                         col.add(icol);
    82                 }
    83                 public Scheme() {
    84                         pat = new ArrayList<>();
    85                         col = new ArrayList<>();
    86                 }
    87         }
    88 
    89         public static class Caption {
    90                 public String string;
    91                 public Font font;
    92                 public Color colour;
    93                 public Delta dd;
    94 
    95                 public Caption(String istr, Font ifont, Color icolour, Delta idd) {
    96                         string = istr;
    97                         font = ifont;
    98                         colour = icolour;
    99                         dd = idd;
    100                 }
    101         }
    102 
    103         public static class LineStyle {
    104                 public Color line;
    105                 public float width;
    106                 public float[] dash;
    107                 public Color fill;
    108 
    109                 public LineStyle(Color ifill) {
    110                         line = null;
    111                         width = 0;
    112                         dash = null;
    113                         fill = ifill;
    114                 }
    115                 public LineStyle(Color iline, float iwidth) {
    116                         line = iline;
    117                         width = iwidth;
    118                         dash = null;
    119                         fill = null;
    120                 }
    121                 public LineStyle(Color iline, float iwidth, float[] idash) {
    122                         line = iline;
    123                         width = iwidth;
    124                         dash = idash;
    125                         fill = null;
    126                 }
    127                 public LineStyle(Color iline, float iwidth, Color ifill) {
    128                         line = iline;
    129                         width = iwidth;
    130                         dash = null;
    131                         fill = ifill;
    132                 }
    133                 public LineStyle(Color iline, float iwidth, float[] idash, Color ifill) {
    134                         line = iline;
    135                         width = iwidth;
    136                         dash = idash;
    137                         fill = ifill;
    138                 }
    139         }
    140 
    141         public static class Symbol extends ArrayList<Instr> {
    142 
    143                 public Symbol() {
    144                         super();
    145                 }
    146         }
    147        
    148         public static class SubSymbol {
    149                 public Symbol instr;
    150                 public double scale;
    151                 public double x;
    152                 public double y;
    153                 public Delta delta;
    154                 public Scheme scheme;
    155 
    156                 public SubSymbol(Symbol iinstr, double iscale, double ix, double iy, Scheme ischeme, Delta idelta) {
    157                         instr = iinstr;
    158                         scale = iscale;
    159                         x = ix;
    160                         y = iy;
    161                         delta = idelta;
    162                         scheme = ischeme;
    163                 }
    164         }
    165 
    166         public static void drawSymbol(Graphics2D g2, Symbol symbol, double scale, double x, double y, Scheme cs, Delta dd) {
    167                 int pn = 0;
    168                 int cn = 0;
    169                 Patt bpat = Patt.Z;
    170                 Color bcol = null;
    171                 g2.setPaint(Color.black);
    172                 if (cs != null) {
    173                         if ((cs.pat.size() > 0) && (cs.col.size() > 0) && (cs.pat.get(0) == Patt.B)) {
    174                                 bpat = (cs.pat.remove(0));
    175                                 bcol = (cs.col.remove(0));
    176                         }
    177                         pn = cs.pat.size();
    178                         cn = cs.col.size() - ((pn != 0) ? pn - 1 : 0);
    179                         if ((pn == 0) && (cs.col.size() == 1)) {
    180                                 g2.setPaint(cs.col.get(0));
    181                         }
    182                 }
    183                 AffineTransform savetr = g2.getTransform();
    184                 g2.translate(x, y);
    185                 g2.scale(scale, scale);
    186                 if (symbol != null) {
    187                         for (Instr item : symbol) {
    188                                 switch (item.type) {
    189                                 case BBOX:
    190                                         Rectangle2D.Double bbox = (Rectangle2D.Double) item.params;
    191                                         double dx = 0.0;
    192                                         double dy = 0.0;
    193                                         if (dd != null) {
    194                                                 g2.transform(dd.t);
    195                                                 switch (dd.h) {
    196                                                 case CC:
    197                                                         dx -= bbox.x + (bbox.width / 2.0);
    198                                                         dy -= bbox.y + (bbox.height / 2.0);
    199                                                         break;
    200                                                 case TL:
    201                                                         dx -= bbox.x;
    202                                                         dy -= bbox.y;
    203                                                         break;
    204                                                 case TR:
    205                                                         dx -= bbox.x + bbox.width;
    206                                                         dy -= bbox.y;
    207                                                         break;
    208                                                 case TC:
    209                                                         dx -= bbox.x + (bbox.width / 2.0);
    210                                                         dy -= bbox.y;
    211                                                         break;
    212                                                 case LC:
    213                                                         dx -= bbox.x;
    214                                                         dy -= bbox.y + (bbox.height / 2.0);
    215                                                         break;
    216                                                 case RC:
    217                                                         dx -= bbox.x + bbox.width;
    218                                                         dy -= bbox.y + (bbox.height / 2.0);
    219                                                         break;
    220                                                 case BL:
    221                                                         dx -= bbox.x;
    222                                                         dy -= bbox.y + bbox.height;
    223                                                         break;
    224                                                 case BR:
    225                                                         dx -= bbox.x + bbox.width;
    226                                                         dy -= bbox.y + bbox.height;
    227                                                         break;
    228                                                 case BC:
    229                                                         dx -= bbox.x + (bbox.width / 2.0);
    230                                                         dy -= bbox.y + bbox.height;
    231                                                         break;
    232                                                 }
    233                                                 g2.translate(dx, dy);
    234                                         }
    235                                         break;
    236                                 case COLR:
    237                                         if ((cs != null) && (cs.col != null)) {
    238                                                 for (Instr patch : (Symbol) item.params) {
    239                                                         switch (patch.type) {
    240                                                         case N1:
    241                                                                 if (cn > 0) {
    242                                                                         Symbol s = (Symbol) patch.params;
    243                                                                         drawSymbol(g2, s, 1.0, 0, 0, new Scheme(cs.col.get(0)), null);
    244                                                                 }
    245                                                                 break;
    246                                                         case N2:
    247                                                                 if (cn > 0) {
    248                                                                         Symbol s = (Symbol) patch.params;
    249                                                                         drawSymbol(g2, s, 1.0, 0, 0, new Scheme((cn > 1) ? cs.col.get(1) : cs.col.get(0)), null);
    250                                                                 }
    251                                                                 break;
    252                                                         case P1:
    253                                                                 if (cn > 0) {
    254                                                                         g2.setPaint(cs.col.get(0));
    255                                                                         g2.fill((Path2D.Double) patch.params);
    256                                                                 }
    257                                                                 break;
    258                                                         case P2:
    259                                                                 if (cn > 0) {
    260                                                                         if (cn > 1) {
    261                                                                                 g2.setPaint(cs.col.get(1));
    262                                                                         } else {
    263                                                                                 g2.setPaint(cs.col.get(0));
    264                                                                         }
    265                                                                         g2.fill((Path2D.Double) patch.params);
    266                                                                 }
    267                                                                 break;
    268                                                         case H2:
    269                                                                 if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
    270                                                                         g2.setPaint(cs.col.get(cs.col.size() - pn));
    271                                                                         g2.fill((Path2D.Double) patch.params);
    272                                                                 }
    273                                                                 break;
    274                                                         case H3:
    275                                                                 if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
    276                                                                         g2.setPaint(cs.col.get(1));
    277                                                                         g2.fill((Path2D.Double) patch.params);
    278                                                                 }
    279                                                                 break;
    280                                                         case H4:
    281                                                                 if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
    282                                                                         g2.setPaint(cs.col.get(1));
    283                                                                         g2.fill((Path2D.Double) patch.params);
    284                                                                 }
    285                                                                 break;
    286                                                         case H5:
    287                                                                 if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
    288                                                                         g2.setPaint(cs.col.get(2));
    289                                                                         g2.fill((Path2D.Double) patch.params);
    290                                                                 }
    291                                                                 break;
    292                                                         case V2:
    293                                                                 if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
    294                                                                         g2.setPaint(cs.col.get(cs.col.size() - pn));
    295                                                                         g2.fill((Path2D.Double) patch.params);
    296                                                                 }
    297                                                                 break;
    298                                                         case V3:
    299                                                                 if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
    300                                                                         g2.setPaint(cs.col.get(1));
    301                                                                         g2.fill((Path2D.Double) patch.params);
    302                                                                 }
    303                                                                 break;
    304                                                         case B1:
    305                                                                 if (bpat == Patt.B) {
    306                                                                         g2.setPaint(bcol);
    307                                                                         g2.fill((Path2D.Double) patch.params);
    308                                                                 }
    309                                                                 break;
    310                                                         case S2:
    311                                                                 if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
    312                                                                         g2.setPaint(cs.col.get(1));
    313                                                                         g2.fill((Path2D.Double) patch.params);
    314                                                                 }
    315                                                                 break;
    316                                                         case S3:
    317                                                                 if ((cn > 2) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
    318                                                                         g2.setPaint(cs.col.get(2));
    319                                                                         g2.fill((Path2D.Double) patch.params);
    320                                                                 }
    321                                                                 break;
    322                                                         case S4:
    323                                                                 if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
    324                                                                         g2.setPaint(cs.col.get(3));
    325                                                                         g2.fill((Path2D.Double) patch.params);
    326                                                                 }
    327                                                                 break;
    328                                                         default:
    329                                                                 break;
    330                                                         }
    331                                                 }
    332                                         }
    333                                         break;
    334                                 case STRK:
    335                                         g2.setStroke((BasicStroke) item.params);
    336                                         break;
    337                                 case FILL:
    338                                         g2.setPaint((Color) item.params);
    339                                         break;
    340                                 case LINE:
    341                                         g2.draw((Line2D.Double) item.params);
    342                                         break;
    343                                 case RECT:
    344                                         g2.draw((Rectangle2D.Double) item.params);
    345                                         break;
    346                                 case RRCT:
    347                                         g2.draw((RoundRectangle2D.Double) item.params);
    348                                         break;
    349                                 case ELPS:
    350                                         g2.draw((Ellipse2D.Double) item.params);
    351                                         break;
    352                                 case EARC:
    353                                         g2.draw((Arc2D.Double) item.params);
    354                                         break;
    355                                 case PLIN:
    356                                         g2.draw((Path2D.Double) item.params);
    357                                         break;
    358                                 case PGON:
    359                                         g2.fill((Path2D.Double) item.params);
    360                                         break;
    361                                 case RSHP:
    362                                         g2.fill((RectangularShape) item.params);
    363                                         break;
    364                                 case SYMB:
    365                                         SubSymbol s = (SubSymbol) item.params;
    366                                         drawSymbol(g2, s.instr, s.scale, s.x, s.y, (s.scheme != null ? s.scheme : cs), s.delta);
    367                                         break;
    368                                 case TEXT:
    369                                         Caption c = (Caption) item.params;
    370                                         g2.setPaint(c.colour);
    371                                         TextLayout layout = new TextLayout(c.string, c.font, g2.getFontRenderContext());
    372                                         Rectangle2D bb = layout.getBounds();
    373                                         dx = 0;
    374                                         dy = 0;
    375                                         if (c.dd != null) {
    376                                                 if (c.dd.t != null) g2.transform(c.dd.t);
    377                                                 switch (c.dd.h) {
    378                                                 case CC:
    379                                                         dx -= bb.getX() + (bb.getWidth() / 2.0);
    380                                                         dy -= bb.getY() + (bb.getHeight() / 2.0);
    381                                                         break;
    382                                                 case TL:
    383                                                         dx -= bb.getX();
    384                                                         dy -= bb.getY();
    385                                                         break;
    386                                                 case TR:
    387                                                         dx -= bb.getX() + bb.getWidth();
    388                                                         dy -= bb.getY();
    389                                                         break;
    390                                                 case TC:
    391                                                         dx -= bb.getX() + (bb.getWidth() / 2.0);
    392                                                         dy -= bb.getY();
    393                                                         break;
    394                                                 case LC:
    395                                                         dx -= bb.getX();
    396                                                         dy -= bb.getY() + (bb.getHeight() / 2.0);
    397                                                         break;
    398                                                 case RC:
    399                                                         dx -= bb.getX() + bb.getWidth();
    400                                                         dy -= bb.getY() + (bb.getHeight() / 2.0);
    401                                                         break;
    402                                                 case BL:
    403                                                         dx -= bb.getX();
    404                                                         dy -= bb.getY() + bb.getHeight();
    405                                                         break;
    406                                                 case BR:
    407                                                         dx -= bb.getX() + bb.getWidth();
    408                                                         dy -= bb.getY() + bb.getHeight();
    409                                                         break;
    410                                                 case BC:
    411                                                         dx -= bb.getX() + (bb.getWidth() / 2.0);
    412                                                         dy -= bb.getY() + bb.getHeight();
    413                                                         break;
    414                                                 }
    415                                         }
    416                                         layout.draw(g2, (float)dx, (float)dy);
    417                                         break;
    418                                 default:
    419                                         break;
    420                                 }
    421                         }
    422                 }
    423                 g2.setTransform(savetr);
    424         }
     28    // CHECKSTYLE.OFF: LineLength
     29    public static final Color Yland = new Color(0xedbc0c);
     30    //    public static final Color Bwater = new Color(0x78acd2);
     31    public static final Color Bwater = new Color(0x9bc5e3);
     32    public static final Color Gdries = new Color(0x689868);
     33    public static final Color Mline = new Color(0x9a6078);
     34    public static final Color Msymb = new Color(0xa30075);
     35    public static final Color Mtss = new Color(0xc0c480ff, true);
     36
     37    public enum Form {
     38        BBOX, STRK, COLR, FILL, LINE, RECT, RRCT, ELPS, EARC, PLIN, PGON, RSHP, TEXT, SYMB, N1, N2, P1, P2, H2, H3, H4, H5, V2, V3, D2, D3, D4, B1, S2, S3, S4, C2, X2
     39    }
     40
     41    public enum Patt {
     42        Z, H, V, D, B, S, C, X
     43    }
     44
     45    public enum Handle {
     46        CC, TL, TR, TC, LC, RC, BL, BR, BC
     47    }
     48
     49    public static class Instr {
     50        public Form type;
     51        public Object params;
     52
     53        public Instr(Form itype, Object iparams) {
     54            type = itype;
     55            params = iparams;
     56        }
     57    }
     58
     59    public static class Delta {
     60        public Handle h;
     61        public AffineTransform t;
     62
     63        public Delta(Handle ih, AffineTransform it) {
     64            h = ih;
     65            t = it;
     66        }
     67
     68        public Delta(Handle ih) {
     69            h = ih;
     70            t = new AffineTransform();
     71        }
     72    }
     73
     74    public static class Scheme {
     75        public ArrayList<Patt> pat;
     76        public ArrayList<Color> col;
     77
     78        public Scheme(ArrayList<Color> icol) {
     79            pat = new ArrayList<>();
     80            col = icol;
     81        }
     82
     83        public Scheme(ArrayList<Patt> ipat, ArrayList<Color> icol) {
     84            pat = ipat;
     85            col = icol;
     86        }
     87
     88        public Scheme(Color icol) {
     89            pat = new ArrayList<>();
     90            col = new ArrayList<>();
     91            col.add(icol);
     92        }
     93
     94        public Scheme() {
     95            pat = new ArrayList<>();
     96            col = new ArrayList<>();
     97        }
     98    }
     99
     100    public static class Caption {
     101        public String string;
     102        public Font font;
     103        public Color colour;
     104        public Delta dd;
     105
     106        public Caption(String istr, Font ifont, Color icolour, Delta idd) {
     107            string = istr;
     108            font = ifont;
     109            colour = icolour;
     110            dd = idd;
     111        }
     112    }
     113
     114    public static class LineStyle {
     115        public Color line;
     116        public float width;
     117        public float[] dash;
     118        public Color fill;
     119
     120        public LineStyle(Color ifill) {
     121            line = null;
     122            width = 0;
     123            dash = null;
     124            fill = ifill;
     125        }
     126
     127        public LineStyle(Color iline, float iwidth) {
     128            line = iline;
     129            width = iwidth;
     130            dash = null;
     131            fill = null;
     132        }
     133
     134        public LineStyle(Color iline, float iwidth, float[] idash) {
     135            line = iline;
     136            width = iwidth;
     137            dash = idash;
     138            fill = null;
     139        }
     140
     141        public LineStyle(Color iline, float iwidth, Color ifill) {
     142            line = iline;
     143            width = iwidth;
     144            dash = null;
     145            fill = ifill;
     146        }
     147
     148        public LineStyle(Color iline, float iwidth, float[] idash, Color ifill) {
     149            line = iline;
     150            width = iwidth;
     151            dash = idash;
     152            fill = ifill;
     153        }
     154    }
     155
     156    public static class Symbol extends ArrayList<Instr> {
     157
     158        public Symbol() {
     159            super();
     160        }
     161    }
     162
     163    public static class SubSymbol {
     164        public Symbol instr;
     165        public double scale;
     166        public double x;
     167        public double y;
     168        public Delta delta;
     169        public Scheme scheme;
     170
     171        public SubSymbol(Symbol iinstr, double iscale, double ix, double iy, Scheme ischeme, Delta idelta) {
     172            instr = iinstr;
     173            scale = iscale;
     174            x = ix;
     175            y = iy;
     176            delta = idelta;
     177            scheme = ischeme;
     178        }
     179    }
     180
     181    public static void drawSymbol(Graphics2D g2, Symbol symbol, double scale, double x, double y, Scheme cs, Delta dd) {
     182        int pn = 0;
     183        int cn = 0;
     184        Patt bpat = Patt.Z;
     185        Color bcol = null;
     186        g2.setPaint(Color.black);
     187        if (cs != null) {
     188            if ((cs.pat.size() > 0) && (cs.col.size() > 0) && (cs.pat.get(0) == Patt.B)) {
     189                bpat = (cs.pat.remove(0));
     190                bcol = (cs.col.remove(0));
     191            }
     192            pn = cs.pat.size();
     193            cn = cs.col.size() - ((pn != 0) ? pn - 1 : 0);
     194            if ((pn == 0) && (cs.col.size() == 1)) {
     195                g2.setPaint(cs.col.get(0));
     196            }
     197        }
     198        AffineTransform savetr = g2.getTransform();
     199        g2.translate(x, y);
     200        g2.scale(scale, scale);
     201        if (symbol != null) {
     202            for (Instr item : symbol) {
     203                switch (item.type) {
     204                case BBOX:
     205                    Rectangle2D.Double bbox = (Rectangle2D.Double) item.params;
     206                    double dx = 0.0;
     207                    double dy = 0.0;
     208                    if (dd != null) {
     209                        g2.transform(dd.t);
     210                        switch (dd.h) {
     211                        case CC:
     212                            dx -= bbox.x + (bbox.width / 2.0);
     213                            dy -= bbox.y + (bbox.height / 2.0);
     214                            break;
     215                        case TL:
     216                            dx -= bbox.x;
     217                            dy -= bbox.y;
     218                            break;
     219                        case TR:
     220                            dx -= bbox.x + bbox.width;
     221                            dy -= bbox.y;
     222                            break;
     223                        case TC:
     224                            dx -= bbox.x + (bbox.width / 2.0);
     225                            dy -= bbox.y;
     226                            break;
     227                        case LC:
     228                            dx -= bbox.x;
     229                            dy -= bbox.y + (bbox.height / 2.0);
     230                            break;
     231                        case RC:
     232                            dx -= bbox.x + bbox.width;
     233                            dy -= bbox.y + (bbox.height / 2.0);
     234                            break;
     235                        case BL:
     236                            dx -= bbox.x;
     237                            dy -= bbox.y + bbox.height;
     238                            break;
     239                        case BR:
     240                            dx -= bbox.x + bbox.width;
     241                            dy -= bbox.y + bbox.height;
     242                            break;
     243                        case BC:
     244                            dx -= bbox.x + (bbox.width / 2.0);
     245                            dy -= bbox.y + bbox.height;
     246                            break;
     247                        }
     248                        g2.translate(dx, dy);
     249                    }
     250                    break;
     251                case COLR:
     252                    if ((cs != null) && (cs.col != null)) {
     253                        for (Instr patch : (Symbol) item.params) {
     254                            switch (patch.type) {
     255                            case N1:
     256                                if (cn > 0) {
     257                                    Symbol s = (Symbol) patch.params;
     258                                    drawSymbol(g2, s, 1.0, 0, 0, new Scheme(cs.col.get(0)), null);
     259                                }
     260                                break;
     261                            case N2:
     262                                if (cn > 0) {
     263                                    Symbol s = (Symbol) patch.params;
     264                                    drawSymbol(g2, s, 1.0, 0, 0, new Scheme((cn > 1) ? cs.col.get(1) : cs.col.get(0)), null);
     265                                }
     266                                break;
     267                            case P1:
     268                                if (cn > 0) {
     269                                    g2.setPaint(cs.col.get(0));
     270                                    g2.fill((Path2D.Double) patch.params);
     271                                }
     272                                break;
     273                            case P2:
     274                                if (cn > 0) {
     275                                    if (cn > 1) {
     276                                        g2.setPaint(cs.col.get(1));
     277                                    } else {
     278                                        g2.setPaint(cs.col.get(0));
     279                                    }
     280                                    g2.fill((Path2D.Double) patch.params);
     281                                }
     282                                break;
     283                            case H2:
     284                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
     285                                    g2.setPaint(cs.col.get(cs.col.size() - pn));
     286                                    g2.fill((Path2D.Double) patch.params);
     287                                }
     288                                break;
     289                            case H3:
     290                                if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
     291                                    g2.setPaint(cs.col.get(1));
     292                                    g2.fill((Path2D.Double) patch.params);
     293                                }
     294                                break;
     295                            case H4:
     296                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
     297                                    g2.setPaint(cs.col.get(1));
     298                                    g2.fill((Path2D.Double) patch.params);
     299                                }
     300                                break;
     301                            case H5:
     302                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
     303                                    g2.setPaint(cs.col.get(2));
     304                                    g2.fill((Path2D.Double) patch.params);
     305                                }
     306                                break;
     307                            case V2:
     308                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
     309                                    g2.setPaint(cs.col.get(cs.col.size() - pn));
     310                                    g2.fill((Path2D.Double) patch.params);
     311                                }
     312                                break;
     313                            case V3:
     314                                if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
     315                                    g2.setPaint(cs.col.get(1));
     316                                    g2.fill((Path2D.Double) patch.params);
     317                                }
     318                                break;
     319                            case B1:
     320                                if (bpat == Patt.B) {
     321                                    g2.setPaint(bcol);
     322                                    g2.fill((Path2D.Double) patch.params);
     323                                }
     324                                break;
     325                            case S2:
     326                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
     327                                    g2.setPaint(cs.col.get(1));
     328                                    g2.fill((Path2D.Double) patch.params);
     329                                }
     330                                break;
     331                            case S3:
     332                                if ((cn > 2) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
     333                                    g2.setPaint(cs.col.get(2));
     334                                    g2.fill((Path2D.Double) patch.params);
     335                                }
     336                                break;
     337                            case S4:
     338                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
     339                                    g2.setPaint(cs.col.get(3));
     340                                    g2.fill((Path2D.Double) patch.params);
     341                                }
     342                                break;
     343                            default:
     344                                break;
     345                            }
     346                        }
     347                    }
     348                    break;
     349                case STRK:
     350                    g2.setStroke((BasicStroke) item.params);
     351                    break;
     352                case FILL:
     353                    g2.setPaint((Color) item.params);
     354                    break;
     355                case LINE:
     356                    g2.draw((Line2D.Double) item.params);
     357                    break;
     358                case RECT:
     359                    g2.draw((Rectangle2D.Double) item.params);
     360                    break;
     361                case RRCT:
     362                    g2.draw((RoundRectangle2D.Double) item.params);
     363                    break;
     364                case ELPS:
     365                    g2.draw((Ellipse2D.Double) item.params);
     366                    break;
     367                case EARC:
     368                    g2.draw((Arc2D.Double) item.params);
     369                    break;
     370                case PLIN:
     371                    g2.draw((Path2D.Double) item.params);
     372                    break;
     373                case PGON:
     374                    g2.fill((Path2D.Double) item.params);
     375                    break;
     376                case RSHP:
     377                    g2.fill((RectangularShape) item.params);
     378                    break;
     379                case SYMB:
     380                    SubSymbol s = (SubSymbol) item.params;
     381                    drawSymbol(g2, s.instr, s.scale, s.x, s.y, (s.scheme != null ? s.scheme : cs), s.delta);
     382                    break;
     383                case TEXT:
     384                    Caption c = (Caption) item.params;
     385                    g2.setPaint(c.colour);
     386                    TextLayout layout = new TextLayout(c.string, c.font, g2.getFontRenderContext());
     387                    Rectangle2D bb = layout.getBounds();
     388                    dx = 0;
     389                    dy = 0;
     390                    if (c.dd != null) {
     391                        if (c.dd.t != null) g2.transform(c.dd.t);
     392                        switch (c.dd.h) {
     393                        case CC:
     394                            dx -= bb.getX() + (bb.getWidth() / 2.0);
     395                            dy -= bb.getY() + (bb.getHeight() / 2.0);
     396                            break;
     397                        case TL:
     398                            dx -= bb.getX();
     399                            dy -= bb.getY();
     400                            break;
     401                        case TR:
     402                            dx -= bb.getX() + bb.getWidth();
     403                            dy -= bb.getY();
     404                            break;
     405                        case TC:
     406                            dx -= bb.getX() + (bb.getWidth() / 2.0);
     407                            dy -= bb.getY();
     408                            break;
     409                        case LC:
     410                            dx -= bb.getX();
     411                            dy -= bb.getY() + (bb.getHeight() / 2.0);
     412                            break;
     413                        case RC:
     414                            dx -= bb.getX() + bb.getWidth();
     415                            dy -= bb.getY() + (bb.getHeight() / 2.0);
     416                            break;
     417                        case BL:
     418                            dx -= bb.getX();
     419                            dy -= bb.getY() + bb.getHeight();
     420                            break;
     421                        case BR:
     422                            dx -= bb.getX() + bb.getWidth();
     423                            dy -= bb.getY() + bb.getHeight();
     424                            break;
     425                        case BC:
     426                            dx -= bb.getX() + (bb.getWidth() / 2.0);
     427                            dy -= bb.getY() + bb.getHeight();
     428                            break;
     429                        }
     430                    }
     431                    layout.draw(g2, (float) dx, (float) dy);
     432                    break;
     433                default:
     434                    break;
     435                }
     436            }
     437        }
     438        g2.setTransform(savetr);
     439    }
    425440}
  • applications/editors/josm/plugins/seachart/src/symbols/Topmarks.java

    r32393 r32394  
    1212import java.awt.BasicStroke;
    1313import java.awt.Color;
    14 import java.awt.geom.*;
     14import java.awt.geom.AffineTransform;
     15import java.awt.geom.Ellipse2D;
     16import java.awt.geom.GeneralPath;
     17import java.awt.geom.Line2D;
     18import java.awt.geom.Path2D;
     19import java.awt.geom.Rectangle2D;
    1520import java.util.EnumMap;
    1621
    17 import s57.S57val.*;
    18 import symbols.Symbols.*;
     22import s57.S57val.BoySHP;
     23import s57.S57val.TopSHP;
     24import symbols.Symbols.Delta;
     25import symbols.Symbols.Form;
     26import symbols.Symbols.Handle;
     27import symbols.Symbols.Instr;
     28import symbols.Symbols.Symbol;
    1929
    2030public class Topmarks {
    21        
    22         public static final Symbol RadarReflector = new Symbol();
    23         static {
    24                 RadarReflector.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-40,100,40)));
    25                 RadarReflector.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    26                 RadarReflector.add(new Instr(Form.FILL, Color.black));
    27                 Path2D.Double p = new Path2D.Double(); p.moveTo(-30,-3); p.quadTo(0, -40, 30, -3); p.moveTo(0,-20); p.lineTo(0,-37);
    28                 p.moveTo(-30, -3); p.lineTo(-43,-14); p.moveTo(30, -3); p.lineTo(44,-14); p.moveTo(-15, -14); p.lineTo(-25,-30); p.moveTo(15, -14); p.lineTo(25,-30);
    29                 RadarReflector.add(new Instr(Form.PLIN, p));
    30         }
    31         public static final Symbol TopBesom = new Symbol();
    32         static {
    33                 TopBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    34                 TopBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    35                 TopBesom.add(new Instr(Form.FILL, Color.black));
    36                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,0.0); p.lineTo(0.0,-30.0); p.lineTo(15.0,0.0); p.moveTo(0.0,0.0); p.lineTo(0.0,-28.0);
    37                 TopBesom.add(new Instr(Form.PLIN, p));
    38         }
    39         public static final Symbol TopIBesom = new Symbol();
    40         static {
    41                 TopIBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    42                 TopIBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    43                 TopIBesom.add(new Instr(Form.FILL, Color.black));
    44                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-30.0); p.lineTo(0.0,0.0); p.lineTo(15.0,-30.0);
    45                 TopIBesom.add(new Instr(Form.PLIN, p));
    46         }
    47         public static final Symbol TopBoard = new Symbol();
    48         static {
    49                 TopBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
    50                 Symbol colours = new Symbol();
    51                 Path2D.Double p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29,-1); p.closePath();
    52                 colours.add(new Instr(Form.P1, p));
    53                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    54                 p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29,-1); p.closePath();
    55                 p.moveTo(-19,-10); p.lineTo(-19,-49); p.lineTo(19,-49); p.lineTo(19,-10); p.closePath();
    56                 colours.add(new Instr(Form.B1, p));
    57                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    58                 p.moveTo(-29,-1); p.lineTo(-29,-30); p.lineTo(29,-30); p.lineTo(29,-59); p.lineTo(0,-59); p.lineTo(0,-1); p.closePath();
    59                 colours.add(new Instr(Form.S2, p));
    60                 p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-30); p.lineTo(0,-30); p.lineTo(0,-1); p.closePath();
    61                 colours.add(new Instr(Form.S3, p));
    62                 p = new Path2D.Double(); p.moveTo(0,-1); p.lineTo(0,-30); p.lineTo(29,-30); p.lineTo(29,-1); p.closePath();
    63                 colours.add(new Instr(Form.S4, p));
    64                 TopBoard.add(new Instr(Form.COLR, colours));
    65                 TopBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    66                 TopBoard.add(new Instr(Form.FILL, Color.black));
    67                 p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29.0,-1); p.closePath();
    68                 TopBoard.add(new Instr(Form.PLIN, p));
    69         }
    70         public static final Symbol TopCan = new Symbol();
    71         static {
    72                 TopCan.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    73                 Symbol colours = new Symbol();
    74                 Path2D.Double p = new Path2D.Double(); p.moveTo(-12.0,-15.0); p.lineTo(-12.0,-48.0); p.lineTo(12.0,-48.0); p.lineTo(12.0,-15.0); p.closePath();
    75                 colours.add(new Instr(Form.P1, p));
    76                 TopCan.add(new Instr(Form.COLR, colours));
    77                 TopCan.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    78                 TopCan.add(new Instr(Form.FILL, Color.black));
    79                 TopCan.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    80                 p = new Path2D.Double(); p.moveTo(-12.0,-15.0); p.lineTo(-12.0,-48.0); p.lineTo(12.0,-48.0); p.lineTo(12.0,-15.0); p.closePath();
    81                 TopCan.add(new Instr(Form.PLIN, p));
    82         }
    83         public static final Symbol TopCanSphere = new Symbol();
    84         public static final Symbol TopCircle = new Symbol();
    85         public static final Symbol TopCircleTriangle = new Symbol();
    86         public static final Symbol TopCone = new Symbol();
    87         static {
    88                 TopCone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    89                 Symbol colours = new Symbol();
    90                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-15.0); p.lineTo(0.0,-45.0); p.lineTo(15.0,-15.0); p.closePath();
    91                 colours.add(new Instr(Form.P1, p));
    92                 TopCone.add(new Instr(Form.COLR, colours));
    93                 TopCone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    94                 TopCone.add(new Instr(Form.FILL, Color.black));
    95                 TopCone.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    96                 p = new Path2D.Double(); p.moveTo(-15.0,-15.0); p.lineTo(0.0,-45.0); p.lineTo(15.0,-15.0); p.closePath();
    97                 TopCone.add(new Instr(Form.PLIN, p));
    98         }
    99         public static final Symbol TopConeSphere = new Symbol();
    100         static {
    101                 TopConeSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    102                 Symbol colours = new Symbol();
    103                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-47.0); p.lineTo(0.0,-77.0); p.lineTo(15.0,-47.0); p.closePath();
    104                 p.moveTo(-14.0,-28.0); p.curveTo(-14.0,-46.7,14.0,-46.7,14.0,-28.0); p.curveTo(14.0,-9.3,-14.0,-9.3,-14.0,-28.0); p.closePath();
    105                 colours.add(new Instr(Form.P1, p));
    106                 TopConeSphere.add(new Instr(Form.COLR, colours));
    107                 TopConeSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    108                 TopConeSphere.add(new Instr(Form.FILL, Color.black));
    109                 TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    110                 TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0,-42,0,-47)));
    111                 p = new Path2D.Double(); p.moveTo(-15.0,-47.0); p.lineTo(0.0,-77.0); p.lineTo(15.0,-47.0); p.closePath();
    112                 TopConeSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-42,28,28)));
    113                 TopConeSphere.add(new Instr(Form.PLIN, p));
    114         }
    115         public static final Symbol TopCross = new Symbol();
    116         static {
    117                 TopCross.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    118                 Symbol colours = new Symbol();
    119                 Path2D.Double p = new Path2D.Double(); p.moveTo(-5.0,-15.0); p.lineTo(-5.0,-32.5); p.lineTo(-22.5,-32.5);       p.lineTo(-22.5,-42.5); p.lineTo(-5.0,-42.5);
    120                 p.lineTo(-5.0,-60.0); p.lineTo(5.0,-60.0); p.lineTo(5.0,-42.5); p.lineTo(22.5,-42.5);   p.lineTo(22.5,-32.5); p.lineTo(5.0,-32.5); p.lineTo(5.0,-15.0); p.closePath();
    121                 colours.add(new Instr(Form.P1, p));
    122                 TopCross.add(new Instr(Form.COLR, colours));
    123                 TopCross.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    124                 TopCross.add(new Instr(Form.FILL, Color.black));
    125                 TopCross.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    126                 TopCross.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    127                 p = new Path2D.Double(); p.moveTo(-5.0,-15.0); p.lineTo(-5.0,-32.5); p.lineTo(-22.5,-32.5); p.lineTo(-22.5,-42.5); p.lineTo(-5.0,-42.5); p.lineTo(-5.0,-60.0);
    128                 p.lineTo(5.0,-60.0); p.lineTo(5.0,-42.5); p.lineTo(22.5,-42.5); p.lineTo(22.5,-32.5); p.lineTo(5.0,-32.5); p.lineTo(5.0,-15.0); p.closePath();
    129                 TopCross.add(new Instr(Form.PLIN, p));
    130         }
    131         public static final Symbol TopCrosses = new Symbol();
    132         static {
    133                
    134         }
    135         public static final Symbol TopCrossCircle = new Symbol();
    136         static {
    137                
    138         }
    139         public static final Symbol TopCube = new Symbol();
    140         static {
    141                 TopCube.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    142                 Symbol colours = new Symbol();
    143                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-48); p.lineTo(-15,-37); p.lineTo(-15,-20); p.lineTo(0,-9); p.lineTo(15,-20); p.lineTo(15,-37); p.closePath();
    144                 colours.add(new Instr(Form.P1, p));
    145                 TopCube.add(new Instr(Form.COLR, colours));
    146                 TopCube.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    147                 TopCube.add(new Instr(Form.FILL, Color.black));
    148                 TopCube.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    149                 p = new Path2D.Double(); p.moveTo(0,-48); p.lineTo(-14,-37); p.lineTo(0,-26); p.lineTo(14,-37); p.closePath(); p.moveTo(0,-26); p.lineTo(0,0);
    150                 p.moveTo(-15,-37); p.lineTo(-15,-20); p.lineTo(0,-9); p.lineTo(15,-20); p.lineTo(15,-37);
    151                 TopCube.add(new Instr(Form.PLIN, p));
    152         }
    153         public static final Symbol TopEast = new Symbol();
    154         static {
    155                 TopEast.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    156                 Symbol colours = new Symbol();
    157                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-80.0); p.lineTo(-15.0,-47.0); p.lineTo(15.0,-47.0); p.closePath();
    158                 colours.add(new Instr(Form.P1, p));
    159                 p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
    160                 colours.add(new Instr(Form.P2, p));
    161                 TopEast.add(new Instr(Form.COLR, colours));
    162                 TopEast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    163                 TopEast.add(new Instr(Form.FILL, Color.black));
    164                 TopEast.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
    165                 TopEast.add(new Instr(Form.LINE, new Line2D.Double(0,-43,0,-47)));
    166                 TopEast.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    167                 p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
    168                 p.moveTo(0.0,-80.0); p.lineTo(-15.0,-47.0);  p.lineTo(15.0,-47.0); p.closePath();
    169                 TopEast.add(new Instr(Form.PLIN, p));
    170         }
    171         public static final Symbol TopFlag = new Symbol();
    172         static {
    173                 TopFlag.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    174                 Symbol colours = new Symbol();
    175                 Path2D.Double p = new Path2D.Double(); p.moveTo(0,-40); p.lineTo(0,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
    176                 colours.add(new Instr(Form.P1, p));
    177                 p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(0,-10); p.lineTo(40,-10); p.lineTo(39,-25); p.closePath();
    178                 colours.add(new Instr(Form.H2, p));
    179                 p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(0,-20); p.lineTo(40,-20); p.lineTo(39,-30); p.closePath();
    180                 colours.add(new Instr(Form.H3, p));
    181                 p = new Path2D.Double(); p.moveTo(19.5,-40); p.lineTo(19.5,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
    182                 colours.add(new Instr(Form.V2, p));
    183                 p = new Path2D.Double(); p.moveTo(13,-40); p.lineTo(13,-10); p.lineTo(26,-10); p.lineTo(26,-40); p.closePath();
    184                 colours.add(new Instr(Form.V3, p));
    185                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    186                 p.moveTo(0,-40); p.lineTo(0,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
    187                 p.moveTo(8,-35); p.lineTo(8,-15); p.lineTo(33,-15); p.lineTo(33,-35); p.closePath();
    188                 colours.add(new Instr(Form.B1, p));
    189                 p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(0,-10); p.lineTo(20,-10); p.lineTo(20,-40); p.lineTo(39,-40); p.lineTo(39,-25); p.closePath();
    190                 colours.add(new Instr(Form.S2, p));
    191                 p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(0,-10); p.lineTo(20,-10); p.lineTo(20,-25); p.closePath();
    192                 colours.add(new Instr(Form.S3, p));
    193                 p = new Path2D.Double(); p.moveTo(20,-25); p.lineTo(20,-10); p.lineTo(39,-10); p.lineTo(39,-25); p.closePath();
    194                 colours.add(new Instr(Form.S4, p));
    195                 TopFlag.add(new Instr(Form.COLR, colours));
    196                 TopFlag.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    197                 TopFlag.add(new Instr(Form.FILL, Color.black));
    198                 TopFlag.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-45)));
    199                 TopFlag.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    200                 TopFlag.add(new Instr(Form.RECT, new Rectangle2D.Double(0,-40,39,30)));
    201         }
    202         public static final Symbol TopIcone = new Symbol();
    203         static {
    204                 TopIcone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    205                 Symbol colours = new Symbol();
    206                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-45.0); p.lineTo(0.0,-15.0); p.lineTo(15.0,-45.0); p.closePath();
    207                 colours.add(new Instr(Form.P1, p));
    208                 TopIcone.add(new Instr(Form.COLR, colours));
    209                 TopIcone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    210                 TopIcone.add(new Instr(Form.FILL, Color.black));
    211                 TopIcone.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    212                 p = new Path2D.Double(); p.moveTo(-15.0,-45.0); p.lineTo(0.0,-15.0); p.lineTo(15.0,-45.0); p.closePath();
    213                 TopIcone.add(new Instr(Form.PLIN, p));
    214         }
    215         public static final Symbol TopIsol = new Symbol();
    216         static {
    217                 TopIsol.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    218                 Symbol colours = new Symbol();
    219                 Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0,-55.0); p.curveTo(-13.0, -72.3, 13.0, -72.3, 13.0,-55.0); p.curveTo(13.0, -37.7, -13.0, -37.7, -13.0,-55.0); p.closePath();
    220                 colours.add(new Instr(Form.P1, p));
    221                 p = new Path2D.Double(); p.moveTo(-13.0,-28.0); p.curveTo(-13.0, -45.3, 13.0, -45.3, 13.0,-28.0); p.curveTo(13.0, -10.7, -13.0, -10.7, -13.0,-28.0); p.closePath();
    222                 colours.add(new Instr(Form.P2, p));
    223                 TopIsol.add(new Instr(Form.COLR, colours));
    224                 TopIsol.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    225                 TopIsol.add(new Instr(Form.FILL, Color.black));
    226                 TopIsol.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    227                 TopIsol.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    228                 TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13,-41,26,26)));
    229                 TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13,-68,26,26)));
    230         }
    231         public static final Symbol TopMooring = new Symbol();
    232         static {
    233                 TopMooring.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    234                 TopMooring.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    235                 TopMooring.add(new Instr(Form.FILL, Color.black));
    236                 TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.5,-6,3,3)));
    237                 TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-8.5,-25,17,17)));
    238         }
    239         public static final Symbol TopNorth = new Symbol();
    240         static {
    241                 TopNorth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    242                 Symbol colours = new Symbol();
    243                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-78.0); p.lineTo(-15.0,-45.0); p.lineTo(15.0,-45.0); p.closePath();
    244                 colours.add(new Instr(Form.P1, p));
    245                 p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
    246                 colours.add(new Instr(Form.P2, p));
    247                 TopNorth.add(new Instr(Form.COLR, colours));
    248                 TopNorth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    249                 TopNorth.add(new Instr(Form.FILL, Color.black));
    250                 TopNorth.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
    251                 TopNorth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    252                 p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
    253                 p.moveTo(0.0,-78.0); p.lineTo(-15.0,-45.0);  p.lineTo(15.0,-45.0); p.closePath();
    254                 TopNorth.add(new Instr(Form.PLIN, p));
    255         }
    256         public static final Symbol TopSouth = new Symbol();
    257         static {
    258                 TopSouth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    259                 Symbol colours = new Symbol();
    260                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
    261                 colours.add(new Instr(Form.P1, p));
    262                 p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
    263                 colours.add(new Instr(Form.P2, p));
    264                 TopSouth.add(new Instr(Form.COLR, colours));
    265                 TopSouth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    266                 TopSouth.add(new Instr(Form.FILL, Color.black));
    267                 TopSouth.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
    268                 TopSouth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    269                 p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
    270                 p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
    271                 TopSouth.add(new Instr(Form.PLIN, p));
    272         }
    273         public static final Symbol TopSphere = new Symbol();
    274         static {
    275                 TopSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    276                 Symbol colours = new Symbol();
    277                 Path2D.Double p = new Path2D.Double(); p.moveTo(-14.0,-28.0); p.curveTo(-14.0,-46.7,14.0,-46.7,14.0,-28.0); p.curveTo(14.0,-9.3,-14.0,-9.3,-14.0,-28.0); p.closePath();
    278                 colours.add(new Instr(Form.P1, p));
    279                 TopSphere.add(new Instr(Form.COLR, colours));
    280                 TopSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    281                 TopSphere.add(new Instr(Form.FILL, Color.black));
    282                 TopSphere.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
    283                 TopSphere.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    284                 TopSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-42,28,28)));
    285         }
    286         public static final Symbol TopSquare = new Symbol();
    287         static {
    288                 TopSquare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    289                 Symbol colours = new Symbol();
    290                 Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    291                 colours.add(new Instr(Form.P1, p));
    292                 p = new Path2D.Double(); p.moveTo(-13.0,-15.0); p.lineTo(-13.0,-1.0); p.lineTo(13.0,-1.0); p.lineTo(13.0,-15.0); p.closePath();
    293                 colours.add(new Instr(Form.H2, p));
    294                 p = new Path2D.Double(); p.moveTo(-13.0,-19.3); p.lineTo(-13.0,-10.7); p.lineTo(13.0,-10.7); p.lineTo(13.0,-19.3); p.closePath();
    295                 colours.add(new Instr(Form.H3, p));
    296                 p = new Path2D.Double(); p.moveTo(0.0,-1.0); p.lineTo(0.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    297                 colours.add(new Instr(Form.V2, p));
    298                 p = new Path2D.Double(); p.moveTo(-4.3,-1.0); p.lineTo(-4.3,-27.0); p.lineTo(4.3,-27.0); p.lineTo(4.3,-1.0); p.closePath();
    299                 colours.add(new Instr(Form.V3, p));
    300                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    301                 p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    302                 p.moveTo(-8.0,-6.0); p.lineTo(-8.0,-22.0); p.lineTo(8.0,-22.0); p.lineTo(8.0,-6.0); p.closePath();
    303                 colours.add(new Instr(Form.B1, p));
    304                 TopSquare.add(new Instr(Form.COLR, colours));
    305                 TopSquare.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    306                 TopSquare.add(new Instr(Form.FILL, Color.black));
    307                 p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    308                 TopSquare.add(new Instr(Form.PLIN, p));
    309         }
    310         public static final Symbol TopRectangleH = new Symbol();
    311         static {
    312                 TopRectangleH.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    313                 Symbol colours = new Symbol();
    314                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20.0,-1.0); p.lineTo(-20.0,-27.0); p.lineTo(20.0,-27.0); p.lineTo(20.0,-1.0); p.closePath();
    315                 colours.add(new Instr(Form.P1, p));
    316                 TopRectangleH.add(new Instr(Form.COLR, colours));
    317                 TopRectangleH.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    318                 TopRectangleH.add(new Instr(Form.FILL, Color.black));
    319                 p = new Path2D.Double(); p.moveTo(-20.0,-1.0); p.lineTo(-20.0,-27.0); p.lineTo(20.0,-27.0); p.lineTo(20.0,-1.0); p.closePath();
    320                 TopRectangleH.add(new Instr(Form.PLIN, p));
    321         }
    322         public static final Symbol TopRectangleV = new Symbol();
    323         static {
    324                 TopRectangleV.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    325                 Symbol colours = new Symbol();
    326                 Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-41.0); p.lineTo(13.0,-41.0); p.lineTo(13.0,-1.0); p.closePath();
    327                 colours.add(new Instr(Form.P1, p));
    328                 TopRectangleV.add(new Instr(Form.COLR, colours));
    329                 TopRectangleV.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    330                 TopRectangleV.add(new Instr(Form.FILL, Color.black));
    331                 p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-13.0,-41.0); p.lineTo(13.0,-41.0); p.lineTo(13.0,-1.0); p.closePath();
    332                 TopRectangleV.add(new Instr(Form.PLIN, p));
    333         }
    334         public static final Symbol TopRhombus = new Symbol();
    335         static {
    336                 TopRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    337                 Symbol colours = new Symbol();
    338                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-29.0); p.lineTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
    339                 colours.add(new Instr(Form.P1, p));
    340                 p = new Path2D.Double(); p.moveTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
    341                 colours.add(new Instr(Form.H2, p));
    342                 p = new Path2D.Double(); p.moveTo(-10.0,-19.7); p.lineTo(-15.0,-15.0); p.lineTo(-10.0,-10.3); p.lineTo(10.0,-10.3); p.lineTo(15.0,-15.0); p.lineTo(10.0,-19.7); p.closePath();
    343                 colours.add(new Instr(Form.H3, p));
    344                 p = new Path2D.Double();  p.moveTo(0.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
    345                 colours.add(new Instr(Form.V2, p));
    346                 p = new Path2D.Double(); p.moveTo(0.0,-29.0); p.lineTo(-5.0,-24.3); p.lineTo(-5.0,-5.7); p.lineTo(0.0,-1.0); p.lineTo(5.0,-5.7); p.lineTo(5.0,-24.3); p.closePath();
    347                 colours.add(new Instr(Form.V3, p));
    348                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    349                 p.moveTo(0.0,-29.0); p.lineTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
    350                 p.moveTo(0.0,-23.0); p.lineTo(-9.0,-15.0); p.lineTo(0.0,-7.0); p.lineTo(9.0,-15.0); p.closePath();
    351                 colours.add(new Instr(Form.B1, p));
    352                 TopRhombus.add(new Instr(Form.COLR, colours));
    353                 TopRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    354                 TopRhombus.add(new Instr(Form.FILL, Color.black));
    355                 p = new Path2D.Double(); p.moveTo(0.0,-29.0); p.lineTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
    356                 TopRhombus.add(new Instr(Form.PLIN, p));
    357         }
    358         public static final Symbol TopRhombusCircle = new Symbol();
    359         static {
    360                
    361         }
    362         public static final Symbol TopSphereRhombus = new Symbol();
    363         static {
    364                 TopSphereRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    365                 TopSphereRhombus.add(new Instr(Form.SYMB, new Symbols.SubSymbol(TopRhombus, 1.0, 0, 0, null, null)));
    366                 Symbol colours = new Symbol();
    367                 Path2D.Double p = new Path2D.Double(); p.moveTo(-14.0,-44.0); p.curveTo(-14.0,-62.7,14.0,-62.7,14.0,-44.0); p.curveTo(14.0,-25.3,-14.0,-25.3,-14.0,-44.0); p.closePath();
    368                 colours.add(new Instr(Form.P1, p));
    369                 TopSphereRhombus.add(new Instr(Form.COLR, colours));
    370                 TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    371                 TopSphereRhombus.add(new Instr(Form.FILL, Color.black));
    372                 TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    373                 TopSphereRhombus.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-58,28,28)));
    374         }
    375         public static final Symbol TopT = new Symbol();
    376         static {
    377                
    378         }
    379         public static final Symbol TopTrapeziumU = new Symbol();
    380         static {
    381                 TopTrapeziumU.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    382                 Symbol colours = new Symbol();
    383                 Path2D.Double p = new Path2D.Double(); p.moveTo(-20.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(20.0,-1.0); p.closePath();
    384                 colours.add(new Instr(Form.P1, p));
    385                 TopTrapeziumU.add(new Instr(Form.COLR, colours));
    386                 TopTrapeziumU.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    387                 TopTrapeziumU.add(new Instr(Form.FILL, Color.black));
    388                 p = new Path2D.Double(); p.moveTo(-20.0,-1.0); p.lineTo(-13.0,-27.0); p.lineTo(13.0,-27.0); p.lineTo(20.0,-1.0); p.closePath();
    389                 TopTrapeziumU.add(new Instr(Form.PLIN, p));
    390         }
    391         public static final Symbol TopTrapeziumD = new Symbol();
    392         static {
    393                 TopTrapeziumD.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    394                 Symbol colours = new Symbol();
    395                 Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-20.0,-27.0); p.lineTo(20.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    396                 colours.add(new Instr(Form.P1, p));
    397                 TopTrapeziumD.add(new Instr(Form.COLR, colours));
    398                 TopTrapeziumD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    399                 TopTrapeziumD.add(new Instr(Form.FILL, Color.black));
    400                 p = new Path2D.Double(); p.moveTo(-13.0,-1.0); p.lineTo(-20.0,-27.0); p.lineTo(20.0,-27.0); p.lineTo(13.0,-1.0); p.closePath();
    401                 TopTrapeziumD.add(new Instr(Form.PLIN, p));
    402         }
    403         public static final Symbol TopTriangle = new Symbol();
    404         static {
    405                 TopTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    406                 Symbol colours = new Symbol();
    407                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-1.0); p.lineTo(0.0,-29.0); p.lineTo(15.0,-1.0); p.closePath();
    408                 colours.add(new Instr(Form.P1, p));
    409                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    410                 p.moveTo(-15.0,-1.0); p.lineTo(0.0,-29.0); p.lineTo(15.0,-1.0); p.closePath();
    411                 p.moveTo(-10.0,-6.0); p.lineTo(0.0,-24.0); p.lineTo(10.0,-6.0); p.closePath();
    412                 colours.add(new Instr(Form.B1, p));
    413                 TopTriangle.add(new Instr(Form.COLR, colours));
    414                 TopTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    415                 TopTriangle.add(new Instr(Form.FILL, Color.black));
    416                 p = new Path2D.Double(); p.moveTo(-15.0,-1.0); p.lineTo(0.0,-29.0); p.lineTo(15.0,-1.0); p.closePath();
    417                 TopTriangle.add(new Instr(Form.PLIN, p));
    418         }
    419         public static final Symbol TopItriangle = new Symbol();
    420         static {
    421                 TopItriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
    422                 Symbol colours = new Symbol();
    423                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-29.0); p.closePath();
    424                 colours.add(new Instr(Form.P1, p));
    425                 p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
    426                 p.moveTo(-15.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-29.0); p.closePath();
    427                 p.moveTo(-10.0,-24.0); p.lineTo(0.0,-6.0); p.lineTo(10.0,-24.0); p.closePath();
    428                 colours.add(new Instr(Form.B1, p));
    429                 TopItriangle.add(new Instr(Form.COLR, colours));
    430                 TopItriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    431                 TopItriangle.add(new Instr(Form.FILL, Color.black));
    432                 p = new Path2D.Double(); p.moveTo(-15.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-29.0); p.closePath();
    433                 TopItriangle.add(new Instr(Form.PLIN, p));
    434         }
    435         public static final Symbol TopTriangleCircle = new Symbol();
    436         static {
    437                
    438         }
    439         public static final Symbol TopWest = new Symbol();
    440         static {
    441                 TopWest.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    442                 Symbol colours = new Symbol();
    443                 Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
    444                 colours.add(new Instr(Form.P1, p));
    445                 p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
    446                 colours.add(new Instr(Form.P2, p));
    447                 TopWest.add(new Instr(Form.COLR, colours));
    448                 TopWest.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    449                 TopWest.add(new Instr(Form.FILL, Color.black));
    450                 TopWest.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
    451                 TopWest.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    452                 p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
    453                 p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
    454                 TopWest.add(new Instr(Form.PLIN, p));
    455         }
    456         public static final Symbol TopX = new Symbol();
    457         static {
    458                 TopX.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
    459                 Symbol colours = new Symbol();
    460                 Path2D.Double p = new Path2D.Double(); p.moveTo(0.0,-27.7); p.lineTo(-12.4,-15.7); p.lineTo(-19.3,-22.6); p.lineTo(-7.3,-35.0); p.lineTo(-19.3,-47.3);
    461                 p.lineTo(-12.4,-54.2); p.lineTo(0.0,-42.4); p.lineTo(12.4,-54.2); p.lineTo(19.3,-47.3); p.lineTo(7.3,-35.0); p.lineTo(19.3,-22.6); p.lineTo(12.4,-15.7); p.closePath();
    462                 colours.add(new Instr(Form.P1, p));
    463                 TopX.add(new Instr(Form.COLR, colours));
    464                 TopX.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    465                 TopX.add(new Instr(Form.FILL, Color.black));
    466                 TopX.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-27)));
    467                 TopX.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
    468                 p = new Path2D.Double(); p.moveTo(0.0,-27.7); p.lineTo(-12.4,-15.7); p.lineTo(-19.3,-22.6); p.lineTo(-7.3,-35.0); p.lineTo(-19.3,-47.3); p.lineTo(-12.4,-54.2); p.lineTo(0.0,-42.4);
    469                 p.lineTo(12.4,-54.2); p.lineTo(19.3,-47.3); p.lineTo(7.3,-35.0); p.lineTo(19.3,-22.6); p.lineTo(12.4,-15.7); p.closePath();
    470                 TopX.add(new Instr(Form.PLIN, p));
    471         }
    472         public static final Symbol TopOther = new Symbol();
    473         static {
    474                
    475         }
    476        
    477         public static final EnumMap<TopSHP, Symbol> Shapes = new EnumMap<>(TopSHP.class);
    478         static {
    479                 Shapes.put(TopSHP.TOP_BESM, TopBesom); Shapes.put(TopSHP.TOP_IBESM, TopIBesom); Shapes.put(TopSHP.TOP_BORD, TopBoard); Shapes.put(TopSHP.TOP_CAN, TopCan);
    480                 Shapes.put(TopSHP.TOP_CONE, TopCone); Shapes.put(TopSHP.TOP_CROS, TopCross); Shapes.put(TopSHP.TOP_EAST, TopEast); Shapes.put(TopSHP.TOP_ICONE, TopIcone);
    481                 Shapes.put(TopSHP.TOP_ISD, TopIsol); Shapes.put(TopSHP.TOP_NORTH, TopNorth); Shapes.put(TopSHP.TOP_SOUTH, TopSouth); Shapes.put(TopSHP.TOP_SPHR, TopSphere);
    482                 Shapes.put(TopSHP.TOP_SQUR, TopSquare); Shapes.put(TopSHP.TOP_TRI, TopTriangle); Shapes.put(TopSHP.TOP_ITRI, TopItriangle); Shapes.put(TopSHP.TOP_WEST, TopWest);
    483                 Shapes.put(TopSHP.TOP_SALT, TopX); Shapes.put(TopSHP.TOP_RHOM, TopRhombus); Shapes.put(TopSHP.TOP_FLAG, TopFlag); Shapes.put(TopSHP.TOP_CUBE, TopCube);
    484                 Shapes.put(TopSHP.TOP_SPRH, TopSphereRhombus); Shapes.put(TopSHP.TOP_HRECT, TopRectangleH); Shapes.put(TopSHP.TOP_VRECT, TopRectangleV);
    485                 Shapes.put(TopSHP.TOP_TRAP, TopTrapeziumU); Shapes.put(TopSHP.TOP_ITRAP, TopTrapeziumD); Shapes.put(TopSHP.TOP_COSP, TopConeSphere);
    486                 Shapes.put(TopSHP.TOP_CIRC, TopCircle); Shapes.put(TopSHP.TOP_CRSS, TopCrosses); Shapes.put(TopSHP.TOP_T, TopT); Shapes.put(TopSHP.TOP_TRCL, TopTriangleCircle);
    487                 Shapes.put(TopSHP.TOP_CRCL, TopCrossCircle); Shapes.put(TopSHP.TOP_RHCL, TopRhombusCircle); Shapes.put(TopSHP.TOP_CLTR, TopCircleTriangle);
    488                 Shapes.put(TopSHP.TOP_CYSP, TopCanSphere); Shapes.put(TopSHP.TOP_OTHR, TopOther);
    489         }
    490 
    491         public static final EnumMap<BoySHP, Delta> BuoyDeltas = new EnumMap<>(BoySHP.class);
    492         static {
    493                 BuoyDeltas.put(BoySHP.BOY_PILR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
    494                 BuoyDeltas.put(BoySHP.BOY_SPAR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
    495                 BuoyDeltas.put(BoySHP.BOY_CAN, new Delta(Handle.BC,  new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
    496                 BuoyDeltas.put(BoySHP.BOY_CONE, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
    497                 BuoyDeltas.put(BoySHP.BOY_SPHR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
    498                 BuoyDeltas.put(BoySHP.BOY_BARL, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
    499                 BuoyDeltas.put(BoySHP.BOY_SUPR, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0)));
    500                 BuoyDeltas.put(BoySHP.BOY_ICE, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -25.0)));
    501         }
    502         public static final Delta FloatDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0));
    503         public static final Delta BeaconDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -70.0));
    504         public static final Delta LightDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -20.0));
    505 
     31    // CHECKSTYLE.OFF: LineLength
     32    public static final Symbol RadarReflector = new Symbol();
     33    static {
     34        RadarReflector.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -40, 100, 40)));
     35        RadarReflector.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     36        RadarReflector.add(new Instr(Form.FILL, Color.black));
     37        Path2D.Double p = new Path2D.Double(); p.moveTo(-30, -3); p.quadTo(0, -40, 30, -3); p.moveTo(0, -20); p.lineTo(0, -37);
     38        p.moveTo(-30, -3); p.lineTo(-43, -14); p.moveTo(30, -3); p.lineTo(44, -14); p.moveTo(-15, -14); p.lineTo(-25, -30); p.moveTo(15, -14); p.lineTo(25, -30);
     39        RadarReflector.add(new Instr(Form.PLIN, p));
     40    }
     41
     42    public static final Symbol TopBesom = new Symbol();
     43    static {
     44        TopBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     45        TopBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     46        TopBesom.add(new Instr(Form.FILL, Color.black));
     47        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, 0.0); p.lineTo(0.0, -30.0); p.lineTo(15.0, 0.0); p.moveTo(0.0, 0.0); p.lineTo(0.0, -28.0);
     48        TopBesom.add(new Instr(Form.PLIN, p));
     49    }
     50
     51    public static final Symbol TopIBesom = new Symbol();
     52    static {
     53        TopIBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     54        TopIBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     55        TopIBesom.add(new Instr(Form.FILL, Color.black));
     56        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -30.0); p.lineTo(0.0, 0.0); p.lineTo(15.0, -30.0);
     57        TopIBesom.add(new Instr(Form.PLIN, p));
     58    }
     59
     60    public static final Symbol TopBoard = new Symbol();
     61    static {
     62        TopBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
     63        Symbol colours = new Symbol();
     64        Path2D.Double p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29, -1); p.closePath();
     65        colours.add(new Instr(Form.P1, p));
     66        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     67        p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29, -1); p.closePath();
     68        p.moveTo(-19, -10); p.lineTo(-19, -49); p.lineTo(19, -49); p.lineTo(19, -10); p.closePath();
     69        colours.add(new Instr(Form.B1, p));
     70        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     71        p.moveTo(-29, -1); p.lineTo(-29, -30); p.lineTo(29, -30); p.lineTo(29, -59); p.lineTo(0, -59); p.lineTo(0, -1); p.closePath();
     72        colours.add(new Instr(Form.S2, p));
     73        p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -30); p.lineTo(0, -30); p.lineTo(0, -1); p.closePath();
     74        colours.add(new Instr(Form.S3, p));
     75        p = new Path2D.Double(); p.moveTo(0, -1); p.lineTo(0, -30); p.lineTo(29, -30); p.lineTo(29, -1); p.closePath();
     76        colours.add(new Instr(Form.S4, p));
     77        TopBoard.add(new Instr(Form.COLR, colours));
     78        TopBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     79        TopBoard.add(new Instr(Form.FILL, Color.black));
     80        p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29.0, -1); p.closePath();
     81        TopBoard.add(new Instr(Form.PLIN, p));
     82    }
     83
     84    public static final Symbol TopCan = new Symbol();
     85    static {
     86        TopCan.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     87        Symbol colours = new Symbol();
     88        Path2D.Double p = new Path2D.Double(); p.moveTo(-12.0, -15.0); p.lineTo(-12.0, -48.0); p.lineTo(12.0, -48.0); p.lineTo(12.0, -15.0); p.closePath();
     89        colours.add(new Instr(Form.P1, p));
     90        TopCan.add(new Instr(Form.COLR, colours));
     91        TopCan.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     92        TopCan.add(new Instr(Form.FILL, Color.black));
     93        TopCan.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     94        p = new Path2D.Double(); p.moveTo(-12.0, -15.0); p.lineTo(-12.0, -48.0); p.lineTo(12.0, -48.0); p.lineTo(12.0, -15.0); p.closePath();
     95        TopCan.add(new Instr(Form.PLIN, p));
     96    }
     97
     98    public static final Symbol TopCanSphere = new Symbol();
     99    public static final Symbol TopCircle = new Symbol();
     100    public static final Symbol TopCircleTriangle = new Symbol();
     101    public static final Symbol TopCone = new Symbol();
     102    static {
     103        TopCone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     104        Symbol colours = new Symbol();
     105        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -15.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -15.0); p.closePath();
     106        colours.add(new Instr(Form.P1, p));
     107        TopCone.add(new Instr(Form.COLR, colours));
     108        TopCone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     109        TopCone.add(new Instr(Form.FILL, Color.black));
     110        TopCone.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     111        p = new Path2D.Double(); p.moveTo(-15.0, -15.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -15.0); p.closePath();
     112        TopCone.add(new Instr(Form.PLIN, p));
     113    }
     114
     115    public static final Symbol TopConeSphere = new Symbol();
     116    static {
     117        TopConeSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     118        Symbol colours = new Symbol();
     119        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -47.0); p.lineTo(0.0, -77.0); p.lineTo(15.0, -47.0); p.closePath();
     120        p.moveTo(-14.0, -28.0); p.curveTo(-14.0, -46.7, 14.0, -46.7, 14.0, -28.0); p.curveTo(14.0, -9.3, -14.0, -9.3, -14.0, -28.0); p.closePath();
     121        colours.add(new Instr(Form.P1, p));
     122        TopConeSphere.add(new Instr(Form.COLR, colours));
     123        TopConeSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     124        TopConeSphere.add(new Instr(Form.FILL, Color.black));
     125        TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     126        TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0, -42, 0, -47)));
     127        p = new Path2D.Double(); p.moveTo(-15.0, -47.0); p.lineTo(0.0, -77.0); p.lineTo(15.0, -47.0); p.closePath();
     128        TopConeSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -42, 28, 28)));
     129        TopConeSphere.add(new Instr(Form.PLIN, p));
     130    }
     131
     132    public static final Symbol TopCross = new Symbol();
     133    static {
     134        TopCross.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     135        Symbol colours = new Symbol();
     136        Path2D.Double p = new Path2D.Double(); p.moveTo(-5.0, -15.0); p.lineTo(-5.0, -32.5); p.lineTo(-22.5, -32.5); p.lineTo(-22.5, -42.5); p.lineTo(-5.0, -42.5);
     137        p.lineTo(-5.0, -60.0); p.lineTo(5.0, -60.0); p.lineTo(5.0, -42.5); p.lineTo(22.5, -42.5); p.lineTo(22.5, -32.5); p.lineTo(5.0, -32.5); p.lineTo(5.0, -15.0); p.closePath();
     138        colours.add(new Instr(Form.P1, p));
     139        TopCross.add(new Instr(Form.COLR, colours));
     140        TopCross.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     141        TopCross.add(new Instr(Form.FILL, Color.black));
     142        TopCross.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     143        TopCross.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     144        p = new Path2D.Double(); p.moveTo(-5.0, -15.0); p.lineTo(-5.0, -32.5); p.lineTo(-22.5, -32.5); p.lineTo(-22.5, -42.5); p.lineTo(-5.0, -42.5); p.lineTo(-5.0, -60.0);
     145        p.lineTo(5.0, -60.0); p.lineTo(5.0, -42.5); p.lineTo(22.5, -42.5); p.lineTo(22.5, -32.5); p.lineTo(5.0, -32.5); p.lineTo(5.0, -15.0); p.closePath();
     146        TopCross.add(new Instr(Form.PLIN, p));
     147    }
     148
     149    public static final Symbol TopCrosses = new Symbol();
     150
     151    public static final Symbol TopCrossCircle = new Symbol();
     152
     153    public static final Symbol TopCube = new Symbol();
     154    static {
     155        TopCube.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     156        Symbol colours = new Symbol();
     157        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -48); p.lineTo(-15, -37); p.lineTo(-15, -20); p.lineTo(0, -9); p.lineTo(15, -20); p.lineTo(15, -37); p.closePath();
     158        colours.add(new Instr(Form.P1, p));
     159        TopCube.add(new Instr(Form.COLR, colours));
     160        TopCube.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     161        TopCube.add(new Instr(Form.FILL, Color.black));
     162        TopCube.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     163        p = new Path2D.Double(); p.moveTo(0, -48); p.lineTo(-14, -37); p.lineTo(0, -26); p.lineTo(14, -37); p.closePath(); p.moveTo(0, -26); p.lineTo(0, 0);
     164        p.moveTo(-15, -37); p.lineTo(-15, -20); p.lineTo(0, -9); p.lineTo(15, -20); p.lineTo(15, -37);
     165        TopCube.add(new Instr(Form.PLIN, p));
     166    }
     167
     168    public static final Symbol TopEast = new Symbol();
     169    static {
     170        TopEast.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     171        Symbol colours = new Symbol();
     172        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -80.0); p.lineTo(-15.0, -47.0); p.lineTo(15.0, -47.0); p.closePath();
     173        colours.add(new Instr(Form.P1, p));
     174        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
     175        colours.add(new Instr(Form.P2, p));
     176        TopEast.add(new Instr(Form.COLR, colours));
     177        TopEast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     178        TopEast.add(new Instr(Form.FILL, Color.black));
     179        TopEast.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
     180        TopEast.add(new Instr(Form.LINE, new Line2D.Double(0, -43, 0, -47)));
     181        TopEast.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     182        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
     183        p.moveTo(0.0, -80.0); p.lineTo(-15.0, -47.0); p.lineTo(15.0, -47.0); p.closePath();
     184        TopEast.add(new Instr(Form.PLIN, p));
     185    }
     186
     187    public static final Symbol TopFlag = new Symbol();
     188    static {
     189        TopFlag.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     190        Symbol colours = new Symbol();
     191        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -40); p.lineTo(0, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
     192        colours.add(new Instr(Form.P1, p));
     193        p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(0, -10); p.lineTo(40, -10); p.lineTo(39, -25); p.closePath();
     194        colours.add(new Instr(Form.H2, p));
     195        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(0, -20); p.lineTo(40, -20); p.lineTo(39, -30); p.closePath();
     196        colours.add(new Instr(Form.H3, p));
     197        p = new Path2D.Double(); p.moveTo(19.5, -40); p.lineTo(19.5, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
     198        colours.add(new Instr(Form.V2, p));
     199        p = new Path2D.Double(); p.moveTo(13, -40); p.lineTo(13, -10); p.lineTo(26, -10); p.lineTo(26, -40); p.closePath();
     200        colours.add(new Instr(Form.V3, p));
     201        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     202        p.moveTo(0, -40); p.lineTo(0, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
     203        p.moveTo(8, -35); p.lineTo(8, -15); p.lineTo(33, -15); p.lineTo(33, -35); p.closePath();
     204        colours.add(new Instr(Form.B1, p));
     205        p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(0, -10); p.lineTo(20, -10); p.lineTo(20, -40); p.lineTo(39, -40); p.lineTo(39, -25); p.closePath();
     206        colours.add(new Instr(Form.S2, p));
     207        p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(0, -10); p.lineTo(20, -10); p.lineTo(20, -25); p.closePath();
     208        colours.add(new Instr(Form.S3, p));
     209        p = new Path2D.Double(); p.moveTo(20, -25); p.lineTo(20, -10); p.lineTo(39, -10); p.lineTo(39, -25); p.closePath();
     210        colours.add(new Instr(Form.S4, p));
     211        TopFlag.add(new Instr(Form.COLR, colours));
     212        TopFlag.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     213        TopFlag.add(new Instr(Form.FILL, Color.black));
     214        TopFlag.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -45)));
     215        TopFlag.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     216        TopFlag.add(new Instr(Form.RECT, new Rectangle2D.Double(0, -40, 39, 30)));
     217    }
     218
     219    public static final Symbol TopIcone = new Symbol();
     220    static {
     221        TopIcone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     222        Symbol colours = new Symbol();
     223        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -45.0); p.lineTo(0.0, -15.0); p.lineTo(15.0, -45.0); p.closePath();
     224        colours.add(new Instr(Form.P1, p));
     225        TopIcone.add(new Instr(Form.COLR, colours));
     226        TopIcone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     227        TopIcone.add(new Instr(Form.FILL, Color.black));
     228        TopIcone.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     229        p = new Path2D.Double(); p.moveTo(-15.0, -45.0); p.lineTo(0.0, -15.0); p.lineTo(15.0, -45.0); p.closePath();
     230        TopIcone.add(new Instr(Form.PLIN, p));
     231    }
     232
     233    public static final Symbol TopIsol = new Symbol();
     234    static {
     235        TopIsol.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     236        Symbol colours = new Symbol();
     237        Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0, -55.0); p.curveTo(-13.0, -72.3, 13.0, -72.3, 13.0, -55.0); p.curveTo(13.0, -37.7, -13.0, -37.7, -13.0, -55.0); p.closePath();
     238        colours.add(new Instr(Form.P1, p));
     239        p = new Path2D.Double(); p.moveTo(-13.0, -28.0); p.curveTo(-13.0, -45.3, 13.0, -45.3, 13.0, -28.0); p.curveTo(13.0, -10.7, -13.0, -10.7, -13.0, -28.0); p.closePath();
     240        colours.add(new Instr(Form.P2, p));
     241        TopIsol.add(new Instr(Form.COLR, colours));
     242        TopIsol.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     243        TopIsol.add(new Instr(Form.FILL, Color.black));
     244        TopIsol.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     245        TopIsol.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     246        TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13, -41, 26, 26)));
     247        TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13, -68, 26, 26)));
     248    }
     249
     250    public static final Symbol TopMooring = new Symbol();
     251    static {
     252        TopMooring.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     253        TopMooring.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     254        TopMooring.add(new Instr(Form.FILL, Color.black));
     255        TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.5, -6, 3, 3)));
     256        TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-8.5, -25, 17, 17)));
     257    }
     258
     259    public static final Symbol TopNorth = new Symbol();
     260    static {
     261        TopNorth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     262        Symbol colours = new Symbol();
     263        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -78.0); p.lineTo(-15.0, -45.0); p.lineTo(15.0, -45.0); p.closePath();
     264        colours.add(new Instr(Form.P1, p));
     265        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
     266        colours.add(new Instr(Form.P2, p));
     267        TopNorth.add(new Instr(Form.COLR, colours));
     268        TopNorth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     269        TopNorth.add(new Instr(Form.FILL, Color.black));
     270        TopNorth.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
     271        TopNorth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     272        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
     273        p.moveTo(0.0, -78.0); p.lineTo(-15.0, -45.0); p.lineTo(15.0, -45.0); p.closePath();
     274        TopNorth.add(new Instr(Form.PLIN, p));
     275    }
     276
     277    public static final Symbol TopSouth = new Symbol();
     278    static {
     279        TopSouth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     280        Symbol colours = new Symbol();
     281        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
     282        colours.add(new Instr(Form.P1, p));
     283        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
     284        colours.add(new Instr(Form.P2, p));
     285        TopSouth.add(new Instr(Form.COLR, colours));
     286        TopSouth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     287        TopSouth.add(new Instr(Form.FILL, Color.black));
     288        TopSouth.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
     289        TopSouth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     290        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
     291        p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
     292        TopSouth.add(new Instr(Form.PLIN, p));
     293    }
     294
     295    public static final Symbol TopSphere = new Symbol();
     296    static {
     297        TopSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     298        Symbol colours = new Symbol();
     299        Path2D.Double p = new Path2D.Double(); p.moveTo(-14.0, -28.0); p.curveTo(-14.0, -46.7, 14.0, -46.7, 14.0, -28.0); p.curveTo(14.0, -9.3, -14.0, -9.3, -14.0, -28.0); p.closePath();
     300        colours.add(new Instr(Form.P1, p));
     301        TopSphere.add(new Instr(Form.COLR, colours));
     302        TopSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     303        TopSphere.add(new Instr(Form.FILL, Color.black));
     304        TopSphere.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
     305        TopSphere.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     306        TopSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -42, 28, 28)));
     307    }
     308
     309    public static final Symbol TopSquare = new Symbol();
     310    static {
     311        TopSquare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     312        Symbol colours = new Symbol();
     313        Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-13.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     314        colours.add(new Instr(Form.P1, p));
     315        p = new Path2D.Double(); p.moveTo(-13.0, -15.0); p.lineTo(-13.0, -1.0); p.lineTo(13.0, -1.0); p.lineTo(13.0, -15.0); p.closePath();
     316        colours.add(new Instr(Form.H2, p));
     317        p = new Path2D.Double(); p.moveTo(-13.0, -19.3); p.lineTo(-13.0, -10.7); p.lineTo(13.0, -10.7); p.lineTo(13.0, -19.3); p.closePath();
     318        colours.add(new Instr(Form.H3, p));
     319        p = new Path2D.Double(); p.moveTo(0.0, -1.0); p.lineTo(0.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     320        colours.add(new Instr(Form.V2, p));
     321        p = new Path2D.Double(); p.moveTo(-4.3, -1.0); p.lineTo(-4.3, -27.0); p.lineTo(4.3, -27.0); p.lineTo(4.3, -1.0); p.closePath();
     322        colours.add(new Instr(Form.V3, p));
     323        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     324        p.moveTo(-13.0, -1.0); p.lineTo(-13.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     325        p.moveTo(-8.0, -6.0); p.lineTo(-8.0, -22.0); p.lineTo(8.0, -22.0); p.lineTo(8.0, -6.0); p.closePath();
     326        colours.add(new Instr(Form.B1, p));
     327        TopSquare.add(new Instr(Form.COLR, colours));
     328        TopSquare.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     329        TopSquare.add(new Instr(Form.FILL, Color.black));
     330        p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-13.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     331        TopSquare.add(new Instr(Form.PLIN, p));
     332    }
     333
     334    public static final Symbol TopRectangleH = new Symbol();
     335    static {
     336        TopRectangleH.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     337        Symbol colours = new Symbol();
     338        Path2D.Double p = new Path2D.Double(); p.moveTo(-20.0, -1.0); p.lineTo(-20.0, -27.0); p.lineTo(20.0, -27.0); p.lineTo(20.0, -1.0); p.closePath();
     339        colours.add(new Instr(Form.P1, p));
     340        TopRectangleH.add(new Instr(Form.COLR, colours));
     341        TopRectangleH.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     342        TopRectangleH.add(new Instr(Form.FILL, Color.black));
     343        p = new Path2D.Double(); p.moveTo(-20.0, -1.0); p.lineTo(-20.0, -27.0); p.lineTo(20.0, -27.0); p.lineTo(20.0, -1.0); p.closePath();
     344        TopRectangleH.add(new Instr(Form.PLIN, p));
     345    }
     346
     347    public static final Symbol TopRectangleV = new Symbol();
     348    static {
     349        TopRectangleV.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     350        Symbol colours = new Symbol();
     351        Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-13.0, -41.0); p.lineTo(13.0, -41.0); p.lineTo(13.0, -1.0); p.closePath();
     352        colours.add(new Instr(Form.P1, p));
     353        TopRectangleV.add(new Instr(Form.COLR, colours));
     354        TopRectangleV.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     355        TopRectangleV.add(new Instr(Form.FILL, Color.black));
     356        p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-13.0, -41.0); p.lineTo(13.0, -41.0); p.lineTo(13.0, -1.0); p.closePath();
     357        TopRectangleV.add(new Instr(Form.PLIN, p));
     358    }
     359
     360    public static final Symbol TopRhombus = new Symbol();
     361    static {
     362        TopRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     363        Symbol colours = new Symbol();
     364        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -29.0); p.lineTo(-15.0, -15.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
     365        colours.add(new Instr(Form.P1, p));
     366        p = new Path2D.Double(); p.moveTo(-15.0, -15.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
     367        colours.add(new Instr(Form.H2, p));
     368        p = new Path2D.Double(); p.moveTo(-10.0, -19.7); p.lineTo(-15.0, -15.0); p.lineTo(-10.0, -10.3); p.lineTo(10.0, -10.3); p.lineTo(15.0, -15.0); p.lineTo(10.0, -19.7); p.closePath();
     369        colours.add(new Instr(Form.H3, p));
     370        p = new Path2D.Double(); p.moveTo(0.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
     371        colours.add(new Instr(Form.V2, p));
     372        p = new Path2D.Double(); p.moveTo(0.0, -29.0); p.lineTo(-5.0, -24.3); p.lineTo(-5.0, -5.7); p.lineTo(0.0, -1.0); p.lineTo(5.0, -5.7); p.lineTo(5.0, -24.3); p.closePath();
     373        colours.add(new Instr(Form.V3, p));
     374        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     375        p.moveTo(0.0, -29.0); p.lineTo(-15.0, -15.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
     376        p.moveTo(0.0, -23.0); p.lineTo(-9.0, -15.0); p.lineTo(0.0, -7.0); p.lineTo(9.0, -15.0); p.closePath();
     377        colours.add(new Instr(Form.B1, p));
     378        TopRhombus.add(new Instr(Form.COLR, colours));
     379        TopRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     380        TopRhombus.add(new Instr(Form.FILL, Color.black));
     381        p = new Path2D.Double(); p.moveTo(0.0, -29.0); p.lineTo(-15.0, -15.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
     382        TopRhombus.add(new Instr(Form.PLIN, p));
     383    }
     384
     385    public static final Symbol TopRhombusCircle = new Symbol();
     386
     387    public static final Symbol TopSphereRhombus = new Symbol();
     388    static {
     389        TopSphereRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     390        TopSphereRhombus.add(new Instr(Form.SYMB, new Symbols.SubSymbol(TopRhombus, 1.0, 0, 0, null, null)));
     391        Symbol colours = new Symbol();
     392        Path2D.Double p = new Path2D.Double(); p.moveTo(-14.0, -44.0); p.curveTo(-14.0, -62.7, 14.0, -62.7, 14.0, -44.0); p.curveTo(14.0, -25.3, -14.0, -25.3, -14.0, -44.0); p.closePath();
     393        colours.add(new Instr(Form.P1, p));
     394        TopSphereRhombus.add(new Instr(Form.COLR, colours));
     395        TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     396        TopSphereRhombus.add(new Instr(Form.FILL, Color.black));
     397        TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     398        TopSphereRhombus.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -58, 28, 28)));
     399    }
     400
     401    public static final Symbol TopT = new Symbol();
     402
     403    public static final Symbol TopTrapeziumU = new Symbol();
     404    static {
     405        TopTrapeziumU.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     406        Symbol colours = new Symbol();
     407        Path2D.Double p = new Path2D.Double(); p.moveTo(-20.0, -1.0); p.lineTo(-13.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(20.0, -1.0); p.closePath();
     408        colours.add(new Instr(Form.P1, p));
     409        TopTrapeziumU.add(new Instr(Form.COLR, colours));
     410        TopTrapeziumU.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     411        TopTrapeziumU.add(new Instr(Form.FILL, Color.black));
     412        p = new Path2D.Double(); p.moveTo(-20.0, -1.0); p.lineTo(-13.0, -27.0); p.lineTo(13.0, -27.0); p.lineTo(20.0, -1.0); p.closePath();
     413        TopTrapeziumU.add(new Instr(Form.PLIN, p));
     414    }
     415
     416    public static final Symbol TopTrapeziumD = new Symbol();
     417    static {
     418        TopTrapeziumD.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     419        Symbol colours = new Symbol();
     420        Path2D.Double p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-20.0, -27.0); p.lineTo(20.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     421        colours.add(new Instr(Form.P1, p));
     422        TopTrapeziumD.add(new Instr(Form.COLR, colours));
     423        TopTrapeziumD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     424        TopTrapeziumD.add(new Instr(Form.FILL, Color.black));
     425        p = new Path2D.Double(); p.moveTo(-13.0, -1.0); p.lineTo(-20.0, -27.0); p.lineTo(20.0, -27.0); p.lineTo(13.0, -1.0); p.closePath();
     426        TopTrapeziumD.add(new Instr(Form.PLIN, p));
     427    }
     428
     429    public static final Symbol TopTriangle = new Symbol();
     430    static {
     431        TopTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     432        Symbol colours = new Symbol();
     433        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -1.0); p.lineTo(0.0, -29.0); p.lineTo(15.0, -1.0); p.closePath();
     434        colours.add(new Instr(Form.P1, p));
     435        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     436        p.moveTo(-15.0, -1.0); p.lineTo(0.0, -29.0); p.lineTo(15.0, -1.0); p.closePath();
     437        p.moveTo(-10.0, -6.0); p.lineTo(0.0, -24.0); p.lineTo(10.0, -6.0); p.closePath();
     438        colours.add(new Instr(Form.B1, p));
     439        TopTriangle.add(new Instr(Form.COLR, colours));
     440        TopTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     441        TopTriangle.add(new Instr(Form.FILL, Color.black));
     442        p = new Path2D.Double(); p.moveTo(-15.0, -1.0); p.lineTo(0.0, -29.0); p.lineTo(15.0, -1.0); p.closePath();
     443        TopTriangle.add(new Instr(Form.PLIN, p));
     444    }
     445
     446    public static final Symbol TopItriangle = new Symbol();
     447    static {
     448        TopItriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
     449        Symbol colours = new Symbol();
     450        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -29.0); p.closePath();
     451        colours.add(new Instr(Form.P1, p));
     452        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
     453        p.moveTo(-15.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -29.0); p.closePath();
     454        p.moveTo(-10.0, -24.0); p.lineTo(0.0, -6.0); p.lineTo(10.0, -24.0); p.closePath();
     455        colours.add(new Instr(Form.B1, p));
     456        TopItriangle.add(new Instr(Form.COLR, colours));
     457        TopItriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     458        TopItriangle.add(new Instr(Form.FILL, Color.black));
     459        p = new Path2D.Double(); p.moveTo(-15.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -29.0); p.closePath();
     460        TopItriangle.add(new Instr(Form.PLIN, p));
     461    }
     462
     463    public static final Symbol TopTriangleCircle = new Symbol();
     464
     465    public static final Symbol TopWest = new Symbol();
     466    static {
     467        TopWest.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     468        Symbol colours = new Symbol();
     469        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
     470        colours.add(new Instr(Form.P1, p));
     471        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
     472        colours.add(new Instr(Form.P2, p));
     473        TopWest.add(new Instr(Form.COLR, colours));
     474        TopWest.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     475        TopWest.add(new Instr(Form.FILL, Color.black));
     476        TopWest.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
     477        TopWest.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     478        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
     479        p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
     480        TopWest.add(new Instr(Form.PLIN, p));
     481    }
     482
     483    public static final Symbol TopX = new Symbol();
     484    static {
     485        TopX.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
     486        Symbol colours = new Symbol();
     487        Path2D.Double p = new Path2D.Double(); p.moveTo(0.0, -27.7); p.lineTo(-12.4, -15.7); p.lineTo(-19.3, -22.6); p.lineTo(-7.3, -35.0); p.lineTo(-19.3, -47.3);
     488        p.lineTo(-12.4, -54.2); p.lineTo(0.0, -42.4); p.lineTo(12.4, -54.2); p.lineTo(19.3, -47.3); p.lineTo(7.3, -35.0); p.lineTo(19.3, -22.6); p.lineTo(12.4, -15.7); p.closePath();
     489        colours.add(new Instr(Form.P1, p));
     490        TopX.add(new Instr(Form.COLR, colours));
     491        TopX.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     492        TopX.add(new Instr(Form.FILL, Color.black));
     493        TopX.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -27)));
     494        TopX.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
     495        p = new Path2D.Double(); p.moveTo(0.0, -27.7); p.lineTo(-12.4, -15.7); p.lineTo(-19.3, -22.6); p.lineTo(-7.3, -35.0); p.lineTo(-19.3, -47.3); p.lineTo(-12.4, -54.2); p.lineTo(0.0, -42.4);
     496        p.lineTo(12.4, -54.2); p.lineTo(19.3, -47.3); p.lineTo(7.3, -35.0); p.lineTo(19.3, -22.6); p.lineTo(12.4, -15.7); p.closePath();
     497        TopX.add(new Instr(Form.PLIN, p));
     498    }
     499
     500    public static final Symbol TopOther = new Symbol();
     501
     502    public static final EnumMap<TopSHP, Symbol> Shapes = new EnumMap<>(TopSHP.class);
     503    static {
     504        Shapes.put(TopSHP.TOP_BESM, TopBesom); Shapes.put(TopSHP.TOP_IBESM, TopIBesom); Shapes.put(TopSHP.TOP_BORD, TopBoard); Shapes.put(TopSHP.TOP_CAN, TopCan);
     505        Shapes.put(TopSHP.TOP_CONE, TopCone); Shapes.put(TopSHP.TOP_CROS, TopCross); Shapes.put(TopSHP.TOP_EAST, TopEast); Shapes.put(TopSHP.TOP_ICONE, TopIcone);
     506        Shapes.put(TopSHP.TOP_ISD, TopIsol); Shapes.put(TopSHP.TOP_NORTH, TopNorth); Shapes.put(TopSHP.TOP_SOUTH, TopSouth); Shapes.put(TopSHP.TOP_SPHR, TopSphere);
     507        Shapes.put(TopSHP.TOP_SQUR, TopSquare); Shapes.put(TopSHP.TOP_TRI, TopTriangle); Shapes.put(TopSHP.TOP_ITRI, TopItriangle); Shapes.put(TopSHP.TOP_WEST, TopWest);
     508        Shapes.put(TopSHP.TOP_SALT, TopX); Shapes.put(TopSHP.TOP_RHOM, TopRhombus); Shapes.put(TopSHP.TOP_FLAG, TopFlag); Shapes.put(TopSHP.TOP_CUBE, TopCube);
     509        Shapes.put(TopSHP.TOP_SPRH, TopSphereRhombus); Shapes.put(TopSHP.TOP_HRECT, TopRectangleH); Shapes.put(TopSHP.TOP_VRECT, TopRectangleV);
     510        Shapes.put(TopSHP.TOP_TRAP, TopTrapeziumU); Shapes.put(TopSHP.TOP_ITRAP, TopTrapeziumD); Shapes.put(TopSHP.TOP_COSP, TopConeSphere);
     511        Shapes.put(TopSHP.TOP_CIRC, TopCircle); Shapes.put(TopSHP.TOP_CRSS, TopCrosses); Shapes.put(TopSHP.TOP_T, TopT); Shapes.put(TopSHP.TOP_TRCL, TopTriangleCircle);
     512        Shapes.put(TopSHP.TOP_CRCL, TopCrossCircle); Shapes.put(TopSHP.TOP_RHCL, TopRhombusCircle); Shapes.put(TopSHP.TOP_CLTR, TopCircleTriangle);
     513        Shapes.put(TopSHP.TOP_CYSP, TopCanSphere); Shapes.put(TopSHP.TOP_OTHR, TopOther);
     514    }
     515
     516    // CHECKSTYLE.OFF: SingleSpaceSeparator
     517    public static final EnumMap<BoySHP, Delta> BuoyDeltas = new EnumMap<>(BoySHP.class);
     518    static {
     519        BuoyDeltas.put(BoySHP.BOY_PILR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
     520        BuoyDeltas.put(BoySHP.BOY_SPAR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
     521        BuoyDeltas.put(BoySHP.BOY_CAN,  new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
     522        BuoyDeltas.put(BoySHP.BOY_CONE, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
     523        BuoyDeltas.put(BoySHP.BOY_SPHR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
     524        BuoyDeltas.put(BoySHP.BOY_BARL, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
     525        BuoyDeltas.put(BoySHP.BOY_SUPR, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0)));
     526        BuoyDeltas.put(BoySHP.BOY_ICE,  new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -25.0)));
     527    }
     528
     529    public static final Delta FloatDelta  = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0));
     530    public static final Delta BeaconDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -70.0));
     531    public static final Delta LightDelta  = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -20.0));
     532    // CHECKSTYLE.ON: SingleSpaceSeparator
    506533}
Note: See TracChangeset for help on using the changeset viewer.