Index: /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java	(revision 32082)
@@ -35,4 +35,6 @@
 	static Context context;
 	static S57map map;
+	static int zoom;
+	static double z2;
 
 	static class Context implements ChartContext {
@@ -42,11 +44,11 @@
 	  
 	  public Context () {
-			top = (1.0 - Math.log(Math.tan(map.bounds.maxlat) + 1.0 / Math.cos(map.bounds.maxlat)) / Math.PI) / 2.0 * 256.0 * 512.0;
+			top = (1.0 - Math.log(Math.tan(map.bounds.maxlat) + 1.0 / Math.cos(map.bounds.maxlat)) / Math.PI) / 2.0 * 256.0 * z2;
 			mile = 256 / ((Math.toDegrees(map.bounds.maxlat) - Math.toDegrees(map.bounds.minlat)) * 60);
 	  }
 	  
 		public Point2D getPoint(Snode coord) {
-			double x = (Math.toDegrees(coord.lon) - Math.toDegrees(map.bounds.minlon)) * 256.0 * 256.0 / 180.0;
-			double y = ((1.0 - Math.log(Math.tan(coord.lat) + 1.0 / Math.cos(coord.lat)) / Math.PI) / 2.0 * 256.0 * 512.0) - top;
+			double x = (Math.toDegrees(coord.lon) - Math.toDegrees(map.bounds.minlon)) * 256.0 * (z2 / 2) / 180.0;
+			double y = ((1.0 - Math.log(Math.tan(coord.lat) + 1.0 / Math.cos(coord.lat)) / Math.PI) / 2.0 * 256.0 * z2) - top;
 			return new Point2D.Double(x, y);
 		}
@@ -60,9 +62,31 @@
 		}
 
-		public Color background() {
+		public Color background(S57map map) {
 			if (map.features.containsKey(Obj.COALNE)) {
-				return Symbols.Bwater;
+				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 {
-				return Symbols.Yland;
+				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;
+				}
 			}
 		}
@@ -74,17 +98,18 @@
 	
 	public static void main(String[] args) throws IOException {
+		if (args.length < 5) {
+			System.err.println("Usage: java -jar jbasemap.jar OSM_file SVG_file zoom xtile ytile");
+			System.exit(-1);
+		}
 		src = args[0];
 		dst = args[1];
+		zoom = Integer.parseInt(args[2]);
+		z2 = Math.pow(2, zoom);
+		double scale = 0.1;
 		try {
 			BufferedReader in = new BufferedReader(new FileReader(src));
 			map = new S57map(false);
-			if (args.length == 4) {
-				map.bounds.maxlat = Math.atan(Math.sinh(Math.PI * (1 - 2 * Double.parseDouble(args[3]) / 512))) * 180.0 / Math.PI;
-				map.bounds.minlat = Math.atan(Math.sinh(Math.PI * (1 - 2 * (Double.parseDouble(args[3]) + 1) / 512))) * 180.0 / Math.PI;
-				map.bounds.minlon = Double.parseDouble(args[2]) / 512 * 360.0 - 180.0;
-				map.bounds.maxlon = (Double.parseDouble(args[2]) + 1) / 512 * 360.0 - 180.0;
-			}
 			try {
-				S57osm.OSMmap(in, map);
+				S57osm.OSMmap(in, map, true);
 			} catch (Exception e) {
 				System.err.println("Input data error");
@@ -96,4 +121,8 @@
 			System.exit(-1);
 		}
+		map.bounds.maxlat = Math.atan(Math.sinh(Math.PI * (1 - 2 * Double.parseDouble(args[4]) / z2)));
+		map.bounds.minlat = Math.atan(Math.sinh(Math.PI * (1 - 2 * (Double.parseDouble(args[4]) + 1) / z2)));
+		map.bounds.minlon = Math.toRadians(Double.parseDouble(args[3]) / z2 * 360.0 - 180.0);
+		map.bounds.maxlon = Math.toRadians((Double.parseDouble(args[3]) + 1) / z2 * 360.0 - 180.0);
 		context = new Context();
 		Rectangle rect = new Rectangle(256, 256);
@@ -104,5 +133,5 @@
 		svgGenerator.setSVGCanvasSize(rect.getSize());
 		svgGenerator.setClip(rect.x, rect.y, rect.width, rect.height);
-		Renderer.reRender(svgGenerator, rect, 9, 0.002, map, context);
+		Renderer.reRender(svgGenerator, rect, zoom, scale, map, context);
 		svgGenerator.stream(dst);
 		System.exit(0);
Index: /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java	(revision 32082)
@@ -203,5 +203,5 @@
 		}
 
-		public Color background() {
+		public Color background(S57map map) {
 			return new Color(0, true);
 		}
Index: /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 32082)
@@ -35,5 +35,4 @@
 import s57.S57osm;
 import s57.S57map.*;
-import symbols.*;
 import render.*;
 
@@ -53,6 +52,6 @@
 	static class Context implements ChartContext {
 		
-	  static double top = 0;
-	  static double mile = 0;
+	  static double top;
+	  static double mile;
 	  
 	  public Context () {
@@ -75,5 +74,5 @@
 		}
 
-		public Color background() {
+		public Color background(S57map map) {
 			return new Color(0, true);
 		}
@@ -88,16 +87,16 @@
 		context = new Context();
 
-		int size = 256;
-		for (int i = 0; i < (12 - zoom); i++) size *= 2;
+		int size = 768;
+//		for (int i = 0; i < (12 - zoom); i++) size *= 2;
 		Rectangle rect = new Rectangle(size, size);
-		img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_ARGB);
-		Renderer.reRender(img.createGraphics(), rect, zoom, 0.05, map, context);
-		ByteArrayOutputStream bos = new ByteArrayOutputStream();
-		ImageIO.write(img, "png", bos);
+//		img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_ARGB);
+//		Renderer.reRender(img.createGraphics(), rect, zoom, 0.05, map, context);
+//		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//		ImageIO.write(img, "png", bos);
 //		empty = bos.size();
 //		tile(zoom, 1, 0, 0);
-		FileOutputStream fos = new FileOutputStream(dstdir + "tst_" + zoom + "-" + xtile + "-" + ytile + ".png");
-		bos.writeTo(fos);
-		fos.close();
+//		FileOutputStream fos = new FileOutputStream(dstdir + "tst_" + zoom + "-" + xtile + "-" + ytile + ".png");
+//		bos.writeTo(fos);
+//		fos.close();
 
 //		for (int z = 12; z <= 18; z++) {
@@ -110,6 +109,7 @@
 			svgGenerator.setClip(rect.x, rect.y, rect.width, rect.height);
 //			svgGenerator.translate(-256, -256);
-			Renderer.reRender(svgGenerator, rect, zoom, 0.05, map, context);
-			svgGenerator.stream(dstdir + "tst_" + zoom + "-" + xtile + "-" + ytile + ".svg");
+			Renderer.reRender(svgGenerator, rect, zoom, 1.0, map, context);
+//			svgGenerator.stream(dstdir + "tst_" + zoom + "-" + xtile + "-" + ytile + ".svg");
+svgGenerator.stream(dstdir);
 //		}
 	}
@@ -180,22 +180,23 @@
 		send = new ArrayList<String>();
 		deletes = new HashMap<String, Boolean>();
-		BufferedReader in = new BufferedReader(new FileReader(srcdir + zoom + "-" + xtile + "-" + ytile + ".osm"));
+//		BufferedReader in = new BufferedReader(new FileReader(srcdir + zoom + "-" + xtile + "-" + ytile + ".osm"));
+BufferedReader in = new BufferedReader(new FileReader(srcdir));
 		map = new S57map(true);
-		S57osm.OSMmap(in, map);
+		S57osm.OSMmap(in, map, false);
 		in.close();
-		if (zoom == 12) {
-			clean(12, 0, 0);
-		}
+//		if (zoom == 12) {
+//			clean(12, 0, 0);
+//		}
 		tileMap(dstdir, zoom);
-		if ((send.size() + deletes.size()) > 0) {
-			PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".send", "UTF-8");
-			for (String str : send) {
-				writer.println(str);
-			}
-			for (String del : deletes.keySet()) {
-				writer.println("rm " + del);
-			}
-			writer.close();
-		}
+//		if ((send.size() + deletes.size()) > 0) {
+//			PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".send", "UTF-8");
+//			for (String str : send) {
+//				writer.println(str);
+//			}
+//			for (String del : deletes.keySet()) {
+//				writer.println("rm " + del);
+//			}
+//			writer.close();
+//		}
 		System.exit(0);
 	}
Index: /applications/editors/josm/plugins/seachart/src/render/ChartContext.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/ChartContext.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/render/ChartContext.java	(revision 32082)
@@ -13,4 +13,5 @@
 import java.awt.geom.Point2D;
 
+import s57.S57map;
 import s57.S57map.*;
 
@@ -21,5 +22,5 @@
 	double mile(Feature feature);
 	boolean clip();
-	Color background();
+	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 32081)
+++ /applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 32082)
@@ -47,5 +47,5 @@
 				g2.clip(new Rectangle2D.Double(tl.getX(), tl.getY(), (br.getX() - tl.getX()), (br.getY() - tl.getY())));
 			}
-			g2.setBackground(context.background());
+			g2.setBackground(context.background(map));
 			g2.clearRect(rect.x, rect.y, rect.width, rect.height);
 			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -484,5 +484,5 @@
 	    g2.setPaint(colour);
 	    FontRenderContext frc = g2.getFontRenderContext();
-	    GlyphVector gv = font.deriveFont((float)(font.getSize()*sScale)).createGlyphVector(frc, (" " + str));
+	    GlyphVector gv = font.deriveFont(font.getSize2D() * (float)sScale).createGlyphVector(frc, (" " + str));
 	    GeneralPath path = new GeneralPath();
 			Point2D prev = new Point2D.Double();
@@ -560,14 +560,16 @@
 			g2.draw(new Line2D.Double(centre.x, centre.y, centre.x - radial * Math.sin(Math.toRadians(mid)), centre.y + radial * Math.cos(Math.toRadians(mid))));
 		} else {
-			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))));
+			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 - 360) % 360, Arc2D.OPEN));
+		g2.draw(new Arc2D.Double(centre.x - radial, centre.y - radial, 2 * radial, 2 * radial, -(s1 + 90), (s1 - s2), 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 - 360) % 360, Arc2D.OPEN));
+			g2.draw(new Arc2D.Double(centre.x - radial + arcWidth, centre.y - radial + arcWidth, 2 * (radial - arcWidth), 2 * (radial - arcWidth), -(s1 + 90), (s1 - s2), Arc2D.OPEN));
 		}
 		if ((str != null) && (!str.isEmpty())) {
@@ -577,10 +579,10 @@
 	    Font font = new Font("Arial", Font.PLAIN, 40);
 	    GeneralPath path = new GeneralPath();
-	    GlyphVector gv = font.deriveFont((float)(font.getSize()*sScale)).createGlyphVector(frc, (" " + str));
+	    GlyphVector gv = font.deriveFont(font.getSize2D() * (float)sScale).createGlyphVector(frc, (" " + str));
 			double gwidth = gv.getLogicalBounds().getWidth();
 			boolean hand = false;
 	    double offset = 0;
 	    Point2D origin;
-			double arc = (s2 - s1 + 360) % 360;
+			double arc = (s2 - s1);
 			if (dir) {
 				radial += 10 * sScale;
Index: /applications/editors/josm/plugins/seachart/src/render/Rules.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32082)
@@ -278,5 +278,6 @@
 			break;
 		case COALNE:
-			Renderer.lineVector(feature, new LineStyle(Color.black, 10));
+			if (Renderer.zoom >= 12)
+				Renderer.lineVector(feature, new LineStyle(Color.black, 10));
 			break;
 		case DEPARE:
@@ -287,5 +288,6 @@
 			break;
 		case LAKARE:
-			Renderer.lineVector(feature, new LineStyle(Symbols.Bwater, 10, Symbols.Bwater));
+			if ((Renderer.zoom >= 12) || (feature.geom.area > 10.0))
+				Renderer.lineVector(feature, new LineStyle(Symbols.Bwater));
 			break;
 		case DRGARE:
@@ -310,9 +312,17 @@
 		case LOKBSN:
 		case HRBBSN:
-			Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Bwater));
+			if (Renderer.zoom >= 12) {
+				Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Bwater));
+			} else {
+				Renderer.lineVector(feature, new LineStyle(Symbols.Bwater));
+			}
 			break;
 		case HRBFAC:
 			if (feature.objs.get(Obj.HRBBSN) != null) {
-				Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Bwater));
+				if (Renderer.zoom >= 12) {
+					Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Bwater));
+				} else {
+					Renderer.lineVector(feature, new LineStyle(Symbols.Bwater));
+				}
 			}
 			break;
@@ -1038,5 +1048,9 @@
 		if ((Renderer.context.ruleset() == RuleSet.ALL) || (Renderer.context.ruleset() == RuleSet.BASE)) {
 			if ((cat != CatSLC.SLC_SWAY) && (cat != CatSLC.SLC_TWAL)) {
-				Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Yland));
+				if (Renderer.zoom >= 12) {
+					Renderer.lineVector(feature, new LineStyle(Color.black, 10, Symbols.Yland));
+				} else {
+					Renderer.lineVector(feature, new LineStyle(Symbols.Yland));
+				}
 			}
 		}
@@ -1049,10 +1063,10 @@
 						Renderer.lineVector(feature, new LineStyle(Color.black, 10, new float[] { 40, 40 }, null));
 						if (Renderer.zoom >= 15)
-							Renderer.lineText(feature, "(covers)", new Font("Arial", Font.PLAIN, 80), Color.black, 0.5, 80);
+							Renderer.lineText(feature, "(covers)", new Font("Arial", Font.PLAIN, 60), Color.black, 0.5, 80);
 					} else {
 						Renderer.lineVector(feature, new LineStyle(Color.black, 10, null, null));
 					}
 					if (Renderer.zoom >= 15)
-						Renderer.lineText(feature, "Training Wall", new Font("Arial", Font.PLAIN, 80), Color.black, 0.5, -30);
+						Renderer.lineText(feature, "Training Wall", new Font("Arial", Font.PLAIN, 60), Color.black, 0.5, -30);
 					break;
 				case SLC_SWAY:
@@ -1199,5 +1213,5 @@
 
 	private static void waterways() {
-		Renderer.lineVector(feature, new LineStyle(Symbols.Bwater, 20, Symbols.Bwater));
+		Renderer.lineVector(feature, new LineStyle(Symbols.Bwater, 20, (feature.geom.prim == Pflag.AREA) ? Symbols.Bwater : null));
 	}
 
Index: /applications/editors/josm/plugins/seachart/src/render/Signals.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32082)
@@ -13,7 +13,10 @@
 import java.awt.Font;
 import java.awt.geom.*;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.EnumMap;
 
+import s57.S57val.CatLIT;
+import s57.S57val.ColCOL;
 import s57.S57att.*;
 import s57.S57obj.*;
@@ -27,56 +30,56 @@
 public class Signals {
 
-	static final EnumMap<ColCOL, Color> lightColours = new EnumMap<ColCOL, Color>(ColCOL.class);
+	static final EnumMap<ColCOL, Color> LightColours = new EnumMap<ColCOL, Color>(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, String>(ColCOL.class);
+		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, String>(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, String>(LitCHR.class);
+		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, String>(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");
+		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");
 	}
 	
@@ -103,4 +106,6 @@
 	}
 
+	static final DecimalFormat df = new DecimalFormat("#.#");
+	
 	public static void fogSignals(Feature feature) {
 		Renderer.symbol(feature, Beacons.FogSignal);
@@ -116,8 +121,8 @@
 		}
 		if (atts.containsKey(Att.SIGPER)) {
-			str += atts.get(Att.SIGPER).val + "s";
+			str += df.format(atts.get(Att.SIGPER).val) + "s";
 		}
 		if (atts.containsKey(Att.VALMXR)) {
-			str += atts.get(Att.VALMXR).val + "M";
+			str += df.format(atts.get(Att.VALMXR).val) + "M";
 		}
 		if ((Renderer.zoom >= 15) && !str.isEmpty()) {
@@ -169,5 +174,4 @@
 	@SuppressWarnings("unchecked")
 	public static void radioStations(Feature feature) {
-		Renderer.symbol(feature, Beacons.RadarStation);
 		ArrayList<CatROS> cats = (ArrayList<CatROS>)Rules.getAttList(feature, Obj.RDOSTA, 0, Att.CATROS);
 		boolean vais = false;
@@ -272,4 +276,7 @@
 				break;
 			}
+		}
+		if (!vais) {
+			Renderer.symbol(feature, Beacons.RadarStation);
 		}
 		if (Renderer.zoom >= 15) {
@@ -315,275 +322,253 @@
 			}
 		}
-		Renderer.symbol(feature, Beacons.LightFlare, new Scheme(lightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
-		if (lights.get(1) != null) {
-			for (AttMap atts : lights.values()) {
-				Enum<ColCOL> col1 = null;
-				Enum<ColCOL> col2 = null;
-				double radius = 0.2;
-				double s1 = 0;
-				double s2 = 0;
-				boolean dir = false;
+		Renderer.symbol(feature, Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
+		if (Renderer.zoom >= 15) {
+			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 = 0;
+					double s2 = 0;
+					boolean dir = false;
+					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.SECTR1)) {
+						s1 = (Double) atts.get(Att.SECTR1).val;
+					} else {
+						continue;
+					}
+					if (atts.containsKey(Att.SECTR2)) {
+						s2 = (Double) atts.get(Att.SECTR2).val;
+					} else {
+						continue;
+					}
+					if (atts.containsKey(Att.CATLIT)) {
+						ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
+						if (cats.contains(CatLIT.LIT_DIR)) {
+							dir = true;
+						}
+					}
+					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 (dir && atts.containsKey(Att.ORIENT)) {
+						double orient = (Double) atts.get(Att.ORIENT).val;
+						str += " " + orient + "°";
+						s1 = (orient - 4 + 360) % 360;
+						s2 = (orient + 4) % 360;
+						double n1 = 360;
+						double n2 = 360;
+						for (AttMap sect : lights.values()) {
+							if (sect != atts) {
+
+							}
+						}
+					}
+					Renderer.lightSector(feature, LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
+				}
+				class LitSect {
+					boolean dir;
+					LitCHR chr;
+					ColCOL col;
+					ColCOL alt;
+					String grp;
+					double per;
+					double rng;
+					double hgt;
+				}
+				str = "";
+				ArrayList<LitSect> litatts = new ArrayList<>();
+				for (AttMap atts : lights.values()) {
+					LitSect sect = new LitSect();
+					litatts.add(sect);
+					sect.dir = (atts.containsKey(Att.CATLIT)) && (atts.get(Att.CATLIT).val == 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;
+					sect.alt = cols.size() > 1 ? cols.get(1) : ColCOL.COL_UNK;
+				}
+				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<LitSect>();
+						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);
+					if (tmp.dir)
+						str += "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)
+						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(feature, str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
+					y += 40;
+					str = "";
+				}
+			} else {
+				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<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.RADIUS)) {
-					radius = (Double) atts.get(Att.RADIUS).val;
-				}
-				if (atts.containsKey(Att.SECTR1)) {
-					s1 = (Double) atts.get(Att.SECTR1).val;
-				} else {
-					continue;
-				}
-				if (atts.containsKey(Att.SECTR2)) {
-					s2 = (Double) atts.get(Att.SECTR2).val;
-				} else {
-					continue;
-				}
-				if (atts.containsKey(Att.CATLIT)) {
-					ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
-					if (cats.contains(CatLIT.LIT_DIR)) {
-						dir = true;
-					}
-				}
-				String str = "";
-				if (atts.containsKey(Att.LITCHR)) {
-					str += lightCharacters.get(atts.get(Att.LITCHR).val);
-				}
-				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 (dir && atts.containsKey(Att.ORIENT)) {
-					double orient = (Double)atts.get(Att.ORIENT).val;
-					str += " " + orient + "°";
-					s1 = (orient - 4 + 360) % 360;
-					s2 = (orient + 4) % 360;
-					double n1 = 360;
-					double n2 = 360;
-					for (AttMap sect : lights.values()) {
-						if (sect != atts) {
-							
-						}
-					}
-				}
-				Renderer.lightSector(feature, lightColours.get(col1), lightColours.get(col2), radius, s1, s2, dir, str);
-			}
-		}
-/*      int secmax = countObjects(item, "light");
-      if ((idx == 0) && (secmax > 0)) {
-        struct SECT {
-          struct SECT *next;
-          int dir;
-          LitCHR_t chr;
-          ColCOL_t col;
-          ColCOL_t alt;
-          char *grp;
-          double per;
-          double rng;
-        } *lights = NULL;
-        for (int i = secmax; i > 0; i--) {
-          struct SECT *tmp = calloc(1, sizeof(struct SECT));
-          tmp->next = lights;
-          lights = tmp;
-          obj = getObj(item, LIGHTS, i);
-          if ((att = getAtt(obj, CATLIT)) != NULL) {
-            lights->dir = testAtt(att, LIT_DIR);
-          }
-          if ((att = getAtt(obj, LITCHR)) != NULL) {
-            lights->chr = att->val.val.e;
-            switch (lights->chr) {
-              case CHR_AL:
-                lights->chr = CHR_F;
-                break;
-              case CHR_ALOC:
-                lights->chr = CHR_OC;
-                break;
-              case CHR_ALLFL:
-                lights->chr = CHR_LFL;
-                break;
-              case CHR_ALFL:
-                lights->chr = CHR_FL;
-                break;
-              case CHR_ALFFL:
-                lights->chr = CHR_FFL;
-                break;
-              default:
-                break;
-            }
-          }
-          if ((att = getAtt(obj, SIGGRP)) != NULL) {
-            lights->grp = att->val.val.a;
-          } else {
-            lights->grp = "";
-          }
-          if ((att = getAtt(obj, SIGPER)) != NULL) {
-            lights->per = att->val.val.f;
-          }
-          if ((att = getAtt(obj, VALNMR)) != NULL) {
-            lights->rng = att->val.val.f;
-          }
-          if ((att = getAtt(obj, COLOUR)) != NULL) {
-            lights->col = att->val.val.l->val;
-            if (att->val.val.l->next != NULL)
-              lights->alt = att->val.val.l->next->val;
-          }
-        }
-        struct COLRNG {
-          int col;
-          double rng;
-        } colrng[14];
-        while (lights != NULL) {
-          strcpy(string2, "");
-          bzero(colrng, 14*sizeof(struct COLRNG));
-          colrng[lights->col].col = 1;
-          colrng[lights->col].rng = lights->rng;
-          struct SECT *this = lights;
-          struct SECT *next = lights->next;
-          while (next != NULL) {
-            if ((this->dir == next->dir) && (this->chr == next->chr) &&
-                (strcmp(this->grp, next->grp) == 0) && (this->per == next->per)) {
-              colrng[next->col].col = 1;
-              if (next->rng > colrng[next->col].rng)
-                colrng[next->col].rng = next->rng;
-              struct SECT *tmp = lights;
-              while (tmp->next != next) tmp = tmp->next;
-              tmp->next = next->next;
-              free(next);
-              next = tmp->next;
-            } else {
-              next = next->next;
-            }
-          }
-          if (this->chr != CHR_UNKN) {
-            if (this->dir) strcpy(string2, "Dir.");
-            strcat(string2, light_characters[this->chr]);
-            if (strcmp(this->grp, "") != 0) {
-              if (this->grp[0] == '(')
-                sprintf(strchr(string2, 0), "%s", this->grp);
-              else
-                sprintf(strchr(string2, 0), "(%s)", this->grp);
-            } else {
-              if (strlen(string2) > 0) strcat(string2, ".");
-            }
-            int n = 0;
-            for (int i = 0; i < 14; i++) if (colrng[i].col) n++;
-            double max = 0.0;
-            for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng > max)) max = colrng[i].rng;
-            double min = max;
-            for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng > 0.0) && (colrng[i].rng < min)) min = colrng[i].rng;
-            if (min == max) {
-              for (int i = 0; i < 14; i++) if (colrng[i].col) strcat(string2, light_letters[i]);
-            } else {
-              for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng == max)) strcat(string2, light_letters[i]);
-              for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng < max) && (colrng[i].rng > min)) strcat(string2, light_letters[i]);
-              for (int i = 0; i < 14; i++) if (colrng[i].col && colrng[i].rng == min) strcat(string2, light_letters[i]);
-            }
-            strcat(string2, ".");
-            if (this->per > 0.0) sprintf(strchr(string2, 0), "%gs", this->per);
-            if (max > 0.0) {
-              sprintf(strchr(string2, 0), "%g", max);
-              if (min != max) {
-                if (n == 2) strcat(string2, "/");
-                else if (n > 2) strcat(string2, "-");
-                if (min < max) sprintf(strchr(string2, 0), "%g", min);
-              }
-              strcat(string2, "M");
-            }
-            if (strlen(string1) > 0) strcat(string1, "\n");
-            strcat(string1, string2);
-          }
-          lights = this->next;
-          free(this);
-          this = lights;
-        }
-      } else {
-        if ((att = getAtt(obj, CATLIT)) != NULL) {
-          if (testAtt(att, LIT_DIR))
-            strcat(string1, "Dir");
-        }
-        if ((att = getAtt(obj, MLTYLT)) != NULL)
-          sprintf(strchr(string1, 0), "%s", stringValue(att->val));
-        if ((att = getAtt(obj, LITCHR)) != NULL) {
-          char *chrstr = strdup(stringValue(att->val));
-          Att_t *grp = getAtt(obj, SIGGRP);
-          if (grp != NULL) {
-            char *strgrp = strdup(stringValue(grp->val));
-            char *grpstr = strtok(strgrp, "()");
-            switch (att->val.val.e) {
-              case CHR_QLFL:
-                sprintf(strchr(string1, 0), "Q(%s)+LFl", grpstr);
-                break;
-              case CHR_VQLFL:
-                sprintf(strchr(string1, 0), "VQ(%s)+LFl", grpstr);
-                break;
-              case CHR_UQLFL:
-                sprintf(strchr(string1, 0), "UQ(%s)+LFl", grpstr);
-                break;
-              default:
-                sprintf(strchr(string1, 0), "%s(%s)", chrstr, grpstr);
-                break;
-            }
-            free(strgrp);
-          } else {
-            sprintf(strchr(string1, 0), "%s", chrstr);
-          }
-          free(chrstr);
-        }
-        if ((att = getAtt(obj, COLOUR)) != NULL) {
-          int n = countValues(att);
-          if (!((n == 1) && (idx == 0) && (testAtt(att, COL_WHT)))) {
-            if ((strlen(string1) > 0) && ((string1[strlen(string1)-1] != ')')))
-              strcat(string1, ".");
-            Lst_t *lst = att->val.val.l;
-            while (lst != NULL) {
-              strcat(string1, light_letters[lst->val]);
-              lst = lst->next;
-            }
-          }
-        }
-        if ((idx == 0) && (att = getAtt(obj, CATLIT)) != NULL) {
-          if (testAtt(att, LIT_VERT))
-            strcat(string1, "(vert)");
-          if (testAtt(att, LIT_HORI))
-            strcat(string1, "(hor)");
-        }
-        if ((strlen(string1) > 0) &&
-            ((getAtt(obj, SIGPER) != NULL) ||
-             (getAtt(obj, HEIGHT) != NULL) ||
-             (getAtt(obj, VALMXR) != NULL)) &&
-            (string1[strlen(string1)-1] != ')'))
-          strcat(string1, ".");
-        if ((att = getAtt(obj, SIGPER)) != NULL)
-          sprintf(strchr(string1, 0), "%ss", stringValue(att->val));
-        if ((idx == 0) && (item->objs.obj != LITMIN)) {
-          if ((att = getAtt(obj, HEIGHT)) != NULL)
-            sprintf(strchr(string1, 0), "%sm", stringValue(att->val));
-          if ((att = getAtt(obj, VALNMR)) != NULL)
-            sprintf(strchr(string1, 0), "%sM", stringValue(att->val));
-        }
-        if ((idx == 0) && (att = getAtt(obj, CATLIT)) != NULL) {
-          if (testAtt(att, LIT_FRNT))
-            strcat(string1, "(Front)");
-          if (testAtt(att, LIT_REAR))
-            strcat(string1, "(Rear)");
-          if (testAtt(att, LIT_UPPR))
-            strcat(string1, "(Upper)");
-          if (testAtt(att, LIT_LOWR))
-            strcat(string1, "(Lower)");
-        }
-      }
-    }
-*/	}
-
+					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(feature, 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 32081)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57att.java	(revision 32082)
@@ -122,5 +122,5 @@
   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, ""); AttStr.put(Att.SORIND, ""); AttStr.put(Att.STATUS, "status");
+  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");
Index: /applications/editors/josm/plugins/seachart/src/s57/S57box.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57box.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57box.java	(revision 32082)
@@ -18,4 +18,16 @@
 	
 	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) {
@@ -105,54 +117,10 @@
 			}
 			for (Land land : lands) {
-				GeomIterator git = map.new GeomIterator(land.land.geom);
-				Snode prev = null;
-				Ext bprev = Ext.I;
-				Ext ext;
-				land.ebound = land.sbound = Ext.I;
-				while (git.hasComp()) {
-					git.nextComp();
-					while (git.hasEdge()) {
-						git.nextEdge();
-						while (git.hasNode()) {
-							long ref = git.nextRef(false);
-							Snode node = map.nodes.get(ref);
-							if (node == null)
-								continue;
-							if (land.first == 0) {
-								land.first = ref;
-							}
-							if (prev == null) {
-								prev = node;
-							}
-							if ((node.lat >= map.bounds.maxlat) && (node.lon < map.bounds.maxlon)) {
-								ext = Ext.N;
-							} else if (node.lon <= map.bounds.minlon) {
-								ext = Ext.W;
-							} else if (node.lat <= map.bounds.minlat) {
-								ext = Ext.S;
-							} else if (node.lon >= map.bounds.maxlon) {
-								ext = Ext.E;
-							} else {
-								ext = Ext.I;
-							}
-							if (ext == Ext.I) {
-								if (land.start == null) {
-									land.start = prev;
-									land.sbound = bprev;
-								}
-								land.end = null;
-								land.ebound = Ext.I;
-							} else {
-								if ((land.start != null) && (land.end == null)) {
-									land.end = node;
-									land.ebound = ext;
-								}
-							}
-							prev = node;
-							bprev = ext;
-							land.last = ref;
-						}
-					}
-				}
+				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<>();
@@ -165,69 +133,36 @@
 				lands.remove(island);
 			}
-			while (lands.size() > 0) {
-				Land land = lands.get(0);
+			for (Land land : lands) {
 				Edge nedge = map.new Edge();
 				nedge.first = land.last;
+				nedge.last = land.first;
 				Ext bound = land.ebound;
-				Snode last = land.end;
-				double delta = Math.PI;
-				int idx = -1;
-				Land next = null;
-				while (idx < 0) {
-					for (int i = 0; i < lands.size(); i++) {
-						next = lands.get(i);
-						if (next.sbound == bound) {
-							double diff = -Math.PI;
-							switch (bound) {
-							case N:
-								diff = last.lon - next.start.lon;
-								break;
-							case W:
-								diff = last.lat - next.start.lat;
-								break;
-							case S:
-								diff = next.start.lon - last.lon;
-								break;
-							case E:
-								diff = next.start.lat - last.lat;
-								break;
-							default:
-								continue;
-							}
-							if ((diff >= 0.0) && (diff < delta)) {
-								delta = diff;
-								idx = i;
-							}
-						}
-					}
-					if (idx < 0) {
-						long ref = (long) bound.ordinal();
-						last = map.nodes.get(ref);
-						nedge.nodes.add(ref);
-						ref = ref < 4 ? ++ref : 1;
-						for (Ext e : Ext.values()) {
-							if (ref == e.ordinal()) {
-								bound = e;
-								break;
-							}
-						}
+				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;
 					}
 				}
-				next = lands.get(idx);
-				nedge.last = next.first;
 				map.edges.put(++map.xref, nedge);
 				land.land.geom.elems.add(map.new Prim(map.xref));
-				if (next != land) {
-					land.land.geom.elems.addAll(next.land.geom.elems);
-					land.ebound = next.ebound;
-					land.end = next.end;
-					land.last = next.last;
-					lands.remove(idx);
-				}
-				map.sortGeom(land.land);
-				if (land.land.geom.prim == Pflag.AREA) {
-					map.features.get(Obj.LNDARE).add(land.land);
-					lands.remove(land);
-				}
+				land.land.geom.comps.get(0).size++;
+				land.land.geom.prim = Pflag.AREA;
+				map.features.get(Obj.LNDARE).add(land.land);
 			}
 		}
Index: /applications/editors/josm/plugins/seachart/src/s57/S57map.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 32082)
@@ -234,5 +234,5 @@
 	private Feature feature;
 	private Edge edge;
-	private KeyVal<?> osm = S57osm.OSMtag("", "");
+	private ArrayList<KeyVal<?>> osm;
 	private boolean sea;
 
@@ -375,5 +375,5 @@
 		feature.geom.elems.add(new Prim(id));
 		edge = null;
-		osm = S57osm.OSMtag("", "");
+		osm =  new ArrayList<>();
 	}
 
@@ -385,5 +385,5 @@
 		feature.geom.elems.add(new Prim(id));
 		edge = new Edge();
-		osm = S57osm.OSMtag("", "");
+		osm = new ArrayList<>();
 	}
 
@@ -406,5 +406,5 @@
 		feature.geom.prim = Pflag.AREA;
 		edge = null;
-		osm = S57osm.OSMtag("", "");
+		osm = new ArrayList<>();
 	}
 
@@ -475,11 +475,5 @@
 			}
 		} else if (!sea) {
-			KeyVal<?> kv = S57osm.OSMtag(key, val);
-			if (kv.obj != Obj.UNKOBJ) {
-				osm.obj = kv.obj;
-				if (kv.att != Att.UNKATT) {
-					osm = kv;
-				}
-			}
+			S57osm.OSMtag(osm, key, val);
 		}
 	}
@@ -489,5 +483,5 @@
 		case POINT:
 			Snode node = nodes.get(id);
-			if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || (osm.obj != Obj.UNKOBJ))) {
+			if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
 				node.flg = Nflag.ISOL;
 			}
@@ -507,5 +501,30 @@
 		}
 		if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
-			if (osm.obj != Obj.UNKOBJ) {
+			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;
@@ -541,12 +560,5 @@
 					features.get(osm.obj).add(base);
 				}
-			}
-			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);
-			}
+			}*/
 		}
 	}
@@ -575,60 +587,89 @@
 				feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
 				return true;
-			} else {
-				int sweep = feature.geom.elems.size();
-				while (!feature.geom.elems.isEmpty()) {
-					Prim prim = feature.geom.elems.remove(0);
-					Edge edge = edges.get(prim.id);
-					if (edge == null) {
-						return false;
-					}
-					if (next == true) {
-						next = false;
-						first = edge.first;
+			}
+			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);
-						if (prim.outer) {
-							sort.outers++;
-						} else {
-							sort.inners++;
+						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;
 						}
-						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(0, 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(0, prim);
-							first = edge.last;
-							prim.forward = false;
-							comp.size++;
-						} else {
-							feature.geom.elems.add(prim);
+						if (outin) {
+							if (sweep != 0) {
+								return false;
+							}
+							outer = inner;
+							outin = false;
+							sweep = outer.elems.size();
 						}
-					}
-					if (--sweep == 0) {
 						next = true;
-						sweep = feature.geom.elems.size();
-					}
-				}
-				if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
-					sort.prim = Pflag.AREA;
-				}
-				feature.geom = sort;
-			}
+						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;
Index: /applications/editors/josm/plugins/seachart/src/s57/S57osm.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 32082)
@@ -35,4 +35,5 @@
 	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));
@@ -51,5 +52,5 @@
 		}
 	
-	public static KeyVal<?> OSMtag(String key, String val) {
+	public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
 		KeyVal<?> kv = OSMtags.get(key + "=" + val);
 		if (kv != null) {
@@ -57,12 +58,35 @@
 				ArrayList<Enum<?>> list = new ArrayList<Enum<?>>();
 				list.add((Enum<?>)kv.val);
-				return new KeyVal<>(kv.obj, kv.att, kv.conv, list);
-			}
-			return kv;
-		}
-		return new KeyVal<>(Obj.UNKOBJ, Att.UNKATT, null, null);
-	}
-	
-	public static void OSMmap(BufferedReader in, S57map map) throws Exception {
+				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 = "";
@@ -84,5 +108,5 @@
 		while ((ln = in.readLine()) != null) {
 			if (inOsm) {
-				if (ln.contains("<bounds")) {
+				if (ln.contains("<bounds") && !bb) {
 					for (String token : ln.split("[ ]+")) {
 						if (token.matches("^minlat=.+")) {
Index: /applications/editors/josm/plugins/seachart/src/s57/S57val.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32082)
@@ -616,8 +616,8 @@
  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, "stone")); 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, "rock"));
+  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, "boulder"));
+  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 } 
@@ -1094,5 +1094,5 @@
   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.A, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
+  keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
  }
  
Index: /applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32081)
+++ /applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32082)
@@ -30,5 +30,7 @@
 import render.ChartContext;
 import render.Renderer;
+import s57.S57map;
 import s57.S57map.*;
+import s57.S57obj.Obj;
 import symbols.Symbols;
 
@@ -98,6 +100,32 @@
 	}
 	
-	public Color background() {
-		return (Symbols.Bwater);
+	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;
+			}
+		}
 	}
 
