Index: applications/editors/josm/plugins/seachart/jicons/build.xml
===================================================================
--- applications/editors/josm/plugins/seachart/jicons/build.xml	(revision 31846)
+++ applications/editors/josm/plugins/seachart/jicons/build.xml	(revision 31955)
@@ -3,6 +3,4 @@
   <property name="build" location="build"/>
   <property name="jarfile" location="./jicons.jar"/>
-  <property name="ant.build.javac.target" value="1.7"/>
-  <property name="ant.build.javac.source" value="1.7"/>
   <property name="batik.dir" value="/usr/local/bin/batik-1.7/"/>
   <path id="classpath">
Index: applications/editors/josm/plugins/seachart/jrender/build.xml
===================================================================
--- applications/editors/josm/plugins/seachart/jrender/build.xml	(revision 31846)
+++ applications/editors/josm/plugins/seachart/jrender/build.xml	(revision 31955)
@@ -3,6 +3,4 @@
   <property name="build" location="build"/>
   <property name="jarfile" location="./jrender.jar"/>
-  <property name="ant.build.javac.target" value="1.7"/>
-  <property name="ant.build.javac.source" value="1.7"/>
   <property name="batik.dir" value="/usr/local/bin/batik-1.7/"/>
   <path id="classpath">
Index: applications/editors/josm/plugins/seachart/src/render/Signals.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 31846)
+++ applications/editors/josm/plugins/seachart/src/render/Signals.java	(revision 31955)
@@ -283,6 +283,17 @@
 	}
 
+	class Sect {
+    int dir;
+    LitCHR chr;
+    ColCOL col;
+    ColCOL alt;
+    String grp;
+    double per;
+    double rng;
+	}
+	
+	@SuppressWarnings("unchecked")
 	public static void lights(Feature feature) {
-/*		Enum<ColCOL> col = null;
+		Enum<ColCOL> col = null;
 		Enum<ColCOL> tcol = null;
 		ObjTab lights = feature.objs.get(Obj.LIGHTS);
@@ -370,56 +381,208 @@
 			}
 		}
-		final Att matches[] = { Att.SIGPER, Att.SIGGRP, Att.MLTYLT, Att.LITCHR, Att.CATLIT, Att.HEIGHT };
-		ArrayList<ArrayList<AttMap>> groups = new ArrayList<ArrayList<AttMap>>();
-		for (AttMap sector : lights.values()) {
-			if (sector.containsKey(Att.COLOUR)) {
-				boolean equal = false;
-				for (ArrayList<AttMap> group : groups) {
-					AttMap member = group.get(0);
-					for (Att match : matches) {
-						if (!((sector.containsKey(match) && member.containsKey(match) && sector.get(match).val.equals(member.get(match).val)) || (!sector.containsKey(match) && !member.containsKey(match)))) {
-							equal = false;
-							break;
-						} else {
-							equal = true;
-						}
-					}
-					if (equal) {
-						group.add(sector);
-						break;
-					}
-				}
-				if (!equal) {
-					ArrayList<AttMap> group = new ArrayList<AttMap>();
-					group.add(sector);
-					groups.add(group);
-				}
-			}
-		}
-		for (boolean sorted = false; !sorted;) {
-			sorted = true;
-			for (int i = 0; i < groups.size()-1; i ++) {
-				if (groups.get(i).size() < groups.get(i+1).size()) {
-					ArrayList<AttMap> tmp = groups.remove(i);
-					groups.add(i+1, tmp);
-					sorted = false;
-				}
-			}
-		}
-		for (ArrayList<AttMap> group : groups) {
-			for (boolean sorted = false; !sorted;) {
-				sorted = true;
-				for (int i = 0; i < group.size()-1; i ++) {
-					AttMap m0 = group.get(i);
-					AttMap m1 = group.get(i+1);
-					if (((m0.containsKey(Att.VALNMR) && m1.containsKey(Att.VALNMR) && ((int)(m0.get(Att.VALNMR).val) < (int)(m1.get(Att.VALNMR).val))))
-							|| (!m0.containsKey(Att.VALNMR) && m1.containsKey(Att.VALNMR))) {
-						AttMap tmp = group.remove(i);
-						group.add(i+1, tmp);
-						sorted = false;
-					}
-				}
-			}
-		}
+/*      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)");
+        }
+      }
+    }
 */	}
 
Index: applications/editors/josm/plugins/seachart/src/s57/S57att.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57att.java	(revision 31846)
+++ applications/editors/josm/plugins/seachart/src/s57/S57att.java	(revision 31955)
@@ -147,5 +147,4 @@
   AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
  }
- 
  private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static { Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
  private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static { Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
@@ -158,5 +157,5 @@
  private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class); static {
   Category.put(Obj.ACHARE, Att.CATACH); Category.put(Obj.ACHBRT, Att.CATACH); Category.put(Obj.AIRARE, Att.CATAIR); Category.put(Obj.BCNCAR, Att.CATCAM); Category.put(Obj.BCNLAT, Att.CATLAM);
-  Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM);
+  Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM); Category.put(Obj.DAYMAR, Att.CATSPM);
   Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
   Category.put(Obj.CBLARE, Att.CATCBL); Category.put(Obj.CBLOHD, Att.CATCBL); Category.put(Obj.CBLSUB, Att.CATCBL); Category.put(Obj.CHKPNT, Att.CATCHP); Category.put(Obj.COMARE, Att.CATCOM);
Index: applications/editors/josm/plugins/seachart/src/s57/S57map.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 31846)
+++ applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 31955)
@@ -559,97 +559,102 @@
 	
 	// Utility methods
-	
+
 	public boolean sortGeom(Feature feature) {
-		Geom sort = new Geom(feature.geom.prim);
-		long first = 0;
-		long last = 0;
-		Comp comp = null;
-		boolean next = true;
-		feature.geom.length = 0;
-		feature.geom.area = 0;
-		if (feature.geom.elems.isEmpty()) {
-			return false;
-		}
-		if (feature.geom.prim == Pflag.POINT) { 
-			feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
-			return true;
-		}	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;
-					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);
+		try {
+			Geom sort = new Geom(feature.geom.prim);
+			long first = 0;
+			long last = 0;
+			Comp comp = null;
+			boolean next = true;
+			feature.geom.length = 0;
+			feature.geom.area = 0;
+			if (feature.geom.elems.isEmpty()) {
+				return false;
+			}
+			if (feature.geom.prim == Pflag.POINT) {
+				feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
+				return true;
+			} 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;
 						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++;
+						if (prim.outer) {
+							sort.outers++;
+						} else {
+							sort.inners++;
+						}
+						comp = new Comp(cref++, 1);
+						sort.comps.add(comp);
 					} else {
-						feature.geom.elems.add(prim);
-					}
-				}
-				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;
-		}
-		if (feature.geom.prim == Pflag.AREA) {
-			int ie = 0;
-			int ic = 0;
-			while (ie < feature.geom.elems.size()) {
-				double area = calcArea(feature.geom, ic);
-				if (ie == 0) feature.geom.area = Math.abs(area) * 3444 * 3444;
-				if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
-					ArrayList<Prim> tmp = new ArrayList<>();
-					for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
-						Prim p = feature.geom.elems.remove(ie);
-						p.forward = !p.forward;
-						tmp.add(0, p);
-					}
-					feature.geom.elems.addAll(ie, tmp);
-				}
-				ie += feature.geom.comps.get(ic).size;
-				ic++;
-			}
-		}
-		feature.geom.length = calcLength(feature.geom);
-		feature.geom.centre = calcCentroid(feature);
-		return true;
+						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 (--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;
+			}
+			if (feature.geom.prim == Pflag.AREA) {
+				int ie = 0;
+				int ic = 0;
+				while (ie < feature.geom.elems.size()) {
+					double area = calcArea(feature.geom, ic);
+					if (ie == 0)
+						feature.geom.area = Math.abs(area) * 3444 * 3444;
+					if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
+						ArrayList<Prim> tmp = new ArrayList<>();
+						for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
+							Prim p = feature.geom.elems.remove(ie);
+							p.forward = !p.forward;
+							tmp.add(0, p);
+						}
+						feature.geom.elems.addAll(ie, tmp);
+					}
+					ie += feature.geom.comps.get(ic).size;
+					ic++;
+				}
+			}
+			feature.geom.length = calcLength(feature.geom);
+			feature.geom.centre = calcCentroid(feature);
+			return true;
+		} catch (Exception e) {
+			return false;
+		}
 	}
 	
Index: applications/editors/josm/plugins/seachart/src/s57/S57osm.java
===================================================================
--- applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 31846)
+++ applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 31955)
@@ -47,5 +47,7 @@
 		OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
 		OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
-	}
+		OSMtags.put("place=city", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_CITY)); OSMtags.put("place=town", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_TOWN));
+		OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
+		}
 	
 	public static KeyVal<?> OSMtag(String key, String val) {
@@ -142,5 +144,9 @@
 								}
 							}
-							map.addToEdge(ref);
+							try {
+								map.addToEdge(ref);
+							} catch (Exception e) {
+								inWay = false;
+							}
 						}
 						if (ln.contains("</way")) {
