Index: /applications/editors/josm/plugins/seachart/src/render/Renderer.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 34895)
+++ /applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 34896)
@@ -602,7 +602,4 @@
 
     public static void lightSector(Color col1, Color col2, double radius, double s1, double s2, Double dir, String str) {
-        if ((zoom >= 16) && (radius > 0.2)) {
-            radius /= Math.pow(2, zoom-15);
-        }
         double mid = (((s1 + s2) / 2) + (s1 > s2 ? 180 : 0)) % 360;
         g2.setStroke(new BasicStroke((float) (3.0 * sScale), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1,
Index: /applications/editors/josm/plugins/seachart/src/render/Rules.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 34895)
+++ /applications/editors/josm/plugins/seachart/src/render/Rules.java	(revision 34896)
@@ -121,5 +121,5 @@
 			}
 		}
-		return (name != null) ? (String) name.val : null;
+		return (name != null) ? ((String) name.val).replace("&quot;", "\"") : null;
 	}
 
@@ -430,6 +430,6 @@
 			if (testAttribute(feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
 				Renderer.symbol(Areas.WindFarm);
-				Renderer.lineVector(new LineStyle(Color.black, 20, new float[] { 40, 40 }));
-				addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 10)));
+				Renderer.lineVector(new LineStyle(Color.black, 12, new float[] { 40, 40 }));
+				addName(15, new Font("Arial", Font.BOLD, 80), new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 120)));
 			}
 			break;
@@ -954,6 +954,8 @@
 	@SuppressWarnings("unchecked")
 	private static void landmarks() {
-		if (!hasAttribute(Obj.LNDMRK, Att.CATLMK) && (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT)) && hasObject(Obj.LIGHTS))
+		if (!hasAttribute(Obj.LNDMRK, Att.CATLMK) && (!hasAttribute(Obj.LNDMRK, Att.FUNCTN) || testAttribute(Obj.LNDMRK, Att.FUNCTN, FncFNC.FNC_LGHT)) && hasObject(Obj.LIGHTS)) {
 			lights();
+			addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
+		}
 		else if (Renderer.zoom >= 12) {
 			switch (feature.type) {
@@ -981,7 +983,6 @@
 				break;
 			}
-			if (Renderer.zoom >= 15)
-				addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
 			Signals.addSignals();
+            addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
 		}
 	}
Index: /applications/editors/josm/plugins/seachart/src/render/Signals.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 34895)
+++ /applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 34896)
@@ -377,322 +377,319 @@
 	}
 
-	@SuppressWarnings("unchecked")
-	public static void lights() {
-		Enum<ColCOL> col = null;
-		Enum<ColCOL> tcol = null;
-		ObjTab lights = feature.objs.get(Obj.LIGHTS);
-		for (AttMap atts : lights.values()) {
-			if (atts.containsKey(Att.COLOUR)) {
-				ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-				if (cols.size() == 1) {
-					if (atts.containsKey(Att.CATLIT) && ((ArrayList<?>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_FLDL)) {
-						Renderer.symbol(Beacons.Floodlight, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(90))));
-					} else {
-						tcol = cols.get(0);
-						if (col == null) {
-							col = tcol;
-						} else if (tcol != col) {
-							col = ColCOL.COL_MAG;
-							break;
-						}
-					}
-				} else {
-					col = ColCOL.COL_MAG;
-					break;
-				}
-			}
-		}
-		if (col != null) {
-			Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)),
-					new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
-		}
-		if (Renderer.zoom >= 12) {
-			String str = "";
-			if (lights.get(1) != null) {
-				for (AttMap atts : lights.values()) {
-					Enum<ColCOL> col1 = null;
-					Enum<ColCOL> col2 = null;
-					double radius = 0.2;
-					double s1 = 361;
-					double s2 = 361;
-					Double dir = null;
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-						col1 = cols.get(0);
-						if (cols.size() > 1)
-							col2 = cols.get(1);
-					} else {
-						continue;
-					}
-					if (atts.containsKey(Att.CATLIT)) {
-						ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
-						if (cats.contains(CatLIT.LIT_DIR)) {
-							if (atts.containsKey(Att.ORIENT)) {
-								dir = (Double) atts.get(Att.ORIENT).val;
-								s1 = ((dir - 4) + 360) % 360;
-								s2 = (dir + 4) % 360;
-								for (AttMap satts : lights.values()) {
-									double srad = 0.2;
-									double ss1 = 361;
-									double ss2 = 361;
-									Double sdir = null;
-									if (satts == atts)
-										continue;
-									if (srad == radius) {
-										ArrayList<CatLIT> scats = (ArrayList<CatLIT>) (satts.containsKey(Att.CATLIT) ? (ArrayList<CatLIT>) satts.get(Att.CATLIT).val : new ArrayList<>());
-										if (scats.contains(CatLIT.LIT_DIR)) {
-											if (satts.containsKey(Att.ORIENT)) {
-												sdir = (Double) satts.get(Att.ORIENT).val;
-												ss1 = sdir;
-												ss2 = sdir;
-											}
-										} else {
-											if (satts.containsKey(Att.SECTR1)) {
-												ss1 = (Double) satts.get(Att.SECTR1).val;
-											}
-											if (satts.containsKey(Att.SECTR2)) {
-												ss2 = (Double) satts.get(Att.SECTR2).val;
-											}
-										}
-										if ((ss1 > 360) || (ss2 > 360))
-											continue;
-										if (sdir != null) {
-											if (((dir - sdir + 360) % 360) < 8) {
-												s1 = ((((sdir > dir) ? 360 : 0) + sdir + dir) / 2) % 360;
-											}
-											if (((sdir - dir + 360) % 360) < 8) {
-												s2 = ((((dir > sdir) ? 360 : 0) + sdir + dir) / 2) % 360;
-											}
-										} else {
-											if (((dir - ss2 + 360) % 360) < 4) {
-												s1 = ss2;
-											}
-											if (((ss1 - dir + 360) % 360) < 4) {
-												s2 = ss1;
-											}
-										}
-									}
-								}
-							}
-						}
-					}
-					if ((s1 > 360) && atts.containsKey(Att.SECTR1)) {
-						s1 = (Double) atts.get(Att.SECTR1).val;
-					} else if (dir == null) {
-						continue;
-					}
-					if ((s2 > 360) && atts.containsKey(Att.SECTR2)) {
-						s2 = (Double) atts.get(Att.SECTR2).val;
-					} else if (dir == null) {
-						continue;
-					}
-					str = "";
-					if (atts.containsKey(Att.LITCHR)) {
-						str += LightCharacters.get(((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0));
-					}
-					if (atts.containsKey(Att.SIGGRP)) {
-						str += "(" + atts.get(Att.SIGGRP).val + ")";
-					} else if (!str.isEmpty()) {
-						str += ".";
-					}
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
-						str += LightLetters.get(cols.get(0));
-						if (cols.size() > 1)
-							str += LightLetters.get(cols.get(1));
-					}
-					if (atts.containsKey(Att.SIGPER)) {
-						str += "." + df.format(atts.get(Att.SIGPER).val) + "s";
-					}
-					if ((s1 <= 360) && (s2 <= 360) && (s1 != s2))
-						Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
-				}
-				if (Renderer.zoom >= 15) {
-					class LitSect {
-						boolean dir;
-						LitCHR chr;
-						ColCOL col;
-						String grp;
-						double per;
-						double rng;
-						double hgt;
-					}
-
-					ArrayList<LitSect> litatts = new ArrayList<>();
-					for (AttMap atts : lights.values()) {
-						LitSect sect = new LitSect();
-						sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
-						sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
-						switch (sect.chr) {
-						case CHR_AL:
-							sect.chr = LitCHR.CHR_F;
-							break;
-						case CHR_ALOC:
-							sect.chr = LitCHR.CHR_OC;
-							break;
-						case CHR_ALLFL:
-							sect.chr = LitCHR.CHR_LFL;
-							break;
-						case CHR_ALFL:
-							sect.chr = LitCHR.CHR_FL;
-							break;
-						case CHR_ALFFL:
-							sect.chr = LitCHR.CHR_FFL;
-							break;
-						default:
-							break;
-						}
-						sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
-						sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
-						sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
-						sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
-						ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
-						sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
-						if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
-							litatts.add(sect);
-					}
-					ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
-					for (LitSect lit : litatts) {
-						boolean found = false;
-						for (ArrayList<LitSect> group : groupings) {
-							LitSect mem = group.get(0);
-							if (lit.dir == mem.dir && lit.chr == mem.chr && lit.grp.equals(mem.grp) && lit.per == mem.per && lit.hgt == mem.hgt) {
-								group.add(lit);
-								found = true;
-							}
-						}
-						if (!found) {
-							ArrayList<LitSect> tmp = new ArrayList<>();
-							tmp.add(lit);
-							groupings.add(tmp);
-						}
-					}
-					for (boolean moved = true; moved;) {
-						moved = false;
-						for (int i = 0; i < groupings.size() - 1; i++) {
-							if (groupings.get(i).size() < groupings.get(i + 1).size()) {
-								ArrayList<LitSect> tmp = groupings.remove(i);
-								groupings.add(i + 1, tmp);
-								moved = true;
-							}
-						}
-					}
-					class ColRng {
-						ColCOL col;
-						double rng;
-
-						ColRng(ColCOL c, double r) {
-							col = c;
-							rng = r;
-						}
-					}
-
-					int y = -30;
-					for (ArrayList<LitSect> group : groupings) {
-						ArrayList<ColRng> colrng = new ArrayList<>();
-						for (LitSect lit : group) {
-							boolean found = false;
-							for (ColRng cr : colrng) {
-								if (cr.col == lit.col) {
-									if (lit.rng > cr.rng) {
-										cr.rng = lit.rng;
-									}
-									found = true;
-								}
-							}
-							if (!found) {
-								colrng.add(new ColRng(lit.col, lit.rng));
-							}
-						}
-						for (boolean moved = true; moved;) {
-							moved = false;
-							for (int i = 0; i < colrng.size() - 1; i++) {
-								if (colrng.get(i).rng < colrng.get(i + 1).rng) {
-									ColRng tmp = colrng.remove(i);
-									colrng.add(i + 1, tmp);
-									moved = true;
-								}
-							}
-						}
-						LitSect tmp = group.get(0);
-						str = tmp.dir ? "Dir" : "";
-						str += LightCharacters.get(tmp.chr);
-						if (!tmp.grp.isEmpty())
-							str += "(" + tmp.grp + ")";
-						else
-							str += ".";
-						for (ColRng cr : colrng) {
-							str += LightLetters.get(cr.col);
-						}
-						if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
-							str += ".";
-						if (tmp.per > 0)
-							str += df.format(tmp.per) + "s";
-						if (tmp.hgt > 0)
-							str += df.format(tmp.hgt) + "m";
-						if (colrng.get(0).rng > 0)
-							str += df.format(colrng.get(0).rng) + ((colrng.size() > 1) ? ((colrng.size() > 2) ? ("-" + df.format(colrng.get(colrng.size() - 1).rng)) : ("/" + df.format(colrng.get(1).rng))) : "") + "M";
-						Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
-						y += 40;
-						str = "";
-					}
-				}
-			} else {
-				if (Renderer.zoom >= 15) {
-					AttMap atts = lights.get(0);
-					ArrayList<CatLIT> cats = new ArrayList<>();
-					if (atts.containsKey(Att.CATLIT)) {
-						cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
-					}
-					str = cats.contains(CatLIT.LIT_DIR) ? "Dir" : "";
-					str += atts.containsKey(Att.MLTYLT) ? atts.get(Att.MLTYLT).val : "";
-					if (atts.containsKey(Att.LITCHR)) {
-						LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
-						if (atts.containsKey(Att.SIGGRP)) {
-							String grp = (String) atts.get(Att.SIGGRP).val;
-							switch (chr) {
-							case CHR_QLFL:
-								str += String.format("Q(%s)+LFl", grp);
-								break;
-							case CHR_VQLFL:
-								str += String.format("VQ(%s)+LFl", grp);
-								break;
-							case CHR_UQLFL:
-								str += String.format("UQ(%s)+LFl", grp);
-								break;
-							default:
-								str += String.format("%s(%s)", LightCharacters.get(chr), grp);
-								break;
-							}
-						} else {
-							str += LightCharacters.get(chr);
-						}
-					}
-					if (atts.containsKey(Att.COLOUR)) {
-						ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
-						if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
-							if (!str.isEmpty() && !str.endsWith(")")) {
-								str += ".";
-							}
-							for (ColCOL acol : cols) {
-								str += LightLetters.get(acol);
-							}
-						}
-					}
-					str += cats.contains(CatLIT.LIT_VERT) ? "(vert)" : "";
-					str += cats.contains(CatLIT.LIT_HORI) ? "(hor)" : "";
-					str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
-					str += atts.containsKey(Att.SIGPER) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
-					str += atts.containsKey(Att.HEIGHT) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
-					str += atts.containsKey(Att.VALNMR) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
-					str += cats.contains(CatLIT.LIT_FRNT) ? "(Front)" : "";
-					str += cats.contains(CatLIT.LIT_REAR) ? "(Rear)" : "";
-					str += cats.contains(CatLIT.LIT_UPPR) ? "(Upper)" : "";
-					str += cats.contains(CatLIT.LIT_LOWR) ? "(Lower)" : "";
-					Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
-				}
-			}
-		}
-	}
+    @SuppressWarnings("unchecked")
+    public static void lights() {
+        Enum<ColCOL> col = null;
+        Enum<ColCOL> tcol = null;
+        ObjTab lights = feature.objs.get(Obj.LIGHTS);
+        for (AttMap atts : lights.values()) {
+            if (atts.containsKey(Att.COLOUR)) {
+                ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                if (cols.size() == 1) {
+                    if (atts.containsKey(Att.CATLIT) && ((ArrayList<?>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_FLDL)) {
+                        Renderer.symbol(Beacons.Floodlight, new Delta(Handle.CC, AffineTransform.getRotateInstance(Math.toRadians(90))));
+                    } else {
+                        tcol = cols.get(0);
+                        if (col == null) {
+                            col = tcol;
+                        } else if (tcol != col) {
+                            col = ColCOL.COL_MAG;
+                            break;
+                        }
+                    }
+                } else {
+                    col = ColCOL.COL_MAG;
+                    break;
+                }
+            }
+        }
+        if (col != null) {
+            Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
+        }
+        String str = "";
+        if (lights.get(1) != null) {
+            for (AttMap atts : lights.values()) {
+                Enum<ColCOL> col1 = null;
+                Enum<ColCOL> col2 = null;
+                double radius = 0.5;
+                if (atts.containsKey(Att.VALNMR)) {
+                    radius += Math.log10((Double) atts.get(Att.VALNMR).val) * 2.0;
+                }
+                radius /= Math.pow(Renderer.zoom, 4) / 5000;
+                double s1 = 361;
+                double s2 = 361;
+                Double dir = null;
+                if (atts.containsKey(Att.COLOUR)) {
+                    ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                    col1 = cols.get(0);
+                    if (cols.size() > 1)
+                        col2 = cols.get(1);
+                } else {
+                    continue;
+                }
+                if (atts.containsKey(Att.CATLIT)) {
+                    ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
+                    if (cats.contains(CatLIT.LIT_DIR)) {
+                        if (atts.containsKey(Att.ORIENT)) {
+                            dir = (Double) atts.get(Att.ORIENT).val;
+                            s1 = ((dir - 4) + 360) % 360;
+                            s2 = (dir + 4) % 360;
+                            for (AttMap satts : lights.values()) {
+                                double ss1 = 361;
+                                double ss2 = 361;
+                                Double sdir = null;
+                                if (satts == atts)
+                                    continue;
+                                ArrayList<CatLIT> scats = (ArrayList<CatLIT>) (satts.containsKey(Att.CATLIT) ? (ArrayList<CatLIT>) satts.get(Att.CATLIT).val : new ArrayList<>());
+                                if (scats.contains(CatLIT.LIT_DIR)) {
+                                    if (satts.containsKey(Att.ORIENT)) {
+                                        sdir = (Double) satts.get(Att.ORIENT).val;
+                                        ss1 = sdir;
+                                        ss2 = sdir;
+                                    }
+                                } else {
+                                    if (satts.containsKey(Att.SECTR1)) {
+                                        ss1 = (Double) satts.get(Att.SECTR1).val;
+                                    }
+                                    if (satts.containsKey(Att.SECTR2)) {
+                                        ss2 = (Double) satts.get(Att.SECTR2).val;
+                                    }
+                                }
+                                if ((ss1 > 360) || (ss2 > 360))
+                                    continue;
+                                if (sdir != null) {
+                                    if (((dir - sdir + 360) % 360) < 8) {
+                                        s1 = ((((sdir > dir) ? 360 : 0) + sdir + dir) / 2) % 360;
+                                    }
+                                    if (((sdir - dir + 360) % 360) < 8) {
+                                        s2 = ((((dir > sdir) ? 360 : 0) + sdir + dir) / 2) % 360;
+                                    }
+                                } else {
+                                    if (((dir - ss2 + 360) % 360) < 4) {
+                                        s1 = ss2;
+                                    }
+                                    if (((ss1 - dir + 360) % 360) < 4) {
+                                        s2 = ss1;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                if ((s1 > 360) && atts.containsKey(Att.SECTR1)) {
+                    s1 = (Double) atts.get(Att.SECTR1).val;
+                } else if (dir == null) {
+                    continue;
+                }
+                if ((s2 > 360) && atts.containsKey(Att.SECTR2)) {
+                    s2 = (Double) atts.get(Att.SECTR2).val;
+                } else if (dir == null) {
+                    continue;
+                }
+                str = "";
+                if (atts.containsKey(Att.LITCHR)) {
+                    str += LightCharacters.get(((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0));
+                }
+                if (atts.containsKey(Att.SIGGRP)) {
+                    str += "(" + atts.get(Att.SIGGRP).val + ")";
+                } else if (!str.isEmpty()) {
+                    str += ".";
+                }
+                if (atts.containsKey(Att.COLOUR)) {
+                    ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
+                    str += LightLetters.get(cols.get(0));
+                    if (cols.size() > 1)
+                        str += LightLetters.get(cols.get(1));
+                }
+                if (atts.containsKey(Att.SIGPER)) {
+                    str += "." + df.format(atts.get(Att.SIGPER).val) + "s";
+                }
+                if ((s1 <= 360) && (s2 <= 360) && (s1 != s2))
+                    Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
+            }
+            if (Renderer.zoom >= 15) {
+                class LitSect {
+                    boolean dir;
+                    LitCHR chr;
+                    ColCOL col;
+                    String grp;
+                    double per;
+                    double rng;
+                    double hgt;
+                }
+
+                ArrayList<LitSect> litatts = new ArrayList<>();
+                for (AttMap atts : lights.values()) {
+                    LitSect sect = new LitSect();
+                    sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
+                    sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
+                    switch (sect.chr) {
+                    case CHR_AL:
+                        sect.chr = LitCHR.CHR_F;
+                        break;
+                    case CHR_ALOC:
+                        sect.chr = LitCHR.CHR_OC;
+                        break;
+                    case CHR_ALLFL:
+                        sect.chr = LitCHR.CHR_LFL;
+                        break;
+                    case CHR_ALFL:
+                        sect.chr = LitCHR.CHR_FL;
+                        break;
+                    case CHR_ALFFL:
+                        sect.chr = LitCHR.CHR_FFL;
+                        break;
+                    default:
+                        break;
+                    }
+                    sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
+                    sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
+                    sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
+                    sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
+                    ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
+                    sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
+                    if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
+                        litatts.add(sect);
+                }
+                ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
+                for (LitSect lit : litatts) {
+                    boolean found = false;
+                    for (ArrayList<LitSect> group : groupings) {
+                        LitSect mem = group.get(0);
+                        if (lit.dir == mem.dir && lit.chr == mem.chr && lit.grp.equals(mem.grp) && lit.per == mem.per && lit.hgt == mem.hgt) {
+                            group.add(lit);
+                            found = true;
+                        }
+                    }
+                    if (!found) {
+                        ArrayList<LitSect> tmp = new ArrayList<>();
+                        tmp.add(lit);
+                        groupings.add(tmp);
+                    }
+                }
+                for (boolean moved = true; moved;) {
+                    moved = false;
+                    for (int i = 0; i < groupings.size() - 1; i++) {
+                        if (groupings.get(i).size() < groupings.get(i + 1).size()) {
+                            ArrayList<LitSect> tmp = groupings.remove(i);
+                            groupings.add(i + 1, tmp);
+                            moved = true;
+                        }
+                    }
+                }
+                class ColRng {
+                    ColCOL col;
+                    double rng;
+
+                    ColRng(ColCOL c, double r) {
+                        col = c;
+                        rng = r;
+                    }
+                }
+
+                int y = -30;
+                for (ArrayList<LitSect> group : groupings) {
+                    ArrayList<ColRng> colrng = new ArrayList<>();
+                    for (LitSect lit : group) {
+                        boolean found = false;
+                        for (ColRng cr : colrng) {
+                            if (cr.col == lit.col) {
+                                if (lit.rng > cr.rng) {
+                                    cr.rng = lit.rng;
+                                }
+                                found = true;
+                            }
+                        }
+                        if (!found) {
+                            colrng.add(new ColRng(lit.col, lit.rng));
+                        }
+                    }
+                    for (boolean moved = true; moved;) {
+                        moved = false;
+                        for (int i = 0; i < colrng.size() - 1; i++) {
+                            if (colrng.get(i).rng < colrng.get(i + 1).rng) {
+                                ColRng tmp = colrng.remove(i);
+                                colrng.add(i + 1, tmp);
+                                moved = true;
+                            }
+                        }
+                    }
+                    LitSect tmp = group.get(0);
+                    str = tmp.dir ? "Dir" : "";
+                    str += LightCharacters.get(tmp.chr);
+                    if (!tmp.grp.isEmpty())
+                        str += "(" + tmp.grp + ")";
+                    else
+                        str += ".";
+                    for (ColRng cr : colrng) {
+                        str += LightLetters.get(cr.col);
+                    }
+                    if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
+                        str += ".";
+                    if (tmp.per > 0)
+                        str += df.format(tmp.per) + "s";
+                    if (tmp.hgt > 0)
+                        str += df.format(tmp.hgt) + "m";
+                    if (colrng.get(0).rng > 0)
+                        str += df.format(colrng.get(0).rng) + ((colrng.size() > 1) ? ((colrng.size() > 2) ? ("-" + df.format(colrng.get(colrng.size() - 1).rng)) : ("/" + df.format(colrng.get(1).rng))) : "") + "M";
+                    Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
+                    y += 40;
+                    str = "";
+                }
+            }
+        } else {
+            if (Renderer.zoom >= 15) {
+                AttMap atts = lights.get(0);
+                ArrayList<CatLIT> cats = new ArrayList<>();
+                if (atts.containsKey(Att.CATLIT)) {
+                    cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
+                }
+                str = cats.contains(CatLIT.LIT_DIR) ? "Dir" : "";
+                str += atts.containsKey(Att.MLTYLT) ? atts.get(Att.MLTYLT).val : "";
+                if (atts.containsKey(Att.LITCHR)) {
+                    LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
+                    if (atts.containsKey(Att.SIGGRP)) {
+                        String grp = (String) atts.get(Att.SIGGRP).val;
+                        switch (chr) {
+                        case CHR_QLFL:
+                            str += String.format("Q(%s)+LFl", grp);
+                            break;
+                        case CHR_VQLFL:
+                            str += String.format("VQ(%s)+LFl", grp);
+                            break;
+                        case CHR_UQLFL:
+                            str += String.format("UQ(%s)+LFl", grp);
+                            break;
+                        default:
+                            str += String.format("%s(%s)", LightCharacters.get(chr), grp);
+                            break;
+                        }
+                    } else {
+                        str += LightCharacters.get(chr);
+                    }
+                }
+                if (atts.containsKey(Att.COLOUR)) {
+                    ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
+                    if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
+                        if (!str.isEmpty() && !str.endsWith(")")) {
+                            str += ".";
+                        }
+                        for (ColCOL acol : cols) {
+                            str += LightLetters.get(acol);
+                        }
+                    }
+                }
+                str += cats.contains(CatLIT.LIT_VERT) ? "(vert)" : "";
+                str += cats.contains(CatLIT.LIT_HORI) ? "(hor)" : "";
+                str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
+                str += atts.containsKey(Att.SIGPER) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
+                str += atts.containsKey(Att.HEIGHT) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
+                str += atts.containsKey(Att.VALNMR) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
+                str += cats.contains(CatLIT.LIT_FRNT) ? "(Front)" : "";
+                str += cats.contains(CatLIT.LIT_REAR) ? "(Rear)" : "";
+                str += cats.contains(CatLIT.LIT_UPPR) ? "(Upper)" : "";
+                str += cats.contains(CatLIT.LIT_LOWR) ? "(Lower)" : "";
+                Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
+            }
+        }
+    }
 }
-
