Index: applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java
===================================================================
--- applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 32095)
@@ -27,9 +27,4 @@
 import javax.imageio.ImageIO;
 
-import org.apache.batik.dom.GenericDOMImplementation;
-import org.apache.batik.svggen.SVGGraphics2D;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-
 import s57.S57map;
 import s57.S57osm;
@@ -56,11 +51,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 * 4096.0;
-			mile = 768 / ((Math.toDegrees(map.bounds.maxlat) - Math.toDegrees(map.bounds.minlat)) * 60);
+			top = (1.0 - Math.log(Math.tan(map.bounds.maxlat) + 1.0 / Math.cos(map.bounds.maxlat)) / Math.PI) / 2.0 * 256.0 * 4096.0 * Math.pow(2, (zoom - 12));
+			mile = (2 * ((zoom < 12) ? (256 / (int)(Math.pow(2, (11 - zoom)))) : 256) + 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 * 2048.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 * 4096.0) - top;
+			double x = (Math.toDegrees(coord.lon) - Math.toDegrees(map.bounds.minlon)) * 256.0 * 2048.0 * Math.pow(2, (zoom - 12)) / 180.0;
+			double y = ((1.0 - Math.log(Math.tan(coord.lat) + 1.0 / Math.cos(coord.lat)) / Math.PI) / 2.0 * 256.0 * 4096.0 * Math.pow(2, (zoom - 12))) - top;
 			return new Point2D.Double(x, y);
 		}
@@ -83,59 +78,27 @@
 	}
 	
-	static final boolean test = true;
-	
-	public static void tileMap(String idir, int zoom) throws IOException {
-		BufferedImage img;
-		context = new Context();
-
-		int border = 256 / (int)Math.pow(2, (12 - zoom));
-		int size = 256;
-		for (int i = 0; i < (12 - zoom); i++) size *= 2;
-		Rectangle rect = new Rectangle((size + (2 * border)), (size + (2 * border)));
-		img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_ARGB);
-		Renderer.reRender(img.createGraphics(), rect, zoom, 1.0, map, context);
-		ByteArrayOutputStream bos = new ByteArrayOutputStream();
-		ImageIO.write(img, "png", bos);
-		empty = bos.size();
-
-		if (test) {
-			for (int z = 12; z <= 18; z++) {
-				DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
-				Document document = domImpl.createDocument("http://www.w3.org/2000/svg", "svg", null);
-				SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
-				svgGenerator.clearRect(rect.x, rect.y, rect.width, rect.height);
-				svgGenerator.setSVGCanvasSize(rect.getSize());
-				svgGenerator.setClip(rect.x, rect.y, rect.width, rect.height);
-				svgGenerator.translate(-border, -border);
-				Renderer.reRender(svgGenerator, rect, z, 1.0, map, context);
-				svgGenerator.stream(dstdir + "tst_" + z + "-" + xtile + "-" + ytile + ".svg");
-			}
-		} else {
-			tile(zoom, 1, 0, 0);
-		}
-	}
-	
-	static void tile(int zoom, int s, int xn, int yn) throws IOException {
-		int scale = (int) Math.pow(2, zoom - 12);
-		int xdir = (scale * xtile) + xn;
-		int ynam = (scale * ytile) + yn;
+	static void tile(int z, int s, int xn, int yn) throws IOException {
+		int border = (z < 12) ? (256 / (int)(Math.pow(2, (11 - zoom)))) : 256;
+		int scale = (int)Math.pow(2, z - 12);
+		int xdir = (scale > 0) ? (scale * xtile) + xn : xtile;
+		int ynam = (scale > 0) ? (scale * ytile) + yn : ytile;
 		BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
 		Graphics2D g2 = img.createGraphics();
 		g2.scale(s, s);
-		g2.translate(-(256 + (xn * 256 / s)), -(256 + (yn * 256 / s)));
-		Renderer.reRender(g2, new Rectangle(256, 256), zoom, 1, map, context);
+		g2.translate(-(border + (xn * 256 / s)), -(border + (yn * 256 / s)));
+		Renderer.reRender(g2, new Rectangle(256, 256), z, 1.0 * Math.pow(2, (zoom - 12)), map, context);
 		ByteArrayOutputStream bos = new ByteArrayOutputStream();
 		ImageIO.write(img, "png", bos);
 		if (bos.size() > empty) {
-			String dstnam = dstdir + zoom + "/" + xdir + "/" + ynam + ".png";
+			String dstnam = dstdir + z + "/" + xdir + "/" + ynam + ".png";
 			deletes.remove(dstnam);
-			send.add("put " + dstnam + " tiles/" + zoom + "/" + xdir + "/" + ynam + ".png");
-			File ofile = new File(dstdir + "/" + zoom + "/" + xdir + "/");
+			send.add("put " + dstnam + " tiles/" + z + "/" + xdir + "/" + ynam + ".png");
+			File ofile = new File(dstdir + "/" + z + "/" + xdir + "/");
 			ofile.mkdirs();
-			FileOutputStream fos = new FileOutputStream(dstdir + "/" + zoom + "/" + xdir + "/" + ynam + ".png");
+			FileOutputStream fos = new FileOutputStream(dstdir + "/" + z + "/" + xdir + "/" + ynam + ".png");
 			bos.writeTo(fos);
 			fos.close();
-			if (send.size() > 10) {
-				PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xdir + "-" + ynam + ".send", "UTF-8");
+			if (send.size() > 20) {
+				PrintWriter writer = new PrintWriter(srcdir + z + "-" + xdir + "-" + ynam + ".send", "UTF-8");
 				for (String str : send) {
 					writer.println(str);
@@ -145,8 +108,8 @@
 			}
 		}
-		if ((zoom >= 12) && (zoom < 18) && ((zoom < 16) || (bos.size() > empty))) {
+		if ((z >= 12) && (z < 18) && ((z < 16) || (bos.size() > empty))) {
 			for (int x = 0; x < 2; x++) {
 				for (int y = 0; y < 2; y++) {
-					tile((zoom + 1), (s * 2), (xn * 2 + x), (yn * 2 + y));
+					tile((z + 1), (s * 2), (xn * 2 + x), (yn * 2 + y));
 				}
 			}
@@ -181,22 +144,30 @@
 		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 + xtile + "-" + ytile + "-" + zoom + ".osm"));
 		map = new S57map(true);
 		S57osm.OSMmap(in, map, false);
 		in.close();
+		context = new Context();
+		ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		ImageIO.write(new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB), "png", bos);
+		empty = bos.size();
 		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();
-//		}
+		tile(zoom, 1, 0, 0);
+		if (send.size() > 0) {
+			PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".send", "UTF-8");
+			for (String str : send) {
+				writer.println(str);
+			}
+			writer.close();
+		}
+		if (deletes.size() > 0) {
+			PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".delete", "UTF-8");
+			for (String del : deletes.keySet()) {
+				writer.println("rm " + del);
+			}
+			writer.close();
+		}
 		System.exit(0);
 	}
Index: applications/editors/josm/plugins/seachart/src/render/Rules.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 32095)
@@ -183,4 +183,8 @@
 		}
 		return false;
+	}
+	
+	static boolean hasObject(Obj obj) {
+		return (feature.objs.containsKey(obj));
 	}
 	
@@ -246,4 +250,5 @@
 			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();
@@ -438,5 +443,6 @@
 	@SuppressWarnings("unchecked")
 	private static void beacons() {
-		if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))) {
+		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)
@@ -485,5 +491,6 @@
 	@SuppressWarnings("unchecked")
 	private static void buoys() {
-		if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))) {
+		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;
@@ -630,5 +637,5 @@
 	@SuppressWarnings("unchecked")
 	private static void floats() {
-		if (Renderer.zoom >= 12) {
+		if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) || (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
 			switch (feature.type) {
 			case LITVES:
@@ -819,5 +826,11 @@
 	@SuppressWarnings("unchecked")
 	private static void landmarks() {
+		if (testAttribute(Obj.LNDMRK, Att.CATLMK, CatLMK.LMK_UNKN)
+				&& (testAttribute(Obj.LNDMRK, Att.CATLMK, FncFNC.FNC_UNKN) || testAttribute(Obj.LNDMRK, Att.CATLMK, FncFNC.FNC_LGHT))
+				&& hasObject(Obj.LIGHTS))
+			lights();
 		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));
@@ -826,10 +839,16 @@
 			if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
 				catSym = Landmarks.ChurchTower;
-			if ((cats.get(0) == CatLMK.LMK_UNKN) && (fncs.get(0) == FncFNC.FNC_UNKN) && (feature.objs.get(Obj.LIGHTS) != null))
-				catSym = Beacons.LightMajor;
 			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)));
@@ -840,33 +859,44 @@
 	@SuppressWarnings("unchecked")
 	private static void lights() {
+		boolean ok = false;
 		switch (feature.type) {
 		case LITMAJ:
+		case LNDMRK:
 			Renderer.symbol(Beacons.LightMajor);
+			ok = true;
 			break;
 		case LITMIN:
 		case LIGHTS:
-			Renderer.symbol(Beacons.LightMinor);
+			if (Renderer.zoom >= 14) {
+				Renderer.symbol(Beacons.LightMinor);
+				ok = true;
+			}
 			break;
 		case PILPNT:
-			if (feature.objs.containsKey(Obj.LIGHTS))
-				Renderer.symbol(Beacons.LightMinor);
-			else
-				Renderer.symbol(Harbours.Post);
+			if (Renderer.zoom >= 14) {
+				if (feature.objs.containsKey(Obj.LIGHTS))
+					Renderer.symbol(Beacons.LightMinor);
+				else
+					Renderer.symbol(Harbours.Post);
+				ok = true;
+			}
 			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.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();
+		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();
+		}
 	}
 
Index: applications/editors/josm/plugins/seachart/src/render/Signals.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 32095)
@@ -28,5 +28,5 @@
 import symbols.Symbols.*;
 
-public class Signals {
+public class Signals extends Rules{
 
 	static final EnumMap<ColCOL, Color> LightColours = new EnumMap<ColCOL, Color>(ColCOL.class);
@@ -101,15 +101,15 @@
 	
 	public static void addSignals() {
-	  if (Rules.feature.objs.containsKey(Obj.RADRFL)) reflectors();
-	  if (Rules.feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
-	  if (Rules.feature.objs.containsKey(Obj.RTPBCN)) radarStations();
-	  if (Rules.feature.objs.containsKey(Obj.RADSTA)) radarStations();
-	  if (Rules.feature.objs.containsKey(Obj.RDOSTA)) radioStations();
-	  if (Rules.feature.objs.containsKey(Obj.LIGHTS)) lights();
+	  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 (Rules.feature.type) {
+			switch (feature.type) {
 			case BCNLAT:
 			case BCNCAR:
@@ -117,5 +117,5 @@
 			case BCNSAW:
 			case BCNSPP:
-				if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
+				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
 					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -140)));
 				} else {
@@ -126,5 +126,5 @@
 			case LITVES:
 			case BOYINB:
-				if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
+				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
 					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -110)));
 				} else {
@@ -134,5 +134,5 @@
 			case LITMAJ:
 			case LITMIN:
-				if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
+				if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
 					Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
 				} else {
@@ -145,6 +145,6 @@
 			case BOYSAW:
 			case BOYSPP:
-				if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
-					if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
+				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 {
@@ -152,5 +152,5 @@
 					}
 				} else {
-					if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
+					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 {
@@ -169,5 +169,5 @@
 			Renderer.symbol(Beacons.FogSignal);
 		if (Renderer.zoom >= 15) {
-			AttMap atts = Rules.feature.objs.get(Obj.FOGSIG).get(0);
+			AttMap atts = feature.objs.get(Obj.FOGSIG).get(0);
 			if (atts != null) {
 				String str = "";
@@ -198,6 +198,6 @@
 		if (Renderer.zoom >= 15) {
 			String bstr = "";
-			CatRTB cat = (CatRTB) Rules.getAttEnum(Obj.RTPBCN, Att.CATRTB);
-			String wal = Rules.getAttStr(Obj.RTPBCN, Att.RADWAL);
+			CatRTB cat = (CatRTB) getAttEnum(Obj.RTPBCN, Att.CATRTB);
+			String wal = getAttStr(Obj.RTPBCN, Att.RADWAL);
 			switch (cat) {
 			case RTB_RAMK:
@@ -206,10 +206,10 @@
 			case RTB_RACN:
 				bstr += " Racon";
-				String astr = Rules.getAttStr(Obj.RTPBCN, Att.SIGGRP);
+				String astr = getAttStr(Obj.RTPBCN, Att.SIGGRP);
 				if (!astr.isEmpty()) {
 					bstr += "(" + astr + ")";
 				}
-				Double per = (Double) Rules.getAttVal(Obj.RTPBCN, Att.SIGPER);
-				Double mxr = (Double) Rules.getAttVal(Obj.RTPBCN, Att.VALMXR);
+				Double per = (Double) getAttVal(Obj.RTPBCN, Att.SIGPER);
+				Double mxr = (Double) getAttVal(Obj.RTPBCN, Att.VALMXR);
 				if ((per != null) || (mxr != null)) {
 					bstr += (astr.isEmpty() ? " " : "");
@@ -244,5 +244,5 @@
 		String bstr = "";
 		if (Renderer.zoom >= 11) {
-			ArrayList<CatROS> cats = (ArrayList<CatROS>) Rules.getAttList(Obj.RDOSTA, Att.CATROS);
+			ArrayList<CatROS> cats = (ArrayList<CatROS>) getAttList(Obj.RDOSTA, Att.CATROS);
 			for (CatROS ros : cats) {
 				switch (ros) {
@@ -373,5 +373,5 @@
 		Enum<ColCOL> col = null;
 		Enum<ColCOL> tcol = null;
-		ObjTab lights = Rules.feature.objs.get(Obj.LIGHTS);
+		ObjTab lights = feature.objs.get(Obj.LIGHTS);
 		for (AttMap atts : lights.values()) {
 			if (atts.containsKey(Att.COLOUR)) {
@@ -392,4 +392,5 @@
 		}
 		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) {
@@ -424,5 +425,6 @@
 									double ss2 = 361;
 									Double sdir = null;
-									if (satts == atts) continue;
+									if (satts == atts)
+										continue;
 									if (satts.containsKey(Att.LITRAD)) {
 										srad = (Double) satts.get(Att.LITRAD).val;
@@ -444,5 +446,6 @@
 											}
 										}
-										if ((ss1 > 360) || (ss2 > 360)) continue;
+										if ((ss1 > 360) || (ss2 > 360))
+											continue;
 										if (sdir != null) {
 											if (((dir - sdir + 360) % 360) < 8) {
@@ -496,185 +499,186 @@
 						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<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) {
+				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 (ColRng cr : colrng) {
-							if (cr.col == lit.col) {
-								if (lit.rng > cr.rng) {
-									cr.rng = lit.rng;
-								}
+						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) {
-							colrng.add(new ColRng(lit.col, lit.rng));
+							ArrayList<LitSect> tmp = new ArrayList<LitSect>();
+							tmp.add(lit);
+							groupings.add(tmp);
 						}
 					}
 					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);
+						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;
 							}
 						}
 					}
-					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(")")) {
+					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 (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)));
+						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/S57val.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/src/s57/S57val.java	(revision 32095)
@@ -216,5 +216,5 @@
  }
  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_MNRT, LMK_WTRT }
+  LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR }
  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"));
Index: applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java	(revision 32095)
@@ -71,5 +71,10 @@
 		g2.setPaint(Color.black);
 		g2.setFont(new Font("Arial", Font.BOLD, 20));
-		g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
+		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));
+		}
 	}
 
Index: applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java	(revision 32094)
+++ applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java	(revision 32095)
@@ -196,5 +196,4 @@
 		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);
-		Shapes.put(CatLMK.LMK_MNRT, Landmarks.Minaret); Shapes.put(CatLMK.LMK_WTRT, Landmarks.WaterTower);
 	}
 
