Index: applications/editors/josm/plugins/seachart/.checkstyle
===================================================================
--- applications/editors/josm/plugins/seachart/.checkstyle	(revision 32394)
+++ applications/editors/josm/plugins/seachart/.checkstyle	(revision 32394)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <local-check-config name="JOSM" location="/JOSM/tools/checkstyle/josm_checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="JOSM" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+</fileset-config>
Index: applications/editors/josm/plugins/seachart/.project
===================================================================
--- applications/editors/josm/plugins/seachart/.project	(revision 32393)
+++ applications/editors/josm/plugins/seachart/.project	(revision 32394)
@@ -16,7 +16,13 @@
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
 	</natures>
 </projectDescription>
Index: applications/editors/josm/plugins/seachart/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- applications/editors/josm/plugins/seachart/.settings/org.eclipse.jdt.ui.prefs	(revision 32394)
+++ applications/editors/josm/plugins/seachart/.settings/org.eclipse.jdt.ui.prefs	(revision 32394)
@@ -0,0 +1,60 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=true
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
Index: applications/editors/josm/plugins/seachart/src/render/ChartContext.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/ChartContext.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/render/ChartContext.java	(revision 32394)
@@ -14,13 +14,18 @@
 
 import s57.S57map;
-import s57.S57map.*;
+import s57.S57map.Feature;
+import s57.S57map.Snode;
 
 public interface ChartContext {
-	public enum RuleSet { ALL, BASE, SEAMARK }
+    enum RuleSet { ALL, BASE, SEAMARK }
 
-	Point2D getPoint(Snode coord);
-	double mile(Feature feature);
-	boolean clip();
-	Color background(S57map map);
-	RuleSet ruleset();
+    Point2D getPoint(Snode coord);
+
+    double mile(Feature feature);
+
+    boolean clip();
+
+    Color background(S57map map);
+
+    RuleSet ruleset();
 }
Index: applications/editors/josm/plugins/seachart/src/render/Renderer.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 32394)
@@ -10,596 +10,630 @@
 package render;
 
-import java.awt.*;
-import java.awt.font.*;
-import java.awt.geom.*;
-import java.awt.image.*;
-import java.util.*;
-
-import s57.S57val.*;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.TexturePaint;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+
 import s57.S57map;
-import s57.S57map.*;
+import s57.S57map.GeomIterator;
+import s57.S57map.Pflag;
+import s57.S57map.Snode;
+import s57.S57val.UniHLU;
 import symbols.Areas;
 import symbols.Symbols;
-import symbols.Symbols.*;
+import symbols.Symbols.Caption;
+import symbols.Symbols.Delta;
+import symbols.Symbols.Form;
+import symbols.Symbols.Handle;
+import symbols.Symbols.Instr;
+import symbols.Symbols.LineStyle;
+import symbols.Symbols.Scheme;
+import symbols.Symbols.SubSymbol;
+import symbols.Symbols.Symbol;
 
 public class Renderer {
 
-	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 };
-
-	public enum LabelStyle { NONE, RRCT, RECT, ELPS, CIRC, VCLR, PCLR, HCLR }
-
-	static ChartContext context;
-	static S57map map;
-	static double sScale;
-	static Graphics2D g2;
-	static int zoom;
-
-	public static void reRender(Graphics2D g, Rectangle rect, int z, double factor, S57map m, ChartContext c) {
-		g2 = g;
-		zoom = z;
-		context = c;
-		map = m;
-		sScale = symbolScale[zoom] * factor;
-		if (map != null) {
-			if (context.clip()) {
-				Point2D tl = context.getPoint(map.new Snode(map.bounds.maxlat, map.bounds.minlon));
-				Point2D br = context.getPoint(map.new Snode(map.bounds.minlat, map.bounds.maxlon));
-				g2.clip(new Rectangle2D.Double(tl.getX(), tl.getY(), (br.getX() - tl.getX()), (br.getY() - tl.getY())));
-			}
-			g2.setBackground(context.background(map));
-			g2.clearRect(rect.x, rect.y, rect.width, rect.height);
-			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-			g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
-			g2.setStroke(new BasicStroke(0, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
-			Rules.rules();
-		}
-	}
-
-	public static void symbol(Symbol symbol) {
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, null);
-	}
-	public static void symbol(Symbol symbol, Scheme scheme) {
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, null);
-	}
-	public static void symbol(Symbol symbol, Delta delta) {
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, delta);
-	}
-	public static void symbol(Symbol symbol, Scheme scheme, Delta delta) {
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, delta);
-	}
-	
-	public static void cluster(ArrayList<Symbol> symbols) {
-		Rectangle2D.Double bbox = null;
-		if (symbols.size() > 4) {
-			for (Instr instr : symbols.get(0)) {
-				if (instr.type == Form.BBOX) {
-					bbox = (Rectangle2D.Double) instr.params;
-					break;
-				}
-			}
-			if (bbox == null) return;
-		}
-		switch (symbols.size()) {
-		case 1:
-			symbol(symbols.get(0), new Delta(Handle.CC, new AffineTransform()));
-			break;
-		case 2:
-			symbol(symbols.get(0), new Delta(Handle.RC, new AffineTransform()));
-			symbol(symbols.get(1), new Delta(Handle.LC, new AffineTransform()));
-			break;
-		case 3:
-			symbol(symbols.get(0), new Delta(Handle.BC, new AffineTransform()));
-			symbol(symbols.get(1), new Delta(Handle.TR, new AffineTransform()));
-			symbol(symbols.get(2), new Delta(Handle.TL, new AffineTransform()));
-			break;
-		case 4:
-			symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
-			symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
-			symbol(symbols.get(2), new Delta(Handle.TR, new AffineTransform()));
-			symbol(symbols.get(3), new Delta(Handle.TL, new AffineTransform()));
-			break;
-		case 5:
-			symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
-			symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
-			symbol(symbols.get(2), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(3), new Delta(Handle.TC, new AffineTransform()));
-			symbol(symbols.get(4), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			break;
-		case 6:
-			symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(1), new Delta(Handle.BC, new AffineTransform()));
-			symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			symbol(symbols.get(3), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(4), new Delta(Handle.TC, new AffineTransform()));
-			symbol(symbols.get(5), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			break;
-		case 7:
-			symbol(symbols.get(0), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
-			symbol(symbols.get(1), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(2), new Delta(Handle.CC, new AffineTransform()));
-			symbol(symbols.get(3), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			symbol(symbols.get(4), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
-			symbol(symbols.get(5), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
-			symbol(symbols.get(6), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
-			break;
-		case 8:
-			symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
-			symbol(symbols.get(1), new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
-			symbol(symbols.get(2), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(3), new Delta(Handle.CC, new AffineTransform()));
-			symbol(symbols.get(4), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			symbol(symbols.get(5), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
-			symbol(symbols.get(6), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
-			symbol(symbols.get(7), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
-			break;
-		case 9:
-			symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, -bbox.height/2)));
-			symbol(symbols.get(1), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
-			symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, -bbox.height/2)));
-			symbol(symbols.get(3), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
-			symbol(symbols.get(4), new Delta(Handle.CC, new AffineTransform()));
-			symbol(symbols.get(5), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
-			symbol(symbols.get(6), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
-			symbol(symbols.get(7), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
-			symbol(symbols.get(8), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
-			break;
-		}
-	}
-
-	private static Rectangle2D.Double symbolSize(Symbol symbol) {
-		Symbol ssymb = symbol;
-		while (ssymb != null) {
-			for (Instr item : symbol) {
-				if (item.type == Form.BBOX) {
-					return (Rectangle2D.Double) item.params;
-				}
-				if (item.type == Form.SYMB) {
-					ssymb = ((SubSymbol) item.params).instr;
-					break;
-				}
-			}
-			if (ssymb == symbol)
-				break;
-		}
-		return null;
-	}
-
-	public static void lineSymbols(Symbol prisymb, double space, Symbol secsymb, Symbol tersymb, int ratio, Color col) {
-		if ((Rules.feature.geom.prim == Pflag.NOSP) || (Rules.feature.geom.prim == Pflag.POINT))
-			return;
-		Rectangle2D.Double prect = symbolSize(prisymb);
-		Rectangle2D.Double srect = symbolSize(secsymb);
-		Rectangle2D.Double trect = symbolSize(tersymb);
-		if (srect == null)
-			ratio = 0;
-		if (prect != null) {
-			double psize = Math.abs(prect.getY()) * sScale;
-			double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
-			double tsize = (trect != null) ? Math.abs(srect.getY()) * sScale : 0;
-			Point2D prev = new Point2D.Double();
-			Point2D next = new Point2D.Double();
-			Point2D curr = new Point2D.Double();
-			Point2D succ = new Point2D.Double();
-			boolean gap = true;
-			boolean piv = false;
-			double len = 0;
-			double angle = 0;
-			int stcount = ratio;
-			boolean stflag = false;
-			Symbol symbol = prisymb;
-			GeomIterator git = map.new GeomIterator(Rules.feature.geom);
-			while (git.hasComp()) {
-				git.nextComp();
-				boolean first = true;
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						Snode node = git.next();
-						if (node == null) continue;
-						prev = next;
-						next = context.getPoint(node);
-						angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
-						piv = true;
-						if (first) {
-							curr = succ = next;
-							gap = (space > 0);
-							stcount = ratio - 1;
-							symbol = prisymb;
-							len = gap ? psize * space * 0.5 : psize;
-							first = false;
-						} else {
-							while (curr.distance(next) >= len) {
-								if (piv) {
-									double rem = len;
-									double s = prev.distance(next);
-									double p = curr.distance(prev);
-									if ((s > 0) && (p > 0)) {
-										double n = curr.distance(next);
-										double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
-										double phi = Math.asin(p / len * Math.sin(theta));
-										rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
-									}
-									succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
-									piv = false;
-								} else {
-									succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
-								}
-								if (!gap) {
-									Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(), new Scheme(col),
-											new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX())) + Math.toRadians(90))));
-								}
-								if (space > 0)
-									gap = !gap;
-								curr = succ;
-								len = gap ? (psize * space) : (--stcount == 0) ? (stflag ? tsize : ssize) : psize;
-								if (stcount == 0) {
-									symbol = stflag ? tersymb : secsymb;
-									if (trect != null)
-										stflag = !stflag;
-									stcount = ratio;
-								} else {
-									symbol = prisymb;
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-
-	public static void lineVector(LineStyle style) {
-		Path2D.Double p = new Path2D.Double();
-		p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		Point2D point;
-		GeomIterator git = map.new GeomIterator(Rules.feature.geom);
-		while (git.hasComp()) {
-			git.nextComp();
-			boolean first = true;
-			while (git.hasEdge()) {
-				git.nextEdge();
-				point = context.getPoint(git.next());
-				if (first) {
-					p.moveTo(point.getX(), point.getY());
-					first = false;
-				} else {
-					p.lineTo(point.getX(), point.getY());
-				}
-				while (git.hasNode()) {
-					Snode node = git.next();
-					if (node == null) continue;
-					point = context.getPoint(node);
-					p.lineTo(point.getX(), point.getY());
-				}
-			}
-		}
-		if ((style.fill != null) && (Rules.feature.geom.prim == Pflag.AREA)) {
-			g2.setPaint(style.fill);
-			g2.fill(p);
-		}
-		if (style.line != null) {
-			if (style.dash != null) {
-				float[] dash = new float[style.dash.length];
-				System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
-				for (int i = 0; i < style.dash.length; i++) {
-					dash[i] *= (float) sScale;
-				}
-				g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
-			} else {
-				g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-			}
-			g2.setPaint(style.line);
-			g2.draw(p);
-		}
-	}
-	
-	public static void lineCircle(LineStyle style, double radius, UniHLU units) {
-		switch (units) {
-		case HLU_FEET:
-			radius /= 6076;
-			break;
-		case HLU_KMTR:
-			radius /= 1.852;
-			break;
-		case HLU_HMTR:
-			radius /= 18.52;
-			break;
-		case HLU_SMIL:
-			radius /= 1.15078;
-			break;
-		case HLU_NMIL:
-			break;
-		default:
-			radius /= 1852;
-			break;
-		}
-		radius *= context.mile(Rules.feature);
-		Symbol circle = new Symbol();
-		if (style.fill != null) {
-			circle.add(new Instr(Form.FILL, style.fill));
-			circle.add(new Instr(Form.RSHP, new Ellipse2D.Double(-radius,-radius,radius*2,radius*2)));
-		}
-		circle.add(new Instr(Form.FILL, style.line));
-		circle.add(new Instr(Form.STRK, new BasicStroke(style.width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, style.dash, 0)));
-		circle.add(new Instr(Form.ELPS, new Ellipse2D.Double(-radius,-radius,radius*2,radius*2)));
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, circle, 1, point.getX(), point.getY(), null, null);
-	}
-
-	public static void fillPattern(BufferedImage image) {
-		Path2D.Double p = new Path2D.Double();
-		p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		Point2D point;
-		switch (Rules.feature.geom.prim) {
-		case POINT:
-			point = context.getPoint(Rules.feature.geom.centre);
-			g2.drawImage(image, new AffineTransformOp(AffineTransform.getScaleInstance(sScale, sScale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
-					(int)(point.getX() - (50 * sScale)), (int)(point.getY() - (50 * sScale)));
-			break;
-		case AREA:
-			GeomIterator git = map.new GeomIterator(Rules.feature.geom);
-			while (git.hasComp()) {
-				git.nextComp();
-				boolean newComp = true;
-				while (git.hasEdge()) {
-					git.nextEdge();
-					point = context.getPoint(git.next());
-					if (newComp) {
-						p.moveTo(point.getX(), point.getY());
-						newComp = false;
-					} else {
-						p.lineTo(point.getX(), point.getY());
-					}
-					while (git.hasNode()) {
-						Snode node = git.next();
-						if (node == null) continue;
-						point = context.getPoint(node);
-						p.lineTo(point.getX(), point.getY());
-					}
-				}
-			}
-	    g2.setPaint(new TexturePaint(image, new Rectangle(0, 0, 1 + (int)(300 * sScale), 1 + (int)(300 * sScale))));
-	    g2.fill(p);
-	    break;
-		default:
-			break;
-		}
-	}
-	
-	public static void labelText(String str, Font font, Color tc) {
-		labelText(str, font, tc, LabelStyle.NONE, null, null, null);
-	}
-	public static void labelText(String str, Font font, Color tc, Delta delta) {
-		labelText(str, font, tc, LabelStyle.NONE, null, null, delta);
-	}
-	public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg) {
-		labelText(str, font, tc, style, fg, null, null);
-	}
-	public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg) {
-		labelText(str, font, tc, style, fg, bg, null);
-	}
-	public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Delta delta) {
-		labelText(str, font, tc, style, fg, null, delta);
-	}
-	public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg, Delta delta) {
-		if (delta == null) delta = new Delta(Handle.CC);
-		if (bg == null) bg = new Color(0x00000000, true);
-		if ((str == null) || (str.isEmpty())) str = " ";
-    FontRenderContext frc = g2.getFontRenderContext();
-    GlyphVector gv = font.deriveFont((float)(font.getSize())).createGlyphVector(frc, str.equals(" ") ? "M" : str);
-    Rectangle2D bounds = gv.getVisualBounds();
-    double width = bounds.getWidth();
-    double height = bounds.getHeight();
-		Symbol label = new Symbol();
-		double lx, ly, tx, ty;
-		switch (style) {
-		case RRCT:
-			width += height * 1.0;
-			height *= 1.5;
-	    if (width < height) width = height;
-	    lx = -width / 2;
-	    ly = -height / 2;
-	    tx = lx + (height * 0.34);
-	    ty = ly + (height * 0.17);
-			label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
-			label.add(new Instr(Form.FILL, bg));
-			label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
-			label.add(new Instr(Form.FILL, fg));
-			label.add(new Instr(Form.STRK, new BasicStroke(1 + (int)(height/10), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-			label.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
-			break;
-		case VCLR:
-			width += height * 1.0;
-			height *= 2.0;
-	    if (width < height) width = height;
-	    lx = -width / 2;
-	    ly = -height / 2;
-	    tx = lx + (height * 0.27);
-	    ty = ly + (height * 0.25);
-			label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
-			label.add(new Instr(Form.FILL, bg));
-			label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
-			label.add(new Instr(Form.FILL, fg));
-			int sw = 1 + (int)(height/10);
-			double po = sw / 2;
-			label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-			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));
-			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));
-			label.add(new Instr(Form.PLIN, p));
-			break;
-		case PCLR:
-			width += height * 1.0;
-			height *= 2.0;
-	    if (width < height) width = height;
-	    lx = -width / 2;
-	    ly = -height / 2;
-	    tx = lx + (height * 0.27);
-	    ty = ly + (height * 0.25);
-			label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
-			label.add(new Instr(Form.FILL, bg));
-			label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
-			label.add(new Instr(Form.FILL, fg));
-			sw = 1 + (int)(height/10);
-			po = sw / 2;
-			label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-			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));
-			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));
-			label.add(new Instr(Form.PLIN, p));
-			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)))));
-			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)))));
-			break;
-		case HCLR:
-			width += height * 1.5;
-			height *= 1.5;
-	    if (width < height) width = height;
-	    lx = -width / 2;
-	    ly = -height / 2;
-	    tx = lx + (height * 0.5);
-	    ty = ly + (height * 0.17);
-			label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
-			label.add(new Instr(Form.FILL, bg));
-			label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx,ly,width,height,height,height)));
-			label.add(new Instr(Form.FILL, fg));
-			sw = 1 + (int)(height/10);
-			double vo = height / 4;
-			label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-			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);
-			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);
-			label.add(new Instr(Form.PLIN, p));
-			break;
-		default:
-			lx = -width / 2;
-			ly = -height / 2;
-			tx = lx;
-			ty = ly;
-			label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx,ly,width,height)));
-			break;
-		}
-		label.add(new Instr(Form.TEXT, new Caption(str, font, tc, new Delta(Handle.TL, AffineTransform.getTranslateInstance(tx, ty)))));
-		Point2D point = context.getPoint(Rules.feature.geom.centre);
-		Symbols.drawSymbol(g2, label, sScale, point.getX(), point.getY(), null, delta);
-	}
-
-	public static void lineText(String str, Font font, Color colour, double dy) {
-		if (!str.isEmpty()) {
-			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-			g2.setPaint(colour);
-			FontRenderContext frc = g2.getFontRenderContext();
-			GlyphVector gv = font.deriveFont(font.getSize2D() * (float) sScale).createGlyphVector(frc, str);
-			double width = gv.getVisualBounds().getWidth();
-			double height = gv.getVisualBounds().getHeight();
-			double offset = (Rules.feature.geom.length * context.mile(Rules.feature) - width) / 2;
-			if (offset > 0) {
-				Point2D before = null;
-				Point2D after = null;
-				ArrayList<Point2D> between = new ArrayList<>();
-				Point2D prev = null;
-				Point2D next = null;
-				double length = 0;
-				double lb = 0;
-				double la = 0;
-				GeomIterator git = map.new GeomIterator(Rules.feature.geom);
-				if (git.hasComp()) {
-					git.nextComp();
-					while (git.hasEdge()) {
-						git.nextEdge();
-						while (git.hasNode()) {
-							Snode node = git.next();
-							if (node == null)
-								continue;
-							prev = next;
-							next = context.getPoint(node);
-							if (prev != null)
-								length += Math.sqrt(Math.pow((next.getX() - prev.getX()), 2) + Math.pow((next.getY() - prev.getY()), 2));
-							if (length < offset) {
-								before = next;
-								lb = la = length;
-							} else if (after == null) {
-								if (length > (offset + width)) {
-									after = next;
-									la = length;
-									break;
-								} else {
-									between.add(next);
-								}
-							}
-						}
-						if (after != null)
-							break;
-					}
-				}
-				if (after != null) {
-					double angle = Math.atan2((after.getY() - before.getY()), (after.getX() - before.getX()));
-					double rotate = Math.abs(angle) < (Math.PI / 2) ? angle : angle + Math.PI;
-					Point2D mid = new Point2D.Double((before.getX() + after.getX()) / 2, (before.getY() + after.getY()) / 2);
-					Point2D centre = context.getPoint(Rules.feature.geom.centre);
-					AffineTransform pos = AffineTransform.getTranslateInstance(-dy * Math.sin(rotate), dy * Math.cos(rotate));
-					pos.rotate(rotate);
-					pos.translate((mid.getX() - centre.getX()), (mid.getY() - centre.getY()));
-					Symbol label = new Symbol();
-					label.add(new Instr(Form.BBOX, new Rectangle2D.Double((-width / 2), (-height), width, height)));
-					label.add(new Instr(Form.TEXT, new Caption(str, font, colour, new Delta(Handle.BC))));
-					Symbols.drawSymbol(g2, label, sScale, centre.getX(), centre.getY(), null, new Delta(Handle.BC, pos));
-				}
-			}
-		}
-	}
-	
-	public static void lightSector(Color col1, Color col2, double radius, double s1, double s2, Double dir, String str) {
-		if ((zoom >= 16) && (radius > 0.2)) {
-			radius /= (Math.pow(2, zoom-15));
-		}
-		double mid = (((s1 + s2)  / 2) + (s1 > s2 ? 180 : 0)) % 360;
-		g2.setStroke(new BasicStroke((float) (3.0 * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, new float[] {20 * (float)sScale, 20 * (float)sScale}, 0));
-		g2.setPaint(Color.black);
-		Point2D.Double centre = (Point2D.Double) context.getPoint(Rules.feature.geom.centre);
-		double radial = radius * context.mile(Rules.feature);
-		if (dir != null) {
-			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))));
-		} else {
-			if ((s1 != 0.0) || (s2 != 360.0)) {
-				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))));
-				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))));
-			}
-		}
-		double arcWidth =  10.0 * sScale;
-		g2.setStroke(new BasicStroke((float)arcWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1));
-		g2.setPaint(col1);
-		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));
-		if (col2 != null) {
-			g2.setPaint(col2);
-			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));
-		}
-		if ((str != null) && (!str.isEmpty())) {
-			Font font = new Font("Arial", Font.PLAIN, 40);
-			double arc = (s2 > s1) ? (s2 - s1) : (s2 - s1 + 360);
-			double awidth = (Math.toRadians(arc) * radial);
-			boolean hand = ((mid > 270) || (mid < 90));
-			double phi = Math.toRadians(mid);
-			radial += 30 * sScale;
-			AffineTransform at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
-			if ((font.getSize() * sScale * str.length()) < awidth) {
-				at.rotate(Math.toRadians(mid + (hand ? 0 : 180)));
-				labelText(str, font, Color.black, new Delta(Handle.CC, at));
-			} else if ((font.getSize() * sScale) < awidth) {
-				hand = (mid < 180);
-				at.rotate(Math.toRadians(mid + (hand ? -90 : 90)));
-				labelText(str, font, Color.black, hand ? new Delta(Handle.RC, at) : new Delta(Handle.LC, at));
-			}
-			if (dir != null) {
-				font = new Font("Arial", Font.PLAIN, 30);
-				str = dir + "°";
-				hand = (dir > 180);
-				phi = Math.toRadians(dir + (hand ? -0.5 : 0.5));
-				radial -= 70 * sScale;
-				at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
-				at.rotate(Math.toRadians(dir + (hand ? 90 : -90)));
-				labelText(str, font, Color.black, hand ? new Delta(Handle.BR, at) : new Delta(Handle.BL, at));
-			}
-		}
-	}
+    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 };
+
+    public enum LabelStyle { NONE, RRCT, RECT, ELPS, CIRC, VCLR, PCLR, HCLR }
+
+    static ChartContext context;
+    static S57map map;
+    static double sScale;
+    static Graphics2D g2;
+    static int zoom;
+
+    public static void reRender(Graphics2D g, Rectangle rect, int z, double factor, S57map m, ChartContext c) {
+        g2 = g;
+        zoom = z;
+        context = c;
+        map = m;
+        sScale = symbolScale[zoom] * factor;
+        if (map != null) {
+            if (context.clip()) {
+                Point2D tl = context.getPoint(map.new Snode(map.bounds.maxlat, map.bounds.minlon));
+                Point2D br = context.getPoint(map.new Snode(map.bounds.minlat, map.bounds.maxlon));
+                g2.clip(new Rectangle2D.Double(tl.getX(), tl.getY(), (br.getX() - tl.getX()), (br.getY() - tl.getY())));
+            }
+            g2.setBackground(context.background(map));
+            g2.clearRect(rect.x, rect.y, rect.width, rect.height);
+            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
+            g2.setStroke(new BasicStroke(0, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
+            Rules.rules();
+        }
+    }
+
+    public static void symbol(Symbol symbol) {
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, null);
+    }
+
+    public static void symbol(Symbol symbol, Scheme scheme) {
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, null);
+    }
+
+    public static void symbol(Symbol symbol, Delta delta) {
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), null, delta);
+    }
+
+    public static void symbol(Symbol symbol, Scheme scheme, Delta delta) {
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, symbol, sScale, point.getX(), point.getY(), scheme, delta);
+    }
+
+    public static void cluster(ArrayList<Symbol> symbols) {
+        Rectangle2D.Double bbox = null;
+        if (symbols.size() > 4) {
+            for (Instr instr : symbols.get(0)) {
+                if (instr.type == Form.BBOX) {
+                    bbox = (Rectangle2D.Double) instr.params;
+                    break;
+                }
+            }
+            if (bbox == null) return;
+        }
+        switch (symbols.size()) {
+        case 1:
+            symbol(symbols.get(0), new Delta(Handle.CC, new AffineTransform()));
+            break;
+        case 2:
+            symbol(symbols.get(0), new Delta(Handle.RC, new AffineTransform()));
+            symbol(symbols.get(1), new Delta(Handle.LC, new AffineTransform()));
+            break;
+        case 3:
+            symbol(symbols.get(0), new Delta(Handle.BC, new AffineTransform()));
+            symbol(symbols.get(1), new Delta(Handle.TR, new AffineTransform()));
+            symbol(symbols.get(2), new Delta(Handle.TL, new AffineTransform()));
+            break;
+        case 4:
+            symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
+            symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
+            symbol(symbols.get(2), new Delta(Handle.TR, new AffineTransform()));
+            symbol(symbols.get(3), new Delta(Handle.TL, new AffineTransform()));
+            break;
+        case 5:
+            symbol(symbols.get(0), new Delta(Handle.BR, new AffineTransform()));
+            symbol(symbols.get(1), new Delta(Handle.BL, new AffineTransform()));
+            symbol(symbols.get(2), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(3), new Delta(Handle.TC, new AffineTransform()));
+            symbol(symbols.get(4), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            break;
+        case 6:
+            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(1), new Delta(Handle.BC, new AffineTransform()));
+            symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            symbol(symbols.get(3), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(4), new Delta(Handle.TC, new AffineTransform()));
+            symbol(symbols.get(5), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            break;
+        case 7:
+            symbol(symbols.get(0), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
+            symbol(symbols.get(1), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(2), new Delta(Handle.CC, new AffineTransform()));
+            symbol(symbols.get(3), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            symbol(symbols.get(4), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
+            symbol(symbols.get(5), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
+            symbol(symbols.get(6), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
+            break;
+        case 8:
+            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
+            symbol(symbols.get(1), new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
+            symbol(symbols.get(2), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(3), new Delta(Handle.CC, new AffineTransform()));
+            symbol(symbols.get(4), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            symbol(symbols.get(5), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
+            symbol(symbols.get(6), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
+            symbol(symbols.get(7), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
+            break;
+        case 9:
+            symbol(symbols.get(0), new Delta(Handle.BR, AffineTransform.getTranslateInstance(-bbox.width/2, -bbox.height/2)));
+            symbol(symbols.get(1), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -bbox.height/2)));
+            symbol(symbols.get(2), new Delta(Handle.BL, AffineTransform.getTranslateInstance(bbox.width/2, -bbox.height/2)));
+            symbol(symbols.get(3), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-bbox.width/2, 0)));
+            symbol(symbols.get(4), new Delta(Handle.CC, new AffineTransform()));
+            symbol(symbols.get(5), new Delta(Handle.LC, AffineTransform.getTranslateInstance(bbox.width/2, 0)));
+            symbol(symbols.get(6), new Delta(Handle.TR, AffineTransform.getTranslateInstance(-bbox.width/2, bbox.height/2)));
+            symbol(symbols.get(7), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, bbox.height/2)));
+            symbol(symbols.get(8), new Delta(Handle.TL, AffineTransform.getTranslateInstance(bbox.width/2, bbox.height/2)));
+            break;
+        }
+    }
+
+    private static Rectangle2D.Double symbolSize(Symbol symbol) {
+        Symbol ssymb = symbol;
+        while (ssymb != null) {
+            for (Instr item : symbol) {
+                if (item.type == Form.BBOX) {
+                    return (Rectangle2D.Double) item.params;
+                }
+                if (item.type == Form.SYMB) {
+                    ssymb = ((SubSymbol) item.params).instr;
+                    break;
+                }
+            }
+            if (ssymb == symbol)
+                break;
+        }
+        return null;
+    }
+
+    public static void lineSymbols(Symbol prisymb, double space, Symbol secsymb, Symbol tersymb, int ratio, Color col) {
+        if ((Rules.feature.geom.prim == Pflag.NOSP) || (Rules.feature.geom.prim == Pflag.POINT))
+            return;
+        Rectangle2D.Double prect = symbolSize(prisymb);
+        Rectangle2D.Double srect = symbolSize(secsymb);
+        Rectangle2D.Double trect = symbolSize(tersymb);
+        if (srect == null)
+            ratio = 0;
+        if (prect != null) {
+            double psize = Math.abs(prect.getY()) * sScale;
+            double ssize = (srect != null) ? Math.abs(srect.getY()) * sScale : 0;
+            double tsize = (trect != null) ? Math.abs(srect.getY()) * sScale : 0;
+            Point2D prev = new Point2D.Double();
+            Point2D next = new Point2D.Double();
+            Point2D curr = new Point2D.Double();
+            Point2D succ = new Point2D.Double();
+            boolean gap = true;
+            boolean piv = false;
+            double len = 0;
+            double angle = 0;
+            int stcount = ratio;
+            boolean stflag = false;
+            Symbol symbol = prisymb;
+            GeomIterator git = map.new GeomIterator(Rules.feature.geom);
+            while (git.hasComp()) {
+                git.nextComp();
+                boolean first = true;
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        if (node == null) continue;
+                        prev = next;
+                        next = context.getPoint(node);
+                        angle = Math.atan2(next.getY() - prev.getY(), next.getX() - prev.getX());
+                        piv = true;
+                        if (first) {
+                            curr = succ = next;
+                            gap = (space > 0);
+                            stcount = ratio - 1;
+                            symbol = prisymb;
+                            len = gap ? psize * space * 0.5 : psize;
+                            first = false;
+                        } else {
+                            while (curr.distance(next) >= len) {
+                                if (piv) {
+                                    double rem = len;
+                                    double s = prev.distance(next);
+                                    double p = curr.distance(prev);
+                                    if ((s > 0) && (p > 0)) {
+                                        double n = curr.distance(next);
+                                        double theta = Math.acos((s * s + p * p - n * n) / 2 / s / p);
+                                        double phi = Math.asin(p / len * Math.sin(theta));
+                                        rem = len * Math.sin(Math.PI - theta - phi) / Math.sin(theta);
+                                    }
+                                    succ = new Point2D.Double(prev.getX() + (rem * Math.cos(angle)), prev.getY() + (rem * Math.sin(angle)));
+                                    piv = false;
+                                } else {
+                                    succ = new Point2D.Double(curr.getX() + (len * Math.cos(angle)), curr.getY() + (len * Math.sin(angle)));
+                                }
+                                if (!gap) {
+                                    Symbols.drawSymbol(g2, symbol, sScale, curr.getX(), curr.getY(), new Scheme(col),
+                                            new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.atan2((succ.getY() - curr.getY()), (succ.getX() - curr.getX())) + Math.toRadians(90))));
+                                }
+                                if (space > 0)
+                                    gap = !gap;
+                                curr = succ;
+                                len = gap ? (psize * space) : (--stcount == 0) ? (stflag ? tsize : ssize) : psize;
+                                if (stcount == 0) {
+                                    symbol = stflag ? tersymb : secsymb;
+                                    if (trect != null)
+                                        stflag = !stflag;
+                                    stcount = ratio;
+                                } else {
+                                    symbol = prisymb;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void lineVector(LineStyle style) {
+        Path2D.Double p = new Path2D.Double();
+        p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        Point2D point;
+        GeomIterator git = map.new GeomIterator(Rules.feature.geom);
+        while (git.hasComp()) {
+            git.nextComp();
+            boolean first = true;
+            while (git.hasEdge()) {
+                git.nextEdge();
+                point = context.getPoint(git.next());
+                if (first) {
+                    p.moveTo(point.getX(), point.getY());
+                    first = false;
+                } else {
+                    p.lineTo(point.getX(), point.getY());
+                }
+                while (git.hasNode()) {
+                    Snode node = git.next();
+                    if (node == null) continue;
+                    point = context.getPoint(node);
+                    p.lineTo(point.getX(), point.getY());
+                }
+            }
+        }
+        if ((style.fill != null) && (Rules.feature.geom.prim == Pflag.AREA)) {
+            g2.setPaint(style.fill);
+            g2.fill(p);
+        }
+        if (style.line != null) {
+            if (style.dash != null) {
+                float[] dash = new float[style.dash.length];
+                System.arraycopy(style.dash, 0, dash, 0, style.dash.length);
+                for (int i = 0; i < style.dash.length; i++) {
+                    dash[i] *= (float) sScale;
+                }
+                g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, dash, 0));
+            } else {
+                g2.setStroke(new BasicStroke((float) (style.width * sScale), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+            }
+            g2.setPaint(style.line);
+            g2.draw(p);
+        }
+    }
+
+    public static void lineCircle(LineStyle style, double radius, UniHLU units) {
+        switch (units) {
+        case HLU_FEET:
+            radius /= 6076;
+            break;
+        case HLU_KMTR:
+            radius /= 1.852;
+            break;
+        case HLU_HMTR:
+            radius /= 18.52;
+            break;
+        case HLU_SMIL:
+            radius /= 1.15078;
+            break;
+        case HLU_NMIL:
+            break;
+        default:
+            radius /= 1852;
+            break;
+        }
+        radius *= context.mile(Rules.feature);
+        Symbol circle = new Symbol();
+        if (style.fill != null) {
+            circle.add(new Instr(Form.FILL, style.fill));
+            circle.add(new Instr(Form.RSHP, new Ellipse2D.Double(-radius, -radius, radius*2, radius*2)));
+        }
+        circle.add(new Instr(Form.FILL, style.line));
+        circle.add(new Instr(Form.STRK, new BasicStroke(style.width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, style.dash, 0)));
+        circle.add(new Instr(Form.ELPS, new Ellipse2D.Double(-radius, -radius, radius*2, radius*2)));
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, circle, 1, point.getX(), point.getY(), null, null);
+    }
+
+    public static void fillPattern(BufferedImage image) {
+        Path2D.Double p = new Path2D.Double();
+        p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        Point2D point;
+        switch (Rules.feature.geom.prim) {
+        case POINT:
+            point = context.getPoint(Rules.feature.geom.centre);
+            g2.drawImage(image, new AffineTransformOp(AffineTransform.getScaleInstance(sScale, sScale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR),
+                    (int) (point.getX() - (50 * sScale)), (int) (point.getY() - (50 * sScale)));
+            break;
+        case AREA:
+            GeomIterator git = map.new GeomIterator(Rules.feature.geom);
+            while (git.hasComp()) {
+                git.nextComp();
+                boolean newComp = true;
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    point = context.getPoint(git.next());
+                    if (newComp) {
+                        p.moveTo(point.getX(), point.getY());
+                        newComp = false;
+                    } else {
+                        p.lineTo(point.getX(), point.getY());
+                    }
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        if (node == null) continue;
+                        point = context.getPoint(node);
+                        p.lineTo(point.getX(), point.getY());
+                    }
+                }
+            }
+            g2.setPaint(new TexturePaint(image, new Rectangle(0, 0, 1 + (int) (300 * sScale), 1 + (int) (300 * sScale))));
+            g2.fill(p);
+            break;
+        default:
+            break;
+        }
+    }
+
+    public static void labelText(String str, Font font, Color tc) {
+        labelText(str, font, tc, LabelStyle.NONE, null, null, null);
+    }
+
+    public static void labelText(String str, Font font, Color tc, Delta delta) {
+        labelText(str, font, tc, LabelStyle.NONE, null, null, delta);
+    }
+
+    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg) {
+        labelText(str, font, tc, style, fg, null, null);
+    }
+
+    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg) {
+        labelText(str, font, tc, style, fg, bg, null);
+    }
+
+    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Delta delta) {
+        labelText(str, font, tc, style, fg, null, delta);
+    }
+
+    public static void labelText(String str, Font font, Color tc, LabelStyle style, Color fg, Color bg, Delta delta) {
+        if (delta == null) delta = new Delta(Handle.CC);
+        if (bg == null) bg = new Color(0x00000000, true);
+        if ((str == null) || (str.isEmpty())) str = " ";
+        FontRenderContext frc = g2.getFontRenderContext();
+        GlyphVector gv = font.deriveFont((float) (font.getSize())).createGlyphVector(frc, str.equals(" ") ? "M" : str);
+        Rectangle2D bounds = gv.getVisualBounds();
+        double width = bounds.getWidth();
+        double height = bounds.getHeight();
+        Symbol label = new Symbol();
+        double lx, ly, tx, ty;
+        switch (style) {
+        case RRCT:
+            width += height * 1.0;
+            height *= 1.5;
+            if (width < height) width = height;
+            lx = -width / 2;
+            ly = -height / 2;
+            tx = lx + (height * 0.34);
+            ty = ly + (height * 0.17);
+            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
+            label.add(new Instr(Form.FILL, bg));
+            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
+            label.add(new Instr(Form.FILL, fg));
+            label.add(new Instr(Form.STRK, new BasicStroke(1 + (int) (height/10), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+            label.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
+            break;
+        case VCLR:
+            width += height * 1.0;
+            height *= 2.0;
+            if (width < height) width = height;
+            lx = -width / 2;
+            ly = -height / 2;
+            tx = lx + (height * 0.27);
+            ty = ly + (height * 0.25);
+            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
+            label.add(new Instr(Form.FILL, bg));
+            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
+            label.add(new Instr(Form.FILL, fg));
+            int sw = 1 + (int) (height/10);
+            double po = sw / 2;
+            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+            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));
+            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));
+            label.add(new Instr(Form.PLIN, p));
+            break;
+        case PCLR:
+            width += height * 1.0;
+            height *= 2.0;
+            if (width < height) width = height;
+            lx = -width / 2;
+            ly = -height / 2;
+            tx = lx + (height * 0.27);
+            ty = ly + (height * 0.25);
+            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
+            label.add(new Instr(Form.FILL, bg));
+            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
+            label.add(new Instr(Form.FILL, fg));
+            sw = 1 + (int) (height/10);
+            po = sw / 2;
+            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+            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));
+            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));
+            label.add(new Instr(Form.PLIN, p));
+            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)))));
+            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)))));
+            break;
+        case HCLR:
+            width += height * 1.5;
+            height *= 1.5;
+            if (width < height) width = height;
+            lx = -width / 2;
+            ly = -height / 2;
+            tx = lx + (height * 0.5);
+            ty = ly + (height * 0.17);
+            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
+            label.add(new Instr(Form.FILL, bg));
+            label.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(lx, ly, width, height, height, height)));
+            label.add(new Instr(Form.FILL, fg));
+            sw = 1 + (int) (height/10);
+            double vo = height / 4;
+            label.add(new Instr(Form.STRK, new BasicStroke(sw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+            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);
+            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);
+            label.add(new Instr(Form.PLIN, p));
+            break;
+        default:
+            lx = -width / 2;
+            ly = -height / 2;
+            tx = lx;
+            ty = ly;
+            label.add(new Instr(Form.BBOX, new Rectangle2D.Double(lx, ly, width, height)));
+            break;
+        }
+        label.add(new Instr(Form.TEXT, new Caption(str, font, tc, new Delta(Handle.TL, AffineTransform.getTranslateInstance(tx, ty)))));
+        Point2D point = context.getPoint(Rules.feature.geom.centre);
+        Symbols.drawSymbol(g2, label, sScale, point.getX(), point.getY(), null, delta);
+    }
+
+    public static void lineText(String str, Font font, Color colour, double dy) {
+        if (!str.isEmpty()) {
+            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g2.setPaint(colour);
+            FontRenderContext frc = g2.getFontRenderContext();
+            GlyphVector gv = font.deriveFont(font.getSize2D() * (float) sScale).createGlyphVector(frc, str);
+            double width = gv.getVisualBounds().getWidth();
+            double height = gv.getVisualBounds().getHeight();
+            double offset = (Rules.feature.geom.length * context.mile(Rules.feature) - width) / 2;
+            if (offset > 0) {
+                Point2D before = null;
+                Point2D after = null;
+                ArrayList<Point2D> between = new ArrayList<>();
+                Point2D prev = null;
+                Point2D next = null;
+                double length = 0;
+                double lb = 0;
+                double la = 0;
+                GeomIterator git = map.new GeomIterator(Rules.feature.geom);
+                if (git.hasComp()) {
+                    git.nextComp();
+                    while (git.hasEdge()) {
+                        git.nextEdge();
+                        while (git.hasNode()) {
+                            Snode node = git.next();
+                            if (node == null)
+                                continue;
+                            prev = next;
+                            next = context.getPoint(node);
+                            if (prev != null)
+                                length += Math.sqrt(Math.pow((next.getX() - prev.getX()), 2) + Math.pow((next.getY() - prev.getY()), 2));
+                            if (length < offset) {
+                                before = next;
+                                lb = la = length;
+                            } else if (after == null) {
+                                if (length > (offset + width)) {
+                                    after = next;
+                                    la = length;
+                                    break;
+                                } else {
+                                    between.add(next);
+                                }
+                            }
+                        }
+                        if (after != null)
+                            break;
+                    }
+                }
+                if (after != null) {
+                    double angle = Math.atan2((after.getY() - before.getY()), (after.getX() - before.getX()));
+                    double rotate = Math.abs(angle) < (Math.PI / 2) ? angle : angle + Math.PI;
+                    Point2D mid = new Point2D.Double((before.getX() + after.getX()) / 2, (before.getY() + after.getY()) / 2);
+                    Point2D centre = context.getPoint(Rules.feature.geom.centre);
+                    AffineTransform pos = AffineTransform.getTranslateInstance(-dy * Math.sin(rotate), dy * Math.cos(rotate));
+                    pos.rotate(rotate);
+                    pos.translate((mid.getX() - centre.getX()), (mid.getY() - centre.getY()));
+                    Symbol label = new Symbol();
+                    label.add(new Instr(Form.BBOX, new Rectangle2D.Double((-width / 2), (-height), width, height)));
+                    label.add(new Instr(Form.TEXT, new Caption(str, font, colour, new Delta(Handle.BC))));
+                    Symbols.drawSymbol(g2, label, sScale, centre.getX(), centre.getY(), null, new Delta(Handle.BC, pos));
+                }
+            }
+        }
+    }
+
+    public static void lightSector(Color col1, Color col2, double radius, double s1, double s2, Double dir, String str) {
+        if ((zoom >= 16) && (radius > 0.2)) {
+            radius /= (Math.pow(2, zoom-15));
+        }
+        double mid = (((s1 + s2) / 2) + (s1 > s2 ? 180 : 0)) % 360;
+        g2.setStroke(new BasicStroke((float) (3.0 * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1, new float[] {20 * (float) sScale, 20 * (float) sScale}, 0));
+        g2.setPaint(Color.black);
+        Point2D.Double centre = (Point2D.Double) context.getPoint(Rules.feature.geom.centre);
+        double radial = radius * context.mile(Rules.feature);
+        if (dir != null) {
+            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))));
+        } else {
+            if ((s1 != 0.0) || (s2 != 360.0)) {
+                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))));
+                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))));
+            }
+        }
+        double arcWidth = 10.0 * sScale;
+        g2.setStroke(new BasicStroke((float) arcWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1));
+        g2.setPaint(col1);
+        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));
+        if (col2 != null) {
+            g2.setPaint(col2);
+            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));
+        }
+        if ((str != null) && (!str.isEmpty())) {
+            Font font = new Font("Arial", Font.PLAIN, 40);
+            double arc = (s2 > s1) ? (s2 - s1) : (s2 - s1 + 360);
+            double awidth = (Math.toRadians(arc) * radial);
+            boolean hand = ((mid > 270) || (mid < 90));
+            double phi = Math.toRadians(mid);
+            radial += 30 * sScale;
+            AffineTransform at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
+            if ((font.getSize() * sScale * str.length()) < awidth) {
+                at.rotate(Math.toRadians(mid + (hand ? 0 : 180)));
+                labelText(str, font, Color.black, new Delta(Handle.CC, at));
+            } else if ((font.getSize() * sScale) < awidth) {
+                hand = (mid < 180);
+                at.rotate(Math.toRadians(mid + (hand ? -90 : 90)));
+                labelText(str, font, Color.black, hand ? new Delta(Handle.RC, at) : new Delta(Handle.LC, at));
+            }
+            if (dir != null) {
+                font = new Font("Arial", Font.PLAIN, 30);
+                str = dir + "°";
+                hand = (dir > 180);
+                phi = Math.toRadians(dir + (hand ? -0.5 : 0.5));
+                radial -= 70 * sScale;
+                at = AffineTransform.getTranslateInstance(-radial * Math.sin(phi) / sScale, radial * Math.cos(phi) / sScale);
+                at.rotate(Math.toRadians(dir + (hand ? 90 : -90)));
+                labelText(str, font, Color.black, hand ? new Delta(Handle.BR, at) : new Delta(Handle.BL, at));
+            }
+        }
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/render/Rules.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32394)
@@ -18,1394 +18,1451 @@
 import java.util.HashMap;
 
+import render.ChartContext.RuleSet;
+import render.Renderer.LabelStyle;
+import s57.S57att.Att;
+import s57.S57map.AttMap;
+import s57.S57map.Feature;
+import s57.S57map.ObjTab;
+import s57.S57map.Pflag;
+import s57.S57map.Rflag;
+import s57.S57obj.Obj;
 import s57.S57val;
-import s57.S57val.*;
-import s57.S57att.*;
-import s57.S57obj.*;
-import s57.S57map.*;
-import render.ChartContext.RuleSet;
-import render.Renderer.*;
-import symbols.*;
-import symbols.Symbols.*;
+import s57.S57val.AddMRK;
+import s57.S57val.AttVal;
+import s57.S57val.BcnSHP;
+import s57.S57val.BnkWTW;
+import s57.S57val.BoySHP;
+import s57.S57val.CatACH;
+import s57.S57val.CatCBL;
+import s57.S57val.CatCRN;
+import s57.S57val.CatDIS;
+import s57.S57val.CatHAF;
+import s57.S57val.CatLAM;
+import s57.S57val.CatLMK;
+import s57.S57val.CatMOR;
+import s57.S57val.CatNMK;
+import s57.S57val.CatOBS;
+import s57.S57val.CatOFP;
+import s57.S57val.CatPIL;
+import s57.S57val.CatPRA;
+import s57.S57val.CatREA;
+import s57.S57val.CatROD;
+import s57.S57val.CatSCF;
+import s57.S57val.CatSEA;
+import s57.S57val.CatSIL;
+import s57.S57val.CatSIT;
+import s57.S57val.CatSIW;
+import s57.S57val.CatSLC;
+import s57.S57val.CatWED;
+import s57.S57val.CatWRK;
+import s57.S57val.ColCOL;
+import s57.S57val.ColPAT;
+import s57.S57val.FncFNC;
+import s57.S57val.MarSYS;
+import s57.S57val.StsSTS;
+import s57.S57val.TopSHP;
+import s57.S57val.TrfTRF;
+import s57.S57val.UniHLU;
+import s57.S57val.WatLEV;
+import symbols.Areas;
+import symbols.Beacons;
+import symbols.Buoys;
+import symbols.Facilities;
+import symbols.Harbours;
+import symbols.Landmarks;
+import symbols.Notices;
+import symbols.Symbols;
+import symbols.Symbols.Delta;
+import symbols.Symbols.Handle;
+import symbols.Symbols.LineStyle;
+import symbols.Symbols.Patt;
+import symbols.Symbols.Scheme;
+import symbols.Symbols.Symbol;
+import symbols.Topmarks;
 
 public class Rules {
-	
-	static final DecimalFormat df = new DecimalFormat("#.#");
-
-	static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<>(ColCOL.class);
-	static {
-		bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
-		bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
-		bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
-		bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
-		bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
-		bodyColours.put(ColCOL.COL_BLU, Color.blue);
-		bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
-		bodyColours.put(ColCOL.COL_GRY, Color.gray);
-		bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
-		bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
-		bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
-		bodyColours.put(ColCOL.COL_ORG, Color.orange);
-		bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
-		bodyColours.put(ColCOL.COL_PNK, Color.pink);
-	}
-
-	static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<>(ColPAT.class);
-	static {
-		pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
-		pattMap.put(ColPAT.PAT_HORI, Patt.H);
-		pattMap.put(ColPAT.PAT_VERT, Patt.V);
-		pattMap.put(ColPAT.PAT_DIAG, Patt.D);
-		pattMap.put(ColPAT.PAT_BRDR, Patt.B);
-		pattMap.put(ColPAT.PAT_SQUR, Patt.S);
-		pattMap.put(ColPAT.PAT_CROS, Patt.C);
-		pattMap.put(ColPAT.PAT_SALT, Patt.X);
-		pattMap.put(ColPAT.PAT_STRP, Patt.H);
-	}
-	
-	static String getName() {
-		AttVal<?> name = feature.atts.get(Att.OBJNAM);
-		if (name == null) {
-			AttMap atts = feature.objs.get(feature.type).get(0);
-			if (atts != null) {
-				name = atts.get(Att.OBJNAM);
-			}
-		}
-		return (name != null) ? (String)name.val: null;
-	}
-
-	public static void addName(int z, Font font) {
-		addName(z, font, Color.black, new Delta(Handle.CC, new AffineTransform()));
-	}
-	public static void addName(int z, Font font, Color colour) {
-		addName(z, font, colour, new Delta(Handle.CC, new AffineTransform()));
-	}
-	public static void addName(int z, Font font, Delta delta) {
-		addName(z, font, Color.black, delta);
-	}
-	public static void addName(int z, Font font, Color colour, Delta delta) {
-		if (Renderer.zoom >= z) {
-			String name = getName();
-			if (name != null) {
-				Renderer.labelText(name, font,  colour, delta);
-			}
-		}
-	}
-
-	static AttMap getAtts(Obj obj, int idx) {
-		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
-		if (objs == null)
-			return null;
-		else
-			return objs.get(idx);
-	}
-
-	public static Object getAttVal(Obj obj, Att att) {
-		AttMap atts;
-		HashMap<Integer, AttMap> objs;
-		AttVal<?> item;
-		if ((objs = feature.objs.get(obj)) != null)
-			atts = objs.get(0);
-		else
-			return null;
-		if ((item = atts.get(att)) == null)
-			return null;
-		else
-			return item.val;
-	}
-	
-	public static String getAttStr(Obj obj, Att att) {
-		String str = (String)getAttVal(obj, att);
-		if (str != null) {
-			return str;
-		}
-		return ""; 
-	}
-
-	@SuppressWarnings("unchecked")
-	public static Enum<?> getAttEnum(Obj obj, Att att) {
-		ArrayList<?> list = (ArrayList<?>)getAttVal(obj, att);
-		if (list != null) {
-			return ((ArrayList<Enum<?>>)list).get(0);
-		}
-		return S57val.unknAtt(att);
-	}
-	
-	@SuppressWarnings("unchecked")
-	public static ArrayList<?> getAttList(Obj obj, Att att) {
-		ArrayList<Enum<?>> list = (ArrayList<Enum<?>>)getAttVal(obj, att);
-		if (list != null) {
-			return list;
-		}
-		list = new ArrayList<>();
-		list.add(S57val.unknAtt(att));
-		return list; 
-	}
-	
-	@SuppressWarnings("unchecked")
-	static Scheme getScheme(Obj obj) {
-		ArrayList<Color> colours = new ArrayList<>();
-		for (ColCOL col : (ArrayList<ColCOL>) getAttList(obj, Att.COLOUR)) {
-			colours.add(bodyColours.get(col));
-		}
-		ArrayList<Patt> patterns = new ArrayList<>();
-		for (ColPAT pat : (ArrayList<ColPAT>) getAttList(obj, Att.COLPAT)) {
-			patterns.add(pattMap.get(pat));
-		}
-		return new Scheme(patterns, colours);
-	}
-
-	static boolean hasAttribute(Obj obj, Att att) {
-		AttMap atts;
-		if ((atts = getAtts(obj, 0)) != null) {
-			AttVal<?> item = atts.get(att);
-			return item != null;
-		}
-		return false;
-	}
-	
-	static boolean testAttribute(Obj obj, Att att, Object val) {
-		AttMap atts;
-		if ((atts = getAtts(obj, 0)) != null) {
-			AttVal<?> item = atts.get(att);
-			if (item != null) {
-				switch (item.conv) {
-				case S:
-				case A:
-					return ((String)item.val).equals(val);
-				case E:
-				case L:
-					return ((ArrayList<?>)item.val).contains(val);
-				case F:
-				case I:
-					return item.val == val;
-				}
-			}
-		}
-		return false;
-	}
-	
-	static boolean hasObject(Obj obj) {
-		return (feature.objs.containsKey(obj));
-	}
-	
-	public static Feature feature;
-	static ArrayList<Feature> objects;
-	
-	static boolean testObject(Obj obj) {
-		return ((objects = Renderer.map.features.get(obj)) != null);
-	}
-	
-	static boolean testFeature(Feature f) {
-		return ((feature = f).reln == Rflag.MASTER);
-	}
-	
-	public static void rules () {
-		if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
-			if (testObject(Obj.LNDARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.BUAARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.HRBBSN)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.LOKBSN)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.LKBSPT)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.LAKARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.RIVERS)) for (Feature f : objects) if (testFeature(f)) waterways();
-			if (testObject(Obj.CANALS)) for (Feature f : objects) if (testFeature(f)) waterways();
-			if (testObject(Obj.DEPARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.COALNE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.ROADWY)) for (Feature f : objects) if (testFeature(f)) highways();
-			if (testObject(Obj.RAILWY)) for (Feature f : objects) if (testFeature(f)) highways();
-		}
-		if (Renderer.context.ruleset() == RuleSet.ALL) {
-			if (testObject(Obj.SOUNDG)) for (Feature f : objects) if (testFeature(f)) depths();
-			if (testObject(Obj.DEPCNT)) for (Feature f : objects) if (testFeature(f)) depths();
-		}
-		if (testObject(Obj.SLCONS)) for (Feature f : objects) if (testFeature(f)) shoreline();
-		if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
-			if (testObject(Obj.PIPSOL)) for (Feature f : objects) if (testFeature(f)) pipelines();
-			if (testObject(Obj.CBLSUB)) for (Feature f : objects) if (testFeature(f)) cables();
-			if (testObject(Obj.PIPOHD)) for (Feature f : objects) if (testFeature(f)) pipelines();
-			if (testObject(Obj.CBLOHD)) for (Feature f : objects) if (testFeature(f)) cables();
-			if (testObject(Obj.TSEZNE)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.TSSCRS)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.TSSRON)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.TSELNE)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.TSSLPT)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.TSSBND)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.ISTZNE)) for (Feature f : objects) if (testFeature(f)) separation();
-			if (testObject(Obj.SNDWAV)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.WEDKLP)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.OSPARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.FAIRWY)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.DRGARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.RESARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.PRCARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.SPLARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.SEAARE)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.OBSTRN)) for (Feature f : objects) if (testFeature(f)) obstructions();
-			if (testObject(Obj.UWTROC)) for (Feature f : objects) if (testFeature(f)) obstructions();
-			if (testObject(Obj.MARCUL)) for (Feature f : objects) if (testFeature(f)) areas();
-			if (testObject(Obj.RECTRC)) for (Feature f : objects) if (testFeature(f)) transits();
-			if (testObject(Obj.NAVLNE)) for (Feature f : objects) if (testFeature(f)) transits();
-			if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) harbours();
-			if (testObject(Obj.ACHARE)) for (Feature f : objects) if (testFeature(f)) harbours();
-			if (testObject(Obj.ACHBRT)) for (Feature f : objects) if (testFeature(f)) harbours();
-			if (testObject(Obj.BERTHS)) for (Feature f : objects) if (testFeature(f)) harbours();
-			if (testObject(Obj.DISMAR)) for (Feature f : objects) if (testFeature(f)) distances();
-			if (testObject(Obj.HULKES)) for (Feature f : objects) if (testFeature(f)) ports();
-			if (testObject(Obj.CRANES)) for (Feature f : objects) if (testFeature(f)) ports();
-			if (testObject(Obj.LNDMRK)) for (Feature f : objects) if (testFeature(f)) landmarks();
-			if (testObject(Obj.SILTNK)) for (Feature f : objects) if (testFeature(f)) landmarks();
-			if (testObject(Obj.BUISGL)) for (Feature f : objects) if (testFeature(f)) harbours();
-			if (testObject(Obj.MORFAC)) for (Feature f : objects) if (testFeature(f)) moorings();
-			if (testObject(Obj.NOTMRK)) for (Feature f : objects) if (testFeature(f)) notices();
-			if (testObject(Obj.SMCFAC)) for (Feature f : objects) if (testFeature(f)) marinas();
-			if (testObject(Obj.BRIDGE)) for (Feature f : objects) if (testFeature(f)) bridges();
-			if (testObject(Obj.PILPNT)) for (Feature f : objects) if (testFeature(f)) points();
-			if (testObject(Obj.TOPMAR)) for (Feature f : objects) if (testFeature(f)) points();
-			if (testObject(Obj.DAYMAR)) for (Feature f : objects) if (testFeature(f)) points();
-			if (testObject(Obj.FOGSIG)) for (Feature f : objects) if (testFeature(f)) points();
-			if (testObject(Obj.RDOCAL)) for (Feature f : objects) if (testFeature(f)) callpoint();
-			if (testObject(Obj.LITMIN)) for (Feature f : objects) if (testFeature(f)) lights();
-			if (testObject(Obj.LITMAJ)) for (Feature f : objects) if (testFeature(f)) lights();
-			if (testObject(Obj.LIGHTS)) for (Feature f : objects) if (testFeature(f)) lights();
-			if (testObject(Obj.SISTAT)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.SISTAW)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.CGUSTA)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.RDOSTA)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.RADRFL)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.RADSTA)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.RTPBCN)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.RSCSTA)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.PILBOP)) for (Feature f : objects) if (testFeature(f)) stations();
-			if (testObject(Obj.WTWGAG)) for (Feature f : objects) if (testFeature(f)) gauges();
-			if (testObject(Obj.OFSPLF)) for (Feature f : objects) if (testFeature(f)) platforms();
-			if (testObject(Obj.WRECKS)) for (Feature f : objects) if (testFeature(f)) wrecks();
-			if (testObject(Obj.LITVES)) for (Feature f : objects) if (testFeature(f)) floats();
-			if (testObject(Obj.LITFLT)) for (Feature f : objects) if (testFeature(f)) floats();
-			if (testObject(Obj.BOYINB)) for (Feature f : objects) if (testFeature(f)) floats();
-			if (testObject(Obj.BOYLAT)) for (Feature f : objects) if (testFeature(f)) buoys();
-			if (testObject(Obj.BOYCAR)) for (Feature f : objects) if (testFeature(f)) buoys();
-			if (testObject(Obj.BOYISD)) for (Feature f : objects) if (testFeature(f)) buoys();
-			if (testObject(Obj.BOYSAW)) for (Feature f : objects) if (testFeature(f)) buoys();
-			if (testObject(Obj.BOYSPP)) for (Feature f : objects) if (testFeature(f)) buoys();
-			if (testObject(Obj.BCNLAT)) for (Feature f : objects) if (testFeature(f)) beacons();
-			if (testObject(Obj.BCNCAR)) for (Feature f : objects) if (testFeature(f)) beacons();
-			if (testObject(Obj.BCNISD)) for (Feature f : objects) if (testFeature(f)) beacons();
-			if (testObject(Obj.BCNSAW)) for (Feature f : objects) if (testFeature(f)) beacons();
-			if (testObject(Obj.BCNSPP)) for (Feature f : objects) if (testFeature(f)) beacons();
-		}
-	}
-	
-	private static void areas() {
-		String name = getName();
-		switch (feature.type) {
-		case BUAARE:
-			Renderer.lineVector(new LineStyle(new Color(0x20000000, true)));
-			break;
-		case COALNE:
-			if (Renderer.zoom >= 12)
-				Renderer.lineVector(new LineStyle(Color.black, 10));
-			break;
-		case DEPARE:
-			Double depmax = 0.0;
-			if (((depmax = (Double) getAttVal(Obj.DEPARE, Att.DRVAL2)) != null) && (depmax <= 0.0)) {
-				Renderer.lineVector(new LineStyle(Symbols.Gdries));
-			}
-			break;
-		case LAKARE:
-			if ((Renderer.zoom >= 12) || (feature.geom.area > 10.0))
-				Renderer.lineVector(new LineStyle(Symbols.Bwater));
-			break;
-		case DRGARE:
-			if (Renderer.zoom < 16)
-				Renderer.lineVector(new LineStyle(Color.black, 8, new float[] { 25, 25 }, new Color(0x40ffffff, true)));
-			else
-				Renderer.lineVector(new LineStyle(Color.black, 8, new float[] { 25, 25 }));
-			addName(12, new Font("Arial", Font.PLAIN, 100), new Delta(Handle.CC, new AffineTransform()));
-			break;
-		case FAIRWY:
-			if (feature.geom.area > 2.0) {
-				if (Renderer.zoom < 16)
-					Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] { 50, 50 }, new Color(0x40ffffff, true)));
-				else
-					Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] { 50, 50 }));
-			} else {
-				if (Renderer.zoom >= 14)
-					Renderer.lineVector(new LineStyle(new Color(0x40ffffff, true)));
-			}
-			break;
-		case LKBSPT:
-		case LOKBSN:
-		case HRBBSN:
-			if (Renderer.zoom >= 12) {
-				Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
-			} else {
-				Renderer.lineVector(new LineStyle(Symbols.Bwater));
-			}
-			break;
-		case HRBFAC:
-			if (feature.objs.get(Obj.HRBBSN) != null) {
-				if (Renderer.zoom >= 12) {
-					Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
-				} else {
-					Renderer.lineVector(new LineStyle(Symbols.Bwater));
-				}
-			}
-			break;
-		case LNDARE:
-			Renderer.lineVector(new LineStyle(Symbols.Yland));
-			break;
-		case MARCUL:
-			if (Renderer.zoom >= 12) {
-				if (Renderer.zoom >= 14) {
-					Renderer.symbol(Areas.MarineFarm);
-				}
-				if ((feature.geom.area > 0.2) || ((feature.geom.area > 0.05) && (Renderer.zoom >= 14)) || ((feature.geom.area > 0.005) && (Renderer.zoom >= 16))) {
-					Renderer.lineVector(new LineStyle(Color.black, 4, new float[] { 10, 10 }));
-				}
-			}
-			break;
-		case OSPARE:
-			if (testAttribute(feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
-				Renderer.symbol(Areas.WindFarm);
-				Renderer.lineVector(new LineStyle(Color.black, 20, new float[] { 40, 40 }));
-				addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
-			}
-			break;
-		case RESARE:
-		case MIPARE:
-			if (Renderer.zoom >= 12) {
-				Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mline);
-				if (testAttribute(feature.type, Att.CATREA, CatREA.REA_NWAK)) {
-					Renderer.symbol(Areas.NoWake);
-				}
-			}
-			break;
-		case PRCARE:
-			if (Renderer.zoom >= 12) {
-				Renderer.lineVector(new LineStyle(Symbols.Mline, 10, new float[] { 40, 40 }));
-			}
-			break;
-		case SEAARE:
-			switch ((CatSEA) getAttEnum(feature.type, Att.CATSEA)) {
-			case SEA_RECH:
-				if ((Renderer.zoom >= 10) && (name != null))
-					if (feature.geom.prim == Pflag.LINE) {
-						Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
-					} else {
-						Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
-					}
-				break;
-			case SEA_BAY:
-				if ((Renderer.zoom >= 12) && (name != null))
-					if (feature.geom.prim == Pflag.LINE) {
-						Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
-					} else {
-						Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
-					}
-				break;
-			case SEA_SHOL:
-				if (Renderer.zoom >= 14) {
-					if (feature.geom.prim == Pflag.AREA) {
-						Renderer.lineVector(new LineStyle(new Color(0xc480ff), 4, new float[] { 25, 25 }));
-						if (name != null) {
-							Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
-							Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
-						}
-					} else if (feature.geom.prim == Pflag.LINE) {
-						if (name != null) {
-							Renderer.lineText(name, new Font("Arial", Font.ITALIC, 75), Color.black, -40);
-							Renderer.lineText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, 0);
-						}
-					} else {
-						if (name != null) {
-							Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
-							Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
-						}
-					}
-				}
-				break;
-			case SEA_GAT:
-			case SEA_NRRW:
-				addName(12, new Font("Arial", Font.PLAIN, 100));
-				break;
-			default:
-				break;
-			}
-			break;
-		case SNDWAV:
-			if (Renderer.zoom >= 12) Renderer.fillPattern(Areas.Sandwaves);
-			break;
-		case WEDKLP:
-			if (Renderer.zoom >= 12) {
-				switch ((CatWED) getAttEnum(feature.type, Att.CATWED)) {
-				case WED_KELP:
-					if (feature.geom.prim == Pflag.AREA) { 
-						Renderer.fillPattern(Areas.KelpA);
-					} else {
-						Renderer.symbol(Areas.KelpS);
-					}
-					break;
-				default:
-					break;
-				}
-			}
-			break;
-		case SPLARE:
-			if (Renderer.zoom >= 12) {
-				Renderer.symbol(Areas.Plane, new Scheme(Symbols.Msymb));
-				Renderer.lineSymbols(Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Symbols.Mline);
-			}
-			addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
-			break;
-		default:
-			break;
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void beacons() {
-		if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))
-				|| ((Renderer.zoom >= 11) && ((feature.type == Obj.BCNSAW) || hasObject(Obj.RTPBCN)))) {
-			BcnSHP shape = (BcnSHP)getAttEnum(feature.type, Att.BCNSHP);
-			if (shape == BcnSHP.BCN_UNKN)
-				shape = BcnSHP.BCN_PILE;
-			if ((shape == BcnSHP.BCN_WTHY) && (feature.type == Obj.BCNLAT)) {
-				switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
-				case LAM_PORT:
-					Renderer.symbol(Beacons.WithyPort);
-					break;
-				case LAM_STBD:
-					Renderer.symbol(Beacons.WithyStarboard);
-					break;
-				default:
-					Renderer.symbol(Beacons.Stake, getScheme(feature.type));
-				}
-			} else if ((shape == BcnSHP.BCN_PRCH) && (feature.type == Obj.BCNLAT) && !(feature.objs.containsKey(Obj.TOPMAR))) {
-				switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
-				case LAM_PORT:
-					Renderer.symbol(Beacons.PerchPort);
-					break;
-				case LAM_STBD:
-					Renderer.symbol(Beacons.PerchStarboard);
-					break;
-				default:
-					Renderer.symbol(Beacons.Stake, getScheme(feature.type));
-				}
-			} else {
-				Renderer.symbol(Beacons.Shapes.get(shape), getScheme(feature.type));
-				if (feature.objs.containsKey(Obj.TOPMAR)) {
-					AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
-					if (topmap.containsKey(Att.TOPSHP)) {
-						Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BeaconDelta);
-					}
-				} else if (feature.objs.containsKey(Obj.DAYMAR)) {
-					AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
-					if (topmap.containsKey(Att.TOPSHP)) {
-						Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BeaconDelta);
-					}
-				}
-			}
-			if (hasObject(Obj.NOTMRK))
-				notices();
-			addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
-			Signals.addSignals();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void buoys() {
-		if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))
-				|| ((Renderer.zoom >= 11) && ((feature.type == Obj.BOYSAW) || hasObject(Obj.RTPBCN)))) {
-			BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
-			if (shape == BoySHP.BOY_UNKN) shape = BoySHP.BOY_PILR;
-			Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
-			if (feature.objs.containsKey(Obj.TOPMAR)) {
-				AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
-				}
-			} else if (feature.objs.containsKey(Obj.DAYMAR)) {
-				AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BuoyDeltas.get(shape));
-				}
-			}
-			addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
-			Signals.addSignals();
-		}
-	}
-	
-	private static void bridges() {
-		if (Renderer.zoom >= 16) {
-			double verclr, verccl, vercop, horclr;
-			AttMap atts = feature.objs.get(Obj.BRIDGE).get(0);
-			String vstr = "";
-			String hstr = "";
-			if (atts != null) {
-				if (atts.containsKey(Att.HORCLR)) {
-					horclr = (Double) atts.get(Att.HORCLR).val;
-					hstr = String.valueOf(horclr);
-				}
-					if (atts.containsKey(Att.VERCLR)) {
-						verclr = (Double) atts.get(Att.VERCLR).val;
-				} else {
-					verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
-				}
-				verccl = atts.containsKey(Att.VERCCL) ? (Double) atts.get(Att.VERCCL).val : 0;
-				vercop = atts.containsKey(Att.VERCOP) ? (Double) atts.get(Att.VERCOP).val : 0;
-				if (verclr > 0) {
-					vstr += String.valueOf(verclr);
-				} else if (verccl > 0) {
-					if (vercop == 0) {
-						vstr += String.valueOf(verccl) + "/-";
-					} else {
-						vstr += String.valueOf(verccl) + "/" + String.valueOf(vercop);
-					}
-				}
-				if (hstr.isEmpty() && !vstr.isEmpty()) {
-					Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.CC));
-				} else if (!hstr.isEmpty() && !vstr.isEmpty()) {
-					Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.BC));
-					Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.TC));
-				} else if (!hstr.isEmpty() && vstr.isEmpty()) {
-					Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.CC));
-				}
-			}
-		}
-	}
-	
-	private static void cables() {
-		if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
-			if (feature.type == Obj.CBLSUB) {
-				Renderer.lineSymbols(Areas.Cable, 0.0, null, null, 0, Symbols.Mline);
-			} else if (feature.type == Obj.CBLOHD) {
-				AttMap atts = feature.objs.get(Obj.CBLOHD).get(0);
-				if ((atts != null) && (atts.containsKey(Att.CATCBL)) && (atts.get(Att.CATCBL).val == CatCBL.CBL_POWR)) {
-					Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, Areas.CableFlash, 2, Color.black);
-				} else {
-					Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, null, 2, Color.black);
-				}
-				if (atts != null) {
-					if (atts.containsKey(Att.VERCLR)) {
-						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)));
-					} else if (atts.containsKey(Att.VERCSA)) {
-						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)));
-					}
-				}
-			}
-		}
-	}
-	
-	private static void callpoint() {
-		if (Renderer.zoom >= 14) {
-			Symbol symb = Harbours.CallPoint2;
-			TrfTRF trf = (TrfTRF) getAttEnum(feature.type, Att.TRAFIC);
-			if (trf != TrfTRF.TRF_TWOW) {
-				symb = Harbours.CallPoint1;
-			}
-			Double orient = 0.0;
-			if ((orient = (Double) getAttVal(feature.type, Att.ORIENT)) == null) {
-				orient = 0.0;
-			}
-			Renderer.symbol(symb, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(orient))));
-			String chn;
-			if (!(chn = getAttStr(feature.type, Att.COMCHA)).isEmpty()) {
-				Renderer.labelText(("Ch." + chn), new Font("Arial", Font.PLAIN, 50), Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0,50)));
-			}
-		}
-	}
-	
-	private static void depths() {
-		switch (feature.type) {
-		case SOUNDG:
-			if ((Renderer.zoom >= 14) && hasAttribute(Obj.SOUNDG, Att.VALSOU)) {
-				double depth = (double)getAttVal(Obj.SOUNDG, Att.VALSOU);
-				String dstr = df.format(depth);
-				String tok[] = dstr.split("[-.]");
-				String ul = "";
-				String id = tok[0];
-				String dd = "";
-				if (tok[0].equals("")) {
-					for (int i = 0; i <  tok[1].length(); i++)
-						ul += "_";
-					id = tok[1];
-					dd = (tok.length == 3) ? tok[2] : "";
-				} else {
-					dd = (tok.length == 2) ? tok[1] : "";
-				}
-				Renderer.labelText(ul, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10,15)));
-				Renderer.labelText(id, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10,0)));
-				Renderer.labelText(dd, new Font("Arial", Font.PLAIN, 20), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(15,10)));
-			}
-			break;
-		case DEPCNT:
-			break;
-		default:
-			break;
-		}
-	}
-	
-	private static void distances() {
-		if (Renderer.zoom >= 14) {
-			if (!testAttribute(Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
-				Renderer.symbol(Harbours.DistanceI);
-			} else {
-				Renderer.symbol(Harbours.DistanceU);
-			}
-			if (Renderer.zoom >= 15) {
-				AttMap atts = getAtts(Obj.DISMAR, 0);
-				if ((atts != null) && (atts.containsKey(Att.WTWDIS))) {
-					Double dist = (Double) atts.get(Att.WTWDIS).val;
-					String str = "";
-					if (atts.containsKey(Att.HUNITS)) {
-						switch ((UniHLU) getAttEnum(Obj.DISMAR, Att.HUNITS)) {
-						case HLU_METR:
-							str += "m ";
-							break;
-						case HLU_FEET:
-							str += "ft ";
-							break;
-						case HLU_HMTR:
-							str += "hm ";
-							break;
-						case HLU_KMTR:
-							str += "km ";
-							break;
-						case HLU_SMIL:
-							str += "M ";
-							break;
-						case HLU_NMIL:
-							str += "NM ";
-							break;
-						default:
-							break;
-						}
-					}
-					str += String.format("%1.0f", dist);
-					Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
-				}
-			}
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void floats() {
-		if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) || (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
-			switch (feature.type) {
-			case LITVES:
-				Renderer.symbol(Buoys.Super, getScheme(feature.type));
-				break;
-			case LITFLT:
-				Renderer.symbol(Buoys.Float, getScheme(feature.type));
-				break;
-			case BOYINB:
-				Renderer.symbol(Buoys.Super, getScheme(feature.type));
-				break;
-			default:
-				break;
-			}
-			if (feature.objs.containsKey(Obj.TOPMAR)) {
-				AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.FloatDelta);
-				}
-			} else if (feature.objs.containsKey(Obj.DAYMAR)) {
-				AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.FloatDelta);
-				}
-			}
-			addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
-			Signals.addSignals();
-		}
-	}
-	
-	private static void gauges() {
-		if (Renderer.zoom >= 14) {
-			Renderer.symbol(Harbours.TideGauge);
-			addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
-			Signals.addSignals();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void harbours() {
-		String name = getName();
-		switch (feature.type) {
-		case ACHBRT:
-			if (Renderer.zoom >= 14) {
-				Renderer.symbol(Harbours.Anchor, new Scheme(Symbols.Msymb));
-				if (Renderer.zoom >= 15) {
-					Renderer.labelText(name == null ? "" : name, new Font("Arial", Font.PLAIN, 30), Symbols.Msymb, LabelStyle.RRCT, Symbols.Msymb, Color.white, new Delta(Handle.BC));
-				}
-			}
-			if (getAttVal(Obj.ACHBRT, Att.RADIUS) != null) {
-				double radius;
-				if ((radius = (Double) getAttVal(Obj.ACHBRT, Att.RADIUS)) != 0) {
-					UniHLU units = (UniHLU) getAttEnum(Obj.ACHBRT, Att.HUNITS);
-					if (units == UniHLU.HLU_UNKN) {
-						units = UniHLU.HLU_METR;
-					}
-					Renderer.lineCircle(new LineStyle(Symbols.Mline, 4, new float[] { 10, 10 }, null), radius, units);
-				}
-			}
-			break;
-		case ACHARE:
-			if (Renderer.zoom >= 12) {
-				if (feature.geom.prim != Pflag.AREA) {
-					Renderer.symbol(Harbours.Anchorage, new Scheme(Color.black));
-				} else {
-					Renderer.symbol(Harbours.Anchorage, new Scheme(Symbols.Mline));
-					Renderer.lineSymbols(Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Symbols.Mline);
-				}
-				addName(15, new Font("Arial", Font.BOLD, 60), Symbols.Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
-				ArrayList<StsSTS> sts = (ArrayList<StsSTS>) getAttList(Obj.ACHARE, Att.STATUS);
-				if ((Renderer.zoom >= 15) && (sts.contains(StsSTS.STS_RESV))) {
-					Renderer.labelText("Reserved", new Font("Arial", Font.PLAIN, 50), Symbols.Mline, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
-				}
-				ArrayList<CatACH> cats = (ArrayList<CatACH>) getAttList(Obj.ACHARE, Att.CATACH);
-				int dy = (cats.size() - 1) * -30;
-				for (CatACH cat : cats) {
-					switch (cat) {
-					case ACH_DEEP:
-						Renderer.labelText("DW", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					case ACH_TANK:
-						Renderer.labelText("Tanker", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					case ACH_H24P:
-						Renderer.labelText("24h", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					case ACH_EXPL:
-						Renderer.symbol(Harbours.Explosives, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					case ACH_QUAR:
-						Renderer.symbol(Harbours.Hospital, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					case ACH_SEAP:
-						Renderer.symbol(Areas.Seaplane, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
-						dy += 60;
-						break;
-					default:
-					}
-				}
-			}
-			break;
-		case BERTHS:
-			if (Renderer.zoom >= 14) {
-				Renderer.lineVector(new LineStyle(Symbols.Mline, 6, new float[] { 20, 20 }));
-				Renderer.labelText(name == null ? " " : name, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, LabelStyle.RRCT, Symbols.Mline, Color.white);
-			}
-			break;
-		case BUISGL:
-			if (Renderer.zoom >= 16) {
-				ArrayList<Symbol> symbols = new ArrayList<>();
-				ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(Obj.BUISGL, Att.FUNCTN);
-				for (FncFNC fnc : fncs) {
-					symbols.add(Landmarks.Funcs.get(fnc));
-				}
-				if (feature.objs.containsKey(Obj.SMCFAC)) {
-					ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
-					for (CatSCF scf : scfs) {
-						symbols.add(Facilities.Cats.get(scf));
-					}
-				}
-				Renderer.cluster(symbols);
-			}
-			break;
-		case HRBFAC:
-			if (Renderer.zoom >= 12) {
-				ArrayList<CatHAF> cathaf = (ArrayList<CatHAF>) getAttList(Obj.HRBFAC, Att.CATHAF);
-				if (cathaf.size() == 1) {
-					switch (cathaf.get(0)) {
-					case HAF_MRNA:
-						Renderer.symbol(Harbours.Marina);
-						break;
-					case HAF_MANF:
-						Renderer.symbol(Harbours.MarinaNF);
-						break;
-					case HAF_FISH:
-						Renderer.symbol(Harbours.Fishing);
-						break;
-					default:
-						Renderer.symbol(Harbours.Harbour);
-						break;
-					}
-				} else {
-					Renderer.symbol(Harbours.Harbour);
-				}
-			}
-			break;
-		default:
-			break;
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void highways() {
-		switch (feature.type) {
-		case ROADWY:
-			ArrayList<CatROD> cat = (ArrayList<CatROD>) (getAttList(Obj.ROADWY, Att.CATROD));
-			if (cat.size() > 0) {
-				switch (cat.get(0)) {
-				case ROD_MWAY:
-					Renderer.lineVector(new LineStyle(Color.black, 20));
-					break;
-				case ROD_MAJR:
-					Renderer.lineVector(new LineStyle(Color.black, 15));
-					break;
-				case ROD_MINR:
-					Renderer.lineVector(new LineStyle(Color.black, 10));
-					break;
-				default:
-					Renderer.lineVector(new LineStyle(Color.black, 5));
-				}
-			} else {
-				Renderer.lineVector(new LineStyle(Color.black, 5));
-			}
-			break;
-		case RAILWY:
-			Renderer.lineVector(new LineStyle(Color.gray, 10));
-			Renderer.lineVector(new LineStyle(Color.black, 10, new float[] { 30, 30 }));
-			break;
-		default:
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void landmarks() {
-		if (!hasAttribute(Obj.LNDMRK, Att.CATLMK)
-				&& (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT))
-				&& hasObject(Obj.LIGHTS))
-			lights();
-		else if (Renderer.zoom >= 12) {
-			switch (feature.type) {
-			case LNDMRK:
-			ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttList(feature.type, Att.CATLMK);
-			Symbol catSym = Landmarks.Shapes.get(cats.get(0));
-			ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(feature.type, Att.FUNCTN);
-			Symbol fncSym = Landmarks.Funcs.get(fncs.get(0));
-			if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
-				catSym = Landmarks.ChurchTower;
-			if (cats.get(0) == CatLMK.LMK_RADR)
-				fncSym = Landmarks.RadioTV;
-			Renderer.symbol(catSym);
-			Renderer.symbol(fncSym);
-			break;
-			case SILTNK:
-				if (testAttribute(feature.type, Att.CATSIL, CatSIL.SIL_WTRT))
-					Renderer.symbol(Landmarks.WaterTower);
-				break;
-			default:
-				break;
-			}
-			if (Renderer.zoom >= 15)
-				addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
-			Signals.addSignals();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void points() {
-		boolean ok = false;
-		switch (feature.type) {
-		case FOGSIG:
-			if (Renderer.zoom >= 12) {
-				if (feature.objs.containsKey(Obj.LIGHTS))
-					lights();
-				else
-					Renderer.symbol(Harbours.Post);
-				ok = true;
-			}
-			break;
-		default:
-			if (Renderer.zoom >= 14) {
-				if (feature.objs.containsKey(Obj.LIGHTS))
-					lights();
-				else
-					Renderer.symbol(Harbours.Post);
-				ok = true;
-			}
-			break;
-		}
-		if (ok) {
-			if (feature.objs.containsKey(Obj.TOPMAR)) {
-				AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), null);
-				}
-			} else if (feature.objs.containsKey(Obj.DAYMAR)) {
-				AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), null);
-				}
-			}
-			Signals.addSignals();
-		}
-	}
-	
-	@SuppressWarnings("unchecked")
-	private static void lights() {
-		boolean ok = false;
-		switch (feature.type) {
-		case LITMAJ:
-		case LNDMRK:
-			if (Renderer.zoom >= 12) {
-				Renderer.symbol(Beacons.LightMajor);
-				ok = true;
-			}
-			break;
-		case LITMIN:
-		case LIGHTS:
-		case PILPNT:
-			if (Renderer.zoom >= 14) {
-				Renderer.symbol(Beacons.LightMinor);
-				ok = true;
-			}
-			break;
-		default:
-			break;
-		}
-		if (ok) {
-			if (feature.objs.containsKey(Obj.TOPMAR)) {
-				AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.LightDelta);
-				}
-			} else if (feature.objs.containsKey(Obj.DAYMAR)) {
-				AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
-				if (topmap.containsKey(Att.TOPSHP)) {
-					Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.LightDelta);
-				}
-			}
-			Signals.addSignals();
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void marinas() {
-		if (Renderer.zoom >= 16) {
-			ArrayList<Symbol> symbols = new ArrayList<>();
-			ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
-			for (CatSCF scf : scfs) {
-				symbols.add(Facilities.Cats.get(scf));
-			}
-			Renderer.cluster(symbols);
-		}
-	}
-	
-	private static void moorings() {
-		if (Renderer.zoom >= 14) {
-			switch ((CatMOR) getAttEnum(feature.type, Att.CATMOR)) {
-			case MOR_DLPN:
-				Renderer.symbol(Harbours.Dolphin);
-				break;
-			case MOR_DDPN:
-				Renderer.symbol(Harbours.DeviationDolphin);
-				break;
-			case MOR_BLRD:
-			case MOR_POST:
-				Renderer.symbol(Harbours.Bollard);
-				break;
-			case MOR_BUOY:
-				BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
-				if (shape == BoySHP.BOY_UNKN) {
-					shape = BoySHP.BOY_SPHR;
-				}
-				Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
-				Renderer.symbol(Topmarks.TopMooring, Topmarks.BuoyDeltas.get(shape));
-				break;
-			default:
-				break;
-			}
-			Signals.addSignals();
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void notices() {
-		if (Renderer.zoom >= 14) {
-			double dx = 0.0, dy = 0.0;
-			switch (feature.type) {
-			case BCNCAR:
-			case BCNISD:
-			case BCNLAT:
-			case BCNSAW:
-			case BCNSPP:
-				if (testAttribute(Obj.TOPMAR, Att.TOPSHP, TopSHP.TOP_BORD) || testAttribute(Obj.DAYMAR, Att.TOPSHP, TopSHP.TOP_BORD)) {
-					dy = -100.0;
-				} else {
-					dy = -45.0;
-				}
-				break;
-			case NOTMRK:
-				dy = 0.0;
-				break;
-			default:
-				return;
-			}
-			MarSYS sys = MarSYS.SYS_CEVN;
-			BnkWTW bnk = BnkWTW.BWW_UNKN;
-			AttVal<?> att = feature.atts.get(Att.MARSYS);
-			if (att != null) sys = (MarSYS)att.val;
-			att = feature.atts.get(Att.BNKWTW);
-			if (att != null) bnk = (BnkWTW)att.val;
-			ObjTab objs = feature.objs.get(Obj.NOTMRK);
-			int n = objs.size();
-			if (n > 5) {
-				Renderer.symbol(Notices.Notice, new Delta(Handle.CC, AffineTransform.getTranslateInstance(dx, dy)));
-			} else {
-				int i = 0;
-				for (AttMap atts : objs.values()) {
-					if (atts.get(Att.MARSYS) != null) sys = ((ArrayList<MarSYS>)(atts.get(Att.MARSYS).val)).get(0);
-					if (atts.get(Att.BNKWTW) != null) bnk = ((ArrayList<BnkWTW>)(atts.get(Att.BNKWTW).val)).get(0);
-					CatNMK cat = CatNMK.NMK_UNKN;
-					if (atts.get(Att.CATNMK) != null) cat = ((ArrayList<CatNMK>)(atts.get(Att.CATNMK).val)).get(0);
-					Symbol sym = Notices.getNotice(cat, sys, bnk);
-					Scheme sch = Notices.getScheme(sys, bnk);
-					ArrayList<AddMRK> add = new ArrayList<>();
-					if (atts.get(Att.ADDMRK) != null) add = (ArrayList<AddMRK>)(atts.get(Att.ADDMRK).val);
-					Handle h = Handle.CC;
-					double ax = 0.0;
-					double ay = 0.0;
-					switch (i) {
-					case 0:
-						if (n != 1) h = null;
-						break;
-					case 1:
-						if (n <= 3) {
-							h = Handle.RC;
-							ax = -30;
-							ay = dy;
-						}
-						else {
-							h = Handle.BR;
-						}
-						break;
-					case 2:
-						if (n <= 3)
-							h = Handle.LC;
-						else
-							h = Handle.BL;
-						break;
-					case 3:
-						if (n == 4)
-							h = Handle.TC;
-						else
-							h = Handle.TR;
-						break;
-					case 4:
-						h = Handle.TL;
-						break;
-					}
-					if (h != null) {
-						Renderer.symbol(sym, sch, new Delta(h, AffineTransform.getTranslateInstance(dx, dy)));
-						if (!add.isEmpty()) Renderer.symbol(Notices.NoticeBoard, new Delta(Handle.BC, AffineTransform.getTranslateInstance(ax, ay - 30)));
-					}
-					i++;
-				}
-			}
-		}
-	}
-
-	private static void obstructions() {
-		if ((Renderer.zoom >= 12) && (feature.type == Obj.OBSTRN)) {
-			switch ((CatOBS) getAttEnum(feature.type, Att.CATOBS)) {
-			case OBS_BOOM:
-				Renderer.lineVector(new LineStyle(Color.black, 5, new float[] { 20, 20 }, null));
-				if (Renderer.zoom >= 15) {
-					Renderer.lineText("Boom", new Font("Arial", Font.PLAIN, 80), Color.black, -20);
-				}
-			default:
-				break;
-			}
-		}
-		if ((Renderer.zoom >= 14) && (feature.type == Obj.UWTROC)) {
-			switch ((WatLEV) getAttEnum(feature.type, Att.WATLEV)) {
-			case LEV_CVRS:
-				Renderer.symbol(Areas.RockC);
-				break;
-			case LEV_AWSH:
-				Renderer.symbol(Areas.RockA);
-				break;
-			default:
-				Renderer.symbol(Areas.Rock);
-			}
-		} else {
-			Renderer.symbol(Areas.Rock);
-		}
-	}
-
-	private static void pipelines() {
-		if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
-			if (feature.type == Obj.PIPSOL) {
-				Renderer.lineSymbols(Areas.Pipeline, 1.0, null, null, 0, Symbols.Mline);
-			} else if (feature.type == Obj.PIPOHD) {
-				Renderer.lineVector(new LineStyle(Color.black, 8));
-				AttMap atts = feature.atts;
-				double verclr = 0;
-				if (atts != null) {
-					if (atts.containsKey(Att.VERCLR)) {
-						verclr = (Double) atts.get(Att.VERCLR).val;
-					} else {
-						verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
-					}
-					if (verclr > 0) {
-						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)));
-					}
-				}
-			}
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void platforms() {
-		ArrayList<CatOFP> cats = (ArrayList<CatOFP>) getAttList(Obj.OFSPLF, Att.CATOFP);
-		if ((CatOFP) cats.get(0) == CatOFP.OFP_FPSO)
-			Renderer.symbol(Buoys.Storage);
-		else
-			Renderer.symbol(Landmarks.Platform);
-		addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
-		Signals.addSignals();
-	}
-
-	private static void ports() {
-		if (Renderer.zoom >= 14) {
-			if (feature.type == Obj.CRANES) {
-				if ((CatCRN) getAttEnum(feature.type, Att.CATCRN) == CatCRN.CRN_CONT)
-					Renderer.symbol(Harbours.ContainerCrane);
-				else
-					Renderer.symbol(Harbours.PortCrane);
-			} else if (feature.type == Obj.HULKES) {
-				Renderer.lineVector(new LineStyle(Color.black, 4, null, new Color(0xffe000)));
-				addName(15, new Font("Arial", Font.BOLD, 40));
-			}
-		}
-	}
-
-	private static void separation() {
-		switch (feature.type) {
-		case TSEZNE:
-		case TSSCRS:
-		case TSSRON:
-			if (Renderer.zoom <= 15)
-				Renderer.lineVector(new LineStyle(Symbols.Mtss));
-			else
-				Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
-			addName(10, new Font("Arial", Font.BOLD, 150), Symbols.Mline);
-			break;
-		case TSELNE:
-			Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
-			break;
-		case TSSLPT:
-			Renderer.lineSymbols(Areas.LaneArrow, 0.5, null, null, 0, Symbols.Mtss);
-			break;
-		case TSSBND:
-			Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, new float[] { 40, 40 }, null));
-			break;
-		case ISTZNE:
-			Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mtss);
-			break;
-		default:
-			break;
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void shoreline() {
-		CatSLC cat = (CatSLC) getAttEnum(feature.type, Att.CATSLC);
-		if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
-			if ((cat != CatSLC.SLC_SWAY) && (cat != CatSLC.SLC_TWAL)) {
-				if (Renderer.zoom >= 12) {
-					Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Yland));
-				} else {
-					Renderer.lineVector(new LineStyle(Symbols.Yland));
-				}
-			}
-		}
-		if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
-			if (Renderer.zoom >= 12) {
-				switch (cat) {
-				case SLC_TWAL:
-					WatLEV lev = (WatLEV) getAttEnum(feature.type, Att.WATLEV);
-					if (lev == WatLEV.LEV_CVRS) {
-						Renderer.lineVector(new LineStyle(Color.black, 10, new float[] { 40, 40 }, null));
-						if (Renderer.zoom >= 15)
-							Renderer.lineText("(covers)", new Font("Arial", Font.PLAIN, 60), Color.black, 80);
-					} else {
-						Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
-					}
-					if (Renderer.zoom >= 15)
-						Renderer.lineText("Training Wall", new Font("Arial", Font.PLAIN, 60), Color.black, -30);
-					break;
-				case SLC_SWAY:
-					Renderer.lineVector(new LineStyle(Color.black, 2, null, new Color(0xffe000)));
-					if ((Renderer.zoom >= 16) && feature.objs.containsKey(Obj.SMCFAC)) {
-						ArrayList<Symbol> symbols = new ArrayList<>();
-						ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
-						for (CatSCF scf : scfs) {
-							symbols.add(Facilities.Cats.get(scf));
-						}
-						Renderer.cluster(symbols);
-					}
-					break;
-				default:
-					break;
-				}
-			}
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	private static void stations() {
-		if (Renderer.zoom >= 14) {
-			String str = "";
-			switch (feature.type) {
-			case SISTAT:
-				Renderer.symbol(Harbours.SignalStation);
-				str = "SS";
-				ArrayList<CatSIT> tcats = (ArrayList<CatSIT>) getAttList(Obj.SISTAT, Att.CATSIT);
-				switch (tcats.get(0)) {
-				case SIT_IPT:
-					str += "(INT)";
-					break;
-				case SIT_PRTE:
-					str += "(Traffic)";
-					break;
-				case SIT_PRTC:
-					str += "(Port Control)";
-					break;
-				case SIT_LOCK:
-					str += "(Lock)";
-					break;
-				case SIT_BRDG:
-					str += "(Bridge)";
-					break;
-				default:
-					break;
-				}
-				break;
-			case SISTAW:
-				Renderer.symbol(Harbours.SignalStation);
-				str = "SS";
-				str = "SS";
-				ArrayList<CatSIW> wcats = (ArrayList<CatSIW>) getAttList(Obj.SISTAW, Att.CATSIW);
-				switch (wcats.get(0)) {
-				case SIW_STRM:
-					str += "(Storm)";
-					break;
-				case SIW_WTHR:
-					str += "(Weather)";
-					break;
-				case SIW_ICE:
-					str += "(Ice)";
-					break;
-				case SIW_TIDG:
-					str = "Tide gauge";
-					break;
-				case SIW_TIDS:
-					str = "Tide scale";
-					break;
-				case SIW_TIDE:
-					str += "(Tide)";
-					break;
-				case SIW_TSTR:
-					str += "(Stream)";
-					break;
-				case SIW_DNGR:
-					str += "(Danger)";
-					break;
-				case SIW_MILY:
-					str += "(Firing)";
-					break;
-				case SIW_TIME:
-					str += "(Time)";
-					break;
-				default:
-					break;
-				}
-				break;
-			case RDOSTA:
-			case RTPBCN:
-				Renderer.symbol(Harbours.SignalStation);
-				Renderer.symbol(Beacons.RadarStation);
-				break;
-			case RADRFL:
-				Renderer.symbol(Topmarks.RadarReflector);
-				break;
-			case RADSTA:
-				Renderer.symbol(Harbours.SignalStation);
-				Renderer.symbol(Beacons.RadarStation);
-				Renderer.labelText("Ra", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
-				break;
-			case PILBOP:
-				Renderer.symbol(Harbours.Pilot);
-				addName(15, new Font("Arial", Font.BOLD, 40), Symbols.Msymb , new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, -40)));
-				CatPIL cat = (CatPIL) getAttEnum(feature.type, Att.CATPIL);
-				if (cat == CatPIL.PIL_HELI) {
-					Renderer.labelText("H", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
-				}
-				break;
-			case CGUSTA:
-				Renderer.symbol(Harbours.SignalStation);
-				str = "CG";
-			  if (feature.objs.containsKey(Obj.RSCSTA)) Renderer.symbol(Harbours.Rescue, new Delta(Handle.CC, AffineTransform.getTranslateInstance(130, 0)));
-				break;
-			case RSCSTA:
-				Renderer.symbol(Harbours.Rescue);
-				break;
-			default:
-				break;
-			}
-			if ((Renderer.zoom >= 15) && !str.isEmpty()) {
-				Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(40, 0)));
-			}
-			Signals.addSignals();
-		}
-	}
-
-	private static void transits() {
-	  if (Renderer.zoom >= 14) {
-	  	if (feature.type == Obj.RECTRC) Renderer.lineVector (new LineStyle(Color.black, 10, null, null));
-	  	else if (feature.type == Obj.NAVLNE) Renderer.lineVector (new LineStyle(Color.black, 10, new float[] { 25, 25 }, null));
-	  }
-		if (Renderer.zoom >= 15) {
-			String str = "";
-			String name = getName();
-			if (name != null)
-				str += name + " ";
-			Double ort;
-			if ((ort = (Double) getAttVal(feature.type, Att.ORIENT)) != null) {
-				str += df.format(ort) + "º";
-				if (!str.isEmpty())
-					Renderer.lineText(str, new Font("Arial", Font.PLAIN, 80), Color.black, -20);
-			}
-		}
-	}
-
-	private static void waterways() {
-		Renderer.lineVector(new LineStyle(Symbols.Bwater, 20, (feature.geom.prim == Pflag.AREA) ? Symbols.Bwater : null));
-	}
-
-	private static void wrecks() {
-		if (Renderer.zoom >= 14) {
-			switch ((CatWRK) getAttEnum(feature.type, Att.CATWRK)) {
-			case WRK_DNGR:
-			case WRK_MSTS:
-				Renderer.symbol(Areas.WreckD);
-				break;
-			case WRK_HULS:
-				Renderer.symbol(Areas.WreckS);
-				break;
-			default:
-				Renderer.symbol(Areas.WreckND);
-			}
-		}
-	}
+
+    static final DecimalFormat df = new DecimalFormat("#.#");
+
+    static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<>(ColCOL.class);
+    static {
+        bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
+        bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
+        bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
+        bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
+        bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
+        bodyColours.put(ColCOL.COL_BLU, Color.blue);
+        bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
+        bodyColours.put(ColCOL.COL_GRY, Color.gray);
+        bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
+        bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
+        bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
+        bodyColours.put(ColCOL.COL_ORG, Color.orange);
+        bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
+        bodyColours.put(ColCOL.COL_PNK, Color.pink);
+    }
+
+    static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<>(ColPAT.class);
+    static {
+        pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
+        pattMap.put(ColPAT.PAT_HORI, Patt.H);
+        pattMap.put(ColPAT.PAT_VERT, Patt.V);
+        pattMap.put(ColPAT.PAT_DIAG, Patt.D);
+        pattMap.put(ColPAT.PAT_BRDR, Patt.B);
+        pattMap.put(ColPAT.PAT_SQUR, Patt.S);
+        pattMap.put(ColPAT.PAT_CROS, Patt.C);
+        pattMap.put(ColPAT.PAT_SALT, Patt.X);
+        pattMap.put(ColPAT.PAT_STRP, Patt.H);
+    }
+
+    static String getName() {
+        AttVal<?> name = feature.atts.get(Att.OBJNAM);
+        if (name == null) {
+            AttMap atts = feature.objs.get(feature.type).get(0);
+            if (atts != null) {
+                name = atts.get(Att.OBJNAM);
+            }
+        }
+        return (name != null) ? (String) name.val : null;
+    }
+
+    public static void addName(int z, Font font) {
+        addName(z, font, Color.black, new Delta(Handle.CC, new AffineTransform()));
+    }
+
+    public static void addName(int z, Font font, Color colour) {
+        addName(z, font, colour, new Delta(Handle.CC, new AffineTransform()));
+    }
+
+    public static void addName(int z, Font font, Delta delta) {
+        addName(z, font, Color.black, delta);
+    }
+
+    public static void addName(int z, Font font, Color colour, Delta delta) {
+        if (Renderer.zoom >= z) {
+            String name = getName();
+            if (name != null) {
+                Renderer.labelText(name, font, colour, delta);
+            }
+        }
+    }
+
+    static AttMap getAtts(Obj obj, int idx) {
+        HashMap<Integer, AttMap> objs = feature.objs.get(obj);
+        if (objs == null)
+            return null;
+        else
+            return objs.get(idx);
+    }
+
+    public static Object getAttVal(Obj obj, Att att) {
+        AttMap atts;
+        HashMap<Integer, AttMap> objs;
+        AttVal<?> item;
+        if ((objs = feature.objs.get(obj)) != null)
+            atts = objs.get(0);
+        else
+            return null;
+        if ((item = atts.get(att)) == null)
+            return null;
+        else
+            return item.val;
+    }
+
+    public static String getAttStr(Obj obj, Att att) {
+        String str = (String) getAttVal(obj, att);
+        if (str != null) {
+            return str;
+        }
+        return "";
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Enum<?> getAttEnum(Obj obj, Att att) {
+        ArrayList<?> list = (ArrayList<?>) getAttVal(obj, att);
+        if (list != null) {
+            return ((ArrayList<Enum<?>>) list).get(0);
+        }
+        return S57val.unknAtt(att);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static ArrayList<?> getAttList(Obj obj, Att att) {
+        ArrayList<Enum<?>> list = (ArrayList<Enum<?>>) getAttVal(obj, att);
+        if (list != null) {
+            return list;
+        }
+        list = new ArrayList<>();
+        list.add(S57val.unknAtt(att));
+        return list;
+    }
+
+    @SuppressWarnings("unchecked")
+    static Scheme getScheme(Obj obj) {
+        ArrayList<Color> colours = new ArrayList<>();
+        for (ColCOL col : (ArrayList<ColCOL>) getAttList(obj, Att.COLOUR)) {
+            colours.add(bodyColours.get(col));
+        }
+        ArrayList<Patt> patterns = new ArrayList<>();
+        for (ColPAT pat : (ArrayList<ColPAT>) getAttList(obj, Att.COLPAT)) {
+            patterns.add(pattMap.get(pat));
+        }
+        return new Scheme(patterns, colours);
+    }
+
+    static boolean hasAttribute(Obj obj, Att att) {
+        AttMap atts;
+        if ((atts = getAtts(obj, 0)) != null) {
+            AttVal<?> item = atts.get(att);
+            return item != null;
+        }
+        return false;
+    }
+
+    static boolean testAttribute(Obj obj, Att att, Object val) {
+        AttMap atts;
+        if ((atts = getAtts(obj, 0)) != null) {
+            AttVal<?> item = atts.get(att);
+            if (item != null) {
+                switch (item.conv) {
+                case S:
+                case A:
+                    return ((String) item.val).equals(val);
+                case E:
+                case L:
+                    return ((ArrayList<?>) item.val).contains(val);
+                case F:
+                case I:
+                    return item.val == val;
+                }
+            }
+        }
+        return false;
+    }
+
+    static boolean hasObject(Obj obj) {
+        return (feature.objs.containsKey(obj));
+    }
+
+    public static Feature feature;
+    static ArrayList<Feature> objects;
+
+    static boolean testObject(Obj obj) {
+        return ((objects = Renderer.map.features.get(obj)) != null);
+    }
+
+    static boolean testFeature(Feature f) {
+        return ((feature = f).reln == Rflag.MASTER);
+    }
+
+    public static void rules() {
+        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
+            if (testObject(Obj.LNDARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.BUAARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.HRBBSN)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.LOKBSN)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.LKBSPT)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.LAKARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.RIVERS)) for (Feature f : objects) if (testFeature(f)) waterways();
+            if (testObject(Obj.CANALS)) for (Feature f : objects) if (testFeature(f)) waterways();
+            if (testObject(Obj.DEPARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.COALNE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.ROADWY)) for (Feature f : objects) if (testFeature(f)) highways();
+            if (testObject(Obj.RAILWY)) for (Feature f : objects) if (testFeature(f)) highways();
+        }
+        if (Renderer.context.ruleset() == RuleSet.ALL) {
+            if (testObject(Obj.SOUNDG)) for (Feature f : objects) if (testFeature(f)) depths();
+            if (testObject(Obj.DEPCNT)) for (Feature f : objects) if (testFeature(f)) depths();
+        }
+        if (testObject(Obj.SLCONS)) for (Feature f : objects) if (testFeature(f)) shoreline();
+        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
+            if (testObject(Obj.PIPSOL)) for (Feature f : objects) if (testFeature(f)) pipelines();
+            if (testObject(Obj.CBLSUB)) for (Feature f : objects) if (testFeature(f)) cables();
+            if (testObject(Obj.PIPOHD)) for (Feature f : objects) if (testFeature(f)) pipelines();
+            if (testObject(Obj.CBLOHD)) for (Feature f : objects) if (testFeature(f)) cables();
+            if (testObject(Obj.TSEZNE)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.TSSCRS)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.TSSRON)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.TSELNE)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.TSSLPT)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.TSSBND)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.ISTZNE)) for (Feature f : objects) if (testFeature(f)) separation();
+            if (testObject(Obj.SNDWAV)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.WEDKLP)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.OSPARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.FAIRWY)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.DRGARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.RESARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.PRCARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.SPLARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.SEAARE)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.OBSTRN)) for (Feature f : objects) if (testFeature(f)) obstructions();
+            if (testObject(Obj.UWTROC)) for (Feature f : objects) if (testFeature(f)) obstructions();
+            if (testObject(Obj.MARCUL)) for (Feature f : objects) if (testFeature(f)) areas();
+            if (testObject(Obj.RECTRC)) for (Feature f : objects) if (testFeature(f)) transits();
+            if (testObject(Obj.NAVLNE)) for (Feature f : objects) if (testFeature(f)) transits();
+            if (testObject(Obj.HRBFAC)) for (Feature f : objects) if (testFeature(f)) harbours();
+            if (testObject(Obj.ACHARE)) for (Feature f : objects) if (testFeature(f)) harbours();
+            if (testObject(Obj.ACHBRT)) for (Feature f : objects) if (testFeature(f)) harbours();
+            if (testObject(Obj.BERTHS)) for (Feature f : objects) if (testFeature(f)) harbours();
+            if (testObject(Obj.DISMAR)) for (Feature f : objects) if (testFeature(f)) distances();
+            if (testObject(Obj.HULKES)) for (Feature f : objects) if (testFeature(f)) ports();
+            if (testObject(Obj.CRANES)) for (Feature f : objects) if (testFeature(f)) ports();
+            if (testObject(Obj.LNDMRK)) for (Feature f : objects) if (testFeature(f)) landmarks();
+            if (testObject(Obj.SILTNK)) for (Feature f : objects) if (testFeature(f)) landmarks();
+            if (testObject(Obj.BUISGL)) for (Feature f : objects) if (testFeature(f)) harbours();
+            if (testObject(Obj.MORFAC)) for (Feature f : objects) if (testFeature(f)) moorings();
+            if (testObject(Obj.NOTMRK)) for (Feature f : objects) if (testFeature(f)) notices();
+            if (testObject(Obj.SMCFAC)) for (Feature f : objects) if (testFeature(f)) marinas();
+            if (testObject(Obj.BRIDGE)) for (Feature f : objects) if (testFeature(f)) bridges();
+            if (testObject(Obj.PILPNT)) for (Feature f : objects) if (testFeature(f)) points();
+            if (testObject(Obj.TOPMAR)) for (Feature f : objects) if (testFeature(f)) points();
+            if (testObject(Obj.DAYMAR)) for (Feature f : objects) if (testFeature(f)) points();
+            if (testObject(Obj.FOGSIG)) for (Feature f : objects) if (testFeature(f)) points();
+            if (testObject(Obj.RDOCAL)) for (Feature f : objects) if (testFeature(f)) callpoint();
+            if (testObject(Obj.LITMIN)) for (Feature f : objects) if (testFeature(f)) lights();
+            if (testObject(Obj.LITMAJ)) for (Feature f : objects) if (testFeature(f)) lights();
+            if (testObject(Obj.LIGHTS)) for (Feature f : objects) if (testFeature(f)) lights();
+            if (testObject(Obj.SISTAT)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.SISTAW)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.CGUSTA)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.RDOSTA)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.RADRFL)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.RADSTA)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.RTPBCN)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.RSCSTA)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.PILBOP)) for (Feature f : objects) if (testFeature(f)) stations();
+            if (testObject(Obj.WTWGAG)) for (Feature f : objects) if (testFeature(f)) gauges();
+            if (testObject(Obj.OFSPLF)) for (Feature f : objects) if (testFeature(f)) platforms();
+            if (testObject(Obj.WRECKS)) for (Feature f : objects) if (testFeature(f)) wrecks();
+            if (testObject(Obj.LITVES)) for (Feature f : objects) if (testFeature(f)) floats();
+            if (testObject(Obj.LITFLT)) for (Feature f : objects) if (testFeature(f)) floats();
+            if (testObject(Obj.BOYINB)) for (Feature f : objects) if (testFeature(f)) floats();
+            if (testObject(Obj.BOYLAT)) for (Feature f : objects) if (testFeature(f)) buoys();
+            if (testObject(Obj.BOYCAR)) for (Feature f : objects) if (testFeature(f)) buoys();
+            if (testObject(Obj.BOYISD)) for (Feature f : objects) if (testFeature(f)) buoys();
+            if (testObject(Obj.BOYSAW)) for (Feature f : objects) if (testFeature(f)) buoys();
+            if (testObject(Obj.BOYSPP)) for (Feature f : objects) if (testFeature(f)) buoys();
+            if (testObject(Obj.BCNLAT)) for (Feature f : objects) if (testFeature(f)) beacons();
+            if (testObject(Obj.BCNCAR)) for (Feature f : objects) if (testFeature(f)) beacons();
+            if (testObject(Obj.BCNISD)) for (Feature f : objects) if (testFeature(f)) beacons();
+            if (testObject(Obj.BCNSAW)) for (Feature f : objects) if (testFeature(f)) beacons();
+            if (testObject(Obj.BCNSPP)) for (Feature f : objects) if (testFeature(f)) beacons();
+        }
+    }
+
+    private static void areas() {
+        String name = getName();
+        switch (feature.type) {
+        case BUAARE:
+            Renderer.lineVector(new LineStyle(new Color(0x20000000, true)));
+            break;
+        case COALNE:
+            if (Renderer.zoom >= 12)
+                Renderer.lineVector(new LineStyle(Color.black, 10));
+            break;
+        case DEPARE:
+            Double depmax = 0.0;
+            if (((depmax = (Double) getAttVal(Obj.DEPARE, Att.DRVAL2)) != null) && (depmax <= 0.0)) {
+                Renderer.lineVector(new LineStyle(Symbols.Gdries));
+            }
+            break;
+        case LAKARE:
+            if ((Renderer.zoom >= 12) || (feature.geom.area > 10.0))
+                Renderer.lineVector(new LineStyle(Symbols.Bwater));
+            break;
+        case DRGARE:
+            if (Renderer.zoom < 16)
+                Renderer.lineVector(new LineStyle(Color.black, 8, new float[] {25, 25 }, new Color(0x40ffffff, true)));
+            else
+                Renderer.lineVector(new LineStyle(Color.black, 8, new float[] {25, 25 }));
+            addName(12, new Font("Arial", Font.PLAIN, 100), new Delta(Handle.CC, new AffineTransform()));
+            break;
+        case FAIRWY:
+            if (feature.geom.area > 2.0) {
+                if (Renderer.zoom < 16)
+                    Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] {50, 50 }, new Color(0x40ffffff, true)));
+                else
+                    Renderer.lineVector(new LineStyle(Symbols.Mline, 8, new float[] {50, 50 }));
+            } else {
+                if (Renderer.zoom >= 14)
+                    Renderer.lineVector(new LineStyle(new Color(0x40ffffff, true)));
+            }
+            break;
+        case LKBSPT:
+        case LOKBSN:
+        case HRBBSN:
+            if (Renderer.zoom >= 12) {
+                Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
+            } else {
+                Renderer.lineVector(new LineStyle(Symbols.Bwater));
+            }
+            break;
+        case HRBFAC:
+            if (feature.objs.get(Obj.HRBBSN) != null) {
+                if (Renderer.zoom >= 12) {
+                    Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Bwater));
+                } else {
+                    Renderer.lineVector(new LineStyle(Symbols.Bwater));
+                }
+            }
+            break;
+        case LNDARE:
+            Renderer.lineVector(new LineStyle(Symbols.Yland));
+            break;
+        case MARCUL:
+            if (Renderer.zoom >= 12) {
+                if (Renderer.zoom >= 14) {
+                    Renderer.symbol(Areas.MarineFarm);
+                }
+                if ((feature.geom.area > 0.2) || ((feature.geom.area > 0.05) && (Renderer.zoom >= 14)) || ((feature.geom.area > 0.005) && (Renderer.zoom >= 16))) {
+                    Renderer.lineVector(new LineStyle(Color.black, 4, new float[] {10, 10}));
+                }
+            }
+            break;
+        case OSPARE:
+            if (testAttribute(feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
+                Renderer.symbol(Areas.WindFarm);
+                Renderer.lineVector(new LineStyle(Color.black, 20, new float[] {40, 40}));
+                addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
+            }
+            break;
+        case RESARE:
+        case MIPARE:
+            if (Renderer.zoom >= 12) {
+                Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mline);
+                if (testAttribute(feature.type, Att.CATREA, CatREA.REA_NWAK)) {
+                    Renderer.symbol(Areas.NoWake);
+                }
+            }
+            break;
+        case PRCARE:
+            if (Renderer.zoom >= 12) {
+                Renderer.lineVector(new LineStyle(Symbols.Mline, 10, new float[] {40, 40}));
+            }
+            break;
+        case SEAARE:
+            switch ((CatSEA) getAttEnum(feature.type, Att.CATSEA)) {
+            case SEA_RECH:
+                if ((Renderer.zoom >= 10) && (name != null))
+                    if (feature.geom.prim == Pflag.LINE) {
+                        Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
+                    } else {
+                        Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
+                    }
+                break;
+            case SEA_BAY:
+                if ((Renderer.zoom >= 12) && (name != null))
+                    if (feature.geom.prim == Pflag.LINE) {
+                        Renderer.lineText(name, new Font("Arial", Font.PLAIN, 150), Color.black, -40);
+                    } else {
+                        Renderer.labelText(name, new Font("Arial", Font.PLAIN, 150), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
+                    }
+                break;
+            case SEA_SHOL:
+                if (Renderer.zoom >= 14) {
+                    if (feature.geom.prim == Pflag.AREA) {
+                        Renderer.lineVector(new LineStyle(new Color(0xc480ff), 4, new float[] {25, 25}));
+                        if (name != null) {
+                            Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
+                            Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
+                        }
+                    } else if (feature.geom.prim == Pflag.LINE) {
+                        if (name != null) {
+                            Renderer.lineText(name, new Font("Arial", Font.ITALIC, 75), Color.black, -40);
+                            Renderer.lineText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, 0);
+                        }
+                    } else {
+                        if (name != null) {
+                            Renderer.labelText(name, new Font("Arial", Font.ITALIC, 75), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -40)));
+                            Renderer.labelText("(Shoal)", new Font("Arial", Font.PLAIN, 60), Color.black, new Delta(Handle.BC));
+                        }
+                    }
+                }
+                break;
+            case SEA_GAT:
+            case SEA_NRRW:
+                addName(12, new Font("Arial", Font.PLAIN, 100));
+                break;
+            default:
+                break;
+            }
+            break;
+        case SNDWAV:
+            if (Renderer.zoom >= 12) Renderer.fillPattern(Areas.Sandwaves);
+            break;
+        case WEDKLP:
+            if (Renderer.zoom >= 12) {
+                switch ((CatWED) getAttEnum(feature.type, Att.CATWED)) {
+                case WED_KELP:
+                    if (feature.geom.prim == Pflag.AREA) {
+                        Renderer.fillPattern(Areas.KelpA);
+                    } else {
+                        Renderer.symbol(Areas.KelpS);
+                    }
+                    break;
+                default:
+                    break;
+                }
+            }
+            break;
+        case SPLARE:
+            if (Renderer.zoom >= 12) {
+                Renderer.symbol(Areas.Plane, new Scheme(Symbols.Msymb));
+                Renderer.lineSymbols(Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Symbols.Mline);
+            }
+            addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
+            break;
+        default:
+            break;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void beacons() {
+        if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))
+                || ((Renderer.zoom >= 11) && ((feature.type == Obj.BCNSAW) || hasObject(Obj.RTPBCN)))) {
+            BcnSHP shape = (BcnSHP) getAttEnum(feature.type, Att.BCNSHP);
+            if (shape == BcnSHP.BCN_UNKN)
+                shape = BcnSHP.BCN_PILE;
+            if ((shape == BcnSHP.BCN_WTHY) && (feature.type == Obj.BCNLAT)) {
+                switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
+                case LAM_PORT:
+                    Renderer.symbol(Beacons.WithyPort);
+                    break;
+                case LAM_STBD:
+                    Renderer.symbol(Beacons.WithyStarboard);
+                    break;
+                default:
+                    Renderer.symbol(Beacons.Stake, getScheme(feature.type));
+                }
+            } else if ((shape == BcnSHP.BCN_PRCH) && (feature.type == Obj.BCNLAT) && !(feature.objs.containsKey(Obj.TOPMAR))) {
+                switch ((CatLAM) getAttEnum(feature.type, Att.CATLAM)) {
+                case LAM_PORT:
+                    Renderer.symbol(Beacons.PerchPort);
+                    break;
+                case LAM_STBD:
+                    Renderer.symbol(Beacons.PerchStarboard);
+                    break;
+                default:
+                    Renderer.symbol(Beacons.Stake, getScheme(feature.type));
+                }
+            } else {
+                Renderer.symbol(Beacons.Shapes.get(shape), getScheme(feature.type));
+                if (feature.objs.containsKey(Obj.TOPMAR)) {
+                    AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
+                    if (topmap.containsKey(Att.TOPSHP)) {
+                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BeaconDelta);
+                    }
+                } else if (feature.objs.containsKey(Obj.DAYMAR)) {
+                    AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
+                    if (topmap.containsKey(Att.TOPSHP)) {
+                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BeaconDelta);
+                    }
+                }
+            }
+            if (hasObject(Obj.NOTMRK))
+                notices();
+            addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void buoys() {
+        if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))
+                || ((Renderer.zoom >= 11) && ((feature.type == Obj.BOYSAW) || hasObject(Obj.RTPBCN)))) {
+            BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
+            if (shape == BoySHP.BOY_UNKN) shape = BoySHP.BOY_PILR;
+            Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
+            if (feature.objs.containsKey(Obj.TOPMAR)) {
+                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
+                }
+            } else if (feature.objs.containsKey(Obj.DAYMAR)) {
+                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.BuoyDeltas.get(shape));
+                }
+            }
+            addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
+            Signals.addSignals();
+        }
+    }
+
+    private static void bridges() {
+        if (Renderer.zoom >= 16) {
+            double verclr, verccl, vercop, horclr;
+            AttMap atts = feature.objs.get(Obj.BRIDGE).get(0);
+            String vstr = "";
+            String hstr = "";
+            if (atts != null) {
+                if (atts.containsKey(Att.HORCLR)) {
+                    horclr = (Double) atts.get(Att.HORCLR).val;
+                    hstr = String.valueOf(horclr);
+                }
+                if (atts.containsKey(Att.VERCLR)) {
+                    verclr = (Double) atts.get(Att.VERCLR).val;
+                } else {
+                    verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
+                }
+                verccl = atts.containsKey(Att.VERCCL) ? (Double) atts.get(Att.VERCCL).val : 0;
+                vercop = atts.containsKey(Att.VERCOP) ? (Double) atts.get(Att.VERCOP).val : 0;
+                if (verclr > 0) {
+                    vstr += String.valueOf(verclr);
+                } else if (verccl > 0) {
+                    if (vercop == 0) {
+                        vstr += String.valueOf(verccl) + "/-";
+                    } else {
+                        vstr += String.valueOf(verccl) + "/" + String.valueOf(vercop);
+                    }
+                }
+                if (hstr.isEmpty() && !vstr.isEmpty()) {
+                    Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.CC));
+                } else if (!hstr.isEmpty() && !vstr.isEmpty()) {
+                    Renderer.labelText(vstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.VCLR, Color.black, Color.white, new Delta(Handle.BC));
+                    Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.TC));
+                } else if (!hstr.isEmpty() && vstr.isEmpty()) {
+                    Renderer.labelText(hstr, new Font("Arial", Font.PLAIN, 30), Color.black, LabelStyle.HCLR, Color.black, Color.white, new Delta(Handle.CC));
+                }
+            }
+        }
+    }
+
+    private static void cables() {
+        if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
+            if (feature.type == Obj.CBLSUB) {
+                Renderer.lineSymbols(Areas.Cable, 0.0, null, null, 0, Symbols.Mline);
+            } else if (feature.type == Obj.CBLOHD) {
+                AttMap atts = feature.objs.get(Obj.CBLOHD).get(0);
+                if ((atts != null) && (atts.containsKey(Att.CATCBL)) && (atts.get(Att.CATCBL).val == CatCBL.CBL_POWR)) {
+                    Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, Areas.CableFlash, 2, Color.black);
+                } else {
+                    Renderer.lineSymbols(Areas.CableDash, 0, Areas.CableDot, null, 2, Color.black);
+                }
+                if (atts != null) {
+                    if (atts.containsKey(Att.VERCLR)) {
+                        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)));
+                    } else if (atts.containsKey(Att.VERCSA)) {
+                        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)));
+                    }
+                }
+            }
+        }
+    }
+
+    private static void callpoint() {
+        if (Renderer.zoom >= 14) {
+            Symbol symb = Harbours.CallPoint2;
+            TrfTRF trf = (TrfTRF) getAttEnum(feature.type, Att.TRAFIC);
+            if (trf != TrfTRF.TRF_TWOW) {
+                symb = Harbours.CallPoint1;
+            }
+            Double orient = 0.0;
+            if ((orient = (Double) getAttVal(feature.type, Att.ORIENT)) == null) {
+                orient = 0.0;
+            }
+            Renderer.symbol(symb, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(orient))));
+            String chn;
+            if (!(chn = getAttStr(feature.type, Att.COMCHA)).isEmpty()) {
+                Renderer.labelText(("Ch." + chn), new Font("Arial", Font.PLAIN, 50), Color.black, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 50)));
+            }
+        }
+    }
+
+    private static void depths() {
+        switch (feature.type) {
+        case SOUNDG:
+            if ((Renderer.zoom >= 14) && hasAttribute(Obj.SOUNDG, Att.VALSOU)) {
+                double depth = (double) getAttVal(Obj.SOUNDG, Att.VALSOU);
+                String dstr = df.format(depth);
+                String[] tok = dstr.split("[-.]");
+                String ul = "";
+                String id = tok[0];
+                String dd = "";
+                if (tok[0].equals("")) {
+                    for (int i = 0; i < tok[1].length(); i++) {
+                        ul += "_";
+                    }
+                    id = tok[1];
+                    dd = (tok.length == 3) ? tok[2] : "";
+                } else {
+                    dd = (tok.length == 2) ? tok[1] : "";
+                }
+                Renderer.labelText(ul, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 15)));
+                Renderer.labelText(id, new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.RC, AffineTransform.getTranslateInstance(10, 0)));
+                Renderer.labelText(dd, new Font("Arial", Font.PLAIN, 20), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(15, 10)));
+            }
+            break;
+        case DEPCNT:
+            break;
+        default:
+            break;
+        }
+    }
+
+    private static void distances() {
+        if (Renderer.zoom >= 14) {
+            if (!testAttribute(Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
+                Renderer.symbol(Harbours.DistanceI);
+            } else {
+                Renderer.symbol(Harbours.DistanceU);
+            }
+            if (Renderer.zoom >= 15) {
+                AttMap atts = getAtts(Obj.DISMAR, 0);
+                if ((atts != null) && (atts.containsKey(Att.WTWDIS))) {
+                    Double dist = (Double) atts.get(Att.WTWDIS).val;
+                    String str = "";
+                    if (atts.containsKey(Att.HUNITS)) {
+                        switch ((UniHLU) getAttEnum(Obj.DISMAR, Att.HUNITS)) {
+                        case HLU_METR:
+                            str += "m ";
+                            break;
+                        case HLU_FEET:
+                            str += "ft ";
+                            break;
+                        case HLU_HMTR:
+                            str += "hm ";
+                            break;
+                        case HLU_KMTR:
+                            str += "km ";
+                            break;
+                        case HLU_SMIL:
+                            str += "M ";
+                            break;
+                        case HLU_NMIL:
+                            str += "NM ";
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                    str += String.format("%1.0f", dist);
+                    Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.CC, AffineTransform.getTranslateInstance(0, 45)));
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void floats() {
+        if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) || (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
+            switch (feature.type) {
+            case LITVES:
+                Renderer.symbol(Buoys.Super, getScheme(feature.type));
+                break;
+            case LITFLT:
+                Renderer.symbol(Buoys.Float, getScheme(feature.type));
+                break;
+            case BOYINB:
+                Renderer.symbol(Buoys.Super, getScheme(feature.type));
+                break;
+            default:
+                break;
+            }
+            if (feature.objs.containsKey(Obj.TOPMAR)) {
+                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.FloatDelta);
+                }
+            } else if (feature.objs.containsKey(Obj.DAYMAR)) {
+                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.FloatDelta);
+                }
+            }
+            addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
+            Signals.addSignals();
+        }
+    }
+
+    private static void gauges() {
+        if (Renderer.zoom >= 14) {
+            Renderer.symbol(Harbours.TideGauge);
+            addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void harbours() {
+        String name = getName();
+        switch (feature.type) {
+        case ACHBRT:
+            if (Renderer.zoom >= 14) {
+                Renderer.symbol(Harbours.Anchor, new Scheme(Symbols.Msymb));
+                if (Renderer.zoom >= 15) {
+                    Renderer.labelText(name == null ? "" : name, new Font("Arial", Font.PLAIN, 30), Symbols.Msymb, LabelStyle.RRCT, Symbols.Msymb, Color.white, new Delta(Handle.BC));
+                }
+            }
+            if (getAttVal(Obj.ACHBRT, Att.RADIUS) != null) {
+                double radius;
+                if ((radius = (Double) getAttVal(Obj.ACHBRT, Att.RADIUS)) != 0) {
+                    UniHLU units = (UniHLU) getAttEnum(Obj.ACHBRT, Att.HUNITS);
+                    if (units == UniHLU.HLU_UNKN) {
+                        units = UniHLU.HLU_METR;
+                    }
+                    Renderer.lineCircle(new LineStyle(Symbols.Mline, 4, new float[] {10, 10}, null), radius, units);
+                }
+            }
+            break;
+        case ACHARE:
+            if (Renderer.zoom >= 12) {
+                if (feature.geom.prim != Pflag.AREA) {
+                    Renderer.symbol(Harbours.Anchorage, new Scheme(Color.black));
+                } else {
+                    Renderer.symbol(Harbours.Anchorage, new Scheme(Symbols.Mline));
+                    Renderer.lineSymbols(Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Symbols.Mline);
+                }
+                addName(15, new Font("Arial", Font.BOLD, 60), Symbols.Mline, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
+                ArrayList<StsSTS> sts = (ArrayList<StsSTS>) getAttList(Obj.ACHARE, Att.STATUS);
+                if ((Renderer.zoom >= 15) && (sts.contains(StsSTS.STS_RESV))) {
+                    Renderer.labelText("Reserved", new Font("Arial", Font.PLAIN, 50), Symbols.Mline, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
+                }
+                ArrayList<CatACH> cats = (ArrayList<CatACH>) getAttList(Obj.ACHARE, Att.CATACH);
+                int dy = (cats.size() - 1) * -30;
+                for (CatACH cat : cats) {
+                    switch (cat) {
+                    case ACH_DEEP:
+                        Renderer.labelText("DW", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    case ACH_TANK:
+                        Renderer.labelText("Tanker", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    case ACH_H24P:
+                        Renderer.labelText("24h", new Font("Arial", Font.BOLD, 50), Symbols.Msymb, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    case ACH_EXPL:
+                        Renderer.symbol(Harbours.Explosives, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    case ACH_QUAR:
+                        Renderer.symbol(Harbours.Hospital, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    case ACH_SEAP:
+                        Renderer.symbol(Areas.Seaplane, new Scheme(Symbols.Msymb), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+                        dy += 60;
+                        break;
+                    default:
+                    }
+                }
+            }
+            break;
+        case BERTHS:
+            if (Renderer.zoom >= 14) {
+                Renderer.lineVector(new LineStyle(Symbols.Mline, 6, new float[] {20, 20}));
+                Renderer.labelText(name == null ? " " : name, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, LabelStyle.RRCT, Symbols.Mline, Color.white);
+            }
+            break;
+        case BUISGL:
+            if (Renderer.zoom >= 16) {
+                ArrayList<Symbol> symbols = new ArrayList<>();
+                ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(Obj.BUISGL, Att.FUNCTN);
+                for (FncFNC fnc : fncs) {
+                    symbols.add(Landmarks.Funcs.get(fnc));
+                }
+                if (feature.objs.containsKey(Obj.SMCFAC)) {
+                    ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
+                    for (CatSCF scf : scfs) {
+                        symbols.add(Facilities.Cats.get(scf));
+                    }
+                }
+                Renderer.cluster(symbols);
+            }
+            break;
+        case HRBFAC:
+            if (Renderer.zoom >= 12) {
+                ArrayList<CatHAF> cathaf = (ArrayList<CatHAF>) getAttList(Obj.HRBFAC, Att.CATHAF);
+                if (cathaf.size() == 1) {
+                    switch (cathaf.get(0)) {
+                    case HAF_MRNA:
+                        Renderer.symbol(Harbours.Marina);
+                        break;
+                    case HAF_MANF:
+                        Renderer.symbol(Harbours.MarinaNF);
+                        break;
+                    case HAF_FISH:
+                        Renderer.symbol(Harbours.Fishing);
+                        break;
+                    default:
+                        Renderer.symbol(Harbours.Harbour);
+                        break;
+                    }
+                } else {
+                    Renderer.symbol(Harbours.Harbour);
+                }
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void highways() {
+        switch (feature.type) {
+        case ROADWY:
+            ArrayList<CatROD> cat = (ArrayList<CatROD>) (getAttList(Obj.ROADWY, Att.CATROD));
+            if (cat.size() > 0) {
+                switch (cat.get(0)) {
+                case ROD_MWAY:
+                    Renderer.lineVector(new LineStyle(Color.black, 20));
+                    break;
+                case ROD_MAJR:
+                    Renderer.lineVector(new LineStyle(Color.black, 15));
+                    break;
+                case ROD_MINR:
+                    Renderer.lineVector(new LineStyle(Color.black, 10));
+                    break;
+                default:
+                    Renderer.lineVector(new LineStyle(Color.black, 5));
+                }
+            } else {
+                Renderer.lineVector(new LineStyle(Color.black, 5));
+            }
+            break;
+        case RAILWY:
+            Renderer.lineVector(new LineStyle(Color.gray, 10));
+            Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {30, 30}));
+            break;
+        default:
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void landmarks() {
+        if (!hasAttribute(Obj.LNDMRK, Att.CATLMK)
+                && (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT))
+                && hasObject(Obj.LIGHTS))
+            lights();
+        else if (Renderer.zoom >= 12) {
+            switch (feature.type) {
+            case LNDMRK:
+                ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttList(feature.type, Att.CATLMK);
+                Symbol catSym = Landmarks.Shapes.get(cats.get(0));
+                ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttList(feature.type, Att.FUNCTN);
+                Symbol fncSym = Landmarks.Funcs.get(fncs.get(0));
+                if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
+                    catSym = Landmarks.ChurchTower;
+                if (cats.get(0) == CatLMK.LMK_RADR)
+                    fncSym = Landmarks.RadioTV;
+                Renderer.symbol(catSym);
+                Renderer.symbol(fncSym);
+                break;
+            case SILTNK:
+                if (testAttribute(feature.type, Att.CATSIL, CatSIL.SIL_WTRT))
+                    Renderer.symbol(Landmarks.WaterTower);
+                break;
+            default:
+                break;
+            }
+            if (Renderer.zoom >= 15)
+                addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void points() {
+        boolean ok = false;
+        switch (feature.type) {
+        case FOGSIG:
+            if (Renderer.zoom >= 12) {
+                if (feature.objs.containsKey(Obj.LIGHTS))
+                    lights();
+                else
+                    Renderer.symbol(Harbours.Post);
+                ok = true;
+            }
+            break;
+        default:
+            if (Renderer.zoom >= 14) {
+                if (feature.objs.containsKey(Obj.LIGHTS))
+                    lights();
+                else
+                    Renderer.symbol(Harbours.Post);
+                ok = true;
+            }
+            break;
+        }
+        if (ok) {
+            if (feature.objs.containsKey(Obj.TOPMAR)) {
+                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), null);
+                }
+            } else if (feature.objs.containsKey(Obj.DAYMAR)) {
+                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), null);
+                }
+            }
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void lights() {
+        boolean ok = false;
+        switch (feature.type) {
+        case LITMAJ:
+        case LNDMRK:
+            if (Renderer.zoom >= 12) {
+                Renderer.symbol(Beacons.LightMajor);
+                ok = true;
+            }
+            break;
+        case LITMIN:
+        case LIGHTS:
+        case PILPNT:
+            if (Renderer.zoom >= 14) {
+                Renderer.symbol(Beacons.LightMinor);
+                ok = true;
+            }
+            break;
+        default:
+            break;
+        }
+        if (ok) {
+            if (feature.objs.containsKey(Obj.TOPMAR)) {
+                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.LightDelta);
+                }
+            } else if (feature.objs.containsKey(Obj.DAYMAR)) {
+                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
+                if (topmap.containsKey(Att.TOPSHP)) {
+                    Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.LightDelta);
+                }
+            }
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void marinas() {
+        if (Renderer.zoom >= 16) {
+            ArrayList<Symbol> symbols = new ArrayList<>();
+            ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
+            for (CatSCF scf : scfs) {
+                symbols.add(Facilities.Cats.get(scf));
+            }
+            Renderer.cluster(symbols);
+        }
+    }
+
+    private static void moorings() {
+        if (Renderer.zoom >= 14) {
+            switch ((CatMOR) getAttEnum(feature.type, Att.CATMOR)) {
+            case MOR_DLPN:
+                Renderer.symbol(Harbours.Dolphin);
+                break;
+            case MOR_DDPN:
+                Renderer.symbol(Harbours.DeviationDolphin);
+                break;
+            case MOR_BLRD:
+            case MOR_POST:
+                Renderer.symbol(Harbours.Bollard);
+                break;
+            case MOR_BUOY:
+                BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
+                if (shape == BoySHP.BOY_UNKN) {
+                    shape = BoySHP.BOY_SPHR;
+                }
+                Renderer.symbol(Buoys.Shapes.get(shape), getScheme(feature.type));
+                Renderer.symbol(Topmarks.TopMooring, Topmarks.BuoyDeltas.get(shape));
+                break;
+            default:
+                break;
+            }
+            Signals.addSignals();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void notices() {
+        if (Renderer.zoom >= 14) {
+            double dx = 0.0, dy = 0.0;
+            switch (feature.type) {
+            case BCNCAR:
+            case BCNISD:
+            case BCNLAT:
+            case BCNSAW:
+            case BCNSPP:
+                if (testAttribute(Obj.TOPMAR, Att.TOPSHP, TopSHP.TOP_BORD) || testAttribute(Obj.DAYMAR, Att.TOPSHP, TopSHP.TOP_BORD)) {
+                    dy = -100.0;
+                } else {
+                    dy = -45.0;
+                }
+                break;
+            case NOTMRK:
+                dy = 0.0;
+                break;
+            default:
+                return;
+            }
+            MarSYS sys = MarSYS.SYS_CEVN;
+            BnkWTW bnk = BnkWTW.BWW_UNKN;
+            AttVal<?> att = feature.atts.get(Att.MARSYS);
+            if (att != null) sys = (MarSYS) att.val;
+            att = feature.atts.get(Att.BNKWTW);
+            if (att != null) bnk = (BnkWTW) att.val;
+            ObjTab objs = feature.objs.get(Obj.NOTMRK);
+            int n = objs.size();
+            if (n > 5) {
+                Renderer.symbol(Notices.Notice, new Delta(Handle.CC, AffineTransform.getTranslateInstance(dx, dy)));
+            } else {
+                int i = 0;
+                for (AttMap atts : objs.values()) {
+                    if (atts.get(Att.MARSYS) != null) sys = ((ArrayList<MarSYS>) (atts.get(Att.MARSYS).val)).get(0);
+                    if (atts.get(Att.BNKWTW) != null) bnk = ((ArrayList<BnkWTW>) (atts.get(Att.BNKWTW).val)).get(0);
+                    CatNMK cat = CatNMK.NMK_UNKN;
+                    if (atts.get(Att.CATNMK) != null) cat = ((ArrayList<CatNMK>) (atts.get(Att.CATNMK).val)).get(0);
+                    Symbol sym = Notices.getNotice(cat, sys, bnk);
+                    Scheme sch = Notices.getScheme(sys, bnk);
+                    ArrayList<AddMRK> add = new ArrayList<>();
+                    if (atts.get(Att.ADDMRK) != null) add = (ArrayList<AddMRK>) (atts.get(Att.ADDMRK).val);
+                    Handle h = Handle.CC;
+                    double ax = 0.0;
+                    double ay = 0.0;
+                    switch (i) {
+                    case 0:
+                        if (n != 1) h = null;
+                        break;
+                    case 1:
+                        if (n <= 3) {
+                            h = Handle.RC;
+                            ax = -30;
+                            ay = dy;
+                        } else {
+                            h = Handle.BR;
+                        }
+                        break;
+                    case 2:
+                        if (n <= 3)
+                            h = Handle.LC;
+                        else
+                            h = Handle.BL;
+                        break;
+                    case 3:
+                        if (n == 4)
+                            h = Handle.TC;
+                        else
+                            h = Handle.TR;
+                        break;
+                    case 4:
+                        h = Handle.TL;
+                        break;
+                    }
+                    if (h != null) {
+                        Renderer.symbol(sym, sch, new Delta(h, AffineTransform.getTranslateInstance(dx, dy)));
+                        if (!add.isEmpty())
+                            Renderer.symbol(Notices.NoticeBoard, new Delta(Handle.BC, AffineTransform.getTranslateInstance(ax, ay - 30)));
+                    }
+                    i++;
+                }
+            }
+        }
+    }
+
+    private static void obstructions() {
+        if ((Renderer.zoom >= 12) && (feature.type == Obj.OBSTRN)) {
+            switch ((CatOBS) getAttEnum(feature.type, Att.CATOBS)) {
+            case OBS_BOOM:
+                Renderer.lineVector(new LineStyle(Color.black, 5, new float[] {20, 20}, null));
+                if (Renderer.zoom >= 15) {
+                    Renderer.lineText("Boom", new Font("Arial", Font.PLAIN, 80), Color.black, -20);
+                }
+            default:
+                break;
+            }
+        }
+        if ((Renderer.zoom >= 14) && (feature.type == Obj.UWTROC)) {
+            switch ((WatLEV) getAttEnum(feature.type, Att.WATLEV)) {
+            case LEV_CVRS:
+                Renderer.symbol(Areas.RockC);
+                break;
+            case LEV_AWSH:
+                Renderer.symbol(Areas.RockA);
+                break;
+            default:
+                Renderer.symbol(Areas.Rock);
+            }
+        } else {
+            Renderer.symbol(Areas.Rock);
+        }
+    }
+
+    private static void pipelines() {
+        if ((Renderer.zoom >= 16) && (feature.geom.length < 2)) {
+            if (feature.type == Obj.PIPSOL) {
+                Renderer.lineSymbols(Areas.Pipeline, 1.0, null, null, 0, Symbols.Mline);
+            } else if (feature.type == Obj.PIPOHD) {
+                Renderer.lineVector(new LineStyle(Color.black, 8));
+                AttMap atts = feature.atts;
+                double verclr = 0;
+                if (atts != null) {
+                    if (atts.containsKey(Att.VERCLR)) {
+                        verclr = (Double) atts.get(Att.VERCLR).val;
+                    } else {
+                        verclr = atts.containsKey(Att.VERCSA) ? (Double) atts.get(Att.VERCSA).val : 0;
+                    }
+                    if (verclr > 0) {
+                        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)));
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void platforms() {
+        ArrayList<CatOFP> cats = (ArrayList<CatOFP>) getAttList(Obj.OFSPLF, Att.CATOFP);
+        if (cats.get(0) == CatOFP.OFP_FPSO)
+            Renderer.symbol(Buoys.Storage);
+        else
+            Renderer.symbol(Landmarks.Platform);
+        addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
+        Signals.addSignals();
+    }
+
+    private static void ports() {
+        if (Renderer.zoom >= 14) {
+            if (feature.type == Obj.CRANES) {
+                if ((CatCRN) getAttEnum(feature.type, Att.CATCRN) == CatCRN.CRN_CONT)
+                    Renderer.symbol(Harbours.ContainerCrane);
+                else
+                    Renderer.symbol(Harbours.PortCrane);
+            } else if (feature.type == Obj.HULKES) {
+                Renderer.lineVector(new LineStyle(Color.black, 4, null, new Color(0xffe000)));
+                addName(15, new Font("Arial", Font.BOLD, 40));
+            }
+        }
+    }
+
+    private static void separation() {
+        switch (feature.type) {
+        case TSEZNE:
+        case TSSCRS:
+        case TSSRON:
+            if (Renderer.zoom <= 15)
+                Renderer.lineVector(new LineStyle(Symbols.Mtss));
+            else
+                Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
+            addName(10, new Font("Arial", Font.BOLD, 150), Symbols.Mline);
+            break;
+        case TSELNE:
+            Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, null, null));
+            break;
+        case TSSLPT:
+            Renderer.lineSymbols(Areas.LaneArrow, 0.5, null, null, 0, Symbols.Mtss);
+            break;
+        case TSSBND:
+            Renderer.lineVector(new LineStyle(Symbols.Mtss, 20, new float[] {40, 40}, null));
+            break;
+        case ISTZNE:
+            Renderer.lineSymbols(Areas.Restricted, 1.0, null, null, 0, Symbols.Mtss);
+            break;
+        default:
+            break;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void shoreline() {
+        CatSLC cat = (CatSLC) getAttEnum(feature.type, Att.CATSLC);
+        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
+            if ((cat != CatSLC.SLC_SWAY) && (cat != CatSLC.SLC_TWAL)) {
+                if (Renderer.zoom >= 12) {
+                    Renderer.lineVector(new LineStyle(Color.black, 10, Symbols.Yland));
+                } else {
+                    Renderer.lineVector(new LineStyle(Symbols.Yland));
+                }
+            }
+        }
+        if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.SEAMARK)) {
+            if (Renderer.zoom >= 12) {
+                switch (cat) {
+                case SLC_TWAL:
+                    WatLEV lev = (WatLEV) getAttEnum(feature.type, Att.WATLEV);
+                    if (lev == WatLEV.LEV_CVRS) {
+                        Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {40, 40}, null));
+                        if (Renderer.zoom >= 15)
+                            Renderer.lineText("(covers)", new Font("Arial", Font.PLAIN, 60), Color.black, 80);
+                    } else {
+                        Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
+                    }
+                    if (Renderer.zoom >= 15)
+                        Renderer.lineText("Training Wall", new Font("Arial", Font.PLAIN, 60), Color.black, -30);
+                    break;
+                case SLC_SWAY:
+                    Renderer.lineVector(new LineStyle(Color.black, 2, null, new Color(0xffe000)));
+                    if ((Renderer.zoom >= 16) && feature.objs.containsKey(Obj.SMCFAC)) {
+                        ArrayList<Symbol> symbols = new ArrayList<>();
+                        ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttList(Obj.SMCFAC, Att.CATSCF);
+                        for (CatSCF scf : scfs) {
+                            symbols.add(Facilities.Cats.get(scf));
+                        }
+                        Renderer.cluster(symbols);
+                    }
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void stations() {
+        if (Renderer.zoom >= 14) {
+            String str = "";
+            switch (feature.type) {
+            case SISTAT:
+                Renderer.symbol(Harbours.SignalStation);
+                str = "SS";
+                ArrayList<CatSIT> tcats = (ArrayList<CatSIT>) getAttList(Obj.SISTAT, Att.CATSIT);
+                switch (tcats.get(0)) {
+                case SIT_IPT:
+                    str += "(INT)";
+                    break;
+                case SIT_PRTE:
+                    str += "(Traffic)";
+                    break;
+                case SIT_PRTC:
+                    str += "(Port Control)";
+                    break;
+                case SIT_LOCK:
+                    str += "(Lock)";
+                    break;
+                case SIT_BRDG:
+                    str += "(Bridge)";
+                    break;
+                default:
+                    break;
+                }
+                break;
+            case SISTAW:
+                Renderer.symbol(Harbours.SignalStation);
+                str = "SS";
+                str = "SS";
+                ArrayList<CatSIW> wcats = (ArrayList<CatSIW>) getAttList(Obj.SISTAW, Att.CATSIW);
+                switch (wcats.get(0)) {
+                case SIW_STRM:
+                    str += "(Storm)";
+                    break;
+                case SIW_WTHR:
+                    str += "(Weather)";
+                    break;
+                case SIW_ICE:
+                    str += "(Ice)";
+                    break;
+                case SIW_TIDG:
+                    str = "Tide gauge";
+                    break;
+                case SIW_TIDS:
+                    str = "Tide scale";
+                    break;
+                case SIW_TIDE:
+                    str += "(Tide)";
+                    break;
+                case SIW_TSTR:
+                    str += "(Stream)";
+                    break;
+                case SIW_DNGR:
+                    str += "(Danger)";
+                    break;
+                case SIW_MILY:
+                    str += "(Firing)";
+                    break;
+                case SIW_TIME:
+                    str += "(Time)";
+                    break;
+                default:
+                    break;
+                }
+                break;
+            case RDOSTA:
+            case RTPBCN:
+                Renderer.symbol(Harbours.SignalStation);
+                Renderer.symbol(Beacons.RadarStation);
+                break;
+            case RADRFL:
+                Renderer.symbol(Topmarks.RadarReflector);
+                break;
+            case RADSTA:
+                Renderer.symbol(Harbours.SignalStation);
+                Renderer.symbol(Beacons.RadarStation);
+                Renderer.labelText("Ra", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
+                break;
+            case PILBOP:
+                Renderer.symbol(Harbours.Pilot);
+                addName(15, new Font("Arial", Font.BOLD, 40), Symbols.Msymb, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, -40)));
+                CatPIL cat = (CatPIL) getAttEnum(feature.type, Att.CATPIL);
+                if (cat == CatPIL.PIL_HELI) {
+                    Renderer.labelText("H", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
+                }
+                break;
+            case CGUSTA:
+                Renderer.symbol(Harbours.SignalStation);
+                str = "CG";
+                if (feature.objs.containsKey(Obj.RSCSTA)) Renderer.symbol(Harbours.Rescue, new Delta(Handle.CC, AffineTransform.getTranslateInstance(130, 0)));
+                break;
+            case RSCSTA:
+                Renderer.symbol(Harbours.Rescue);
+                break;
+            default:
+                break;
+            }
+            if ((Renderer.zoom >= 15) && !str.isEmpty()) {
+                Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.LC, AffineTransform.getTranslateInstance(40, 0)));
+            }
+            Signals.addSignals();
+        }
+    }
+
+    private static void transits() {
+        if (Renderer.zoom >= 14) {
+            if (feature.type == Obj.RECTRC) Renderer.lineVector(new LineStyle(Color.black, 10, null, null));
+            else if (feature.type == Obj.NAVLNE) Renderer.lineVector(new LineStyle(Color.black, 10, new float[] {25, 25}, null));
+        }
+        if (Renderer.zoom >= 15) {
+            String str = "";
+            String name = getName();
+            if (name != null)
+                str += name + " ";
+            Double ort;
+            if ((ort = (Double) getAttVal(feature.type, Att.ORIENT)) != null) {
+                str += df.format(ort) + "º";
+                if (!str.isEmpty())
+                    Renderer.lineText(str, new Font("Arial", Font.PLAIN, 80), Color.black, -20);
+            }
+        }
+    }
+
+    private static void waterways() {
+        Renderer.lineVector(new LineStyle(Symbols.Bwater, 20, (feature.geom.prim == Pflag.AREA) ? Symbols.Bwater : null));
+    }
+
+    private static void wrecks() {
+        if (Renderer.zoom >= 14) {
+            switch ((CatWRK) getAttEnum(feature.type, Att.CATWRK)) {
+            case WRK_DNGR:
+            case WRK_MSTS:
+                Renderer.symbol(Areas.WreckD);
+                break;
+            case WRK_HULS:
+                Renderer.symbol(Areas.WreckS);
+                break;
+            default:
+                Renderer.symbol(Areas.WreckND);
+            }
+        }
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/render/Signals.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32394)
@@ -12,675 +12,684 @@
 import java.awt.Color;
 import java.awt.Font;
-import java.awt.geom.*;
+import java.awt.geom.AffineTransform;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.EnumMap;
 
+import s57.S57att.Att;
+import s57.S57map.AttMap;
+import s57.S57map.ObjTab;
+import s57.S57obj.Obj;
+import s57.S57val.BoySHP;
+import s57.S57val.CatFOG;
 import s57.S57val.CatLIT;
+import s57.S57val.CatROS;
+import s57.S57val.CatRTB;
 import s57.S57val.ColCOL;
-import s57.S57att.*;
-import s57.S57obj.*;
-import s57.S57val.*;
-import s57.S57map.*;
+import s57.S57val.LitCHR;
 import symbols.Beacons;
 import symbols.Symbols;
+import symbols.Symbols.Delta;
+import symbols.Symbols.Handle;
+import symbols.Symbols.Scheme;
 import symbols.Topmarks;
-import symbols.Symbols.*;
-
-public class Signals extends Rules{
-
-	static final EnumMap<ColCOL, Color> LightColours = new EnumMap<>(ColCOL.class);
-	static {
-		LightColours.put(ColCOL.COL_WHT, new Color(0xffff00));
-		LightColours.put(ColCOL.COL_RED, new Color(0xff0000));
-		LightColours.put(ColCOL.COL_GRN, new Color(0x00ff00));
-		LightColours.put(ColCOL.COL_BLU, new Color(0x0000ff));
-		LightColours.put(ColCOL.COL_YEL, new Color(0xffff00));
-		LightColours.put(ColCOL.COL_AMB, new Color(0xffc200));
-		LightColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
-		LightColours.put(ColCOL.COL_ORG, Color.orange);
-		LightColours.put(ColCOL.COL_MAG, Color.magenta);
-	}
-
-	static final EnumMap<ColCOL, String> LightLetters = new EnumMap<>(ColCOL.class);
-	static {
-		LightLetters.put(ColCOL.COL_WHT, "W");
-		LightLetters.put(ColCOL.COL_RED, "R");
-		LightLetters.put(ColCOL.COL_GRN, "G");
-		LightLetters.put(ColCOL.COL_BLU, "Bu");
-		LightLetters.put(ColCOL.COL_YEL, "Y");
-		LightLetters.put(ColCOL.COL_AMB, "Am");
-		LightLetters.put(ColCOL.COL_VIO, "Vi");
-		LightLetters.put(ColCOL.COL_ORG, "Or");
-	}
-
-	static final EnumMap<LitCHR, String> LightCharacters = new EnumMap<>(LitCHR.class);
-	static {
-		LightCharacters.put(LitCHR.CHR_F, "F");
-		LightCharacters.put(LitCHR.CHR_FL, "Fl");
-		LightCharacters.put(LitCHR.CHR_LFL, "LFl");
-		LightCharacters.put(LitCHR.CHR_Q, "Q");
-		LightCharacters.put(LitCHR.CHR_VQ, "VQ");
-		LightCharacters.put(LitCHR.CHR_UQ, "UQ");
-		LightCharacters.put(LitCHR.CHR_ISO, "Iso");
-		LightCharacters.put(LitCHR.CHR_OC, "Oc");
-		LightCharacters.put(LitCHR.CHR_IQ, "IQ");
-		LightCharacters.put(LitCHR.CHR_IVQ, "IVQ");
-		LightCharacters.put(LitCHR.CHR_IUQ, "IUQ");
-		LightCharacters.put(LitCHR.CHR_MO, "Mo");
-		LightCharacters.put(LitCHR.CHR_FFL, "FFl");
-		LightCharacters.put(LitCHR.CHR_FLLFL, "FlLFl");
-		LightCharacters.put(LitCHR.CHR_OCFL, "OcFl");
-		LightCharacters.put(LitCHR.CHR_FLFL, "FLFl");
-		LightCharacters.put(LitCHR.CHR_ALOC, "Al.Oc");
-		LightCharacters.put(LitCHR.CHR_ALLFL, "Al.LFl");
-		LightCharacters.put(LitCHR.CHR_ALFL, "Al.Fl");
-		LightCharacters.put(LitCHR.CHR_ALGR, "Al.Gr");
-		LightCharacters.put(LitCHR.CHR_QLFL, "Q+LFl");
-		LightCharacters.put(LitCHR.CHR_VQLFL, "VQ+LFl");
-		LightCharacters.put(LitCHR.CHR_UQLFL, "UQ+LFl");
-		LightCharacters.put(LitCHR.CHR_AL, "Al");
-		LightCharacters.put(LitCHR.CHR_ALFFL, "Al.FFl");
-	}
-	
-	static final EnumMap<CatFOG, String> fogSignals = new EnumMap<>(CatFOG.class);
-	static {
-		fogSignals.put(CatFOG.FOG_EXPL, "Explos");
-		fogSignals.put(CatFOG.FOG_DIA, "Dia");
-		fogSignals.put(CatFOG.FOG_SIRN, "Siren");
-		fogSignals.put(CatFOG.FOG_NAUT, "Horn");
-		fogSignals.put(CatFOG.FOG_REED, "Horn");
-		fogSignals.put(CatFOG.FOG_TYPH, "Horn");
-		fogSignals.put(CatFOG.FOG_BELL, "Bell");
-		fogSignals.put(CatFOG.FOG_WHIS, "Whis");
-		fogSignals.put(CatFOG.FOG_GONG, "Gong");
-		fogSignals.put(CatFOG.FOG_HORN, "Horn");
-	}
-
-	static final DecimalFormat df = new DecimalFormat("#.#");
-	
-	public static void addSignals() {
-	  if (feature.objs.containsKey(Obj.RADRFL)) reflectors();
-	  if (feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
-	  if (feature.objs.containsKey(Obj.RTPBCN)) radarStations();
-	  if (feature.objs.containsKey(Obj.RADSTA)) radarStations();
-	  if (feature.objs.containsKey(Obj.RDOSTA)) radioStations();
-	  if (feature.objs.containsKey(Obj.LIGHTS)) lights();
-	}
-
-	public static void reflectors() {
-		if (Renderer.zoom >= 14) {
-			switch (feature.type) {
-			case BCNLAT:
-			case BCNCAR:
-			case BCNISD:
-			case BCNSAW:
-			case BCNSPP:
-				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -140)));
-				} else {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -80)));
-				}
-				break;
-			case LITFLT:
-			case LITVES:
-			case BOYINB:
-				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -110)));
-				} else {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -60)));
-				}
-				break;
-			case LITMAJ:
-			case LITMIN:
-				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
-				} else {
-					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -30)));
-				}
-				break;
-			case BOYLAT:
-			case BOYCAR:
-			case BOYISD:
-			case BOYSAW:
-			case BOYSPP:
-				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
-					if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
-						Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(50, -160)));
-					} else {
-						Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(25, -80)));
-					}
-				} else {
-					if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
-						Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(30, -100)));
-					} else {
-						Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(10, -50)));
-					}
-				}
-				break;
-			default:
-				break;
-			}
-		}
-	}
-	
-	public static void fogSignals() {
-		if (Renderer.zoom >= 11)
-			Renderer.symbol(Beacons.FogSignal);
-		if (Renderer.zoom >= 15) {
-			AttMap atts = feature.objs.get(Obj.FOGSIG).get(0);
-			if (atts != null) {
-				String str = "";
-				if (atts.containsKey(Att.CATFOG)) {
-					str += fogSignals.get(((ArrayList<?>) (atts.get(Att.CATFOG).val)).get(0));
-				}
-				if (atts.containsKey(Att.SIGGRP)) {
-					str += "(" + atts.get(Att.SIGGRP).val + ")";
-				} else {
-					str += " ";
-				}
-				if (atts.containsKey(Att.SIGPER)) {
-					str += df.format(atts.get(Att.SIGPER).val) + "s";
-				}
-				if (atts.containsKey(Att.VALMXR)) {
-					str += df.format(atts.get(Att.VALMXR).val) + "M";
-				}
-				if (!str.isEmpty()) {
-					Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-60, -30)));
-				}
-			}
-		}
-	}
-
-	public static void radarStations() {
-		if (Renderer.zoom >= 11)
-			Renderer.symbol(Beacons.RadarStation);
-		if (Renderer.zoom >= 15) {
-			String bstr = "";
-			CatRTB cat = (CatRTB) getAttEnum(Obj.RTPBCN, Att.CATRTB);
-			String wal = getAttStr(Obj.RTPBCN, Att.RADWAL);
-			switch (cat) {
-			case RTB_RAMK:
-				bstr += " Ramark";
-				break;
-			case RTB_RACN:
-				bstr += " Racon";
-				String astr = getAttStr(Obj.RTPBCN, Att.SIGGRP);
-				if (!astr.isEmpty()) {
-					bstr += "(" + astr + ")";
-				}
-				Double per = (Double) getAttVal(Obj.RTPBCN, Att.SIGPER);
-				Double mxr = (Double) getAttVal(Obj.RTPBCN, Att.VALMXR);
-				if ((per != null) || (mxr != null)) {
-					bstr += (astr.isEmpty() ? " " : "");
-					if (per != null)
-						bstr += (per != 0) ? per.toString() + "s" : "";
-					if (mxr != null)
-						bstr += (mxr != 0) ? mxr.toString() + "M" : "";
-				}
-				break;
-			default:
-				break;
-			}
-			if (!wal.isEmpty()) {
-				switch (wal) {
-				case "0.03-X":
-					bstr += "(3cm)";
-					break;
-				case "0.10-S":
-					bstr += "(10cm)";
-					break;
-				}
-			}
-			if (!bstr.isEmpty()) {
-				Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
-			}
-		}
-	}
-
-	@SuppressWarnings("unchecked")
-	public static void radioStations() {
-		boolean vais = false;
-		String bstr = "";
-		if (Renderer.zoom >= 11) {
-			ArrayList<CatROS> cats = (ArrayList<CatROS>) getAttList(Obj.RDOSTA, Att.CATROS);
-			for (CatROS ros : cats) {
-				switch (ros) {
-				case ROS_OMNI:
-					bstr += " RC";
-					break;
-				case ROS_DIRL:
-					bstr += " RD";
-					break;
-				case ROS_ROTP:
-					bstr += " RW";
-					break;
-				case ROS_CNSL:
-					bstr += " Consol";
-					break;
-				case ROS_RDF:
-					bstr += " RG";
-					break;
-				case ROS_QTA:
-					bstr += " R";
-					break;
-				case ROS_AERO:
-					bstr += " AeroRC";
-					break;
-				case ROS_DECA:
-					bstr += " Decca";
-					break;
-				case ROS_LORN:
-					bstr += " Loran";
-					break;
-				case ROS_DGPS:
-					bstr += " DGPS";
-					break;
-				case ROS_TORN:
-					bstr += " Toran";
-					break;
-				case ROS_OMGA:
-					bstr += " Omega";
-					break;
-				case ROS_SYLD:
-					bstr += " Syledis";
-					break;
-				case ROS_CHKA:
-					bstr += " Chiaka";
-					break;
-				case ROS_PCOM:
-				case ROS_COMB:
-				case ROS_FACS:
-				case ROS_TIME:
-					break;
-				case ROS_PAIS:
-				case ROS_SAIS:
-					bstr += " AIS";
-					break;
-				case ROS_VAIS:
-					vais = true;
-					break;
-				case ROS_VANC:
-					vais = true;
-					Renderer.symbol(Topmarks.TopNorth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VASC:
-					vais = true;
-					Renderer.symbol(Topmarks.TopSouth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VAEC:
-					vais = true;
-					Renderer.symbol(Topmarks.TopEast, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VAWC:
-					vais = true;
-					Renderer.symbol(Topmarks.TopWest, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VAPL:
-					vais = true;
-					Renderer.symbol(Topmarks.TopCan, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VASL:
-					vais = true;
-					Renderer.symbol(Topmarks.TopCone, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VAID:
-					vais = true;
-					Renderer.symbol(Topmarks.TopIsol, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VASW:
-					vais = true;
-					Renderer.symbol(Topmarks.TopSphere, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VASP:
-					vais = true;
-					Renderer.symbol(Topmarks.TopX, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				case ROS_VAWK:
-					vais = true;
-					Renderer.symbol(Topmarks.TopCross, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
-					break;
-				default:
-					break;
-				}
-			}
-			if (!vais) {
-				Renderer.symbol(Beacons.RadarStation);
-			}
-		}
-		if (Renderer.zoom >= 15) {
-			if (vais) {
-				Renderer.labelText("V-AIS", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 70)));
-			}
-			if (!bstr.isEmpty()) {
-				Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -110)));
-			}
-		}
-	}
-
-	class Sect {
-    int dir;
-    LitCHR chr;
-    ColCOL col;
-    ColCOL alt;
-    String grp;
-    double per;
-    double rng;
-	}
-	
-	@SuppressWarnings("unchecked")
-	public static void lights() {
-		Enum<ColCOL> col = null;
-		Enum<ColCOL> tcol = null;
-		ObjTab lights = feature.objs.get(Obj.LIGHTS);
-		for (AttMap atts : lights.values()) {
-			if (atts.containsKey(Att.COLOUR)) {
-				ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-				if (cols.size() == 1) {
-					tcol = cols.get(0);
-					if (col == null) {
-						col = tcol;
-					} else if (tcol != col) {
-						col = ColCOL.COL_MAG;
-						break;
-					}
-				} else {
-					col = ColCOL.COL_MAG;
-					break;
-				}
-			}
-		}
-		Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
-		if (Renderer.zoom >= 12) {
-			String str = "";
-			if (lights.get(1) != null) {
-				for (AttMap atts : lights.values()) {
-					Enum<ColCOL> col1 = null;
-					Enum<ColCOL> col2 = null;
-					double radius = 0.2;
-					double s1 = 361;
-					double s2 = 361;
-					Double dir = null;
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-						col1 = cols.get(0);
-						if (cols.size() > 1)
-							col2 = cols.get(1);
-					} else {
-						continue;
-					}
-					if (atts.containsKey(Att.LITRAD)) {
-						radius = (Double) atts.get(Att.LITRAD).val;
-					}
-					if (atts.containsKey(Att.CATLIT)) {
-						ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
-						if (cats.contains(CatLIT.LIT_DIR)) {
-							if (atts.containsKey(Att.ORIENT)) {
-								dir = (Double) atts.get(Att.ORIENT).val;
-								s1 = ((dir - 4) + 360) % 360;
-								s2 = (dir + 4) % 360;
-								for (AttMap satts : lights.values()) {
-									double srad = 0.2;
-									double ss1 = 361;
-									double ss2 = 361;
-									Double sdir = null;
-									if (satts == atts)
-										continue;
-									if (satts.containsKey(Att.LITRAD)) {
-										srad = (Double) satts.get(Att.LITRAD).val;
-									}
-									if (srad == radius) {
-										ArrayList<CatLIT> scats = (satts.containsKey(Att.CATLIT)) ? (ArrayList<CatLIT>) satts.get(Att.CATLIT).val : new ArrayList<CatLIT>();
-										if (scats.contains(CatLIT.LIT_DIR)) {
-											if (satts.containsKey(Att.ORIENT)) {
-												sdir = (Double) satts.get(Att.ORIENT).val;
-												ss1 = sdir;
-												ss2 = sdir;
-											}
-										} else {
-											if (satts.containsKey(Att.SECTR1)) {
-												ss1 = (Double) satts.get(Att.SECTR1).val;
-											}
-											if (satts.containsKey(Att.SECTR2)) {
-												ss2 = (Double) satts.get(Att.SECTR2).val;
-											}
-										}
-										if ((ss1 > 360) || (ss2 > 360))
-											continue;
-										if (sdir != null) {
-											if (((dir - sdir + 360) % 360) < 8) {
-												s1 = ((((sdir > dir) ? 360 : 0) + sdir + dir) / 2) % 360;
-											}
-											if (((sdir - dir + 360) % 360) < 8) {
-												s2 = ((((dir > sdir) ? 360 : 0) + sdir + dir) / 2) % 360;
-											}
-										} else {
-											if (((dir - ss2 + 360) % 360) < 4) {
-												s1 = ss2;
-											}
-											if (((ss1 - dir + 360) % 360) < 4) {
-												s2 = ss1;
-											}
-										}
-									}
-								}
-							}
-						}
-					}
-					if ((s1 > 360) && atts.containsKey(Att.SECTR1)) {
-						s1 = (Double) atts.get(Att.SECTR1).val;
-					} else if (dir == null) {
-						continue;
-					}
-					if ((s2 > 360) && atts.containsKey(Att.SECTR2)) {
-						s2 = (Double) atts.get(Att.SECTR2).val;
-					} else if (dir == null) {
-						continue;
-					}
-					str = "";
-					if (atts.containsKey(Att.LITCHR)) {
-						str += LightCharacters.get(((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0));
-					}
-					if (atts.containsKey(Att.SIGGRP)) {
-						str += "(" + atts.get(Att.SIGGRP).val + ")";
-					} else if (!str.isEmpty()) {
-						str += ".";
-					}
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-						str += LightLetters.get(cols.get(0));
-						if (cols.size() > 1)
-							str += LightLetters.get(cols.get(1));
-					}
-					if (atts.containsKey(Att.SIGPER)) {
-						str += "." + df.format(atts.get(Att.SIGPER).val) + "s";
-					}
-					if ((s1 <= 360) && (s2 <= 360) && (s1 != s2))
-						Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
-				}
-				if (Renderer.zoom >= 15) {
-					class LitSect {
-						boolean dir;
-						LitCHR chr;
-						ColCOL col;
-						String grp;
-						double per;
-						double rng;
-						double hgt;
-					}
-					ArrayList<LitSect> litatts = new ArrayList<>();
-					for (AttMap atts : lights.values()) {
-						LitSect sect = new LitSect();
-						sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
-						sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
-						switch (sect.chr) {
-						case CHR_AL:
-							sect.chr = LitCHR.CHR_F;
-							break;
-						case CHR_ALOC:
-							sect.chr = LitCHR.CHR_OC;
-							break;
-						case CHR_ALLFL:
-							sect.chr = LitCHR.CHR_LFL;
-							break;
-						case CHR_ALFL:
-							sect.chr = LitCHR.CHR_FL;
-							break;
-						case CHR_ALFFL:
-							sect.chr = LitCHR.CHR_FFL;
-							break;
-						default:
-							break;
-						}
-						sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
-						sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
-						sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
-						sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
-						ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
-						sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
-						if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
-							litatts.add(sect);
-					}
-					ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
-					for (LitSect lit : litatts) {
-						boolean found = false;
-						for (ArrayList<LitSect> group : groupings) {
-							LitSect mem = group.get(0);
-							if ((lit.dir == mem.dir) && (lit.chr == mem.chr) && (lit.grp.equals(mem.grp)) && (lit.per == mem.per) && (lit.hgt == mem.hgt)) {
-								group.add(lit);
-								found = true;
-							}
-						}
-						if (!found) {
-							ArrayList<LitSect> tmp = new ArrayList<>();
-							tmp.add(lit);
-							groupings.add(tmp);
-						}
-					}
-					for (boolean moved = true; moved;) {
-						moved = false;
-						for (int i = 0; i < groupings.size() - 1; i++) {
-							if (groupings.get(i).size() < groupings.get(i + 1).size()) {
-								ArrayList<LitSect> tmp = groupings.remove(i);
-								groupings.add(i + 1, tmp);
-								moved = true;
-							}
-						}
-					}
-					class ColRng {
-						ColCOL col;
-						double rng;
-
-						public ColRng(ColCOL c, double r) {
-							col = c;
-							rng = r;
-						}
-					}
-					int y = -30;
-					for (ArrayList<LitSect> group : groupings) {
-						ArrayList<ColRng> colrng = new ArrayList<>();
-						for (LitSect lit : group) {
-							boolean found = false;
-							for (ColRng cr : colrng) {
-								if (cr.col == lit.col) {
-									if (lit.rng > cr.rng) {
-										cr.rng = lit.rng;
-									}
-									found = true;
-								}
-							}
-							if (!found) {
-								colrng.add(new ColRng(lit.col, lit.rng));
-							}
-						}
-						for (boolean moved = true; moved;) {
-							moved = false;
-							for (int i = 0; i < colrng.size() - 1; i++) {
-								if (colrng.get(i).rng < colrng.get(i + 1).rng) {
-									ColRng tmp = colrng.remove(i);
-									colrng.add(i + 1, tmp);
-									moved = true;
-								}
-							}
-						}
-						LitSect tmp = group.get(0);
-						str = (tmp.dir) ? "Dir" : "";
-						str += LightCharacters.get(tmp.chr);
-						if (!tmp.grp.isEmpty())
-							str += "(" + tmp.grp + ")";
-						else
-							str += ".";
-						for (ColRng cr : colrng) {
-							str += LightLetters.get(cr.col);
-						}
-						if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
-							str += ".";
-						if (tmp.per > 0)
-							str += df.format(tmp.per) + "s";
-						if (tmp.hgt > 0)
-							str += df.format(tmp.hgt) + "m";
-						if (colrng.get(0).rng > 0)
-							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";
-						Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
-						y += 40;
-						str = "";
-					}
-				}
-			} else {
-				if (Renderer.zoom >= 15) {
-					AttMap atts = lights.get(0);
-					ArrayList<CatLIT> cats = new ArrayList<>();
-					if (atts.containsKey(Att.CATLIT)) {
-						cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
-					}
-					str = (cats.contains(CatLIT.LIT_DIR)) ? "Dir" : "";
-					str += (atts.containsKey(Att.MLTYLT)) ? atts.get(Att.MLTYLT).val : "";
-					if (atts.containsKey(Att.LITCHR)) {
-						LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
-						if (atts.containsKey(Att.SIGGRP)) {
-							String grp = (String) atts.get(Att.SIGGRP).val;
-							switch (chr) {
-							case CHR_QLFL:
-								str += String.format("Q(%s)+LFl", grp);
-								break;
-							case CHR_VQLFL:
-								str += String.format("VQ(%s)+LFl", grp);
-								break;
-							case CHR_UQLFL:
-								str += String.format("UQ(%s)+LFl", grp);
-								break;
-							default:
-								str += String.format("%s(%s)", LightCharacters.get(chr), grp);
-								break;
-							}
-						} else {
-							str += LightCharacters.get(chr);
-						}
-					}
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
-						if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
-							if (!str.isEmpty() && !str.endsWith(")")) {
-								str += ".";
-							}
-							for (ColCOL acol : cols) {
-								str += LightLetters.get(acol);
-							}
-						}
-					}
-					str += (cats.contains(CatLIT.LIT_VERT)) ? "(vert)" : "";
-					str += (cats.contains(CatLIT.LIT_HORI)) ? "(hor)" : "";
-					str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
-					str += (atts.containsKey(Att.SIGPER)) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
-					str += (atts.containsKey(Att.HEIGHT)) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
-					str += (atts.containsKey(Att.VALNMR)) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
-					str += (cats.contains(CatLIT.LIT_FRNT)) ? "(Front)" : "";
-					str += (cats.contains(CatLIT.LIT_REAR)) ? "(Rear)" : "";
-					str += (cats.contains(CatLIT.LIT_UPPR)) ? "(Upper)" : "";
-					str += (cats.contains(CatLIT.LIT_LOWR)) ? "(Lower)" : "";
-					Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
-				}
-			}
-		}
-	}
+
+public class Signals extends Rules {
+
+    static final EnumMap<ColCOL, Color> LightColours = new EnumMap<>(ColCOL.class);
+    static {
+        LightColours.put(ColCOL.COL_WHT, new Color(0xffff00));
+        LightColours.put(ColCOL.COL_RED, new Color(0xff0000));
+        LightColours.put(ColCOL.COL_GRN, new Color(0x00ff00));
+        LightColours.put(ColCOL.COL_BLU, new Color(0x0000ff));
+        LightColours.put(ColCOL.COL_YEL, new Color(0xffff00));
+        LightColours.put(ColCOL.COL_AMB, new Color(0xffc200));
+        LightColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
+        LightColours.put(ColCOL.COL_ORG, Color.orange);
+        LightColours.put(ColCOL.COL_MAG, Color.magenta);
+    }
+
+    static final EnumMap<ColCOL, String> LightLetters = new EnumMap<>(ColCOL.class);
+    static {
+        LightLetters.put(ColCOL.COL_WHT, "W");
+        LightLetters.put(ColCOL.COL_RED, "R");
+        LightLetters.put(ColCOL.COL_GRN, "G");
+        LightLetters.put(ColCOL.COL_BLU, "Bu");
+        LightLetters.put(ColCOL.COL_YEL, "Y");
+        LightLetters.put(ColCOL.COL_AMB, "Am");
+        LightLetters.put(ColCOL.COL_VIO, "Vi");
+        LightLetters.put(ColCOL.COL_ORG, "Or");
+    }
+
+    static final EnumMap<LitCHR, String> LightCharacters = new EnumMap<>(LitCHR.class);
+    static {
+        LightCharacters.put(LitCHR.CHR_F, "F");
+        LightCharacters.put(LitCHR.CHR_FL, "Fl");
+        LightCharacters.put(LitCHR.CHR_LFL, "LFl");
+        LightCharacters.put(LitCHR.CHR_Q, "Q");
+        LightCharacters.put(LitCHR.CHR_VQ, "VQ");
+        LightCharacters.put(LitCHR.CHR_UQ, "UQ");
+        LightCharacters.put(LitCHR.CHR_ISO, "Iso");
+        LightCharacters.put(LitCHR.CHR_OC, "Oc");
+        LightCharacters.put(LitCHR.CHR_IQ, "IQ");
+        LightCharacters.put(LitCHR.CHR_IVQ, "IVQ");
+        LightCharacters.put(LitCHR.CHR_IUQ, "IUQ");
+        LightCharacters.put(LitCHR.CHR_MO, "Mo");
+        LightCharacters.put(LitCHR.CHR_FFL, "FFl");
+        LightCharacters.put(LitCHR.CHR_FLLFL, "FlLFl");
+        LightCharacters.put(LitCHR.CHR_OCFL, "OcFl");
+        LightCharacters.put(LitCHR.CHR_FLFL, "FLFl");
+        LightCharacters.put(LitCHR.CHR_ALOC, "Al.Oc");
+        LightCharacters.put(LitCHR.CHR_ALLFL, "Al.LFl");
+        LightCharacters.put(LitCHR.CHR_ALFL, "Al.Fl");
+        LightCharacters.put(LitCHR.CHR_ALGR, "Al.Gr");
+        LightCharacters.put(LitCHR.CHR_QLFL, "Q+LFl");
+        LightCharacters.put(LitCHR.CHR_VQLFL, "VQ+LFl");
+        LightCharacters.put(LitCHR.CHR_UQLFL, "UQ+LFl");
+        LightCharacters.put(LitCHR.CHR_AL, "Al");
+        LightCharacters.put(LitCHR.CHR_ALFFL, "Al.FFl");
+    }
+
+    static final EnumMap<CatFOG, String> fogSignals = new EnumMap<>(CatFOG.class);
+    static {
+        fogSignals.put(CatFOG.FOG_EXPL, "Explos");
+        fogSignals.put(CatFOG.FOG_DIA, "Dia");
+        fogSignals.put(CatFOG.FOG_SIRN, "Siren");
+        fogSignals.put(CatFOG.FOG_NAUT, "Horn");
+        fogSignals.put(CatFOG.FOG_REED, "Horn");
+        fogSignals.put(CatFOG.FOG_TYPH, "Horn");
+        fogSignals.put(CatFOG.FOG_BELL, "Bell");
+        fogSignals.put(CatFOG.FOG_WHIS, "Whis");
+        fogSignals.put(CatFOG.FOG_GONG, "Gong");
+        fogSignals.put(CatFOG.FOG_HORN, "Horn");
+    }
+
+    static final DecimalFormat df = new DecimalFormat("#.#");
+
+    public static void addSignals() {
+        if (feature.objs.containsKey(Obj.RADRFL)) reflectors();
+        if (feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
+        if (feature.objs.containsKey(Obj.RTPBCN)) radarStations();
+        if (feature.objs.containsKey(Obj.RADSTA)) radarStations();
+        if (feature.objs.containsKey(Obj.RDOSTA)) radioStations();
+        if (feature.objs.containsKey(Obj.LIGHTS)) lights();
+    }
+
+    public static void reflectors() {
+        if (Renderer.zoom >= 14) {
+            switch (feature.type) {
+            case BCNLAT:
+            case BCNCAR:
+            case BCNISD:
+            case BCNSAW:
+            case BCNSPP:
+                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -140)));
+                } else {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -80)));
+                }
+                break;
+            case LITFLT:
+            case LITVES:
+            case BOYINB:
+                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -110)));
+                } else {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -60)));
+                }
+                break;
+            case LITMAJ:
+            case LITMIN:
+                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
+                } else {
+                    Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -30)));
+                }
+                break;
+            case BOYLAT:
+            case BOYCAR:
+            case BOYISD:
+            case BOYSAW:
+            case BOYSPP:
+                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
+                    if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
+                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(50, -160)));
+                    } else {
+                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(25, -80)));
+                    }
+                } else {
+                    if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
+                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(30, -100)));
+                    } else {
+                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(10, -50)));
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    public static void fogSignals() {
+        if (Renderer.zoom >= 11)
+            Renderer.symbol(Beacons.FogSignal);
+        if (Renderer.zoom >= 15) {
+            AttMap atts = feature.objs.get(Obj.FOGSIG).get(0);
+            if (atts != null) {
+                String str = "";
+                if (atts.containsKey(Att.CATFOG)) {
+                    str += fogSignals.get(((ArrayList<?>) (atts.get(Att.CATFOG).val)).get(0));
+                }
+                if (atts.containsKey(Att.SIGGRP)) {
+                    str += "(" + atts.get(Att.SIGGRP).val + ")";
+                } else {
+                    str += " ";
+                }
+                if (atts.containsKey(Att.SIGPER)) {
+                    str += df.format(atts.get(Att.SIGPER).val) + "s";
+                }
+                if (atts.containsKey(Att.VALMXR)) {
+                    str += df.format(atts.get(Att.VALMXR).val) + "M";
+                }
+                if (!str.isEmpty()) {
+                    Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-60, -30)));
+                }
+            }
+        }
+    }
+
+    public static void radarStations() {
+        if (Renderer.zoom >= 11)
+            Renderer.symbol(Beacons.RadarStation);
+        if (Renderer.zoom >= 15) {
+            String bstr = "";
+            CatRTB cat = (CatRTB) getAttEnum(Obj.RTPBCN, Att.CATRTB);
+            String wal = getAttStr(Obj.RTPBCN, Att.RADWAL);
+            switch (cat) {
+            case RTB_RAMK:
+                bstr += " Ramark";
+                break;
+            case RTB_RACN:
+                bstr += " Racon";
+                String astr = getAttStr(Obj.RTPBCN, Att.SIGGRP);
+                if (!astr.isEmpty()) {
+                    bstr += "(" + astr + ")";
+                }
+                Double per = (Double) getAttVal(Obj.RTPBCN, Att.SIGPER);
+                Double mxr = (Double) getAttVal(Obj.RTPBCN, Att.VALMXR);
+                if ((per != null) || (mxr != null)) {
+                    bstr += (astr.isEmpty() ? " " : "");
+                    if (per != null)
+                        bstr += (per != 0) ? per.toString() + "s" : "";
+                    if (mxr != null)
+                        bstr += (mxr != 0) ? mxr.toString() + "M" : "";
+                }
+                break;
+            default:
+                break;
+            }
+            if (!wal.isEmpty()) {
+                switch (wal) {
+                case "0.03-X":
+                    bstr += "(3cm)";
+                    break;
+                case "0.10-S":
+                    bstr += "(10cm)";
+                    break;
+                }
+            }
+            if (!bstr.isEmpty()) {
+                Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void radioStations() {
+        boolean vais = false;
+        String bstr = "";
+        if (Renderer.zoom >= 11) {
+            ArrayList<CatROS> cats = (ArrayList<CatROS>) getAttList(Obj.RDOSTA, Att.CATROS);
+            for (CatROS ros : cats) {
+                switch (ros) {
+                case ROS_OMNI:
+                    bstr += " RC";
+                    break;
+                case ROS_DIRL:
+                    bstr += " RD";
+                    break;
+                case ROS_ROTP:
+                    bstr += " RW";
+                    break;
+                case ROS_CNSL:
+                    bstr += " Consol";
+                    break;
+                case ROS_RDF:
+                    bstr += " RG";
+                    break;
+                case ROS_QTA:
+                    bstr += " R";
+                    break;
+                case ROS_AERO:
+                    bstr += " AeroRC";
+                    break;
+                case ROS_DECA:
+                    bstr += " Decca";
+                    break;
+                case ROS_LORN:
+                    bstr += " Loran";
+                    break;
+                case ROS_DGPS:
+                    bstr += " DGPS";
+                    break;
+                case ROS_TORN:
+                    bstr += " Toran";
+                    break;
+                case ROS_OMGA:
+                    bstr += " Omega";
+                    break;
+                case ROS_SYLD:
+                    bstr += " Syledis";
+                    break;
+                case ROS_CHKA:
+                    bstr += " Chiaka";
+                    break;
+                case ROS_PCOM:
+                case ROS_COMB:
+                case ROS_FACS:
+                case ROS_TIME:
+                    break;
+                case ROS_PAIS:
+                case ROS_SAIS:
+                    bstr += " AIS";
+                    break;
+                case ROS_VAIS:
+                    vais = true;
+                    break;
+                case ROS_VANC:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopNorth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VASC:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopSouth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VAEC:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopEast, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VAWC:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopWest, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VAPL:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopCan, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VASL:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopCone, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VAID:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopIsol, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VASW:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopSphere, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VASP:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopX, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                case ROS_VAWK:
+                    vais = true;
+                    Renderer.symbol(Topmarks.TopCross, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
+                    break;
+                default:
+                    break;
+                }
+            }
+            if (!vais) {
+                Renderer.symbol(Beacons.RadarStation);
+            }
+        }
+        if (Renderer.zoom >= 15) {
+            if (vais) {
+                Renderer.labelText("V-AIS", new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 70)));
+            }
+            if (!bstr.isEmpty()) {
+                Renderer.labelText(bstr, new Font("Arial", Font.PLAIN, 40), Symbols.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -110)));
+            }
+        }
+    }
+
+    class Sect {
+        int dir;
+        LitCHR chr;
+        ColCOL col;
+        ColCOL alt;
+        String grp;
+        double per;
+        double rng;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void lights() {
+        Enum<ColCOL> col = null;
+        Enum<ColCOL> tcol = null;
+        ObjTab lights = feature.objs.get(Obj.LIGHTS);
+        for (AttMap atts : lights.values()) {
+            if (atts.containsKey(Att.COLOUR)) {
+                ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                if (cols.size() == 1) {
+                    tcol = cols.get(0);
+                    if (col == null) {
+                        col = tcol;
+                    } else if (tcol != col) {
+                        col = ColCOL.COL_MAG;
+                        break;
+                    }
+                } else {
+                    col = ColCOL.COL_MAG;
+                    break;
+                }
+            }
+        }
+        Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
+        if (Renderer.zoom >= 12) {
+            String str = "";
+            if (lights.get(1) != null) {
+                for (AttMap atts : lights.values()) {
+                    Enum<ColCOL> col1 = null;
+                    Enum<ColCOL> col2 = null;
+                    double radius = 0.2;
+                    double s1 = 361;
+                    double s2 = 361;
+                    Double dir = null;
+                    if (atts.containsKey(Att.COLOUR)) {
+                        ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                        col1 = cols.get(0);
+                        if (cols.size() > 1)
+                            col2 = cols.get(1);
+                    } else {
+                        continue;
+                    }
+                    if (atts.containsKey(Att.LITRAD)) {
+                        radius = (Double) atts.get(Att.LITRAD).val;
+                    }
+                    if (atts.containsKey(Att.CATLIT)) {
+                        ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
+                        if (cats.contains(CatLIT.LIT_DIR)) {
+                            if (atts.containsKey(Att.ORIENT)) {
+                                dir = (Double) atts.get(Att.ORIENT).val;
+                                s1 = ((dir - 4) + 360) % 360;
+                                s2 = (dir + 4) % 360;
+                                for (AttMap satts : lights.values()) {
+                                    double srad = 0.2;
+                                    double ss1 = 361;
+                                    double ss2 = 361;
+                                    Double sdir = null;
+                                    if (satts == atts)
+                                        continue;
+                                    if (satts.containsKey(Att.LITRAD)) {
+                                        srad = (Double) satts.get(Att.LITRAD).val;
+                                    }
+                                    if (srad == radius) {
+                                        ArrayList<CatLIT> scats = (satts.containsKey(Att.CATLIT)) ? (ArrayList<CatLIT>) satts.get(Att.CATLIT).val : new ArrayList<CatLIT>();
+                                        if (scats.contains(CatLIT.LIT_DIR)) {
+                                            if (satts.containsKey(Att.ORIENT)) {
+                                                sdir = (Double) satts.get(Att.ORIENT).val;
+                                                ss1 = sdir;
+                                                ss2 = sdir;
+                                            }
+                                        } else {
+                                            if (satts.containsKey(Att.SECTR1)) {
+                                                ss1 = (Double) satts.get(Att.SECTR1).val;
+                                            }
+                                            if (satts.containsKey(Att.SECTR2)) {
+                                                ss2 = (Double) satts.get(Att.SECTR2).val;
+                                            }
+                                        }
+                                        if ((ss1 > 360) || (ss2 > 360))
+                                            continue;
+                                        if (sdir != null) {
+                                            if (((dir - sdir + 360) % 360) < 8) {
+                                                s1 = ((((sdir > dir) ? 360 : 0) + sdir + dir) / 2) % 360;
+                                            }
+                                            if (((sdir - dir + 360) % 360) < 8) {
+                                                s2 = ((((dir > sdir) ? 360 : 0) + sdir + dir) / 2) % 360;
+                                            }
+                                        } else {
+                                            if (((dir - ss2 + 360) % 360) < 4) {
+                                                s1 = ss2;
+                                            }
+                                            if (((ss1 - dir + 360) % 360) < 4) {
+                                                s2 = ss1;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if ((s1 > 360) && atts.containsKey(Att.SECTR1)) {
+                        s1 = (Double) atts.get(Att.SECTR1).val;
+                    } else if (dir == null) {
+                        continue;
+                    }
+                    if ((s2 > 360) && atts.containsKey(Att.SECTR2)) {
+                        s2 = (Double) atts.get(Att.SECTR2).val;
+                    } else if (dir == null) {
+                        continue;
+                    }
+                    str = "";
+                    if (atts.containsKey(Att.LITCHR)) {
+                        str += LightCharacters.get(((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0));
+                    }
+                    if (atts.containsKey(Att.SIGGRP)) {
+                        str += "(" + atts.get(Att.SIGGRP).val + ")";
+                    } else if (!str.isEmpty()) {
+                        str += ".";
+                    }
+                    if (atts.containsKey(Att.COLOUR)) {
+                        ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                        str += LightLetters.get(cols.get(0));
+                        if (cols.size() > 1)
+                            str += LightLetters.get(cols.get(1));
+                    }
+                    if (atts.containsKey(Att.SIGPER)) {
+                        str += "." + df.format(atts.get(Att.SIGPER).val) + "s";
+                    }
+                    if ((s1 <= 360) && (s2 <= 360) && (s1 != s2))
+                        Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
+                }
+                if (Renderer.zoom >= 15) {
+                    class LitSect {
+                        boolean dir;
+                        LitCHR chr;
+                        ColCOL col;
+                        String grp;
+                        double per;
+                        double rng;
+                        double hgt;
+                    }
+
+                    ArrayList<LitSect> litatts = new ArrayList<>();
+                    for (AttMap atts : lights.values()) {
+                        LitSect sect = new LitSect();
+                        sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
+                        sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
+                        switch (sect.chr) {
+                        case CHR_AL:
+                            sect.chr = LitCHR.CHR_F;
+                            break;
+                        case CHR_ALOC:
+                            sect.chr = LitCHR.CHR_OC;
+                            break;
+                        case CHR_ALLFL:
+                            sect.chr = LitCHR.CHR_LFL;
+                            break;
+                        case CHR_ALFL:
+                            sect.chr = LitCHR.CHR_FL;
+                            break;
+                        case CHR_ALFFL:
+                            sect.chr = LitCHR.CHR_FFL;
+                            break;
+                        default:
+                            break;
+                        }
+                        sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
+                        sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
+                        sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
+                        sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
+                        ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
+                        sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
+                        if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
+                            litatts.add(sect);
+                    }
+                    ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
+                    for (LitSect lit : litatts) {
+                        boolean found = false;
+                        for (ArrayList<LitSect> group : groupings) {
+                            LitSect mem = group.get(0);
+                            if ((lit.dir == mem.dir) && (lit.chr == mem.chr) && (lit.grp.equals(mem.grp)) && (lit.per == mem.per) && (lit.hgt == mem.hgt)) {
+                                group.add(lit);
+                                found = true;
+                            }
+                        }
+                        if (!found) {
+                            ArrayList<LitSect> tmp = new ArrayList<>();
+                            tmp.add(lit);
+                            groupings.add(tmp);
+                        }
+                    }
+                    for (boolean moved = true; moved;) {
+                        moved = false;
+                        for (int i = 0; i < groupings.size() - 1; i++) {
+                            if (groupings.get(i).size() < groupings.get(i + 1).size()) {
+                                ArrayList<LitSect> tmp = groupings.remove(i);
+                                groupings.add(i + 1, tmp);
+                                moved = true;
+                            }
+                        }
+                    }
+                    class ColRng {
+                        ColCOL col;
+                        double rng;
+
+                        ColRng(ColCOL c, double r) {
+                            col = c;
+                            rng = r;
+                        }
+                    }
+
+                    int y = -30;
+                    for (ArrayList<LitSect> group : groupings) {
+                        ArrayList<ColRng> colrng = new ArrayList<>();
+                        for (LitSect lit : group) {
+                            boolean found = false;
+                            for (ColRng cr : colrng) {
+                                if (cr.col == lit.col) {
+                                    if (lit.rng > cr.rng) {
+                                        cr.rng = lit.rng;
+                                    }
+                                    found = true;
+                                }
+                            }
+                            if (!found) {
+                                colrng.add(new ColRng(lit.col, lit.rng));
+                            }
+                        }
+                        for (boolean moved = true; moved;) {
+                            moved = false;
+                            for (int i = 0; i < colrng.size() - 1; i++) {
+                                if (colrng.get(i).rng < colrng.get(i + 1).rng) {
+                                    ColRng tmp = colrng.remove(i);
+                                    colrng.add(i + 1, tmp);
+                                    moved = true;
+                                }
+                            }
+                        }
+                        LitSect tmp = group.get(0);
+                        str = (tmp.dir) ? "Dir" : "";
+                        str += LightCharacters.get(tmp.chr);
+                        if (!tmp.grp.isEmpty())
+                            str += "(" + tmp.grp + ")";
+                        else
+                            str += ".";
+                        for (ColRng cr : colrng) {
+                            str += LightLetters.get(cr.col);
+                        }
+                        if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
+                            str += ".";
+                        if (tmp.per > 0)
+                            str += df.format(tmp.per) + "s";
+                        if (tmp.hgt > 0)
+                            str += df.format(tmp.hgt) + "m";
+                        if (colrng.get(0).rng > 0)
+                            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";
+                        Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
+                        y += 40;
+                        str = "";
+                    }
+                }
+            } else {
+                if (Renderer.zoom >= 15) {
+                    AttMap atts = lights.get(0);
+                    ArrayList<CatLIT> cats = new ArrayList<>();
+                    if (atts.containsKey(Att.CATLIT)) {
+                        cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
+                    }
+                    str = (cats.contains(CatLIT.LIT_DIR)) ? "Dir" : "";
+                    str += (atts.containsKey(Att.MLTYLT)) ? atts.get(Att.MLTYLT).val : "";
+                    if (atts.containsKey(Att.LITCHR)) {
+                        LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
+                        if (atts.containsKey(Att.SIGGRP)) {
+                            String grp = (String) atts.get(Att.SIGGRP).val;
+                            switch (chr) {
+                            case CHR_QLFL:
+                                str += String.format("Q(%s)+LFl", grp);
+                                break;
+                            case CHR_VQLFL:
+                                str += String.format("VQ(%s)+LFl", grp);
+                                break;
+                            case CHR_UQLFL:
+                                str += String.format("UQ(%s)+LFl", grp);
+                                break;
+                            default:
+                                str += String.format("%s(%s)", LightCharacters.get(chr), grp);
+                                break;
+                            }
+                        } else {
+                            str += LightCharacters.get(chr);
+                        }
+                    }
+                    if (atts.containsKey(Att.COLOUR)) {
+                        ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
+                        if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
+                            if (!str.isEmpty() && !str.endsWith(")")) {
+                                str += ".";
+                            }
+                            for (ColCOL acol : cols) {
+                                str += LightLetters.get(acol);
+                            }
+                        }
+                    }
+                    str += (cats.contains(CatLIT.LIT_VERT)) ? "(vert)" : "";
+                    str += (cats.contains(CatLIT.LIT_HORI)) ? "(hor)" : "";
+                    str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
+                    str += (atts.containsKey(Att.SIGPER)) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
+                    str += (atts.containsKey(Att.HEIGHT)) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
+                    str += (atts.containsKey(Att.VALNMR)) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
+                    str += (cats.contains(CatLIT.LIT_FRNT)) ? "(Front)" : "";
+                    str += (cats.contains(CatLIT.LIT_REAR)) ? "(Rear)" : "";
+                    str += (cats.contains(CatLIT.LIT_UPPR)) ? "(Upper)" : "";
+                    str += (cats.contains(CatLIT.LIT_LOWR)) ? "(Lower)" : "";
+                    Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
+                }
+            }
+        }
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57att.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57att.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57att.java	(revision 32394)
@@ -10,379 +10,643 @@
 package s57;
 
-import java.util.*;
-
-import s57.S57obj.*;
+import java.util.EnumMap;
+import java.util.HashMap;
+
+import s57.S57obj.Obj;
 
 public class S57att { // S57 Attribute lookup tables & methods
- 
- public enum Att {
-   UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
-   CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
-   CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
-   CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
-   DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
-   MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
-   SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
-   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,
-   VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
-   DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
-   MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
-   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,
-   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
- }
-
- private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
- static {
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
- }
-
- private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
- static {
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
- }
- 
- private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
- static {
-  AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
-  AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
-  AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
-  AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
-  AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
-  AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
-  AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
-  AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
-  AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
-  AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
-  AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
-  AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
-  AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
-  AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
-  AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
-  AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
-  AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
-  AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
-  AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
-  AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
-  AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
-  AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
-  AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
-  AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
-  AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
-  AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
-  AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
-  AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
-  AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
-  AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
-  AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
-  AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
-  AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
-  AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
-  AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
-  AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
-  AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
-  AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
-  AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
-  AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
-  AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
-  AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
-  AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
-  AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
-  AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
-  AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
-  AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
-  AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
-  AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
-  AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
-  AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
-  AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
-  AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
-  AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
-  AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
-  AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
- }
- private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static { Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
- private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static { Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
- private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static { Agency.put(Obj.UNKOBJ, Att.AGENCY); }
- private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static { Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
- private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static { Authority.put(Obj.UNKOBJ, Att.SURATH); }
- private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static { Availability.put(Obj.UNKOBJ, Att.BUNVES); }
- private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static { Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
- private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static { Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
- private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class); static {
-  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);
-  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);
-  Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  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);
-  Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
-  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);
-  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);
-  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);
-  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);
-  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);
-  Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
- }
- 
- private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static { Channel.put(Obj.UNKOBJ, Att.COMCHA); }
- private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static { Character.put(Obj.UNKOBJ, Att.LITCHR); }
- private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static { Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
- private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static { Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
- private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static { Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
- private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static { Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
- private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static { Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
- private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static { Colour.put(Obj.UNKOBJ, Att.COLOUR); }
- private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static { Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
- private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static { Communication.put(Obj.UNKOBJ, Att.COMCTN); }
- private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static { Condition.put(Obj.UNKOBJ, Att.CONDTN); }
- private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static { Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
- private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static { Construction.put(Obj.UNKOBJ, Att.NATCON); }
- private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static { Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
- private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static { Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
- private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static { Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
- private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static { Description.put(Obj.UNKOBJ, Att.TXTDSC); }
- private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static { Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
- private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static { Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
- private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static { Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
- private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static { Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
- private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static { Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
- private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static { Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
- private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static { End_date.put(Obj.UNKOBJ, Att.DATEND); }
- private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static { End_time.put(Obj.UNKOBJ, Att.TIMEND); }
- private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static { Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
- private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static { Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
- private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static { Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
- private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static { Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
- private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static { Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
- 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); }
- private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static { Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
- private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static { Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
- private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static { Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
- private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static { Group.put(Obj.UNKOBJ, Att.SIGGRP); }
- private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static { Height.put(Obj.UNKOBJ, Att.HEIGHT); }
- private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static { High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
- private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static { High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
- private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static { High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
- private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static { Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
- private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static { Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
- private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static { Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
- private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static { Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
- private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static { Information.put(Obj.UNKOBJ, Att.INFORM); }
- private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static { Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
- private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static { Length.put(Obj.UNKOBJ, Att.HORLEN); }
- private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static { Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
- private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static { Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
- private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static { Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
- private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static { Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
- private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static { Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
- private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static { Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
- private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static { Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
- private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static { Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
- private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static { Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
- private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static { Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
- private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static { Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
- private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static { Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
- private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static { Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
- private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static { Message.put(Obj.UNKOBJ, Att.UPDMSG); }
- private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static { Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
- private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static { Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
- private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static { Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
- private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static { Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
- private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static { Name.put(Obj.UNKOBJ, Att.OBJNAM); }
- private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static { National_information.put(Obj.UNKOBJ, Att.NINFOM); }
- private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static { Nationality.put(Obj.UNKOBJ, Att.NATION); }
- private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static { National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
- private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static { National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
- private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static { National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
- private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static { Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
- private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static { Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
- private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static { Operation.put(Obj.UNKOBJ, Att.CATTAB); }
- private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static { Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
- private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static { Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
- private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static { Period.put(Obj.UNKOBJ, Att.SIGPER); }
- private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static { Period_end.put(Obj.UNKOBJ, Att.PEREND); }
- private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static { Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
- private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static { Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
- private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static { Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
- private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static { Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
- private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static { Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
- private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static { Product.put(Obj.UNKOBJ, Att.PRODCT); }
- private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static { Quality.put(Obj.UNKOBJ, Att.QUASOU); }
- private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static { Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
- private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static { Range.put(Obj.UNKOBJ, Att.VALNMR); }
- private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static { Reference.put(Obj.UNKOBJ, Att.PUBREF); }
- private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static { Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
- private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static { Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
- private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static { Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
- private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static { Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
-  Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
-  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);
-  Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
-  Shape.put(Obj.SILTNK, Att.BUISHP);
- }
- private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static { Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
- private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static { Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
- private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static { Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
- private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static { Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
- private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static { Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
- private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static { Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
- private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static { Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
- private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static { Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
- private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static { Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
- private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static { Status.put(Obj.UNKOBJ, Att.STATUS); }
- private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static { Surface.put(Obj.UNKOBJ, Att.NATSUR); }
- private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static { Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
- private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static { Survey.put(Obj.UNKOBJ, Att.SURTYP); }
- private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static { Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
- private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static { Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
- private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static { System.put(Obj.UNKOBJ, Att.MARSYS); }
- private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static { Technique.put(Obj.UNKOBJ, Att.TECSOU); }
- private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static { Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
- private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static { Units.put(Obj.UNKOBJ, Att.HUNITS); }
- private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static { Use.put(Obj.UNKOBJ, Att.USESHP); }
- private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static { Variation.put(Obj.UNKOBJ, Att.VALMAG); }
- private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static { Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
- private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static { Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
- private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static { Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
- private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static { Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
- private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static { Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
- private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static { Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
- private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static { Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
- private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static { Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
- private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static { Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
- private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static { Width.put(Obj.UNKOBJ, Att.HORWID); }
- private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static { Year.put(Obj.UNKOBJ, Att.RYRMGV); }
- 
- private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
- static {
-  StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
-  StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
-  StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
-  StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
-  StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
-  StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
-  StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
-  StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
-  StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
-  StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
-  StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
-  StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
-  StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
-  StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
-  StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
-  StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
-  StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
-  StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
-  StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
-  StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
-  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);
-  StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
-  StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
-  StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
-  StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
-  StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
-  StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
-  StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
-  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);
-  StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
-  StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
-  StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
- }
-
- public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
-		for (Att att : AttS57.keySet()) {
-			if (AttS57.get(att) == attl) return att;
-		}
-		for (Att att : AttIENC.keySet()) {
-			if (AttIENC.get(att) == attl) return att;
-		}
-  return Att.UNKATT;
- }
- 
- public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
-  if (AttS57.containsKey(attribute))
-   return AttS57.get(attribute);
-  else if (AttIENC.containsKey(attribute))
-   return AttIENC.get(attribute);
-  return 0;
- }
-
- public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
-   return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
- }
-
- public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
-  String str = AttStr.get(attribute);
-  return str != null ? str : "";
- }
- 
- public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
-   if ((attribute != null) && !attribute.isEmpty()) {
-   EnumMap<Obj, Att> map = StrAtt.get(attribute);
-   if (map != null) {
-    if (map.containsKey(obj)) {
-     return map.get(obj);
-    } else if (map.containsKey(Obj.UNKOBJ)) {
-     return map.get(Obj.UNKOBJ);
-    } else {
-     return Att.UNKATT;
-    }
-   }
-   }
-  return Att.UNKATT;
- }
-
+    // CHECKSTYLE.OFF: LineLength
+
+    public enum Att {
+        UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
+        CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
+        CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
+        CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
+        DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
+        MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
+        SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
+        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,
+        VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
+        DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
+        MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
+        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,
+        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
+    }
+
+    private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
+    static {
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
+    }
+
+    private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
+    static {
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
+    }
+
+    private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
+    static {
+        AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
+        AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
+        AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
+        AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
+        AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
+        AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
+        AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
+        AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
+        AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
+        AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
+        AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
+        AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
+        AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
+        AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
+        AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
+        AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
+        AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
+        AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
+        AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
+        AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
+        AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
+        AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
+        AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
+        AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
+        AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
+        AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
+        AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
+        AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
+        AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
+        AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
+        AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
+        AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
+        AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
+        AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
+        AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
+        AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
+        AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
+        AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
+        AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
+        AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
+        AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
+        AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
+        AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
+        AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
+        AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
+        AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
+        AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
+        AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
+        AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
+        AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
+        AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
+        AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
+        AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
+        AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
+        AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
+        AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
+    }
+
+    private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static {
+        Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
+
+    private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static {
+        Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
+
+    private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static {
+        Agency.put(Obj.UNKOBJ, Att.AGENCY); }
+
+    private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static {
+        Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
+
+    private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static {
+        Authority.put(Obj.UNKOBJ, Att.SURATH); }
+
+    private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static {
+        Availability.put(Obj.UNKOBJ, Att.BUNVES); }
+
+    private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static {
+        Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
+
+    private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static {
+        Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
+
+    private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class);
+    static {
+        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);
+        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);
+        Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
+        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);
+        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);
+        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);
+        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);
+        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);
+        Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
+    }
+
+    private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static {
+        Channel.put(Obj.UNKOBJ, Att.COMCHA); }
+
+    private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static {
+        Character.put(Obj.UNKOBJ, Att.LITCHR); }
+
+    private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static {
+        Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
+
+    private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static {
+        Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
+
+    private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static {
+        Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
+
+    private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static {
+        Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
+
+    private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static {
+        Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
+
+    private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static {
+        Colour.put(Obj.UNKOBJ, Att.COLOUR); }
+
+    private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static {
+        Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
+
+    private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static {
+        Communication.put(Obj.UNKOBJ, Att.COMCTN); }
+
+    private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static {
+        Condition.put(Obj.UNKOBJ, Att.CONDTN); }
+
+    private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static {
+        Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
+
+    private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static {
+        Construction.put(Obj.UNKOBJ, Att.NATCON); }
+
+    private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static {
+        Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
+
+    private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static {
+        Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
+
+    private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static {
+        Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
+
+    private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static {
+        Description.put(Obj.UNKOBJ, Att.TXTDSC); }
+
+    private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static {
+        Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
+
+    private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static {
+        Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
+
+    private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static {
+        Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
+
+    private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static {
+        Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
+
+    private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static {
+        Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
+
+    private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static {
+        Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
+
+    private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static {
+        End_date.put(Obj.UNKOBJ, Att.DATEND); }
+
+    private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static {
+        End_time.put(Obj.UNKOBJ, Att.TIMEND); }
+
+    private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static {
+        Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
+
+    private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static {
+        Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
+
+    private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static {
+        Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
+
+    private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static {
+        Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
+
+    private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static {
+        Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
+
+    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); }
+
+    private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static {
+        Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
+
+    private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static {
+        Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
+
+    private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static {
+        Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
+
+    private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static {
+        Group.put(Obj.UNKOBJ, Att.SIGGRP); }
+
+    private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static {
+        Height.put(Obj.UNKOBJ, Att.HEIGHT); }
+
+    private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static {
+        High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
+
+    private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static {
+        High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
+
+    private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static {
+        High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
+
+    private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static {
+        Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
+
+    private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static {
+        Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
+
+    private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static {
+        Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
+
+    private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static {
+        Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
+
+    private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static {
+        Information.put(Obj.UNKOBJ, Att.INFORM); }
+
+    private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static {
+        Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
+
+    private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static {
+        Length.put(Obj.UNKOBJ, Att.HORLEN); }
+
+    private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static {
+        Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
+
+    private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static {
+        Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
+
+    private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static {
+        Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
+
+    private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static {
+        Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
+
+    private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static {
+        Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
+
+    private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static {
+        Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
+
+    private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static {
+        Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
+
+    private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static {
+        Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
+
+    private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static {
+        Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
+
+    private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static {
+        Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
+
+    private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static {
+        Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
+
+    private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static {
+        Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
+
+    private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static {
+        Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
+
+    private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static {
+        Message.put(Obj.UNKOBJ, Att.UPDMSG); }
+
+    private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static {
+        Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
+
+    private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static {
+        Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
+
+    private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static {
+        Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
+
+    private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static {
+        Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
+
+    private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static {
+        Name.put(Obj.UNKOBJ, Att.OBJNAM); }
+
+    private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static {
+        National_information.put(Obj.UNKOBJ, Att.NINFOM); }
+
+    private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static {
+        Nationality.put(Obj.UNKOBJ, Att.NATION); }
+
+    private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static {
+        National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
+
+    private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static {
+        National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
+
+    private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static {
+        National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
+
+    private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static {
+        Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
+
+    private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static {
+        Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
+
+    private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static {
+        Operation.put(Obj.UNKOBJ, Att.CATTAB); }
+
+    private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static {
+        Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
+
+    private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static {
+        Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
+
+    private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static {
+        Period.put(Obj.UNKOBJ, Att.SIGPER); }
+
+    private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static {
+        Period_end.put(Obj.UNKOBJ, Att.PEREND); }
+
+    private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static {
+        Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
+
+    private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static {
+        Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
+
+    private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static {
+        Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
+
+    private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static {
+        Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
+
+    private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static {
+        Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
+
+    private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static {
+        Product.put(Obj.UNKOBJ, Att.PRODCT); }
+
+    private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static {
+        Quality.put(Obj.UNKOBJ, Att.QUASOU); }
+
+    private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static {
+        Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
+
+    private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static {
+        Range.put(Obj.UNKOBJ, Att.VALNMR); }
+
+    private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static {
+        Reference.put(Obj.UNKOBJ, Att.PUBREF); }
+
+    private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static {
+        Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
+
+    private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static {
+        Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
+
+    private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static {
+        Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
+
+    private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static {
+        Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
+        Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
+        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);
+        Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
+        Shape.put(Obj.SILTNK, Att.BUISHP);
+    }
+
+    private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static {
+        Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
+
+    private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static {
+        Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
+
+    private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static {
+        Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
+
+    private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static {
+        Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
+
+    private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static {
+        Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
+
+    private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static {
+        Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
+
+    private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static {
+        Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
+
+    private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static {
+        Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
+
+    private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static {
+        Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
+
+    private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static {
+        Status.put(Obj.UNKOBJ, Att.STATUS); }
+
+    private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static {
+        Surface.put(Obj.UNKOBJ, Att.NATSUR); }
+
+    private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static {
+        Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
+
+    private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static {
+        Survey.put(Obj.UNKOBJ, Att.SURTYP); }
+
+    private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static {
+        Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
+
+    private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static {
+        Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
+
+    private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static {
+        System.put(Obj.UNKOBJ, Att.MARSYS); }
+
+    private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static {
+        Technique.put(Obj.UNKOBJ, Att.TECSOU); }
+
+    private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static {
+        Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
+
+    private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static {
+        Units.put(Obj.UNKOBJ, Att.HUNITS); }
+
+    private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static {
+        Use.put(Obj.UNKOBJ, Att.USESHP); }
+
+    private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static {
+        Variation.put(Obj.UNKOBJ, Att.VALMAG); }
+
+    private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static {
+        Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
+
+    private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static {
+        Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
+
+    private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static {
+        Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
+
+    private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static {
+        Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
+
+    private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static {
+        Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
+
+    private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static {
+        Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
+
+    private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static {
+        Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
+
+    private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static {
+        Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
+
+    private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static {
+        Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
+
+    private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static {
+        Width.put(Obj.UNKOBJ, Att.HORWID); }
+
+    private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static {
+        Year.put(Obj.UNKOBJ, Att.RYRMGV); }
+
+    private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
+    static {
+        StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
+        StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
+        StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
+        StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
+        StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
+        StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
+        StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
+        StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
+        StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
+        StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
+        StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
+        StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
+        StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
+        StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
+        StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
+        StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
+        StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
+        StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
+        StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
+        StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
+        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);
+        StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
+        StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
+        StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
+        StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
+        StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
+        StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
+        StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
+        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);
+        StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
+        StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
+        StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
+    }
+
+    public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
+        for (Att att : AttS57.keySet()) {
+            if (AttS57.get(att) == attl) return att;
+        }
+        for (Att att : AttIENC.keySet()) {
+            if (AttIENC.get(att) == attl) return att;
+        }
+        return Att.UNKATT;
+    }
+
+    public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
+        if (AttS57.containsKey(attribute))
+            return AttS57.get(attribute);
+        else if (AttIENC.containsKey(attribute))
+            return AttIENC.get(attribute);
+        return 0;
+    }
+
+    public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
+        return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
+    }
+
+    public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
+        String str = AttStr.get(attribute);
+        return str != null ? str : "";
+    }
+
+    public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
+        if ((attribute != null) && !attribute.isEmpty()) {
+            EnumMap<Obj, Att> map = StrAtt.get(attribute);
+            if (map != null) {
+                if (map.containsKey(obj)) {
+                    return map.get(obj);
+                } else if (map.containsKey(Obj.UNKOBJ)) {
+                    return map.get(Obj.UNKOBJ);
+                } else {
+                    return Att.UNKATT;
+                }
+            }
+        }
+        return Att.UNKATT;
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57box.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57box.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57box.java	(revision 32394)
@@ -12,162 +12,169 @@
 import java.util.ArrayList;
 
-import s57.S57map.*;
-import s57.S57obj.*;
+import s57.S57map.Edge;
+import s57.S57map.Feature;
+import s57.S57map.Pflag;
+import s57.S57map.Rflag;
+import s57.S57map.Snode;
+import s57.S57obj.Obj;
 
 public class S57box { //S57 bounding box truncation
-	
-	enum Ext {I, N, W, S, E }
-	
-	static Ext getExt(S57map map, double lat, double lon) {
-		if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
-			return Ext.N;
-		} else if (lon <= map.bounds.minlon) {
-			return Ext.W;
-		} else if (lat <= map.bounds.minlat) {
-			return Ext.S;
-		} else if (lon >= map.bounds.maxlon) {
-			return Ext.E;
-		}		return Ext.I;
-	}
-	
-	public static void bBox(S57map map) {
-		/* Truncations
-		 * Points: delete point features outside BB
-		 * Lines: Truncate edges at BB boundaries
-		 * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
-		 * Remove nodes outside BB
-		 * Remove edges that are completely outside BB
-		 */
-		class Land {
-			long first;
-			Snode start;
-			Ext sbound;
-			long last;
-			Snode end;
-			Ext ebound;
-			Feature land;
+    // CHECKSTYLE.OFF: LineLength
 
-			Land(Feature l) {
-				land = l;
-				first = last = 0;
-				start = end = null;
-				sbound = ebound = Ext.I;
-			}
-		}
-		if (map.features.get(Obj.COALNE) != null) {
-			ArrayList<Feature> coasts = new ArrayList<>();
-			ArrayList<Land> lands = new ArrayList<>();
-			if (map.features.get(Obj.LNDARE) == null) {
-				map.features.put(Obj.LNDARE, new ArrayList<Feature>());
-			}
-			for (Feature feature : map.features.get(Obj.COALNE)) {
-				Feature land = map.new Feature();
-				land.id = ++map.xref;
-				land.type = Obj.LNDARE;
-				land.reln = Rflag.MASTER;
-				land.objs.put(Obj.LNDARE, map.new ObjTab());
-				land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
-				if (feature.geom.prim == Pflag.AREA) {
-					land.geom = feature.geom;
-					map.features.get(Obj.LNDARE).add(land);
-				} else if (feature.geom.prim == Pflag.LINE) {
-					land.geom.prim = Pflag.LINE;
-					land.geom.elems.addAll(feature.geom.elems);
-					coasts.add(land);
-				}
-			}
-			while (coasts.size() > 0) {
-				Feature land = coasts.remove(0);
-				Edge fedge = map.edges.get(land.geom.elems.get(0).id);
-				long first = fedge.first;
-				long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
-				if (coasts.size() > 0) {
-					boolean added = true;
-					while (added) {
-						added = false;
-						for (int i = 0; i < coasts.size(); i++) {
-							Feature coast = coasts.get(i);
-							Edge edge = map.edges.get(coast.geom.elems.get(0).id);
-							if (edge.first == last) {
-								land.geom.elems.add(coast.geom.elems.get(0));
-								last = edge.last;
-								coasts.remove(i--);
-								added = true;
-							} else if (edge.last == first) {
-								land.geom.elems.add(0, coast.geom.elems.get(0));
-								first = edge.first;
-								coasts.remove(i--);
-								added = true;
-							}
-						}
-					}
-				}
-				lands.add(new Land(land));
-			}
-			ArrayList<Land> islands = new ArrayList<>();
-			for (Land land : lands) {
-				map.sortGeom(land.land);
-				if (land.land.geom.prim == Pflag.AREA) {
-					islands.add(land);
-					map.features.get(Obj.LNDARE).add(land.land);
-				}
-			}
-			for (Land island : islands) {
-				lands.remove(island);
-			}
-			for (Land land : lands) {
-				land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
-				land.start = map.nodes.get(land.first);
-				land.sbound = getExt(map, land.start.lat, land.start.lon);
-				land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
-				land.end = map.nodes.get(land.last);
-				land.ebound = getExt(map, land.end.lat, land.end.lon);
-			}
-			islands = new ArrayList<>();
-			for (Land land : lands) {
-				if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
-					islands.add(land);
-				}
-			}
-			for (Land island : islands) {
-				lands.remove(island);
-			}
-			for (Land land : lands) {
-				Edge nedge = map.new Edge();
-				nedge.first = land.last;
-				nedge.last = land.first;
-				Ext bound = land.ebound;
-				while (bound != land.sbound) {
-					switch (bound) {
-					case N:
-						nedge.nodes.add(1l);
-						bound = Ext.W;
-						break;
-					case W:
-						nedge.nodes.add(2l);
-						bound = Ext.S;
-						break;
-					case S:
-						nedge.nodes.add(3l);
-						bound = Ext.E;
-						break;
-					case E:
-						nedge.nodes.add(4l);
-						bound = Ext.N;
-						break;
-					default:
-						continue;
-					}
-				}
-				map.edges.put(++map.xref, nedge);
-				land.land.geom.elems.add(map.new Prim(map.xref));
-				land.land.geom.comps.get(0).size++;
-				land.land.geom.prim = Pflag.AREA;
-				map.features.get(Obj.LNDARE).add(land.land);
-			}
-		}
-		return;
+    enum Ext { I, N, W, S, E }
 
-	}
+    static Ext getExt(S57map map, double lat, double lon) {
+        if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
+            return Ext.N;
+        } else if (lon <= map.bounds.minlon) {
+            return Ext.W;
+        } else if (lat <= map.bounds.minlat) {
+            return Ext.S;
+        } else if (lon >= map.bounds.maxlon) {
+            return Ext.E;
+        }
+        return Ext.I;
+    }
+
+    public static void bBox(S57map map) {
+        /* Truncations
+         * Points: delete point features outside BB
+         * Lines: Truncate edges at BB boundaries
+         * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
+         * Remove nodes outside BB
+         * Remove edges that are completely outside BB
+         */
+        class Land {
+            long first;
+            Snode start;
+            Ext sbound;
+            long last;
+            Snode end;
+            Ext ebound;
+            Feature land;
+
+            Land(Feature l) {
+                land = l;
+                first = last = 0;
+                start = end = null;
+                sbound = ebound = Ext.I;
+            }
+        }
+
+        if (map.features.get(Obj.COALNE) != null) {
+            ArrayList<Feature> coasts = new ArrayList<>();
+            ArrayList<Land> lands = new ArrayList<>();
+            if (map.features.get(Obj.LNDARE) == null) {
+                map.features.put(Obj.LNDARE, new ArrayList<Feature>());
+            }
+            for (Feature feature : map.features.get(Obj.COALNE)) {
+                Feature land = map.new Feature();
+                land.id = ++map.xref;
+                land.type = Obj.LNDARE;
+                land.reln = Rflag.MASTER;
+                land.objs.put(Obj.LNDARE, map.new ObjTab());
+                land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
+                if (feature.geom.prim == Pflag.AREA) {
+                    land.geom = feature.geom;
+                    map.features.get(Obj.LNDARE).add(land);
+                } else if (feature.geom.prim == Pflag.LINE) {
+                    land.geom.prim = Pflag.LINE;
+                    land.geom.elems.addAll(feature.geom.elems);
+                    coasts.add(land);
+                }
+            }
+            while (coasts.size() > 0) {
+                Feature land = coasts.remove(0);
+                Edge fedge = map.edges.get(land.geom.elems.get(0).id);
+                long first = fedge.first;
+                long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
+                if (coasts.size() > 0) {
+                    boolean added = true;
+                    while (added) {
+                        added = false;
+                        for (int i = 0; i < coasts.size(); i++) {
+                            Feature coast = coasts.get(i);
+                            Edge edge = map.edges.get(coast.geom.elems.get(0).id);
+                            if (edge.first == last) {
+                                land.geom.elems.add(coast.geom.elems.get(0));
+                                last = edge.last;
+                                coasts.remove(i--);
+                                added = true;
+                            } else if (edge.last == first) {
+                                land.geom.elems.add(0, coast.geom.elems.get(0));
+                                first = edge.first;
+                                coasts.remove(i--);
+                                added = true;
+                            }
+                        }
+                    }
+                }
+                lands.add(new Land(land));
+            }
+            ArrayList<Land> islands = new ArrayList<>();
+            for (Land land : lands) {
+                map.sortGeom(land.land);
+                if (land.land.geom.prim == Pflag.AREA) {
+                    islands.add(land);
+                    map.features.get(Obj.LNDARE).add(land.land);
+                }
+            }
+            for (Land island : islands) {
+                lands.remove(island);
+            }
+            for (Land land : lands) {
+                land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
+                land.start = map.nodes.get(land.first);
+                land.sbound = getExt(map, land.start.lat, land.start.lon);
+                land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
+                land.end = map.nodes.get(land.last);
+                land.ebound = getExt(map, land.end.lat, land.end.lon);
+            }
+            islands = new ArrayList<>();
+            for (Land land : lands) {
+                if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
+                    islands.add(land);
+                }
+            }
+            for (Land island : islands) {
+                lands.remove(island);
+            }
+            for (Land land : lands) {
+                Edge nedge = map.new Edge();
+                nedge.first = land.last;
+                nedge.last = land.first;
+                Ext bound = land.ebound;
+                while (bound != land.sbound) {
+                    switch (bound) {
+                    case N:
+                        nedge.nodes.add(1L);
+                        bound = Ext.W;
+                        break;
+                    case W:
+                        nedge.nodes.add(2L);
+                        bound = Ext.S;
+                        break;
+                    case S:
+                        nedge.nodes.add(3L);
+                        bound = Ext.E;
+                        break;
+                    case E:
+                        nedge.nodes.add(4L);
+                        bound = Ext.N;
+                        break;
+                    default:
+                        continue;
+                    }
+                }
+                map.edges.put(++map.xref, nedge);
+                land.land.geom.elems.add(map.new Prim(map.xref));
+                land.land.geom.comps.get(0).size++;
+                land.land.geom.prim = Pflag.AREA;
+                map.features.get(Obj.LNDARE).add(land.land);
+            }
+        }
+        return;
+
+    }
 
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57dat.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57dat.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57dat.java	(revision 32394)
@@ -11,491 +11,496 @@
 
 import java.io.UnsupportedEncodingException;
-import java.util.*;
-
-import s57.S57map.*;
-import s57.S57obj.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+
+import s57.S57map.Feature;
+import s57.S57map.Pflag;
+import s57.S57obj.Obj;
 
 public class S57dat { // S57 ENC file fields lookup tables & methods
-	
-	public static class S57conv {
-		int asc;	// 0=A(), 1+=A(n)
-		int bin;	// 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE) 
-		S57conv(int a, int b) {
-			asc = a; bin = b;
-		}
-	}
-	
-	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,
-		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,
-		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,
-		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,
-		VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
-
-	private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
-	static {
-		convs.put(S57subf.I8RN, new S57conv(5,2));
-		convs.put(S57subf.RCNM, new S57conv(2,1)); convs.put(S57subf.RCID, new S57conv(10,4)); convs.put(S57subf.EXPP, new S57conv(1,1));
-		convs.put(S57subf.INTU, new S57conv(1,1)); convs.put(S57subf.DSNM, new S57conv(0,0)); convs.put(S57subf.EDTN, new S57conv(0,0));
-		convs.put(S57subf.UPDN, new S57conv(0,0)); convs.put(S57subf.UADT, new S57conv(8,0)); convs.put(S57subf.ISDT, new S57conv(8,0));
-		convs.put(S57subf.STED, new S57conv(4,0)); convs.put(S57subf.PRSP, new S57conv(3,1)); convs.put(S57subf.PSDN, new S57conv(0,0));
-		convs.put(S57subf.PRED, new S57conv(0,0)); convs.put(S57subf.PROF, new S57conv(2,1)); convs.put(S57subf.AGEN, new S57conv(2,2));
-		convs.put(S57subf.COMT, new S57conv(0,0)); convs.put(S57subf.DSTR, new S57conv(2,1)); convs.put(S57subf.AALL, new S57conv(1,1));
-		convs.put(S57subf.NALL, new S57conv(1,1)); convs.put(S57subf.NOMR, new S57conv(0,4)); convs.put(S57subf.NOCR, new S57conv(0,4));
-		convs.put(S57subf.NOGR, new S57conv(0,4)); convs.put(S57subf.NOLR, new S57conv(0,4)); convs.put(S57subf.NOIN, new S57conv(0,4));
-		convs.put(S57subf.NOCN, new S57conv(0,4)); convs.put(S57subf.NOED, new S57conv(0,4)); convs.put(S57subf.NOFA, new S57conv(0,4));
-		convs.put(S57subf.HDAT, new S57conv(3,1)); convs.put(S57subf.VDAT, new S57conv(2,1)); convs.put(S57subf.SDAT, new S57conv(2,1));
-		convs.put(S57subf.CSCL, new S57conv(0,4)); convs.put(S57subf.DUNI, new S57conv(2,1)); convs.put(S57subf.HUNI, new S57conv(2,1));
-		convs.put(S57subf.PUNI, new S57conv(2,1)); convs.put(S57subf.COUN, new S57conv(2,1)); convs.put(S57subf.COMF, new S57conv(0,4));
-		convs.put(S57subf.SOMF, new S57conv(0,4)); convs.put(S57subf.PROJ, new S57conv(3,1)); convs.put(S57subf.PRP1, new S57conv(0,-4));
-		convs.put(S57subf.PRP2, new S57conv(0,-4)); convs.put(S57subf.PRP3, new S57conv(0,-4)); convs.put(S57subf.PRP4, new S57conv(0,-4));
-		convs.put(S57subf.FEAS, new S57conv(0,-4)); convs.put(S57subf.FNOR, new S57conv(0,-4)); convs.put(S57subf.FPMF, new S57conv(0,4));
-		convs.put(S57subf.RPID, new S57conv(1,1)); convs.put(S57subf.RYCO, new S57conv(0,-4)); convs.put(S57subf.RXCO, new S57conv(0,-4));
-		convs.put(S57subf.CURP, new S57conv(2,1)); convs.put(S57subf.RXVL, new S57conv(0,-4)); convs.put(S57subf.RYVL, new S57conv(0,-4));
-		convs.put(S57subf.PRCO, new S57conv(2,2)); convs.put(S57subf.ESDT, new S57conv(8,0)); convs.put(S57subf.LSDT, new S57conv(8,0));
-		convs.put(S57subf.DCRT, new S57conv(0,0)); convs.put(S57subf.CODT, new S57conv(8,0)); convs.put(S57subf.PACC, new S57conv(0,4));
-		convs.put(S57subf.HACC, new S57conv(0,4)); convs.put(S57subf.SACC, new S57conv(0,4)); convs.put(S57subf.FILE, new S57conv(0,0));
-		convs.put(S57subf.LFIL, new S57conv(0,0)); convs.put(S57subf.VOLM, new S57conv(0,0)); convs.put(S57subf.IMPL, new S57conv(3,0));
-		convs.put(S57subf.SLAT, new S57conv(0,0)); convs.put(S57subf.WLON, new S57conv(0,0)); convs.put(S57subf.NLAT, new S57conv(0,0));
-		convs.put(S57subf.ELON, new S57conv(0,0)); convs.put(S57subf.CRCS, new S57conv(0,0)); convs.put(S57subf.NAM1, new S57conv(12,5));
-		convs.put(S57subf.NAM2, new S57conv(12,5)); convs.put(S57subf.OORA, new S57conv(1,1)); convs.put(S57subf.OAAC, new S57conv(6,0));
-		convs.put(S57subf.OACO, new S57conv(5,2)); convs.put(S57subf.OALL, new S57conv(0,0)); convs.put(S57subf.OATY, new S57conv(1,1));
-		convs.put(S57subf.DEFN, new S57conv(0,0)); convs.put(S57subf.AUTH, new S57conv(2,2)); convs.put(S57subf.RFTP, new S57conv(2,1));
-		convs.put(S57subf.RFVL, new S57conv(0,0)); convs.put(S57subf.ATLB, new S57conv(5,2)); convs.put(S57subf.ATDO, new S57conv(1,1));
-		convs.put(S57subf.ADMU, new S57conv(0,0)); convs.put(S57subf.ADFT, new S57conv(0,0)); convs.put(S57subf.RAVA, new S57conv(1,1));
-		convs.put(S57subf.DVAL, new S57conv(0,0)); convs.put(S57subf.DVSD, new S57conv(0,0)); convs.put(S57subf.OBLB, new S57conv(5,2));
-		convs.put(S57subf.ASET, new S57conv(1,1)); convs.put(S57subf.PRIM, new S57conv(1,1)); convs.put(S57subf.GRUP, new S57conv(3,1));
-		convs.put(S57subf.OBJL, new S57conv(5,2)); convs.put(S57subf.RVER, new S57conv(3,2)); convs.put(S57subf.RUIN, new S57conv(1,1));
-		convs.put(S57subf.FIDN, new S57conv(10,4)); convs.put(S57subf.FIDS, new S57conv(5,2)); convs.put(S57subf.ATTL, new S57conv(5,2));
-		convs.put(S57subf.ATVL, new S57conv(0,0)); convs.put(S57subf.FFUI, new S57conv(1,1)); convs.put(S57subf.FFIX, new S57conv(0,2));
-		convs.put(S57subf.NFPT, new S57conv(0,2)); convs.put(S57subf.LNAM, new S57conv(17,8)); convs.put(S57subf.RIND, new S57conv(0,1));
-		convs.put(S57subf.FSUI, new S57conv(1,1)); convs.put(S57subf.FSIX, new S57conv(0,2)); convs.put(S57subf.NSPT, new S57conv(0,2));
-		convs.put(S57subf.NAME, new S57conv(12,5)); convs.put(S57subf.ORNT, new S57conv(1,1)); convs.put(S57subf.USAG, new S57conv(1,1));
-		convs.put(S57subf.MASK, new S57conv(1,1)); convs.put(S57subf.VPUI, new S57conv(1,1)); convs.put(S57subf.VPIX, new S57conv(0,2));
-		convs.put(S57subf.NVPT, new S57conv(0,2)); convs.put(S57subf.TOPI, new S57conv(1,1)); convs.put(S57subf.CCUI, new S57conv(1,1));
-		convs.put(S57subf.CCIX, new S57conv(0,2)); convs.put(S57subf.CCNC, new S57conv(0,2)); convs.put(S57subf.YCOO, new S57conv(0,-4));
-		convs.put(S57subf.XCOO, new S57conv(0,-4)); convs.put(S57subf.VE3D, new S57conv(0,-4)); convs.put(S57subf.ATYP, new S57conv(1,1));
-		convs.put(S57subf.SURF, new S57conv(1,1)); convs.put(S57subf.ORDR, new S57conv(1,1)); convs.put(S57subf.RESO, new S57conv(0,4));
-		convs.put(S57subf.STPT, new S57conv(0,0)); convs.put(S57subf.CTPT, new S57conv(0,0)); convs.put(S57subf.ENPT, new S57conv(0,0));
-		convs.put(S57subf.CDPM, new S57conv(0,0)); convs.put(S57subf.CDPR, new S57conv(0,0));
-	}
-	
-	public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
-		FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
-	
-	private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
-	private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
-			S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
-	private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
-			S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA ));
-	private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
-			S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT ));
-	private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
-			S57subf.FPMF, S57subf.COMT ));
-	private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
-			S57subf.COMT ));
-	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 ));
-	private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT ));
-	private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
-			S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT ));
-	private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT ));
-	private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
-			S57subf.DEFN, S57subf.AUTH, S57subf.COMT ));
-	private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
-	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 ));
-	private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH ));
-	private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
-	private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB ));
-	private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH ));
-	private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN ));
-	private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS ));
-	private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
-	private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
-	private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
-	private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT ));
-	private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT ));
-	private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT ));
-	private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK ));
-	private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN ));
-	private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
-	private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT ));
-	private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK ));
-	private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC ));
-	private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
-	private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D ));
-	private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF ));
-	private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO ));
-	private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO ));
-	private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
-	
-	private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
-	static {
-		fields.put(S57field.I8RI, S57i8ri);
-		fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
-		fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
-		fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
-		fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
-		fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
-		fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
-		fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
-		fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
-		fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d); 
-	}
-	
-	private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
-	private static byte[] buffer;
-	private static int offset;
-	private static int maxoff;
-	private static int index;
-	private static S57field field;
-	private static String aall = "US-ASCII";
-	private static String nall = "US-ASCII";
-	public static int rnum;
-	
-	private static S57conv findSubf(S57subf subf) {
-		ArrayList<S57subf> subs = fields.get(field);
-		boolean wrap = false;
-		while (true) {
-			if (index == subs.size()) {
-				if (!wrap) {
-					index = 0;
-					wrap = true;
-				} else {
-					System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
-					System.exit(-1);
-				}
-			}
-			S57subf sub = subs.get(index++);
-			S57conv conv = convs.get(sub);
-			if (sub == subf) {
-				return conv;
-			} else {
-				offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
-			}
-		}
-	}
-	
-	public static void setField(byte[] buf, int off, S57field fld, int len) {
-		buffer = buf;
-		offset = off;
-		maxoff = off + len - 1;
-		field = fld;
-		index = 0;
-	}
-	
-	public static boolean more() {
-		return (offset < maxoff);
-	}
-	
-	public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
-		buffer = buf;
-		offset = off;
-		index = 0;
-		return decSubf(fld, subf);
-	}
-	
-	public static Object decSubf(S57field fld, S57subf subf) {
-		field = fld;
-		index = 0;
-		return decSubf(subf);
-	}
-
-	public static Object decSubf(S57subf subf) {
-		S57conv conv = findSubf(subf);
-		if (conv.bin == 0) {
-			String str = "";
-			int i = 0;
-			if (conv.asc == 0) {
-				for (i=0; buffer[offset+i] != 0x1f; i++) {}
-				try {
-					String charset = "";
-					if (field == S57field.ATTF) charset = aall;
-					else if (field == S57field.NATF) charset = nall;
-					else charset = "US-ASCII";
-					str = new String(buffer, offset, i, charset);
-				} catch (UnsupportedEncodingException e) {
-					e.printStackTrace();
-				}
-				offset += i + 1;
-			} else {
-				str = new String(buffer, offset, conv.asc);
-				offset += conv.asc;
-			}
-			return str;
-		} else {
-			int f = Math.abs(conv.bin);
-			if (f < 5) {
-				long val = buffer[offset + --f];
-				if (conv.bin > 0)
-					val &= 0xff;
-				while (f > 0) {
-					val = (val << 8) + (buffer[offset + --f] & 0xff);
-				}
-				offset += Math.abs(conv.bin);
-				if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
-					String charset = "";
-					switch ((int)val) {
-					case 0:
-						charset = "US-ASCII";
-						break;
-					case 1:
-						charset = "ISO-8859-1";
-						break;
-					case 2:
-						charset = "UTF-16LE";
-						break;
-					}
-					if (subf == S57subf.NALL) {
-						nall = charset;
-					} else {
-						aall = charset;
-					}
-				}
-				return val;
-			} else {
-				if (f == 5) {
-					long val = buffer[offset++] & 0xff;
-					f--;
-					while (f > 0) {
-						val = (val << 8) + (buffer[offset + --f] & 0xff);
-					}
-					offset += 4;
-					return val;
-				} else {
-					long val = buffer[offset++] & 0xff;
-					val = (val << 8) + (buffer[offset++] & 0xff);
-					f = 4;
-					while (f > 0) {
-						val = (val << 8) + (buffer[offset + --f] & 0xff);
-					}
-					offset += 4;
-					f = 2;
-					while (f > 0) {
-						val = (val << 8) + (buffer[offset + --f] & 0xff);
-					}
-					offset += 2;
-					return val;
-				}
-			}
-		}
-	}
-
-	public static byte[] encSubf(S57subf subf, Object val) {
-		S57conv conv = convs.get(subf);
-		if ((conv.bin == 0) || asc) {
-			String sval = "";
-			if (val instanceof String) {
-				sval = (String) val;
-			} else if (val instanceof Integer) {
-				sval = ((Integer)val).toString();
-			} else if (val instanceof Long) {
-				sval = ((Long)val).toString();
-			} else if (val instanceof Double) {
-				sval = ((Double)val).toString();
-			}
-			index = sval.length();
-			try {
-				buffer = ((String) sval + " ").getBytes("ISO-8859-1");
-			} catch (Exception e) {
-				System.err.println(e.getMessage());
-				System.exit(-1);
-			}
-			if (conv.asc == 0) {
-				buffer[index] = 0x01f;
-			} else {
-				buffer = Arrays.copyOf(buffer, conv.asc);
-				while (index < buffer.length) {
-					buffer[index++] = ' ';
-				}
-			}
-		} else {
-			int f = Math.abs(conv.bin);
-			long lval;
-			if (val instanceof String) {
-				lval = Long.parseLong((String)val);
-			} else	if (val instanceof Double) {
-				double dval = (double) val;
-				lval = (long) dval;
-			} else	if (val instanceof Integer) {
-				lval = (int) val;
-			} else {
-				lval = (long) val;
-			}
-			buffer = new byte[f];
-			for (int i = 0; i < f; i++) {
-				buffer[i] = (byte) (lval & 0xff);
-				lval >>= 8;
-			}
-		}
-		return buffer;
-	}
-
-	static class Index {
-		byte[] field;
-		int length;
-		int offset;
-		Index (byte[] id, int l, int o) {
-			field = id;
-			length = l;
-			offset = o;
-		}
-	}
-	
-	public static class Fparams {
-		public S57field field;
-		public Object[] params;
-		public Fparams(S57field f, Object[] p) {
-			field = f;
-			params = p;
-		}
-	};
-
-	static boolean asc = false;
-	
-	public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
-		asc = true;
-		return encRecord(Integer.parseInt(i8rn), fparams);
-	}
-	
-	public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
-		ArrayList<Index> index = new ArrayList<>();
-		int offset = 3;
-		int maxlen = 3;
-		byte[] buf = encSubf(S57subf.I8RN, i8rn);
-		buf = Arrays.copyOf(buf, 3);
-		buf[2] = 0x1e;
-		index.add(new Index("0001".getBytes(), 3, 0));
-		for (Fparams sfparams : fparams) {
-			for (int ip = 0; ip < sfparams.params.length; ) {
-				for (S57subf subf : fields.get(sfparams.field)) {
-					byte[] next = encSubf(subf, sfparams.params[ip++]);
-					buf = Arrays.copyOf(buf, (buf.length + next.length));
-					System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
-				}
-			}
-			buf = Arrays.copyOf(buf, (buf.length + 1));
-			buf[buf.length-1] = 0x1e;
-			int flen = buf.length - offset;
-			index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
-			maxlen = (flen > maxlen) ? flen : maxlen;
-			offset += flen;
-		}
-		int mlen = String.valueOf(maxlen).length();
-		String ffmt = "%0" + mlen + "d";
-		int olen = String.valueOf(offset).length();
-		String ofmt = "%0" + olen + "d";
-		int ilen = 4 + mlen + olen;
-		int isiz = (ilen * index.size()) + 1;
-		byte[] ibuf = new byte[isiz];
-		int i = 0;
-		for (Index item : index) {
-			for (byte ch : item.field) {
-				ibuf[i++] = ch;
-			}
-			byte[] digits = String.format(ffmt, item.length).getBytes();
-			for (byte ch : digits) {
-				ibuf[i++] = ch;
-			}
-			digits = String.format(ofmt, item.offset).getBytes();
-			for (byte ch : digits) {
-				ibuf[i++] = ch;
-			}
-		}
-		ibuf[i] = 0x1e;
-		byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
-		System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
-		System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
-		fbuf[20] = (byte)(mlen + 0x30);
-		fbuf[21] = (byte)(olen + 0x30);
-		System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
-		System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
-		asc = false;
-		return fbuf;
-	}
-
-	enum Prims { N, P, L, A, PA, PL, LA, PLA }
-	private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
-	static {
-		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);
-		S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
-		S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
-		S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
-		S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
-		S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
-		S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
-		S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
-		S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
-		S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
-		S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
-		S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
-		S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
-		S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
-		S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
-		S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
-		S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
-		S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
-		S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
-		S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
-		S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
-		S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
-		S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
-		S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
-		S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
-		S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
-		S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
-		S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
-		S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
-		S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
-		S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
-		S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
-		S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
-		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);
-		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);
-		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);
-		S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
-		S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
-		S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
-		S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
-		S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
-		S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
-		S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
-		S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
-		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); 
-	}
-
-	public static void S57geoms(S57map map) {
-		for (ArrayList<Feature> list : map.features.values()) {
-			for (Feature feature : list) {
-				switch (S57prims.get(feature.type)) {
-				case N:
-					break;
-				case P:
-					if (feature.geom.prim != Pflag.POINT) {
-//						Snode node = feature.geom.centre;
-//						node.flg = Nflag.ISOL;
-//						map.nodes.put(++map.xref, node);
-//						feature.geom = map.new Geom(Pflag.POINT);
-//						feature.geom.centre = node;
-//						feature.geom.elems.add(map.new Prim(map.xref));
-					}
-					break;
-				case L:
-					break;
-				case A:
-					break;
-				case PA:
-					break;
-				case PL:
-					break;
-				case LA:
-					if (feature.geom.prim == Pflag.POINT) {
-//						list.remove(feature);
-					}
-					break;
-				case PLA:
-					// No changes needed
-					break;
-				}
-			}
-		}
-	}
+    // CHECKSTYLE.OFF: LineLength
+
+    public static class S57conv {
+        int asc;    // 0=A(), 1+=A(n)
+        int bin;    // 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE)
+        S57conv(int a, int b) {
+            asc = a; bin = b;
+        }
+    }
+
+    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,
+        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,
+        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,
+        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,
+        VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
+
+    private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
+    static {
+        convs.put(S57subf.I8RN, new S57conv(5, 2));
+        convs.put(S57subf.RCNM, new S57conv(2, 1)); convs.put(S57subf.RCID, new S57conv(10, 4)); convs.put(S57subf.EXPP, new S57conv(1, 1));
+        convs.put(S57subf.INTU, new S57conv(1, 1)); convs.put(S57subf.DSNM, new S57conv(0, 0)); convs.put(S57subf.EDTN, new S57conv(0, 0));
+        convs.put(S57subf.UPDN, new S57conv(0, 0)); convs.put(S57subf.UADT, new S57conv(8, 0)); convs.put(S57subf.ISDT, new S57conv(8, 0));
+        convs.put(S57subf.STED, new S57conv(4, 0)); convs.put(S57subf.PRSP, new S57conv(3, 1)); convs.put(S57subf.PSDN, new S57conv(0, 0));
+        convs.put(S57subf.PRED, new S57conv(0, 0)); convs.put(S57subf.PROF, new S57conv(2, 1)); convs.put(S57subf.AGEN, new S57conv(2, 2));
+        convs.put(S57subf.COMT, new S57conv(0, 0)); convs.put(S57subf.DSTR, new S57conv(2, 1)); convs.put(S57subf.AALL, new S57conv(1, 1));
+        convs.put(S57subf.NALL, new S57conv(1, 1)); convs.put(S57subf.NOMR, new S57conv(0, 4)); convs.put(S57subf.NOCR, new S57conv(0, 4));
+        convs.put(S57subf.NOGR, new S57conv(0, 4)); convs.put(S57subf.NOLR, new S57conv(0, 4)); convs.put(S57subf.NOIN, new S57conv(0, 4));
+        convs.put(S57subf.NOCN, new S57conv(0, 4)); convs.put(S57subf.NOED, new S57conv(0, 4)); convs.put(S57subf.NOFA, new S57conv(0, 4));
+        convs.put(S57subf.HDAT, new S57conv(3, 1)); convs.put(S57subf.VDAT, new S57conv(2, 1)); convs.put(S57subf.SDAT, new S57conv(2, 1));
+        convs.put(S57subf.CSCL, new S57conv(0, 4)); convs.put(S57subf.DUNI, new S57conv(2, 1)); convs.put(S57subf.HUNI, new S57conv(2, 1));
+        convs.put(S57subf.PUNI, new S57conv(2, 1)); convs.put(S57subf.COUN, new S57conv(2, 1)); convs.put(S57subf.COMF, new S57conv(0, 4));
+        convs.put(S57subf.SOMF, new S57conv(0, 4)); convs.put(S57subf.PROJ, new S57conv(3, 1)); convs.put(S57subf.PRP1, new S57conv(0, -4));
+        convs.put(S57subf.PRP2, new S57conv(0, -4)); convs.put(S57subf.PRP3, new S57conv(0, -4)); convs.put(S57subf.PRP4, new S57conv(0, -4));
+        convs.put(S57subf.FEAS, new S57conv(0, -4)); convs.put(S57subf.FNOR, new S57conv(0, -4)); convs.put(S57subf.FPMF, new S57conv(0, 4));
+        convs.put(S57subf.RPID, new S57conv(1, 1)); convs.put(S57subf.RYCO, new S57conv(0, -4)); convs.put(S57subf.RXCO, new S57conv(0, -4));
+        convs.put(S57subf.CURP, new S57conv(2, 1)); convs.put(S57subf.RXVL, new S57conv(0, -4)); convs.put(S57subf.RYVL, new S57conv(0, -4));
+        convs.put(S57subf.PRCO, new S57conv(2, 2)); convs.put(S57subf.ESDT, new S57conv(8, 0)); convs.put(S57subf.LSDT, new S57conv(8, 0));
+        convs.put(S57subf.DCRT, new S57conv(0, 0)); convs.put(S57subf.CODT, new S57conv(8, 0)); convs.put(S57subf.PACC, new S57conv(0, 4));
+        convs.put(S57subf.HACC, new S57conv(0, 4)); convs.put(S57subf.SACC, new S57conv(0, 4)); convs.put(S57subf.FILE, new S57conv(0, 0));
+        convs.put(S57subf.LFIL, new S57conv(0, 0)); convs.put(S57subf.VOLM, new S57conv(0, 0)); convs.put(S57subf.IMPL, new S57conv(3, 0));
+        convs.put(S57subf.SLAT, new S57conv(0, 0)); convs.put(S57subf.WLON, new S57conv(0, 0)); convs.put(S57subf.NLAT, new S57conv(0, 0));
+        convs.put(S57subf.ELON, new S57conv(0, 0)); convs.put(S57subf.CRCS, new S57conv(0, 0)); convs.put(S57subf.NAM1, new S57conv(12, 5));
+        convs.put(S57subf.NAM2, new S57conv(12, 5)); convs.put(S57subf.OORA, new S57conv(1, 1)); convs.put(S57subf.OAAC, new S57conv(6, 0));
+        convs.put(S57subf.OACO, new S57conv(5, 2)); convs.put(S57subf.OALL, new S57conv(0, 0)); convs.put(S57subf.OATY, new S57conv(1, 1));
+        convs.put(S57subf.DEFN, new S57conv(0, 0)); convs.put(S57subf.AUTH, new S57conv(2, 2)); convs.put(S57subf.RFTP, new S57conv(2, 1));
+        convs.put(S57subf.RFVL, new S57conv(0, 0)); convs.put(S57subf.ATLB, new S57conv(5, 2)); convs.put(S57subf.ATDO, new S57conv(1, 1));
+        convs.put(S57subf.ADMU, new S57conv(0, 0)); convs.put(S57subf.ADFT, new S57conv(0, 0)); convs.put(S57subf.RAVA, new S57conv(1, 1));
+        convs.put(S57subf.DVAL, new S57conv(0, 0)); convs.put(S57subf.DVSD, new S57conv(0, 0)); convs.put(S57subf.OBLB, new S57conv(5, 2));
+        convs.put(S57subf.ASET, new S57conv(1, 1)); convs.put(S57subf.PRIM, new S57conv(1, 1)); convs.put(S57subf.GRUP, new S57conv(3, 1));
+        convs.put(S57subf.OBJL, new S57conv(5, 2)); convs.put(S57subf.RVER, new S57conv(3, 2)); convs.put(S57subf.RUIN, new S57conv(1, 1));
+        convs.put(S57subf.FIDN, new S57conv(10, 4)); convs.put(S57subf.FIDS, new S57conv(5, 2)); convs.put(S57subf.ATTL, new S57conv(5, 2));
+        convs.put(S57subf.ATVL, new S57conv(0, 0)); convs.put(S57subf.FFUI, new S57conv(1, 1)); convs.put(S57subf.FFIX, new S57conv(0, 2));
+        convs.put(S57subf.NFPT, new S57conv(0, 2)); convs.put(S57subf.LNAM, new S57conv(17, 8)); convs.put(S57subf.RIND, new S57conv(0, 1));
+        convs.put(S57subf.FSUI, new S57conv(1, 1)); convs.put(S57subf.FSIX, new S57conv(0, 2)); convs.put(S57subf.NSPT, new S57conv(0, 2));
+        convs.put(S57subf.NAME, new S57conv(12, 5)); convs.put(S57subf.ORNT, new S57conv(1, 1)); convs.put(S57subf.USAG, new S57conv(1, 1));
+        convs.put(S57subf.MASK, new S57conv(1, 1)); convs.put(S57subf.VPUI, new S57conv(1, 1)); convs.put(S57subf.VPIX, new S57conv(0, 2));
+        convs.put(S57subf.NVPT, new S57conv(0, 2)); convs.put(S57subf.TOPI, new S57conv(1, 1)); convs.put(S57subf.CCUI, new S57conv(1, 1));
+        convs.put(S57subf.CCIX, new S57conv(0, 2)); convs.put(S57subf.CCNC, new S57conv(0, 2)); convs.put(S57subf.YCOO, new S57conv(0, -4));
+        convs.put(S57subf.XCOO, new S57conv(0, -4)); convs.put(S57subf.VE3D, new S57conv(0, -4)); convs.put(S57subf.ATYP, new S57conv(1, 1));
+        convs.put(S57subf.SURF, new S57conv(1, 1)); convs.put(S57subf.ORDR, new S57conv(1, 1)); convs.put(S57subf.RESO, new S57conv(0, 4));
+        convs.put(S57subf.STPT, new S57conv(0, 0)); convs.put(S57subf.CTPT, new S57conv(0, 0)); convs.put(S57subf.ENPT, new S57conv(0, 0));
+        convs.put(S57subf.CDPM, new S57conv(0, 0)); convs.put(S57subf.CDPR, new S57conv(0, 0));
+    }
+
+    public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
+        FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
+
+    private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
+    private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
+            S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
+    private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
+            S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA));
+    private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
+            S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT));
+    private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
+            S57subf.FPMF, S57subf.COMT));
+    private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
+            S57subf.COMT));
+    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));
+    private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT));
+    private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
+            S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT));
+    private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT));
+    private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
+            S57subf.DEFN, S57subf.AUTH, S57subf.COMT));
+    private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
+    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));
+    private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH));
+    private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
+    private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB));
+    private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH));
+    private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN));
+    private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS));
+    private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
+    private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
+    private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
+    private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT));
+    private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT));
+    private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT));
+    private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK));
+    private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN));
+    private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
+    private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT));
+    private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK));
+    private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC));
+    private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
+    private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D));
+    private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF));
+    private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO));
+    private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO));
+    private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
+
+    private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
+    static {
+        fields.put(S57field.I8RI, S57i8ri);
+        fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
+        fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
+        fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
+        fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
+        fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
+        fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
+        fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
+        fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
+        fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d);
+    }
+
+    private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
+    private static byte[] buffer;
+    private static int offset;
+    private static int maxoff;
+    private static int index;
+    private static S57field field;
+    private static String aall = "US-ASCII";
+    private static String nall = "US-ASCII";
+    public static int rnum;
+
+    private static S57conv findSubf(S57subf subf) {
+        ArrayList<S57subf> subs = fields.get(field);
+        boolean wrap = false;
+        while (true) {
+            if (index == subs.size()) {
+                if (!wrap) {
+                    index = 0;
+                    wrap = true;
+                } else {
+                    System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
+                    System.exit(-1);
+                }
+            }
+            S57subf sub = subs.get(index++);
+            S57conv conv = convs.get(sub);
+            if (sub == subf) {
+                return conv;
+            } else {
+                offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
+            }
+        }
+    }
+
+    public static void setField(byte[] buf, int off, S57field fld, int len) {
+        buffer = buf;
+        offset = off;
+        maxoff = off + len - 1;
+        field = fld;
+        index = 0;
+    }
+
+    public static boolean more() {
+        return (offset < maxoff);
+    }
+
+    public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
+        buffer = buf;
+        offset = off;
+        index = 0;
+        return decSubf(fld, subf);
+    }
+
+    public static Object decSubf(S57field fld, S57subf subf) {
+        field = fld;
+        index = 0;
+        return decSubf(subf);
+    }
+
+    public static Object decSubf(S57subf subf) {
+        S57conv conv = findSubf(subf);
+        if (conv.bin == 0) {
+            String str = "";
+            int i = 0;
+            if (conv.asc == 0) {
+                for (i = 0; buffer[offset+i] != 0x1f; i++) { }
+                try {
+                    String charset = "";
+                    if (field == S57field.ATTF) charset = aall;
+                    else if (field == S57field.NATF) charset = nall;
+                    else charset = "US-ASCII";
+                    str = new String(buffer, offset, i, charset);
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                offset += i + 1;
+            } else {
+                str = new String(buffer, offset, conv.asc);
+                offset += conv.asc;
+            }
+            return str;
+        } else {
+            int f = Math.abs(conv.bin);
+            if (f < 5) {
+                long val = buffer[offset + --f];
+                if (conv.bin > 0)
+                    val &= 0xff;
+                while (f > 0) {
+                    val = (val << 8) + (buffer[offset + --f] & 0xff);
+                }
+                offset += Math.abs(conv.bin);
+                if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
+                    String charset = "";
+                    switch ((int) val) {
+                    case 0:
+                        charset = "US-ASCII";
+                        break;
+                    case 1:
+                        charset = "ISO-8859-1";
+                        break;
+                    case 2:
+                        charset = "UTF-16LE";
+                        break;
+                    }
+                    if (subf == S57subf.NALL) {
+                        nall = charset;
+                    } else {
+                        aall = charset;
+                    }
+                }
+                return val;
+            } else {
+                if (f == 5) {
+                    long val = buffer[offset++] & 0xff;
+                    f--;
+                    while (f > 0) {
+                        val = (val << 8) + (buffer[offset + --f] & 0xff);
+                    }
+                    offset += 4;
+                    return val;
+                } else {
+                    long val = buffer[offset++] & 0xff;
+                    val = (val << 8) + (buffer[offset++] & 0xff);
+                    f = 4;
+                    while (f > 0) {
+                        val = (val << 8) + (buffer[offset + --f] & 0xff);
+                    }
+                    offset += 4;
+                    f = 2;
+                    while (f > 0) {
+                        val = (val << 8) + (buffer[offset + --f] & 0xff);
+                    }
+                    offset += 2;
+                    return val;
+                }
+            }
+        }
+    }
+
+    public static byte[] encSubf(S57subf subf, Object val) {
+        S57conv conv = convs.get(subf);
+        if ((conv.bin == 0) || asc) {
+            String sval = "";
+            if (val instanceof String) {
+                sval = (String) val;
+            } else if (val instanceof Integer) {
+                sval = ((Integer) val).toString();
+            } else if (val instanceof Long) {
+                sval = ((Long) val).toString();
+            } else if (val instanceof Double) {
+                sval = ((Double) val).toString();
+            }
+            index = sval.length();
+            try {
+                buffer = (sval + " ").getBytes("ISO-8859-1");
+            } catch (Exception e) {
+                System.err.println(e.getMessage());
+                System.exit(-1);
+            }
+            if (conv.asc == 0) {
+                buffer[index] = 0x01f;
+            } else {
+                buffer = Arrays.copyOf(buffer, conv.asc);
+                while (index < buffer.length) {
+                    buffer[index++] = ' ';
+                }
+            }
+        } else {
+            int f = Math.abs(conv.bin);
+            long lval;
+            if (val instanceof String) {
+                lval = Long.parseLong((String) val);
+            } else if (val instanceof Double) {
+                double dval = (double) val;
+                lval = (long) dval;
+            } else if (val instanceof Integer) {
+                lval = (int) val;
+            } else {
+                lval = (long) val;
+            }
+            buffer = new byte[f];
+            for (int i = 0; i < f; i++) {
+                buffer[i] = (byte) (lval & 0xff);
+                lval >>= 8;
+            }
+        }
+        return buffer;
+    }
+
+    static class Index {
+        byte[] field;
+        int length;
+        int offset;
+        Index(byte[] id, int l, int o) {
+            field = id;
+            length = l;
+            offset = o;
+        }
+    }
+
+    public static class Fparams {
+        public S57field field;
+        public Object[] params;
+        public Fparams(S57field f, Object[] p) {
+            field = f;
+            params = p;
+        }
+    }
+
+    static boolean asc = false;
+
+    public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
+        asc = true;
+        return encRecord(Integer.parseInt(i8rn), fparams);
+    }
+
+    public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
+        ArrayList<Index> index = new ArrayList<>();
+        int offset = 3;
+        int maxlen = 3;
+        byte[] buf = encSubf(S57subf.I8RN, i8rn);
+        buf = Arrays.copyOf(buf, 3);
+        buf[2] = 0x1e;
+        index.add(new Index("0001".getBytes(), 3, 0));
+        for (Fparams sfparams : fparams) {
+            for (int ip = 0; ip < sfparams.params.length;) {
+                for (S57subf subf : fields.get(sfparams.field)) {
+                    byte[] next = encSubf(subf, sfparams.params[ip++]);
+                    buf = Arrays.copyOf(buf, (buf.length + next.length));
+                    System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
+                }
+            }
+            buf = Arrays.copyOf(buf, (buf.length + 1));
+            buf[buf.length-1] = 0x1e;
+            int flen = buf.length - offset;
+            index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
+            maxlen = (flen > maxlen) ? flen : maxlen;
+            offset += flen;
+        }
+        int mlen = String.valueOf(maxlen).length();
+        String ffmt = "%0" + mlen + "d";
+        int olen = String.valueOf(offset).length();
+        String ofmt = "%0" + olen + "d";
+        int ilen = 4 + mlen + olen;
+        int isiz = (ilen * index.size()) + 1;
+        byte[] ibuf = new byte[isiz];
+        int i = 0;
+        for (Index item : index) {
+            for (byte ch : item.field) {
+                ibuf[i++] = ch;
+            }
+            byte[] digits = String.format(ffmt, item.length).getBytes();
+            for (byte ch : digits) {
+                ibuf[i++] = ch;
+            }
+            digits = String.format(ofmt, item.offset).getBytes();
+            for (byte ch : digits) {
+                ibuf[i++] = ch;
+            }
+        }
+        ibuf[i] = 0x1e;
+        byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
+        System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
+        System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
+        fbuf[20] = (byte) (mlen + 0x30);
+        fbuf[21] = (byte) (olen + 0x30);
+        System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
+        System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
+        asc = false;
+        return fbuf;
+    }
+
+    enum Prims { N, P, L, A, PA, PL, LA, PLA }
+
+    private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
+    static {
+        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);
+        S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
+        S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
+        S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
+        S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
+        S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
+        S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
+        S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
+        S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
+        S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
+        S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
+        S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
+        S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
+        S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
+        S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
+        S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
+        S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
+        S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
+        S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
+        S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
+        S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
+        S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
+        S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
+        S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
+        S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
+        S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
+        S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
+        S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
+        S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
+        S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
+        S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
+        S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
+        S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
+        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);
+        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);
+        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);
+        S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
+        S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
+        S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
+        S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
+        S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
+        S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
+        S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
+        S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
+        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);
+    }
+
+    public static void S57geoms(S57map map) {
+        for (ArrayList<Feature> list : map.features.values()) {
+            for (Feature feature : list) {
+                switch (S57prims.get(feature.type)) {
+                case N:
+                    break;
+                case P:
+                    if (feature.geom.prim != Pflag.POINT) {
+                        //                        Snode node = feature.geom.centre;
+                        //                        node.flg = Nflag.ISOL;
+                        //                        map.nodes.put(++map.xref, node);
+                        //                        feature.geom = map.new Geom(Pflag.POINT);
+                        //                        feature.geom.centre = node;
+                        //                        feature.geom.elems.add(map.new Prim(map.xref));
+                    }
+                    break;
+                case L:
+                    break;
+                case A:
+                    break;
+                case PA:
+                    break;
+                case PL:
+                    break;
+                case LA:
+                    if (feature.geom.prim == Pflag.POINT) {
+                        //                        list.remove(feature);
+                    }
+                    break;
+                case PLA:
+                    // No changes needed
+                    break;
+                }
+            }
+        }
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57dec.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57dec.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57dec.java	(revision 32394)
@@ -13,201 +13,203 @@
 import java.io.IOException;
 
-import s57.S57dat.*;
-import s57.S57map.*;
+import s57.S57dat.S57field;
+import s57.S57dat.S57subf;
+import s57.S57map.Nflag;
 
 public class S57dec { // S57 ENC file input & map conversion
-
-	public static void decodeChart(FileInputStream in, S57map map) throws IOException {
-		S57dat.rnum = 0;
-		byte[] leader = new byte[24];
-		byte[] record = new byte[0];
-		boolean ddr = false;
-		int length = 0;
-		int fields = 0;;
-		int mapfl, mapfp, mapts, entry;
-		String tag;
-		int len;
-		int pos;
-		boolean inFeature = false;
-
-		double comf = 1;
-		double somf = 1;
-		long name = 0;
-		S57map.Nflag nflag = Nflag.ANON;
-		S57map.Pflag pflag = S57map.Pflag.NOSP;
-		long objl = 0;
-		
-		while (in.read(leader) == 24) {
-			try {
-			length = Integer.parseInt(new String(leader, 0, 5)) - 24;
-			record = new byte[length];
-			ddr = (leader[6] == 'L');
-			fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
-			} catch (Exception e) {
-				System.err.println("Invalid file format - Encrypted/compressed ENC file?");
-				System.exit(-1);
-			}
-			mapfl = leader[20] - '0';
-			mapfp = leader[21] - '0';
-			mapts = leader[23] - '0';
-			entry = mapfl + mapfp + mapts;
-			if (in.read(record) != length)
-				break;
-			for (int idx = 0; idx < fields-1; idx += entry) {
-				tag = new String(record, idx, mapts);
-				len = Integer.parseInt(new String(record, idx+mapts, mapfl));
-				pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
-				if (!ddr) {
-					switch (tag.toString()) {
-					case "0001":
-						int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
-//						if (i8rn != ++S57dat.rnum) {
-//							System.err.println("Out of order record ID");
-//							in.close();
-//							System.exit(-1);
-//						}
-						break;
-					case "DSSI":
-						S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
-						S57dat.decSubf(S57subf.NALL);
-						break;
-					case "DSPM":
-						comf = (double) (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
-						somf = (double) (Long) S57dat.decSubf(S57subf.SOMF);
-						break;
-					case "FRID":
-						inFeature = true;
-						switch (((Long)S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
-						case 1:
-							pflag = S57map.Pflag.POINT;
-							break;
-						case 2:
-							pflag = S57map.Pflag.LINE;
-							break;
-						case 3:
-							pflag = S57map.Pflag.AREA;
-							break;
-						default:
-							pflag = S57map.Pflag.NOSP;
-						}
-						objl = (Long)S57dat.decSubf(S57subf.OBJL);
-						break;
-					case "FOID":
-						name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
-						map.newFeature(name, pflag, objl);
-						break;
-					case "ATTF":
-						S57dat.setField(record, fields + pos, S57field.ATTF, len);
-						do {
-							long attl = (Long) S57dat.decSubf(S57subf.ATTL);
-							String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
-							if (!atvl.isEmpty()) {
-								map.newAtt(attl, atvl);
-							}
-						} while (S57dat.more());
-						break;
-					case "FFPT":
-						S57dat.setField(record, fields + pos, S57field.FFPT, len);
-						do {
-							name = (long) S57dat.decSubf(S57subf.LNAM);
-							int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
-							S57dat.decSubf(S57subf.COMT);
-							map.refObj(name, rind);
-						} while (S57dat.more());
-						break;
-					case "FSPT":
-						S57dat.setField(record, fields + pos, S57field.FSPT, len);
-						do {
-							name = (long) S57dat.decSubf(S57subf.NAME) << 16;
-							map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
-							S57dat.decSubf(S57subf.MASK);
-						} while (S57dat.more());
-						break;
-					case "VRID":
-						inFeature = false;
-						name = (long) (Long)S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
-						switch ((int) name) {
-						case 110:
-							nflag = Nflag.ISOL;
-							break;
-						case 120:
-							nflag = Nflag.CONN;
-							break;
-						default:
-							nflag = Nflag.ANON;
-							break;
-						}
-						name <<= 32;
-						name += (long) S57dat.decSubf(S57subf.RCID);
-						name <<= 16;
-						if (nflag == Nflag.ANON) {
-							map.newEdge(name);
-						}
-						break;
-					case "VRPT":
-						S57dat.setField(record, fields + pos, S57field.VRPT, len);
-						do {
-							long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
-							int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
-							map.addConn(conn, topi);
-							S57dat.decSubf(S57subf.MASK);
-						} while (S57dat.more());
-						break;
-					case "SG2D":
-						S57dat.setField(record, fields + pos, S57field.SG2D, len);
-						do {
-							double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
-							double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
-							if (nflag == Nflag.ANON) {
-								map.newNode(++name, lat, lon, nflag);
-							} else {
-								map.newNode(name, lat, lon, nflag);
-							}
-							lat = Math.toRadians(lat);
-							lon = Math.toRadians(lon);
-							if (lat < map.bounds.minlat)
-								map.bounds.minlat = lat;
-							if (lat > map.bounds.maxlat)
-								map.bounds.maxlat = lat;
-							if (lon < map.bounds.minlon)
-								map.bounds.minlon = lon;
-							if (lon > map.bounds.maxlon)
-								map.bounds.maxlon = lon;
-						} while (S57dat.more());
-						break;
-					case "SG3D":
-						S57dat.setField(record, fields + pos, S57field.SG3D, len);
-						do {
-							double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
-							double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
-							double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
-							map.newNode(name++, lat, lon, depth);
-							lat = Math.toRadians(lat);
-							lon = Math.toRadians(lon);
-							if (lat < map.bounds.minlat)
-								map.bounds.minlat = lat;
-							if (lat > map.bounds.maxlat)
-								map.bounds.maxlat = lat;
-							if (lon < map.bounds.minlon)
-								map.bounds.minlon = lon;
-							if (lon > map.bounds.maxlon)
-								map.bounds.maxlon = lon;
-						} while (S57dat.more());
-						break;
-					default:
-						break;
-					}
-				}
-				if (inFeature) {
-					map.endFeature();
-					inFeature = false;
-				}
-			}
-		}
-		map.endFile();
-		in.close();
-		
-		return;
-	}
-	
+    // CHECKSTYLE.OFF: LineLength
+
+    public static void decodeChart(FileInputStream in, S57map map) throws IOException {
+        S57dat.rnum = 0;
+        byte[] leader = new byte[24];
+        byte[] record = new byte[0];
+        boolean ddr = false;
+        int length = 0;
+        int fields = 0;;
+        int mapfl, mapfp, mapts, entry;
+        String tag;
+        int len;
+        int pos;
+        boolean inFeature = false;
+
+        double comf = 1;
+        double somf = 1;
+        long name = 0;
+        S57map.Nflag nflag = Nflag.ANON;
+        S57map.Pflag pflag = S57map.Pflag.NOSP;
+        long objl = 0;
+
+        while (in.read(leader) == 24) {
+            try {
+                length = Integer.parseInt(new String(leader, 0, 5)) - 24;
+                record = new byte[length];
+                ddr = (leader[6] == 'L');
+                fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
+            } catch (Exception e) {
+                System.err.println("Invalid file format - Encrypted/compressed ENC file?");
+                System.exit(-1);
+            }
+            mapfl = leader[20] - '0';
+            mapfp = leader[21] - '0';
+            mapts = leader[23] - '0';
+            entry = mapfl + mapfp + mapts;
+            if (in.read(record) != length)
+                break;
+            for (int idx = 0; idx < fields-1; idx += entry) {
+                tag = new String(record, idx, mapts);
+                len = Integer.parseInt(new String(record, idx+mapts, mapfl));
+                pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
+                if (!ddr) {
+                    switch (tag.toString()) {
+                    case "0001":
+                        int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
+                        //                        if (i8rn != ++S57dat.rnum) {
+                        //                            System.err.println("Out of order record ID");
+                        //                            in.close();
+                        //                            System.exit(-1);
+                        //                        }
+                        break;
+                    case "DSSI":
+                        S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
+                        S57dat.decSubf(S57subf.NALL);
+                        break;
+                    case "DSPM":
+                        comf = (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
+                        somf = (Long) S57dat.decSubf(S57subf.SOMF);
+                        break;
+                    case "FRID":
+                        inFeature = true;
+                        switch (((Long) S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
+                        case 1:
+                            pflag = S57map.Pflag.POINT;
+                            break;
+                        case 2:
+                            pflag = S57map.Pflag.LINE;
+                            break;
+                        case 3:
+                            pflag = S57map.Pflag.AREA;
+                            break;
+                        default:
+                            pflag = S57map.Pflag.NOSP;
+                        }
+                        objl = (Long) S57dat.decSubf(S57subf.OBJL);
+                        break;
+                    case "FOID":
+                        name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
+                        map.newFeature(name, pflag, objl);
+                        break;
+                    case "ATTF":
+                        S57dat.setField(record, fields + pos, S57field.ATTF, len);
+                        do {
+                            long attl = (Long) S57dat.decSubf(S57subf.ATTL);
+                            String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
+                            if (!atvl.isEmpty()) {
+                                map.newAtt(attl, atvl);
+                            }
+                        } while (S57dat.more());
+                        break;
+                    case "FFPT":
+                        S57dat.setField(record, fields + pos, S57field.FFPT, len);
+                        do {
+                            name = (long) S57dat.decSubf(S57subf.LNAM);
+                            int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
+                            S57dat.decSubf(S57subf.COMT);
+                            map.refObj(name, rind);
+                        } while (S57dat.more());
+                        break;
+                    case "FSPT":
+                        S57dat.setField(record, fields + pos, S57field.FSPT, len);
+                        do {
+                            name = (long) S57dat.decSubf(S57subf.NAME) << 16;
+                            map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
+                            S57dat.decSubf(S57subf.MASK);
+                        } while (S57dat.more());
+                        break;
+                    case "VRID":
+                        inFeature = false;
+                        name = (Long) S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
+                        switch ((int) name) {
+                        case 110:
+                            nflag = Nflag.ISOL;
+                            break;
+                        case 120:
+                            nflag = Nflag.CONN;
+                            break;
+                        default:
+                            nflag = Nflag.ANON;
+                            break;
+                        }
+                        name <<= 32;
+                        name += (long) S57dat.decSubf(S57subf.RCID);
+                        name <<= 16;
+                        if (nflag == Nflag.ANON) {
+                            map.newEdge(name);
+                        }
+                        break;
+                    case "VRPT":
+                        S57dat.setField(record, fields + pos, S57field.VRPT, len);
+                        do {
+                            long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
+                            int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
+                            map.addConn(conn, topi);
+                            S57dat.decSubf(S57subf.MASK);
+                        } while (S57dat.more());
+                        break;
+                    case "SG2D":
+                        S57dat.setField(record, fields + pos, S57field.SG2D, len);
+                        do {
+                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
+                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
+                            if (nflag == Nflag.ANON) {
+                                map.newNode(++name, lat, lon, nflag);
+                            } else {
+                                map.newNode(name, lat, lon, nflag);
+                            }
+                            lat = Math.toRadians(lat);
+                            lon = Math.toRadians(lon);
+                            if (lat < map.bounds.minlat)
+                                map.bounds.minlat = lat;
+                            if (lat > map.bounds.maxlat)
+                                map.bounds.maxlat = lat;
+                            if (lon < map.bounds.minlon)
+                                map.bounds.minlon = lon;
+                            if (lon > map.bounds.maxlon)
+                                map.bounds.maxlon = lon;
+                        } while (S57dat.more());
+                        break;
+                    case "SG3D":
+                        S57dat.setField(record, fields + pos, S57field.SG3D, len);
+                        do {
+                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
+                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
+                            double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
+                            map.newNode(name++, lat, lon, depth);
+                            lat = Math.toRadians(lat);
+                            lon = Math.toRadians(lon);
+                            if (lat < map.bounds.minlat)
+                                map.bounds.minlat = lat;
+                            if (lat > map.bounds.maxlat)
+                                map.bounds.maxlat = lat;
+                            if (lon < map.bounds.minlon)
+                                map.bounds.minlon = lon;
+                            if (lon > map.bounds.maxlon)
+                                map.bounds.maxlon = lon;
+                        } while (S57dat.more());
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                if (inFeature) {
+                    map.endFeature();
+                    inFeature = false;
+                }
+            }
+        }
+        map.endFile();
+        in.close();
+
+        return;
+    }
+
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57enc.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57enc.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57enc.java	(revision 32394)
@@ -21,363 +21,370 @@
 import java.util.zip.CRC32;
 
-import s57.S57obj.*;
+import s57.S57att.Att;
+import s57.S57dat.Fparams;
+import s57.S57dat.S57field;
+import s57.S57map.AttMap;
+import s57.S57map.Feature;
+import s57.S57map.Nflag;
+import s57.S57map.ObjTab;
+import s57.S57map.Pflag;
+import s57.S57map.Prim;
+import s57.S57obj.Obj;
 import s57.S57val.AttVal;
-import s57.S57att.Att;
-import s57.S57dat.*;
-import s57.S57map.*;
 
 public class S57enc { // S57 ENC file generation
-
-	private static final byte[] header = {
-		
-		'0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
-		'0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
-		'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
-		'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
-		'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
-		'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
-		'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
-		'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
-		'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
-		// File control field
-		'0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
-		'0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
-		'0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
-		'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
-		'0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
-		'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
-		// Record identifier fields
-		'0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
-		'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
-		'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
-		'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
-		'!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
-		'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
-		'4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
-		',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
-		'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
-		'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
-		'!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
-		'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
-		't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
-		'!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
-		'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
-		'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
-		'1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
-		'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
-		'!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
-		'(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
-		'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
-		'!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
-		't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
-		'(', 'b', '1', '2', ',', 'A', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
-		't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
-		'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
-		' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
-		'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
-		')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
-		' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
-		'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
-		'(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
-		'1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
-		'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
-		'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
-		'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
-		'1', '2', ',', 'A', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
-		'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
-		'!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
-		'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
-		'2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
-		'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
-		'!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
-	};
-	
-	static final double COMF=10000000;
-	static final double SOMF=10;
-	
-	static String file = "0S000000.000";
-	static int intu = 0;
-	static String code = "0S";
-	static int agen = 3878;
-	static int cscl = 10000;
-	static int vdat = 23;
-	static int duni = 1;
-	static int huni = 1;
-	
-	static int idx;
-	static int recs;
-	
-	static int isols;
-	static int conns;
-	static int metas;
-	static int geos;
-	static int edges;
-	
-	static long hash(long val) {
-		byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
-		CRC32 crc = new CRC32();
-		crc.update(bval);
-		return crc.getValue();
-	}
-
-	public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
-		
-		for (Entry<String, String> entry : meta.entrySet()) {
-			try {
-				switch (entry.getKey()) {
-				case "FILE":
-					file = entry.getValue();
-					break;
-				case "INTU":
-					intu = Integer.parseInt(entry.getValue());
-					break;
-				case "AGEN":
-					String[] tokens = entry.getValue().split("/");
-					code = tokens[0];
-					agen = Integer.parseInt(tokens[1]);
-					break;
-				case "VDAT":
-					vdat = Integer.parseInt(entry.getValue());
-					break;
-				case "CSCL":
-					cscl = Integer.parseInt(entry.getValue());
-					break;
-				case "DUNI":
-					duni = Integer.parseInt(entry.getValue());
-					break;
-				case "HUNI":
-					huni = Integer.parseInt(entry.getValue());
-					break;
-				}
-			} catch (Exception e) {
-				System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
-				System.exit(-1);
-			}
-		}
-		
-		//M_COVR & MNSYS in BB if not in map
-		if (!map.features.containsKey(Obj.M_COVR)) {
-			S57osm.OSMmeta(map);
-		}
-		
-		S57dat.S57geoms(map);
-
-		byte[] record;
-		ArrayList<Fparams> fields;
-
-		isols = conns = metas = geos = edges = 0;
-		String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
-		ArrayList<Fparams> ds = new ArrayList<>();
-		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" }));
-		ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
-		ArrayList<Fparams> dp = new ArrayList<>();
-		dp.add(new Fparams(S57field.DSPM, new Object[] { 20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
-
-		System.arraycopy(header, 0, buf, 0, header.length);
-		idx = header.length;
-		record = S57dat.encRecord(1, ds);
-		System.arraycopy(record, 0, buf, idx, record.length);
-		idx += record.length;
-		record = S57dat.encRecord(2, dp);
-		System.arraycopy(record, 0, buf, idx, record.length);
-		idx += record.length;
-		recs = 3;
-
-		// Depths
-		Object[] depths = new Object[0];
-		for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
-			S57map.Snode node = entry.getValue();
-			if (node.flg == Nflag.DPTH) {
-				Object[] dval = new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
-				depths = Arrays.copyOf(depths, (depths.length + dval.length));
-				System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
-			}
-		}
-		if (depths.length > 0) {
-			fields = new ArrayList<>();
-			fields.add(new Fparams(S57field.VRID, new Object[] { 110, -2, 1, 1 }));
-			fields.add(new Fparams(S57field.SG3D, depths));
-			record = S57dat.encRecord(recs++, fields);
-			System.arraycopy(record, 0, buf, idx, record.length);
-			idx += record.length;
-			isols++;
-		}
-
-		// Isolated nodes
-		for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
-			S57map.Snode node = entry.getValue();
-			if (node.flg == Nflag.ISOL) {
-				fields = new ArrayList<>();
-				fields.add(new Fparams(S57field.VRID, new Object[] { 110, hash(entry.getKey()), 1, 1 }));
-				fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
-				record = S57dat.encRecord(recs++, fields);
-				System.arraycopy(record, 0, buf, idx, record.length);
-				idx += record.length;
-				isols++;
-			}
-		}
-
-		// Connected nodes
-		for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
-			S57map.Snode node = entry.getValue();
-			if (node.flg == Nflag.CONN) {
-				fields = new ArrayList<>();
-				fields.add(new Fparams(S57field.VRID, new Object[] { 120, hash(entry.getKey()), 1, 1 }));
-				fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
-				record = S57dat.encRecord(recs++, fields);
-				System.arraycopy(record, 0, buf, idx, record.length);
-				idx += record.length;
-				conns++;
-			}
-		}
-
-		// Edges
-		for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
-			S57map.Edge edge = entry.getValue();
-			fields = new ArrayList<>();
-			fields.add(new Fparams(S57field.VRID, new Object[] { 130, hash(entry.getKey()), 1, 1 }));
-			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 }));
-			Object[] nodes = new Object[0];
-			for (long ref : edge.nodes) {
-				Object[] nval = new Object[] { (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
-				nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
-				System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
-			}
-			if (nodes.length > 0) {
-				fields.add(new Fparams(S57field.SG2D, nodes));
-			}
-			record = S57dat.encRecord(recs++, fields);
-			System.arraycopy(record, 0, buf, idx, record.length);
-			idx += record.length;
-			edges++;
-		}
-
-		// Meta & Geo objects
-		boolean soundings = false;
-		for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
-			Obj obj = entry.getKey();
-			for (Feature feature : entry.getValue()) {
-				if (obj == Obj.SOUNDG) {
-					if (soundings) {
-						continue;
-					} else {
-						soundings = true;
-					}
-				}
-				int prim = feature.geom.prim.ordinal();
-				prim = (prim == 0) ? 255 : prim;
-				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;
-
-				ArrayList<Fparams> geom = new ArrayList<>();
-				int outers = 0;
-				outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
-				for (Prim elem : feature.geom.elems) {
-					if (feature.geom.prim == Pflag.POINT) {
-						if (obj == Obj.SOUNDG) {
-							geom.add(new Fparams(S57field.FSPT, new Object[] { ((-2 << 8) + 110l), 255, 255, 255 }));
-						} else {
-							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 }));
-						}
-					} else {
-						geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + 130l), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
-					}
-				}
-
-				ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
-				ArrayList<Long> slaves = new ArrayList<>();
-				long slaveid = feature.id + 0x0100000000000000l;
-				for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
-					Obj objobj = objs.getKey();
-					boolean master = true;
-					for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
-						ArrayList<Fparams> objatts = new ArrayList<>();
-						master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
-						long id = hash(master ? feature.id : slaveid);
-						objatts.add(new Fparams(S57field.FRID, new Object[] { 100, id, prim, grup, S57obj.encodeType(objobj), 1, 1 }));
-						objatts.add(new Fparams(S57field.FOID, new Object[] { agen, id, 1 }));
-						Object[] attf = new Object[0];
-						Object[] natf = new Object[0];
-						AttMap atts = map.new AttMap();
-						atts.putAll(object.getValue());
-						if (master) {
-							atts.putAll(feature.atts);
-						}
-						for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
-							if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
-								long attl = S57att.encodeAttribute(att.getKey());
-								Object[] next = new Object[] { attl, S57val.encodeValue(att.getValue(), att.getKey()) };
-								if ((attl < 300) || (attl > 304)) {
-									attf = Arrays.copyOf(attf, (attf.length + next.length));
-									System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
-								} else {
-									natf = Arrays.copyOf(natf, (natf.length + next.length));
-									System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
-								}
-							}
-						}
-						if (attf.length > 0) {
-							objatts.add(new Fparams(S57field.ATTF, attf));
-						}
-						if (natf.length > 0) {
-							objatts.add(new Fparams(S57field.NATF, attf));
-						}
-						if (master) {
-							objects.add(objatts);
-						} else {
-							slaves.add(id);
-							objects.add(0, objatts);
-							slaveid += 0x0100000000000000l;
-						}
-					}
-				}
-
-				if (!slaves.isEmpty()) {
-					ArrayList<Fparams> refs = new ArrayList<>();
-					Object[] params = new Object[0];
-					while (!slaves.isEmpty()) {
-						long id = slaves.remove(0);
-						Object[] next = new Object[] { (long) ((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)), 2, "" };
-						params = Arrays.copyOf(params, (params.length + next.length));
-						System.arraycopy(next, 0, params, (params.length - next.length), next.length);
-					}
-					refs.add(new Fparams(S57field.FFPT, params));
-					objects.get(objects.size() - 1).addAll(refs);
-				}
-
-				for (ArrayList<Fparams> object : objects) {
-					object.addAll(geom);
-					record = S57dat.encRecord(recs++, object);
-					System.arraycopy(record, 0, buf, idx, record.length);
-					idx += record.length;
-					if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
-						metas++;
-					} else {
-						geos++;
-					}
-				}
-			}
-		}
-
-		// Re-write DSID/DSSI with final totals
-		ds = new ArrayList<>();
-		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" }));
-		ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
-		record = S57dat.encRecord(1, ds);
-		System.arraycopy(record, 0, buf, header.length, record.length);
-
-		return idx;
-	}
+    // CHECKSTYLE.OFF: LineLength
+
+    private static final byte[] header = {
+
+            '0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
+            '0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
+            'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
+            'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
+            'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
+            'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
+            'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
+            'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
+            'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
+            // File control field
+            '0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
+            '0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
+            '0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
+            'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
+            '0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
+            'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
+            // Record identifier fields
+            '0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
+            'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
+            'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
+            'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
+            '!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
+            'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
+            '4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
+            ',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
+            'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
+            'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
+            '!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
+            'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
+            't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
+            '!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
+            'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
+            'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
+            '1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
+            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
+            '!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
+            '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
+            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
+            '!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
+            't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
+            '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
+            't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
+            'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
+            ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
+            'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
+            ')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
+            ' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
+            'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
+            '(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
+            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
+            'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
+            'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
+            'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
+            '1', '2', ',', 'A', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
+            'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
+            '!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
+            'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
+            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
+            'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
+            '!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
+    };
+
+    static final double COMF = 10000000;
+    static final double SOMF = 10;
+
+    static String file = "0S000000.000";
+    static int intu = 0;
+    static String code = "0S";
+    static int agen = 3878;
+    static int cscl = 10000;
+    static int vdat = 23;
+    static int duni = 1;
+    static int huni = 1;
+
+    static int idx;
+    static int recs;
+
+    static int isols;
+    static int conns;
+    static int metas;
+    static int geos;
+    static int edges;
+
+    static long hash(long val) {
+        byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
+        CRC32 crc = new CRC32();
+        crc.update(bval);
+        return crc.getValue();
+    }
+
+    public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
+
+        for (Entry<String, String> entry : meta.entrySet()) {
+            try {
+                switch (entry.getKey()) {
+                case "FILE":
+                    file = entry.getValue();
+                    break;
+                case "INTU":
+                    intu = Integer.parseInt(entry.getValue());
+                    break;
+                case "AGEN":
+                    String[] tokens = entry.getValue().split("/");
+                    code = tokens[0];
+                    agen = Integer.parseInt(tokens[1]);
+                    break;
+                case "VDAT":
+                    vdat = Integer.parseInt(entry.getValue());
+                    break;
+                case "CSCL":
+                    cscl = Integer.parseInt(entry.getValue());
+                    break;
+                case "DUNI":
+                    duni = Integer.parseInt(entry.getValue());
+                    break;
+                case "HUNI":
+                    huni = Integer.parseInt(entry.getValue());
+                    break;
+                }
+            } catch (Exception e) {
+                System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
+                System.exit(-1);
+            }
+        }
+
+        //M_COVR & MNSYS in BB if not in map
+        if (!map.features.containsKey(Obj.M_COVR)) {
+            S57osm.OSMmeta(map);
+        }
+
+        S57dat.S57geoms(map);
+
+        byte[] record;
+        ArrayList<Fparams> fields;
+
+        isols = conns = metas = geos = edges = 0;
+        String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
+        ArrayList<Fparams> ds = new ArrayList<>();
+        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" }));
+        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
+        ArrayList<Fparams> dp = new ArrayList<>();
+        dp.add(new Fparams(S57field.DSPM, new Object[] {20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
+
+        System.arraycopy(header, 0, buf, 0, header.length);
+        idx = header.length;
+        record = S57dat.encRecord(1, ds);
+        System.arraycopy(record, 0, buf, idx, record.length);
+        idx += record.length;
+        record = S57dat.encRecord(2, dp);
+        System.arraycopy(record, 0, buf, idx, record.length);
+        idx += record.length;
+        recs = 3;
+
+        // Depths
+        Object[] depths = new Object[0];
+        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
+            S57map.Snode node = entry.getValue();
+            if (node.flg == Nflag.DPTH) {
+                Object[] dval = new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
+                depths = Arrays.copyOf(depths, (depths.length + dval.length));
+                System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
+            }
+        }
+        if (depths.length > 0) {
+            fields = new ArrayList<>();
+            fields.add(new Fparams(S57field.VRID, new Object[] {110, -2, 1, 1 }));
+            fields.add(new Fparams(S57field.SG3D, depths));
+            record = S57dat.encRecord(recs++, fields);
+            System.arraycopy(record, 0, buf, idx, record.length);
+            idx += record.length;
+            isols++;
+        }
+
+        // Isolated nodes
+        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
+            S57map.Snode node = entry.getValue();
+            if (node.flg == Nflag.ISOL) {
+                fields = new ArrayList<>();
+                fields.add(new Fparams(S57field.VRID, new Object[] {110, hash(entry.getKey()), 1, 1 }));
+                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
+                record = S57dat.encRecord(recs++, fields);
+                System.arraycopy(record, 0, buf, idx, record.length);
+                idx += record.length;
+                isols++;
+            }
+        }
+
+        // Connected nodes
+        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
+            S57map.Snode node = entry.getValue();
+            if (node.flg == Nflag.CONN) {
+                fields = new ArrayList<>();
+                fields.add(new Fparams(S57field.VRID, new Object[] {120, hash(entry.getKey()), 1, 1 }));
+                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
+                record = S57dat.encRecord(recs++, fields);
+                System.arraycopy(record, 0, buf, idx, record.length);
+                idx += record.length;
+                conns++;
+            }
+        }
+
+        // Edges
+        for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
+            S57map.Edge edge = entry.getValue();
+            fields = new ArrayList<>();
+            fields.add(new Fparams(S57field.VRID, new Object[] {130, hash(entry.getKey()), 1, 1}));
+            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 }));
+            Object[] nodes = new Object[0];
+            for (long ref : edge.nodes) {
+                Object[] nval = new Object[] {(Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
+                nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
+                System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
+            }
+            if (nodes.length > 0) {
+                fields.add(new Fparams(S57field.SG2D, nodes));
+            }
+            record = S57dat.encRecord(recs++, fields);
+            System.arraycopy(record, 0, buf, idx, record.length);
+            idx += record.length;
+            edges++;
+        }
+
+        // Meta & Geo objects
+        boolean soundings = false;
+        for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
+            Obj obj = entry.getKey();
+            for (Feature feature : entry.getValue()) {
+                if (obj == Obj.SOUNDG) {
+                    if (soundings) {
+                        continue;
+                    } else {
+                        soundings = true;
+                    }
+                }
+                int prim = feature.geom.prim.ordinal();
+                prim = (prim == 0) ? 255 : prim;
+                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;
+
+                ArrayList<Fparams> geom = new ArrayList<>();
+                int outers = 0;
+                outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
+                for (Prim elem : feature.geom.elems) {
+                    if (feature.geom.prim == Pflag.POINT) {
+                        if (obj == Obj.SOUNDG) {
+                            geom.add(new Fparams(S57field.FSPT, new Object[] {((-2 << 8) + 110L), 255, 255, 255 }));
+                        } else {
+                            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 }));
+                        }
+                    } else {
+                        geom.add(new Fparams(S57field.FSPT, new Object[] {((hash(elem.id) << 8) + 130L), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
+                    }
+                }
+
+                ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
+                ArrayList<Long> slaves = new ArrayList<>();
+                long slaveid = feature.id + 0x0100000000000000L;
+                for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
+                    Obj objobj = objs.getKey();
+                    boolean master = true;
+                    for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
+                        ArrayList<Fparams> objatts = new ArrayList<>();
+                        master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
+                        long id = hash(master ? feature.id : slaveid);
+                        objatts.add(new Fparams(S57field.FRID, new Object[] {100, id, prim, grup, S57obj.encodeType(objobj), 1, 1}));
+                        objatts.add(new Fparams(S57field.FOID, new Object[] {agen, id, 1}));
+                        Object[] attf = new Object[0];
+                        Object[] natf = new Object[0];
+                        AttMap atts = map.new AttMap();
+                        atts.putAll(object.getValue());
+                        if (master) {
+                            atts.putAll(feature.atts);
+                        }
+                        for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
+                            if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
+                                long attl = S57att.encodeAttribute(att.getKey());
+                                Object[] next = new Object[] {attl, S57val.encodeValue(att.getValue(), att.getKey())};
+                                if ((attl < 300) || (attl > 304)) {
+                                    attf = Arrays.copyOf(attf, (attf.length + next.length));
+                                    System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
+                                } else {
+                                    natf = Arrays.copyOf(natf, (natf.length + next.length));
+                                    System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
+                                }
+                            }
+                        }
+                        if (attf.length > 0) {
+                            objatts.add(new Fparams(S57field.ATTF, attf));
+                        }
+                        if (natf.length > 0) {
+                            objatts.add(new Fparams(S57field.NATF, attf));
+                        }
+                        if (master) {
+                            objects.add(objatts);
+                        } else {
+                            slaves.add(id);
+                            objects.add(0, objatts);
+                            slaveid += 0x0100000000000000L;
+                        }
+                    }
+                }
+
+                if (!slaves.isEmpty()) {
+                    ArrayList<Fparams> refs = new ArrayList<>();
+                    Object[] params = new Object[0];
+                    while (!slaves.isEmpty()) {
+                        long id = slaves.remove(0);
+                        Object[] next = new Object[] {(long) ((((id & 0xffffffff) + 0x100000000L) << 16) + (agen & 0xffff)), 2, "" };
+                        params = Arrays.copyOf(params, (params.length + next.length));
+                        System.arraycopy(next, 0, params, (params.length - next.length), next.length);
+                    }
+                    refs.add(new Fparams(S57field.FFPT, params));
+                    objects.get(objects.size() - 1).addAll(refs);
+                }
+
+                for (ArrayList<Fparams> object : objects) {
+                    object.addAll(geom);
+                    record = S57dat.encRecord(recs++, object);
+                    System.arraycopy(record, 0, buf, idx, record.length);
+                    idx += record.length;
+                    if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
+                        metas++;
+                    } else {
+                        geos++;
+                    }
+                }
+            }
+        }
+
+        // Re-write DSID/DSSI with final totals
+        ds = new ArrayList<>();
+        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" }));
+        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
+        record = S57dat.encRecord(1, ds);
+        System.arraycopy(record, 0, buf, header.length, record.length);
+
+        return idx;
+    }
 
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57map.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 32394)
@@ -10,962 +10,969 @@
 package s57;
 
-import java.util.*;
-
-import s57.S57obj;
-import s57.S57obj.*;
-import s57.S57att;
-import s57.S57att.*;
-import s57.S57val;
-import s57.S57val.*;
-import s57.S57osm;
-import s57.S57osm.*;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.ListIterator;
+
+import s57.S57att.Att;
+import s57.S57obj.Obj;
+import s57.S57osm.KeyVal;
+import s57.S57val.AttVal;
 
 public class S57map { // S57/OSM map generation methods
-	
-	public class MapBounds {
-		public double minlat;
-		public double minlon;
-		public double maxlat;
-		public double maxlon;
-		public MapBounds() {
-			minlat = Math.toRadians(90);
-			minlon = Math.toRadians(180);
-			maxlat = Math.toRadians(-90);
-			maxlon = Math.toRadians(-180);
-		}
-	}
-
-	public enum Nflag {
-		ANON,	// Edge inner nodes
-		ISOL,	// Node not part of Edge
-		CONN,	// Edge first and last nodes
-		TRNK, // Edge truncated polygon nodes
-		DPTH	// Sounding nodes
-	}
-
-	public class Snode {	// All coordinates in map
-		public double lat;	// Latitude in radians
-		public double lon;	// Longitude in radians
-		public Nflag flg;		// Role of node
-		public double val;	// Optional value
-
-		public Snode() {
-			flg = Nflag.ANON;
-			lat = 0;
-			lon = 0;
-			val = 0;
-		}
-		public Snode(double ilat, double ilon) {
-			flg = Nflag.ANON;
-			lat = ilat;
-			lon = ilon;
-			val = 0;
-		}
-		public Snode(double ilat, double ilon, Nflag iflg) {
-			lat = ilat;
-			lon = ilon;
-			flg = iflg;
-			val = 0;
-		}
-		public Snode(double ilat, double ilon, double ival) {
-			flg = Nflag.DPTH;
-			lat = ilat;
-			lon = ilon;
-			val = ival;
-		}
-	}
-
-	public class Edge {		// A polyline segment
-		public long first;	// First CONN node
-		public long last;		// Last CONN node
-		public ArrayList<Long> nodes; // Inner ANON nodes
-
-		public Edge() {
-			first = 0;
-			last = 0;
-			nodes = new ArrayList<>();
-		}
-	}
-	
-	public enum Rflag {
-		UNKN, MASTER, SLAVE
-	}
-	
-	public class Reln {
-		public long id;
-		public Rflag reln;
-		public Reln(long i, Rflag r) {
-			id = i;
-			reln = r;
-		}
-	}
-
-	public class RelTab extends ArrayList<Reln> {
-		public RelTab() {
-			super();
-		}
-	}
-
-	public class ObjTab extends HashMap<Integer, AttMap> {
-		public ObjTab() {
-			super();
-		}
-	}
-
-	public class ObjMap extends EnumMap<Obj, ObjTab> {
-		public ObjMap() {
-			super(Obj.class);
-		}
-	}
-
-	public class AttMap extends HashMap<Att, AttVal<?>> {
-		public AttMap() {
-			super();
-		}
-	}
-
-	public class NodeTab extends HashMap<Long, Snode> {
-		public NodeTab() {
-			super();
-		}
-	}
-
-	public class EdgeTab extends HashMap<Long, Edge> {
-		public EdgeTab() {
-			super();
-		}
-	}
-
-	public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
-		public FtrMap() {
-			super(Obj.class);
-		}
-	}
-
-	public class FtrTab extends HashMap<Long, Feature> {
-		public FtrTab() {
-			super();
-		}
-	}
-
-	public class Prim {				// Spatial element
-		public long id;					// Snode ID for POINTs, Edge ID for LINEs & AREAs)
-		public boolean forward;	// Direction of vector used (LINEs & AREAs)
-		public boolean outer;		// Exterior/Interior boundary (AREAs)
-		public boolean trunc;		// Cell limit truncation
-		public Prim() {
-			id = 0; forward = true; outer = true; trunc = false;
-		}
-		public Prim(long i) {
-			id = i; forward = true; outer = true; trunc = false;
-		}
-		public Prim(long i, boolean o) {
-			id = i; forward = true; outer = o; trunc = false;
-		}
-		public Prim(long i, boolean f, boolean o) {
-			id = i; forward = f; outer = o; trunc = false;
-		}
-		public Prim(long i, boolean f, boolean o, boolean t) {
-			id = i; forward = f; outer = o; trunc = t;
-		}
-	}
-	
-	public class Comp {			// Composite spatial element
-		public long ref;			// ID of Comp
-		public int size;			// Number of Prims in this Comp
-		public Comp(long r, int s) {
-			ref = r;
-			size = s;
-		}
-	}
-	
-	public enum Pflag {
-		NOSP, POINT, LINE, AREA
-	}
-	
-	public class Geom {							// Geometric structure of feature
-		public Pflag prim;						// Geometry type
-		public ArrayList<Prim> elems;	// Ordered list of elements
-		public int outers;						// Number of outers
-		public int inners;						// Number of inners
-		public ArrayList<Comp> comps;	// Ordered list of compounds
-		public double area;						// Area of feature
-		public double length;					// Length of feature
-		public Snode centre;					// Centre of feature
-		public Geom(Pflag p) {
-			prim = p;
-			elems = new ArrayList<>();
-			outers = inners = 0;
-			comps = new ArrayList<>();
-			area = 0;
-			length = 0;
-			centre = new Snode();
-		}
-	}
-	
-	public class Feature {
-		public long id;				// Ref for this feature
-		public Rflag reln;		// Relationship status
-		public Geom geom;			// Geometry data
-		public Obj type;			// Feature type
-		public AttMap atts;		// Feature attributes
-		public RelTab rels;		// Related objects
-		public ObjMap objs;		// Slave object attributes
-
-		Feature() {
-			id = 0;
-			reln = Rflag.UNKN;
-			geom = new Geom(Pflag.NOSP);
-			type = Obj.UNKOBJ;
-			atts = new AttMap();
-			rels = new RelTab();
-			objs = new ObjMap();
-		}
-	}
-	
-	public MapBounds bounds;
-	public NodeTab nodes;
-	public EdgeTab edges;
-	public FtrMap features;
-	public FtrTab index;
-	public long xref;
-
-	private long cref;
-	private Feature feature;
-	private Edge edge;
-	private ArrayList<KeyVal<?>> osm;
-	private boolean sea;
-
-	public S57map(boolean s) {
-		sea = s;
-		nodes = new NodeTab();		// All nodes in map
-		edges = new EdgeTab();		// All edges in map
-		feature = new Feature();	// Current feature being built
-		features = new FtrMap();	// All features in map, grouped by type
-		index = new FtrTab();			// Feature look-up table
-		bounds = new MapBounds();
-		cref = 0x0000ffffffff0000L;// Compound reference generator
-		xref = 0x0fff000000000000L;// Extras reference generator
-	}
-
-	// S57 map building methods
-	
-	public void newNode(long id, double lat, double lon, Nflag flag) {
-		nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
-		if (flag == Nflag.ANON) {
-			edge.nodes.add(id);
-		}
-	}
-
-	public void newNode(long id, double lat, double lon, double depth) {
-		nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
-	}
-
-	public void newFeature(long id, Pflag p, long objl) {
-		feature = new Feature();
-		Obj obj = S57obj.decodeType(objl);
-		feature.geom = new Geom(p);
-		feature.type = obj;
-		if (obj != Obj.UNKOBJ) {
-			index.put(id, feature);
-			feature.id = id;
-		}
-	}
-	
-	public void refObj(long id, int rind) {
-		Rflag r = Rflag.UNKN;
-		switch (rind) {
-		case 1:
-			r = Rflag.MASTER;
-			break;
-		case 2:
-			r = Rflag.SLAVE;
-			break;
-		case 3:
-			r = Rflag.UNKN;
-			break;
-		}
-		feature.rels.add(new Reln(id, r));
-	}
-	
-	public void endFeature() {
-		
-	}
-	
-	public void newAtt(long attl, String atvl) {
-		Att att = S57att.decodeAttribute(attl);
-		AttVal<?> val = S57val.decodeValue(atvl, att);
-		feature.atts.put(att, val);
-	}
-
-	public void newPrim(long id, long ornt, long usag) {
-		feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
-	}
-
-	public void addConn(long id, int topi) {
-		if (topi == 1) {
-			edge.first = id;
-		} else {
-			edge.last = id;
-		}
-	}
-
-	public void newEdge(long id) {
-		edge = new Edge();
-		edges.put(id, edge);
-	}
-
-	public void endFile() {
-		for (long id : index.keySet()) {
-			Feature feature = index.get(id);
-			sortGeom(feature);
-			for (Reln reln : feature.rels) {
-				Feature rel = index.get(reln.id);
-				if (cmpGeoms(feature.geom, rel.geom)) {
-					switch (reln.reln) {
-					case SLAVE:
-						feature.reln = Rflag.MASTER;
-						break;
-					default:
-						feature.reln = Rflag.UNKN;
-						break;
-					}
-					rel.reln = reln.reln; 
-				} else {
-					reln.reln = Rflag.UNKN;
-				}
-			}
-		}
-		for (long id : index.keySet()) {
-			Feature feature = index.get(id);
-			if (feature.reln == Rflag.UNKN) {
-				feature.reln = Rflag.MASTER;
-			}
-			if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
-				if (features.get(feature.type) == null) {
-					features.put(feature.type, new ArrayList<Feature>());
-				}
-				features.get(feature.type).add(feature);
-			}
-		}
-		for (long id : index.keySet()) {
-			Feature feature = index.get(id);
-			for (Reln reln : feature.rels) {
-				Feature rel = index.get(reln.id);
-				if (rel.reln == Rflag.SLAVE) {
-					if (feature.objs.get(rel.type) == null) {
-						feature.objs.put(rel.type, new ObjTab());
-					}
-					ObjTab tab = feature.objs.get(rel.type);
-					int ix = tab.size();
-					tab.put(ix, rel.atts);
-				}
-			}
-		}
-	}
-
-	// OSM map building methods
-
-	public void addNode(long id, double lat, double lon) {
-		nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
-		feature = new Feature();
-		feature.id = id;
-		feature.reln = Rflag.UNKN;
-		feature.geom.prim = Pflag.POINT;
-		feature.geom.elems.add(new Prim(id));
-		edge = null;
-		osm =  new ArrayList<>();
-	}
-
-	public void addEdge(long id) {
-		feature = new Feature();
-		feature.id = id;
-		feature.reln = Rflag.UNKN;
-		feature.geom.prim = Pflag.LINE;
-		feature.geom.elems.add(new Prim(id));
-		edge = new Edge();
-		osm = new ArrayList<>();
-	}
-
-	public void addToEdge(long node) {
-		if (edge.first == 0) {
-			edge.first = node;
-			nodes.get(node).flg = Nflag.CONN;
-		} else {
-			if (edge.last != 0) {
-				edge.nodes.add(edge.last);
-			}
-			edge.last = node;
-		}
-	}
-
-	public void addArea(long id) {
-		feature = new Feature();
-		feature.id = id;
-		feature.reln = Rflag.UNKN;
-		feature.geom.prim = Pflag.AREA;
-		edge = null;
-		osm = new ArrayList<>();
-	}
-
-	public void addToArea(long id, boolean outer) {
-		feature.geom.elems.add(new Prim(id, outer));
-	}
-
-	public void addTag(String key, String val) {
-		feature.reln = Rflag.MASTER;
-		String subkeys[] = key.split(":");
-		if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
-			Obj obj = S57obj.enumType(subkeys[1]);
-			if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
-				int idx = 0;
-				Att att = Att.UNKATT;
-				try {
-					idx = Integer.parseInt(subkeys[2]);
-					if (subkeys.length == 4) {
-						att = s57.S57att.enumAttribute(subkeys[3], obj);
-					}
-				} catch (Exception e) {
-					att = S57att.enumAttribute(subkeys[2], obj);
-				}
-				ObjTab objs = feature.objs.get(obj);
-				if (objs == null) {
-					objs = new ObjTab();
-					feature.objs.put(obj, objs);
-				}
-				AttMap atts = objs.get(idx);
-				if (atts == null) {
-					atts = new AttMap();
-					objs.put(idx, atts);
-				}
-				AttVal<?> attval = S57val.convertValue(val, att);
-				if (attval.val != null) {
-					if (att == Att.VALSOU) {
-						Snode node = nodes.get(feature.geom.elems.get(0).id);
-						node.val = (Double) attval.val;
-					}
-					atts.put(att, attval);
-				}
-			} else {
-				if (subkeys[1].equals("type")) {
-					obj = S57obj.enumType(val);
-					feature.type = obj;
-					ObjTab objs = feature.objs.get(obj);
-					if (objs == null) {
-						objs = new ObjTab();
-						feature.objs.put(obj, objs);
-					}
-					AttMap atts = objs.get(0);
-					if (atts == null) {
-						atts = new AttMap();
-						objs.put(0, atts);
-					}
-					if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
-						Snode node = nodes.get(feature.geom.elems.get(0).id);
-						node.flg = Nflag.DPTH;
-					}
-				} else {
-					if (obj != Obj.UNKOBJ) {
-						if (val.equals("yes")) {
-							ObjTab objs = feature.objs.get(obj);
-							if (objs == null) {
-								objs = new ObjTab();
-								feature.objs.put(obj, objs);
-							}
-						}
-					} else {
-						Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
-						if (att != Att.UNKATT) {
-							AttVal<?> attval = S57val.convertValue(val, att);
-							if (attval.val != null)
-								feature.atts.put(att, attval);
-						}
-					}
-				}
-			}
-		} else if (!sea) {
-			S57osm.OSMtag(osm, key, val);
-		}
-	}
-
-	public void tagsDone(long id) {
-		switch (feature.geom.prim) {
-		case POINT:
-			Snode node = nodes.get(id);
-			if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
-				node.flg = Nflag.ISOL;
-			}
-			break;
-		case LINE:
-			edges.put(id, edge);
-			nodes.get(edge.first).flg = Nflag.CONN;
-			nodes.get(edge.last).flg = Nflag.CONN;
-			if (edge.first == edge.last) {
-				feature.geom.prim = Pflag.AREA;
-			}
-			break;
-		case AREA:
-			break;
-		default:
-			break;
-		}
-		if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
-			if (feature.type != Obj.UNKOBJ) {
-				index.put(id, feature);
-				if (features.get(feature.type) == null) {
-					features.put(feature.type, new ArrayList<Feature>());
-				}
-				features.get(feature.type).add(feature);
-			}
-			for (KeyVal<?> kvx : osm) {
-				Feature base = new Feature();
-				base.reln = Rflag.MASTER;
-				base.geom = feature.geom;
-				base.type = kvx.obj;
-				ObjTab objs = new ObjTab();
-				base.objs.put(kvx.obj, objs);
-				AttMap atts = new AttMap();
-				objs.put(0, atts);
-				if (kvx.att != Att.UNKATT) {
-					atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
-				}
-				index.put(++xref, base);
-				if (features.get(kvx.obj) == null) {
-					features.put(kvx.obj, new ArrayList<Feature>());
-				}
-				features.get(kvx.obj).add(base);
-			}
-/*			if (!osm.isEmpty()) {
-				if (feature.type == Obj.UNKOBJ) {
-					feature.type = osm.obj;
-					ObjTab objs = feature.objs.get(osm.obj);
-					if (objs == null) {
-						objs = new ObjTab();
-						feature.objs.put(osm.obj, objs);
-					}
-					AttMap atts = objs.get(0);
-					if (atts == null) {
-						atts = new AttMap();
-						objs.put(0, atts);
-					}
-					if (osm.att != Att.UNKATT) {
-						atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
-					}
-				} else {
-					Feature base = new Feature();
-					base.reln = Rflag.MASTER;
-					base.geom = feature.geom;
-					base.type = osm.obj;
-					ObjTab objs = new ObjTab();
-					base.objs.put(osm.obj, objs);
-					AttMap atts = new AttMap();
-					objs.put(0, atts);
-					if (osm.att != Att.UNKATT) {
-						atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
-					}
-					index.put(++xref, base);
-					if (features.get(osm.obj) == null) {
-						features.put(osm.obj, new ArrayList<Feature>());
-					}
-					features.get(osm.obj).add(base);
-				}
-			}*/
-		}
-	}
-	
-	public void mapDone() {
-		if (!sea) {
-			S57box.bBox(this);
-		}
-	}
-	
-	// Utility methods
-
-	public boolean sortGeom(Feature feature) {
-		try {
-			Geom sort = new Geom(feature.geom.prim);
-			long first = 0;
-			long last = 0;
-			Comp comp = null;
-			boolean next = true;
-			feature.geom.length = 0;
-			feature.geom.area = 0;
-			if (feature.geom.elems.isEmpty()) {
-				return false;
-			}
-			if (feature.geom.prim == Pflag.POINT) {
-				feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
-				return true;
-			}
-			Geom outer = new Geom(feature.geom.prim);
-			Geom inner = new Geom(feature.geom.prim);
-			for (Prim prim : feature.geom.elems) {
-				if (prim.outer) {
-					outer.elems.add(prim);
-				} else {
-					inner.elems.add(prim);
-				}
-			}
-			boolean outin = true;
-			int sweep = outer.elems.size();
-			if (sweep == 0) {
-				return false;
-			}
-			int prev = sweep;
-			int top = 0;
-			while (!outer.elems.isEmpty()) {
-				Prim prim = outer.elems.remove(0);
-				Edge edge = edges.get(prim.id);
-				if (edge == null) {
-					return false;
-				}
-				if (next == true) {
-					next = false;
-					first = edge.first;
-					last = edge.last;
-					prim.forward = true;
-					sort.elems.add(prim);
-					if (prim.outer) {
-						sort.outers++;
-					} else {
-						sort.inners++;
-					}
-					comp = new Comp(cref++, 1);
-					sort.comps.add(comp);
-				} else {
-					if (edge.first == last) {
-						sort.elems.add(prim);
-						last = edge.last;
-						prim.forward = true;
-						comp.size++;
-					} else if (edge.last == first) {
-						sort.elems.add(top, prim);
-						first = edge.first;
-						prim.forward = true;
-						comp.size++;
-					} else if (edge.last == last) {
-						sort.elems.add(prim);
-						last = edge.first;
-						prim.forward = false;
-						comp.size++;
-					} else if (edge.first == first) {
-						sort.elems.add(top, prim);
-						first = edge.last;
-						prim.forward = false;
-						comp.size++;
-					} else {
-						outer.elems.add(prim);
-					}
-				}
-				if (--sweep == 0) {
-					sweep = outer.elems.size();
-					if ((sweep == 0) || (sweep == prev)) {
-						if ((sort.prim == Pflag.AREA) && (first != last)) {
-							return false;
-						}
-						if (outin) {
-							if (sweep != 0) {
-								return false;
-							}
-							outer = inner;
-							outin = false;
-							sweep = outer.elems.size();
-						}
-						next = true;
-						top = sort.elems.size();
-					}
-					prev = sweep;
-				}
-			}
-			if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
-				sort.prim = Pflag.AREA;
-			}
-			feature.geom = sort;
-			if (feature.geom.prim == Pflag.AREA) {
-				int ie = 0;
-				int ic = 0;
-				while (ie < feature.geom.elems.size()) {
-					double area = calcArea(feature.geom, ic);
-					if (ie == 0)
-						feature.geom.area = Math.abs(area) * 3444 * 3444;
-					if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
-						ArrayList<Prim> tmp = new ArrayList<>();
-						for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
-							Prim p = feature.geom.elems.remove(ie);
-							p.forward = !p.forward;
-							tmp.add(0, p);
-						}
-						feature.geom.elems.addAll(ie, tmp);
-					}
-					ie += feature.geom.comps.get(ic).size;
-					ic++;
-				}
-			}
-			feature.geom.length = calcLength(feature.geom);
-			feature.geom.centre = calcCentroid(feature);
-			return true;
-		} catch (Exception e) {
-			return false;
-		}
-	}
-	
-	public boolean cmpGeoms (Geom g1, Geom g2) {
-		return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
-	}
-	
-	public class EdgeIterator {
-		Edge edge;
-		boolean forward;
-		ListIterator<Long> it;
-
-		public EdgeIterator(Edge e, boolean dir) {
-			edge = e;
-			forward = dir;
-			it = null;
-		}
-
-		public boolean hasNext() {
-			return (edge != null);
-		}
-
-		public long nextRef() {
-			long ref = 0;
-			if (forward) {
-				if (it == null) {
-					ref = edge.first;
-					it = edge.nodes.listIterator();
-				} else {
-					if (it.hasNext()) {
-						ref = it.next();
-					} else {
-						ref = edge.last;
-						edge = null;
-					}
-				}
-			} else {
-				if (it == null) {
-					ref = edge.last;
-					it = edge.nodes.listIterator(edge.nodes.size());
-				} else {
-					if (it.hasPrevious()) {
-						ref = it.previous();
-					} else {
-						ref = edge.first;
-						edge = null;
-					}
-				}
-			}
-			return ref;
-		}
-		
-		public Snode next() {
-			return nodes.get(nextRef());
-		}
-	}
-
-	public class GeomIterator {
-		Geom geom;
-		Prim prim;
-		EdgeIterator eit;
-		ListIterator<S57map.Prim> ite;
-		ListIterator<Comp> itc;
-		Comp comp;
-		int ec;
-		long lastref;
-
-		public GeomIterator(Geom g) {
-			geom = g;
-			lastref = 0;
-			ite = geom.elems.listIterator();
-			itc = geom.comps.listIterator();
-		}
-		
-		public boolean hasComp() {
-			return (itc.hasNext());
-		}
-		
-		public long nextComp() {
-			comp = itc.next();
-			ec = comp.size;
-			lastref = 0;
-			return comp.ref;
-		}
-		
-		public boolean hasEdge() {
-			return (ec > 0) && ite.hasNext();
-		}
-		
-		public long nextEdge() {
-			prim = ite.next();
-			eit = new EdgeIterator(edges.get(prim.id), prim.forward);
-			ec--;
-			return prim.id;
-		}
-		
-		public boolean hasNode() {
-			return (eit.hasNext());
-		}
-		
-		public long nextRef(boolean all) {
-			long ref = eit.nextRef();
-			if (!all && (ref == lastref)) {
-				ref = eit.nextRef();
-			}
-			lastref = ref;
-			return ref;
-		}
-		
-		public long nextRef() {
-			return nextRef(false);
-		}
-		
-		public Snode next() {
-			return nodes.get(nextRef());
-		}
-	}
-	
-	double calcArea(Geom geom, int comp) {
-		Snode node;
-		double lat, lon, llon, llat;
-		lat = lon = llon = llat = 0;
-		double sigma = 0;
-		GeomIterator git = new GeomIterator(geom);
-		for (int i = 0; i <= comp; i++) {
-			if (git.hasComp()) {
-				git.nextComp();
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						node = git.next();
-						if (node == null)
-							continue;
-						llon = lon;
-						llat = lat;
-						lat = node.lat;
-						lon = node.lon;
-						sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
-					}
-				}
-				if (i != comp)
-					sigma = lat = lon = llon = llat = 0;
-			}
-		}
-		return sigma / 2.0;
-	}
-
-	double calcLength(Geom geom) {
-		Snode node;
-		double lat, lon, llon, llat;
-		lat = lon = llon = llat = 0;
-		double sigma = 0;
-		boolean first = true;
-		GeomIterator git = new GeomIterator(geom);
-		while (git.hasComp()) {
-			git.nextComp();
-			while (git.hasEdge()) {
-				git.nextEdge();
-				while (git.hasNode()) {
-					node = git.next();
-					if (first) {
-						first = false;
-						lat = node.lat;
-						lon = node.lon;
-					} else if (node != null) {
-						llat = lat;
-						llon = lon;
-						lat = node.lat;
-						lon = node.lon;
-						sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
-					}
-				}
-			}
-		}
-		return sigma * 3444;
-	}
-
-	Snode calcCentroid(Feature feature) {
-		double lat, lon, slat, slon, llat, llon;
-		llat = llon = lat = lon = slat = slon = 0;
-		double sarc = 0;
-		boolean first = true;
-		switch (feature.geom.prim) {
-		case POINT:
-			return nodes.get(feature.geom.elems.get(0).id);
-		case LINE:
-			GeomIterator git = new GeomIterator(feature.geom);
-			while (git.hasComp()) {
-				git.nextComp();
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						Snode node = git.next();
-						if (node == null) continue;
-						lat = node.lat;
-						lon = node.lon;
-						if (first) {
-							first = false;
-						} else {
-							sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
-						}
-						llat = lat;
-						llon = lon;
-					}
-				}
-			}
-			double harc = sarc / 2;
-			sarc = 0;
-			first = true;
-			git = new GeomIterator(feature.geom);
-			while (git.hasComp()) {
-				git.nextComp();
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						Snode node = git.next();
-						if (node == null) continue;
-						lat = node.lat;
-						lon = node.lon;
-						if (first) {
-							first = false;
-						} else {
-							sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
-							if (sarc > harc)
-								break;
-						}
-						harc -= sarc;
-						llat = lat;
-						llon = lon;
-					}
-				}
-			}
-			return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
-		case AREA:
-			git = new GeomIterator(feature.geom);
-			while (git.hasComp()) {
-				git.nextComp();
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						Snode node = git.next();
-						lat = node.lat;
-						lon = node.lon;
-						if (first) {
-							first = false;
-						} else {
-							double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
-							slat += ((lat + llat) / 2 * arc);
-							slon += ((lon + llon) / 2 * arc);
-							sarc += arc;
-						}
-						llon = lon;
-						llat = lat;
-					}
-				}
-			}
-			return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
-		default:
-		}
-		return null;
-	}
+    // CHECKSTYLE.OFF: LineLength
+
+    public class MapBounds {
+        public double minlat;
+        public double minlon;
+        public double maxlat;
+        public double maxlon;
+        public MapBounds() {
+            minlat = Math.toRadians(90);
+            minlon = Math.toRadians(180);
+            maxlat = Math.toRadians(-90);
+            maxlon = Math.toRadians(-180);
+        }
+    }
+
+    public enum Nflag {
+        ANON,    // Edge inner nodes
+        ISOL,    // Node not part of Edge
+        CONN,    // Edge first and last nodes
+        TRNK, // Edge truncated polygon nodes
+        DPTH    // Sounding nodes
+    }
+
+    public class Snode {    // All coordinates in map
+        public double lat;    // Latitude in radians
+        public double lon;    // Longitude in radians
+        public Nflag flg;        // Role of node
+        public double val;    // Optional value
+
+        public Snode() {
+            flg = Nflag.ANON;
+            lat = 0;
+            lon = 0;
+            val = 0;
+        }
+
+        public Snode(double ilat, double ilon) {
+            flg = Nflag.ANON;
+            lat = ilat;
+            lon = ilon;
+            val = 0;
+        }
+
+        public Snode(double ilat, double ilon, Nflag iflg) {
+            lat = ilat;
+            lon = ilon;
+            flg = iflg;
+            val = 0;
+        }
+
+        public Snode(double ilat, double ilon, double ival) {
+            flg = Nflag.DPTH;
+            lat = ilat;
+            lon = ilon;
+            val = ival;
+        }
+    }
+
+    public class Edge {        // A polyline segment
+        public long first;    // First CONN node
+        public long last;        // Last CONN node
+        public ArrayList<Long> nodes; // Inner ANON nodes
+
+        public Edge() {
+            first = 0;
+            last = 0;
+            nodes = new ArrayList<>();
+        }
+    }
+
+    public enum Rflag {
+        UNKN, MASTER, SLAVE
+    }
+
+    public class Reln {
+        public long id;
+        public Rflag reln;
+        public Reln(long i, Rflag r) {
+            id = i;
+            reln = r;
+        }
+    }
+
+    public class RelTab extends ArrayList<Reln> {
+        public RelTab() {
+            super();
+        }
+    }
+
+    public class ObjTab extends HashMap<Integer, AttMap> {
+        public ObjTab() {
+            super();
+        }
+    }
+
+    public class ObjMap extends EnumMap<Obj, ObjTab> {
+        public ObjMap() {
+            super(Obj.class);
+        }
+    }
+
+    public class AttMap extends HashMap<Att, AttVal<?>> {
+        public AttMap() {
+            super();
+        }
+    }
+
+    public class NodeTab extends HashMap<Long, Snode> {
+        public NodeTab() {
+            super();
+        }
+    }
+
+    public class EdgeTab extends HashMap<Long, Edge> {
+        public EdgeTab() {
+            super();
+        }
+    }
+
+    public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
+        public FtrMap() {
+            super(Obj.class);
+        }
+    }
+
+    public class FtrTab extends HashMap<Long, Feature> {
+        public FtrTab() {
+            super();
+        }
+    }
+
+    public class Prim {                // Spatial element
+        public long id;                    // Snode ID for POINTs, Edge ID for LINEs & AREAs)
+        public boolean forward;    // Direction of vector used (LINEs & AREAs)
+        public boolean outer;        // Exterior/Interior boundary (AREAs)
+        public boolean trunc;        // Cell limit truncation
+        public Prim() {
+            id = 0; forward = true; outer = true; trunc = false;
+        }
+
+        public Prim(long i) {
+            id = i; forward = true; outer = true; trunc = false;
+        }
+
+        public Prim(long i, boolean o) {
+            id = i; forward = true; outer = o; trunc = false;
+        }
+
+        public Prim(long i, boolean f, boolean o) {
+            id = i; forward = f; outer = o; trunc = false;
+        }
+
+        public Prim(long i, boolean f, boolean o, boolean t) {
+            id = i; forward = f; outer = o; trunc = t;
+        }
+    }
+
+    public class Comp {            // Composite spatial element
+        public long ref;            // ID of Comp
+        public int size;            // Number of Prims in this Comp
+        public Comp(long r, int s) {
+            ref = r;
+            size = s;
+        }
+    }
+
+    public enum Pflag {
+        NOSP, POINT, LINE, AREA
+    }
+
+    public class Geom {                            // Geometric structure of feature
+        public Pflag prim;                        // Geometry type
+        public ArrayList<Prim> elems;    // Ordered list of elements
+        public int outers;                        // Number of outers
+        public int inners;                        // Number of inners
+        public ArrayList<Comp> comps;    // Ordered list of compounds
+        public double area;                        // Area of feature
+        public double length;                    // Length of feature
+        public Snode centre;                    // Centre of feature
+        public Geom(Pflag p) {
+            prim = p;
+            elems = new ArrayList<>();
+            outers = inners = 0;
+            comps = new ArrayList<>();
+            area = 0;
+            length = 0;
+            centre = new Snode();
+        }
+    }
+
+    public class Feature {
+        public long id;                // Ref for this feature
+        public Rflag reln;        // Relationship status
+        public Geom geom;            // Geometry data
+        public Obj type;            // Feature type
+        public AttMap atts;        // Feature attributes
+        public RelTab rels;        // Related objects
+        public ObjMap objs;        // Slave object attributes
+
+        Feature() {
+            id = 0;
+            reln = Rflag.UNKN;
+            geom = new Geom(Pflag.NOSP);
+            type = Obj.UNKOBJ;
+            atts = new AttMap();
+            rels = new RelTab();
+            objs = new ObjMap();
+        }
+    }
+
+    public MapBounds bounds;
+    public NodeTab nodes;
+    public EdgeTab edges;
+    public FtrMap features;
+    public FtrTab index;
+    public long xref;
+
+    private long cref;
+    private Feature feature;
+    private Edge edge;
+    private ArrayList<KeyVal<?>> osm;
+    private boolean sea;
+
+    public S57map(boolean s) {
+        sea = s;
+        nodes = new NodeTab();      // All nodes in map
+        edges = new EdgeTab();      // All edges in map
+        feature = new Feature();    // Current feature being built
+        features = new FtrMap();    // All features in map, grouped by type
+        index = new FtrTab();       // Feature look-up table
+        bounds = new MapBounds();
+        cref = 0x0000ffffffff0000L; // Compound reference generator
+        xref = 0x0fff000000000000L; // Extras reference generator
+    }
+
+    // S57 map building methods
+
+    public void newNode(long id, double lat, double lon, Nflag flag) {
+        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
+        if (flag == Nflag.ANON) {
+            edge.nodes.add(id);
+        }
+    }
+
+    public void newNode(long id, double lat, double lon, double depth) {
+        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
+    }
+
+    public void newFeature(long id, Pflag p, long objl) {
+        feature = new Feature();
+        Obj obj = S57obj.decodeType(objl);
+        feature.geom = new Geom(p);
+        feature.type = obj;
+        if (obj != Obj.UNKOBJ) {
+            index.put(id, feature);
+            feature.id = id;
+        }
+    }
+
+    public void refObj(long id, int rind) {
+        Rflag r = Rflag.UNKN;
+        switch (rind) {
+        case 1:
+            r = Rflag.MASTER;
+            break;
+        case 2:
+            r = Rflag.SLAVE;
+            break;
+        case 3:
+            r = Rflag.UNKN;
+            break;
+        }
+        feature.rels.add(new Reln(id, r));
+    }
+
+    public void endFeature() {
+
+    }
+
+    public void newAtt(long attl, String atvl) {
+        Att att = S57att.decodeAttribute(attl);
+        AttVal<?> val = S57val.decodeValue(atvl, att);
+        feature.atts.put(att, val);
+    }
+
+    public void newPrim(long id, long ornt, long usag) {
+        feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
+    }
+
+    public void addConn(long id, int topi) {
+        if (topi == 1) {
+            edge.first = id;
+        } else {
+            edge.last = id;
+        }
+    }
+
+    public void newEdge(long id) {
+        edge = new Edge();
+        edges.put(id, edge);
+    }
+
+    public void endFile() {
+        for (long id : index.keySet()) {
+            Feature feature = index.get(id);
+            sortGeom(feature);
+            for (Reln reln : feature.rels) {
+                Feature rel = index.get(reln.id);
+                if (cmpGeoms(feature.geom, rel.geom)) {
+                    switch (reln.reln) {
+                    case SLAVE:
+                        feature.reln = Rflag.MASTER;
+                        break;
+                    default:
+                        feature.reln = Rflag.UNKN;
+                        break;
+                    }
+                    rel.reln = reln.reln;
+                } else {
+                    reln.reln = Rflag.UNKN;
+                }
+            }
+        }
+        for (long id : index.keySet()) {
+            Feature feature = index.get(id);
+            if (feature.reln == Rflag.UNKN) {
+                feature.reln = Rflag.MASTER;
+            }
+            if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
+                if (features.get(feature.type) == null) {
+                    features.put(feature.type, new ArrayList<Feature>());
+                }
+                features.get(feature.type).add(feature);
+            }
+        }
+        for (long id : index.keySet()) {
+            Feature feature = index.get(id);
+            for (Reln reln : feature.rels) {
+                Feature rel = index.get(reln.id);
+                if (rel.reln == Rflag.SLAVE) {
+                    if (feature.objs.get(rel.type) == null) {
+                        feature.objs.put(rel.type, new ObjTab());
+                    }
+                    ObjTab tab = feature.objs.get(rel.type);
+                    int ix = tab.size();
+                    tab.put(ix, rel.atts);
+                }
+            }
+        }
+    }
+
+    // OSM map building methods
+
+    public void addNode(long id, double lat, double lon) {
+        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
+        feature = new Feature();
+        feature.id = id;
+        feature.reln = Rflag.UNKN;
+        feature.geom.prim = Pflag.POINT;
+        feature.geom.elems.add(new Prim(id));
+        edge = null;
+        osm = new ArrayList<>();
+    }
+
+    public void addEdge(long id) {
+        feature = new Feature();
+        feature.id = id;
+        feature.reln = Rflag.UNKN;
+        feature.geom.prim = Pflag.LINE;
+        feature.geom.elems.add(new Prim(id));
+        edge = new Edge();
+        osm = new ArrayList<>();
+    }
+
+    public void addToEdge(long node) {
+        if (edge.first == 0) {
+            edge.first = node;
+            nodes.get(node).flg = Nflag.CONN;
+        } else {
+            if (edge.last != 0) {
+                edge.nodes.add(edge.last);
+            }
+            edge.last = node;
+        }
+    }
+
+    public void addArea(long id) {
+        feature = new Feature();
+        feature.id = id;
+        feature.reln = Rflag.UNKN;
+        feature.geom.prim = Pflag.AREA;
+        edge = null;
+        osm = new ArrayList<>();
+    }
+
+    public void addToArea(long id, boolean outer) {
+        feature.geom.elems.add(new Prim(id, outer));
+    }
+
+    public void addTag(String key, String val) {
+        feature.reln = Rflag.MASTER;
+        String[] subkeys = key.split(":");
+        if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
+            Obj obj = S57obj.enumType(subkeys[1]);
+            if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
+                int idx = 0;
+                Att att = Att.UNKATT;
+                try {
+                    idx = Integer.parseInt(subkeys[2]);
+                    if (subkeys.length == 4) {
+                        att = s57.S57att.enumAttribute(subkeys[3], obj);
+                    }
+                } catch (Exception e) {
+                    att = S57att.enumAttribute(subkeys[2], obj);
+                }
+                ObjTab objs = feature.objs.get(obj);
+                if (objs == null) {
+                    objs = new ObjTab();
+                    feature.objs.put(obj, objs);
+                }
+                AttMap atts = objs.get(idx);
+                if (atts == null) {
+                    atts = new AttMap();
+                    objs.put(idx, atts);
+                }
+                AttVal<?> attval = S57val.convertValue(val, att);
+                if (attval.val != null) {
+                    if (att == Att.VALSOU) {
+                        Snode node = nodes.get(feature.geom.elems.get(0).id);
+                        node.val = (Double) attval.val;
+                    }
+                    atts.put(att, attval);
+                }
+            } else {
+                if (subkeys[1].equals("type")) {
+                    obj = S57obj.enumType(val);
+                    feature.type = obj;
+                    ObjTab objs = feature.objs.get(obj);
+                    if (objs == null) {
+                        objs = new ObjTab();
+                        feature.objs.put(obj, objs);
+                    }
+                    AttMap atts = objs.get(0);
+                    if (atts == null) {
+                        atts = new AttMap();
+                        objs.put(0, atts);
+                    }
+                    if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
+                        Snode node = nodes.get(feature.geom.elems.get(0).id);
+                        node.flg = Nflag.DPTH;
+                    }
+                } else {
+                    if (obj != Obj.UNKOBJ) {
+                        if (val.equals("yes")) {
+                            ObjTab objs = feature.objs.get(obj);
+                            if (objs == null) {
+                                objs = new ObjTab();
+                                feature.objs.put(obj, objs);
+                            }
+                        }
+                    } else {
+                        Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
+                        if (att != Att.UNKATT) {
+                            AttVal<?> attval = S57val.convertValue(val, att);
+                            if (attval.val != null)
+                                feature.atts.put(att, attval);
+                        }
+                    }
+                }
+            }
+        } else if (!sea) {
+            S57osm.OSMtag(osm, key, val);
+        }
+    }
+
+    public void tagsDone(long id) {
+        switch (feature.geom.prim) {
+        case POINT:
+            Snode node = nodes.get(id);
+            if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
+                node.flg = Nflag.ISOL;
+            }
+            break;
+        case LINE:
+            edges.put(id, edge);
+            nodes.get(edge.first).flg = Nflag.CONN;
+            nodes.get(edge.last).flg = Nflag.CONN;
+            if (edge.first == edge.last) {
+                feature.geom.prim = Pflag.AREA;
+            }
+            break;
+        case AREA:
+            break;
+        default:
+            break;
+        }
+        if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
+            if (feature.type != Obj.UNKOBJ) {
+                index.put(id, feature);
+                if (features.get(feature.type) == null) {
+                    features.put(feature.type, new ArrayList<Feature>());
+                }
+                features.get(feature.type).add(feature);
+            }
+            for (KeyVal<?> kvx : osm) {
+                Feature base = new Feature();
+                base.reln = Rflag.MASTER;
+                base.geom = feature.geom;
+                base.type = kvx.obj;
+                ObjTab objs = new ObjTab();
+                base.objs.put(kvx.obj, objs);
+                AttMap atts = new AttMap();
+                objs.put(0, atts);
+                if (kvx.att != Att.UNKATT) {
+                    atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
+                }
+                index.put(++xref, base);
+                if (features.get(kvx.obj) == null) {
+                    features.put(kvx.obj, new ArrayList<Feature>());
+                }
+                features.get(kvx.obj).add(base);
+            }
+            /*            if (!osm.isEmpty()) {
+                if (feature.type == Obj.UNKOBJ) {
+                    feature.type = osm.obj;
+                    ObjTab objs = feature.objs.get(osm.obj);
+                    if (objs == null) {
+                        objs = new ObjTab();
+                        feature.objs.put(osm.obj, objs);
+                    }
+                    AttMap atts = objs.get(0);
+                    if (atts == null) {
+                        atts = new AttMap();
+                        objs.put(0, atts);
+                    }
+                    if (osm.att != Att.UNKATT) {
+                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
+                    }
+                } else {
+                    Feature base = new Feature();
+                    base.reln = Rflag.MASTER;
+                    base.geom = feature.geom;
+                    base.type = osm.obj;
+                    ObjTab objs = new ObjTab();
+                    base.objs.put(osm.obj, objs);
+                    AttMap atts = new AttMap();
+                    objs.put(0, atts);
+                    if (osm.att != Att.UNKATT) {
+                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
+                    }
+                    index.put(++xref, base);
+                    if (features.get(osm.obj) == null) {
+                        features.put(osm.obj, new ArrayList<Feature>());
+                    }
+                    features.get(osm.obj).add(base);
+                }
+            }*/
+        }
+    }
+
+    public void mapDone() {
+        if (!sea) {
+            S57box.bBox(this);
+        }
+    }
+
+    // Utility methods
+
+    public boolean sortGeom(Feature feature) {
+        try {
+            Geom sort = new Geom(feature.geom.prim);
+            long first = 0;
+            long last = 0;
+            Comp comp = null;
+            boolean next = true;
+            feature.geom.length = 0;
+            feature.geom.area = 0;
+            if (feature.geom.elems.isEmpty()) {
+                return false;
+            }
+            if (feature.geom.prim == Pflag.POINT) {
+                feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
+                return true;
+            }
+            Geom outer = new Geom(feature.geom.prim);
+            Geom inner = new Geom(feature.geom.prim);
+            for (Prim prim : feature.geom.elems) {
+                if (prim.outer) {
+                    outer.elems.add(prim);
+                } else {
+                    inner.elems.add(prim);
+                }
+            }
+            boolean outin = true;
+            int sweep = outer.elems.size();
+            if (sweep == 0) {
+                return false;
+            }
+            int prev = sweep;
+            int top = 0;
+            while (!outer.elems.isEmpty()) {
+                Prim prim = outer.elems.remove(0);
+                Edge edge = edges.get(prim.id);
+                if (edge == null) {
+                    return false;
+                }
+                if (next == true) {
+                    next = false;
+                    first = edge.first;
+                    last = edge.last;
+                    prim.forward = true;
+                    sort.elems.add(prim);
+                    if (prim.outer) {
+                        sort.outers++;
+                    } else {
+                        sort.inners++;
+                    }
+                    comp = new Comp(cref++, 1);
+                    sort.comps.add(comp);
+                } else {
+                    if (edge.first == last) {
+                        sort.elems.add(prim);
+                        last = edge.last;
+                        prim.forward = true;
+                        comp.size++;
+                    } else if (edge.last == first) {
+                        sort.elems.add(top, prim);
+                        first = edge.first;
+                        prim.forward = true;
+                        comp.size++;
+                    } else if (edge.last == last) {
+                        sort.elems.add(prim);
+                        last = edge.first;
+                        prim.forward = false;
+                        comp.size++;
+                    } else if (edge.first == first) {
+                        sort.elems.add(top, prim);
+                        first = edge.last;
+                        prim.forward = false;
+                        comp.size++;
+                    } else {
+                        outer.elems.add(prim);
+                    }
+                }
+                if (--sweep == 0) {
+                    sweep = outer.elems.size();
+                    if ((sweep == 0) || (sweep == prev)) {
+                        if ((sort.prim == Pflag.AREA) && (first != last)) {
+                            return false;
+                        }
+                        if (outin) {
+                            if (sweep != 0) {
+                                return false;
+                            }
+                            outer = inner;
+                            outin = false;
+                            sweep = outer.elems.size();
+                        }
+                        next = true;
+                        top = sort.elems.size();
+                    }
+                    prev = sweep;
+                }
+            }
+            if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
+                sort.prim = Pflag.AREA;
+            }
+            feature.geom = sort;
+            if (feature.geom.prim == Pflag.AREA) {
+                int ie = 0;
+                int ic = 0;
+                while (ie < feature.geom.elems.size()) {
+                    double area = calcArea(feature.geom, ic);
+                    if (ie == 0)
+                        feature.geom.area = Math.abs(area) * 3444 * 3444;
+                    if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
+                        ArrayList<Prim> tmp = new ArrayList<>();
+                        for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
+                            Prim p = feature.geom.elems.remove(ie);
+                            p.forward = !p.forward;
+                            tmp.add(0, p);
+                        }
+                        feature.geom.elems.addAll(ie, tmp);
+                    }
+                    ie += feature.geom.comps.get(ic).size;
+                    ic++;
+                }
+            }
+            feature.geom.length = calcLength(feature.geom);
+            feature.geom.centre = calcCentroid(feature);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    public boolean cmpGeoms(Geom g1, Geom g2) {
+        return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
+    }
+
+    public class EdgeIterator {
+        Edge edge;
+        boolean forward;
+        ListIterator<Long> it;
+
+        public EdgeIterator(Edge e, boolean dir) {
+            edge = e;
+            forward = dir;
+            it = null;
+        }
+
+        public boolean hasNext() {
+            return (edge != null);
+        }
+
+        public long nextRef() {
+            long ref = 0;
+            if (forward) {
+                if (it == null) {
+                    ref = edge.first;
+                    it = edge.nodes.listIterator();
+                } else {
+                    if (it.hasNext()) {
+                        ref = it.next();
+                    } else {
+                        ref = edge.last;
+                        edge = null;
+                    }
+                }
+            } else {
+                if (it == null) {
+                    ref = edge.last;
+                    it = edge.nodes.listIterator(edge.nodes.size());
+                } else {
+                    if (it.hasPrevious()) {
+                        ref = it.previous();
+                    } else {
+                        ref = edge.first;
+                        edge = null;
+                    }
+                }
+            }
+            return ref;
+        }
+
+        public Snode next() {
+            return nodes.get(nextRef());
+        }
+    }
+
+    public class GeomIterator {
+        Geom geom;
+        Prim prim;
+        EdgeIterator eit;
+        ListIterator<S57map.Prim> ite;
+        ListIterator<Comp> itc;
+        Comp comp;
+        int ec;
+        long lastref;
+
+        public GeomIterator(Geom g) {
+            geom = g;
+            lastref = 0;
+            ite = geom.elems.listIterator();
+            itc = geom.comps.listIterator();
+        }
+
+        public boolean hasComp() {
+            return (itc.hasNext());
+        }
+
+        public long nextComp() {
+            comp = itc.next();
+            ec = comp.size;
+            lastref = 0;
+            return comp.ref;
+        }
+
+        public boolean hasEdge() {
+            return (ec > 0) && ite.hasNext();
+        }
+
+        public long nextEdge() {
+            prim = ite.next();
+            eit = new EdgeIterator(edges.get(prim.id), prim.forward);
+            ec--;
+            return prim.id;
+        }
+
+        public boolean hasNode() {
+            return (eit.hasNext());
+        }
+
+        public long nextRef(boolean all) {
+            long ref = eit.nextRef();
+            if (!all && (ref == lastref)) {
+                ref = eit.nextRef();
+            }
+            lastref = ref;
+            return ref;
+        }
+
+        public long nextRef() {
+            return nextRef(false);
+        }
+
+        public Snode next() {
+            return nodes.get(nextRef());
+        }
+    }
+
+    double calcArea(Geom geom, int comp) {
+        Snode node;
+        double lat, lon, llon, llat;
+        lat = lon = llon = llat = 0;
+        double sigma = 0;
+        GeomIterator git = new GeomIterator(geom);
+        for (int i = 0; i <= comp; i++) {
+            if (git.hasComp()) {
+                git.nextComp();
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        node = git.next();
+                        if (node == null)
+                            continue;
+                        llon = lon;
+                        llat = lat;
+                        lat = node.lat;
+                        lon = node.lon;
+                        sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
+                    }
+                }
+                if (i != comp)
+                    sigma = lat = lon = llon = llat = 0;
+            }
+        }
+        return sigma / 2.0;
+    }
+
+    double calcLength(Geom geom) {
+        Snode node;
+        double lat, lon, llon, llat;
+        lat = lon = llon = llat = 0;
+        double sigma = 0;
+        boolean first = true;
+        GeomIterator git = new GeomIterator(geom);
+        while (git.hasComp()) {
+            git.nextComp();
+            while (git.hasEdge()) {
+                git.nextEdge();
+                while (git.hasNode()) {
+                    node = git.next();
+                    if (first) {
+                        first = false;
+                        lat = node.lat;
+                        lon = node.lon;
+                    } else if (node != null) {
+                        llat = lat;
+                        llon = lon;
+                        lat = node.lat;
+                        lon = node.lon;
+                        sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
+                    }
+                }
+            }
+        }
+        return sigma * 3444;
+    }
+
+    Snode calcCentroid(Feature feature) {
+        double lat, lon, slat, slon, llat, llon;
+        llat = llon = lat = lon = slat = slon = 0;
+        double sarc = 0;
+        boolean first = true;
+        switch (feature.geom.prim) {
+        case POINT:
+            return nodes.get(feature.geom.elems.get(0).id);
+        case LINE:
+            GeomIterator git = new GeomIterator(feature.geom);
+            while (git.hasComp()) {
+                git.nextComp();
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        if (node == null) continue;
+                        lat = node.lat;
+                        lon = node.lon;
+                        if (first) {
+                            first = false;
+                        } else {
+                            sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
+                        }
+                        llat = lat;
+                        llon = lon;
+                    }
+                }
+            }
+            double harc = sarc / 2;
+            sarc = 0;
+            first = true;
+            git = new GeomIterator(feature.geom);
+            while (git.hasComp()) {
+                git.nextComp();
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        if (node == null) continue;
+                        lat = node.lat;
+                        lon = node.lon;
+                        if (first) {
+                            first = false;
+                        } else {
+                            sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
+                            if (sarc > harc)
+                                break;
+                        }
+                        harc -= sarc;
+                        llat = lat;
+                        llon = lon;
+                    }
+                }
+            }
+            return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
+        case AREA:
+            git = new GeomIterator(feature.geom);
+            while (git.hasComp()) {
+                git.nextComp();
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        lat = node.lat;
+                        lon = node.lon;
+                        if (first) {
+                            first = false;
+                        } else {
+                            double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
+                            slat += ((lat + llat) / 2 * arc);
+                            slon += ((lon + llon) / 2 * arc);
+                            sarc += arc;
+                        }
+                        llon = lon;
+                        llat = lat;
+                    }
+                }
+            }
+            return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
+        default:
+        }
+        return null;
+    }
 
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57obj.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57obj.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57obj.java	(revision 32394)
@@ -10,161 +10,163 @@
 package s57;
 
-import java.util.*;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
 
 public class S57obj { // S57 Object lookup tables & methods
-	
-	public enum Obj {
-		UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
-		BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
-		COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
-		DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
-		HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
-		MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
-		PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
-		RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
-		SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
-		TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
-		WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
-		LG_SDM, LG_VSP, LITMIN, LITMAJ
-	}
+    // CHECKSTYLE.OFF: LineLength
 
-	private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
-	static {
-		ObjS57.put(Obj.UNKOBJ,0);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-	}
+    public enum Obj {
+        UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
+        BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
+        COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
+        DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
+        HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
+        MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
+        PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
+        RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
+        SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
+        TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
+        WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
+        LG_SDM, LG_VSP, LITMIN, LITMAJ
+    }
 
-	private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
-	static {
-		ObjIENC.put(Obj.UNKOBJ, 0);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		ObjIENC.put(Obj.LG_SDM, 18001);	ObjIENC.put(Obj.LG_VSP, 18002);
-	}
+    private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
+    static {
+        ObjS57.put(Obj.UNKOBJ, 0);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+    }
 
-	private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
-	static {
-		ObjStr.put(Obj.UNKOBJ, "");	ObjStr.put(Obj.AIRARE, "airfield");	ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
-		ObjStr.put(Obj.BCNCAR, "beacon_cardinal");	ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
-		ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
-		ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
-		ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral");	ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
-		ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area");	ObjStr.put(Obj.CBLOHD, "cable_overhead");
-		ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area");	ObjStr.put(Obj.CAUSWY, "causeway");
-		ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station");	ObjStr.put(Obj.COALNE, "coastline");
-		ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
-		ObjStr.put(Obj.CONVYR, "conveyor");	ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
-		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");
-		ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
-		ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock");	ObjStr.put(Obj.DMPGRD, "dumping_ground");	ObjStr.put(Obj.DYKCON, "dyke");
-		ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
-		ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility");	ObjStr.put(Obj.FSHGRD, "fishing_ground");	ObjStr.put(Obj.FLODOC, "floating_dock");
-		ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
-		ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area");	ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
-		ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
-		ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region");	ObjStr.put(Obj.LNDMRK, "landmark");
-		ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float");	ObjStr.put(Obj.LITVES, "light_vessel");	ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
-		ObjStr.put(Obj.LOKBSN, "lock_basin");	ObjStr.put(Obj.LOGPON, "log_pond");	ObjStr.put(Obj.MAGVAR, "magnetic_variation");	ObjStr.put(Obj.MARCUL, "marine_farm");
-		ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring");	ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
-		ObjStr.put(Obj.OFSPLF, "platform");	ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier");	ObjStr.put(Obj.PILPNT, "pile");
-		ObjStr.put(Obj.PILBOP, "pilot_boarding");	ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead");	ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
-		ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area");ObjStr.put(Obj.PYLONS, "pylon");
-		ObjStr.put(Obj.RADLNE, "radar_line");	ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector");	ObjStr.put(Obj.RADSTA, "radar_station");
-		ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station");	ObjStr.put(Obj.RAILWY, "railway");
-		ObjStr.put(Obj.RAPIDS, "rapids");	ObjStr.put(Obj.RCRTCL, "recommended_route_centreline");	ObjStr.put(Obj.RECTRC, "recommended_track");
-		ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane");	ObjStr.put(Obj.RSCSTA, "rescue_station");	ObjStr.put(Obj.RESARE, "restricted_area");
-		ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river");	ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
-		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");
-		ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
-		ObjStr.put(Obj.SILTNK, "tank");	ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
-		ObjStr.put(Obj.SOUNDG, "sounding");	ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline");	ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
-		ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area");	ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
-		ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary");	ObjStr.put(Obj.TSSCRS, "separation_crossing");
-		ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout");	ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
-		ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area");	ObjStr.put(Obj.VEGATN, "vegetation");
-		ObjStr.put(Obj.WATTUR, "water_turbulence");	ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
-		ObjStr.put(Obj.TS_FEB, "tidal_stream");	ObjStr.put(Obj.NOTMRK, "notice");	ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
-		ObjStr.put(Obj.BUNSTA, "bunker_station");	ObjStr.put(Obj.COMARE, "communication_area");	ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
-		ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
-		ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
-		ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
-		ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
-	}
-	
-	private static final HashMap<String, Obj> StrObj = new HashMap<>();
-	static {
-		for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
-			if (!entry.getValue().isEmpty())
-				StrObj.put(entry.getValue(), entry.getKey());
-		}
-	}
-	
-	public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
-		for (Obj obj : ObjS57.keySet()) {
-			if (ObjS57.get(obj) == objl) return obj;
-		}
-		for (Obj obj : ObjIENC.keySet()) {
-			if (ObjIENC.get(obj) == objl) return obj;
-		}
-		return Obj.UNKOBJ;
-	}
+    private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
+    static {
+        ObjIENC.put(Obj.UNKOBJ, 0);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        ObjIENC.put(Obj.LG_SDM, 18001); ObjIENC.put(Obj.LG_VSP, 18002);
+    }
 
-	public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
-		if (ObjS57.containsKey(type))
-			return ObjS57.get(type);
-		else if (ObjIENC.containsKey(type))
-			return ObjIENC.get(type);
-		return 0;
-	}
+    private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
+    static {
+        ObjStr.put(Obj.UNKOBJ, ""); ObjStr.put(Obj.AIRARE, "airfield"); ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
+        ObjStr.put(Obj.BCNCAR, "beacon_cardinal"); ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
+        ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
+        ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
+        ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral"); ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
+        ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area"); ObjStr.put(Obj.CBLOHD, "cable_overhead");
+        ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area"); ObjStr.put(Obj.CAUSWY, "causeway");
+        ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station"); ObjStr.put(Obj.COALNE, "coastline");
+        ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
+        ObjStr.put(Obj.CONVYR, "conveyor"); ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
+        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");
+        ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
+        ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock"); ObjStr.put(Obj.DMPGRD, "dumping_ground"); ObjStr.put(Obj.DYKCON, "dyke");
+        ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
+        ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility"); ObjStr.put(Obj.FSHGRD, "fishing_ground"); ObjStr.put(Obj.FLODOC, "floating_dock");
+        ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
+        ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area"); ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
+        ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
+        ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region"); ObjStr.put(Obj.LNDMRK, "landmark");
+        ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float"); ObjStr.put(Obj.LITVES, "light_vessel"); ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
+        ObjStr.put(Obj.LOKBSN, "lock_basin"); ObjStr.put(Obj.LOGPON, "log_pond"); ObjStr.put(Obj.MAGVAR, "magnetic_variation"); ObjStr.put(Obj.MARCUL, "marine_farm");
+        ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring"); ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
+        ObjStr.put(Obj.OFSPLF, "platform"); ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier"); ObjStr.put(Obj.PILPNT, "pile");
+        ObjStr.put(Obj.PILBOP, "pilot_boarding"); ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead"); ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
+        ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area"); ObjStr.put(Obj.PYLONS, "pylon");
+        ObjStr.put(Obj.RADLNE, "radar_line"); ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector"); ObjStr.put(Obj.RADSTA, "radar_station");
+        ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station"); ObjStr.put(Obj.RAILWY, "railway");
+        ObjStr.put(Obj.RAPIDS, "rapids"); ObjStr.put(Obj.RCRTCL, "recommended_route_centreline"); ObjStr.put(Obj.RECTRC, "recommended_track");
+        ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane"); ObjStr.put(Obj.RSCSTA, "rescue_station"); ObjStr.put(Obj.RESARE, "restricted_area");
+        ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river"); ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
+        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");
+        ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
+        ObjStr.put(Obj.SILTNK, "tank"); ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
+        ObjStr.put(Obj.SOUNDG, "sounding"); ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline"); ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
+        ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area"); ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
+        ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary"); ObjStr.put(Obj.TSSCRS, "separation_crossing");
+        ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout"); ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
+        ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area"); ObjStr.put(Obj.VEGATN, "vegetation");
+        ObjStr.put(Obj.WATTUR, "water_turbulence"); ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
+        ObjStr.put(Obj.TS_FEB, "tidal_stream"); ObjStr.put(Obj.NOTMRK, "notice"); ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
+        ObjStr.put(Obj.BUNSTA, "bunker_station"); ObjStr.put(Obj.COMARE, "communication_area"); ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
+        ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
+        ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
+        ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
+        ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
+    }
 
-	public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
-		String str = ObjStr.get(type);
-			return str != null ? str : "";
-	}
+    private static final HashMap<String, Obj> StrObj = new HashMap<>();
+    static {
+        for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
+            if (!entry.getValue().isEmpty())
+                StrObj.put(entry.getValue(), entry.getKey());
+        }
+    }
 
-	public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
-		if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
-			return StrObj.get(type);
-		else
-			return Obj.UNKOBJ;
-	}
-	
+    public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
+        for (Obj obj : ObjS57.keySet()) {
+            if (ObjS57.get(obj) == objl) return obj;
+        }
+        for (Obj obj : ObjIENC.keySet()) {
+            if (ObjIENC.get(obj) == objl) return obj;
+        }
+        return Obj.UNKOBJ;
+    }
+
+    public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
+        if (ObjS57.containsKey(type))
+            return ObjS57.get(type);
+        else if (ObjIENC.containsKey(type))
+            return ObjIENC.get(type);
+        return 0;
+    }
+
+    public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
+        String str = ObjStr.get(type);
+        return str != null ? str : "";
+    }
+
+    public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
+        if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
+            return StrObj.get(type);
+        else
+            return Obj.UNKOBJ;
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57osm.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 32394)
@@ -11,241 +11,245 @@
 
 import java.io.BufferedReader;
-import java.util.*;
-
-import s57.S57obj.*;
-import s57.S57att.*;
-import s57.S57val.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import s57.S57att.Att;
+import s57.S57obj.Obj;
+import s57.S57val.CatBUA;
+import s57.S57val.CatROD;
+import s57.S57val.Conv;
 
 public class S57osm { // OSM to S57 Object/Attribute and Object/Primitive conversions
-	
-	static class KeyVal<V> {
-		Obj obj;
-		Att att;
-		Conv conv;
-		V val;
-		KeyVal(Obj o, Att a, Conv c, V v) {
-			obj = o;
-			att = a;
-			conv = c;
-			val = v;
-		}
-	}
-	
-	private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
-	static {
-		OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
-		OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
-		OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
-		OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
-		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));
-		OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
-		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));
-		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));
-		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));
-		OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
-		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));
-		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));
-		OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
-		OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
-		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));
-		OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
-		}
-	
-	public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
-		KeyVal<?> kv = OSMtags.get(key + "=" + val);
-		if (kv != null) {
-			if (kv.conv == Conv.E) {
-				ArrayList<Enum<?>> list = new ArrayList<>();
-				list.add((Enum<?>)kv.val);
-				osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
-			} else {
-				osm.add(kv);
-			}
-		}
-		KeyVal<?> kvl = null;
-		KeyVal<?> kvd = null;
-		boolean rc = false;
-		boolean rcl = false;
-		for (KeyVal<?> kvx : osm) {
-			if (kvx.obj == Obj.LAKARE) {
-				kvl = kvx;
-			} else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
-				rc = true;
-			}
-			if (kvx.obj == Obj.DEPARE) {
-				kvd = kvx;
-			} else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
-				rcl = true;
-			}
-		}
-		if (rc && (kvl != null)) {
-			osm.remove(kvl);
-		}
-		if (rcl && (kvd != null)) {
-			osm.remove(kvd);
-		}
-		return;
-	}
-	
-	public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
-		String k = "";
-		String v = "";
-
-		double lat = 0;
-		double lon = 0;
-		long id = 0;
-
-		boolean inOsm = false;
-		boolean inNode = false;
-		boolean inWay = false;
-		boolean inRel = false;
-		map.nodes.put(1l, map.new Snode());
-		map.nodes.put(2l, map.new Snode());
-		map.nodes.put(3l, map.new Snode());
-		map.nodes.put(4l, map.new Snode());
-
-		String ln;
-		while ((ln = in.readLine()) != null) {
-			if (inOsm) {
-				if (ln.contains("<bounds") && !bb) {
-					for (String token : ln.split("[ ]+")) {
-						if (token.matches("^minlat=.+")) {
-							map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
-							map.nodes.get(2l).lat = map.bounds.minlat;
-							map.nodes.get(3l).lat = map.bounds.minlat;
-						} else if (token.matches("^minlon=.+")) {
-							map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
-							map.nodes.get(1l).lon = map.bounds.minlon;
-							map.nodes.get(2l).lon = map.bounds.minlon;
-						} else if (token.matches("^maxlat=.+")) {
-							map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
-							map.nodes.get(1l).lat = map.bounds.maxlat;
-							map.nodes.get(4l).lat = map.bounds.maxlat;
-						} else if (token.matches("^maxlon=.+")) {
-							map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
-							map.nodes.get(3l).lon = map.bounds.maxlon;
-							map.nodes.get(4l).lon = map.bounds.maxlon;
-						}
-					}
-				} else {
-					if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
-						k = v = "";
-						String[] token = ln.split("k=");
-						k = token[1].split("[\"\']")[1];
-						token = token[1].split("v=");
-						v = token[1].split("[\"\']")[1];
-						if (!k.isEmpty() && !v.isEmpty()) {
-							map.addTag(k, v);
-						}
-					}
-					if (inNode) {
-						if (ln.contains("</node")) {
-							inNode = false;
-							map.tagsDone(id);
-						}
-					} else if (ln.contains("<node")) {
-						for (String token : ln.split("[ ]+")) {
-							if (token.matches("^id=.+")) {
-								id = Long.parseLong(token.split("[\"\']")[1]);
-							} else if (token.matches("^lat=.+")) {
-								lat = Double.parseDouble(token.split("[\"\']")[1]);
-							} else if (token.matches("^lon=.+")) {
-								lon = Double.parseDouble(token.split("[\"\']")[1]);
-							}
-						}
-						map.addNode(id, lat, lon);
-						if (ln.contains("/>")) {
-							map.tagsDone(id);
-						} else {
-							inNode = true;
-						}
-					} else if (inWay) {
-						if (ln.contains("<nd")) {
-							long ref = 0;
-							for (String token : ln.split("[ ]+")) {
-								if (token.matches("^ref=.+")) {
-									ref = Long.parseLong(token.split("[\"\']")[1]);
-								}
-							}
-							try {
-								map.addToEdge(ref);
-							} catch (Exception e) {
-								inWay = false;
-							}
-						}
-						if (ln.contains("</way")) {
-							inWay = false;
-							map.tagsDone(id);
-						}
-					} else if (ln.contains("<way")) {
-						for (String token : ln.split("[ ]+")) {
-							if (token.matches("^id=.+")) {
-								id = Long.parseLong(token.split("[\"\']")[1]);
-							}
-						}
-						map.addEdge(id);
-						if (ln.contains("/>")) {
-							map.tagsDone(0);
-						} else {
-							inWay = true;
-						}
-					} else if (ln.contains("</osm")) {
-						map.mapDone();
-						inOsm = false;
-						break;
-					} else if (inRel) {
-						if (ln.contains("<member")) {
-							String type = "";
-							String role = "";
-							long ref = 0;
-							for (String token : ln.split("[ ]+")) {
-								if (token.matches("^ref=.+")) {
-									ref = Long.parseLong(token.split("[\"\']")[1]);
-								} else if (token.matches("^type=.+")) {
-									type = (token.split("[\"\']")[1]);
-								} else if (token.matches("^role=.+")) {
-									String str[] = token.split("[\"\']");
-									if (str.length > 1) {
-										role = (token.split("[\"\']")[1]);
-									}
-								}
-							}
-							if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
-								map.addToArea(ref, role.equals("outer"));
-						}
-						if (ln.contains("</relation")) {
-							inRel = false;
-							map.tagsDone(id);
-						}
-					} else if (ln.contains("<relation")) {
-						for (String token : ln.split("[ ]+")) {
-							if (token.matches("^id=.+")) {
-								id = Long.parseLong(token.split("[\"\']")[1]);
-							}
-						}
-						map.addArea(id);
-						if (ln.contains("/>")) {
-							map.tagsDone(id);
-						} else {
-							inRel = true;
-						}
-					}
-				}
-			} else if (ln.contains("<osm")) {
-				inOsm = true;
-			}
-		}
-		return;
-	}
-	
-	public static void OSMmeta(S57map map) {
-		map.addEdge(++map.xref);
-		for (long ref = 0; ref <= 4; ref++) {
-			map.addToEdge((ref == 0) ? 4 : ref);
-		}
-		map.addTag("seamark:type", "coverage");
-		map.addTag("seamark:coverage:category", "coverage");
-		map.tagsDone(map.xref);
-	}
-	
+    // CHECKSTYLE.OFF: LineLength
+
+    static class KeyVal<V> {
+        Obj obj;
+        Att att;
+        Conv conv;
+        V val;
+        KeyVal(Obj o, Att a, Conv c, V v) {
+            obj = o;
+            att = a;
+            conv = c;
+            val = v;
+        }
+    }
+
+    private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
+    static {
+        OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
+        OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
+        OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
+        OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
+        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));
+        OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
+        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));
+        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));
+        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));
+        OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
+        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));
+        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));
+        OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
+        OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
+        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));
+        OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
+    }
+
+    public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
+        KeyVal<?> kv = OSMtags.get(key + "=" + val);
+        if (kv != null) {
+            if (kv.conv == Conv.E) {
+                ArrayList<Enum<?>> list = new ArrayList<>();
+                list.add((Enum<?>) kv.val);
+                osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
+            } else {
+                osm.add(kv);
+            }
+        }
+        KeyVal<?> kvl = null;
+        KeyVal<?> kvd = null;
+        boolean rc = false;
+        boolean rcl = false;
+        for (KeyVal<?> kvx : osm) {
+            if (kvx.obj == Obj.LAKARE) {
+                kvl = kvx;
+            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
+                rc = true;
+            }
+            if (kvx.obj == Obj.DEPARE) {
+                kvd = kvx;
+            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
+                rcl = true;
+            }
+        }
+        if (rc && (kvl != null)) {
+            osm.remove(kvl);
+        }
+        if (rcl && (kvd != null)) {
+            osm.remove(kvd);
+        }
+        return;
+    }
+
+    public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
+        String k = "";
+        String v = "";
+
+        double lat = 0;
+        double lon = 0;
+        long id = 0;
+
+        boolean inOsm = false;
+        boolean inNode = false;
+        boolean inWay = false;
+        boolean inRel = false;
+        map.nodes.put(1L, map.new Snode());
+        map.nodes.put(2L, map.new Snode());
+        map.nodes.put(3L, map.new Snode());
+        map.nodes.put(4L, map.new Snode());
+
+        String ln;
+        while ((ln = in.readLine()) != null) {
+            if (inOsm) {
+                if (ln.contains("<bounds") && !bb) {
+                    for (String token : ln.split("[ ]+")) {
+                        if (token.matches("^minlat=.+")) {
+                            map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+                            map.nodes.get(2L).lat = map.bounds.minlat;
+                            map.nodes.get(3L).lat = map.bounds.minlat;
+                        } else if (token.matches("^minlon=.+")) {
+                            map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+                            map.nodes.get(1L).lon = map.bounds.minlon;
+                            map.nodes.get(2L).lon = map.bounds.minlon;
+                        } else if (token.matches("^maxlat=.+")) {
+                            map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+                            map.nodes.get(1L).lat = map.bounds.maxlat;
+                            map.nodes.get(4L).lat = map.bounds.maxlat;
+                        } else if (token.matches("^maxlon=.+")) {
+                            map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+                            map.nodes.get(3L).lon = map.bounds.maxlon;
+                            map.nodes.get(4L).lon = map.bounds.maxlon;
+                        }
+                    }
+                } else {
+                    if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
+                        k = v = "";
+                        String[] token = ln.split("k=");
+                        k = token[1].split("[\"\']")[1];
+                        token = token[1].split("v=");
+                        v = token[1].split("[\"\']")[1];
+                        if (!k.isEmpty() && !v.isEmpty()) {
+                            map.addTag(k, v);
+                        }
+                    }
+                    if (inNode) {
+                        if (ln.contains("</node")) {
+                            inNode = false;
+                            map.tagsDone(id);
+                        }
+                    } else if (ln.contains("<node")) {
+                        for (String token : ln.split("[ ]+")) {
+                            if (token.matches("^id=.+")) {
+                                id = Long.parseLong(token.split("[\"\']")[1]);
+                            } else if (token.matches("^lat=.+")) {
+                                lat = Double.parseDouble(token.split("[\"\']")[1]);
+                            } else if (token.matches("^lon=.+")) {
+                                lon = Double.parseDouble(token.split("[\"\']")[1]);
+                            }
+                        }
+                        map.addNode(id, lat, lon);
+                        if (ln.contains("/>")) {
+                            map.tagsDone(id);
+                        } else {
+                            inNode = true;
+                        }
+                    } else if (inWay) {
+                        if (ln.contains("<nd")) {
+                            long ref = 0;
+                            for (String token : ln.split("[ ]+")) {
+                                if (token.matches("^ref=.+")) {
+                                    ref = Long.parseLong(token.split("[\"\']")[1]);
+                                }
+                            }
+                            try {
+                                map.addToEdge(ref);
+                            } catch (Exception e) {
+                                inWay = false;
+                            }
+                        }
+                        if (ln.contains("</way")) {
+                            inWay = false;
+                            map.tagsDone(id);
+                        }
+                    } else if (ln.contains("<way")) {
+                        for (String token : ln.split("[ ]+")) {
+                            if (token.matches("^id=.+")) {
+                                id = Long.parseLong(token.split("[\"\']")[1]);
+                            }
+                        }
+                        map.addEdge(id);
+                        if (ln.contains("/>")) {
+                            map.tagsDone(0);
+                        } else {
+                            inWay = true;
+                        }
+                    } else if (ln.contains("</osm")) {
+                        map.mapDone();
+                        inOsm = false;
+                        break;
+                    } else if (inRel) {
+                        if (ln.contains("<member")) {
+                            String type = "";
+                            String role = "";
+                            long ref = 0;
+                            for (String token : ln.split("[ ]+")) {
+                                if (token.matches("^ref=.+")) {
+                                    ref = Long.parseLong(token.split("[\"\']")[1]);
+                                } else if (token.matches("^type=.+")) {
+                                    type = (token.split("[\"\']")[1]);
+                                } else if (token.matches("^role=.+")) {
+                                    String[] str = token.split("[\"\']");
+                                    if (str.length > 1) {
+                                        role = (token.split("[\"\']")[1]);
+                                    }
+                                }
+                            }
+                            if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
+                                map.addToArea(ref, role.equals("outer"));
+                        }
+                        if (ln.contains("</relation")) {
+                            inRel = false;
+                            map.tagsDone(id);
+                        }
+                    } else if (ln.contains("<relation")) {
+                        for (String token : ln.split("[ ]+")) {
+                            if (token.matches("^id=.+")) {
+                                id = Long.parseLong(token.split("[\"\']")[1]);
+                            }
+                        }
+                        map.addArea(id);
+                        if (ln.contains("/>")) {
+                            map.tagsDone(id);
+                        } else {
+                            inRel = true;
+                        }
+                    }
+                }
+            } else if (ln.contains("<osm")) {
+                inOsm = true;
+            }
+        }
+        return;
+    }
+
+    public static void OSMmeta(S57map map) {
+        map.addEdge(++map.xref);
+        for (long ref = 0; ref <= 4; ref++) {
+            map.addToEdge((ref == 0) ? 4 : ref);
+        }
+        map.addTag("seamark:type", "coverage");
+        map.addTag("seamark:coverage:category", "coverage");
+        map.tagsDone(map.xref);
+    }
+
 }
Index: applications/editors/josm/plugins/seachart/src/s57/S57val.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32394)
@@ -10,1260 +10,1650 @@
 package s57;
 
-import java.util.*;
-
-import s57.S57att.*;
+import java.util.ArrayList;
+import java.util.EnumMap;
+
+import s57.S57att.Att;
 
 public class S57val { // S57 Attribute values lookup tables & methods
-
- static class S57enum {
-  Integer atvl;
-  String val;
-  S57enum(Integer a, String v) {
-   atvl = a; val = v;
-  }
- }
- 
- public enum Conv { S, A, L, E, F, I }
- 
- static class S57key {
-  Conv conv;
-  EnumMap<?, ?> map;
-  S57key(Conv c, EnumMap<?, S57enum> m) {
-   conv = c; map = m;
-  }
- }
- 
- public static class AttVal<V> {
-  public Conv conv;
-  public V val;
-  AttVal(Conv c, V v) {
-   conv = c; val = v;
-  }
- }
- 
- 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 }
- private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class); static { Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
- }
- public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
- private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class); static { Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
-  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"));
-  Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
- }
- public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
- private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class); static { Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-   Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
- }
- public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
- private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class); static { Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
- }
- 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 }
- private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class); static {Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
- }
- 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 }
- private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
- }
- public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
- private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static { Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY } 
- private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
- }
- public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
- private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static { Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
-  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"));
- }
- public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
- private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static { Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
-  Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
-  Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
- }
- public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
- private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static { Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
-  Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
- }
- 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 } 
- private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static { Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
- }
- public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS } 
- private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static { Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
- }
- public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
- private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static { Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
-  Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
- }
- public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH } 
- private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static { Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
- private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static { Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
-  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"));
- }
- public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
- private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static { Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
-  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"));
-  Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
- }
- public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
- private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static { Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
-  Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
- }
- public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL } 
- private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static { Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
- private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static { Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
-  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"));
-  Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
- }
- public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR } 
- private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static { Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
-  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"));
-  Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
- }
- public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY } 
- private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static { Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
-  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"));
-  Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
- }
- 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 }
- private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
-  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"));
-  Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
-   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"));
-   Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
-  }
- public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT } 
- private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static { Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC } 
- private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static { Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- 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,
-  HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF } 
- private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static { Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support"));  Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
-  Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
- }
- public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO } 
- private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static { Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR } 
- private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static { Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
- }
- public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
- private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static { 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"));
- }
- 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,
-  LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
- private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static { Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
- }
- 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,
-  LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
- private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
-   Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
- }
- 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,
-  LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP } 
- private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static { Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
- }
- 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 }
- private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static { Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
- }
- public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
- private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static { Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
-  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"));
-  Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
- }
- public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA } 
- private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static { Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- 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 } 
- private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static { Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
- }
- public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
- private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static { Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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,
-	 OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII } 
- private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static { Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
- }
-
- 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 } 
- private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static { Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
- }
- public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
- private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static { Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
-  Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
- }
- public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
- private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static { Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
-
- public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
- private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static { Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
-  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"));
- }
- public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
- private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static { Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
-  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"));
-  Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
- }
- 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 } 
- private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static { Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
- }
- public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER } 
- private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static { Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
-  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"));
-  Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
- }
- public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
- private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static { Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
-  Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
- }
- public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
- private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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,
-  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 } 
- private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static { Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
-  Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
-  Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
-  Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
-  Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck")); 
- }
- 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 } 
- private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static { Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
- }
- 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,
-  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,
-  REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS } 
- private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static { Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
-   Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
-   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"));
- }
- public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH } 
- private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static { Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
- }
- public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
- private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static { 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"));
- }
- 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,
-  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,
-  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,
-  SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
- private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static { Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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")); 
-  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"));
- }
- 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,
-  SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF,  SLC_OFWF,  SLC_LRMP,  SLC_LWAL, SLC_ICEB } 
- private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static { Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
- }
- 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 }
- private static final EnumMap<CatSIT, S57enum>  Catsit = new EnumMap<>(CatSIT.class); static {Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
- }
- 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,
-   SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
- private static final EnumMap<CatSIW, S57enum>  Catsiw = new EnumMap<>(CatSIW.class); static {Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-   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"));
-   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"));
-   Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
- }
- public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT } 
- private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static { Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
-  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"));
-  Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
- }
- public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE } 
- private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static { Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- 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,
-  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,
-  SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
- private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static { Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
- }
- 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,
-  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,
-  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 } 
- private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static { Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
-  Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-   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"));
-   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"));
-   Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
- }
- public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
- private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static { Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
-  Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
- }
- public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
- private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static { Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
-  Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
- }
- 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,
-  VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
- private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static { Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
- }
- public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR } 
- private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static { Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
-  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"));
-  Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
- }
- public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO } 
- private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static { Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
-  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"));
-  Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
- }
- public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS } 
- private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static { Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
-  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"));
-  Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
- }
- public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U } 
- private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static { Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- 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 }
- private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static { Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
- }
- public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
- private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static { Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
- }
- public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS } 
- private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static { Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
-  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"));
-  Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
- }
- public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
- private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static { Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
-  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"));
- }
- public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
- private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static { Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
-  Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
- }
- public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
- private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static { Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
-  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"));
-  Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
- }
- public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM } 
- private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static { Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
-  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"));
-  Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
- }
- public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
- private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static { Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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,
-  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,
-  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,
-  FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
- private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
- }
-
- public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
- private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static { Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
- private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static { Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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,
-  CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
- private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static { Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
- }
- public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
- private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static { Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
- }
- public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
- private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static { Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
- }
- 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 }
- private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static { Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
- }
- 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 } 
- private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static { Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
- }
- 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 } 
- private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static { Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
- }
- 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,
-  PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
- private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static { Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
- }
- 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 } 
- private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static { Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
- }
- 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,
-  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,
-  RST_RFWD, RST_RFWW, RST_NSWM  }
- private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static { Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
-  Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
-  Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
-  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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
- }
- public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
- private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static { Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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,
-  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 } 
- private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static { Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
-  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")); 
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
- }
- public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
- private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static { Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
-  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"));
-  Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
- }
- 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 } 
- private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static { Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
- 	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"));
-  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"));
-  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"));
-  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"));
-  Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
- }
- 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,
-   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,
-   TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
-
-	private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static { Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		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"));
-		Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
-	}
- public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
- private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static { Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
-  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"));
-  Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
- }
- public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
- private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static { Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
- }
- public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
- 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, ""));
-  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"));
- }
- public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS } 
- private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static { Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
-  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"));
-  Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
- }
- 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 } 
- private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static { Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
- }
- 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,
-  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,
-  DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO } 
- private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static { Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
- }
- public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
- private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static { Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
-  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"));
-  Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
- }
- public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
- private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static { Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
- Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
- }
- 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,
-  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,
-  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,
-  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,
-  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,
-  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,
-  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,
-  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,
-  NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
- private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static { Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-   Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit"));  Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
-   Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
-   Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
-   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"));
-   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"));
-   Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
-   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"));
-   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"));
-   Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
-   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"));
-   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"));
-   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"));
-   Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
-   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"));
-   Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   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"));
-   Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point")); 
- }
- public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
- private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static { Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
-  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"));
-  Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
- }
- public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
- private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static { Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
-  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"));
-  Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
- }
- public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
- private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static { Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
-  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"));
-  Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
- }
- public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
- private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static { Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
-  Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
- }
- public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS } 
- private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static { Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
-  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"));
-  Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
-  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"));
- }
- public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
- private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static { Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
-  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"));
- }
- 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 } 
- private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static { Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-   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"));
-   Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
- }
- public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR } 
- private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static { Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
- }
- public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
- private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static { Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
-  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"));
-  Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
- }
- public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF } 
- private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static { Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
-  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"));
-  Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
- }
- public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
- private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static { Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
-  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"));
-  Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
- }
- 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 } 
- private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static { Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
- }
- public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI } 
- private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static { Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
-  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"));
-  Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
- }
- public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 } 
- private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static { Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
- }
- public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
- private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static { Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
- }
- public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
- private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static { Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
-  Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
- }
- public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
- private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static { Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
-  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"));
- }
- public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR } 
- private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static { Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
-  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"));
-  Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
- }
- 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,
-  WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR } 
- private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static { Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
- }
- public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
- 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, ""));
-  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"));
- }
- public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
- 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, ""));
-  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"));
- }
- public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
- 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, ""));
-  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"));
-  Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
- }
- public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD } 
- 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, ""));
-  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"));
-  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"));
-  Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
- }
- 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, 
-  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 }
- 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, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
- }
- 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, ""));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  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"));
-  Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
- }
- public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV } 
- 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, ""));
-  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"));
-  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"));
-  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"));
- }
- 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, ""));
-  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"));
-  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"));
-  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"));
- }
- public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS } 
- 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, ""));
-  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"));
-  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"));
-  Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
- }
- 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, ""));
-  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"));
-  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"));
-  Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
- }
-
- 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 }
- private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static { Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
-  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"));
-  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."));
-  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"));
-  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"));
-  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"));
- }
-
- public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
- private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static { Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
- Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
- }
-
- private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
- static {
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.RADIUS, new S57key(Conv.F, null));
-  keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  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));
-  keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
- }
- 
- public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
-  EnumMap<?, ?> map = keys.get(att).map;
-  Enum<?> unkn = null;
-  int i = 0;
-  try {
-   i = Integer.parseInt(val);
-  } catch (Exception e) {
-   return unkn;
-  }
-  if (map != null) {
-   for (Object item : map.keySet()) {
-    if (unkn == null)
-     unkn = (Enum<?>) item;
-    if (((S57enum) map.get(item)).atvl.equals(i))
-     return (Enum<?>) item;
-   }
-  }
-  return unkn;
- }
-
- public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
-  Conv conv = keys.get(att).conv;
-  switch (conv) {
-  case A:
-  case S:
-   return new AttVal<>(conv, val);
-  case E:
-   ArrayList<Enum<?>> list = new ArrayList<>();
-   list.add(s57Enum(val, att));
-   return new AttVal<ArrayList<?>>(Conv.E, list);
-  case L:
-   list = new ArrayList<>();
-   for (String item : val.split(",")) {
-    list.add(s57Enum(item, att));
-   }
-   return new AttVal<ArrayList<?>>(Conv.L, list);
-  case I:
-   try {
-    return new AttVal<>(Conv.I, Long.parseLong(val));
-   } catch (Exception e) {
-    break;
-   }
-  case F:
-   try {
-    return new AttVal<>(Conv.F, Double.parseDouble(val));
-   } catch (Exception e) {
-    break;
-   }
-  }
-  return null;
- }
-
- public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
-	  if (attval != null) {
-	  	String str = stringValue(attval, att);
-	  	if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
-	  		String[] vals = str.split(";");
-	  		str = "";
-	  		for (String val : vals) {
-	  			if (!str.isEmpty()) str += ",";
-	  			EnumMap<?, ?> map = keys.get(att).map;
-	  			for (Object item : map.keySet()) {
-	  				if (((S57enum)map.get(item)).val.equals(val))
-		        str += ((S57enum)map.get(item)).atvl.toString();
-		      }
-	  		}
-	  	}
-  		return str;
-	  }
-  return "";
- }
-
- public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
-  if (attval != null) {
-   switch (attval.conv) {
-   case A:
-   case S:
-    return (String) attval.val;
-   case E:
-    EnumMap<?, ?> map = keys.get(att).map;
-    return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
-   case L:
-    String str = "";
-    map = keys.get(att).map;
-    for (Object item : (ArrayList<?>) attval.val) {
-     if (!str.isEmpty())
-      str += ";";
-     if (item != null)
-      str += ((S57enum) map.get(item)).val;
-    }
-    return str;
-   case I:
-    return ((Long) attval.val).toString();
-   case F:
-    return ((Double) attval.val).toString();
-   }
-  }
-  return "";
- }
-
- public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
-  EnumMap<?, ?> map = keys.get(att).map;
-  Enum<?> unkn = null;
-  if (map != null) {
-   for (Object item : map.keySet()) {
-    if (unkn == null)
-     unkn = (Enum<?>) item;
-    if (((S57enum) map.get(item)).val.equals(val))
-     return (Enum<?>) item;
-   }
-  }
-  return unkn;
- }
-
- public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
-  switch (keys.get(att).conv) {
-  case A:
-  case S:
-   return new AttVal<>(Conv.S, val);
-  case E:
-   ArrayList<Enum<?>> list = new ArrayList<>();
-   list.add(osmEnum(val, att));
-   return new AttVal<ArrayList<?>>(Conv.E, list);
-  case L:
-   list = new ArrayList<>();
-   for (String item : val.split(";")) {
-    list.add(osmEnum(item, att));
-   }
-   return new AttVal<ArrayList<?>>(Conv.L, list);
-  case I:
-   try {
-    return new AttVal<>(Conv.I, Long.parseLong(val));
-   } catch (Exception e) {
-    break;
-   }
-  case F:
-   try {
-    return new AttVal<>(Conv.F, Double.parseDouble(val));
-   } catch (Exception e) {
-    break;
-   }
-  }
-  return new AttVal<>(keys.get(att).conv, null);
- }
- 
- public static Enum<?> unknAtt(Att att) {
-  return (Enum<?>)(keys.get(att).map.keySet().toArray()[0]);
- }
-
+    // CHECKSTYLE.OFF: LineLength
+
+    static class S57enum {
+        Integer atvl;
+        String val;
+        S57enum(Integer a, String v) {
+            atvl = a; val = v;
+        }
+    }
+
+    public enum Conv { S, A, L, E, F, I }
+
+    static class S57key {
+        Conv conv;
+        EnumMap<?, ?> map;
+        S57key(Conv c, EnumMap<?, S57enum> m) {
+            conv = c; map = m;
+        }
+    }
+
+    public static class AttVal<V> {
+        public Conv conv;
+        public V val;
+        AttVal(Conv c, V v) {
+            conv = c; val = v;
+        }
+    }
+
+    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 }
+
+    private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class);
+    static {
+        Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
+    }
+
+    public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
+
+    private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class);
+    static {
+        Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
+        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"));
+        Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
+    }
+
+    public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
+
+    private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class);
+    static {
+        Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
+    }
+
+    public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
+
+    private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class);
+    static {
+        Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class);
+    static {
+        Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {
+        Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
+
+    private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static {
+        Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY }
+
+    private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {
+        Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
+    }
+
+    public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
+
+    private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static {
+        Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
+
+    private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static {
+        Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
+        Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
+        Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
+    }
+
+    public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
+
+    private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static {
+        Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
+        Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static {
+        Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
+    }
+
+    public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS }
+
+    private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static {
+        Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
+    }
+
+    public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
+
+    private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static {
+        Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
+        Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
+    }
+
+    public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH }
+
+    private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static {
+        Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
+
+    private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static {
+        Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
+
+    private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static {
+        Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
+        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"));
+        Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
+    }
+
+    public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
+
+    private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static {
+        Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
+        Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
+    }
+
+    public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL }
+
+    private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static {
+        Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
+
+    private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static {
+        Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
+        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"));
+        Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
+    }
+
+    public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR }
+
+    private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static {
+        Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
+        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"));
+        Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
+    }
+
+    public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY }
+
+    private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static {
+        Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
+        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"));
+        Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {
+        Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
+        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"));
+        Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
+        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"));
+        Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
+    }
+
+    public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT }
+
+    private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static {
+        Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC }
+
+    private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static {
+        Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    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,
+        HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF }
+
+    private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static {
+        Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support")); Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
+        Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
+    }
+
+    public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO }
+
+    private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static {
+        Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR }
+
+    private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static {
+        Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
+    }
+
+    public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
+
+    private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static {
+        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"));
+    }
+
+    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,
+        LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
+
+    private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static {
+        Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
+    }
+
+    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,
+        LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
+
+    private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {
+        Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
+        Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
+    }
+
+    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,
+        LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP }
+
+    private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static {
+        Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static {
+        Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
+
+    private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static {
+        Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
+        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"));
+        Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
+    }
+
+    public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA }
+
+    private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static {
+        Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static {
+        Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
+
+    private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static {
+        Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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,
+        OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII }
+
+    private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static {
+        Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static {
+        Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
+    }
+
+    public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
+
+    private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static {
+        Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
+        Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
+    }
+
+    public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
+
+    private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static {
+        Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
+
+    private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static {
+        Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
+
+    private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static {
+        Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
+        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"));
+        Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static {
+        Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
+    }
+
+    public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER }
+
+    private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static {
+        Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
+        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"));
+        Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
+    }
+
+    public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
+
+    private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static {
+        Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
+        Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
+    }
+
+    public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
+
+    private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {
+        Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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,
+        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 }
+
+    private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static {
+        Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
+        Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
+        Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
+        Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
+        Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static {
+        Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
+    }
+
+    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,
+        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,
+        REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS }
+
+    private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static {
+        Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
+        Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
+        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"));
+    }
+
+    public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH }
+
+    private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static {
+        Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
+    }
+
+    public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
+
+    private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static {
+        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"));
+    }
+
+    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,
+        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,
+        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,
+        SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
+
+    private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static {
+        Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    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,
+        SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF, SLC_OFWF, SLC_LRMP, SLC_LWAL, SLC_ICEB }
+
+    private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static {
+        Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatSIT, S57enum> Catsit = new EnumMap<>(CatSIT.class); static {
+        Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
+    }
+
+    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,
+        SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
+
+    private static final EnumMap<CatSIW, S57enum> Catsiw = new EnumMap<>(CatSIW.class); static {
+        Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
+    }
+
+    public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT }
+
+    private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static {
+        Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
+        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"));
+        Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
+    }
+
+    public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE }
+
+    private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static {
+        Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    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,
+        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,
+        SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
+
+    private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static {
+        Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    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,
+        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,
+        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 }
+
+    private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static {
+        Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
+        Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
+    }
+
+    public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
+
+    private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static {
+        Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
+        Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
+    }
+
+    public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
+
+    private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static {
+        Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
+        Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
+    }
+
+    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,
+        VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
+
+    private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static {
+        Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
+    }
+
+    public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR }
+
+    private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static {
+        Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
+        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"));
+        Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
+    }
+
+    public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO }
+
+    private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static {
+        Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
+        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"));
+        Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
+    }
+
+    public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS }
+
+    private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static {
+        Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
+        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"));
+        Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
+    }
+
+    public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U }
+
+    private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static {
+        Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static {
+        Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
+    }
+
+    public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
+
+    private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static {
+        Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
+    }
+
+    public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS }
+
+    private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static {
+        Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
+        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"));
+        Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
+    }
+
+    public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
+
+    private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static {
+        Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
+
+    private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static {
+        Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
+        Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
+    }
+
+    public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
+
+    private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static {
+        Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
+        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"));
+        Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
+    }
+
+    public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM }
+
+    private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static {
+        Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
+        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"));
+        Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
+    }
+
+    public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
+
+    private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static {
+        Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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,
+        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,
+        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,
+        FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
+
+    private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {
+        Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
+    }
+
+    public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
+
+    private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static {
+        Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
+
+    private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static {
+        Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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,
+        CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
+
+    private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static {
+        Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
+    }
+
+    public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
+
+    private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static {
+        Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
+    }
+
+    public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
+
+    private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static {
+        Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static {
+        Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static {
+        Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
+    }
+
+    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 }
+
+    private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static {
+        Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
+    }
+
+    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,
+        PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
+
+    private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static {
+        Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
+    }
+
+    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 }
+
+    private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static {
+        Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
+    }
+
+    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,
+        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,
+        RST_RFWD, RST_RFWW, RST_NSWM }
+
+    private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static {
+        Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
+        Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
+        Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
+    }
+
+    public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
+
+    private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static {
+        Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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,
+        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 }
+
+    private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static {
+        Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
+    }
+
+    public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
+
+    private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static {
+        Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
+        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"));
+        Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
+    }
+
+    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 }
+
+    private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static {
+        Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
+    }
+
+    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,
+        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,
+        TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
+
+    private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static {
+        Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
+    }
+
+    public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
+
+    private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static {
+        Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
+        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"));
+        Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
+    }
+
+    public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
+
+    private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static {
+        Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
+
+    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, ""));
+        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"));
+    }
+
+    public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS }
+
+    private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static {
+        Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
+        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"));
+        Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
+    }
+
+    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 }
+
+    private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static {
+        Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
+    }
+
+    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,
+        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,
+        DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO }
+
+    private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static {
+        Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
+    }
+
+    public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
+
+    private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static {
+        Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
+        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"));
+        Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
+    }
+
+    public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
+
+    private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static {
+        Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
+        Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
+    }
+
+    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,
+        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,
+        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,
+        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,
+        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,
+        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,
+        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,
+        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,
+        NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
+
+    private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static {
+        Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit")); Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
+        Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
+        Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
+        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"));
+        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"));
+        Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
+        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"));
+        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"));
+        Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
+        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"));
+        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"));
+        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"));
+        Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
+        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"));
+        Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point"));
+    }
+
+    public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
+
+    private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static {
+        Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
+        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"));
+        Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
+    }
+
+    public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
+
+    private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static {
+        Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
+        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"));
+        Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
+    }
+
+    public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
+
+    private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static {
+        Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
+        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"));
+        Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
+    }
+
+    public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
+
+    private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static {
+        Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
+        Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
+    }
+
+    public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS }
+
+    private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static {
+        Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
+        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"));
+        Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
+        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"));
+    }
+
+    public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
+
+    private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static {
+        Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    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 }
+
+    private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static {
+        Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
+    }
+
+    public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR }
+
+    private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static {
+        Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
+    }
+
+    public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
+
+    private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static {
+        Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
+        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"));
+        Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
+    }
+
+    public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF }
+
+    private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static {
+        Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
+        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"));
+        Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
+    }
+
+    public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
+
+    private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static {
+        Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
+        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"));
+        Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
+    }
+
+    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 }
+
+    private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static {
+        Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
+    }
+
+    public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI }
+
+    private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static {
+        Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
+        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"));
+        Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
+    }
+
+    public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 }
+
+    private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static {
+        Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
+
+    private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static {
+        Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+    }
+
+    public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
+
+    private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static {
+        Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
+        Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
+    }
+
+    public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
+
+    private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static {
+        Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
+        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"));
+    }
+
+    public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR }
+
+    private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static {
+        Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
+        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"));
+        Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
+    }
+
+    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,
+        WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR }
+
+    private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static {
+        Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
+    }
+
+    public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
+
+    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, ""));
+        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"));
+    }
+
+    public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
+
+    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, ""));
+        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"));
+    }
+
+    public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
+
+    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, ""));
+        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"));
+        Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
+    }
+
+    public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD }
+
+    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, ""));
+        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"));
+        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"));
+        Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
+    }
+
+    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,
+        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 }
+
+    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, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
+    }
+
+    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, ""));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        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"));
+        Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
+    }
+
+    public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV }
+
+    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, ""));
+        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"));
+        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"));
+        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"));
+    }
+
+    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, ""));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS }
+
+    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, ""));
+        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"));
+        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"));
+        Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
+    }
+
+    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, ""));
+        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"));
+        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"));
+        Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
+    }
+
+    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 }
+
+    private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static {
+        Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
+        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"));
+        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."));
+        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"));
+        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"));
+        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"));
+    }
+
+    public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
+
+    private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static {
+        Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
+        Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
+    }
+
+    private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
+    static {
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.RADIUS, new S57key(Conv.F, null));
+        keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        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));
+        keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
+    }
+
+    public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
+        EnumMap<?, ?> map = keys.get(att).map;
+        Enum<?> unkn = null;
+        int i = 0;
+        try {
+            i = Integer.parseInt(val);
+        } catch (Exception e) {
+            return unkn;
+        }
+        if (map != null) {
+            for (Object item : map.keySet()) {
+                if (unkn == null)
+                    unkn = (Enum<?>) item;
+                if (((S57enum) map.get(item)).atvl.equals(i))
+                    return (Enum<?>) item;
+            }
+        }
+        return unkn;
+    }
+
+    public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
+        Conv conv = keys.get(att).conv;
+        switch (conv) {
+        case A:
+        case S:
+            return new AttVal<>(conv, val);
+        case E:
+            ArrayList<Enum<?>> list = new ArrayList<>();
+            list.add(s57Enum(val, att));
+            return new AttVal<ArrayList<?>>(Conv.E, list);
+        case L:
+            list = new ArrayList<>();
+            for (String item : val.split(",")) {
+                list.add(s57Enum(item, att));
+            }
+            return new AttVal<ArrayList<?>>(Conv.L, list);
+        case I:
+            try {
+                return new AttVal<>(Conv.I, Long.parseLong(val));
+            } catch (Exception e) {
+                break;
+            }
+        case F:
+            try {
+                return new AttVal<>(Conv.F, Double.parseDouble(val));
+            } catch (Exception e) {
+                break;
+            }
+        }
+        return null;
+    }
+
+    public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
+        if (attval != null) {
+            String str = stringValue(attval, att);
+            if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
+                String[] vals = str.split(";");
+                str = "";
+                for (String val : vals) {
+                    if (!str.isEmpty()) str += ",";
+                    EnumMap<?, ?> map = keys.get(att).map;
+                    for (Object item : map.keySet()) {
+                        if (((S57enum) map.get(item)).val.equals(val))
+                            str += ((S57enum) map.get(item)).atvl.toString();
+                    }
+                }
+            }
+            return str;
+        }
+        return "";
+    }
+
+    public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
+        if (attval != null) {
+            switch (attval.conv) {
+            case A:
+            case S:
+                return (String) attval.val;
+            case E:
+                EnumMap<?, ?> map = keys.get(att).map;
+                return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
+            case L:
+                String str = "";
+                map = keys.get(att).map;
+                for (Object item : (ArrayList<?>) attval.val) {
+                    if (!str.isEmpty())
+                        str += ";";
+                    if (item != null)
+                        str += ((S57enum) map.get(item)).val;
+                }
+                return str;
+            case I:
+                return ((Long) attval.val).toString();
+            case F:
+                return ((Double) attval.val).toString();
+            }
+        }
+        return "";
+    }
+
+    public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
+        EnumMap<?, ?> map = keys.get(att).map;
+        Enum<?> unkn = null;
+        if (map != null) {
+            for (Object item : map.keySet()) {
+                if (unkn == null)
+                    unkn = (Enum<?>) item;
+                if (((S57enum) map.get(item)).val.equals(val))
+                    return (Enum<?>) item;
+            }
+        }
+        return unkn;
+    }
+
+    public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
+        switch (keys.get(att).conv) {
+        case A:
+        case S:
+            return new AttVal<>(Conv.S, val);
+        case E:
+            ArrayList<Enum<?>> list = new ArrayList<>();
+            list.add(osmEnum(val, att));
+            return new AttVal<ArrayList<?>>(Conv.E, list);
+        case L:
+            list = new ArrayList<>();
+            for (String item : val.split(";")) {
+                list.add(osmEnum(item, att));
+            }
+            return new AttVal<ArrayList<?>>(Conv.L, list);
+        case I:
+            try {
+                return new AttVal<>(Conv.I, Long.parseLong(val));
+            } catch (Exception e) {
+                break;
+            }
+        case F:
+            try {
+                return new AttVal<>(Conv.F, Double.parseDouble(val));
+            } catch (Exception e) {
+                break;
+            }
+        }
+        return new AttVal<>(keys.get(att).conv, null);
+    }
+
+    public static Enum<?> unknAtt(Att att) {
+        return (Enum<?>) (keys.get(att).map.keySet().toArray()[0]);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32394)
@@ -31,5 +31,8 @@
 import render.Renderer;
 import s57.S57map;
-import s57.S57map.*;
+import s57.S57map.Feature;
+import s57.S57map.GeomIterator;
+import s57.S57map.Pflag;
+import s57.S57map.Snode;
 import s57.S57obj.Obj;
 import symbols.Symbols;
@@ -37,104 +40,111 @@
 public class ChartImage extends ImageryLayer implements ZoomChangeListener, ChartContext {
 
-	double top;
-	double bottom;
-	double left;
-	double right;
-	double width;
-	double height;
-	int zoom;
-	
-	public ChartImage(ImageryInfo info) {
-		super(info);
-		MapView.addZoomChangeListener(this);
-		zoomChanged();
-	}
-	
-	@Override
-	public Action[] getMenuEntries() {
-		return null;
-	}
+    double top;
+    double bottom;
+    double left;
+    double right;
+    double width;
+    double height;
+    int zoom;
 
-	@Override
-	public String getToolTipText() {
-		return null;
-	}
+    public ChartImage(ImageryInfo info) {
+        super(info);
+        MapView.addZoomChangeListener(this);
+        zoomChanged();
+    }
 
-	@Override
-	public void visitBoundingBox(BoundingXYVisitor arg0) {
-	}
+    @Override
+    public Action[] getMenuEntries() {
+        return null;
+    }
 
-	@Override
-	public void paint(Graphics2D g2, MapView mv, Bounds bb) {
-		Rectangle rect = Main.map.mapView.getBounds();
-		Renderer.reRender(g2, rect, zoom, Math.pow(2, (zoom-12)), SeachartAction.map, this);
-		g2.setPaint(Color.black);
-		g2.setFont(new Font("Arial", Font.BOLD, 20));
-		Rectangle crect = g2.getClipBounds();
-		if ((crect.y + crect.height) < (rect.y + rect.height - 10)) {
-			g2.drawString(("Z" + zoom), (crect.x + crect.width - 40), (crect.y + crect.height - 10));
-		} else {
-			g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
-		}
-	}
+    @Override
+    public String getToolTipText() {
+        return null;
+    }
 
-	@Override
-	public void zoomChanged() {
-		if ((Main.map != null) && (Main.map.mapView != null)) {
-			Bounds bounds = Main.map.mapView.getRealBounds();
-			top = bounds.getMax().lat();
-			bottom = bounds.getMin().lat();
-			left = bounds.getMin().lon();
-			right = bounds.getMax().lon();
-			width = Main.map.mapView.getBounds().getWidth();
-			height = Main.map.mapView.getBounds().getHeight();
-			zoom = ((int) Math.min(18, Math.max(9, Math.round(Math.floor(Math.log(1024 / bounds.asRect().height) / Math.log(2))))));
-		}
-	}
+    @Override
+    public void visitBoundingBox(BoundingXYVisitor arg0) {
+    }
 
-	public Point2D.Double getPoint(Snode coord) {
-		return (Double) Main.map.mapView.getPoint2D(new LatLon(Math.toDegrees(coord.lat), Math.toDegrees(coord.lon)));
-	}
+    @Override
+    public void paint(Graphics2D g2, MapView mv, Bounds bb) {
+        Rectangle rect = Main.map.mapView.getBounds();
+        Renderer.reRender(g2, rect, zoom, Math.pow(2, (zoom-12)), SeachartAction.map, this);
+        g2.setPaint(Color.black);
+        g2.setFont(new Font("Arial", Font.BOLD, 20));
+        Rectangle crect = g2.getClipBounds();
+        if ((crect.y + crect.height) < (rect.y + rect.height - 10)) {
+            g2.drawString(("Z" + zoom), (crect.x + crect.width - 40), (crect.y + crect.height - 10));
+        } else {
+            g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
+        }
+    }
 
-	public double mile(Feature feature) {
-		return 185000 / Main.map.mapView.getDist100Pixel();
-	}
-	
-	public boolean clip() {
-		return true;
-	}
-	
-	public Color background(S57map map) {
-		if (map.features.containsKey(Obj.COALNE)) {
-			for (Feature feature : map.features.get(Obj.COALNE)) {
-				if (feature.geom.prim == Pflag.POINT) {
-					break;
-				}
-				GeomIterator git = map.new GeomIterator(feature.geom);
-				git.nextComp();
-				while (git.hasEdge()) {
-					git.nextEdge();
-					while (git.hasNode()) {
-						Snode node = git.next();
-						if (node == null)
-							continue;
-						if ((node.lat >= map.bounds.minlat) && (node.lat <= map.bounds.maxlat) && (node.lon >= map.bounds.minlon) && (node.lon <= map.bounds.maxlon)) {
-							return Symbols.Bwater;
-						}
-					}
-				}
-			}
-			return Symbols.Yland;
-		} else {
-			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)) {
-				return Symbols.Yland;
-			} else {
-				return Symbols.Bwater;
-			}
-		}
-	}
+    @Override
+    public void zoomChanged() {
+        if ((Main.map != null) && (Main.map.mapView != null)) {
+            Bounds bounds = Main.map.mapView.getRealBounds();
+            top = bounds.getMax().lat();
+            bottom = bounds.getMin().lat();
+            left = bounds.getMin().lon();
+            right = bounds.getMax().lon();
+            width = Main.map.mapView.getBounds().getWidth();
+            height = Main.map.mapView.getBounds().getHeight();
+            zoom = ((int) Math.min(18, Math.max(9, Math.round(Math.floor(Math.log(1024 / bounds.asRect().height) / Math.log(2))))));
+        }
+    }
 
-	public RuleSet ruleset() {
-		return RuleSet.ALL;
-	}
+    @Override
+    public Point2D.Double getPoint(Snode coord) {
+        return (Double) Main.map.mapView.getPoint2D(new LatLon(Math.toDegrees(coord.lat), Math.toDegrees(coord.lon)));
+    }
+
+    @Override
+    public double mile(Feature feature) {
+        return 185000 / Main.map.mapView.getDist100Pixel();
+    }
+
+    @Override
+    public boolean clip() {
+        return true;
+    }
+
+    @Override
+    public Color background(S57map map) {
+        if (map.features.containsKey(Obj.COALNE)) {
+            for (Feature feature : map.features.get(Obj.COALNE)) {
+                if (feature.geom.prim == Pflag.POINT) {
+                    break;
+                }
+                GeomIterator git = map.new GeomIterator(feature.geom);
+                git.nextComp();
+                while (git.hasEdge()) {
+                    git.nextEdge();
+                    while (git.hasNode()) {
+                        Snode node = git.next();
+                        if (node == null)
+                            continue;
+                        if ((node.lat >= map.bounds.minlat) && (node.lat <= map.bounds.maxlat)
+                                && (node.lon >= map.bounds.minlon) && (node.lon <= map.bounds.maxlon)) {
+                            return Symbols.Bwater;
+                        }
+                    }
+                }
+            }
+            return Symbols.Yland;
+        } else {
+            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)) {
+                return Symbols.Yland;
+            } else {
+                return Symbols.Bwater;
+            }
+        }
+    }
+
+    @Override
+    public RuleSet ruleset() {
+        return RuleSet.ALL;
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/seachart/Seachart.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/seachart/Seachart.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/seachart/Seachart.java	(revision 32394)
@@ -17,5 +17,5 @@
 public class Seachart extends Plugin {
 
-	public Seachart(PluginInformation info) {
+    public Seachart(PluginInformation info) {
         super(info);
         MainMenu.add(Main.main.menu.imageryMenu, new SeachartAction());
Index: applications/editors/josm/plugins/seachart/src/seachart/SeachartAction.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/seachart/SeachartAction.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/seachart/SeachartAction.java	(revision 32394)
@@ -46,67 +46,67 @@
 
 public class SeachartAction extends JosmAction implements ActiveLayerChangeListener, LayerChangeListener {
-	private static String title = "SeaChart";
-	private boolean isOpen = false;
-	public static ChartImage rendering;
-	public static S57map map = null;
-	public DataSet data = null;
-
-	private final DataSetListener dataSetListener = new DataSetListener() {
-
-		@Override
-		public void dataChanged(DataChangedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void nodeMoved(NodeMovedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void otherDatasetChange(AbstractDatasetChangedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void primitivesAdded(PrimitivesAddedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void primitivesRemoved(PrimitivesRemovedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void relationMembersChanged(RelationMembersChangedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void tagsChanged(TagsChangedEvent e) {
-			makeChart();
-		}
-
-		@Override
-		public void wayNodesChanged(WayNodesChangedEvent e) {
-			makeChart();
-		}
-	};
-
-	public SeachartAction() {
-		super(title, "SC", title, null, true);
-	}
-
-	@Override
-	public void layerAdded(LayerAddEvent e) {
-	}
-
-	@Override
-	public void layerRemoving(LayerRemoveEvent e) {
-		if ("SeaChart".equals(e.getRemovedLayer().getName())) {
-			closeChartLayer();
-		}
-	}
+    private static String title = "SeaChart";
+    private boolean isOpen = false;
+    public static ChartImage rendering;
+    public static S57map map = null;
+    public DataSet data = null;
+
+    private final DataSetListener dataSetListener = new DataSetListener() {
+
+        @Override
+        public void dataChanged(DataChangedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void nodeMoved(NodeMovedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void otherDatasetChange(AbstractDatasetChangedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void primitivesAdded(PrimitivesAddedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void primitivesRemoved(PrimitivesRemovedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void relationMembersChanged(RelationMembersChangedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void tagsChanged(TagsChangedEvent e) {
+            makeChart();
+        }
+
+        @Override
+        public void wayNodesChanged(WayNodesChangedEvent e) {
+            makeChart();
+        }
+    };
+
+    public SeachartAction() {
+        super(title, "SC", title, null, true);
+    }
+
+    @Override
+    public void layerAdded(LayerAddEvent e) {
+    }
+
+    @Override
+    public void layerRemoving(LayerRemoveEvent e) {
+        if ("SeaChart".equals(e.getRemovedLayer().getName())) {
+            closeChartLayer();
+        }
+    }
 
     @Override
@@ -115,116 +115,116 @@
 
     @Override
-	public void actionPerformed(ActionEvent arg0) {
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-				if (!isOpen)
-					createChartLayer();
-				isOpen = true;
-			}
-		});
-	}
-
-	protected void createChartLayer() {
-		rendering = new ChartImage(new ImageryInfo("SeaChart"));
-		rendering.setBackgroundLayer(true);
-		Main.getLayerManager().addLayer(rendering);
-		Main.getLayerManager().addAndFireActiveLayerChangeListener(this);
-		Main.getLayerManager().addLayerChangeListener(this);
-	}
-
-	public void closeChartLayer() {
-		if (isOpen) {
-		    Main.getLayerManager().removeActiveLayerChangeListener(this);
-			Main.getLayerManager().removeLayerChangeListener(this);
-			Main.getLayerManager().removeLayer(rendering);
-		}
-		isOpen = false;
-	}
-
-	@Override
-	public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
-	    OsmDataLayer oldLayer = e.getPreviousEditLayer();
-		if (oldLayer != null) {
-			oldLayer.data.removeDataSetListener(dataSetListener);
-		}
-	    OsmDataLayer newLayer = Main.getLayerManager().getEditLayer();
-		if (newLayer != null) {
-			newLayer.data.addDataSetListener(dataSetListener);
-			data = newLayer.data;
-			makeChart();
-		} else {
-			data = null;
-			map = null;
-		}
-	}
-
-	void makeChart() {
-		map = new S57map(false);
-		if (data != null) {
-			double minlat = 90;
-			double maxlat = -90;
-			double minlon = 180;
-			double maxlon = -180;
-			for (Bounds bounds : data.getDataSourceBounds()) {
-				if (bounds.getMinLat() < minlat) {
-					minlat = bounds.getMinLat();
-				}
-				if (bounds.getMaxLat() > maxlat) {
-					maxlat = bounds.getMaxLat();
-				}
-				if (bounds.getMinLon() < minlon) {
-					minlon = bounds.getMinLon();
-				}
-				if (bounds.getMaxLon() > maxlon) {
-					maxlon = bounds.getMaxLon();
-				}
-			}
-			map.addNode(1, maxlat, minlon);
-			map.addNode(2, minlat, minlon);
-			map.addNode(3, minlat, maxlon);
-			map.addNode(4, maxlat, maxlon);
-			map.bounds.minlat = Math.toRadians(minlat);
-			map.bounds.maxlat = Math.toRadians(maxlat);
-			map.bounds.minlon = Math.toRadians(minlon);
-			map.bounds.maxlon = Math.toRadians(maxlon);
-			for (Node node : data.getNodes()) {
-				LatLon coor = node.getCoor();
-				if (coor != null) {
-					map.addNode(node.getUniqueId(), coor.lat(), coor.lon());
-					for (Entry<String, String> entry : node.getKeys().entrySet()) {
-						map.addTag(entry.getKey(), entry.getValue());
-					}
-					map.tagsDone(node.getUniqueId());
-				}
-			}
-			for (Way way : data.getWays()) {
-				if (way.getNodesCount() > 0) {
-					map.addEdge(way.getUniqueId());
-					for (Node node : way.getNodes()) {
-						map.addToEdge((node.getUniqueId()));
-					}
-					for (Entry<String, String> entry : way.getKeys().entrySet()) {
-						map.addTag(entry.getKey(), entry.getValue());
-					}
-					map.tagsDone(way.getUniqueId());
-				}
-			}
-			for (Relation rel : data.getRelations()) {
-				if (rel.isMultipolygon() && (rel.getMembersCount() > 0)) {
-					map.addArea(rel.getUniqueId());
-					for (RelationMember mem : rel.getMembers()) {
-						if (mem.getType() == OsmPrimitiveType.WAY)
-							map.addToArea(mem.getUniqueId(), (mem.getRole().equals("outer")));
-					}
-					for (Entry<String, String> entry : rel.getKeys().entrySet()) {
-						map.addTag(entry.getKey(), entry.getValue());
-					}
-					map.tagsDone(rel.getUniqueId());
-				}
-			}
-			map.mapDone();
-			if (rendering != null) rendering.zoomChanged();
-		}
-	}
+    public void actionPerformed(ActionEvent arg0) {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                if (!isOpen)
+                    createChartLayer();
+                isOpen = true;
+            }
+        });
+    }
+
+    protected void createChartLayer() {
+        rendering = new ChartImage(new ImageryInfo("SeaChart"));
+        rendering.setBackgroundLayer(true);
+        Main.getLayerManager().addLayer(rendering);
+        Main.getLayerManager().addAndFireActiveLayerChangeListener(this);
+        Main.getLayerManager().addLayerChangeListener(this);
+    }
+
+    public void closeChartLayer() {
+        if (isOpen) {
+            Main.getLayerManager().removeActiveLayerChangeListener(this);
+            Main.getLayerManager().removeLayerChangeListener(this);
+            Main.getLayerManager().removeLayer(rendering);
+        }
+        isOpen = false;
+    }
+
+    @Override
+    public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
+        OsmDataLayer oldLayer = e.getPreviousEditLayer();
+        if (oldLayer != null) {
+            oldLayer.data.removeDataSetListener(dataSetListener);
+        }
+        OsmDataLayer newLayer = Main.getLayerManager().getEditLayer();
+        if (newLayer != null) {
+            newLayer.data.addDataSetListener(dataSetListener);
+            data = newLayer.data;
+            makeChart();
+        } else {
+            data = null;
+            map = null;
+        }
+    }
+
+    void makeChart() {
+        map = new S57map(false);
+        if (data != null) {
+            double minlat = 90;
+            double maxlat = -90;
+            double minlon = 180;
+            double maxlon = -180;
+            for (Bounds bounds : data.getDataSourceBounds()) {
+                if (bounds.getMinLat() < minlat) {
+                    minlat = bounds.getMinLat();
+                }
+                if (bounds.getMaxLat() > maxlat) {
+                    maxlat = bounds.getMaxLat();
+                }
+                if (bounds.getMinLon() < minlon) {
+                    minlon = bounds.getMinLon();
+                }
+                if (bounds.getMaxLon() > maxlon) {
+                    maxlon = bounds.getMaxLon();
+                }
+            }
+            map.addNode(1, maxlat, minlon);
+            map.addNode(2, minlat, minlon);
+            map.addNode(3, minlat, maxlon);
+            map.addNode(4, maxlat, maxlon);
+            map.bounds.minlat = Math.toRadians(minlat);
+            map.bounds.maxlat = Math.toRadians(maxlat);
+            map.bounds.minlon = Math.toRadians(minlon);
+            map.bounds.maxlon = Math.toRadians(maxlon);
+            for (Node node : data.getNodes()) {
+                LatLon coor = node.getCoor();
+                if (coor != null) {
+                    map.addNode(node.getUniqueId(), coor.lat(), coor.lon());
+                    for (Entry<String, String> entry : node.getKeys().entrySet()) {
+                        map.addTag(entry.getKey(), entry.getValue());
+                    }
+                    map.tagsDone(node.getUniqueId());
+                }
+            }
+            for (Way way : data.getWays()) {
+                if (way.getNodesCount() > 0) {
+                    map.addEdge(way.getUniqueId());
+                    for (Node node : way.getNodes()) {
+                        map.addToEdge((node.getUniqueId()));
+                    }
+                    for (Entry<String, String> entry : way.getKeys().entrySet()) {
+                        map.addTag(entry.getKey(), entry.getValue());
+                    }
+                    map.tagsDone(way.getUniqueId());
+                }
+            }
+            for (Relation rel : data.getRelations()) {
+                if (rel.isMultipolygon() && (rel.getMembersCount() > 0)) {
+                    map.addArea(rel.getUniqueId());
+                    for (RelationMember mem : rel.getMembers()) {
+                        if (mem.getType() == OsmPrimitiveType.WAY)
+                            map.addToArea(mem.getUniqueId(), (mem.getRole().equals("outer")));
+                    }
+                    for (Entry<String, String> entry : rel.getKeys().entrySet()) {
+                        map.addTag(entry.getKey(), entry.getValue());
+                    }
+                    map.tagsDone(rel.getUniqueId());
+                }
+            }
+            map.mapDone();
+            if (rendering != null) rendering.zoomChanged();
+        }
+    }
 
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Areas.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Areas.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Areas.java	(revision 32394)
@@ -10,219 +10,252 @@
 package symbols;
 
-import java.awt.*;
-import java.awt.geom.*;
-import java.awt.image.*;
-
-import symbols.Symbols.*;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+
+import symbols.Symbols.Delta;
+import symbols.Symbols.Form;
+import symbols.Symbols.Handle;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Areas {
-	public static final Symbol Plane = new Symbol();
-	static {
-		Plane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
-		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);
-		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();
-		Plane.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Cable = new Symbol();
-	static {
-		Cable.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
-		Cable.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Cable.add(new Instr(Form.FILL, new Color(0xc480ff)));
-		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);
-		Cable.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol CableDot = new Symbol();
-	static {
-		CableDot.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
-		CableDot.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-40,20,20)));
-	}
-	public static final Symbol CableDash = new Symbol();
-	static {
-		CableDash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
-		CableDash.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		CableDash.add(new Instr(Form.LINE, new Line2D.Double(0,-15,0,-45)));
-	}
-	public static final Symbol CableFlash = new Symbol();
-	static {
-		CableFlash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
-		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();
-		CableFlash.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol LaneArrow = new Symbol();
-	static {
-		LaneArrow.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-240,40,240)));
-		LaneArrow.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		LaneArrow.add(new Instr(Form.FILL, Symbols.Mtss));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(15,0); p.lineTo(15,-195); p.lineTo(40,-195);
-		p.lineTo(0,-240); p.lineTo(-40,-195); p.lineTo(-15,-195); p.lineTo(-15,0); p.closePath();
-		LaneArrow.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol LineAnchor = new Symbol();
-	static {
-		LineAnchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,90)));
-		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))))));
-	}
-	public static final Symbol LinePlane = new Symbol();
-	static {
-		LinePlane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,90)));
-		LinePlane.add(new Instr(Form.FILL, new Color(0xc480ff)));
-		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))))));
-	}
-	public static final Symbol MarineFarm = new Symbol();
-	static {
-		MarineFarm.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		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);
-		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);
-		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);
-		MarineFarm.add(new Instr(Form.PLIN, p));
-		MarineFarm.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,-2,4,4)));
-	}
-	public static final Symbol NoWake = new Symbol();
-	static {
-		NoWake.add(new Instr(Form.STRK, new BasicStroke(12, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoWake.add(new Instr(Form.FILL, new Color(0xa30075)));
-		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);
-		NoWake.add(new Instr(Form.PLIN, p));
-		NoWake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60,60,60,-60)));
-		NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60,-60,60,60)));
-	}
-	public static final Symbol Pipeline = new Symbol();
-	static {
-		Pipeline.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15,-60,30,60)));
-		Pipeline.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Pipeline.add(new Instr(Form.FILL, new Color(0xc480ff)));
-		Pipeline.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-50)));
-		Pipeline.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-60,20,20)));
-	}
-	public static final Symbol Restricted = new Symbol();
-	static {
-		Restricted.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15,-30,30,30)));
-		Restricted.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Restricted.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-30)));
-		Restricted.add(new Instr(Form.LINE, new Line2D.Double(0,-15,17,-15)));
-	}
-	public static final Symbol Rock = new Symbol();
-	static {
-		Rock.add(new Instr(Form.FILL, new Color(0x80c0ff)));
-		Rock.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
-		Rock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
-		Rock.add(new Instr(Form.FILL, Color.black));
-		Rock.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
-		Rock.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Rock.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
-		Rock.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,20)));
-	}
-	public static final Symbol RockA = new Symbol();
-	static {
-		RockA.add(new Instr(Form.FILL, new Color(0x80c0ff)));
-		RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
-		RockA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
-		RockA.add(new Instr(Form.FILL, Color.black));
-		RockA.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
-		RockA.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		RockA.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
-		RockA.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,20)));
-		RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17,-17,8,8)));
-		RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17,9,8,8)));
-		RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,-17,8,8)));
-		RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9,9,8,8)));
-	}
-	public static final Symbol RockC = new Symbol();
-	static {
-		RockC.add(new Instr(Form.FILL, new Color(0x80c0ff)));
-		RockC.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
-		RockC.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
-		RockC.add(new Instr(Form.FILL, Color.black));
-		RockC.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
-		RockC.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		RockC.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
-		RockC.add(new Instr(Form.LINE, new Line2D.Double(-10,17.3,10,-17.3)));
-		RockC.add(new Instr(Form.LINE, new Line2D.Double(10,17.3,-10,-17.3)));
-	}
-	public static final Symbol Seaplane = new Symbol();
-	static {
-		Seaplane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
-		Seaplane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Seaplane.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58,-58,116,116)));
-		Seaplane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol WindFarm = new Symbol();
-	static {
-		WindFarm.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		WindFarm.add(new Instr(Form.ELPS, new Ellipse2D.Double(-100,-100,200,200)));
-		WindFarm.add(new Instr(Form.LINE, new Line2D.Double(-35,50,35,50)));
-		WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,50,0,-27.5)));
-		WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,30,-27.5)));
-		WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,-13.8,-3.8)));
-		WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0,-27.5,-13.8,-53.6)));
-	}
-	public static final Symbol WreckD = new Symbol();
-	static {
-		WreckD.add(new Instr(Form.FILL, new Color(0x80c0ff)));
-		WreckD.add(new Instr(Form.RSHP, new Ellipse2D.Double(-50,-40,100,80)));
-		WreckD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5,5}, 0)));
-		WreckD.add(new Instr(Form.FILL, Color.black));
-		WreckD.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50,-40,100,80)));
-		WreckD.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		WreckD.add(new Instr(Form.LINE, new Line2D.Double(-40,0,40,0)));
-		WreckD.add(new Instr(Form.LINE, new Line2D.Double(0,-30,0,30)));
-		WreckD.add(new Instr(Form.LINE, new Line2D.Double(-20,-15,-20,15)));
-		WreckD.add(new Instr(Form.LINE, new Line2D.Double(20,-15,20,15)));
-	}
-	public static final Symbol WreckND = new Symbol();
-	static {
-		WreckND.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		WreckND.add(new Instr(Form.LINE, new Line2D.Double(-40,0,40,0)));
-		WreckND.add(new Instr(Form.LINE, new Line2D.Double(0,-30,0,30)));
-		WreckND.add(new Instr(Form.LINE, new Line2D.Double(-20,-15,-20,15)));
-		WreckND.add(new Instr(Form.LINE, new Line2D.Double(20,-15,20,15)));
-	}
-	public static final Symbol WreckS = new Symbol();
-	static {
-		WreckS.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		WreckS.add(new Instr(Form.ELPS, new Ellipse2D.Double(-6,-6,12,12)));
-		WreckS.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-6,0)));
-		WreckS.add(new Instr(Form.LINE, new Line2D.Double(40,0,6,0)));
-		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);
-		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();
-		WreckS.add(new Instr(Form.PGON, p));
-	}
-	public static final BufferedImage Sandwaves = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
-	static {
-		Graphics2D g2 = Sandwaves.createGraphics();
-		g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-		g2.setBackground(new Color(0, true));
-		g2.clearRect(0,  0, 100, 100);
-		g2.setPaint(new Color(0xffd400));
-		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);
-		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);
-		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);
-		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);
-		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);
-		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);
-		g2.draw(p);
-	}
-	public static final Symbol KelpS = new Symbol();
-	static {
-		KelpS.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		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);
-		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);
-		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);
-		KelpS.add(new Instr(Form.PLIN, p));
-	}
-	public static final BufferedImage KelpA = new BufferedImage(240, 240, BufferedImage.TYPE_INT_ARGB);
-	static {
-		Graphics2D g2 = KelpA.createGraphics();
-		g2.setStroke(new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
-		g2.setBackground(new Color(0, true));
-		g2.clearRect(0,  0, 240, 240);
-		g2.setPaint(Color.black);
-		Path2D.Double p = new Path2D.Double();
-			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);
-      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);
-      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);
-      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);
-		g2.draw(p);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    public static final Symbol Plane = new Symbol();
+    static {
+        Plane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
+        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);
+        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();
+        Plane.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Cable = new Symbol();
+    static {
+        Cable.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
+        Cable.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Cable.add(new Instr(Form.FILL, new Color(0xc480ff)));
+        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);
+        Cable.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol CableDot = new Symbol();
+    static {
+        CableDot.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
+        CableDot.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -40, 20, 20)));
+    }
+
+    public static final Symbol CableDash = new Symbol();
+    static {
+        CableDash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
+        CableDash.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        CableDash.add(new Instr(Form.LINE, new Line2D.Double(0, -15, 0, -45)));
+    }
+
+    public static final Symbol CableFlash = new Symbol();
+    static {
+        CableFlash.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
+        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();
+        CableFlash.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol LaneArrow = new Symbol();
+    static {
+        LaneArrow.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -240, 40, 240)));
+        LaneArrow.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        LaneArrow.add(new Instr(Form.FILL, Symbols.Mtss));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(15, 0); p.lineTo(15, -195); p.lineTo(40, -195);
+        p.lineTo(0, -240); p.lineTo(-40, -195); p.lineTo(-15, -195); p.lineTo(-15, 0); p.closePath();
+        LaneArrow.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol LineAnchor = new Symbol();
+    static {
+        LineAnchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 90)));
+        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))))));
+    }
+
+    public static final Symbol LinePlane = new Symbol();
+    static {
+        LinePlane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 90)));
+        LinePlane.add(new Instr(Form.FILL, new Color(0xc480ff)));
+        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))))));
+    }
+
+    public static final Symbol MarineFarm = new Symbol();
+    static {
+        MarineFarm.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        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);
+        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);
+        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);
+        MarineFarm.add(new Instr(Form.PLIN, p));
+        MarineFarm.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, -2, 4, 4)));
+    }
+
+    public static final Symbol NoWake = new Symbol();
+    static {
+        NoWake.add(new Instr(Form.STRK, new BasicStroke(12, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoWake.add(new Instr(Form.FILL, new Color(0xa30075)));
+        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);
+        NoWake.add(new Instr(Form.PLIN, p));
+        NoWake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60, 60, 60, -60)));
+        NoWake.add(new Instr(Form.LINE, new Line2D.Double(-60, -60, 60, 60)));
+    }
+
+    public static final Symbol Pipeline = new Symbol();
+    static {
+        Pipeline.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15, -60, 30, 60)));
+        Pipeline.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Pipeline.add(new Instr(Form.FILL, new Color(0xc480ff)));
+        Pipeline.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -50)));
+        Pipeline.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -60, 20, 20)));
+    }
+
+    public static final Symbol Restricted = new Symbol();
+    static {
+        Restricted.add(new Instr(Form.BBOX, new Rectangle2D.Double(-15, -30, 30, 30)));
+        Restricted.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Restricted.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -30)));
+        Restricted.add(new Instr(Form.LINE, new Line2D.Double(0, -15, 17, -15)));
+    }
+
+    public static final Symbol Rock = new Symbol();
+    static {
+        Rock.add(new Instr(Form.FILL, new Color(0x80c0ff)));
+        Rock.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
+        Rock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
+        Rock.add(new Instr(Form.FILL, Color.black));
+        Rock.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
+        Rock.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Rock.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
+        Rock.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 20)));
+    }
+
+    public static final Symbol RockA = new Symbol();
+    static {
+        RockA.add(new Instr(Form.FILL, new Color(0x80c0ff)));
+        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
+        RockA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
+        RockA.add(new Instr(Form.FILL, Color.black));
+        RockA.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
+        RockA.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        RockA.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
+        RockA.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 20)));
+        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17, -17, 8, 8)));
+        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(-17, 9, 8, 8)));
+        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, -17, 8, 8)));
+        RockA.add(new Instr(Form.RSHP, new Ellipse2D.Double(9, 9, 8, 8)));
+    }
+
+    public static final Symbol RockC = new Symbol();
+    static {
+        RockC.add(new Instr(Form.FILL, new Color(0x80c0ff)));
+        RockC.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
+        RockC.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
+        RockC.add(new Instr(Form.FILL, Color.black));
+        RockC.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
+        RockC.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        RockC.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
+        RockC.add(new Instr(Form.LINE, new Line2D.Double(-10, 17.3, 10, -17.3)));
+        RockC.add(new Instr(Form.LINE, new Line2D.Double(10, 17.3, -10, -17.3)));
+    }
+
+    public static final Symbol Seaplane = new Symbol();
+    static {
+        Seaplane.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
+        Seaplane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Seaplane.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58, -58, 116, 116)));
+        Seaplane.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Areas.Plane, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol WindFarm = new Symbol();
+    static {
+        WindFarm.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        WindFarm.add(new Instr(Form.ELPS, new Ellipse2D.Double(-100, -100, 200, 200)));
+        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(-35, 50, 35, 50)));
+        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, 50, 0, -27.5)));
+        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, 30, -27.5)));
+        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, -13.8, -3.8)));
+        WindFarm.add(new Instr(Form.LINE, new Line2D.Double(0, -27.5, -13.8, -53.6)));
+    }
+
+    public static final Symbol WreckD = new Symbol();
+    static {
+        WreckD.add(new Instr(Form.FILL, new Color(0x80c0ff)));
+        WreckD.add(new Instr(Form.RSHP, new Ellipse2D.Double(-50, -40, 100, 80)));
+        WreckD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[]{5, 5}, 0)));
+        WreckD.add(new Instr(Form.FILL, Color.black));
+        WreckD.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50, -40, 100, 80)));
+        WreckD.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        WreckD.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, 40, 0)));
+        WreckD.add(new Instr(Form.LINE, new Line2D.Double(0, -30, 0, 30)));
+        WreckD.add(new Instr(Form.LINE, new Line2D.Double(-20, -15, -20, 15)));
+        WreckD.add(new Instr(Form.LINE, new Line2D.Double(20, -15, 20, 15)));
+    }
+
+    public static final Symbol WreckND = new Symbol();
+    static {
+        WreckND.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        WreckND.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, 40, 0)));
+        WreckND.add(new Instr(Form.LINE, new Line2D.Double(0, -30, 0, 30)));
+        WreckND.add(new Instr(Form.LINE, new Line2D.Double(-20, -15, -20, 15)));
+        WreckND.add(new Instr(Form.LINE, new Line2D.Double(20, -15, 20, 15)));
+    }
+
+    public static final Symbol WreckS = new Symbol();
+    static {
+        WreckS.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        WreckS.add(new Instr(Form.ELPS, new Ellipse2D.Double(-6, -6, 12, 12)));
+        WreckS.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -6, 0)));
+        WreckS.add(new Instr(Form.LINE, new Line2D.Double(40, 0, 6, 0)));
+        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);
+        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();
+        WreckS.add(new Instr(Form.PGON, p));
+    }
+
+    public static final BufferedImage Sandwaves = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+    static {
+        Graphics2D g2 = Sandwaves.createGraphics();
+        g2.setStroke(new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+        g2.setBackground(new Color(0, true));
+        g2.clearRect(0, 0, 100, 100);
+        g2.setPaint(new Color(0xffd400));
+        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);
+        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);
+        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);
+        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);
+        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);
+        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);
+        g2.draw(p);
+    }
+
+    public static final Symbol KelpS = new Symbol();
+    static {
+        KelpS.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        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);
+        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);
+        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);
+        KelpS.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final BufferedImage KelpA = new BufferedImage(240, 240, BufferedImage.TYPE_INT_ARGB);
+    static {
+        Graphics2D g2 = KelpA.createGraphics();
+        g2.setStroke(new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+        g2.setBackground(new Color(0, true));
+        g2.clearRect(0, 0, 240, 240);
+        g2.setPaint(Color.black);
+        Path2D.Double p = new Path2D.Double();
+        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);
+        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);
+        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);
+        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);
+        g2.draw(p);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Beacons.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Beacons.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Beacons.java	(revision 32394)
@@ -12,180 +12,199 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.geom.*;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
 import java.util.EnumMap;
 
-import symbols.Symbols.*;
-import s57.S57val.*;
+import s57.S57val.BcnSHP;
+import symbols.Symbols.Form;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Beacons {
-	
-	public static final Symbol Beacon = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-    Beacon.add(new Instr(Form.COLR, colours));
-    Beacon.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    Beacon.add(new Instr(Form.FILL, Color.black));
-    Beacon.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    Beacon.add(new Instr(Form.LINE, new Line2D.Double(-20,0,-10,0)));
-    Beacon.add(new Instr(Form.LINE, new Line2D.Double(10,0,20,0)));
-		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);
-		Beacon.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Cairn = new Symbol();
-	static {
-		Cairn.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Cairn.add(new Instr(Form.FILL, Color.black));
-		Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Cairn.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
-		Cairn.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
-		Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(3,-40,40,40)));
-		Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-43,-40,40,40)));
-		Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-18,-70,36,36)));
-	}
-	public static final Symbol FogSignal = new Symbol();
-	static {
-		FogSignal.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		FogSignal.add(new Instr(Form.FILL, Color.black));
-		FogSignal.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		FogSignal.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		FogSignal.add(new Instr(Form.FILL, new Color(0xd400d4)));
-		FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-120.0,-120.0,240.0,240.0,190.0,50.0,Arc2D.OPEN)));
-		FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-92.5,-92.5,185.0,185.0,190.0,50.0,Arc2D.OPEN)));
-		FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-65.0,-65.0,130.0,130.0,190.0,50.0,Arc2D.OPEN)));
-	}
-	public static final Symbol LightFlare = new Symbol();
-	static {
-		LightFlare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-100,40,100)));
-		LightFlare.add(new Instr(Form.RSHP, new Ellipse2D.Double(-3,-3,6,6)));
-		Path2D.Double p = new Path2D.Double();
-		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);
-		p.closePath();
-		LightFlare.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol LightMajor = new Symbol();
-	static {
-		LightMajor.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_NON_ZERO);
-		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();
-		p.moveTo(0.0,-35.5); p.lineTo(8.0,-11.2); p.lineTo(33.5,-11.2); p.lineTo(12.8,4.0);
-		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();
-		LightMajor.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol LightMinor = new Symbol();
-	static {
-		LightMinor.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		LightMinor.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol PerchPort = new Symbol();
-	static {
-		PerchPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		PerchPort.add(new Instr(Form.FILL, Color.black));
-		PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
-		PerchPort.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-40)));
-		PerchPort.add(new Instr(Form.LINE, new Line2D.Double(25,-70,0,-40)));
-		PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-25,-70,0,-40)));
-	}
-	public static final Symbol PerchStarboard = new Symbol();
-	static {
-		PerchStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		PerchStarboard.add(new Instr(Form.FILL, Color.black));
-		PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
-		PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
-		PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(25,-40,0,-68.7)));
-		PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-25,-40,0,-68.7)));
-	}
-	public static final Symbol RadarStation = new Symbol();
-	static {
-		RadarStation.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		RadarStation.add(new Instr(Form.FILL, new Color(0xd400d4)));
-		RadarStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-125,-125,250,250)));
-	}
-	public static final Symbol Stake = new Symbol();
-	static {
-		Stake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Stake.add(new Instr(Form.FILL, Color.black));
-		Stake.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-		colours.add(new Instr(Form.H2, p));
-		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();
-		colours.add(new Instr(Form.H3, p));
-		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();
-		colours.add(new Instr(Form.H4, p));
-		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();
-		colours.add(new Instr(Form.H5, p));
-		Stake.add(new Instr(Form.COLR, colours));
-		Stake.add(new Instr(Form.FILL, Color.black));
-		Stake.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
-	}
-	public static final Symbol Tower = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-    Tower.add(new Instr(Form.COLR, colours));
-    Tower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    Tower.add(new Instr(Form.FILL, Color.black));
-    Tower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    Tower.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
-    Tower.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
-		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);
-		Tower.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol WithyPort = new Symbol();
-	static {
-		WithyPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		WithyPort.add(new Instr(Form.FILL, Color.black));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(20,-60,0,-50)));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-20,-60,0,-50)));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(30,-35,0,-21)));
-		WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-30,-35,0,-21)));
-	}
-	public static final Symbol WithyStarboard = new Symbol();
-	static {
-		WithyStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		WithyStarboard.add(new Instr(Form.FILL, Color.black));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10,0,10,0)));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-70)));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(20,-50,0,-60)));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-20,-50,0,-60)));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(30,-21,0,-35)));
-		WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-30,-21,0,-35)));
-	}
-	
-	public static final EnumMap<BcnSHP, Symbol> Shapes = new EnumMap<>(BcnSHP.class);
-	static {
-		Shapes.put(BcnSHP.BCN_UNKN, Beacons.Beacon); Shapes.put(BcnSHP.BCN_STAK, Beacons.Stake); Shapes.put(BcnSHP.BCN_TOWR, Beacons.Tower);
-		Shapes.put(BcnSHP.BCN_LATT, Beacons.Beacon); Shapes.put(BcnSHP.BCN_PILE, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POLE, Beacons.Stake);
-		Shapes.put(BcnSHP.BCN_CARN, Beacons.Cairn); Shapes.put(BcnSHP.BCN_BUOY, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POST, Beacons.Stake);
-		Shapes.put(BcnSHP.BCN_PRCH, Beacons.Stake);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    public static final Symbol Beacon = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Beacon.add(new Instr(Form.COLR, colours));
+        Beacon.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Beacon.add(new Instr(Form.FILL, Color.black));
+        Beacon.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Beacon.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, -10, 0)));
+        Beacon.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 20, 0)));
+        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);
+        Beacon.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Cairn = new Symbol();
+    static {
+        Cairn.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Cairn.add(new Instr(Form.FILL, Color.black));
+        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Cairn.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
+        Cairn.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
+        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(3, -40, 40, 40)));
+        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-43, -40, 40, 40)));
+        Cairn.add(new Instr(Form.ELPS, new Ellipse2D.Double(-18, -70, 36, 36)));
+    }
+
+    public static final Symbol FogSignal = new Symbol();
+    static {
+        FogSignal.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        FogSignal.add(new Instr(Form.FILL, Color.black));
+        FogSignal.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        FogSignal.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        FogSignal.add(new Instr(Form.FILL, new Color(0xd400d4)));
+        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-120.0, -120.0, 240.0, 240.0, 190.0, 50.0, Arc2D.OPEN)));
+        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-92.5, -92.5, 185.0, 185.0, 190.0, 50.0, Arc2D.OPEN)));
+        FogSignal.add(new Instr(Form.EARC, new Arc2D.Double(-65.0, -65.0, 130.0, 130.0, 190.0, 50.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol LightFlare = new Symbol();
+    static {
+        LightFlare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -100, 40, 100)));
+        LightFlare.add(new Instr(Form.RSHP, new Ellipse2D.Double(-3, -3, 6, 6)));
+        Path2D.Double p = new Path2D.Double();
+        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);
+        p.closePath();
+        LightFlare.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol LightMajor = new Symbol();
+    static {
+        LightMajor.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_NON_ZERO);
+        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();
+        p.moveTo(0.0, -35.5); p.lineTo(8.0, -11.2); p.lineTo(33.5, -11.2); p.lineTo(12.8, 4.0);
+        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();
+        LightMajor.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol LightMinor = new Symbol();
+    static {
+        LightMinor.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        LightMinor.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol PerchPort = new Symbol();
+    static {
+        PerchPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        PerchPort.add(new Instr(Form.FILL, Color.black));
+        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
+        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -40)));
+        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(25, -70, 0, -40)));
+        PerchPort.add(new Instr(Form.LINE, new Line2D.Double(-25, -70, 0, -40)));
+    }
+
+    public static final Symbol PerchStarboard = new Symbol();
+    static {
+        PerchStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        PerchStarboard.add(new Instr(Form.FILL, Color.black));
+        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
+        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
+        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(25, -40, 0, -68.7)));
+        PerchStarboard.add(new Instr(Form.LINE, new Line2D.Double(-25, -40, 0, -68.7)));
+    }
+
+    public static final Symbol RadarStation = new Symbol();
+    static {
+        RadarStation.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        RadarStation.add(new Instr(Form.FILL, new Color(0xd400d4)));
+        RadarStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-125, -125, 250, 250)));
+    }
+
+    public static final Symbol Stake = new Symbol();
+    static {
+        Stake.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Stake.add(new Instr(Form.FILL, Color.black));
+        Stake.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        Stake.add(new Instr(Form.COLR, colours));
+        Stake.add(new Instr(Form.FILL, Color.black));
+        Stake.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
+    }
+
+    public static final Symbol Tower = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Tower.add(new Instr(Form.COLR, colours));
+        Tower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Tower.add(new Instr(Form.FILL, Color.black));
+        Tower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Tower.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
+        Tower.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
+        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);
+        Tower.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol WithyPort = new Symbol();
+    static {
+        WithyPort.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        WithyPort.add(new Instr(Form.FILL, Color.black));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(20, -60, 0, -50)));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-20, -60, 0, -50)));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(30, -35, 0, -21)));
+        WithyPort.add(new Instr(Form.LINE, new Line2D.Double(-30, -35, 0, -21)));
+    }
+
+    public static final Symbol WithyStarboard = new Symbol();
+    static {
+        WithyStarboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        WithyStarboard.add(new Instr(Form.FILL, Color.black));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, 10, 0)));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -70)));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(20, -50, 0, -60)));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-20, -50, 0, -60)));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(30, -21, 0, -35)));
+        WithyStarboard.add(new Instr(Form.LINE, new Line2D.Double(-30, -21, 0, -35)));
+    }
+
+    public static final EnumMap<BcnSHP, Symbol> Shapes = new EnumMap<>(BcnSHP.class);
+    static {
+        Shapes.put(BcnSHP.BCN_UNKN, Beacons.Beacon); Shapes.put(BcnSHP.BCN_STAK, Beacons.Stake); Shapes.put(BcnSHP.BCN_TOWR, Beacons.Tower);
+        Shapes.put(BcnSHP.BCN_LATT, Beacons.Beacon); Shapes.put(BcnSHP.BCN_PILE, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POLE, Beacons.Stake);
+        Shapes.put(BcnSHP.BCN_CARN, Beacons.Cairn); Shapes.put(BcnSHP.BCN_BUOY, Beacons.Beacon); Shapes.put(BcnSHP.BCN_POST, Beacons.Stake);
+        Shapes.put(BcnSHP.BCN_PRCH, Beacons.Stake);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Buoys.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Buoys.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Buoys.java	(revision 32394)
@@ -12,246 +12,260 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.geom.*;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
 import java.util.EnumMap;
 
 import s57.S57val.BoySHP;
-import symbols.Symbols.*;
+import symbols.Symbols.Form;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Buoys {
-
-	public static final Symbol Barrel = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		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);
-		p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		Barrel.add(new Instr(Form.COLR, colours));
-    Barrel.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Barrel.add(new Instr(Form.FILL, Color.black));
-		Barrel.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Barrel.add(new Instr(Form.LINE, new Line2D.Double(-57,0,-10,0)));
-		Barrel.add(new Instr(Form.LINE, new Line2D.Double(10,0,50,0)));
-		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);
-		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);
-    Barrel.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Can = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-		Can.add(new Instr(Form.COLR, colours));
-    Can.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Can.add(new Instr(Form.FILL, Color.black));
-		Can.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Can.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
-		Can.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
-		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);
-    Can.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Cone = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-		Cone.add(new Instr(Form.COLR, colours));
-    Cone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Cone.add(new Instr(Form.FILL, Color.black));
-		Cone.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Cone.add(new Instr(Form.LINE, new Line2D.Double(-40,0,-10,0)));
-		Cone.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
-		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);
-    Cone.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Float = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		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);
-		p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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);
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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);
-		p.lineTo(19.0,-23.0); p.quadTo(28.4,-24.3,47.0,-33.0); p.lineTo(43.0,-21.0);	p.closePath();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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);
-		p.lineTo(8.0,0.0); p.quadTo(7.7,-7.7,0.0,-8.0); p.closePath();
-    colours.add(new Instr(Form.V2, p));
-		Float.add(new Instr(Form.COLR, colours));
-    Float.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Float.add(new Instr(Form.FILL, Color.black));
-		Float.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Float.add(new Instr(Form.LINE, new Line2D.Double(-54,0,-10,0)));
-		Float.add(new Instr(Form.LINE, new Line2D.Double(10,0,54,0)));
-		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);
-		p.moveTo(-19.0, -23.0); p.lineTo(-12.0,-42.0); p.lineTo(12.0,-42.0); p.lineTo(19.0,-23.0);
-    Float.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Ice = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-    Ice.add(new Instr(Form.COLR, colours));
-    Ice.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    Ice.add(new Instr(Form.FILL, Color.black));
-    Ice.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    Ice.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
-    Ice.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
-		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);
-		Ice.add(new Instr(Form.PLIN, p));
-		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);
-		Ice.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Pillar = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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);
-		p.lineTo(25.0,0.0); p.lineTo(8.0,0.0); p.quadTo(8.0,-6.0,2.5,-7.6); p.closePath();
-    colours.add(new Instr(Form.V2, p));
-		Pillar.add(new Instr(Form.COLR, colours));
-		Pillar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Pillar.add(new Instr(Form.FILL, Color.black));
-		Pillar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Pillar.add(new Instr(Form.LINE, new Line2D.Double(-42,0,-10,0)));
-		Pillar.add(new Instr(Form.LINE, new Line2D.Double(10,0,36,0)));
-		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);
-		Pillar.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Spar = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-		Spar.add(new Instr(Form.COLR, colours));
-		Spar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Spar.add(new Instr(Form.FILL, Color.black));
-		Spar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Spar.add(new Instr(Form.LINE, new Line2D.Double(-20,0,-10,0)));
-		Spar.add(new Instr(Form.LINE, new Line2D.Double(10,0,20,0)));
-		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);
-		Spar.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Sphere = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-    Sphere.add(new Instr(Form.COLR, colours));
-    Sphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    Sphere.add(new Instr(Form.FILL, Color.black));
-    Sphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    Sphere.add(new Instr(Form.LINE, new Line2D.Double(-33,0,-10,0)));
-    Sphere.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
-    Sphere.add(new Instr(Form.EARC, new Arc2D.Double(-26.5,-39.4,60.0,60.0,-18.0,216.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Storage = new Symbol();
-	static {
-		Storage.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Storage.add(new Instr(Form.FILL, Color.black));
-		Storage.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    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);
-    p.lineTo(50.0,0.0); p.lineTo(40.0,20.0); p.lineTo(-40.0,20.0); p.closePath();
-    Storage.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Super = new Symbol();
-	static {
-		Symbol colours = new Symbol();
-		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);
-		p.lineTo(8.0, 0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-    colours.add(new Instr(Form.H2, p));
-		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();
-    colours.add(new Instr(Form.H3, p));
-		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();
-    colours.add(new Instr(Form.H4, p));
-		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();
-    colours.add(new Instr(Form.H5, p));
-		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();
-    colours.add(new Instr(Form.V2, p));
-		Super.add(new Instr(Form.COLR, colours));
-    Super.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Super.add(new Instr(Form.FILL, Color.black));
-		Super.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Super.add(new Instr(Form.LINE, new Line2D.Double(-54,0,-10,0)));
-		Super.add(new Instr(Form.LINE, new Line2D.Double(10,0,54,0)));
-		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);
-    Super.add(new Instr(Form.PLIN, p));
-	}
-	
-	public static final EnumMap<BoySHP, Symbol> Shapes = new EnumMap<>(BoySHP.class);
-	static {
-		Shapes.put(BoySHP.BOY_UNKN, Buoys.Pillar); Shapes.put(BoySHP.BOY_CONE, Buoys.Cone); Shapes.put(BoySHP.BOY_CAN, Buoys.Can);
-		Shapes.put(BoySHP.BOY_SPHR, Buoys.Sphere); Shapes.put(BoySHP.BOY_PILR, Buoys.Pillar); Shapes.put(BoySHP.BOY_SPAR, Buoys.Spar);
-		Shapes.put(BoySHP.BOY_BARL, Buoys.Barrel); Shapes.put(BoySHP.BOY_SUPR, Buoys.Super); Shapes.put(BoySHP.BOY_ICE, Buoys.Ice);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    public static final Symbol Barrel = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        Barrel.add(new Instr(Form.COLR, colours));
+        Barrel.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Barrel.add(new Instr(Form.FILL, Color.black));
+        Barrel.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Barrel.add(new Instr(Form.LINE, new Line2D.Double(-57, 0, -10, 0)));
+        Barrel.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 50, 0)));
+        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);
+        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);
+        Barrel.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Can = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Can.add(new Instr(Form.COLR, colours));
+        Can.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Can.add(new Instr(Form.FILL, Color.black));
+        Can.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Can.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
+        Can.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
+        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);
+        Can.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Cone = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Cone.add(new Instr(Form.COLR, colours));
+        Cone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Cone.add(new Instr(Form.FILL, Color.black));
+        Cone.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Cone.add(new Instr(Form.LINE, new Line2D.Double(-40, 0, -10, 0)));
+        Cone.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
+        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);
+        Cone.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Float = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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);
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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);
+        p.lineTo(19.0, -23.0); p.quadTo(28.4, -24.3, 47.0, -33.0); p.lineTo(43.0, -21.0); p.closePath();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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);
+        p.lineTo(8.0, 0.0); p.quadTo(7.7, -7.7, 0.0, -8.0); p.closePath();
+        colours.add(new Instr(Form.V2, p));
+        Float.add(new Instr(Form.COLR, colours));
+        Float.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Float.add(new Instr(Form.FILL, Color.black));
+        Float.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Float.add(new Instr(Form.LINE, new Line2D.Double(-54, 0, -10, 0)));
+        Float.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 54, 0)));
+        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);
+        p.moveTo(-19.0, -23.0); p.lineTo(-12.0, -42.0); p.lineTo(12.0, -42.0); p.lineTo(19.0, -23.0);
+        Float.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Ice = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        Ice.add(new Instr(Form.COLR, colours));
+        Ice.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Ice.add(new Instr(Form.FILL, Color.black));
+        Ice.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Ice.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
+        Ice.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
+        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);
+        Ice.add(new Instr(Form.PLIN, p));
+        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);
+        Ice.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Pillar = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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);
+        p.lineTo(25.0, 0.0); p.lineTo(8.0, 0.0); p.quadTo(8.0, -6.0, 2.5, -7.6); p.closePath();
+        colours.add(new Instr(Form.V2, p));
+        Pillar.add(new Instr(Form.COLR, colours));
+        Pillar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Pillar.add(new Instr(Form.FILL, Color.black));
+        Pillar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Pillar.add(new Instr(Form.LINE, new Line2D.Double(-42, 0, -10, 0)));
+        Pillar.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 36, 0)));
+        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);
+        Pillar.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Spar = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Spar.add(new Instr(Form.COLR, colours));
+        Spar.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Spar.add(new Instr(Form.FILL, Color.black));
+        Spar.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Spar.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, -10, 0)));
+        Spar.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 20, 0)));
+        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);
+        Spar.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Sphere = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Sphere.add(new Instr(Form.COLR, colours));
+        Sphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Sphere.add(new Instr(Form.FILL, Color.black));
+        Sphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Sphere.add(new Instr(Form.LINE, new Line2D.Double(-33, 0, -10, 0)));
+        Sphere.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
+        Sphere.add(new Instr(Form.EARC, new Arc2D.Double(-26.5, -39.4, 60.0, 60.0, -18.0, 216.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Storage = new Symbol();
+    static {
+        Storage.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Storage.add(new Instr(Form.FILL, Color.black));
+        Storage.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        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);
+        p.lineTo(50.0, 0.0); p.lineTo(40.0, 20.0); p.lineTo(-40.0, 20.0); p.closePath();
+        Storage.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Super = new Symbol();
+    static {
+        Symbol colours = new Symbol();
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.H4, p));
+        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();
+        colours.add(new Instr(Form.H5, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        Super.add(new Instr(Form.COLR, colours));
+        Super.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Super.add(new Instr(Form.FILL, Color.black));
+        Super.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Super.add(new Instr(Form.LINE, new Line2D.Double(-54, 0, -10, 0)));
+        Super.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 54, 0)));
+        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);
+        Super.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final EnumMap<BoySHP, Symbol> Shapes = new EnumMap<>(BoySHP.class);
+    static {
+        Shapes.put(BoySHP.BOY_UNKN, Buoys.Pillar); Shapes.put(BoySHP.BOY_CONE, Buoys.Cone); Shapes.put(BoySHP.BOY_CAN, Buoys.Can);
+        Shapes.put(BoySHP.BOY_SPHR, Buoys.Sphere); Shapes.put(BoySHP.BOY_PILR, Buoys.Pillar); Shapes.put(BoySHP.BOY_SPAR, Buoys.Spar);
+        Shapes.put(BoySHP.BOY_BARL, Buoys.Barrel); Shapes.put(BoySHP.BOY_SUPR, Buoys.Super); Shapes.put(BoySHP.BOY_ICE, Buoys.Ice);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Facilities.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Facilities.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Facilities.java	(revision 32394)
@@ -12,188 +12,209 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.geom.*;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
 import java.util.EnumMap;
 
-import s57.S57val.*;
-import symbols.Symbols.*;
+import s57.S57val.CatSCF;
+import symbols.Symbols.Form;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Facilities {
-	private static final Symbol Facility = new Symbol();
-	static {
-		Facility.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Facility.add(new Instr(Form.FILL, new Color(0x80ffffff, true)));
-		RoundRectangle2D.Double s = new RoundRectangle2D.Double(-29,-29,58,58,15,15);
-		Facility.add(new Instr(Form.RSHP, s));
-		Facility.add(new Instr(Form.FILL, new Color(0xa30075)));
-		Facility.add(new Instr(Form.RRCT, s));
-	}
-	public static final Symbol Boatlift = new Symbol();//was Crane
-	static {
-		Boatlift.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Boatlift.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Boatlift.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Boatlift.add(new Instr(Form.ELPS, new Ellipse2D.Double(-3.7,-19.7,12,12)));
-		Boatlift.add(new Instr(Form.LINE, new Line2D.Double(2.3,-7.7,2.3,-2.0)));
-		Boatlift.add(new Instr(Form.EARC, new Arc2D.Double(-10.0,-1.5,20,20,75.0,-260.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Boatyard = new Symbol();
-	static {
-		Boatyard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Boatyard.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Boatyard.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Boatyard.add(new Instr(Form.LINE, new Line2D.Double(19,19,-8,-8)));
-		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);
-		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();
-		Boatyard.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Chandler = new Symbol();
-	static {
-		Chandler.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Chandler.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Chandler.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Chandler.add(new Instr(Form.ELPS, new Ellipse2D.Double(14,7,10,10)));
-		Chandler.add(new Instr(Form.LINE, new Line2D.Double(-23.0,12.0,14.0,12.0)));
-		Chandler.add(new Instr(Form.LINE, new Line2D.Double(8.0,21.0,8.0,-8.6)));
-		Chandler.add(new Instr(Form.LINE, new Line2D.Double(-16.0,21.0,-16.0,-8.6)));
-		Chandler.add(new Instr(Form.EARC, new Arc2D.Double(-16.0,-20.5,24,24,0.0,180.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Fuel = new Symbol();
-	static {
-		Fuel.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Fuel.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Fuel.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Fuel.add(new Instr(Form.FILL, new Color(0xa30075)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		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(); 
-		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);
-		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();
-		Fuel.add(new Instr(Form.PGON, p));
-		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);
-		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);
-		Fuel.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Laundrette = new Symbol();
-	static {
-		Laundrette.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Laundrette.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Laundrette.add(new Instr(Form.STRK, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Laundrette.add(new Instr(Form.FILL, new Color(0xa30075)));
-		Laundrette.add(new Instr(Form.RECT, new Rectangle2D.Double(-15,-15,30,30)));
-		Laundrette.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-15); p.lineTo(-15,-20); p.lineTo(15,-20); p.lineTo(15,-15);
-		p.moveTo(-10,15); p.lineTo(-10,20); p.lineTo(10,20); p.lineTo(10,15);
-		Laundrette.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol PumpOut = new Symbol();
-	static {
-		PumpOut.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		PumpOut.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		PumpOut.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		PumpOut.add(new Instr(Form.FILL, new Color(0xa30075)));
-		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);
-		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);
-		PumpOut.add(new Instr(Form.PLIN, p));
-		PumpOut.add(new Instr(Form.STRK, new BasicStroke(3.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		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);
-		PumpOut.add(new Instr(Form.PLIN, p));
-		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();
-		PumpOut.add(new Instr(Form.PGON, p));
-		p = new Path2D.Double(); p.moveTo(14.1,-10.6); p.lineTo(23.1,-6.7); p.lineTo(14.1,-2.8); p.closePath();
-		PumpOut.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol SailingClub = new Symbol();
-	static {
-		SailingClub.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		SailingClub.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		SailingClub.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		SailingClub.add(new Instr(Form.FILL, new Color(0xa30075)));
-		SailingClub.add(new Instr(Form.LINE, new Line2D.Double(-5,20,-5,-20)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-5,0); p.lineTo(20,-10); p.lineTo(-5,-20); p.closePath();
-		SailingClub.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Shower = new Symbol();
-	static {
-		Shower.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Shower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Shower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Shower.add(new Instr(Form.FILL, new Color(0xa30075)));
-		Shower.add(new Instr(Form.LINE, new Line2D.Double(-4.8,-24.5,6.2,-13.5)));
-		Shower.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Shower.add(new Instr(Form.LINE, new Line2D.Double(-18.1,-17.9,-6.1,-21.3)));
-		Shower.add(new Instr(Form.LINE, new Line2D.Double(-13.9,-10.2,-3.9,-17.7)));
-		Shower.add(new Instr(Form.LINE, new Line2D.Double(-7.8,-4.4,-0.5,-14.3)));
-		Shower.add(new Instr(Form.LINE, new Line2D.Double(-0.2,-0.2,3.1,-12.1)));
-		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);
-		Shower.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Slipway = new Symbol();
-	static {
-		Slipway.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Slipway.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Slipway.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Slipway.add(new Instr(Form.FILL, new Color(0xa30075)));
-		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);
-		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);
-		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();
-		Slipway.add(new Instr(Form.PGON, p));
-		Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.65,-1.9,8,8)));
-		Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Slipway.add(new Instr(Form.LINE, new Line2D.Double(-24.5,-8.3,-3.1,-2.4)));
-		Slipway.add(new Instr(Form.LINE, new Line2D.Double(9.3,1.1,22.2,4.6)));
-		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);
-		p.lineTo(-17.1,-18.9); p.quadTo(-16.8,-11.4,-7.7,-7.7); p.closePath();
-		Slipway.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Toilet = new Symbol();
-	static {
-		Toilet.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Toilet.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
-		Toilet.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		Toilet.add(new Instr(Form.FILL, new Color(0xa30075)));
-		Toilet.add(new Instr(Form.LINE, new Line2D.Double(0,20,0,-20)));
-		Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(-18.5,-22.5,7.4,7.4)));
-		Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(11,-22.5,7.4,7.4)));
-		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);
-		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);
-		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();
-		Toilet.add(new Instr(Form.PGON, p));
-		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);
-		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);
-		p.lineTo(6.8,-10.1); p.lineTo(9.4,-12.2); p.closePath();
-		Toilet.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol VisitorBerth = new Symbol();
-	static {
-		VisitorBerth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		VisitorBerth.add(new Instr(Form.FILL, new Color(0xa30075)));
-		VisitorBerth.add(new Instr(Form.RSHP, new Ellipse2D.Double(-25,-25,50,50)));
-		VisitorBerth.add(new Instr(Form.FILL, Color.white));
-		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);
-		p.lineTo(-14.0,-13.6); p.lineTo(-7.9,-13.6); p.lineTo(0.0,8.7); p.closePath();
-		VisitorBerth.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol VisitorMooring = new Symbol();
-	static {
-		VisitorMooring.add(new Instr(Form.FILL, new Color(0xa30075)));
-		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);
-		p.lineTo(8.0,0.0); p.curveTo(8.0,-11.0,-8.0,-11.0,-8.0,0.0); p.closePath();
-		VisitorMooring.add(new Instr(Form.PGON, p));
-    VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-    VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(-33,0,-10,0)));
-    VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(10,0,40,0)));
-    VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-    VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(6.5,-49.5,12,12)));
-    VisitorMooring.add(new Instr(Form.FILL, Color.white));
-		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);
-		p.lineTo(-1.9,-32.8); p.lineTo(3.2,-18.1); p.closePath();
-		VisitorMooring.add(new Instr(Form.PGON, p));
-	}
-
-	public static final EnumMap<CatSCF, Symbol> Cats = new EnumMap<>(CatSCF.class);
-	static {
-		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);
-		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);
-		Cats.put(CatSCF.SCF_VBTH, VisitorBerth); Cats.put(CatSCF.SCF_VMOR, VisitorMooring);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    private static final Symbol Facility = new Symbol();
+    static {
+        Facility.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Facility.add(new Instr(Form.FILL, new Color(0x80ffffff, true)));
+        RoundRectangle2D.Double s = new RoundRectangle2D.Double(-29, -29, 58, 58, 15, 15);
+        Facility.add(new Instr(Form.RSHP, s));
+        Facility.add(new Instr(Form.FILL, new Color(0xa30075)));
+        Facility.add(new Instr(Form.RRCT, s));
+    }
+
+    public static final Symbol Boatlift = new Symbol(); //was Crane
+    static {
+        Boatlift.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Boatlift.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Boatlift.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Boatlift.add(new Instr(Form.ELPS, new Ellipse2D.Double(-3.7, -19.7, 12, 12)));
+        Boatlift.add(new Instr(Form.LINE, new Line2D.Double(2.3, -7.7, 2.3, -2.0)));
+        Boatlift.add(new Instr(Form.EARC, new Arc2D.Double(-10.0, -1.5, 20, 20, 75.0, -260.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Boatyard = new Symbol();
+    static {
+        Boatyard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Boatyard.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Boatyard.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Boatyard.add(new Instr(Form.LINE, new Line2D.Double(19, 19, -8, -8)));
+        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);
+        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();
+        Boatyard.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Chandler = new Symbol();
+    static {
+        Chandler.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Chandler.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Chandler.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Chandler.add(new Instr(Form.ELPS, new Ellipse2D.Double(14, 7, 10, 10)));
+        Chandler.add(new Instr(Form.LINE, new Line2D.Double(-23.0, 12.0, 14.0, 12.0)));
+        Chandler.add(new Instr(Form.LINE, new Line2D.Double(8.0, 21.0, 8.0, -8.6)));
+        Chandler.add(new Instr(Form.LINE, new Line2D.Double(-16.0, 21.0, -16.0, -8.6)));
+        Chandler.add(new Instr(Form.EARC, new Arc2D.Double(-16.0, -20.5, 24, 24, 0.0, 180.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Fuel = new Symbol();
+    static {
+        Fuel.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Fuel.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Fuel.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Fuel.add(new Instr(Form.FILL, new Color(0xa30075)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        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();
+        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);
+        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();
+        Fuel.add(new Instr(Form.PGON, p));
+        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);
+        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);
+        Fuel.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Laundrette = new Symbol();
+    static {
+        Laundrette.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Laundrette.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Laundrette.add(new Instr(Form.STRK, new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Laundrette.add(new Instr(Form.FILL, new Color(0xa30075)));
+        Laundrette.add(new Instr(Form.RECT, new Rectangle2D.Double(-15, -15, 30, 30)));
+        Laundrette.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -15); p.lineTo(-15, -20); p.lineTo(15, -20); p.lineTo(15, -15);
+        p.moveTo(-10, 15); p.lineTo(-10, 20); p.lineTo(10, 20); p.lineTo(10, 15);
+        Laundrette.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol PumpOut = new Symbol();
+    static {
+        PumpOut.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        PumpOut.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        PumpOut.add(new Instr(Form.STRK, new BasicStroke(2.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        PumpOut.add(new Instr(Form.FILL, new Color(0xa30075)));
+        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);
+        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);
+        PumpOut.add(new Instr(Form.PLIN, p));
+        PumpOut.add(new Instr(Form.STRK, new BasicStroke(3.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        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);
+        PumpOut.add(new Instr(Form.PLIN, p));
+        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();
+        PumpOut.add(new Instr(Form.PGON, p));
+        p = new Path2D.Double(); p.moveTo(14.1, -10.6); p.lineTo(23.1, -6.7); p.lineTo(14.1, -2.8); p.closePath();
+        PumpOut.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol SailingClub = new Symbol();
+    static {
+        SailingClub.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        SailingClub.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        SailingClub.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        SailingClub.add(new Instr(Form.FILL, new Color(0xa30075)));
+        SailingClub.add(new Instr(Form.LINE, new Line2D.Double(-5, 20, -5, -20)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-5, 0); p.lineTo(20, -10); p.lineTo(-5, -20); p.closePath();
+        SailingClub.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Shower = new Symbol();
+    static {
+        Shower.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Shower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Shower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Shower.add(new Instr(Form.FILL, new Color(0xa30075)));
+        Shower.add(new Instr(Form.LINE, new Line2D.Double(-4.8, -24.5, 6.2, -13.5)));
+        Shower.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Shower.add(new Instr(Form.LINE, new Line2D.Double(-18.1, -17.9, -6.1, -21.3)));
+        Shower.add(new Instr(Form.LINE, new Line2D.Double(-13.9, -10.2, -3.9, -17.7)));
+        Shower.add(new Instr(Form.LINE, new Line2D.Double(-7.8, -4.4, -0.5, -14.3)));
+        Shower.add(new Instr(Form.LINE, new Line2D.Double(-0.2, -0.2, 3.1, -12.1)));
+        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);
+        Shower.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Slipway = new Symbol();
+    static {
+        Slipway.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Slipway.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Slipway.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Slipway.add(new Instr(Form.FILL, new Color(0xa30075)));
+        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);
+        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);
+        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();
+        Slipway.add(new Instr(Form.PGON, p));
+        Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.65, -1.9, 8, 8)));
+        Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Slipway.add(new Instr(Form.LINE, new Line2D.Double(-24.5, -8.3, -3.1, -2.4)));
+        Slipway.add(new Instr(Form.LINE, new Line2D.Double(9.3, 1.1, 22.2, 4.6)));
+        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);
+        p.lineTo(-17.1, -18.9); p.quadTo(-16.8, -11.4, -7.7, -7.7); p.closePath();
+        Slipway.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Toilet = new Symbol();
+    static {
+        Toilet.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Toilet.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Facilities.Facility, 1.0, 0, 0, null, null)));
+        Toilet.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        Toilet.add(new Instr(Form.FILL, new Color(0xa30075)));
+        Toilet.add(new Instr(Form.LINE, new Line2D.Double(0, 20, 0, -20)));
+        Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(-18.5, -22.5, 7.4, 7.4)));
+        Toilet.add(new Instr(Form.RSHP, new Ellipse2D.Double(11, -22.5, 7.4, 7.4)));
+        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);
+        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);
+        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();
+        Toilet.add(new Instr(Form.PGON, p));
+        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);
+        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);
+        p.lineTo(6.8, -10.1); p.lineTo(9.4, -12.2); p.closePath();
+        Toilet.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol VisitorBerth = new Symbol();
+    static {
+        VisitorBerth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        VisitorBerth.add(new Instr(Form.FILL, new Color(0xa30075)));
+        VisitorBerth.add(new Instr(Form.RSHP, new Ellipse2D.Double(-25, -25, 50, 50)));
+        VisitorBerth.add(new Instr(Form.FILL, Color.white));
+        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);
+        p.lineTo(-14.0, -13.6); p.lineTo(-7.9, -13.6); p.lineTo(0.0, 8.7); p.closePath();
+        VisitorBerth.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol VisitorMooring = new Symbol();
+    static {
+        VisitorMooring.add(new Instr(Form.FILL, new Color(0xa30075)));
+        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);
+        p.lineTo(8.0, 0.0); p.curveTo(8.0, -11.0, -8.0, -11.0, -8.0, 0.0); p.closePath();
+        VisitorMooring.add(new Instr(Form.PGON, p));
+        VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(-33, 0, -10, 0)));
+        VisitorMooring.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 40, 0)));
+        VisitorMooring.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        VisitorMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(6.5, -49.5, 12, 12)));
+        VisitorMooring.add(new Instr(Form.FILL, Color.white));
+        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);
+        p.lineTo(-1.9, -32.8); p.lineTo(3.2, -18.1); p.closePath();
+        VisitorMooring.add(new Instr(Form.PGON, p));
+    }
+
+    public static final EnumMap<CatSCF, Symbol> Cats = new EnumMap<>(CatSCF.class);
+    static {
+        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);
+        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);
+        Cats.put(CatSCF.SCF_VBTH, VisitorBerth); Cats.put(CatSCF.SCF_VMOR, VisitorMooring);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Harbours.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Harbours.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Harbours.java	(revision 32394)
@@ -12,205 +12,239 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.geom.*;
-
-import symbols.Symbols.*;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+
+import symbols.Symbols.Form;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Scheme;
+import symbols.Symbols.Symbol;
 
 public class Harbours {
-	public static final Symbol Anchor = new Symbol();
-	static {
-		Anchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60,-60,120,120)));
-		Anchor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Anchor.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-59,20,20)));
-		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);
-		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);
-		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);
-		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();
-		Anchor.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Yacht = new Symbol();
-	static {
-		Yacht.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		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();
-		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();
-		Yacht.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Anchorage = new Symbol();
-	static {
-		Anchorage.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.67, 0, 0, new Scheme(Symbols.Msymb), null)));
-	}
-	public static final Symbol Bollard = new Symbol();
-	static {
-		Bollard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Bollard.add(new Instr(Form.FILL, Color.white));
-		Ellipse2D.Double s = new Ellipse2D.Double(-10,-10,20,20);
-		Bollard.add(new Instr(Form.RSHP, s));
-		Bollard.add(new Instr(Form.FILL, Color.black));
-		Bollard.add(new Instr(Form.ELPS, s));
-	}
-	public static final Symbol CallPoint1 = new Symbol();
-	static {
-		CallPoint1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-50,100,100)));
-		CallPoint1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		CallPoint1.add(new Instr(Form.FILL, Symbols.Msymb));
-		CallPoint1.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0,-20.0); p.lineTo(0.0,-50.0); p.lineTo(16.0,-20.0);
-		CallPoint1.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol CallPoint2 = new Symbol();
-	static {
-		CallPoint2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-50,100,100)));
-		CallPoint2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(CallPoint1, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0,20.0); p.lineTo(0.0,50.0); p.lineTo(16.0,20.0);
-		CallPoint2.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol ContainerCrane = new Symbol();
-	static {
-		ContainerCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		ContainerCrane.add(new Instr(Form.RSHP, new Rectangle2D.Double(-15,-65,30,100)));
-		ContainerCrane.add(new Instr(Form.RECT, new Rectangle2D.Double(-40,-12.5,80,25)));
-	}
-	public static final Symbol Customs = new Symbol();
-	static {
-		Customs.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Customs.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Customs.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28,-28,56,56)));
-		Customs.add(new Instr(Form.LINE, new Line2D.Double(-25,5,25,5)));
-		Customs.add(new Instr(Form.LINE, new Line2D.Double(-25,-5,25,-5)));
-	}
-	public static final Symbol DeviationDolphin = new Symbol();
-	static {
-		DeviationDolphin.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		p.moveTo(-20.0,0.0); p.lineTo(-15.0,-32.0); p.lineTo(15.0,-32.0); p.lineTo(20.0,0.0);
-		DeviationDolphin.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol DistanceI = new Symbol();
-	static {
-		DistanceI.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		DistanceI.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11,-11,22,22)));
-	}
-	public static final Symbol DistanceU = new Symbol();
-	static {
-		DistanceU.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		DistanceU.add(new Instr(Form.FILL, Symbols.Msymb));
-		DistanceU.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11,-11,22,22)));
-	}
-	public static final Symbol Dolphin = new Symbol();
-	static {
-		Dolphin.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Dolphin.add(new Instr(Form.FILL, new Color(0xffd400)));
-		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);
-		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();
-		Dolphin.add(new Instr(Form.PGON, p));
-		Dolphin.add(new Instr(Form.FILL, Color.black));
-		Dolphin.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Explosives = new Symbol();
-	static {
-		Explosives.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Explosives.add(new Instr(Form.RSHP, new Ellipse2D.Double(-5,25,10,10)));
-		Explosives.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-10,20); p.lineTo(-13,17); p.lineTo(-13,8);
-		p.moveTo(0,10); p.lineTo(0,0); p.lineTo(-8,-10);
-		p.moveTo(10,17); p.lineTo(18,-10); p.lineTo(10,-20);
-		Explosives.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Fishing = new Symbol();
-	static {
-		Fishing.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Fishing.add(new Instr(Form.FILL, Symbols.Msymb));
-		Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50,-50,100,100,15,140,Arc2D.OPEN)));
-		Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50,-50,100,100,-15,-140,Arc2D.OPEN)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-24,3); p.curveTo(12,24,30,15,48,0); p.curveTo(30,-15,12,-24,-24,-3);
-		p.lineTo(-45,-15); p.quadTo(-48, 0, -45, 15); p.closePath();
-		p.moveTo(25, 0); p.curveTo(25, 6, 34, 6, 34, 0); p.curveTo(34, -6, 25, -6, 25, 0); p.closePath();
-		Fishing.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Harbour = new Symbol();
-	static {
-		Harbour.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Harbour.add(new Instr(Form.FILL, Symbols.Msymb));
-		Harbour.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50,-50,100,100)));
-		Harbour.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
-	}
-	public static final Symbol HarbourMaster = new Symbol();
-	static {
-		HarbourMaster.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		HarbourMaster.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		HarbourMaster.add(new Instr(Form.ELPS, new Ellipse2D.Double(-24,-28,48,56)));
-		HarbourMaster.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
-	}
-	public static final Symbol Hospital = new Symbol();
-	static {
-		Hospital.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Hospital.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Hospital.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28,-28,56,56)));
-		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);
-		p.moveTo(-25,5); p.lineTo(-5,5); p.lineTo(-5,25); p.moveTo(5,25); p.lineTo(5,5); p.lineTo(25,5);
-		Hospital.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol LandingSteps = new Symbol();
-	static {
-		LandingSteps.add(new Instr(Form.FILL, Symbols.Msymb));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-20,-10); p.lineTo(10,20); p.lineTo(20,20); p.lineTo(20,10);
-		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();
-		LandingSteps.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol Marina = new Symbol();
-	static {
-		Marina.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Marina.add(new Instr(Form.FILL, Symbols.Msymb));
-		Marina.add(new Instr(Form.EARC, new Arc2D.Double(-50.0,-50.0,100.0,100.0,215.0,-250.0,Arc2D.OPEN)));
-		Marina.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
-	}
-	public static final Symbol MarinaNF = new Symbol();
-	static {
-		MarinaNF.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
-	}
-	public static final Symbol Pilot = new Symbol();
-	static{
-		Pilot.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Pilot.add(new Instr(Form.FILL, new Color(0xd400d4)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15,0); p.lineTo(0,-56); p.lineTo(15,0); p.lineTo(0,56); p.closePath();
-		Pilot.add(new Instr(Form.PGON, p));
-		Pilot.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58,-58,116,116)));
-	}
-	public static final Symbol PortCrane = new Symbol();
-	static {
-		PortCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		PortCrane.add(new Instr(Form.EARC, new Arc2D.Double(-36.0,-36.0,72.0,72.0,70.0,-320.0,Arc2D.OPEN)));
-		PortCrane.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-60)));
-	}
-	public static final Symbol Post = new Symbol();
-	static {
-		Post.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-10,20,20)));
-	}
-	public static final Symbol Rescue = new Symbol();
-	static{
-		Rescue.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-50,40,100)));
-		Rescue.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-11,0); p.lineTo(0,-43); p.lineTo(11,0); p.lineTo(0,43); p.closePath();
-		Rescue.add(new Instr(Form.PGON, p));
-		Rescue.add(new Instr(Form.LINE, new Line2D.Double(-15,0,15,0)));
-	}
-	public static final Symbol SignalStation = new Symbol();
-	static {
-		SignalStation.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		SignalStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
-		SignalStation.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
-	}
-	public static final Symbol TideGauge = new Symbol();
-	static {
-		TideGauge.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TideGauge.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-10,0,-30,0)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(10,0,30,0)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-80)));
-		TideGauge.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15,-25,15,-25)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-25,-45,25,-45)));
-		TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15,-65,15,-65)));
-	}
+    // CHECKSTYLE.OFF: LineLength
+    public static final Symbol Anchor = new Symbol();
+    static {
+        Anchor.add(new Instr(Form.BBOX, new Rectangle2D.Double(-60, -60, 120, 120)));
+        Anchor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Anchor.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -59, 20, 20)));
+        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);
+        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);
+        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);
+        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();
+        Anchor.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Yacht = new Symbol();
+    static {
+        Yacht.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        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();
+        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();
+        Yacht.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Anchorage = new Symbol();
+    static {
+        Anchorage.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.67, 0, 0, new Scheme(Symbols.Msymb), null)));
+    }
+
+    public static final Symbol Bollard = new Symbol();
+    static {
+        Bollard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Bollard.add(new Instr(Form.FILL, Color.white));
+        Ellipse2D.Double s = new Ellipse2D.Double(-10, -10, 20, 20);
+        Bollard.add(new Instr(Form.RSHP, s));
+        Bollard.add(new Instr(Form.FILL, Color.black));
+        Bollard.add(new Instr(Form.ELPS, s));
+    }
+
+    public static final Symbol CallPoint1 = new Symbol();
+    static {
+        CallPoint1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -50, 100, 100)));
+        CallPoint1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        CallPoint1.add(new Instr(Form.FILL, Symbols.Msymb));
+        CallPoint1.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0, -20.0); p.lineTo(0.0, -50.0); p.lineTo(16.0, -20.0);
+        CallPoint1.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol CallPoint2 = new Symbol();
+    static {
+        CallPoint2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -50, 100, 100)));
+        CallPoint2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(CallPoint1, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-16.0, 20.0); p.lineTo(0.0, 50.0); p.lineTo(16.0, 20.0);
+        CallPoint2.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol ContainerCrane = new Symbol();
+    static {
+        ContainerCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ContainerCrane.add(new Instr(Form.RSHP, new Rectangle2D.Double(-15, -65, 30, 100)));
+        ContainerCrane.add(new Instr(Form.RECT, new Rectangle2D.Double(-40, -12.5, 80, 25)));
+    }
+
+    public static final Symbol Customs = new Symbol();
+    static {
+        Customs.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Customs.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Customs.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28, -28, 56, 56)));
+        Customs.add(new Instr(Form.LINE, new Line2D.Double(-25, 5, 25, 5)));
+        Customs.add(new Instr(Form.LINE, new Line2D.Double(-25, -5, 25, -5)));
+    }
+
+    public static final Symbol DeviationDolphin = new Symbol();
+    static {
+        DeviationDolphin.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        p.moveTo(-20.0, 0.0); p.lineTo(-15.0, -32.0); p.lineTo(15.0, -32.0); p.lineTo(20.0, 0.0);
+        DeviationDolphin.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol DistanceI = new Symbol();
+    static {
+        DistanceI.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        DistanceI.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11, -11, 22, 22)));
+    }
+
+    public static final Symbol DistanceU = new Symbol();
+    static {
+        DistanceU.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        DistanceU.add(new Instr(Form.FILL, Symbols.Msymb));
+        DistanceU.add(new Instr(Form.ELPS, new Ellipse2D.Double(-11, -11, 22, 22)));
+    }
+
+    public static final Symbol Dolphin = new Symbol();
+    static {
+        Dolphin.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Dolphin.add(new Instr(Form.FILL, new Color(0xffd400)));
+        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);
+        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();
+        Dolphin.add(new Instr(Form.PGON, p));
+        Dolphin.add(new Instr(Form.FILL, Color.black));
+        Dolphin.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Explosives = new Symbol();
+    static {
+        Explosives.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Explosives.add(new Instr(Form.RSHP, new Ellipse2D.Double(-5, 25, 10, 10)));
+        Explosives.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 20); p.lineTo(-13, 17); p.lineTo(-13, 8);
+        p.moveTo(0, 10); p.lineTo(0, 0); p.lineTo(-8, -10);
+        p.moveTo(10, 17); p.lineTo(18, -10); p.lineTo(10, -20);
+        Explosives.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Fishing = new Symbol();
+    static {
+        Fishing.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Fishing.add(new Instr(Form.FILL, Symbols.Msymb));
+        Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50, -50, 100, 100, 15, 140, Arc2D.OPEN)));
+        Fishing.add(new Instr(Form.EARC, new Arc2D.Double(-50, -50, 100, 100, -15, -140, Arc2D.OPEN)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-24, 3); p.curveTo(12, 24, 30, 15, 48, 0); p.curveTo(30, -15, 12, -24, -24, -3);
+        p.lineTo(-45, -15); p.quadTo(-48, 0, -45, 15); p.closePath();
+        p.moveTo(25, 0); p.curveTo(25, 6, 34, 6, 34, 0); p.curveTo(34, -6, 25, -6, 25, 0); p.closePath();
+        Fishing.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Harbour = new Symbol();
+    static {
+        Harbour.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Harbour.add(new Instr(Form.FILL, Symbols.Msymb));
+        Harbour.add(new Instr(Form.ELPS, new Ellipse2D.Double(-50, -50, 100, 100)));
+        Harbour.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
+    }
+
+    public static final Symbol HarbourMaster = new Symbol();
+    static {
+        HarbourMaster.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        HarbourMaster.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        HarbourMaster.add(new Instr(Form.ELPS, new Ellipse2D.Double(-24, -28, 48, 56)));
+        HarbourMaster.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
+    }
+
+    public static final Symbol Hospital = new Symbol();
+    static {
+        Hospital.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Hospital.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Hospital.add(new Instr(Form.ELPS, new Ellipse2D.Double(-28, -28, 56, 56)));
+        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);
+        p.moveTo(-25, 5); p.lineTo(-5, 5); p.lineTo(-5, 25); p.moveTo(5, 25); p.lineTo(5, 5); p.lineTo(25, 5);
+        Hospital.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol LandingSteps = new Symbol();
+    static {
+        LandingSteps.add(new Instr(Form.FILL, Symbols.Msymb));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, -10); p.lineTo(10, 20); p.lineTo(20, 20); p.lineTo(20, 10);
+        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();
+        LandingSteps.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol Marina = new Symbol();
+    static {
+        Marina.add(new Instr(Form.STRK, new BasicStroke(10, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Marina.add(new Instr(Form.FILL, Symbols.Msymb));
+        Marina.add(new Instr(Form.EARC, new Arc2D.Double(-50.0, -50.0, 100.0, 100.0, 215.0, -250.0, Arc2D.OPEN)));
+        Marina.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
+    }
+
+    public static final Symbol MarinaNF = new Symbol();
+    static {
+        MarinaNF.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Yacht, 0.6, 0, 0, new Scheme(Symbols.Msymb), null)));
+    }
+
+    public static final Symbol Pilot = new Symbol();
+    static {
+        Pilot.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Pilot.add(new Instr(Form.FILL, new Color(0xd400d4)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, 0); p.lineTo(0, -56); p.lineTo(15, 0); p.lineTo(0, 56); p.closePath();
+        Pilot.add(new Instr(Form.PGON, p));
+        Pilot.add(new Instr(Form.ELPS, new Ellipse2D.Double(-58, -58, 116, 116)));
+    }
+
+    public static final Symbol PortCrane = new Symbol();
+    static {
+        PortCrane.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        PortCrane.add(new Instr(Form.EARC, new Arc2D.Double(-36.0, -36.0, 72.0, 72.0, 70.0, -320.0, Arc2D.OPEN)));
+        PortCrane.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -60)));
+    }
+
+    public static final Symbol Post = new Symbol();
+    static {
+        Post.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -10, 20, 20)));
+    }
+
+    public static final Symbol Rescue = new Symbol();
+    static {
+        Rescue.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -50, 40, 100)));
+        Rescue.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-11, 0); p.lineTo(0, -43); p.lineTo(11, 0); p.lineTo(0, 43); p.closePath();
+        Rescue.add(new Instr(Form.PGON, p));
+        Rescue.add(new Instr(Form.LINE, new Line2D.Double(-15, 0, 15, 0)));
+    }
+
+    public static final Symbol SignalStation = new Symbol();
+    static {
+        SignalStation.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        SignalStation.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
+        SignalStation.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
+    }
+
+    public static final Symbol TideGauge = new Symbol();
+    static {
+        TideGauge.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TideGauge.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-10, 0, -30, 0)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 30, 0)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -80)));
+        TideGauge.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15, -25, 15, -25)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-25, -45, 25, -45)));
+        TideGauge.add(new Instr(Form.LINE, new Line2D.Double(-15, -65, 15, -65)));
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java	(revision 32394)
@@ -11,199 +11,225 @@
 
 import java.awt.BasicStroke;
-import java.awt.geom.*;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
 import java.util.EnumMap;
 
-import s57.S57val.*;
-import symbols.Symbols.*;
-
+import s57.S57val.CatLMK;
+import s57.S57val.FncFNC;
+import symbols.Symbols.Form;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Landmarks {
-	private static final Symbol Base = new Symbol();
-	static {
-		Base.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Base.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10,-10,20,20)));
-		Base.add(new Instr(Form.LINE, new Line2D.Double(-35,0,-10,0)));
-		Base.add(new Instr(Form.LINE, new Line2D.Double(10,0,35,0)));
-	}
-	
-	public static final Symbol Chimney = new Symbol();
-	static {
-		Chimney.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Chimney.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		p.moveTo(-10.0,-128.0); p.curveTo(-13.0,-147.0,15.0,-159.0,20.0,-148.0);
-		p.moveTo(16.0,-152.3); p.curveTo(58.0,-194.0,98.0,-87.0,16.0,-132.0);
-		p.moveTo(11.0,-128.0); p.curveTo(13.4,-132.0,20.0,-132.0,20.0,-136.0);
-		Chimney.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Church = new Symbol();
-	static {
-		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);
-		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);
-		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);
-		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);
-		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();
-		Church.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol ChurchTower = new Symbol();
-	static {
-		ChurchTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		ChurchTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-36,-36,72,72)));
-		ChurchTower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-2,-2,4,4)));
-	}
-	public static final Symbol Cross = new Symbol();
-	static {
-		Cross.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Cross.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Cross.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-150)));
-		Cross.add(new Instr(Form.LINE, new Line2D.Double(-30,-115,30,-115)));
-	}
-	public static final Symbol DishAerial = new Symbol();
-	static {
-		DishAerial.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		DishAerial.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
-		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);
-		p.moveTo(-9.5,-157.0); p.curveTo(-60.7,-125.5,-16.5,-33.9,44.9,-61.7); p.closePath();
-		DishAerial.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Dome = new Symbol();
-	static {
-		Dome.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Dome.add(new Instr(Form.ELPS, new Ellipse2D.Double(-36,-36,72,72)));
-		Dome.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
-	}
-	public static final Symbol Flagstaff = new Symbol();
-	static {
-		Flagstaff.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Flagstaff.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		Flagstaff.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol FlareStack = new Symbol();
-	static {
-		FlareStack.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		FlareStack.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		FlareStack.add(new Instr(Form.PLIN, p));
-		FlareStack.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		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);
-		FlareStack.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol LandTower = new Symbol();
-	static {
-		LandTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		LandTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		LandTower.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-120)));
-		LandTower.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-120)));
-		LandTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-15,-150,30,30)));
-	}
-	public static final Symbol Mast = new Symbol();
-	static {
-		Mast.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Mast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0,0.0); p.lineTo(0.0,-150.0); p.lineTo(25.0,0.0);
-		Mast.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol Monument = new Symbol();
-	static {
-		Monument.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Monument.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Monument.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-105)));
-		Monument.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-105)));
-		Monument.add(new Instr(Form.EARC, new Arc2D.Double(-25.0,-150.0,50.0,50.0,233.0,-285.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Platform = new Symbol();
-	static {
-		Platform.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Platform.add(new Instr(Form.RECT, new Rectangle2D.Double(-48,-48,96,96)));
-		Platform.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
-	}
-	public static final Symbol RadioTV = new Symbol();
-	static {
-		RadioTV.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)));
-		RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0,-180.0,60.0,60.0,45.0,-90.0,Arc2D.OPEN)));
-		RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0,-195.0,90.0,90.0,45.0,-90.0,Arc2D.OPEN)));
-		RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0,-180.0,60.0,60.0,225.0,-90.0,Arc2D.OPEN)));
-		RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0,-195.0,90.0,90.0,225.0,-90.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Spire = new Symbol();
-	static {
-		Spire.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Spire.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25,-25,50,50)));
-		Spire.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4,-4,8,8)));
-	}
-	public static final Symbol Minaret = new Symbol();
-	static {
-		Minaret.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Spire, 1.0, 0, 0, null, null)));
-		Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Minaret.add(new Instr(Form.LINE, new Line2D.Double(0,-25,0,-50)));
-		Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Minaret.add(new Instr(Form.EARC, new Arc2D.Double(-40.0,-110.0,80.0,60.0,180.0,180.0,Arc2D.OPEN)));
-	}
-	public static final Symbol Temple = new Symbol();
-	static {
-		Temple.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Temple.add(new Instr(Form.RECT, new Rectangle2D.Double(-25,-15,50,30)));
-		Temple.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Temple.add(new Instr(Form.LINE, new Line2D.Double(-35,-21,35,21)));
-		Temple.add(new Instr(Form.LINE, new Line2D.Double(-35,21,35,-21)));
-	}
-	public static final Symbol WaterTower = new Symbol();
-	static {
-		WaterTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		WaterTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		WaterTower.add(new Instr(Form.LINE, new Line2D.Double(-25,0,-15,-120)));
-		WaterTower.add(new Instr(Form.LINE, new Line2D.Double(25,0,15,-120)));
-		WaterTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-25,-150,50,30)));
-	}
-	public static final Symbol WindMotor = new Symbol();
-	static {
-		WindMotor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		WindMotor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-90)));
-		WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,30,-90)));
-		WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,-14,-116.6)));
-		WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0,-90,-14.3,-66.7)));
-	}
-	public static final Symbol Windmill = new Symbol();
-	static {
-		Windmill.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Windmill.add(new Instr(Form.ELPS, new Ellipse2D.Double(-12,-12,24,24)));
-		Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30,-42,30,10)));
-		Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30,10,30,-42)));
-	}
-	public static final Symbol Windsock = new Symbol();
-	static {
-		Windsock.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
-		Windsock.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Windsock.add(new Instr(Form.LINE, new Line2D.Double(0,-10,0,-100)));
-		Windsock.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Windsock.add(new Instr(Form.LINE, new Line2D.Double(0,-100,0,-150)));
-		Windsock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		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);
-		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);
-		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);
-		Windsock.add(new Instr(Form.PLIN, p));
-	}
-	
-	public static final EnumMap<CatLMK, Symbol> Shapes = new EnumMap<>(CatLMK.class);
-	static {
-		Shapes.put(CatLMK.LMK_CARN, Beacons.Cairn); Shapes.put(CatLMK.LMK_CHMY, Landmarks.Chimney);
-		Shapes.put(CatLMK.LMK_DISH, Landmarks.DishAerial); Shapes.put(CatLMK.LMK_FLAG, Landmarks.Flagstaff); Shapes.put(CatLMK.LMK_FLAR, Landmarks.FlareStack);
-		Shapes.put(CatLMK.LMK_MAST, Landmarks.Mast); Shapes.put(CatLMK.LMK_WNDS, Landmarks.Windsock); Shapes.put(CatLMK.LMK_MNMT, Landmarks.Monument);
-		Shapes.put(CatLMK.LMK_CLMN, Landmarks.Monument); Shapes.put(CatLMK.LMK_MEML, Landmarks.Monument); Shapes.put(CatLMK.LMK_OBLK, Landmarks.Monument);
-		Shapes.put(CatLMK.LMK_STAT, Landmarks.Monument); Shapes.put(CatLMK.LMK_CROS, Landmarks.Cross); Shapes.put(CatLMK.LMK_DOME, Landmarks.Dome);
-		Shapes.put(CatLMK.LMK_RADR, Landmarks.Mast); Shapes.put(CatLMK.LMK_TOWR, Landmarks.LandTower); Shapes.put(CatLMK.LMK_WNDM, Landmarks.Windmill);
-		Shapes.put(CatLMK.LMK_WNDG, Landmarks.WindMotor); Shapes.put(CatLMK.LMK_SPIR, Landmarks.Spire); Shapes.put(CatLMK.LMK_BLDR, Beacons.Cairn);
-	}
-
-	public static final EnumMap<FncFNC, Symbol> Funcs = new EnumMap<>(FncFNC.class);
-	static {
-		Funcs.put(FncFNC.FNC_CHCH, Landmarks.Church); Funcs.put(FncFNC.FNC_CHPL, Landmarks.Church); Funcs.put(FncFNC.FNC_TMPL, Landmarks.Temple);
-		Funcs.put(FncFNC.FNC_PGDA, Landmarks.Temple); Funcs.put(FncFNC.FNC_SHSH, Landmarks.Temple); Funcs.put(FncFNC.FNC_BTMP, Landmarks.Temple);
-		Funcs.put(FncFNC.FNC_MOSQ, Landmarks.Minaret); Funcs.put(FncFNC.FNC_MRBT, Landmarks.Spire); Funcs.put(FncFNC.FNC_COMM, Landmarks.RadioTV);
-		Funcs.put(FncFNC.FNC_TV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADO, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADR, Landmarks.RadioTV);
-		Funcs.put(FncFNC.FNC_LGHT, Beacons.LightMajor); Funcs.put(FncFNC.FNC_MCWV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_HBRM, Harbours.HarbourMaster);
-		Funcs.put(FncFNC.FNC_CSTM, Harbours.Customs); Funcs.put(FncFNC.FNC_HLTH, Harbours.Hospital); Funcs.put(FncFNC.FNC_HOSP, Harbours.Hospital);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    private static final Symbol Base = new Symbol();
+    static {
+        Base.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Base.add(new Instr(Form.ELPS, new Ellipse2D.Double(-10, -10, 20, 20)));
+        Base.add(new Instr(Form.LINE, new Line2D.Double(-35, 0, -10, 0)));
+        Base.add(new Instr(Form.LINE, new Line2D.Double(10, 0, 35, 0)));
+    }
+
+    public static final Symbol Chimney = new Symbol();
+    static {
+        Chimney.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Chimney.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        p.moveTo(-10.0, -128.0); p.curveTo(-13.0, -147.0, 15.0, -159.0, 20.0, -148.0);
+        p.moveTo(16.0, -152.3); p.curveTo(58.0, -194.0, 98.0, -87.0, 16.0, -132.0);
+        p.moveTo(11.0, -128.0); p.curveTo(13.4, -132.0, 20.0, -132.0, 20.0, -136.0);
+        Chimney.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Church = new Symbol();
+    static {
+        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);
+        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);
+        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);
+        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);
+        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();
+        Church.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol ChurchTower = new Symbol();
+    static {
+        ChurchTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ChurchTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-36, -36, 72, 72)));
+        ChurchTower.add(new Instr(Form.ELPS, new Ellipse2D.Double(-2, -2, 4, 4)));
+    }
+
+    public static final Symbol Cross = new Symbol();
+    static {
+        Cross.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Cross.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Cross.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -150)));
+        Cross.add(new Instr(Form.LINE, new Line2D.Double(-30, -115, 30, -115)));
+    }
+
+    public static final Symbol DishAerial = new Symbol();
+    static {
+        DishAerial.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        DishAerial.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
+        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);
+        p.moveTo(-9.5, -157.0); p.curveTo(-60.7, -125.5, -16.5, -33.9, 44.9, -61.7); p.closePath();
+        DishAerial.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Dome = new Symbol();
+    static {
+        Dome.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Dome.add(new Instr(Form.ELPS, new Ellipse2D.Double(-36, -36, 72, 72)));
+        Dome.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
+    }
+
+    public static final Symbol Flagstaff = new Symbol();
+    static {
+        Flagstaff.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Flagstaff.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        Flagstaff.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol FlareStack = new Symbol();
+    static {
+        FlareStack.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        FlareStack.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        FlareStack.add(new Instr(Form.PLIN, p));
+        FlareStack.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        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);
+        FlareStack.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol LandTower = new Symbol();
+    static {
+        LandTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        LandTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        LandTower.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -120)));
+        LandTower.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -120)));
+        LandTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-15, -150, 30, 30)));
+    }
+
+    public static final Symbol Mast = new Symbol();
+    static {
+        Mast.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Mast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-25.0, 0.0); p.lineTo(0.0, -150.0); p.lineTo(25.0, 0.0);
+        Mast.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol Monument = new Symbol();
+    static {
+        Monument.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Monument.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Monument.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -105)));
+        Monument.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -105)));
+        Monument.add(new Instr(Form.EARC, new Arc2D.Double(-25.0, -150.0, 50.0, 50.0, 233.0, -285.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Platform = new Symbol();
+    static {
+        Platform.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Platform.add(new Instr(Form.RECT, new Rectangle2D.Double(-48, -48, 96, 96)));
+        Platform.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
+    }
+
+    public static final Symbol RadioTV = new Symbol();
+    static {
+        RadioTV.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)));
+        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0, -180.0, 60.0, 60.0, 45.0, -90.0, Arc2D.OPEN)));
+        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0, -195.0, 90.0, 90.0, 45.0, -90.0, Arc2D.OPEN)));
+        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-30.0, -180.0, 60.0, 60.0, 225.0, -90.0, Arc2D.OPEN)));
+        RadioTV.add(new Instr(Form.EARC, new Arc2D.Double(-45.0, -195.0, 90.0, 90.0, 225.0, -90.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Spire = new Symbol();
+    static {
+        Spire.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Spire.add(new Instr(Form.ELPS, new Ellipse2D.Double(-25, -25, 50, 50)));
+        Spire.add(new Instr(Form.RSHP, new Ellipse2D.Double(-4, -4, 8, 8)));
+    }
+
+    public static final Symbol Minaret = new Symbol();
+    static {
+        Minaret.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Spire, 1.0, 0, 0, null, null)));
+        Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Minaret.add(new Instr(Form.LINE, new Line2D.Double(0, -25, 0, -50)));
+        Minaret.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Minaret.add(new Instr(Form.EARC, new Arc2D.Double(-40.0, -110.0, 80.0, 60.0, 180.0, 180.0, Arc2D.OPEN)));
+    }
+
+    public static final Symbol Temple = new Symbol();
+    static {
+        Temple.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Temple.add(new Instr(Form.RECT, new Rectangle2D.Double(-25, -15, 50, 30)));
+        Temple.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Temple.add(new Instr(Form.LINE, new Line2D.Double(-35, -21, 35, 21)));
+        Temple.add(new Instr(Form.LINE, new Line2D.Double(-35, 21, 35, -21)));
+    }
+
+    public static final Symbol WaterTower = new Symbol();
+    static {
+        WaterTower.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        WaterTower.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        WaterTower.add(new Instr(Form.LINE, new Line2D.Double(-25, 0, -15, -120)));
+        WaterTower.add(new Instr(Form.LINE, new Line2D.Double(25, 0, 15, -120)));
+        WaterTower.add(new Instr(Form.RECT, new Rectangle2D.Double(-25, -150, 50, 30)));
+    }
+
+    public static final Symbol WindMotor = new Symbol();
+    static {
+        WindMotor.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        WindMotor.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -90)));
+        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, 30, -90)));
+        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, -14, -116.6)));
+        WindMotor.add(new Instr(Form.LINE, new Line2D.Double(0, -90, -14.3, -66.7)));
+    }
+
+    public static final Symbol Windmill = new Symbol();
+    static {
+        Windmill.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Windmill.add(new Instr(Form.ELPS, new Ellipse2D.Double(-12, -12, 24, 24)));
+        Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30, -42, 30, 10)));
+        Windmill.add(new Instr(Form.LINE, new Line2D.Double(-30, 10, 30, -42)));
+    }
+
+    public static final Symbol Windsock = new Symbol();
+    static {
+        Windsock.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Landmarks.Base, 1.0, 0, 0, null, null)));
+        Windsock.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Windsock.add(new Instr(Form.LINE, new Line2D.Double(0, -10, 0, -100)));
+        Windsock.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Windsock.add(new Instr(Form.LINE, new Line2D.Double(0, -100, 0, -150)));
+        Windsock.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        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);
+        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);
+        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);
+        Windsock.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final EnumMap<CatLMK, Symbol> Shapes = new EnumMap<>(CatLMK.class);
+    static {
+        Shapes.put(CatLMK.LMK_CARN, Beacons.Cairn); Shapes.put(CatLMK.LMK_CHMY, Landmarks.Chimney);
+        Shapes.put(CatLMK.LMK_DISH, Landmarks.DishAerial); Shapes.put(CatLMK.LMK_FLAG, Landmarks.Flagstaff); Shapes.put(CatLMK.LMK_FLAR, Landmarks.FlareStack);
+        Shapes.put(CatLMK.LMK_MAST, Landmarks.Mast); Shapes.put(CatLMK.LMK_WNDS, Landmarks.Windsock); Shapes.put(CatLMK.LMK_MNMT, Landmarks.Monument);
+        Shapes.put(CatLMK.LMK_CLMN, Landmarks.Monument); Shapes.put(CatLMK.LMK_MEML, Landmarks.Monument); Shapes.put(CatLMK.LMK_OBLK, Landmarks.Monument);
+        Shapes.put(CatLMK.LMK_STAT, Landmarks.Monument); Shapes.put(CatLMK.LMK_CROS, Landmarks.Cross); Shapes.put(CatLMK.LMK_DOME, Landmarks.Dome);
+        Shapes.put(CatLMK.LMK_RADR, Landmarks.Mast); Shapes.put(CatLMK.LMK_TOWR, Landmarks.LandTower); Shapes.put(CatLMK.LMK_WNDM, Landmarks.Windmill);
+        Shapes.put(CatLMK.LMK_WNDG, Landmarks.WindMotor); Shapes.put(CatLMK.LMK_SPIR, Landmarks.Spire); Shapes.put(CatLMK.LMK_BLDR, Beacons.Cairn);
+    }
+
+    public static final EnumMap<FncFNC, Symbol> Funcs = new EnumMap<>(FncFNC.class);
+    static {
+        Funcs.put(FncFNC.FNC_CHCH, Landmarks.Church); Funcs.put(FncFNC.FNC_CHPL, Landmarks.Church); Funcs.put(FncFNC.FNC_TMPL, Landmarks.Temple);
+        Funcs.put(FncFNC.FNC_PGDA, Landmarks.Temple); Funcs.put(FncFNC.FNC_SHSH, Landmarks.Temple); Funcs.put(FncFNC.FNC_BTMP, Landmarks.Temple);
+        Funcs.put(FncFNC.FNC_MOSQ, Landmarks.Minaret); Funcs.put(FncFNC.FNC_MRBT, Landmarks.Spire); Funcs.put(FncFNC.FNC_COMM, Landmarks.RadioTV);
+        Funcs.put(FncFNC.FNC_TV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADO, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_RADR, Landmarks.RadioTV);
+        Funcs.put(FncFNC.FNC_LGHT, Beacons.LightMajor); Funcs.put(FncFNC.FNC_MCWV, Landmarks.RadioTV); Funcs.put(FncFNC.FNC_HBRM, Harbours.HarbourMaster);
+        Funcs.put(FncFNC.FNC_CSTM, Harbours.Customs); Funcs.put(FncFNC.FNC_HLTH, Harbours.Hospital); Funcs.put(FncFNC.FNC_HOSP, Harbours.Hospital);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Notices.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Notices.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Notices.java	(revision 32394)
@@ -13,1567 +13,1738 @@
 import java.awt.Color;
 import java.awt.Font;
-import java.awt.geom.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
 import java.util.ArrayList;
 import java.util.EnumMap;
 
-import s57.S57val.*;
-import symbols.Symbols.*;
+import s57.S57val.BnkWTW;
+import s57.S57val.CatNMK;
+import s57.S57val.MarSYS;
+import symbols.Symbols.Caption;
+import symbols.Symbols.Delta;
+import symbols.Symbols.Form;
+import symbols.Symbols.Handle;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Scheme;
+import symbols.Symbols.Symbol;
 
 public class Notices {
-	private static final Symbol Bollard = new Symbol();
-	static {
-		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);
-		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);
-		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);
-		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();
-		Bollard.add(new Instr(Form.PGON, p));
-	}
-	private static final Symbol Motor = new Symbol();
-	static {
-		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);
-		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);
-		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);
-		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();
-		Motor.add(new Instr(Form.PGON, p));
-	}
-	private static final Symbol Rowboat = new Symbol();
-	static {
-		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();
-		Rowboat.add(new Instr(Form.PGON, p));
-		Rowboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-6,-17.5,6,6)));
-		Rowboat.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5,-9,-8,0)));
-		Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.0,10.0,-7.5,14.0)));
-		Rowboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5,-9,7,-6.5)));
-		Rowboat.add(new Instr(Form.LINE, new Line2D.Double(7.3,-7.8,-5.0,10.0)));
-	}
-	private static final Symbol Sailboard = new Symbol();
-	static {
-		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();
-		Sailboard.add(new Instr(Form.PGON, p));
-		Sailboard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-2,20,-10,20)));
-		Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-13,2.5,-3,2.5)));
-		Sailboard.add(new Instr(Form.RSHP, new Ellipse2D.Double(-15,-4,5,5)));
-		Sailboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		p = new Path2D.Double(); p.moveTo(-13,2.5); p.lineTo(-12,6.0); p.lineTo(-12,9.5);
-		Sailboard.add(new Instr(Form.PLIN, p));
-		Sailboard.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		p = new Path2D.Double(); p.moveTo(-12,9.5); p.lineTo(-7.5,13.0); p.lineTo(-6.0,19.0);
-		Sailboard.add(new Instr(Form.PLIN, p));
-	}
-	private static final Symbol Sailboat = new Symbol();
-	static {
-		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();
-		Sailboat.add(new Instr(Form.PGON, p));
-		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();
-		Sailboat.add(new Instr(Form.PGON, p));
-	}
-	private static final Symbol Slipway = new Symbol();
-	static {
-		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();
-		p.moveTo(-14,7); p.lineTo(-14,11); p.lineTo(20,11); p.lineTo(20,2); p.closePath();
-		Slipway.add(new Instr(Form.PGON, p));
-		Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Slipway.add(new Instr(Form.LINE, new Line2D.Double(-14,3,20,-2.5)));
-		Slipway.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(1,1.5,3,3)));
-		p = new Path2D.Double(); p.moveTo(-21,8.5); p.curveTo(-17.5, 5, -17.5, 12, -13, 7.2);
-		Slipway.add(new Instr(Form.PLIN, p));
-	}
-	private static final Symbol Speedboat = new Symbol();
-	static {
-		Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-21,0,-17,-1)));
-		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);
-		Speedboat.add(new Instr(Form.PLIN, p));
-		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);
-		p.lineTo(9.5,-6); p.lineTo(6.5,-8); p.lineTo(2.5,-4); p.closePath();
-		Speedboat.add(new Instr(Form.PGON, p));
-		Speedboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-1.5,-13,5,5)));
-		Speedboat.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2,-7,-5,0)));
-		Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2,-7,5,-5)));
-	}
-	private static final Symbol Turn = new Symbol();
-	static {
-		Turn.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Turn.add(new Instr(Form.EARC, new Arc2D.Double(-9.0,-9.0,18.0,18.0,270.0,230.0,Arc2D.OPEN)));
-		Turn.add(new Instr(Form.EARC, new Arc2D.Double(-20.0,-20.0,40.0,40.0,315.0,-280.0,Arc2D.OPEN)));
-		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();
-		p.moveTo(-12.9,0.7); p.lineTo(-1.7,-2.3); p.lineTo(-9.9,-10.5); p.closePath();
-		Turn.add(new Instr(Form.PGON, p));
-	}
-	private static final Symbol Waterbike = new Symbol();
-	static {
-		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);
-		Waterbike.add(new Instr(Form.PLIN, p));
-		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();
-		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();
-		Waterbike.add(new Instr(Form.PGON, p));
-		Waterbike.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		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);
-		Waterbike.add(new Instr(Form.PLIN, p));
-		Waterbike.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		Waterbike.add(new Instr(Form.LINE, new Line2D.Double(-11.5,-10.5,-3,-8.5)));
-		Waterbike.add(new Instr(Form.RSHP, new Ellipse2D.Double(-11.5,-18,5,5)));
-	}
-	private static final Symbol Waterski = new Symbol();
-	static {
-		Waterski.add(new Instr(Form.RSHP, new Ellipse2D.Double(12,-18,6,6)));
-		Waterski.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Waterski.add(new Instr(Form.LINE, new Line2D.Double(-18,-6,0,-6)));
-		Waterski.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		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);
-		Waterski.add(new Instr(Form.PLIN, p));
-		Waterski.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
-		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);
-		Waterski.add(new Instr(Form.PLIN, p));
-	}
-	private static final Symbol NoticeA = new Symbol();
-	static {
-		NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
-		NoticeA.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeA.add(new Instr(Form.FILL, Color.white));
-		NoticeA.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
-		NoticeA.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
-		NoticeA.add(new Instr(Form.LINE, new Line2D.Double(-25,-25,25,25)));
-		NoticeA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeA.add(new Instr(Form.FILL, Color.black));
-		NoticeA.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-	private static final Symbol NoticeB = new Symbol();
-	static {
-		NoticeB.add(new Instr(Form.FILL, new Color(0xe80000)));
-		NoticeB.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeB.add(new Instr(Form.FILL, Color.white));
-		NoticeB.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
-		NoticeB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB.add(new Instr(Form.FILL, Color.black));
-		NoticeB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-	private static final Symbol NoticeE = new Symbol();
-	static {
-		NoticeE.add(new Instr(Form.FILL, new Color(0x0000a0)));
-		NoticeE.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeE.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE.add(new Instr(Form.FILL, Color.black));
-		NoticeE.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeE.add(new Instr(Form.FILL, Color.white));
-	}
-	public static final Symbol Notice = new Symbol();
-	static {
-		Notice.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Notice.add(new Instr(Form.FILL, new Color(0xe80000)));
-		Notice.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		Notice.add(new Instr(Form.FILL, new Color(0x0000a0)));
-		Notice.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21,-21,42,42)));
-		Notice.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Notice.add(new Instr(Form.FILL, Color.black));
-		Notice.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-	public static final Symbol NoticeA1 = new Symbol();
-	static {
-		NoticeA1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA1.add(new Instr(Form.FILL, new Color(0xe80000)));
-		NoticeA1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeA1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeA1.add(new Instr(Form.FILL, Color.white));
-		NoticeA1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-30,-10,60,20)));
-		NoticeA1.add(new Instr(Form.FILL, Color.black));
-		NoticeA1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-	public static final Symbol NoticeA1a = new Symbol();
-	static {
-		NoticeA1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA1a.add(new Instr(Form.FILL, new Color(0xe80000)));
-		NoticeA1a.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30,-30,60,60)));
-		NoticeA1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeA1a.add(new Instr(Form.FILL, Color.white));
-		NoticeA1a.add(new Instr(Form.RSHP, new Rectangle2D.Double(-29,-10,58,20)));
-		NoticeA1a.add(new Instr(Form.FILL, Color.black));
-		NoticeA1a.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
-	}
-	public static final Symbol NoticeA2 = new Symbol();
-	static {
-		NoticeA2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA2.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		NoticeA2.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeA3 = new Symbol();
-	static {
-		NoticeA3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA2, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-10,12); p.lineTo(-6,12); p.lineTo(-12.5,4); p.lineTo(-19,12);
-		p.closePath(); p.moveTo(10,-3); p.lineTo(6,-3); p.lineTo(12.5,-11); p.lineTo(19,-3); p.closePath();
-		NoticeA3.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeA4 = new Symbol();
-	static {
-		NoticeA4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA4.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		NoticeA4.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeA4_1 = new Symbol();
-	static {
-		NoticeA4_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA4_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA4, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-10,-4); p.lineTo(-6,-4); p.lineTo(-12.5,4); p.lineTo(-19,-4);
-		p.closePath(); p.moveTo(10,5); p.lineTo(6,5); p.lineTo(12.5,-3); p.lineTo(19,5); p.closePath();
-		NoticeA4_1.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeA5 = new Symbol();
-	static {
-		NoticeA5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		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);
-		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();
-		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();
-		NoticeA5.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeA5_1 = new Symbol();
-	static {
-		NoticeA5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeA6 = new Symbol();
-	static {
-		NoticeA6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		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))))));
-	}
-	public static final Symbol NoticeA7 = new Symbol();
-	static {
-		NoticeA7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA8 = new Symbol();
-	static {
-		NoticeA8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA9 = new Symbol();
-	static {
-		NoticeA9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA9.add(new Instr(Form.STRK, new BasicStroke(7, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeA9.add(new Instr(Form.FILL, Color.black));
-		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);
-		p.moveTo(-23,-3); p.curveTo(-11,-3,-12,-9,0,-9); p.curveTo(12,-9,11,-3,23,-3);
-		NoticeA9.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeA10a = new Symbol();
-	static {
-		NoticeA10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA10a.add(new Instr(Form.FILL, Color.white));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(30,0); p.lineTo(0,30); p.closePath();
-		NoticeA10a.add(new Instr(Form.PGON, p));
-		NoticeA10a.add(new Instr(Form.FILL, new Color(0xe80000)));
-		p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.closePath();
-		NoticeA10a.add(new Instr(Form.PGON, p));
-		NoticeA10a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeA10a.add(new Instr(Form.FILL, Color.black));
-		p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
-		NoticeA10a.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeA10b = new Symbol();
-	static {
-		NoticeA10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		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))))));
-	}
-	public static final Symbol NoticeA12 = new Symbol();
-	static {
-		NoticeA12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA13 = new Symbol();
-	static {
-		NoticeA13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		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)))));
-	}
-	public static final Symbol NoticeA14 = new Symbol();
-	static {
-		NoticeA14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA15 = new Symbol();
-	static {
-		NoticeA15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA16 = new Symbol();
-	static {
-		NoticeA16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA17 = new Symbol();
-	static {
-		NoticeA17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA18 = new Symbol();
-	static {
-		NoticeA18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA19 = new Symbol();
-	static {
-		NoticeA19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeA20 = new Symbol();
-	static {
-		NoticeA20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
-		NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeB1a = new Symbol();
-	static {
-		NoticeB1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB1a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(21,8); p.lineTo(-8,8); p.lineTo(-8,18); p.lineTo(-21,0);
-		p.lineTo(-8,-18); p.lineTo(-8,-8); p.lineTo(21,-8); p.closePath();
-		NoticeB1a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB1b = new Symbol();
-	static {
-		NoticeB1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB1b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-21,8); p.lineTo(8,8); p.lineTo(8,18); p.lineTo(21,0);
-		p.lineTo(8,-18); p.lineTo(8,-8); p.lineTo(-21,-8); p.closePath();
-		NoticeB1b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB2a = new Symbol();
-	static {
-		NoticeB2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB2a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB2a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(18,21); p.lineTo(18,10); p.lineTo(-15,-10); p.lineTo(-15,-15);
-		NoticeB2a.add(new Instr(Form.PLIN, p));
-		p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(-21,-15); p.lineTo(-9,-15); p.closePath();
-		NoticeB2a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB2b = new Symbol();
-	static {
-		NoticeB2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB2b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-18,21); p.lineTo(-18,10); p.lineTo(15,-10); p.lineTo(15,-15);
-		NoticeB2b.add(new Instr(Form.PLIN, p));
-		p = new Path2D.Double(); p.moveTo(15,-21); p.lineTo(21,-15); p.lineTo(9,-15); p.closePath();
-		NoticeB2b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB3a = new Symbol();
-	static {
-		NoticeB3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(-15,21,-15,-15)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(-21,-15); p.lineTo(-9,-15); p.closePath();
-		NoticeB3a.add(new Instr(Form.PGON, p));
-		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)));
-		NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(15,-21,15,15)));
-		p = new Path2D.Double(); p.moveTo(15,21); p.lineTo(21,15); p.lineTo(9,15); p.closePath();
-		NoticeB3a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB3b = new Symbol();
-	static {
-		NoticeB3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(15,21,15,-15)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(15,-21); p.lineTo(21,-15); p.lineTo(9,-15); p.closePath();
-		NoticeB3b.add(new Instr(Form.PGON, p));
-		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)));
-		NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(-15,-21,-15,15)));
-		p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(-21,15); p.lineTo(-9,15); p.closePath();
-		NoticeB3b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB4a = new Symbol();
-	static {
-		NoticeB4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2a, 1.0, 0, 0, null, null)));
-		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)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(18,-21); p.lineTo(18,-10); p.lineTo(-15,10); p.lineTo(-15,15);
-		NoticeB4a.add(new Instr(Form.PLIN, p));
-		p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(-21,15); p.lineTo(-9,15); p.closePath();
-		NoticeB4a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB4b = new Symbol();
-	static {
-		NoticeB4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2b, 1.0, 0, 0, null, null)));
-		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)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-18,-21); p.lineTo(-18,-10); p.lineTo(15,10); p.lineTo(15,15);
-		NoticeB4b.add(new Instr(Form.PLIN, p));
-		p = new Path2D.Double(); p.moveTo(15,21); p.lineTo(21,15); p.lineTo(9,15); p.closePath();
-		NoticeB4b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeB5 = new Symbol();
-	static {
-		NoticeB5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB5.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		NoticeB5.add(new Instr(Form.LINE, new Line2D.Double(15,0,-15,0)));
-	}
-	public static final Symbol NoticeB6 = new Symbol();
-	static {
-		NoticeB6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeB7 = new Symbol();
-	static {
-		NoticeB7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB7.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10,-10,20,20)));
-	}
-	public static final Symbol NoticeB8 = new Symbol();
-	static {
-		NoticeB8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB8.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		NoticeB8.add(new Instr(Form.LINE, new Line2D.Double(0,15,0,-15)));
-	}
-	public static final Symbol NoticeB9a = new Symbol();
-	static {
-		NoticeB9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(-21,0,21,0)));
-		NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(0,21,0,0)));
-	}
-	public static final Symbol NoticeB9b = new Symbol();
-	static {
-		NoticeB9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(-21,0,21,0)));
-		NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(0,21,0,-21)));
-	}
-	public static final Symbol NoticeB11 = new Symbol();
-	static {
-		NoticeB11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeB11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		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)))));
-	}
-	public static final Symbol NoticeC1 = new Symbol();
-	static {
-		NoticeC1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15,21); p.lineTo(0,12); p.lineTo(15,21); p.closePath();
-		NoticeC1.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeC2 = new Symbol();
-	static {
-		NoticeC2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15,-21); p.lineTo(0,-12); p.lineTo(15,-21); p.closePath();
-		NoticeC2.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeC3 = new Symbol();
-	static {
-		NoticeC3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(21,-15); p.lineTo(12,0); p.lineTo(21,15); p.closePath();
-		p.moveTo(-21,-15); p.lineTo(-12,0); p.lineTo(-21,15); p.closePath();
-		NoticeC3.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeC4 = new Symbol();
-	static {
-		NoticeC4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeC5a = new Symbol();
-	static {
-		NoticeC5a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC5a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		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();
-		NoticeC5a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeC5b = new Symbol();
-	static {
-		NoticeC5b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeC5b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
-		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();
-		NoticeC5b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeD1a = new Symbol();
-	static {
-		NoticeD1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeD1a.add(new Instr(Form.FILL, Color.yellow));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
-		NoticeD1a.add(new Instr(Form.PGON, p));
-		NoticeD1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeD1a.add(new Instr(Form.FILL, Color.black));
-		NoticeD1a.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeD1b = new Symbol();
-	static {
-		NoticeD1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeD1b.add(new Instr(Form.FILL, Color.yellow));
-		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();
-		NoticeD1b.add(new Instr(Form.PGON, p));
-		NoticeD1b.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeD1b.add(new Instr(Form.FILL, Color.black));
-		NoticeD1b.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeD2a = new Symbol();
-	static {
-		NoticeD2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeD2a.add(new Instr(Form.FILL, Color.white));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.closePath();
-		NoticeD2a.add(new Instr(Form.PGON, p));
-		NoticeD2a.add(new Instr(Form.FILL, new Color(0x00e800)));
-		p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(30,0); p.lineTo(0,30); p.closePath();
-		NoticeD2a.add(new Instr(Form.PGON, p));
-		NoticeD2a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeD2a.add(new Instr(Form.FILL, Color.black));
-		p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,0); p.lineTo(0,30); p.lineTo(30,0); p.closePath();
-		NoticeD2a.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeD2b = new Symbol();
-	static {
-		NoticeD2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		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))))));
-	}
-	public static final Symbol NoticeD3a = new Symbol();
-	static {
-		NoticeD3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeD3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(28,10); p.lineTo(-10,10); p.lineTo(-10,20); p.lineTo(-28,0);
-		p.lineTo(-10,-20); p.lineTo(-10,-10); p.lineTo(28,-10); p.closePath();
-		NoticeD3a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeD3b = new Symbol();
-	static {
-		NoticeD3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeD3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-28,10); p.lineTo(10,10); p.lineTo(10,20); p.lineTo(28,0);
-		p.lineTo(10,-20); p.lineTo(10,-10); p.lineTo(-28,-10); p.closePath();
-		NoticeD3b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE1 = new Symbol();
-	static {
-		NoticeE1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE1.add(new Instr(Form.FILL, new Color(0x00e800)));
-		NoticeE1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeE1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE1.add(new Instr(Form.FILL, Color.white));
-		NoticeE1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-10,-30,20,60)));
-		NoticeE1.add(new Instr(Form.FILL, Color.black));
-		NoticeE1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-	public static final Symbol NoticeE2 = new Symbol();
-	static {
-		NoticeE2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(5,-25); p.lineTo(-10,-1); p.lineTo(10,-1); p.lineTo(-10,20);
-		p.lineTo(-7,20); p.lineTo(-12,25); p.lineTo(-16,20); p.lineTo(-13,20); p.lineTo(4,1); p.lineTo(-14,1);
-		p.lineTo(2,-25); p.closePath();
-		NoticeE2.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE3 = new Symbol();
-	static {
-		NoticeE3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE3.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(25,-20,25,20)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-25,-20,-25,20)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-15,-15,-15,20)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-5,-15,-5,20)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(5,-15,5,20)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(15,-15,15,20)));
-		NoticeE3.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26,18.5,26,18.5)));
-		NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26,-15,26,-15)));
-	}
-	public static final Symbol NoticeE4a = new Symbol();
-	static {
-		NoticeE4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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);
-		p.lineTo(20,-10); p.lineTo(15,0); p.lineTo(-15,0); p.closePath();
-		p.moveTo(-25,5); p.lineTo(25,5); p.lineTo(25,10); p.lineTo(-25,10); p.closePath();
-		NoticeE4a.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE4b = new Symbol();
-	static {
-		NoticeE4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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);
-		p.lineTo(20,0); p.lineTo(15,10); p.lineTo(-15,10); p.closePath();
-		NoticeE4b.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5 = new Symbol();
-	static {
-		NoticeE5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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);
-		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();
-		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();
-		NoticeE5.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_1 = new Symbol();
-	static {
-		NoticeE5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeE5_2 = new Symbol();
-	static {
-		NoticeE5_2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeE5_3 = new Symbol();
-	static {
-		NoticeE5_3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeE5_4 = new Symbol();
-	static {
-		NoticeE5_4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
-		NoticeE5_4.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_5 = new Symbol();
-	static {
-		NoticeE5_5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
-		p.moveTo(0,24); p.lineTo(-15,2); p.lineTo(15,2); p.closePath();
-		NoticeE5_5.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_6 = new Symbol();
-	static {
-		NoticeE5_6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
-		p.moveTo(0,7); p.lineTo(-10,-8); p.lineTo(10,-8); p.closePath();
-		p.moveTo(0,24); p.lineTo(-10,9); p.lineTo(10,9); p.closePath();
-		NoticeE5_6.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_7 = new Symbol();
-	static {
-		NoticeE5_7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,25); p.lineTo(0,-28); p.lineTo(28,25); p.closePath();
-		p.moveTo(0,-1); p.lineTo(-8,-11); p.lineTo(8,-11); p.closePath();
-		p.moveTo(0,11); p.lineTo(-8,1); p.lineTo(8,1); p.closePath();
-		p.moveTo(0,23); p.lineTo(-8,13); p.lineTo(8,13); p.closePath();
-		NoticeE5_7.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_8 = new Symbol();
-	static {
-		NoticeE5_8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
-		NoticeE5_8.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_9 = new Symbol();
-	static {
-		NoticeE5_9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
-		p.moveTo(0,8); p.lineTo(-15,-14); p.lineTo(15,-14); p.closePath();
-		NoticeE5_9.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_10 = new Symbol();
-	static {
-		NoticeE5_10.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_10.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
-		p.moveTo(0,-5); p.lineTo(-10,-20); p.lineTo(10,-20); p.closePath();
-		p.moveTo(0,15); p.lineTo(-10,0); p.lineTo(10,0); p.closePath();
-		NoticeE5_10.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_11 = new Symbol();
-	static {
-		NoticeE5_11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,-25); p.lineTo(0,28); p.lineTo(28,-25); p.closePath();
-		p.moveTo(0,-12); p.lineTo(-8,-22); p.lineTo(8,-22); p.closePath();
-		p.moveTo(0,3); p.lineTo(-8,-7); p.lineTo(8,-7); p.closePath();
-		p.moveTo(0,18); p.lineTo(-8,8); p.lineTo(8,8); p.closePath();
-		NoticeE5_11.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_12 = new Symbol();
-	static {
-		NoticeE5_12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
-		NoticeE5_12.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_13 = new Symbol();
-	static {
-		NoticeE5_13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
-		p.moveTo(0,15); p.lineTo(-15,-7); p.lineTo(15,-7); p.closePath();
-		NoticeE5_13.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_14 = new Symbol();
-	static {
-		NoticeE5_14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
-		p.moveTo(0,0); p.lineTo(-10,-15); p.lineTo(10,-15); p.closePath();
-		p.moveTo(0,20); p.lineTo(-10,5); p.lineTo(10,5); p.closePath();
-		NoticeE5_14.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE5_15 = new Symbol();
-	static {
-		NoticeE5_15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE5_15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-28,0); p.lineTo(0,28); p.lineTo(28,0); p.lineTo(0,-28); p.closePath();
-		p.moveTo(0,-7); p.lineTo(-8,-17); p.lineTo(8,-17); p.closePath();
-		p.moveTo(0,8); p.lineTo(-8,-2); p.lineTo(8,-2); p.closePath();
-		p.moveTo(0,23); p.lineTo(-8,13); p.lineTo(8,13); p.closePath();
-		NoticeE5_15.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE6 = new Symbol();
-	static {
-		NoticeE6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE7 = new Symbol();
-	static {
-		NoticeE7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE7_1 = new Symbol();
-	static {
-		NoticeE7_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE7_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20,25,20,-10)));
-		NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(22,-8,-15,-20)));
-		NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20,8,0,-15)));
-		Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		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);
-		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();
-		p.moveTo(-15,4); p.quadTo(-3,2,5,4); p.lineTo(6,11); p.quadTo(-5,9,-16,11); p.closePath();
-		NoticeE7_1.add(new Instr(Form.PGON, p));
-		NoticeE7_1.add(new Instr(Form.FILL, new Color(0x0000a0)));
-		NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(-16,13,4,4)));
-		NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(2,13,4,4)));
-	}
-	public static final Symbol NoticeE8 = new Symbol();
-	static {
-		NoticeE8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE9a = new Symbol();
-	static {
-		NoticeE9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
-		NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
-	}
-	public static final Symbol NoticeE9b = new Symbol();
-	static {
-		NoticeE9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
-		NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
-	}
-	public static final Symbol NoticeE9c = new Symbol();
-	static {
-		NoticeE9c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
-		NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
-	}
-	public static final Symbol NoticeE9d = new Symbol();
-	static {
-		NoticeE9d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
-		NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
-	}
-	public static final Symbol NoticeE9e = new Symbol();
-	static {
-		NoticeE9e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
-		NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
-	}
-	public static final Symbol NoticeE9f = new Symbol();
-	static {
-		NoticeE9f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
-		NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
-	}
-	public static final Symbol NoticeE9g = new Symbol();
-	static {
-		NoticeE9g.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9g.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
-		NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
-	}
-	public static final Symbol NoticeE9h = new Symbol();
-	static {
-		NoticeE9h.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9h.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
-		NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
-		NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
-	}
-	public static final Symbol NoticeE9i = new Symbol();
-	static {
-		NoticeE9i.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE9i.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-4)));
-		NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
-		NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,2)));
-		NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
-	}
-	public static final Symbol NoticeE10a = new Symbol();
-	static {
-		NoticeE10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE10a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
-		NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-29)));
-	}
-	public static final Symbol NoticeE10b = new Symbol();
-	static {
-		NoticeE10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(-29,0,29,0)));
-		NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
-	}
-	public static final Symbol NoticeE10c = new Symbol();
-	static {
-		NoticeE10c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE10c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
-		NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
-		NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
-	}
-	public static final Symbol NoticeE10d = new Symbol();
-	static {
-		NoticeE10d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE10d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
-		NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
-		NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
-	}
-	public static final Symbol NoticeE10e = new Symbol();
-	static {
-	NoticeE10e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-	NoticeE10e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-	NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-	NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
-	NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(-4,0,29,0)));
-	NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-	NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
-	NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(2,0,-29,0)));
-	}
-	public static final Symbol NoticeE10f = new Symbol();
-	static {
-		NoticeE10f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE10f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0,-29,0,4)));
-		NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(4,0,-29,0)));
-		NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0,29,0,-2)));
-		NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(-2,0,29,0)));
-	}
-	public static final Symbol NoticeE11 = new Symbol();
-	static {
-		NoticeE11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE11.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
-		NoticeE11.add(new Instr(Form.LINE, new Line2D.Double(-27,-27,27,27)));
-	}
-	public static final Symbol NoticeE13 = new Symbol();
-	static {
-		NoticeE13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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);
-		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);
-		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);
-		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);
-		p.lineTo(1.5,-7); p.lineTo(1.5,-14); p.lineTo(-4,-14); p.closePath();
-		NoticeE13.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE14 = new Symbol();
-	static {
-		NoticeE14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-18,-18); p.lineTo(-11,-7); p.lineTo(-9,-10); p.lineTo(-14,-18); p.closePath();
-		p.moveTo(9.5,7); p.lineTo(22.5,9); p.lineTo(21.5,5.5); p.lineTo(12,4); p.closePath();
-		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);
-		p.curveTo(15.5,23,1,18.5,-9,12); p.curveTo(-18,6,-28.5,-7,-19,-16.5); p.closePath();
-		NoticeE14.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeE15 = new Symbol();
-	static {
-		NoticeE15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE16 = new Symbol();
-	static {
-		NoticeE16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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)))));
-	}
-	public static final Symbol NoticeE17 = new Symbol();
-	static {
-		NoticeE17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE18 = new Symbol();
-	static {
-		NoticeE18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE19 = new Symbol();
-	static {
-		NoticeE19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE20 = new Symbol();
-	static {
-		NoticeE20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE21 = new Symbol();
-	static {
-		NoticeE21.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE22 = new Symbol();
-	static {
-		NoticeE22.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-	public static final Symbol NoticeE23 = new Symbol();
-	static {
-		NoticeE23.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE23.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		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)))));
-	}
-	public static final Symbol NoticeE24 = new Symbol();
-	static {
-		NoticeE24.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
-		NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.white), null)));
-	}
-
-	public static final Symbol NoticeBoard = new Symbol();
-	static {
-		NoticeBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,30)));
-		NoticeBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-20,0); p.lineTo(20,0); p.lineTo(20,-15); p.lineTo(-20,-15); p.closePath();
-		NoticeBoard.add(new Instr(Form.FILL, Color.white));
-		NoticeBoard.add(new Instr(Form.PGON, p));
-		NoticeBoard.add(new Instr(Form.FILL, Color.black));
-		NoticeBoard.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeTriangle = new Symbol();
-	static {
-		NoticeTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,30)));
-		NoticeTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-20,0); p.lineTo(20,0); p.lineTo(0,-15); p.closePath();
-		NoticeTriangle.add(new Instr(Form.FILL, Color.white));
-		NoticeTriangle.add(new Instr(Form.PGON, p));
-		NoticeTriangle.add(new Instr(Form.FILL, Color.black));
-		NoticeTriangle.add(new Instr(Form.PLIN, p));
-	}
-
-	public static final EnumMap<CatNMK, Symbol> NmkCevni = new EnumMap<>(CatNMK.class);
-	static {
-		NmkCevni.put(CatNMK.NMK_UNKN, Notice); NmkCevni.put(CatNMK.NMK_NENT, NoticeA1); NmkCevni.put(CatNMK.NMK_CLSA, NoticeA1a); NmkCevni.put(CatNMK.NMK_NOVK, NoticeA2);
-		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);
-		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);
-		NmkCevni.put(CatNMK.NMK_NWSH, NoticeA9); NmkCevni.put(CatNMK.NMK_NPSL, NoticeA10a); NmkCevni.put(CatNMK.NMK_NPSR, NoticeA10b); NmkCevni.put(CatNMK.NMK_NMTC, NoticeA12);
-		NmkCevni.put(CatNMK.NMK_NSPC, NoticeA13); NmkCevni.put(CatNMK.NMK_NWSK, NoticeA14); NmkCevni.put(CatNMK.NMK_NSLC, NoticeA15); NmkCevni.put(CatNMK.NMK_NUPC, NoticeA16);
-		NmkCevni.put(CatNMK.NMK_NSLB, NoticeA17); NmkCevni.put(CatNMK.NMK_NWBK, NoticeA20); NmkCevni.put(CatNMK.NMK_NHSC, NoticeA18); NmkCevni.put(CatNMK.NMK_NLBG, NoticeA19);
-		NmkCevni.put(CatNMK.NMK_MVTL, NoticeB1a); NmkCevni.put(CatNMK.NMK_MVTR, NoticeB1b); NmkCevni.put(CatNMK.NMK_MVTP, NoticeB2a); NmkCevni.put(CatNMK.NMK_MVTS, NoticeB2b);
-		NmkCevni.put(CatNMK.NMK_KPTP, NoticeB3a); NmkCevni.put(CatNMK.NMK_KPTS, NoticeB3b); NmkCevni.put(CatNMK.NMK_CSTP, NoticeB4a); NmkCevni.put(CatNMK.NMK_CSTS, NoticeB4b);
-		NmkCevni.put(CatNMK.NMK_STOP, NoticeB5); NmkCevni.put(CatNMK.NMK_SPDL, NoticeB6); NmkCevni.put(CatNMK.NMK_SHRN, NoticeB7); NmkCevni.put(CatNMK.NMK_KPLO, NoticeB8);
-		NmkCevni.put(CatNMK.NMK_GWJN, NoticeB9a); NmkCevni.put(CatNMK.NMK_GWCS, NoticeB9b); NmkCevni.put(CatNMK.NMK_MKRC, NoticeB11);
-		NmkCevni.put(CatNMK.NMK_LMDP, NoticeC1); NmkCevni.put(CatNMK.NMK_LMHR, NoticeC2);	NmkCevni.put(CatNMK.NMK_LMWD, NoticeC3); NmkCevni.put(CatNMK.NMK_NAVR, NoticeC4);
-		NmkCevni.put(CatNMK.NMK_CHDL, NoticeC5a); NmkCevni.put(CatNMK.NMK_CHDR, NoticeC5b);
-		NmkCevni.put(CatNMK.NMK_CHTW, NoticeD1a); NmkCevni.put(CatNMK.NMK_CHOW, NoticeD1b); NmkCevni.put(CatNMK.NMK_OPTR, NoticeD2a); NmkCevni.put(CatNMK.NMK_OPTL, NoticeD2b);
-		NmkCevni.put(CatNMK.NMK_PRTL, NoticeD3a); NmkCevni.put(CatNMK.NMK_PRTR, NoticeD3b);
-		NmkCevni.put(CatNMK.NMK_ENTP, NoticeE1); NmkCevni.put(CatNMK.NMK_OVHC, NoticeE2);	NmkCevni.put(CatNMK.NMK_WEIR, NoticeE3); NmkCevni.put(CatNMK.NMK_FERN, NoticeE4a);
-		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);
-		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);
-		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);
-		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);
-		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);
-		NmkCevni.put(CatNMK.NMK_TRNA, NoticeE8); NmkCevni.put(CatNMK.NMK_SWWC, NoticeE9a);	NmkCevni.put(CatNMK.NMK_SWWR, NoticeE9b); NmkCevni.put(CatNMK.NMK_SWWL, NoticeE9c);
-		NmkCevni.put(CatNMK.NMK_WRSA, NoticeE9d); NmkCevni.put(CatNMK.NMK_WLSA, NoticeE9e);	NmkCevni.put(CatNMK.NMK_WRSL, NoticeE9f); NmkCevni.put(CatNMK.NMK_WLSR, NoticeE9g);
-		NmkCevni.put(CatNMK.NMK_WRAL, NoticeE9h); NmkCevni.put(CatNMK.NMK_WLAR, NoticeE9i);	NmkCevni.put(CatNMK.NMK_MWWC, NoticeE10a); NmkCevni.put(CatNMK.NMK_MWWJ, NoticeE10b);
-		NmkCevni.put(CatNMK.NMK_MWAR, NoticeE10c); NmkCevni.put(CatNMK.NMK_MWAL, NoticeE10d);	NmkCevni.put(CatNMK.NMK_WARL, NoticeE10e); NmkCevni.put(CatNMK.NMK_WALR, NoticeE10f);
-		NmkCevni.put(CatNMK.NMK_PEND, NoticeE11); NmkCevni.put(CatNMK.NMK_DWTR, NoticeE13);	NmkCevni.put(CatNMK.NMK_TELE, NoticeE14); NmkCevni.put(CatNMK.NMK_MTCP, NoticeE15);
-		NmkCevni.put(CatNMK.NMK_SPCP, NoticeE16); NmkCevni.put(CatNMK.NMK_WSKP, NoticeE17);	NmkCevni.put(CatNMK.NMK_SLCP, NoticeE18); NmkCevni.put(CatNMK.NMK_UPCP, NoticeE19);
-		NmkCevni.put(CatNMK.NMK_SLBP, NoticeE20); NmkCevni.put(CatNMK.NMK_RADI, NoticeE23);	NmkCevni.put(CatNMK.NMK_WTBP, NoticeE24); NmkCevni.put(CatNMK.NMK_HSCP, NoticeE21);
-		NmkCevni.put(CatNMK.NMK_LBGP, NoticeE22);
-  };
-
-  private static final Symbol NoticeBB = new Symbol();
-  static {
-  	NoticeBB.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(-29,-29,-29,29)));
-  	NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(29,-29,29,29)));
-  	NoticeBB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	NoticeBB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-  }
-  
-  private static final Symbol NoticeBP = new Symbol();
-	static {
-		NoticeBP.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeBP.add(new Instr(Form.FILL, Color.white));
-		NoticeBP.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeBP.add(new Instr(Form.FILL, Color.black));
-		NoticeBP.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-	}
-
-  private static final Symbol NoticeCR = new Symbol();
-	static {
-		NoticeCR.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeCR.add(new Instr(Form.FILL, Color.white));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
-		NoticeCR.add(new Instr(Form.PGON, p));
-		NoticeCR.add(new Instr(Form.FILL, Color.black));
-		NoticeCR.add(new Instr(Form.PLIN, p));
-	}
-
-  private static final Symbol NoticeKT = new Symbol();
-	static {
-		NoticeKT.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeKT.add(new Instr(Form.FILL, Color.white));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
-		NoticeKT.add(new Instr(Form.PGON, p));
-		NoticeKT.add(new Instr(Form.FILL, Color.black));
-		NoticeKT.add(new Instr(Form.PLIN, p));
-	}
-
-	public static final Symbol NoticeBnank = new Symbol();
-	static {
-		NoticeBnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
-		ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		ss.add(new Instr(Form.LINE, new Line2D.Double(-27,-27,27,27)));
-		ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBnank.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBlmhr = new Symbol();
-	static {
-		NoticeBlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-29,-29); p.lineTo(29,-29); p.lineTo(0,0); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-		ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBlmhr.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBktpm = new Symbol();
-	static {
-		NoticeBktpm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-14,-26); p.lineTo(-20,-12); p.lineTo(-8,-12); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	ss.add(new Instr(Form.LINE, new Line2D.Double(-14,-16,-14,25)));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBktpm.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBktsm = new Symbol();
-	static {
-		NoticeBktsm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(14,-26); p.lineTo(20,-12); p.lineTo(8,-12); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	ss.add(new Instr(Form.LINE, new Line2D.Double(14,-16,14,25)));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBktsm.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBktmr = new Symbol();
-	static {
-		NoticeBktmr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-26); p.lineTo(-6,-12); p.lineTo(6,-12); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	ss.add(new Instr(Form.LINE, new Line2D.Double(0,-16,0,25)));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBktmr.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBcrtp = new Symbol();
-	static {
-		NoticeBcrtp.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-14,-26); p.lineTo(-20,-12); p.lineTo(-8,-12); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(-14,-16); p.lineTo(-14,0); p.lineTo(14,10); p.lineTo(14,25);
-		ss.add(new Instr(Form.PLIN, p));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBcrtp.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBcrts = new Symbol();
-	static {
-		NoticeBcrts.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(14,-26); p.lineTo(20,-12); p.lineTo(8,-12); p.closePath();
-		ss.add(new Instr(Form.PGON, p));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(14,-16); p.lineTo(14,0); p.lineTo(-14,10); p.lineTo(-14,25);
-		ss.add(new Instr(Form.PLIN, p));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBcrts.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBtrbm = new Symbol();
-	static {
-		NoticeBtrbm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-  	ss.add(new Instr(Form.STRK, new BasicStroke(15, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	ss.add(new Instr(Form.LINE, new Line2D.Double(0,-25,0,25)));
-  	ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-  	ss.add(new Instr(Form.LINE, new Line2D.Double(-20,0,20,0)));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBtrbm.add(new Instr(Form.COLR, colours));
-	}
-	public static final Symbol NoticeBrspd = new Symbol();
-	static {
-		NoticeBrspd.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		Symbol colours = new Symbol();
-		Symbol ss = new Symbol();
-		ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		colours.add(new Instr(Form.N1, ss));
-		ss = new Symbol();
-		ss.add(new Instr(Form.TEXT, new Caption("R", new Font("Arial", Font.BOLD, 60), null, new Delta(Handle.CC, null))));
-		ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
-		colours.add(new Instr(Form.N2, ss));
-		NoticeBrspd.add(new Instr(Form.COLR, colours));
-	}
-	static final Symbol NoticePBwral = new Symbol();
-	static {
-		NoticePBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePBwral.add(new Instr(Form.FILL, new Color(0xffff00)));
-		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);
-		p.lineTo(20,-25); p.lineTo(5,-25); p.lineTo(-5,-10); p.lineTo(-15,-25); p.closePath();
-		NoticePBwral.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeBwral = new Symbol();
-	static {
-		NoticeBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeBwral.add(new Instr(Form.FILL, Color.black));
-		NoticeBwral.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeBwral.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticeBwlar = new Symbol();
-	static {
-		NoticeBwlar.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeBwlar.add(new Instr(Form.FILL, Color.black));
-		NoticeBwlar.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30,-30,60,60,4,4)));
-		NoticeBwlar.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getScaleInstance(-1, 1)))));
-	}
-	public static final Symbol NoticeBoptr = new Symbol();
-	static {
-		NoticeBoptr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeBoptr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
-		NoticeBoptr.add(new Instr(Form.FILL, new Color(0x00a000)));
-		NoticeBoptr.add(new Instr(Form.RSHP, new Rectangle2D.Double(-20,-20,40,40)));
-	}
-	public static final Symbol NoticeBoptl = new Symbol();
-	static {
-		NoticeBoptl.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeBoptl.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
-		NoticeBoptl.add(new Instr(Form.FILL, new Color(0xf00000)));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-20); p.lineTo(-20,20); p.lineTo(20,20); p.closePath();
-		NoticeBoptl.add(new Instr(Form.PGON, p));
-	}
-	public static final EnumMap<CatNMK, Symbol> NmkBniwr = new EnumMap<>(CatNMK.class);
-	static {
-		NmkBniwr.put(CatNMK.NMK_NANK, NoticeBnank); NmkBniwr.put(CatNMK.NMK_LMHR, NoticeBlmhr); NmkBniwr.put(CatNMK.NMK_OPTR, NoticeBoptr); NmkBniwr.put(CatNMK.NMK_OPTL, NoticeBoptl);
-		NmkBniwr.put(CatNMK.NMK_WRAL, NoticeBwral); NmkBniwr.put(CatNMK.NMK_WLAR, NoticeBwlar); NmkBniwr.put(CatNMK.NMK_KTPM, NoticeBktpm); NmkBniwr.put(CatNMK.NMK_KTSM, NoticeBktsm);
-		NmkBniwr.put(CatNMK.NMK_KTMR, NoticeBktmr); NmkBniwr.put(CatNMK.NMK_CRTP, NoticeBcrtp); NmkBniwr.put(CatNMK.NMK_CRTS, NoticeBcrts); NmkBniwr.put(CatNMK.NMK_TRBM, NoticeBtrbm);
-		NmkBniwr.put(CatNMK.NMK_RSPD, NoticeBrspd);
-	}
-	public static final Symbol NoticePwralL = new Symbol();
-	static {
-		NoticePwralL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePwralL.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
-		NoticePwralL.add(new Instr(Form.PGON, p));
-		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)))));
-	}
-	public static final Symbol NoticePwralR = new Symbol();
-	static {
-		NoticePwralR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePwralR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwral, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticePwlarL = new Symbol();
-	static {
-		NoticePwlarL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePwlarL.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(-30,30); p.lineTo(30,30); p.closePath();
-		NoticePwlarL.add(new Instr(Form.PGON, p));
-		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)))));
-	}
-	public static final Symbol NoticePwlarR = new Symbol();
-	static {
-		NoticePwlarR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePwlarR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwlar, 1.0, 0, 0, null, null)));
-	}
-	public static final Symbol NoticePktmR = new Symbol();
-	static {
-		NoticePktmR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePktmR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
-		NoticePktmR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePktmR.add(new Instr(Form.FILL, new Color(0x00d400)));
-		NoticePktmR.add(new Instr(Form.RECT, new Rectangle2D.Double(-20,-20,40,40)));
-	}
-	public static final Symbol NoticePktmL = new Symbol();
-	static {
-		NoticePktmL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePktmL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
-		NoticePktmL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePktmL.add(new Instr(Form.FILL, new Color(0xd40000)));
-		NoticePktmL.add(new Instr(Form.RECT, new Rectangle2D.Double(-12,2,24,24)));
-	}
-	public static final Symbol NoticePktmrL = new Symbol();
-	static {
-		NoticePktmrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePktmrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
-		NoticePktmrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePktmrL.add(new Instr(Form.FILL, new Color(0xd40000)));
-		NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12,2,-12,28)));
-		NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(12,2,12,28)));
-		NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12,15,12,15)));
-	}
-	public static final Symbol NoticePktmrR = new Symbol();
-	static {
-		NoticePktmrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePktmrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
-		NoticePktmrR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePktmrR.add(new Instr(Form.FILL, new Color(0x00d400)));
-		NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15,-20,-15,20)));
-		NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(15,-20,15,20)));
-		NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15,0,15,0)));
-	}
-	public static final Symbol NoticePcrL = new Symbol();
-	static {
-		NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePcrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
-		NoticePcrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePcrL.add(new Instr(Form.FILL, new Color(0xd40000)));
-		NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,12,12)));
-		NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12,12,12,-12)));
-	}
-	public static final Symbol NoticePcrR = new Symbol();
-	static {
-		NoticePcrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticePcrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
-		NoticePcrR.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticePcrR.add(new Instr(Form.FILL, new Color(0x00d400)));
-		NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,12,12)));
-		NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12,12,12,-12)));
-	}
-	static final Symbol NoticeRphib = new Symbol();
-	static {
-		NoticeRphib.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeRphib.add(new Instr(Form.FILL, new Color(0xd40000)));
-		NoticeRphib.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30,-30,60,60)));
-		NoticeRphib.add(new Instr(Form.LINE, new Line2D.Double(-20,-20,20,20)));
-	}
-	static final Symbol NoticeRinfo = new Symbol();
-	static {
-		NoticeRinfo.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeRinfo.add(new Instr(Form.FILL, new Color(0xd40000)));
-		NoticeRinfo.add(new Instr(Form.RECT, new Rectangle2D.Double(-30,-30,60,60)));
-	}
-	public static final Symbol NoticeRnpas = new Symbol();
-	static {
-		NoticeRnpas.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRnpas.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
-		NoticeRnpas.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		NoticeRnpas.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRnank = new Symbol();
-	static {
-		NoticeRnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
-		NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), null)));
-	}
-	public static final Symbol NoticeRnwsh = new Symbol();
-	static {
-		NoticeRnwsh.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRnwsh.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
-		NoticeRnwsh.add(new Instr(Form.FILL, Color.black));
-		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);
-		p.moveTo(-23,-3); p.curveTo(-11,-3,-12,-9,0,-9); p.curveTo(12,-9,11,-3,23,-3);
-		NoticeRnwsh.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol NoticeRlmhr = new Symbol();
-	static {
-		NoticeRlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRlmhr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
-		NoticeRlmhr.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-10); p.lineTo(27,-27); p.lineTo(-27,-27); p.closePath();
-		NoticeRlmhr.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRtrna = new Symbol();
-	static {
-		NoticeRtrna.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRtrna.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
-		NoticeRtrna.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeRtrna.add(new Instr(Form.EARC, new Arc2D.Double(-15.0,-15.0,30.0,30.0,315.0,-280.0,Arc2D.OPEN)));
-		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();
-		NoticeRtrna.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRncps = new Symbol();
-	static {
-		NoticeRncps.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRncps.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
-		NoticeRncps.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		NoticeRncps.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRnsmc = new Symbol();
-	static {
-		NoticeRnsmc.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRnsmc.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
-		NoticeRnsmc.add(new Instr(Form.FILL, Color.black));
-		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();
-		p.moveTo(-23,2); p.lineTo(-21,10); p.lineTo(-18,8); p.lineTo(-20,0); p.closePath();
-		NoticeRnsmc.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRattn = new Symbol();
-	static {
-		NoticeRattn.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRattn.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
-		NoticeRattn.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		NoticeRattn.add(new Instr(Form.FILL, Color.black));
-		NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0,-20,0,10)));
-		NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0,15,0,20)));
-	}
-	public static final Symbol NoticeRfwcr = new Symbol();
-	static {
-		NoticeRfwcr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRfwcr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
-		NoticeRfwcr.add(new Instr(Form.FILL, Color.black));
-		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);
-		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();
-		NoticeRfwcr.add(new Instr(Form.PGON, p));
-	}
-	public static final Symbol NoticeRship = new Symbol();
-	static {
-		NoticeRship.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-30,60,60)));
-		NoticeRship.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
-		NoticeRship.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
-		NoticeRship.add(new Instr(Form.FILL, Color.black));
-		NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12,-12,10,10)));
-		NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12,-8,-8,-12)));
-		NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12,-12,-10,10)));
-		NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12,-8,8,-12)));
-		NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-17,-13,30,30,185,80,Arc2D.OPEN)));
-		NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-13,-13,30,30,275,80,Arc2D.OPEN)));
-	}
-
-	public static final EnumMap<CatNMK, Symbol> NmkPpwbcl = new EnumMap<>(CatNMK.class);
-	static {
-		NmkPpwbcl.put(CatNMK.NMK_WRAL, NoticePwralL); NmkPpwbcl.put(CatNMK.NMK_WLAR, NoticePwlarL); NmkPpwbcl.put(CatNMK.NMK_KTPM, NoticePktmL); NmkPpwbcl.put(CatNMK.NMK_KTSM, NoticePktmL);
-		NmkPpwbcl.put(CatNMK.NMK_KTMR, NoticePktmrL); NmkPpwbcl.put(CatNMK.NMK_CRTP, NoticePcrL); NmkPpwbcl.put(CatNMK.NMK_CRTS, NoticePcrL);
-	}
-	
-	public static final EnumMap<CatNMK, Symbol> NmkPpwbcr = new EnumMap<>(CatNMK.class);
-	static {
-		NmkPpwbcr.put(CatNMK.NMK_WRAL, NoticePwralR); NmkPpwbcr.put(CatNMK.NMK_WLAR, NoticePwlarR); NmkPpwbcr.put(CatNMK.NMK_KTPM, NoticePktmR); NmkPpwbcr.put(CatNMK.NMK_KTSM, NoticePktmR);
-		NmkPpwbcr.put(CatNMK.NMK_KTMR, NoticePktmrR); NmkPpwbcr.put(CatNMK.NMK_CRTP, NoticePcrR); NmkPpwbcr.put(CatNMK.NMK_CRTS, NoticePcrR);
-	}
-	
-	public static final EnumMap<CatNMK, Symbol> NmkRiwr = new EnumMap<>(CatNMK.class);
-	static {
-		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);
-		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);
-	}
-	
-	public static Scheme getScheme(MarSYS sys, BnkWTW bank) {
-		ArrayList<Color> colours = new ArrayList<>();
-		Scheme scheme = new Scheme(colours);
-		switch (sys) {
-		case SYS_BNWR:
-		case SYS_BWR2:
-			switch (bank) {
-			case BWW_LEFT:
-				colours.add(Color.white);
-				colours.add(new Color(0xf00000));
-				break;
-			case BWW_RGHT:
-				colours.add(Color.white);
-				colours.add(new Color(0x00a000));
-				break;
-			default:
-				colours.add(new Color(0xff8040));
-				colours.add(Color.black);
-				break;
-			}
-			break;
-		default:
-			break;
-		}
-		return scheme;
-	}
-	
-	public static Symbol getNotice(CatNMK cat, MarSYS sys, BnkWTW bank) {
-		Symbol symbol = null;
-		switch (sys) {
-		case SYS_CEVN:
-			symbol = NmkCevni.get(cat);
-			break;
-		case SYS_BNWR:
-		case SYS_BWR2:
-			symbol = NmkBniwr.get(cat);
-			break;
-		case SYS_PPWB:
-			switch (bank) {
-			case BWW_LEFT:
-				symbol = NmkPpwbcl.get(cat);
-				break;
-			case BWW_RGHT:
-				symbol = NmkPpwbcr.get(cat);
-				break;
-			default:
-				break;
-			}
-			break;
-		case SYS_RIWR:
-			symbol = NmkRiwr.get(cat);
-			break;
-		default:
-			break;
-		}
-		return symbol;
-	}
+    // CHECKSTYLE.OFF: LineLength
+    private static final Symbol Bollard = new Symbol();
+    static {
+        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);
+        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);
+        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);
+        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();
+        Bollard.add(new Instr(Form.PGON, p));
+    }
+
+    private static final Symbol Motor = new Symbol();
+    static {
+        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);
+        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);
+        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);
+        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();
+        Motor.add(new Instr(Form.PGON, p));
+    }
+
+    private static final Symbol Rowboat = new Symbol();
+    static {
+        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();
+        Rowboat.add(new Instr(Form.PGON, p));
+        Rowboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-6, -17.5, 6, 6)));
+        Rowboat.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5, -9, -8, 0)));
+        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.0, 10.0, -7.5, 14.0)));
+        Rowboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(-5.5, -9, 7, -6.5)));
+        Rowboat.add(new Instr(Form.LINE, new Line2D.Double(7.3, -7.8, -5.0, 10.0)));
+    }
+
+    private static final Symbol Sailboard = new Symbol();
+    static {
+        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();
+        Sailboard.add(new Instr(Form.PGON, p));
+        Sailboard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-2, 20, -10, 20)));
+        Sailboard.add(new Instr(Form.LINE, new Line2D.Double(-13, 2.5, -3, 2.5)));
+        Sailboard.add(new Instr(Form.RSHP, new Ellipse2D.Double(-15, -4, 5, 5)));
+        Sailboard.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        p = new Path2D.Double(); p.moveTo(-13, 2.5); p.lineTo(-12, 6.0); p.lineTo(-12, 9.5);
+        Sailboard.add(new Instr(Form.PLIN, p));
+        Sailboard.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        p = new Path2D.Double(); p.moveTo(-12, 9.5); p.lineTo(-7.5, 13.0); p.lineTo(-6.0, 19.0);
+        Sailboard.add(new Instr(Form.PLIN, p));
+    }
+
+    private static final Symbol Sailboat = new Symbol();
+    static {
+        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();
+        Sailboat.add(new Instr(Form.PGON, p));
+        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();
+        Sailboat.add(new Instr(Form.PGON, p));
+    }
+
+    private static final Symbol Slipway = new Symbol();
+    static {
+        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();
+        p.moveTo(-14, 7); p.lineTo(-14, 11); p.lineTo(20, 11); p.lineTo(20, 2); p.closePath();
+        Slipway.add(new Instr(Form.PGON, p));
+        Slipway.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Slipway.add(new Instr(Form.LINE, new Line2D.Double(-14, 3, 20, -2.5)));
+        Slipway.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Slipway.add(new Instr(Form.ELPS, new Ellipse2D.Double(1, 1.5, 3, 3)));
+        p = new Path2D.Double(); p.moveTo(-21, 8.5); p.curveTo(-17.5, 5, -17.5, 12, -13, 7.2);
+        Slipway.add(new Instr(Form.PLIN, p));
+    }
+
+    private static final Symbol Speedboat = new Symbol();
+    static {
+        Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, -17, -1)));
+        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);
+        Speedboat.add(new Instr(Form.PLIN, p));
+        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);
+        p.lineTo(9.5, -6); p.lineTo(6.5, -8); p.lineTo(2.5, -4); p.closePath();
+        Speedboat.add(new Instr(Form.PGON, p));
+        Speedboat.add(new Instr(Form.RSHP, new Ellipse2D.Double(-1.5, -13, 5, 5)));
+        Speedboat.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2, -7, -5, 0)));
+        Speedboat.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Speedboat.add(new Instr(Form.LINE, new Line2D.Double(-2, -7, 5, -5)));
+    }
+
+    private static final Symbol Turn = new Symbol();
+    static {
+        Turn.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Turn.add(new Instr(Form.EARC, new Arc2D.Double(-9.0, -9.0, 18.0, 18.0, 270.0, 230.0, Arc2D.OPEN)));
+        Turn.add(new Instr(Form.EARC, new Arc2D.Double(-20.0, -20.0, 40.0, 40.0, 315.0, -280.0, Arc2D.OPEN)));
+        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();
+        p.moveTo(-12.9, 0.7); p.lineTo(-1.7, -2.3); p.lineTo(-9.9, -10.5); p.closePath();
+        Turn.add(new Instr(Form.PGON, p));
+    }
+
+    private static final Symbol Waterbike = new Symbol();
+    static {
+        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);
+        Waterbike.add(new Instr(Form.PLIN, p));
+        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();
+        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();
+        Waterbike.add(new Instr(Form.PGON, p));
+        Waterbike.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        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);
+        Waterbike.add(new Instr(Form.PLIN, p));
+        Waterbike.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        Waterbike.add(new Instr(Form.LINE, new Line2D.Double(-11.5, -10.5, -3, -8.5)));
+        Waterbike.add(new Instr(Form.RSHP, new Ellipse2D.Double(-11.5, -18, 5, 5)));
+    }
+
+    private static final Symbol Waterski = new Symbol();
+    static {
+        Waterski.add(new Instr(Form.RSHP, new Ellipse2D.Double(12, -18, 6, 6)));
+        Waterski.add(new Instr(Form.STRK, new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Waterski.add(new Instr(Form.LINE, new Line2D.Double(-18, -6, 0, -6)));
+        Waterski.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        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);
+        Waterski.add(new Instr(Form.PLIN, p));
+        Waterski.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND)));
+        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);
+        Waterski.add(new Instr(Form.PLIN, p));
+    }
+
+    private static final Symbol NoticeA = new Symbol();
+    static {
+        NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
+        NoticeA.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeA.add(new Instr(Form.FILL, Color.white));
+        NoticeA.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
+        NoticeA.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        NoticeA.add(new Instr(Form.FILL, new Color(0xe80000)));
+        NoticeA.add(new Instr(Form.LINE, new Line2D.Double(-25, -25, 25, 25)));
+        NoticeA.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeA.add(new Instr(Form.FILL, Color.black));
+        NoticeA.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    private static final Symbol NoticeB = new Symbol();
+    static {
+        NoticeB.add(new Instr(Form.FILL, new Color(0xe80000)));
+        NoticeB.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeB.add(new Instr(Form.FILL, Color.white));
+        NoticeB.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
+        NoticeB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB.add(new Instr(Form.FILL, Color.black));
+        NoticeB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    private static final Symbol NoticeE = new Symbol();
+    static {
+        NoticeE.add(new Instr(Form.FILL, new Color(0x0000a0)));
+        NoticeE.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeE.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE.add(new Instr(Form.FILL, Color.black));
+        NoticeE.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeE.add(new Instr(Form.FILL, Color.white));
+    }
+
+    public static final Symbol Notice = new Symbol();
+    static {
+        Notice.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Notice.add(new Instr(Form.FILL, new Color(0xe80000)));
+        Notice.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        Notice.add(new Instr(Form.FILL, new Color(0x0000a0)));
+        Notice.add(new Instr(Form.RSHP, new Rectangle2D.Double(-21, -21, 42, 42)));
+        Notice.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Notice.add(new Instr(Form.FILL, Color.black));
+        Notice.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    public static final Symbol NoticeA1 = new Symbol();
+    static {
+        NoticeA1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA1.add(new Instr(Form.FILL, new Color(0xe80000)));
+        NoticeA1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeA1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeA1.add(new Instr(Form.FILL, Color.white));
+        NoticeA1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-30, -10, 60, 20)));
+        NoticeA1.add(new Instr(Form.FILL, Color.black));
+        NoticeA1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    public static final Symbol NoticeA1a = new Symbol();
+    static {
+        NoticeA1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA1a.add(new Instr(Form.FILL, new Color(0xe80000)));
+        NoticeA1a.add(new Instr(Form.RSHP, new Ellipse2D.Double(-30, -30, 60, 60)));
+        NoticeA1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeA1a.add(new Instr(Form.FILL, Color.white));
+        NoticeA1a.add(new Instr(Form.RSHP, new Rectangle2D.Double(-29, -10, 58, 20)));
+        NoticeA1a.add(new Instr(Form.FILL, Color.black));
+        NoticeA1a.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
+    }
+
+    public static final Symbol NoticeA2 = new Symbol();
+    static {
+        NoticeA2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA2.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        NoticeA2.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeA3 = new Symbol();
+    static {
+        NoticeA3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA2, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, 12); p.lineTo(-6, 12); p.lineTo(-12.5, 4); p.lineTo(-19, 12);
+        p.closePath(); p.moveTo(10, -3); p.lineTo(6, -3); p.lineTo(12.5, -11); p.lineTo(19, -3); p.closePath();
+        NoticeA3.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeA4 = new Symbol();
+    static {
+        NoticeA4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA4.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        NoticeA4.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeA4_1 = new Symbol();
+    static {
+        NoticeA4_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA4_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA4, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-10, -4); p.lineTo(-6, -4); p.lineTo(-12.5, 4); p.lineTo(-19, -4);
+        p.closePath(); p.moveTo(10, 5); p.lineTo(6, 5); p.lineTo(12.5, -3); p.lineTo(19, 5); p.closePath();
+        NoticeA4_1.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeA5 = new Symbol();
+    static {
+        NoticeA5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        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);
+        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();
+        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();
+        NoticeA5.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeA5_1 = new Symbol();
+    static {
+        NoticeA5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeA6 = new Symbol();
+    static {
+        NoticeA6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        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))))));
+    }
+
+    public static final Symbol NoticeA7 = new Symbol();
+    static {
+        NoticeA7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA8 = new Symbol();
+    static {
+        NoticeA8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA9 = new Symbol();
+    static {
+        NoticeA9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA9.add(new Instr(Form.STRK, new BasicStroke(7, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeA9.add(new Instr(Form.FILL, Color.black));
+        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);
+        p.moveTo(-23, -3); p.curveTo(-11, -3, -12, -9, 0, -9); p.curveTo(12, -9, 11, -3, 23, -3);
+        NoticeA9.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeA10a = new Symbol();
+    static {
+        NoticeA10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA10a.add(new Instr(Form.FILL, Color.white));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(30, 0); p.lineTo(0, 30); p.closePath();
+        NoticeA10a.add(new Instr(Form.PGON, p));
+        NoticeA10a.add(new Instr(Form.FILL, new Color(0xe80000)));
+        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.closePath();
+        NoticeA10a.add(new Instr(Form.PGON, p));
+        NoticeA10a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeA10a.add(new Instr(Form.FILL, Color.black));
+        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
+        NoticeA10a.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeA10b = new Symbol();
+    static {
+        NoticeA10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        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))))));
+    }
+
+    public static final Symbol NoticeA12 = new Symbol();
+    static {
+        NoticeA12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA13 = new Symbol();
+    static {
+        NoticeA13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        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)))));
+    }
+
+    public static final Symbol NoticeA14 = new Symbol();
+    static {
+        NoticeA14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA15 = new Symbol();
+    static {
+        NoticeA15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA16 = new Symbol();
+    static {
+        NoticeA16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA17 = new Symbol();
+    static {
+        NoticeA17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA18 = new Symbol();
+    static {
+        NoticeA18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA19 = new Symbol();
+    static {
+        NoticeA19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeA20 = new Symbol();
+    static {
+        NoticeA20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeA, 1.0, 0, 0, null, null)));
+        NoticeA20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeB1a = new Symbol();
+    static {
+        NoticeB1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB1a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(21, 8); p.lineTo(-8, 8); p.lineTo(-8, 18); p.lineTo(-21, 0);
+        p.lineTo(-8, -18); p.lineTo(-8, -8); p.lineTo(21, -8); p.closePath();
+        NoticeB1a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB1b = new Symbol();
+    static {
+        NoticeB1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB1b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-21, 8); p.lineTo(8, 8); p.lineTo(8, 18); p.lineTo(21, 0);
+        p.lineTo(8, -18); p.lineTo(8, -8); p.lineTo(-21, -8); p.closePath();
+        NoticeB1b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB2a = new Symbol();
+    static {
+        NoticeB2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB2a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB2a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(18, 21); p.lineTo(18, 10); p.lineTo(-15, -10); p.lineTo(-15, -15);
+        NoticeB2a.add(new Instr(Form.PLIN, p));
+        p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(-21, -15); p.lineTo(-9, -15); p.closePath();
+        NoticeB2a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB2b = new Symbol();
+    static {
+        NoticeB2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB2b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB2b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, 21); p.lineTo(-18, 10); p.lineTo(15, -10); p.lineTo(15, -15);
+        NoticeB2b.add(new Instr(Form.PLIN, p));
+        p = new Path2D.Double(); p.moveTo(15, -21); p.lineTo(21, -15); p.lineTo(9, -15); p.closePath();
+        NoticeB2b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB3a = new Symbol();
+    static {
+        NoticeB3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB3a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(-15, 21, -15, -15)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(-21, -15); p.lineTo(-9, -15); p.closePath();
+        NoticeB3a.add(new Instr(Form.PGON, p));
+        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)));
+        NoticeB3a.add(new Instr(Form.LINE, new Line2D.Double(15, -21, 15, 15)));
+        p = new Path2D.Double(); p.moveTo(15, 21); p.lineTo(21, 15); p.lineTo(9, 15); p.closePath();
+        NoticeB3a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB3b = new Symbol();
+    static {
+        NoticeB3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB3b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(15, 21, 15, -15)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(15, -21); p.lineTo(21, -15); p.lineTo(9, -15); p.closePath();
+        NoticeB3b.add(new Instr(Form.PGON, p));
+        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)));
+        NoticeB3b.add(new Instr(Form.LINE, new Line2D.Double(-15, -21, -15, 15)));
+        p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(-21, 15); p.lineTo(-9, 15); p.closePath();
+        NoticeB3b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB4a = new Symbol();
+    static {
+        NoticeB4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2a, 1.0, 0, 0, null, null)));
+        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)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(18, -21); p.lineTo(18, -10); p.lineTo(-15, 10); p.lineTo(-15, 15);
+        NoticeB4a.add(new Instr(Form.PLIN, p));
+        p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(-21, 15); p.lineTo(-9, 15); p.closePath();
+        NoticeB4a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB4b = new Symbol();
+    static {
+        NoticeB4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB2b, 1.0, 0, 0, null, null)));
+        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)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, -21); p.lineTo(-18, -10); p.lineTo(15, 10); p.lineTo(15, 15);
+        NoticeB4b.add(new Instr(Form.PLIN, p));
+        p = new Path2D.Double(); p.moveTo(15, 21); p.lineTo(21, 15); p.lineTo(9, 15); p.closePath();
+        NoticeB4b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeB5 = new Symbol();
+    static {
+        NoticeB5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB5.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        NoticeB5.add(new Instr(Form.LINE, new Line2D.Double(15, 0, -15, 0)));
+    }
+
+    public static final Symbol NoticeB6 = new Symbol();
+    static {
+        NoticeB6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeB7 = new Symbol();
+    static {
+        NoticeB7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB7.add(new Instr(Form.RSHP, new Ellipse2D.Double(-10, -10, 20, 20)));
+    }
+
+    public static final Symbol NoticeB8 = new Symbol();
+    static {
+        NoticeB8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB8.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        NoticeB8.add(new Instr(Form.LINE, new Line2D.Double(0, 15, 0, -15)));
+    }
+
+    public static final Symbol NoticeB9a = new Symbol();
+    static {
+        NoticeB9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, 21, 0)));
+        NoticeB9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB9a.add(new Instr(Form.LINE, new Line2D.Double(0, 21, 0, 0)));
+    }
+
+    public static final Symbol NoticeB9b = new Symbol();
+    static {
+        NoticeB9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(-21, 0, 21, 0)));
+        NoticeB9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeB9b.add(new Instr(Form.LINE, new Line2D.Double(0, 21, 0, -21)));
+    }
+
+    public static final Symbol NoticeB11 = new Symbol();
+    static {
+        NoticeB11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeB11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        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)))));
+    }
+
+    public static final Symbol NoticeC1 = new Symbol();
+    static {
+        NoticeC1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, 21); p.lineTo(0, 12); p.lineTo(15, 21); p.closePath();
+        NoticeC1.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeC2 = new Symbol();
+    static {
+        NoticeC2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15, -21); p.lineTo(0, -12); p.lineTo(15, -21); p.closePath();
+        NoticeC2.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeC3 = new Symbol();
+    static {
+        NoticeC3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(21, -15); p.lineTo(12, 0); p.lineTo(21, 15); p.closePath();
+        p.moveTo(-21, -15); p.lineTo(-12, 0); p.lineTo(-21, 15); p.closePath();
+        NoticeC3.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeC4 = new Symbol();
+    static {
+        NoticeC4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeC5a = new Symbol();
+    static {
+        NoticeC5a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC5a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        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();
+        NoticeC5a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeC5b = new Symbol();
+    static {
+        NoticeC5b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeC5b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeB, 1.0, 0, 0, null, null)));
+        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();
+        NoticeC5b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeD1a = new Symbol();
+    static {
+        NoticeD1a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeD1a.add(new Instr(Form.FILL, Color.yellow));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
+        NoticeD1a.add(new Instr(Form.PGON, p));
+        NoticeD1a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeD1a.add(new Instr(Form.FILL, Color.black));
+        NoticeD1a.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeD1b = new Symbol();
+    static {
+        NoticeD1b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeD1b.add(new Instr(Form.FILL, Color.yellow));
+        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();
+        NoticeD1b.add(new Instr(Form.PGON, p));
+        NoticeD1b.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeD1b.add(new Instr(Form.FILL, Color.black));
+        NoticeD1b.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeD2a = new Symbol();
+    static {
+        NoticeD2a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeD2a.add(new Instr(Form.FILL, Color.white));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.closePath();
+        NoticeD2a.add(new Instr(Form.PGON, p));
+        NoticeD2a.add(new Instr(Form.FILL, new Color(0x00e800)));
+        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(30, 0); p.lineTo(0, 30); p.closePath();
+        NoticeD2a.add(new Instr(Form.PGON, p));
+        NoticeD2a.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeD2a.add(new Instr(Form.FILL, Color.black));
+        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
+        NoticeD2a.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeD2b = new Symbol();
+    static {
+        NoticeD2b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        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))))));
+    }
+
+    public static final Symbol NoticeD3a = new Symbol();
+    static {
+        NoticeD3a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeD3a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(28, 10); p.lineTo(-10, 10); p.lineTo(-10, 20); p.lineTo(-28, 0);
+        p.lineTo(-10, -20); p.lineTo(-10, -10); p.lineTo(28, -10); p.closePath();
+        NoticeD3a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeD3b = new Symbol();
+    static {
+        NoticeD3b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeD3b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-28, 10); p.lineTo(10, 10); p.lineTo(10, 20); p.lineTo(28, 0);
+        p.lineTo(10, -20); p.lineTo(10, -10); p.lineTo(-28, -10); p.closePath();
+        NoticeD3b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE1 = new Symbol();
+    static {
+        NoticeE1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE1.add(new Instr(Form.FILL, new Color(0x00e800)));
+        NoticeE1.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeE1.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE1.add(new Instr(Form.FILL, Color.white));
+        NoticeE1.add(new Instr(Form.RSHP, new Rectangle2D.Double(-10, -30, 20, 60)));
+        NoticeE1.add(new Instr(Form.FILL, Color.black));
+        NoticeE1.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    public static final Symbol NoticeE2 = new Symbol();
+    static {
+        NoticeE2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(5, -25); p.lineTo(-10, -1); p.lineTo(10, -1); p.lineTo(-10, 20);
+        p.lineTo(-7, 20); p.lineTo(-12, 25); p.lineTo(-16, 20); p.lineTo(-13, 20); p.lineTo(4, 1); p.lineTo(-14, 1);
+        p.lineTo(2, -25); p.closePath();
+        NoticeE2.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE3 = new Symbol();
+    static {
+        NoticeE3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE3.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(25, -20, 25, 20)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-25, -20, -25, 20)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-15, -15, -15, 20)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-5, -15, -5, 20)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(5, -15, 5, 20)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(15, -15, 15, 20)));
+        NoticeE3.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26, 18.5, 26, 18.5)));
+        NoticeE3.add(new Instr(Form.LINE, new Line2D.Double(-26, -15, 26, -15)));
+    }
+
+    public static final Symbol NoticeE4a = new Symbol();
+    static {
+        NoticeE4a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE4a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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);
+        p.lineTo(20, -10); p.lineTo(15, 0); p.lineTo(-15, 0); p.closePath();
+        p.moveTo(-25, 5); p.lineTo(25, 5); p.lineTo(25, 10); p.lineTo(-25, 10); p.closePath();
+        NoticeE4a.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE4b = new Symbol();
+    static {
+        NoticeE4b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE4b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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);
+        p.lineTo(20, 0); p.lineTo(15, 10); p.lineTo(-15, 10); p.closePath();
+        NoticeE4b.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5 = new Symbol();
+    static {
+        NoticeE5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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);
+        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();
+        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();
+        NoticeE5.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_1 = new Symbol();
+    static {
+        NoticeE5_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeE5_2 = new Symbol();
+    static {
+        NoticeE5_2.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_2.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeE5_3 = new Symbol();
+    static {
+        NoticeE5_3.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_3.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeE5_4 = new Symbol();
+    static {
+        NoticeE5_4.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_4.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
+        NoticeE5_4.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_5 = new Symbol();
+    static {
+        NoticeE5_5.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_5.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
+        p.moveTo(0, 24); p.lineTo(-15, 2); p.lineTo(15, 2); p.closePath();
+        NoticeE5_5.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_6 = new Symbol();
+    static {
+        NoticeE5_6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
+        p.moveTo(0, 7); p.lineTo(-10, -8); p.lineTo(10, -8); p.closePath();
+        p.moveTo(0, 24); p.lineTo(-10, 9); p.lineTo(10, 9); p.closePath();
+        NoticeE5_6.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_7 = new Symbol();
+    static {
+        NoticeE5_7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 25); p.lineTo(0, -28); p.lineTo(28, 25); p.closePath();
+        p.moveTo(0, -1); p.lineTo(-8, -11); p.lineTo(8, -11); p.closePath();
+        p.moveTo(0, 11); p.lineTo(-8, 1); p.lineTo(8, 1); p.closePath();
+        p.moveTo(0, 23); p.lineTo(-8, 13); p.lineTo(8, 13); p.closePath();
+        NoticeE5_7.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_8 = new Symbol();
+    static {
+        NoticeE5_8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
+        NoticeE5_8.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_9 = new Symbol();
+    static {
+        NoticeE5_9.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_9.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
+        p.moveTo(0, 8); p.lineTo(-15, -14); p.lineTo(15, -14); p.closePath();
+        NoticeE5_9.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_10 = new Symbol();
+    static {
+        NoticeE5_10.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_10.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
+        p.moveTo(0, -5); p.lineTo(-10, -20); p.lineTo(10, -20); p.closePath();
+        p.moveTo(0, 15); p.lineTo(-10, 0); p.lineTo(10, 0); p.closePath();
+        NoticeE5_10.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_11 = new Symbol();
+    static {
+        NoticeE5_11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, -25); p.lineTo(0, 28); p.lineTo(28, -25); p.closePath();
+        p.moveTo(0, -12); p.lineTo(-8, -22); p.lineTo(8, -22); p.closePath();
+        p.moveTo(0, 3); p.lineTo(-8, -7); p.lineTo(8, -7); p.closePath();
+        p.moveTo(0, 18); p.lineTo(-8, 8); p.lineTo(8, 8); p.closePath();
+        NoticeE5_11.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_12 = new Symbol();
+    static {
+        NoticeE5_12.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_12.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
+        NoticeE5_12.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_13 = new Symbol();
+    static {
+        NoticeE5_13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
+        p.moveTo(0, 15); p.lineTo(-15, -7); p.lineTo(15, -7); p.closePath();
+        NoticeE5_13.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_14 = new Symbol();
+    static {
+        NoticeE5_14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
+        p.moveTo(0, 0); p.lineTo(-10, -15); p.lineTo(10, -15); p.closePath();
+        p.moveTo(0, 20); p.lineTo(-10, 5); p.lineTo(10, 5); p.closePath();
+        NoticeE5_14.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE5_15 = new Symbol();
+    static {
+        NoticeE5_15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE5_15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-28, 0); p.lineTo(0, 28); p.lineTo(28, 0); p.lineTo(0, -28); p.closePath();
+        p.moveTo(0, -7); p.lineTo(-8, -17); p.lineTo(8, -17); p.closePath();
+        p.moveTo(0, 8); p.lineTo(-8, -2); p.lineTo(8, -2); p.closePath();
+        p.moveTo(0, 23); p.lineTo(-8, 13); p.lineTo(8, 13); p.closePath();
+        NoticeE5_15.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE6 = new Symbol();
+    static {
+        NoticeE6.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE6.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE7 = new Symbol();
+    static {
+        NoticeE7.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE7.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Bollard, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE7_1 = new Symbol();
+    static {
+        NoticeE7_1.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE7_1.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20, 25, 20, -10)));
+        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(22, -8, -15, -20)));
+        NoticeE7_1.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE7_1.add(new Instr(Form.LINE, new Line2D.Double(20, 8, 0, -15)));
+        Path2D.Double p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        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);
+        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();
+        p.moveTo(-15, 4); p.quadTo(-3, 2, 5, 4); p.lineTo(6, 11); p.quadTo(-5, 9, -16, 11); p.closePath();
+        NoticeE7_1.add(new Instr(Form.PGON, p));
+        NoticeE7_1.add(new Instr(Form.FILL, new Color(0x0000a0)));
+        NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(-16, 13, 4, 4)));
+        NoticeE7_1.add(new Instr(Form.RSHP, new Ellipse2D.Double(2, 13, 4, 4)));
+    }
+
+    public static final Symbol NoticeE8 = new Symbol();
+    static {
+        NoticeE8.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE8.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Turn, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE9a = new Symbol();
+    static {
+        NoticeE9a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
+        NoticeE9a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9a.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
+    }
+
+    public static final Symbol NoticeE9b = new Symbol();
+    static {
+        NoticeE9b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
+        NoticeE9b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9b.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
+    }
+
+    public static final Symbol NoticeE9c = new Symbol();
+    static {
+        NoticeE9c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
+        NoticeE9c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9c.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
+    }
+
+    public static final Symbol NoticeE9d = new Symbol();
+    static {
+        NoticeE9d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
+        NoticeE9d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9d.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
+    }
+
+    public static final Symbol NoticeE9e = new Symbol();
+    static {
+        NoticeE9e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
+        NoticeE9e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9e.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
+    }
+
+    public static final Symbol NoticeE9f = new Symbol();
+    static {
+        NoticeE9f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
+        NoticeE9f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9f.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
+    }
+
+    public static final Symbol NoticeE9g = new Symbol();
+    static {
+        NoticeE9g.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9g.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
+        NoticeE9g.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9g.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
+    }
+
+    public static final Symbol NoticeE9h = new Symbol();
+    static {
+        NoticeE9h.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9h.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
+        NoticeE9h.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
+        NoticeE9h.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
+    }
+
+    public static final Symbol NoticeE9i = new Symbol();
+    static {
+        NoticeE9i.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE9i.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -4)));
+        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
+        NoticeE9i.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 2)));
+        NoticeE9i.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
+    }
+
+    public static final Symbol NoticeE10a = new Symbol();
+    static {
+        NoticeE10a.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10a.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
+        NoticeE10a.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10a.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -29)));
+    }
+
+    public static final Symbol NoticeE10b = new Symbol();
+    static {
+        NoticeE10b.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10b.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(-29, 0, 29, 0)));
+        NoticeE10b.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10b.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
+    }
+
+    public static final Symbol NoticeE10c = new Symbol();
+    static {
+        NoticeE10c.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10c.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
+        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
+        NoticeE10c.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10c.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
+    }
+
+    public static final Symbol NoticeE10d = new Symbol();
+    static {
+        NoticeE10d.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10d.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
+        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
+        NoticeE10d.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10d.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
+    }
+
+    public static final Symbol NoticeE10e = new Symbol();
+    static {
+        NoticeE10e.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10e.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
+        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(-4, 0, 29, 0)));
+        NoticeE10e.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
+        NoticeE10e.add(new Instr(Form.LINE, new Line2D.Double(2, 0, -29, 0)));
+    }
+
+    public static final Symbol NoticeE10f = new Symbol();
+    static {
+        NoticeE10f.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE10f.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0, -29, 0, 4)));
+        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(4, 0, -29, 0)));
+        NoticeE10f.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(0, 29, 0, -2)));
+        NoticeE10f.add(new Instr(Form.LINE, new Line2D.Double(-2, 0, 29, 0)));
+    }
+
+    public static final Symbol NoticeE11 = new Symbol();
+    static {
+        NoticeE11.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE11.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE11.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)));
+        NoticeE11.add(new Instr(Form.LINE, new Line2D.Double(-27, -27, 27, 27)));
+    }
+
+    public static final Symbol NoticeE13 = new Symbol();
+    static {
+        NoticeE13.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE13.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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);
+        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);
+        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);
+        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);
+        p.lineTo(1.5, -7); p.lineTo(1.5, -14); p.lineTo(-4, -14); p.closePath();
+        NoticeE13.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE14 = new Symbol();
+    static {
+        NoticeE14.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE14.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-18, -18); p.lineTo(-11, -7); p.lineTo(-9, -10); p.lineTo(-14, -18); p.closePath();
+        p.moveTo(9.5, 7); p.lineTo(22.5, 9); p.lineTo(21.5, 5.5); p.lineTo(12, 4); p.closePath();
+        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);
+        p.curveTo(15.5, 23, 1, 18.5, -9, 12); p.curveTo(-18, 6, -28.5, -7, -19, -16.5); p.closePath();
+        NoticeE14.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeE15 = new Symbol();
+    static {
+        NoticeE15.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE15.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Motor, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE16 = new Symbol();
+    static {
+        NoticeE16.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE16.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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)))));
+    }
+
+    public static final Symbol NoticeE17 = new Symbol();
+    static {
+        NoticeE17.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE17.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterski, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE18 = new Symbol();
+    static {
+        NoticeE18.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE18.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboat, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE19 = new Symbol();
+    static {
+        NoticeE19.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE19.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Rowboat, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE20 = new Symbol();
+    static {
+        NoticeE20.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE20.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Sailboard, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE21 = new Symbol();
+    static {
+        NoticeE21.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE21.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Speedboat, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE22 = new Symbol();
+    static {
+        NoticeE22.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE22.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Slipway, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeE23 = new Symbol();
+    static {
+        NoticeE23.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE23.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        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)))));
+    }
+
+    public static final Symbol NoticeE24 = new Symbol();
+    static {
+        NoticeE24.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.NoticeE, 1.0, 0, 0, null, null)));
+        NoticeE24.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Notices.Waterbike, 1.0, 0, 0, new Scheme(Color.white), null)));
+    }
+
+    public static final Symbol NoticeBoard = new Symbol();
+    static {
+        NoticeBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 30)));
+        NoticeBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, 0); p.lineTo(20, 0); p.lineTo(20, -15); p.lineTo(-20, -15); p.closePath();
+        NoticeBoard.add(new Instr(Form.FILL, Color.white));
+        NoticeBoard.add(new Instr(Form.PGON, p));
+        NoticeBoard.add(new Instr(Form.FILL, Color.black));
+        NoticeBoard.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeTriangle = new Symbol();
+    static {
+        NoticeTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 30)));
+        NoticeTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-20, 0); p.lineTo(20, 0); p.lineTo(0, -15); p.closePath();
+        NoticeTriangle.add(new Instr(Form.FILL, Color.white));
+        NoticeTriangle.add(new Instr(Form.PGON, p));
+        NoticeTriangle.add(new Instr(Form.FILL, Color.black));
+        NoticeTriangle.add(new Instr(Form.PLIN, p));
+    }
+
+    // CHECKSTYLE.OFF: SingleSpaceSeparator
+    public static final EnumMap<CatNMK, Symbol> NmkCevni = new EnumMap<>(CatNMK.class);
+    static {
+        NmkCevni.put(CatNMK.NMK_UNKN, Notice);      NmkCevni.put(CatNMK.NMK_NENT, NoticeA1);    NmkCevni.put(CatNMK.NMK_CLSA, NoticeA1a);   NmkCevni.put(CatNMK.NMK_NOVK, NoticeA2);
+        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);
+        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);
+        NmkCevni.put(CatNMK.NMK_NWSH, NoticeA9);    NmkCevni.put(CatNMK.NMK_NPSL, NoticeA10a);  NmkCevni.put(CatNMK.NMK_NPSR, NoticeA10b);  NmkCevni.put(CatNMK.NMK_NMTC, NoticeA12);
+        NmkCevni.put(CatNMK.NMK_NSPC, NoticeA13);   NmkCevni.put(CatNMK.NMK_NWSK, NoticeA14);   NmkCevni.put(CatNMK.NMK_NSLC, NoticeA15);   NmkCevni.put(CatNMK.NMK_NUPC, NoticeA16);
+        NmkCevni.put(CatNMK.NMK_NSLB, NoticeA17);   NmkCevni.put(CatNMK.NMK_NWBK, NoticeA20);   NmkCevni.put(CatNMK.NMK_NHSC, NoticeA18);   NmkCevni.put(CatNMK.NMK_NLBG, NoticeA19);
+        NmkCevni.put(CatNMK.NMK_MVTL, NoticeB1a);   NmkCevni.put(CatNMK.NMK_MVTR, NoticeB1b);   NmkCevni.put(CatNMK.NMK_MVTP, NoticeB2a);   NmkCevni.put(CatNMK.NMK_MVTS, NoticeB2b);
+        NmkCevni.put(CatNMK.NMK_KPTP, NoticeB3a);   NmkCevni.put(CatNMK.NMK_KPTS, NoticeB3b);   NmkCevni.put(CatNMK.NMK_CSTP, NoticeB4a);   NmkCevni.put(CatNMK.NMK_CSTS, NoticeB4b);
+        NmkCevni.put(CatNMK.NMK_STOP, NoticeB5);    NmkCevni.put(CatNMK.NMK_SPDL, NoticeB6);    NmkCevni.put(CatNMK.NMK_SHRN, NoticeB7);    NmkCevni.put(CatNMK.NMK_KPLO, NoticeB8);
+        NmkCevni.put(CatNMK.NMK_GWJN, NoticeB9a);   NmkCevni.put(CatNMK.NMK_GWCS, NoticeB9b);   NmkCevni.put(CatNMK.NMK_MKRC, NoticeB11);
+        NmkCevni.put(CatNMK.NMK_LMDP, NoticeC1);    NmkCevni.put(CatNMK.NMK_LMHR, NoticeC2);    NmkCevni.put(CatNMK.NMK_LMWD, NoticeC3);    NmkCevni.put(CatNMK.NMK_NAVR, NoticeC4);
+        NmkCevni.put(CatNMK.NMK_CHDL, NoticeC5a);   NmkCevni.put(CatNMK.NMK_CHDR, NoticeC5b);
+        NmkCevni.put(CatNMK.NMK_CHTW, NoticeD1a);   NmkCevni.put(CatNMK.NMK_CHOW, NoticeD1b);   NmkCevni.put(CatNMK.NMK_OPTR, NoticeD2a);   NmkCevni.put(CatNMK.NMK_OPTL, NoticeD2b);
+        NmkCevni.put(CatNMK.NMK_PRTL, NoticeD3a);   NmkCevni.put(CatNMK.NMK_PRTR, NoticeD3b);
+        NmkCevni.put(CatNMK.NMK_ENTP, NoticeE1);    NmkCevni.put(CatNMK.NMK_OVHC, NoticeE2);    NmkCevni.put(CatNMK.NMK_WEIR, NoticeE3);    NmkCevni.put(CatNMK.NMK_FERN, NoticeE4a);
+        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);
+        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);
+        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);
+        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);
+        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);
+        NmkCevni.put(CatNMK.NMK_TRNA, NoticeE8);    NmkCevni.put(CatNMK.NMK_SWWC, NoticeE9a);   NmkCevni.put(CatNMK.NMK_SWWR, NoticeE9b);   NmkCevni.put(CatNMK.NMK_SWWL, NoticeE9c);
+        NmkCevni.put(CatNMK.NMK_WRSA, NoticeE9d);   NmkCevni.put(CatNMK.NMK_WLSA, NoticeE9e);   NmkCevni.put(CatNMK.NMK_WRSL, NoticeE9f);   NmkCevni.put(CatNMK.NMK_WLSR, NoticeE9g);
+        NmkCevni.put(CatNMK.NMK_WRAL, NoticeE9h);   NmkCevni.put(CatNMK.NMK_WLAR, NoticeE9i);   NmkCevni.put(CatNMK.NMK_MWWC, NoticeE10a);  NmkCevni.put(CatNMK.NMK_MWWJ, NoticeE10b);
+        NmkCevni.put(CatNMK.NMK_MWAR, NoticeE10c);  NmkCevni.put(CatNMK.NMK_MWAL, NoticeE10d);  NmkCevni.put(CatNMK.NMK_WARL, NoticeE10e);  NmkCevni.put(CatNMK.NMK_WALR, NoticeE10f);
+        NmkCevni.put(CatNMK.NMK_PEND, NoticeE11);   NmkCevni.put(CatNMK.NMK_DWTR, NoticeE13);   NmkCevni.put(CatNMK.NMK_TELE, NoticeE14);   NmkCevni.put(CatNMK.NMK_MTCP, NoticeE15);
+        NmkCevni.put(CatNMK.NMK_SPCP, NoticeE16);   NmkCevni.put(CatNMK.NMK_WSKP, NoticeE17);   NmkCevni.put(CatNMK.NMK_SLCP, NoticeE18);   NmkCevni.put(CatNMK.NMK_UPCP, NoticeE19);
+        NmkCevni.put(CatNMK.NMK_SLBP, NoticeE20);   NmkCevni.put(CatNMK.NMK_RADI, NoticeE23);   NmkCevni.put(CatNMK.NMK_WTBP, NoticeE24);   NmkCevni.put(CatNMK.NMK_HSCP, NoticeE21);
+        NmkCevni.put(CatNMK.NMK_LBGP, NoticeE22);
+    }
+    // CHECKSTYLE.ON: SingleSpaceSeparator
+
+    private static final Symbol NoticeBB = new Symbol();
+    static {
+        NoticeBB.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(-29, -29, -29, 29)));
+        NoticeBB.add(new Instr(Form.LINE, new Line2D.Double(29, -29, 29, 29)));
+        NoticeBB.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeBB.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    private static final Symbol NoticeBP = new Symbol();
+    static {
+        NoticeBP.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeBP.add(new Instr(Form.FILL, Color.white));
+        NoticeBP.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeBP.add(new Instr(Form.FILL, Color.black));
+        NoticeBP.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+    }
+
+    private static final Symbol NoticeCR = new Symbol();
+    static {
+        NoticeCR.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeCR.add(new Instr(Form.FILL, Color.white));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 0); p.lineTo(0, 30); p.lineTo(30, 0); p.closePath();
+        NoticeCR.add(new Instr(Form.PGON, p));
+        NoticeCR.add(new Instr(Form.FILL, Color.black));
+        NoticeCR.add(new Instr(Form.PLIN, p));
+    }
+
+    private static final Symbol NoticeKT = new Symbol();
+    static {
+        NoticeKT.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeKT.add(new Instr(Form.FILL, Color.white));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
+        NoticeKT.add(new Instr(Form.PGON, p));
+        NoticeKT.add(new Instr(Form.FILL, Color.black));
+        NoticeKT.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeBnank = new Symbol();
+    static {
+        NoticeBnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, null, null)));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(-27, -27, 27, 27)));
+        ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBnank.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBlmhr = new Symbol();
+    static {
+        NoticeBlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-29, -29); p.lineTo(29, -29); p.lineTo(0, 0); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.RRCT, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBlmhr.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBktpm = new Symbol();
+    static {
+        NoticeBktpm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-14, -26); p.lineTo(-20, -12); p.lineTo(-8, -12); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(-14, -16, -14, 25)));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBktpm.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBktsm = new Symbol();
+    static {
+        NoticeBktsm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(14, -26); p.lineTo(20, -12); p.lineTo(8, -12); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(14, -16, 14, 25)));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBktsm.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBktmr = new Symbol();
+    static {
+        NoticeBktmr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -26); p.lineTo(-6, -12); p.lineTo(6, -12); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(0, -16, 0, 25)));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBktmr.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBcrtp = new Symbol();
+    static {
+        NoticeBcrtp.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-14, -26); p.lineTo(-20, -12); p.lineTo(-8, -12); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(-14, -16); p.lineTo(-14, 0); p.lineTo(14, 10); p.lineTo(14, 25);
+        ss.add(new Instr(Form.PLIN, p));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBcrtp.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBcrts = new Symbol();
+    static {
+        NoticeBcrts.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(14, -26); p.lineTo(20, -12); p.lineTo(8, -12); p.closePath();
+        ss.add(new Instr(Form.PGON, p));
+        ss.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(14, -16); p.lineTo(14, 0); p.lineTo(-14, 10); p.lineTo(-14, 25);
+        ss.add(new Instr(Form.PLIN, p));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBcrts.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBtrbm = new Symbol();
+    static {
+        NoticeBtrbm.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        ss.add(new Instr(Form.STRK, new BasicStroke(15, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(0, -25, 0, 25)));
+        ss.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        ss.add(new Instr(Form.LINE, new Line2D.Double(-20, 0, 20, 0)));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBtrbm.add(new Instr(Form.COLR, colours));
+    }
+
+    public static final Symbol NoticeBrspd = new Symbol();
+    static {
+        NoticeBrspd.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        Symbol colours = new Symbol();
+        Symbol ss = new Symbol();
+        ss.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        colours.add(new Instr(Form.N1, ss));
+        ss = new Symbol();
+        ss.add(new Instr(Form.TEXT, new Caption("R", new Font("Arial", Font.BOLD, 60), null, new Delta(Handle.CC, null))));
+        ss.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBB, 1.0, 0, 0, null, null)));
+        colours.add(new Instr(Form.N2, ss));
+        NoticeBrspd.add(new Instr(Form.COLR, colours));
+    }
+
+    static final Symbol NoticePBwral = new Symbol();
+    static {
+        NoticePBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePBwral.add(new Instr(Form.FILL, new Color(0xffff00)));
+        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);
+        p.lineTo(20, -25); p.lineTo(5, -25); p.lineTo(-5, -10); p.lineTo(-15, -25); p.closePath();
+        NoticePBwral.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeBwral = new Symbol();
+    static {
+        NoticeBwral.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeBwral.add(new Instr(Form.FILL, Color.black));
+        NoticeBwral.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeBwral.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticeBwlar = new Symbol();
+    static {
+        NoticeBwlar.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeBwlar.add(new Instr(Form.FILL, Color.black));
+        NoticeBwlar.add(new Instr(Form.RSHP, new RoundRectangle2D.Double(-30, -30, 60, 60, 4, 4)));
+        NoticeBwlar.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticePBwral, 1.0, 0, 0, null, new Delta(Handle.CC, AffineTransform.getScaleInstance(-1, 1)))));
+    }
+
+    public static final Symbol NoticeBoptr = new Symbol();
+    static {
+        NoticeBoptr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeBoptr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
+        NoticeBoptr.add(new Instr(Form.FILL, new Color(0x00a000)));
+        NoticeBoptr.add(new Instr(Form.RSHP, new Rectangle2D.Double(-20, -20, 40, 40)));
+    }
+
+    public static final Symbol NoticeBoptl = new Symbol();
+    static {
+        NoticeBoptl.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeBoptl.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
+        NoticeBoptl.add(new Instr(Form.FILL, new Color(0xf00000)));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -20); p.lineTo(-20, 20); p.lineTo(20, 20); p.closePath();
+        NoticeBoptl.add(new Instr(Form.PGON, p));
+    }
+
+    public static final EnumMap<CatNMK, Symbol> NmkBniwr = new EnumMap<>(CatNMK.class);
+    static {
+        NmkBniwr.put(CatNMK.NMK_NANK, NoticeBnank); NmkBniwr.put(CatNMK.NMK_LMHR, NoticeBlmhr); NmkBniwr.put(CatNMK.NMK_OPTR, NoticeBoptr); NmkBniwr.put(CatNMK.NMK_OPTL, NoticeBoptl);
+        NmkBniwr.put(CatNMK.NMK_WRAL, NoticeBwral); NmkBniwr.put(CatNMK.NMK_WLAR, NoticeBwlar); NmkBniwr.put(CatNMK.NMK_KTPM, NoticeBktpm); NmkBniwr.put(CatNMK.NMK_KTSM, NoticeBktsm);
+        NmkBniwr.put(CatNMK.NMK_KTMR, NoticeBktmr); NmkBniwr.put(CatNMK.NMK_CRTP, NoticeBcrtp); NmkBniwr.put(CatNMK.NMK_CRTS, NoticeBcrts); NmkBniwr.put(CatNMK.NMK_TRBM, NoticeBtrbm);
+        NmkBniwr.put(CatNMK.NMK_RSPD, NoticeBrspd);
+    }
+
+    public static final Symbol NoticePwralL = new Symbol();
+    static {
+        NoticePwralL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePwralL.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
+        NoticePwralL.add(new Instr(Form.PGON, p));
+        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)))));
+    }
+
+    public static final Symbol NoticePwralR = new Symbol();
+    static {
+        NoticePwralR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePwralR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwral, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticePwlarL = new Symbol();
+    static {
+        NoticePwlarL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePwlarL.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(-30, 30); p.lineTo(30, 30); p.closePath();
+        NoticePwlarL.add(new Instr(Form.PGON, p));
+        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)))));
+    }
+
+    public static final Symbol NoticePwlarR = new Symbol();
+    static {
+        NoticePwlarR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePwlarR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBwlar, 1.0, 0, 0, null, null)));
+    }
+
+    public static final Symbol NoticePktmR = new Symbol();
+    static {
+        NoticePktmR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePktmR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
+        NoticePktmR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePktmR.add(new Instr(Form.FILL, new Color(0x00d400)));
+        NoticePktmR.add(new Instr(Form.RECT, new Rectangle2D.Double(-20, -20, 40, 40)));
+    }
+
+    public static final Symbol NoticePktmL = new Symbol();
+    static {
+        NoticePktmL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePktmL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
+        NoticePktmL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePktmL.add(new Instr(Form.FILL, new Color(0xd40000)));
+        NoticePktmL.add(new Instr(Form.RECT, new Rectangle2D.Double(-12, 2, 24, 24)));
+    }
+
+    public static final Symbol NoticePktmrL = new Symbol();
+    static {
+        NoticePktmrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePktmrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeKT, 1.0, 0, 0, null, null)));
+        NoticePktmrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePktmrL.add(new Instr(Form.FILL, new Color(0xd40000)));
+        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 2, -12, 28)));
+        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(12, 2, 12, 28)));
+        NoticePktmrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 15, 12, 15)));
+    }
+
+    public static final Symbol NoticePktmrR = new Symbol();
+    static {
+        NoticePktmrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePktmrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeBP, 1.0, 0, 0, null, null)));
+        NoticePktmrR.add(new Instr(Form.STRK, new BasicStroke(8, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePktmrR.add(new Instr(Form.FILL, new Color(0x00d400)));
+        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15, -20, -15, 20)));
+        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(15, -20, 15, 20)));
+        NoticePktmrR.add(new Instr(Form.LINE, new Line2D.Double(-15, 0, 15, 0)));
+    }
+
+    public static final Symbol NoticePcrL = new Symbol();
+    static {
+        NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePcrL.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePcrL.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
+        NoticePcrL.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePcrL.add(new Instr(Form.FILL, new Color(0xd40000)));
+        NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 12, 12)));
+        NoticePcrL.add(new Instr(Form.LINE, new Line2D.Double(-12, 12, 12, -12)));
+    }
+
+    public static final Symbol NoticePcrR = new Symbol();
+    static {
+        NoticePcrR.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticePcrR.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
+        NoticePcrR.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticePcrR.add(new Instr(Form.FILL, new Color(0x00d400)));
+        NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 12, 12)));
+        NoticePcrR.add(new Instr(Form.LINE, new Line2D.Double(-12, 12, 12, -12)));
+    }
+
+    static final Symbol NoticeRphib = new Symbol();
+    static {
+        NoticeRphib.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeRphib.add(new Instr(Form.FILL, new Color(0xd40000)));
+        NoticeRphib.add(new Instr(Form.ELPS, new Ellipse2D.Double(-30, -30, 60, 60)));
+        NoticeRphib.add(new Instr(Form.LINE, new Line2D.Double(-20, -20, 20, 20)));
+    }
+
+    static final Symbol NoticeRinfo = new Symbol();
+    static {
+        NoticeRinfo.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeRinfo.add(new Instr(Form.FILL, new Color(0xd40000)));
+        NoticeRinfo.add(new Instr(Form.RECT, new Rectangle2D.Double(-30, -30, 60, 60)));
+    }
+
+    public static final Symbol NoticeRnpas = new Symbol();
+    static {
+        NoticeRnpas.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRnpas.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
+        NoticeRnpas.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        NoticeRnpas.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRnank = new Symbol();
+    static {
+        NoticeRnank.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
+        NoticeRnank.add(new Instr(Form.SYMB, new Symbols.SubSymbol(Harbours.Anchor, 0.4, 0, 0, new Scheme(Color.black), null)));
+    }
+
+    public static final Symbol NoticeRnwsh = new Symbol();
+    static {
+        NoticeRnwsh.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRnwsh.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
+        NoticeRnwsh.add(new Instr(Form.FILL, Color.black));
+        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);
+        p.moveTo(-23, -3); p.curveTo(-11, -3, -12, -9, 0, -9); p.curveTo(12, -9, 11, -3, 23, -3);
+        NoticeRnwsh.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol NoticeRlmhr = new Symbol();
+    static {
+        NoticeRlmhr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRlmhr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
+        NoticeRlmhr.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -10); p.lineTo(27, -27); p.lineTo(-27, -27); p.closePath();
+        NoticeRlmhr.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRtrna = new Symbol();
+    static {
+        NoticeRtrna.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRtrna.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
+        NoticeRtrna.add(new Instr(Form.STRK, new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeRtrna.add(new Instr(Form.EARC, new Arc2D.Double(-15.0, -15.0, 30.0, 30.0, 315.0, -280.0, Arc2D.OPEN)));
+        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();
+        NoticeRtrna.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRncps = new Symbol();
+    static {
+        NoticeRncps.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRncps.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
+        NoticeRncps.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        NoticeRncps.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRnsmc = new Symbol();
+    static {
+        NoticeRnsmc.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRnsmc.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRphib, 1.0, 0, 0, null, null)));
+        NoticeRnsmc.add(new Instr(Form.FILL, Color.black));
+        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();
+        p.moveTo(-23, 2); p.lineTo(-21, 10); p.lineTo(-18, 8); p.lineTo(-20, 0); p.closePath();
+        NoticeRnsmc.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRattn = new Symbol();
+    static {
+        NoticeRattn.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRattn.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
+        NoticeRattn.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        NoticeRattn.add(new Instr(Form.FILL, Color.black));
+        NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0, -20, 0, 10)));
+        NoticeRattn.add(new Instr(Form.LINE, new Line2D.Double(0, 15, 0, 20)));
+    }
+
+    public static final Symbol NoticeRfwcr = new Symbol();
+    static {
+        NoticeRfwcr.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRfwcr.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeRinfo, 1.0, 0, 0, null, null)));
+        NoticeRfwcr.add(new Instr(Form.FILL, Color.black));
+        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);
+        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();
+        NoticeRfwcr.add(new Instr(Form.PGON, p));
+    }
+
+    public static final Symbol NoticeRship = new Symbol();
+    static {
+        NoticeRship.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -30, 60, 60)));
+        NoticeRship.add(new Instr(Form.SYMB, new Symbols.SubSymbol(NoticeCR, 1.0, 0, 0, null, null)));
+        NoticeRship.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER)));
+        NoticeRship.add(new Instr(Form.FILL, Color.black));
+        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12, -12, 10, 10)));
+        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(-12, -8, -8, -12)));
+        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12, -12, -10, 10)));
+        NoticeRship.add(new Instr(Form.LINE, new Line2D.Double(12, -8, 8, -12)));
+        NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-17, -13, 30, 30, 185, 80, Arc2D.OPEN)));
+        NoticeRship.add(new Instr(Form.EARC, new Arc2D.Double(-13, -13, 30, 30, 275, 80, Arc2D.OPEN)));
+    }
+
+    public static final EnumMap<CatNMK, Symbol> NmkPpwbcl = new EnumMap<>(CatNMK.class);
+    static {
+        NmkPpwbcl.put(CatNMK.NMK_WRAL, NoticePwralL); NmkPpwbcl.put(CatNMK.NMK_WLAR, NoticePwlarL); NmkPpwbcl.put(CatNMK.NMK_KTPM, NoticePktmL); NmkPpwbcl.put(CatNMK.NMK_KTSM, NoticePktmL);
+        NmkPpwbcl.put(CatNMK.NMK_KTMR, NoticePktmrL); NmkPpwbcl.put(CatNMK.NMK_CRTP, NoticePcrL); NmkPpwbcl.put(CatNMK.NMK_CRTS, NoticePcrL);
+    }
+
+    public static final EnumMap<CatNMK, Symbol> NmkPpwbcr = new EnumMap<>(CatNMK.class);
+    static {
+        NmkPpwbcr.put(CatNMK.NMK_WRAL, NoticePwralR); NmkPpwbcr.put(CatNMK.NMK_WLAR, NoticePwlarR); NmkPpwbcr.put(CatNMK.NMK_KTPM, NoticePktmR); NmkPpwbcr.put(CatNMK.NMK_KTSM, NoticePktmR);
+        NmkPpwbcr.put(CatNMK.NMK_KTMR, NoticePktmrR); NmkPpwbcr.put(CatNMK.NMK_CRTP, NoticePcrR); NmkPpwbcr.put(CatNMK.NMK_CRTS, NoticePcrR);
+    }
+
+    public static final EnumMap<CatNMK, Symbol> NmkRiwr = new EnumMap<>(CatNMK.class);
+    static {
+        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);
+        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);
+    }
+
+    public static Scheme getScheme(MarSYS sys, BnkWTW bank) {
+        ArrayList<Color> colours = new ArrayList<>();
+        Scheme scheme = new Scheme(colours);
+        switch (sys) {
+        case SYS_BNWR:
+        case SYS_BWR2:
+            switch (bank) {
+            case BWW_LEFT:
+                colours.add(Color.white);
+                colours.add(new Color(0xf00000));
+                break;
+            case BWW_RGHT:
+                colours.add(Color.white);
+                colours.add(new Color(0x00a000));
+                break;
+            default:
+                colours.add(new Color(0xff8040));
+                colours.add(Color.black);
+                break;
+            }
+            break;
+        default:
+            break;
+        }
+        return scheme;
+    }
+
+    public static Symbol getNotice(CatNMK cat, MarSYS sys, BnkWTW bank) {
+        Symbol symbol = null;
+        switch (sys) {
+        case SYS_CEVN:
+            symbol = NmkCevni.get(cat);
+            break;
+        case SYS_BNWR:
+        case SYS_BWR2:
+            symbol = NmkBniwr.get(cat);
+            break;
+        case SYS_PPWB:
+            switch (bank) {
+            case BWW_LEFT:
+                symbol = NmkPpwbcl.get(cat);
+                break;
+            case BWW_RGHT:
+                symbol = NmkPpwbcr.get(cat);
+                break;
+            default:
+                break;
+            }
+            break;
+        case SYS_RIWR:
+            symbol = NmkRiwr.get(cat);
+            break;
+        default:
+            break;
+        }
+        return symbol;
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Symbols.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Symbols.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Symbols.java	(revision 32394)
@@ -15,411 +15,426 @@
 import java.awt.Graphics2D;
 import java.awt.font.TextLayout;
-import java.awt.geom.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RectangularShape;
+import java.awt.geom.RoundRectangle2D;
 import java.util.ArrayList;
 
 public class Symbols {
-
-	public static final Color Yland = new Color(0xedbc0c);
-//	public static final Color Bwater = new Color(0x78acd2);
-	public static final Color Bwater = new Color(0x9bc5e3);
-	public static final Color Gdries = new Color(0x689868);
-	public static final Color Mline = new Color(0x9a6078);
-	public static final Color Msymb = new Color(0xa30075);
-	public static final Color Mtss = new Color(0xc0c480ff, true);
-	
-	public enum Form {
-		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
-	}
-
-	public enum Patt {
-		Z, H, V, D, B, S, C, X
-	}
-
-	public enum Handle {
-		CC, TL, TR, TC, LC, RC, BL, BR, BC
-	}
-
-	public static class Instr {
-		public Form type;
-		public Object params;
-
-		public Instr(Form itype, Object iparams) {
-			type = itype;
-			params = iparams;
-		}
-	}
-
-	public static class Delta {
-		public Handle h;
-		public AffineTransform t;
-
-		public Delta(Handle ih, AffineTransform it) {
-			h = ih;
-			t = it;
-		}
-		public Delta(Handle ih) {
-			h = ih;
-			t = new AffineTransform();
-		}
-	}
-
-	public static class Scheme {
-		public ArrayList<Patt> pat;
-		public ArrayList<Color> col;
-
-		public Scheme(ArrayList<Color> icol) {
-			pat = new ArrayList<>();
-			col = icol;
-		}
-		public Scheme(ArrayList<Patt> ipat, ArrayList<Color> icol) {
-			pat = ipat;
-			col = icol;
-		}
-		public Scheme(Color icol) {
-			pat = new ArrayList<>();
-			col = new ArrayList<>();
-			col.add(icol);
-		}
-		public Scheme() {
-			pat = new ArrayList<>();
-			col = new ArrayList<>();
-		}
-	}
-
-	public static class Caption {
-		public String string;
-		public Font font;
-		public Color colour;
-		public Delta dd;
-
-		public Caption(String istr, Font ifont, Color icolour, Delta idd) {
-			string = istr;
-			font = ifont;
-			colour = icolour;
-			dd = idd;
-		}
-	}
-
-	public static class LineStyle {
-		public Color line;
-		public float width;
-		public float[] dash;
-		public Color fill;
-
-		public LineStyle(Color ifill) {
-			line = null;
-			width = 0;
-			dash = null;
-			fill = ifill;
-		}
-		public LineStyle(Color iline, float iwidth) {
-			line = iline;
-			width = iwidth;
-			dash = null;
-			fill = null;
-		}
-		public LineStyle(Color iline, float iwidth, float[] idash) {
-			line = iline;
-			width = iwidth;
-			dash = idash;
-			fill = null;
-		}
-		public LineStyle(Color iline, float iwidth, Color ifill) {
-			line = iline;
-			width = iwidth;
-			dash = null;
-			fill = ifill;
-		}
-		public LineStyle(Color iline, float iwidth, float[] idash, Color ifill) {
-			line = iline;
-			width = iwidth;
-			dash = idash;
-			fill = ifill;
-		}
-	}
-
-	public static class Symbol extends ArrayList<Instr> {
-
-		public Symbol() {
-			super();
-		}
-	}
-	
-	public static class SubSymbol {
-		public Symbol instr;
-		public double scale;
-		public double x;
-		public double y;
-		public Delta delta;
-		public Scheme scheme;
-
-		public SubSymbol(Symbol iinstr, double iscale, double ix, double iy, Scheme ischeme, Delta idelta) {
-			instr = iinstr;
-			scale = iscale;
-			x = ix;
-			y = iy;
-			delta = idelta;
-			scheme = ischeme;
-		}
-	}
-
-	public static void drawSymbol(Graphics2D g2, Symbol symbol, double scale, double x, double y, Scheme cs, Delta dd) {
-		int pn = 0;
-		int cn = 0;
-		Patt bpat = Patt.Z;
-		Color bcol = null;
-		g2.setPaint(Color.black);
-		if (cs != null) {
-			if ((cs.pat.size() > 0) && (cs.col.size() > 0) && (cs.pat.get(0) == Patt.B)) {
-				bpat = (cs.pat.remove(0));
-				bcol = (cs.col.remove(0));
-			}
-			pn = cs.pat.size();
-			cn = cs.col.size() - ((pn != 0) ? pn - 1 : 0);
-			if ((pn == 0) && (cs.col.size() == 1)) {
-				g2.setPaint(cs.col.get(0));
-			}
-		}
-		AffineTransform savetr = g2.getTransform();
-		g2.translate(x, y);
-		g2.scale(scale, scale);
-		if (symbol != null) {
-			for (Instr item : symbol) {
-				switch (item.type) {
-				case BBOX:
-					Rectangle2D.Double bbox = (Rectangle2D.Double) item.params;
-					double dx = 0.0;
-					double dy = 0.0;
-					if (dd != null) {
-						g2.transform(dd.t);
-						switch (dd.h) {
-						case CC:
-							dx -= bbox.x + (bbox.width / 2.0);
-							dy -= bbox.y + (bbox.height / 2.0);
-							break;
-						case TL:
-							dx -= bbox.x;
-							dy -= bbox.y;
-							break;
-						case TR:
-							dx -= bbox.x + bbox.width;
-							dy -= bbox.y;
-							break;
-						case TC:
-							dx -= bbox.x + (bbox.width / 2.0);
-							dy -= bbox.y;
-							break;
-						case LC:
-							dx -= bbox.x;
-							dy -= bbox.y + (bbox.height / 2.0);
-							break;
-						case RC:
-							dx -= bbox.x + bbox.width;
-							dy -= bbox.y + (bbox.height / 2.0);
-							break;
-						case BL:
-							dx -= bbox.x;
-							dy -= bbox.y + bbox.height;
-							break;
-						case BR:
-							dx -= bbox.x + bbox.width;
-							dy -= bbox.y + bbox.height;
-							break;
-						case BC:
-							dx -= bbox.x + (bbox.width / 2.0);
-							dy -= bbox.y + bbox.height;
-							break;
-						}
-						g2.translate(dx, dy);
-					}
-					break;
-				case COLR:
-					if ((cs != null) && (cs.col != null)) {
-						for (Instr patch : (Symbol) item.params) {
-							switch (patch.type) {
-							case N1:
-								if (cn > 0) {
-									Symbol s = (Symbol) patch.params;
-									drawSymbol(g2, s, 1.0, 0, 0, new Scheme(cs.col.get(0)), null);
-								}
-								break;
-							case N2:
-								if (cn > 0) {
-									Symbol s = (Symbol) patch.params;
-									drawSymbol(g2, s, 1.0, 0, 0, new Scheme((cn > 1) ? cs.col.get(1) : cs.col.get(0)), null);
-								}
-								break;
-							case P1:
-								if (cn > 0) {
-									g2.setPaint(cs.col.get(0));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case P2:
-								if (cn > 0) {
-									if (cn > 1) {
-										g2.setPaint(cs.col.get(1));
-									} else {
-										g2.setPaint(cs.col.get(0));
-									}
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case H2:
-								if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
-									g2.setPaint(cs.col.get(cs.col.size() - pn));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case H3:
-								if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
-									g2.setPaint(cs.col.get(1));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case H4:
-								if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
-									g2.setPaint(cs.col.get(1));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case H5:
-								if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
-									g2.setPaint(cs.col.get(2));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case V2:
-								if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
-									g2.setPaint(cs.col.get(cs.col.size() - pn));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case V3:
-								if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
-									g2.setPaint(cs.col.get(1));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case B1:
-								if (bpat == Patt.B) {
-									g2.setPaint(bcol);
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case S2:
-								if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
-									g2.setPaint(cs.col.get(1));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case S3:
-								if ((cn > 2) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
-									g2.setPaint(cs.col.get(2));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							case S4:
-								if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
-									g2.setPaint(cs.col.get(3));
-									g2.fill((Path2D.Double) patch.params);
-								}
-								break;
-							default:
-								break;
-							}
-						}
-					}
-					break;
-				case STRK:
-					g2.setStroke((BasicStroke) item.params);
-					break;
-				case FILL:
-					g2.setPaint((Color) item.params);
-					break;
-				case LINE:
-					g2.draw((Line2D.Double) item.params);
-					break;
-				case RECT:
-					g2.draw((Rectangle2D.Double) item.params);
-					break;
-				case RRCT:
-					g2.draw((RoundRectangle2D.Double) item.params);
-					break;
-				case ELPS:
-					g2.draw((Ellipse2D.Double) item.params);
-					break;
-				case EARC:
-					g2.draw((Arc2D.Double) item.params);
-					break;
-				case PLIN:
-					g2.draw((Path2D.Double) item.params);
-					break;
-				case PGON:
-					g2.fill((Path2D.Double) item.params);
-					break;
-				case RSHP:
-					g2.fill((RectangularShape) item.params);
-					break;
-				case SYMB:
-					SubSymbol s = (SubSymbol) item.params;
-					drawSymbol(g2, s.instr, s.scale, s.x, s.y, (s.scheme != null ? s.scheme : cs), s.delta);
-					break;
-				case TEXT:
-					Caption c = (Caption) item.params;
-					g2.setPaint(c.colour);
-					TextLayout layout = new TextLayout(c.string, c.font, g2.getFontRenderContext());
-					Rectangle2D bb = layout.getBounds();
-					dx = 0;
-					dy = 0;
-					if (c.dd != null) {
-						if (c.dd.t != null) g2.transform(c.dd.t);
-						switch (c.dd.h) {
-						case CC:
-							dx -= bb.getX() + (bb.getWidth() / 2.0);
-							dy -= bb.getY() + (bb.getHeight() / 2.0);
-							break;
-						case TL:
-							dx -= bb.getX();
-							dy -= bb.getY();
-							break;
-						case TR:
-							dx -= bb.getX() + bb.getWidth();
-							dy -= bb.getY();
-							break;
-						case TC:
-							dx -= bb.getX() + (bb.getWidth() / 2.0);
-							dy -= bb.getY();
-							break;
-						case LC:
-							dx -= bb.getX();
-							dy -= bb.getY() + (bb.getHeight() / 2.0);
-							break;
-						case RC:
-							dx -= bb.getX() + bb.getWidth();
-							dy -= bb.getY() + (bb.getHeight() / 2.0);
-							break;
-						case BL:
-							dx -= bb.getX();
-							dy -= bb.getY() + bb.getHeight();
-							break;
-						case BR:
-							dx -= bb.getX() + bb.getWidth();
-							dy -= bb.getY() + bb.getHeight();
-							break;
-						case BC:
-							dx -= bb.getX() + (bb.getWidth() / 2.0);
-							dy -= bb.getY() + bb.getHeight();
-							break;
-						}
-					}
-					layout.draw(g2, (float)dx, (float)dy);
-					break;
-				default:
-					break;
-				}
-			}
-		}
-		g2.setTransform(savetr);
-	}
+    // CHECKSTYLE.OFF: LineLength
+    public static final Color Yland = new Color(0xedbc0c);
+    //    public static final Color Bwater = new Color(0x78acd2);
+    public static final Color Bwater = new Color(0x9bc5e3);
+    public static final Color Gdries = new Color(0x689868);
+    public static final Color Mline = new Color(0x9a6078);
+    public static final Color Msymb = new Color(0xa30075);
+    public static final Color Mtss = new Color(0xc0c480ff, true);
+
+    public enum Form {
+        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
+    }
+
+    public enum Patt {
+        Z, H, V, D, B, S, C, X
+    }
+
+    public enum Handle {
+        CC, TL, TR, TC, LC, RC, BL, BR, BC
+    }
+
+    public static class Instr {
+        public Form type;
+        public Object params;
+
+        public Instr(Form itype, Object iparams) {
+            type = itype;
+            params = iparams;
+        }
+    }
+
+    public static class Delta {
+        public Handle h;
+        public AffineTransform t;
+
+        public Delta(Handle ih, AffineTransform it) {
+            h = ih;
+            t = it;
+        }
+
+        public Delta(Handle ih) {
+            h = ih;
+            t = new AffineTransform();
+        }
+    }
+
+    public static class Scheme {
+        public ArrayList<Patt> pat;
+        public ArrayList<Color> col;
+
+        public Scheme(ArrayList<Color> icol) {
+            pat = new ArrayList<>();
+            col = icol;
+        }
+
+        public Scheme(ArrayList<Patt> ipat, ArrayList<Color> icol) {
+            pat = ipat;
+            col = icol;
+        }
+
+        public Scheme(Color icol) {
+            pat = new ArrayList<>();
+            col = new ArrayList<>();
+            col.add(icol);
+        }
+
+        public Scheme() {
+            pat = new ArrayList<>();
+            col = new ArrayList<>();
+        }
+    }
+
+    public static class Caption {
+        public String string;
+        public Font font;
+        public Color colour;
+        public Delta dd;
+
+        public Caption(String istr, Font ifont, Color icolour, Delta idd) {
+            string = istr;
+            font = ifont;
+            colour = icolour;
+            dd = idd;
+        }
+    }
+
+    public static class LineStyle {
+        public Color line;
+        public float width;
+        public float[] dash;
+        public Color fill;
+
+        public LineStyle(Color ifill) {
+            line = null;
+            width = 0;
+            dash = null;
+            fill = ifill;
+        }
+
+        public LineStyle(Color iline, float iwidth) {
+            line = iline;
+            width = iwidth;
+            dash = null;
+            fill = null;
+        }
+
+        public LineStyle(Color iline, float iwidth, float[] idash) {
+            line = iline;
+            width = iwidth;
+            dash = idash;
+            fill = null;
+        }
+
+        public LineStyle(Color iline, float iwidth, Color ifill) {
+            line = iline;
+            width = iwidth;
+            dash = null;
+            fill = ifill;
+        }
+
+        public LineStyle(Color iline, float iwidth, float[] idash, Color ifill) {
+            line = iline;
+            width = iwidth;
+            dash = idash;
+            fill = ifill;
+        }
+    }
+
+    public static class Symbol extends ArrayList<Instr> {
+
+        public Symbol() {
+            super();
+        }
+    }
+
+    public static class SubSymbol {
+        public Symbol instr;
+        public double scale;
+        public double x;
+        public double y;
+        public Delta delta;
+        public Scheme scheme;
+
+        public SubSymbol(Symbol iinstr, double iscale, double ix, double iy, Scheme ischeme, Delta idelta) {
+            instr = iinstr;
+            scale = iscale;
+            x = ix;
+            y = iy;
+            delta = idelta;
+            scheme = ischeme;
+        }
+    }
+
+    public static void drawSymbol(Graphics2D g2, Symbol symbol, double scale, double x, double y, Scheme cs, Delta dd) {
+        int pn = 0;
+        int cn = 0;
+        Patt bpat = Patt.Z;
+        Color bcol = null;
+        g2.setPaint(Color.black);
+        if (cs != null) {
+            if ((cs.pat.size() > 0) && (cs.col.size() > 0) && (cs.pat.get(0) == Patt.B)) {
+                bpat = (cs.pat.remove(0));
+                bcol = (cs.col.remove(0));
+            }
+            pn = cs.pat.size();
+            cn = cs.col.size() - ((pn != 0) ? pn - 1 : 0);
+            if ((pn == 0) && (cs.col.size() == 1)) {
+                g2.setPaint(cs.col.get(0));
+            }
+        }
+        AffineTransform savetr = g2.getTransform();
+        g2.translate(x, y);
+        g2.scale(scale, scale);
+        if (symbol != null) {
+            for (Instr item : symbol) {
+                switch (item.type) {
+                case BBOX:
+                    Rectangle2D.Double bbox = (Rectangle2D.Double) item.params;
+                    double dx = 0.0;
+                    double dy = 0.0;
+                    if (dd != null) {
+                        g2.transform(dd.t);
+                        switch (dd.h) {
+                        case CC:
+                            dx -= bbox.x + (bbox.width / 2.0);
+                            dy -= bbox.y + (bbox.height / 2.0);
+                            break;
+                        case TL:
+                            dx -= bbox.x;
+                            dy -= bbox.y;
+                            break;
+                        case TR:
+                            dx -= bbox.x + bbox.width;
+                            dy -= bbox.y;
+                            break;
+                        case TC:
+                            dx -= bbox.x + (bbox.width / 2.0);
+                            dy -= bbox.y;
+                            break;
+                        case LC:
+                            dx -= bbox.x;
+                            dy -= bbox.y + (bbox.height / 2.0);
+                            break;
+                        case RC:
+                            dx -= bbox.x + bbox.width;
+                            dy -= bbox.y + (bbox.height / 2.0);
+                            break;
+                        case BL:
+                            dx -= bbox.x;
+                            dy -= bbox.y + bbox.height;
+                            break;
+                        case BR:
+                            dx -= bbox.x + bbox.width;
+                            dy -= bbox.y + bbox.height;
+                            break;
+                        case BC:
+                            dx -= bbox.x + (bbox.width / 2.0);
+                            dy -= bbox.y + bbox.height;
+                            break;
+                        }
+                        g2.translate(dx, dy);
+                    }
+                    break;
+                case COLR:
+                    if ((cs != null) && (cs.col != null)) {
+                        for (Instr patch : (Symbol) item.params) {
+                            switch (patch.type) {
+                            case N1:
+                                if (cn > 0) {
+                                    Symbol s = (Symbol) patch.params;
+                                    drawSymbol(g2, s, 1.0, 0, 0, new Scheme(cs.col.get(0)), null);
+                                }
+                                break;
+                            case N2:
+                                if (cn > 0) {
+                                    Symbol s = (Symbol) patch.params;
+                                    drawSymbol(g2, s, 1.0, 0, 0, new Scheme((cn > 1) ? cs.col.get(1) : cs.col.get(0)), null);
+                                }
+                                break;
+                            case P1:
+                                if (cn > 0) {
+                                    g2.setPaint(cs.col.get(0));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case P2:
+                                if (cn > 0) {
+                                    if (cn > 1) {
+                                        g2.setPaint(cs.col.get(1));
+                                    } else {
+                                        g2.setPaint(cs.col.get(0));
+                                    }
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case H2:
+                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
+                                    g2.setPaint(cs.col.get(cs.col.size() - pn));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case H3:
+                                if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
+                                    g2.setPaint(cs.col.get(1));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case H4:
+                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
+                                    g2.setPaint(cs.col.get(1));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case H5:
+                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.H)) {
+                                    g2.setPaint(cs.col.get(2));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case V2:
+                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
+                                    g2.setPaint(cs.col.get(cs.col.size() - pn));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case V3:
+                                if ((cn == 3) && (pn > 0) && (cs.pat.get(0) == Patt.V)) {
+                                    g2.setPaint(cs.col.get(1));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case B1:
+                                if (bpat == Patt.B) {
+                                    g2.setPaint(bcol);
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case S2:
+                                if ((cn > 1) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
+                                    g2.setPaint(cs.col.get(1));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case S3:
+                                if ((cn > 2) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
+                                    g2.setPaint(cs.col.get(2));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            case S4:
+                                if ((cn == 4) && (pn > 0) && (cs.pat.get(0) == Patt.S)) {
+                                    g2.setPaint(cs.col.get(3));
+                                    g2.fill((Path2D.Double) patch.params);
+                                }
+                                break;
+                            default:
+                                break;
+                            }
+                        }
+                    }
+                    break;
+                case STRK:
+                    g2.setStroke((BasicStroke) item.params);
+                    break;
+                case FILL:
+                    g2.setPaint((Color) item.params);
+                    break;
+                case LINE:
+                    g2.draw((Line2D.Double) item.params);
+                    break;
+                case RECT:
+                    g2.draw((Rectangle2D.Double) item.params);
+                    break;
+                case RRCT:
+                    g2.draw((RoundRectangle2D.Double) item.params);
+                    break;
+                case ELPS:
+                    g2.draw((Ellipse2D.Double) item.params);
+                    break;
+                case EARC:
+                    g2.draw((Arc2D.Double) item.params);
+                    break;
+                case PLIN:
+                    g2.draw((Path2D.Double) item.params);
+                    break;
+                case PGON:
+                    g2.fill((Path2D.Double) item.params);
+                    break;
+                case RSHP:
+                    g2.fill((RectangularShape) item.params);
+                    break;
+                case SYMB:
+                    SubSymbol s = (SubSymbol) item.params;
+                    drawSymbol(g2, s.instr, s.scale, s.x, s.y, (s.scheme != null ? s.scheme : cs), s.delta);
+                    break;
+                case TEXT:
+                    Caption c = (Caption) item.params;
+                    g2.setPaint(c.colour);
+                    TextLayout layout = new TextLayout(c.string, c.font, g2.getFontRenderContext());
+                    Rectangle2D bb = layout.getBounds();
+                    dx = 0;
+                    dy = 0;
+                    if (c.dd != null) {
+                        if (c.dd.t != null) g2.transform(c.dd.t);
+                        switch (c.dd.h) {
+                        case CC:
+                            dx -= bb.getX() + (bb.getWidth() / 2.0);
+                            dy -= bb.getY() + (bb.getHeight() / 2.0);
+                            break;
+                        case TL:
+                            dx -= bb.getX();
+                            dy -= bb.getY();
+                            break;
+                        case TR:
+                            dx -= bb.getX() + bb.getWidth();
+                            dy -= bb.getY();
+                            break;
+                        case TC:
+                            dx -= bb.getX() + (bb.getWidth() / 2.0);
+                            dy -= bb.getY();
+                            break;
+                        case LC:
+                            dx -= bb.getX();
+                            dy -= bb.getY() + (bb.getHeight() / 2.0);
+                            break;
+                        case RC:
+                            dx -= bb.getX() + bb.getWidth();
+                            dy -= bb.getY() + (bb.getHeight() / 2.0);
+                            break;
+                        case BL:
+                            dx -= bb.getX();
+                            dy -= bb.getY() + bb.getHeight();
+                            break;
+                        case BR:
+                            dx -= bb.getX() + bb.getWidth();
+                            dy -= bb.getY() + bb.getHeight();
+                            break;
+                        case BC:
+                            dx -= bb.getX() + (bb.getWidth() / 2.0);
+                            dy -= bb.getY() + bb.getHeight();
+                            break;
+                        }
+                    }
+                    layout.draw(g2, (float) dx, (float) dy);
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        g2.setTransform(savetr);
+    }
 }
Index: applications/editors/josm/plugins/seachart/src/symbols/Topmarks.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Topmarks.java	(revision 32393)
+++ applications/editors/josm/plugins/seachart/src/symbols/Topmarks.java	(revision 32394)
@@ -12,495 +12,522 @@
 import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.geom.*;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
 import java.util.EnumMap;
 
-import s57.S57val.*;
-import symbols.Symbols.*;
+import s57.S57val.BoySHP;
+import s57.S57val.TopSHP;
+import symbols.Symbols.Delta;
+import symbols.Symbols.Form;
+import symbols.Symbols.Handle;
+import symbols.Symbols.Instr;
+import symbols.Symbols.Symbol;
 
 public class Topmarks {
-	
-	public static final Symbol RadarReflector = new Symbol();
-	static {
-		RadarReflector.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50,-40,100,40)));
-		RadarReflector.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		RadarReflector.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-30,-3); p.quadTo(0, -40, 30, -3); p.moveTo(0,-20); p.lineTo(0,-37);
-		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);
-		RadarReflector.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopBesom = new Symbol();
-	static {
-		TopBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		TopBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopBesom.add(new Instr(Form.FILL, Color.black));
-		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);
-		TopBesom.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopIBesom = new Symbol();
-	static {
-		TopIBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		TopIBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopIBesom.add(new Instr(Form.FILL, Color.black));
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0,-30.0); p.lineTo(0.0,0.0); p.lineTo(15.0,-30.0);
-		TopIBesom.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopBoard = new Symbol();
-	static {
-		TopBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-60,60,60)));
-		Symbol colours = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29,-1); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29,-1); p.closePath();
-		p.moveTo(-19,-10); p.lineTo(-19,-49); p.lineTo(19,-49); p.lineTo(19,-10); p.closePath();
-		colours.add(new Instr(Form.B1, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		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();
-		colours.add(new Instr(Form.S2, p));
-		p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-30); p.lineTo(0,-30); p.lineTo(0,-1); p.closePath();
-		colours.add(new Instr(Form.S3, p));
-		p = new Path2D.Double(); p.moveTo(0,-1); p.lineTo(0,-30); p.lineTo(29,-30); p.lineTo(29,-1); p.closePath();
-		colours.add(new Instr(Form.S4, p));
-		TopBoard.add(new Instr(Form.COLR, colours));
-		TopBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopBoard.add(new Instr(Form.FILL, Color.black));
-		p = new Path2D.Double(); p.moveTo(-29,-1); p.lineTo(-29,-59); p.lineTo(29,-59); p.lineTo(29.0,-1); p.closePath();
-		TopBoard.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopCan = new Symbol();
-	static {
-		TopCan.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopCan.add(new Instr(Form.COLR, colours));
-		TopCan.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopCan.add(new Instr(Form.FILL, Color.black));
-		TopCan.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		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();
-		TopCan.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopCanSphere = new Symbol();
-	public static final Symbol TopCircle = new Symbol();
-	public static final Symbol TopCircleTriangle = new Symbol();
-	public static final Symbol TopCone = new Symbol();
-	static {
-		TopCone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopCone.add(new Instr(Form.COLR, colours));
-		TopCone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopCone.add(new Instr(Form.FILL, Color.black));
-		TopCone.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		p = new Path2D.Double(); p.moveTo(-15.0,-15.0); p.lineTo(0.0,-45.0); p.lineTo(15.0,-15.0); p.closePath();
-		TopCone.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopConeSphere = new Symbol();
-	static {
-		TopConeSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopConeSphere.add(new Instr(Form.COLR, colours));
-		TopConeSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopConeSphere.add(new Instr(Form.FILL, Color.black));
-		TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0,-42,0,-47)));
-		p = new Path2D.Double(); p.moveTo(-15.0,-47.0); p.lineTo(0.0,-77.0); p.lineTo(15.0,-47.0); p.closePath();
-		TopConeSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-42,28,28)));
-		TopConeSphere.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopCross = new Symbol();
-	static {
-		TopCross.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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);
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopCross.add(new Instr(Form.COLR, colours));
-		TopCross.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopCross.add(new Instr(Form.FILL, Color.black));
-		TopCross.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		TopCross.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		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();
-		TopCross.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopCrosses = new Symbol();
-	static {
-		
-	}
-	public static final Symbol TopCrossCircle = new Symbol();
-	static {
-		
-	}
-	public static final Symbol TopCube = new Symbol();
-	static {
-		TopCube.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopCube.add(new Instr(Form.COLR, colours));
-		TopCube.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopCube.add(new Instr(Form.FILL, Color.black));
-		TopCube.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		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);
-		p.moveTo(-15,-37); p.lineTo(-15,-20); p.lineTo(0,-9); p.lineTo(15,-20); p.lineTo(15,-37);
-		TopCube.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopEast = new Symbol();
-	static {
-		TopEast.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
-		colours.add(new Instr(Form.P2, p));
-		TopEast.add(new Instr(Form.COLR, colours));
-		TopEast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopEast.add(new Instr(Form.FILL, Color.black));
-		TopEast.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
-		TopEast.add(new Instr(Form.LINE, new Line2D.Double(0,-43,0,-47)));
-		TopEast.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
-		p.moveTo(0.0,-80.0); p.lineTo(-15.0,-47.0);  p.lineTo(15.0,-47.0); p.closePath();
-		TopEast.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopFlag = new Symbol();
-	static {
-		TopFlag.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		Path2D.Double p = new Path2D.Double(); p.moveTo(0,-40); p.lineTo(0,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(0,-10); p.lineTo(40,-10); p.lineTo(39,-25); p.closePath();
-		colours.add(new Instr(Form.H2, p));
-		p = new Path2D.Double(); p.moveTo(0,-30); p.lineTo(0,-20); p.lineTo(40,-20); p.lineTo(39,-30); p.closePath();
-		colours.add(new Instr(Form.H3, p));
-		p = new Path2D.Double(); p.moveTo(19.5,-40); p.lineTo(19.5,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
-		colours.add(new Instr(Form.V2, p));
-		p = new Path2D.Double(); p.moveTo(13,-40); p.lineTo(13,-10); p.lineTo(26,-10); p.lineTo(26,-40); p.closePath();
-		colours.add(new Instr(Form.V3, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(0,-40); p.lineTo(0,-10); p.lineTo(39,-10); p.lineTo(39,-40); p.closePath();
-		p.moveTo(8,-35); p.lineTo(8,-15); p.lineTo(33,-15); p.lineTo(33,-35); p.closePath();
-		colours.add(new Instr(Form.B1, p));
-		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();
-		colours.add(new Instr(Form.S2, p));
-		p = new Path2D.Double(); p.moveTo(0,-25); p.lineTo(0,-10); p.lineTo(20,-10); p.lineTo(20,-25); p.closePath();
-		colours.add(new Instr(Form.S3, p));
-		p = new Path2D.Double(); p.moveTo(20,-25); p.lineTo(20,-10); p.lineTo(39,-10); p.lineTo(39,-25); p.closePath();
-		colours.add(new Instr(Form.S4, p));
-		TopFlag.add(new Instr(Form.COLR, colours));
-		TopFlag.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopFlag.add(new Instr(Form.FILL, Color.black));
-		TopFlag.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-45)));
-		TopFlag.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopFlag.add(new Instr(Form.RECT, new Rectangle2D.Double(0,-40,39,30)));
-	}
-	public static final Symbol TopIcone = new Symbol();
-	static {
-		TopIcone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopIcone.add(new Instr(Form.COLR, colours));
-		TopIcone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopIcone.add(new Instr(Form.FILL, Color.black));
-		TopIcone.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		p = new Path2D.Double(); p.moveTo(-15.0,-45.0); p.lineTo(0.0,-15.0); p.lineTo(15.0,-45.0); p.closePath();
-		TopIcone.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopIsol = new Symbol();
-	static {
-		TopIsol.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-		colours.add(new Instr(Form.P2, p));
-		TopIsol.add(new Instr(Form.COLR, colours));
-		TopIsol.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopIsol.add(new Instr(Form.FILL, Color.black));
-		TopIsol.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		TopIsol.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13,-41,26,26)));
-		TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13,-68,26,26)));
-	}
-	public static final Symbol TopMooring = new Symbol();
-	static {
-		TopMooring.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		TopMooring.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopMooring.add(new Instr(Form.FILL, Color.black));
-		TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.5,-6,3,3)));
-		TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-8.5,-25,17,17)));
-	}
-	public static final Symbol TopNorth = new Symbol();
-	static {
-		TopNorth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
-		colours.add(new Instr(Form.P2, p));
-		TopNorth.add(new Instr(Form.COLR, colours));
-		TopNorth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopNorth.add(new Instr(Form.FILL, Color.black));
-		TopNorth.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
-		TopNorth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
-		p.moveTo(0.0,-78.0); p.lineTo(-15.0,-45.0);  p.lineTo(15.0,-45.0); p.closePath();
-		TopNorth.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopSouth = new Symbol();
-	static {
-		TopSouth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
-		colours.add(new Instr(Form.P2, p));
-		TopSouth.add(new Instr(Form.COLR, colours));
-		TopSouth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSouth.add(new Instr(Form.FILL, Color.black));
-		TopSouth.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
-		TopSouth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(0.0,-10.0); p.lineTo(-15.0,-43.0); p.lineTo(15.0,-43.0); p.closePath();
-		p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
-		TopSouth.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopSphere = new Symbol();
-	static {
-		TopSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopSphere.add(new Instr(Form.COLR, colours));
-		TopSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSphere.add(new Instr(Form.FILL, Color.black));
-		TopSphere.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-15)));
-		TopSphere.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-42,28,28)));
-	}
-	public static final Symbol TopSquare = new Symbol();
-	static {
-		TopSquare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		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();
-		colours.add(new Instr(Form.H2, p));
-		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();
-		colours.add(new Instr(Form.H3, p));
-		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();
-		colours.add(new Instr(Form.V2, p));
-		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();
-		colours.add(new Instr(Form.V3, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		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();
-		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();
-		colours.add(new Instr(Form.B1, p));
-		TopSquare.add(new Instr(Form.COLR, colours));
-		TopSquare.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSquare.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopSquare.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopRectangleH = new Symbol();
-	static {
-		TopRectangleH.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopRectangleH.add(new Instr(Form.COLR, colours));
-		TopRectangleH.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopRectangleH.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopRectangleH.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopRectangleV = new Symbol();
-	static {
-		TopRectangleV.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopRectangleV.add(new Instr(Form.COLR, colours));
-		TopRectangleV.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopRectangleV.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopRectangleV.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopRhombus = new Symbol();
-	static {
-		TopRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(-15.0,-15.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
-		colours.add(new Instr(Form.H2, p));
-		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();
-		colours.add(new Instr(Form.H3, p));
-		p = new Path2D.Double();  p.moveTo(0.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-15.0); p.closePath();
-		colours.add(new Instr(Form.V2, p));
-		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();
-		colours.add(new Instr(Form.V3, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		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();
-		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();
-		colours.add(new Instr(Form.B1, p));
-		TopRhombus.add(new Instr(Form.COLR, colours));
-		TopRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopRhombus.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopRhombus.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopRhombusCircle = new Symbol();
-	static {
-		
-	}
-	public static final Symbol TopSphereRhombus = new Symbol();
-	static {
-		TopSphereRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		TopSphereRhombus.add(new Instr(Form.SYMB, new Symbols.SubSymbol(TopRhombus, 1.0, 0, 0, null, null)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopSphereRhombus.add(new Instr(Form.COLR, colours));
-		TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSphereRhombus.add(new Instr(Form.FILL, Color.black));
-		TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopSphereRhombus.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14,-58,28,28)));
-	}
-	public static final Symbol TopT = new Symbol();
-	static {
-		
-	}
-	public static final Symbol TopTrapeziumU = new Symbol();
-	static {
-		TopTrapeziumU.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopTrapeziumU.add(new Instr(Form.COLR, colours));
-		TopTrapeziumU.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopTrapeziumU.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopTrapeziumU.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopTrapeziumD = new Symbol();
-	static {
-		TopTrapeziumD.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopTrapeziumD.add(new Instr(Form.COLR, colours));
-		TopTrapeziumD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopTrapeziumD.add(new Instr(Form.FILL, Color.black));
-		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();
-		TopTrapeziumD.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopTriangle = new Symbol();
-	static {
-		TopTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-15.0,-1.0); p.lineTo(0.0,-29.0); p.lineTo(15.0,-1.0); p.closePath();
-		p.moveTo(-10.0,-6.0); p.lineTo(0.0,-24.0); p.lineTo(10.0,-6.0); p.closePath();
-		colours.add(new Instr(Form.B1, p));
-		TopTriangle.add(new Instr(Form.COLR, colours));
-		TopTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopTriangle.add(new Instr(Form.FILL, Color.black));
-		p = new Path2D.Double(); p.moveTo(-15.0,-1.0); p.lineTo(0.0,-29.0); p.lineTo(15.0,-1.0); p.closePath();
-		TopTriangle.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopItriangle = new Symbol();
-	static {
-		TopItriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20,-80,40,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
-		p.moveTo(-15.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-29.0); p.closePath();
-		p.moveTo(-10.0,-24.0); p.lineTo(0.0,-6.0); p.lineTo(10.0,-24.0); p.closePath();
-		colours.add(new Instr(Form.B1, p));
-		TopItriangle.add(new Instr(Form.COLR, colours));
-		TopItriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopItriangle.add(new Instr(Form.FILL, Color.black));
-		p = new Path2D.Double(); p.moveTo(-15.0,-29.0); p.lineTo(0.0,-1.0); p.lineTo(15.0,-29.0); p.closePath();
-		TopItriangle.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopTriangleCircle = new Symbol();
-	static {
-		
-	}
-	public static final Symbol TopWest = new Symbol();
-	static {
-		TopWest.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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();
-		colours.add(new Instr(Form.P1, p));
-		p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
-		colours.add(new Instr(Form.P2, p));
-		TopWest.add(new Instr(Form.COLR, colours));
-		TopWest.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopWest.add(new Instr(Form.FILL, Color.black));
-		TopWest.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-10)));
-		TopWest.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		p = new Path2D.Double(); p.moveTo(-15.0,-10.0); p.lineTo(0.0,-43.0); p.lineTo(15.0,-10.0); p.closePath();
-		p.moveTo(-15.0,-78.0); p.lineTo(0.0,-45.0);  p.lineTo(15.0,-78.0); p.closePath();
-		TopWest.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopX = new Symbol();
-	static {
-		TopX.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30,-80,60,80)));
-		Symbol colours = new Symbol();
-		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);
-		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();
-		colours.add(new Instr(Form.P1, p));
-		TopX.add(new Instr(Form.COLR, colours));
-		TopX.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		TopX.add(new Instr(Form.FILL, Color.black));
-		TopX.add(new Instr(Form.LINE, new Line2D.Double(0,0,0,-27)));
-		TopX.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
-		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);
-		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();
-		TopX.add(new Instr(Form.PLIN, p));
-	}
-	public static final Symbol TopOther = new Symbol();
-	static {
-		
-	}
-	
-	public static final EnumMap<TopSHP, Symbol> Shapes = new EnumMap<>(TopSHP.class);
-	static {
-		Shapes.put(TopSHP.TOP_BESM, TopBesom); Shapes.put(TopSHP.TOP_IBESM, TopIBesom); Shapes.put(TopSHP.TOP_BORD, TopBoard); Shapes.put(TopSHP.TOP_CAN, TopCan);
-		Shapes.put(TopSHP.TOP_CONE, TopCone); Shapes.put(TopSHP.TOP_CROS, TopCross); Shapes.put(TopSHP.TOP_EAST, TopEast); Shapes.put(TopSHP.TOP_ICONE, TopIcone);
-		Shapes.put(TopSHP.TOP_ISD, TopIsol); Shapes.put(TopSHP.TOP_NORTH, TopNorth); Shapes.put(TopSHP.TOP_SOUTH, TopSouth); Shapes.put(TopSHP.TOP_SPHR, TopSphere);
-		Shapes.put(TopSHP.TOP_SQUR, TopSquare); Shapes.put(TopSHP.TOP_TRI, TopTriangle); Shapes.put(TopSHP.TOP_ITRI, TopItriangle); Shapes.put(TopSHP.TOP_WEST, TopWest);
-		Shapes.put(TopSHP.TOP_SALT, TopX); Shapes.put(TopSHP.TOP_RHOM, TopRhombus); Shapes.put(TopSHP.TOP_FLAG, TopFlag); Shapes.put(TopSHP.TOP_CUBE, TopCube);
-		Shapes.put(TopSHP.TOP_SPRH, TopSphereRhombus); Shapes.put(TopSHP.TOP_HRECT, TopRectangleH); Shapes.put(TopSHP.TOP_VRECT, TopRectangleV);
-		Shapes.put(TopSHP.TOP_TRAP, TopTrapeziumU); Shapes.put(TopSHP.TOP_ITRAP, TopTrapeziumD); Shapes.put(TopSHP.TOP_COSP, TopConeSphere);
-		Shapes.put(TopSHP.TOP_CIRC, TopCircle); Shapes.put(TopSHP.TOP_CRSS, TopCrosses); Shapes.put(TopSHP.TOP_T, TopT); Shapes.put(TopSHP.TOP_TRCL, TopTriangleCircle);
-		Shapes.put(TopSHP.TOP_CRCL, TopCrossCircle); Shapes.put(TopSHP.TOP_RHCL, TopRhombusCircle); Shapes.put(TopSHP.TOP_CLTR, TopCircleTriangle);
-		Shapes.put(TopSHP.TOP_CYSP, TopCanSphere); Shapes.put(TopSHP.TOP_OTHR, TopOther);
-	}
-
-	public static final EnumMap<BoySHP, Delta> BuoyDeltas = new EnumMap<>(BoySHP.class);
-	static {
-		BuoyDeltas.put(BoySHP.BOY_PILR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0))); 
-		BuoyDeltas.put(BoySHP.BOY_SPAR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0))); 
-		BuoyDeltas.put(BoySHP.BOY_CAN, new Delta(Handle.BC,  new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9))); 
-		BuoyDeltas.put(BoySHP.BOY_CONE, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9))); 
-		BuoyDeltas.put(BoySHP.BOY_SPHR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9))); 
-		BuoyDeltas.put(BoySHP.BOY_BARL, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9))); 
-		BuoyDeltas.put(BoySHP.BOY_SUPR, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0))); 
-		BuoyDeltas.put(BoySHP.BOY_ICE, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -25.0))); 
-	}
-	public static final Delta FloatDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0));
-	public static final Delta BeaconDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -70.0));
-	public static final Delta LightDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -20.0));
-
+    // CHECKSTYLE.OFF: LineLength
+    public static final Symbol RadarReflector = new Symbol();
+    static {
+        RadarReflector.add(new Instr(Form.BBOX, new Rectangle2D.Double(-50, -40, 100, 40)));
+        RadarReflector.add(new Instr(Form.STRK, new BasicStroke(6, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        RadarReflector.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-30, -3); p.quadTo(0, -40, 30, -3); p.moveTo(0, -20); p.lineTo(0, -37);
+        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);
+        RadarReflector.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopBesom = new Symbol();
+    static {
+        TopBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        TopBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopBesom.add(new Instr(Form.FILL, Color.black));
+        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);
+        TopBesom.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopIBesom = new Symbol();
+    static {
+        TopIBesom.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        TopIBesom.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopIBesom.add(new Instr(Form.FILL, Color.black));
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-15.0, -30.0); p.lineTo(0.0, 0.0); p.lineTo(15.0, -30.0);
+        TopIBesom.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopBoard = new Symbol();
+    static {
+        TopBoard.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -60, 60, 60)));
+        Symbol colours = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29, -1); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29, -1); p.closePath();
+        p.moveTo(-19, -10); p.lineTo(-19, -49); p.lineTo(19, -49); p.lineTo(19, -10); p.closePath();
+        colours.add(new Instr(Form.B1, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        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();
+        colours.add(new Instr(Form.S2, p));
+        p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -30); p.lineTo(0, -30); p.lineTo(0, -1); p.closePath();
+        colours.add(new Instr(Form.S3, p));
+        p = new Path2D.Double(); p.moveTo(0, -1); p.lineTo(0, -30); p.lineTo(29, -30); p.lineTo(29, -1); p.closePath();
+        colours.add(new Instr(Form.S4, p));
+        TopBoard.add(new Instr(Form.COLR, colours));
+        TopBoard.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopBoard.add(new Instr(Form.FILL, Color.black));
+        p = new Path2D.Double(); p.moveTo(-29, -1); p.lineTo(-29, -59); p.lineTo(29, -59); p.lineTo(29.0, -1); p.closePath();
+        TopBoard.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopCan = new Symbol();
+    static {
+        TopCan.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopCan.add(new Instr(Form.COLR, colours));
+        TopCan.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopCan.add(new Instr(Form.FILL, Color.black));
+        TopCan.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        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();
+        TopCan.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopCanSphere = new Symbol();
+    public static final Symbol TopCircle = new Symbol();
+    public static final Symbol TopCircleTriangle = new Symbol();
+    public static final Symbol TopCone = new Symbol();
+    static {
+        TopCone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopCone.add(new Instr(Form.COLR, colours));
+        TopCone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopCone.add(new Instr(Form.FILL, Color.black));
+        TopCone.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        p = new Path2D.Double(); p.moveTo(-15.0, -15.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -15.0); p.closePath();
+        TopCone.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopConeSphere = new Symbol();
+    static {
+        TopConeSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopConeSphere.add(new Instr(Form.COLR, colours));
+        TopConeSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopConeSphere.add(new Instr(Form.FILL, Color.black));
+        TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        TopConeSphere.add(new Instr(Form.LINE, new Line2D.Double(0, -42, 0, -47)));
+        p = new Path2D.Double(); p.moveTo(-15.0, -47.0); p.lineTo(0.0, -77.0); p.lineTo(15.0, -47.0); p.closePath();
+        TopConeSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -42, 28, 28)));
+        TopConeSphere.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopCross = new Symbol();
+    static {
+        TopCross.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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);
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopCross.add(new Instr(Form.COLR, colours));
+        TopCross.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopCross.add(new Instr(Form.FILL, Color.black));
+        TopCross.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        TopCross.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        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();
+        TopCross.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopCrosses = new Symbol();
+
+    public static final Symbol TopCrossCircle = new Symbol();
+
+    public static final Symbol TopCube = new Symbol();
+    static {
+        TopCube.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopCube.add(new Instr(Form.COLR, colours));
+        TopCube.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopCube.add(new Instr(Form.FILL, Color.black));
+        TopCube.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        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);
+        p.moveTo(-15, -37); p.lineTo(-15, -20); p.lineTo(0, -9); p.lineTo(15, -20); p.lineTo(15, -37);
+        TopCube.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopEast = new Symbol();
+    static {
+        TopEast.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
+        colours.add(new Instr(Form.P2, p));
+        TopEast.add(new Instr(Form.COLR, colours));
+        TopEast.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopEast.add(new Instr(Form.FILL, Color.black));
+        TopEast.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
+        TopEast.add(new Instr(Form.LINE, new Line2D.Double(0, -43, 0, -47)));
+        TopEast.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
+        p.moveTo(0.0, -80.0); p.lineTo(-15.0, -47.0); p.lineTo(15.0, -47.0); p.closePath();
+        TopEast.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopFlag = new Symbol();
+    static {
+        TopFlag.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        Path2D.Double p = new Path2D.Double(); p.moveTo(0, -40); p.lineTo(0, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(0, -10); p.lineTo(40, -10); p.lineTo(39, -25); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        p = new Path2D.Double(); p.moveTo(0, -30); p.lineTo(0, -20); p.lineTo(40, -20); p.lineTo(39, -30); p.closePath();
+        colours.add(new Instr(Form.H3, p));
+        p = new Path2D.Double(); p.moveTo(19.5, -40); p.lineTo(19.5, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
+        colours.add(new Instr(Form.V2, p));
+        p = new Path2D.Double(); p.moveTo(13, -40); p.lineTo(13, -10); p.lineTo(26, -10); p.lineTo(26, -40); p.closePath();
+        colours.add(new Instr(Form.V3, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(0, -40); p.lineTo(0, -10); p.lineTo(39, -10); p.lineTo(39, -40); p.closePath();
+        p.moveTo(8, -35); p.lineTo(8, -15); p.lineTo(33, -15); p.lineTo(33, -35); p.closePath();
+        colours.add(new Instr(Form.B1, p));
+        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();
+        colours.add(new Instr(Form.S2, p));
+        p = new Path2D.Double(); p.moveTo(0, -25); p.lineTo(0, -10); p.lineTo(20, -10); p.lineTo(20, -25); p.closePath();
+        colours.add(new Instr(Form.S3, p));
+        p = new Path2D.Double(); p.moveTo(20, -25); p.lineTo(20, -10); p.lineTo(39, -10); p.lineTo(39, -25); p.closePath();
+        colours.add(new Instr(Form.S4, p));
+        TopFlag.add(new Instr(Form.COLR, colours));
+        TopFlag.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopFlag.add(new Instr(Form.FILL, Color.black));
+        TopFlag.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -45)));
+        TopFlag.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopFlag.add(new Instr(Form.RECT, new Rectangle2D.Double(0, -40, 39, 30)));
+    }
+
+    public static final Symbol TopIcone = new Symbol();
+    static {
+        TopIcone.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopIcone.add(new Instr(Form.COLR, colours));
+        TopIcone.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopIcone.add(new Instr(Form.FILL, Color.black));
+        TopIcone.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        p = new Path2D.Double(); p.moveTo(-15.0, -45.0); p.lineTo(0.0, -15.0); p.lineTo(15.0, -45.0); p.closePath();
+        TopIcone.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopIsol = new Symbol();
+    static {
+        TopIsol.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.P2, p));
+        TopIsol.add(new Instr(Form.COLR, colours));
+        TopIsol.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopIsol.add(new Instr(Form.FILL, Color.black));
+        TopIsol.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        TopIsol.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13, -41, 26, 26)));
+        TopIsol.add(new Instr(Form.ELPS, new Ellipse2D.Double(-13, -68, 26, 26)));
+    }
+
+    public static final Symbol TopMooring = new Symbol();
+    static {
+        TopMooring.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        TopMooring.add(new Instr(Form.STRK, new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopMooring.add(new Instr(Form.FILL, Color.black));
+        TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-1.5, -6, 3, 3)));
+        TopMooring.add(new Instr(Form.ELPS, new Ellipse2D.Double(-8.5, -25, 17, 17)));
+    }
+
+    public static final Symbol TopNorth = new Symbol();
+    static {
+        TopNorth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
+        colours.add(new Instr(Form.P2, p));
+        TopNorth.add(new Instr(Form.COLR, colours));
+        TopNorth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopNorth.add(new Instr(Form.FILL, Color.black));
+        TopNorth.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
+        TopNorth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
+        p.moveTo(0.0, -78.0); p.lineTo(-15.0, -45.0); p.lineTo(15.0, -45.0); p.closePath();
+        TopNorth.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopSouth = new Symbol();
+    static {
+        TopSouth.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
+        colours.add(new Instr(Form.P2, p));
+        TopSouth.add(new Instr(Form.COLR, colours));
+        TopSouth.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSouth.add(new Instr(Form.FILL, Color.black));
+        TopSouth.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
+        TopSouth.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(0.0, -10.0); p.lineTo(-15.0, -43.0); p.lineTo(15.0, -43.0); p.closePath();
+        p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
+        TopSouth.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopSphere = new Symbol();
+    static {
+        TopSphere.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopSphere.add(new Instr(Form.COLR, colours));
+        TopSphere.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSphere.add(new Instr(Form.FILL, Color.black));
+        TopSphere.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -15)));
+        TopSphere.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSphere.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -42, 28, 28)));
+    }
+
+    public static final Symbol TopSquare = new Symbol();
+    static {
+        TopSquare.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        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();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        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();
+        colours.add(new Instr(Form.V2, p));
+        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();
+        colours.add(new Instr(Form.V3, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        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();
+        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();
+        colours.add(new Instr(Form.B1, p));
+        TopSquare.add(new Instr(Form.COLR, colours));
+        TopSquare.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSquare.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopSquare.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopRectangleH = new Symbol();
+    static {
+        TopRectangleH.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopRectangleH.add(new Instr(Form.COLR, colours));
+        TopRectangleH.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopRectangleH.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopRectangleH.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopRectangleV = new Symbol();
+    static {
+        TopRectangleV.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopRectangleV.add(new Instr(Form.COLR, colours));
+        TopRectangleV.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopRectangleV.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopRectangleV.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopRhombus = new Symbol();
+    static {
+        TopRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(-15.0, -15.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
+        colours.add(new Instr(Form.H2, p));
+        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();
+        colours.add(new Instr(Form.H3, p));
+        p = new Path2D.Double(); p.moveTo(0.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -15.0); p.closePath();
+        colours.add(new Instr(Form.V2, p));
+        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();
+        colours.add(new Instr(Form.V3, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        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();
+        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();
+        colours.add(new Instr(Form.B1, p));
+        TopRhombus.add(new Instr(Form.COLR, colours));
+        TopRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopRhombus.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopRhombus.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopRhombusCircle = new Symbol();
+
+    public static final Symbol TopSphereRhombus = new Symbol();
+    static {
+        TopSphereRhombus.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        TopSphereRhombus.add(new Instr(Form.SYMB, new Symbols.SubSymbol(TopRhombus, 1.0, 0, 0, null, null)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopSphereRhombus.add(new Instr(Form.COLR, colours));
+        TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSphereRhombus.add(new Instr(Form.FILL, Color.black));
+        TopSphereRhombus.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopSphereRhombus.add(new Instr(Form.ELPS, new Ellipse2D.Double(-14, -58, 28, 28)));
+    }
+
+    public static final Symbol TopT = new Symbol();
+
+    public static final Symbol TopTrapeziumU = new Symbol();
+    static {
+        TopTrapeziumU.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopTrapeziumU.add(new Instr(Form.COLR, colours));
+        TopTrapeziumU.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopTrapeziumU.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopTrapeziumU.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopTrapeziumD = new Symbol();
+    static {
+        TopTrapeziumD.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopTrapeziumD.add(new Instr(Form.COLR, colours));
+        TopTrapeziumD.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopTrapeziumD.add(new Instr(Form.FILL, Color.black));
+        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();
+        TopTrapeziumD.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopTriangle = new Symbol();
+    static {
+        TopTriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-15.0, -1.0); p.lineTo(0.0, -29.0); p.lineTo(15.0, -1.0); p.closePath();
+        p.moveTo(-10.0, -6.0); p.lineTo(0.0, -24.0); p.lineTo(10.0, -6.0); p.closePath();
+        colours.add(new Instr(Form.B1, p));
+        TopTriangle.add(new Instr(Form.COLR, colours));
+        TopTriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopTriangle.add(new Instr(Form.FILL, Color.black));
+        p = new Path2D.Double(); p.moveTo(-15.0, -1.0); p.lineTo(0.0, -29.0); p.lineTo(15.0, -1.0); p.closePath();
+        TopTriangle.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopItriangle = new Symbol();
+    static {
+        TopItriangle.add(new Instr(Form.BBOX, new Rectangle2D.Double(-20, -80, 40, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.setWindingRule(GeneralPath.WIND_EVEN_ODD);
+        p.moveTo(-15.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -29.0); p.closePath();
+        p.moveTo(-10.0, -24.0); p.lineTo(0.0, -6.0); p.lineTo(10.0, -24.0); p.closePath();
+        colours.add(new Instr(Form.B1, p));
+        TopItriangle.add(new Instr(Form.COLR, colours));
+        TopItriangle.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopItriangle.add(new Instr(Form.FILL, Color.black));
+        p = new Path2D.Double(); p.moveTo(-15.0, -29.0); p.lineTo(0.0, -1.0); p.lineTo(15.0, -29.0); p.closePath();
+        TopItriangle.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopTriangleCircle = new Symbol();
+
+    public static final Symbol TopWest = new Symbol();
+    static {
+        TopWest.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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();
+        colours.add(new Instr(Form.P1, p));
+        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
+        colours.add(new Instr(Form.P2, p));
+        TopWest.add(new Instr(Form.COLR, colours));
+        TopWest.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopWest.add(new Instr(Form.FILL, Color.black));
+        TopWest.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -10)));
+        TopWest.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        p = new Path2D.Double(); p.moveTo(-15.0, -10.0); p.lineTo(0.0, -43.0); p.lineTo(15.0, -10.0); p.closePath();
+        p.moveTo(-15.0, -78.0); p.lineTo(0.0, -45.0); p.lineTo(15.0, -78.0); p.closePath();
+        TopWest.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopX = new Symbol();
+    static {
+        TopX.add(new Instr(Form.BBOX, new Rectangle2D.Double(-30, -80, 60, 80)));
+        Symbol colours = new Symbol();
+        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);
+        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();
+        colours.add(new Instr(Form.P1, p));
+        TopX.add(new Instr(Form.COLR, colours));
+        TopX.add(new Instr(Form.STRK, new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        TopX.add(new Instr(Form.FILL, Color.black));
+        TopX.add(new Instr(Form.LINE, new Line2D.Double(0, 0, 0, -27)));
+        TopX.add(new Instr(Form.STRK, new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)));
+        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);
+        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();
+        TopX.add(new Instr(Form.PLIN, p));
+    }
+
+    public static final Symbol TopOther = new Symbol();
+
+    public static final EnumMap<TopSHP, Symbol> Shapes = new EnumMap<>(TopSHP.class);
+    static {
+        Shapes.put(TopSHP.TOP_BESM, TopBesom); Shapes.put(TopSHP.TOP_IBESM, TopIBesom); Shapes.put(TopSHP.TOP_BORD, TopBoard); Shapes.put(TopSHP.TOP_CAN, TopCan);
+        Shapes.put(TopSHP.TOP_CONE, TopCone); Shapes.put(TopSHP.TOP_CROS, TopCross); Shapes.put(TopSHP.TOP_EAST, TopEast); Shapes.put(TopSHP.TOP_ICONE, TopIcone);
+        Shapes.put(TopSHP.TOP_ISD, TopIsol); Shapes.put(TopSHP.TOP_NORTH, TopNorth); Shapes.put(TopSHP.TOP_SOUTH, TopSouth); Shapes.put(TopSHP.TOP_SPHR, TopSphere);
+        Shapes.put(TopSHP.TOP_SQUR, TopSquare); Shapes.put(TopSHP.TOP_TRI, TopTriangle); Shapes.put(TopSHP.TOP_ITRI, TopItriangle); Shapes.put(TopSHP.TOP_WEST, TopWest);
+        Shapes.put(TopSHP.TOP_SALT, TopX); Shapes.put(TopSHP.TOP_RHOM, TopRhombus); Shapes.put(TopSHP.TOP_FLAG, TopFlag); Shapes.put(TopSHP.TOP_CUBE, TopCube);
+        Shapes.put(TopSHP.TOP_SPRH, TopSphereRhombus); Shapes.put(TopSHP.TOP_HRECT, TopRectangleH); Shapes.put(TopSHP.TOP_VRECT, TopRectangleV);
+        Shapes.put(TopSHP.TOP_TRAP, TopTrapeziumU); Shapes.put(TopSHP.TOP_ITRAP, TopTrapeziumD); Shapes.put(TopSHP.TOP_COSP, TopConeSphere);
+        Shapes.put(TopSHP.TOP_CIRC, TopCircle); Shapes.put(TopSHP.TOP_CRSS, TopCrosses); Shapes.put(TopSHP.TOP_T, TopT); Shapes.put(TopSHP.TOP_TRCL, TopTriangleCircle);
+        Shapes.put(TopSHP.TOP_CRCL, TopCrossCircle); Shapes.put(TopSHP.TOP_RHCL, TopRhombusCircle); Shapes.put(TopSHP.TOP_CLTR, TopCircleTriangle);
+        Shapes.put(TopSHP.TOP_CYSP, TopCanSphere); Shapes.put(TopSHP.TOP_OTHR, TopOther);
+    }
+
+    // CHECKSTYLE.OFF: SingleSpaceSeparator
+    public static final EnumMap<BoySHP, Delta> BuoyDeltas = new EnumMap<>(BoySHP.class);
+    static {
+        BuoyDeltas.put(BoySHP.BOY_PILR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
+        BuoyDeltas.put(BoySHP.BOY_SPAR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 31.5, -95.0)));
+        BuoyDeltas.put(BoySHP.BOY_CAN,  new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
+        BuoyDeltas.put(BoySHP.BOY_CONE, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
+        BuoyDeltas.put(BoySHP.BOY_SPHR, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
+        BuoyDeltas.put(BoySHP.BOY_BARL, new Delta(Handle.BC, new AffineTransform(0.948324, 0.317305, -0.3173047, 0.948324, 12.7, -37.9)));
+        BuoyDeltas.put(BoySHP.BOY_SUPR, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0)));
+        BuoyDeltas.put(BoySHP.BOY_ICE,  new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -25.0)));
+    }
+
+    public static final Delta FloatDelta  = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -42.0));
+    public static final Delta BeaconDelta = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -70.0));
+    public static final Delta LightDelta  = new Delta(Handle.BC, AffineTransform.getTranslateInstance(0.0, -20.0));
+    // CHECKSTYLE.ON: SingleSpaceSeparator
 }
