Index: /applications/editors/josm/plugins/smed2/src/s57/S57att.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/s57/S57att.java	(revision 30045)
+++ /applications/editors/josm/plugins/smed2/src/s57/S57att.java	(revision 30046)
@@ -139,8 +139,8 @@
 		AttStr.put(Att.NPLDST, "national_pilot_district"); AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum");
 		AttStr.put(Att.POSACC, "positional_accuracy"); AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank");
-		AttStr.put(Att.CATBNK, "category");	AttStr.put(Att.CATNMK, "category"); AttStr.put(Att.CLSDNG, "class"); AttStr.put(Att.DIRIMP, "impact");
+		AttStr.put(Att.CATBNK, "category");	AttStr.put(Att.CATNMK, "category"); AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact");
 		AttStr.put(Att.DISBK1, "distance_start");	AttStr.put(Att.DISBK2, "distance_end");AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down");
 		AttStr.put(Att.ELEVA1, "minimum_elevation"); AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance");
-		AttStr.put(Att.BUNVES, "availibility");	AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category");
+		AttStr.put(Att.BUNVES, "availability");	AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category");
 		AttStr.put(Att.CATHBR, "category");	AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication");
 		AttStr.put(Att.HORCLL, "clearance_length");	AttStr.put(Att.HORCLW, "clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, "locode");
@@ -150,4 +150,5 @@
 		AttStr.put(Att.CATVTR, "category");	AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
 		AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
+		AttStr.put(Att.CATCOM, "category");
 		AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.CATWWM, "category"); AttStr.put(Att.SHPTYP, "ship"); AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
 	}
@@ -203,4 +204,6 @@
 	  objatt.add(new ObjAtt(Obj.WEDKLP, Att.CATWED)); objatt.add(new ObjAtt(Obj.WRECKS, Att.CATWRK)); objatt.add(new ObjAtt(Obj.TS_FEB, Att.CAT_TS));
 	  objatt.add(new ObjAtt(Obj.DEPCNT, Att.VALDCO)); objatt.add(new ObjAtt(Obj.SOUNDG, Att.VALSOU)); objatt.add(new ObjAtt(Obj.NOTMRK, Att.BNKWTW));
+	  objatt.add(new ObjAtt(Obj.WTWAXS, Att.CATCCL)); objatt.add(new ObjAtt(Obj.WTWARE, Att.CATCCL)); objatt.add(new ObjAtt(Obj.COMARE, Att.CATCOM));
+	  objatt.add(new ObjAtt(Obj.RDOCAL, Att.CATCOM)); objatt.add(new ObjAtt(Obj.WTWGAG, Att.CATGAG));
 	  objatt.add(new ObjAtt(Obj.ACHBRT, Att.RADIUS)); objatt.add(new ObjAtt(Obj.LIGHTS, Att.LITRAD));
 	}
Index: /applications/editors/josm/plugins/smed2/src/s57/S57val.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/s57/S57val.java	(revision 30045)
+++ /applications/editors/josm/plugins/smed2/src/s57/S57val.java	(revision 30046)
@@ -96,5 +96,5 @@
 	public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
 	private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<CatCHP, S57enum>(CatCHP.class); static { Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
-		Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "custom")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
+		Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
 	}
 	public enum CatCOA { COA_UNKN, COA_STEP, COA_FLAT, COA_SAND, COA_STON, COA_SHNG, COA_GLCR, COA_MNGV, COA_MRSH, COA_CRRF, COA_ICE, COA_SHEL } 
@@ -855,10 +855,10 @@
 	private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<CatCOM, S57enum>(CatCOM.class); static { Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
 		Catcom.put(CatCOM.COM_VTSC, new S57enum(1, "vts_centre")); Catcom.put(CatCOM.COM_VTSS, new S57enum(2, "vts_sector")); Catcom.put(CatCOM.COM_IVSP, new S57enum(3, "ivs_point"));
-		Catcom.put(CatCOM.COM_MID, new S57enum(4, "mid")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
-		Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "custom")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
+		Catcom.put(CatCOM.COM_MID, new S57enum(4, "mib")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
+		Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
 	}
 	public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
 	private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<CatHBR, S57enum>(CatHBR.class); static { Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
-		Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "custom")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
+		Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "customs")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
 		Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
 	}
Index: /applications/editors/josm/plugins/smed2/src/seamap/Renderer.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/seamap/Renderer.java	(revision 30045)
+++ /applications/editors/josm/plugins/smed2/src/seamap/Renderer.java	(revision 30046)
@@ -16,8 +16,5 @@
 import java.util.*;
 
-import s57.S57att.*;
-import s57.S57obj.*;
 import s57.S57val.*;
-import s57.S57val;
 import seamap.SeaMap;
 import seamap.SeaMap.*;
@@ -30,4 +27,39 @@
 	public static final double symbolScale[] = { 256.0, 128.0, 64.0, 32.0, 16.0, 8.0, 4.0, 2.0, 1.0, 0.61, 0.372, 0.227, 0.138, 0.0843, 0.0514, 0.0313, 0.0191, 0.0117, 0.007, 0.138 };
 
+	public static final Color Yland = new Color(0x50b0ff);
+	public static final Color Mline = new Color(0x80c480);
+	public static final Color Msymb = new Color(0xa30075);
+	
+	static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<ColCOL, Color>(ColCOL.class);
+	static {
+		bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
+		bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
+		bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
+		bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
+		bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
+		bodyColours.put(ColCOL.COL_BLU, Color.blue);
+		bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
+		bodyColours.put(ColCOL.COL_GRY, Color.gray);
+		bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
+		bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
+		bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
+		bodyColours.put(ColCOL.COL_ORG, Color.orange);
+		bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
+		bodyColours.put(ColCOL.COL_PNK, Color.pink);
+	}
+
+	static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<ColPAT, Patt>(ColPAT.class);
+	static {
+		pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
+		pattMap.put(ColPAT.PAT_HORI, Patt.H);
+		pattMap.put(ColPAT.PAT_VERT, Patt.V);
+		pattMap.put(ColPAT.PAT_DIAG, Patt.D);
+		pattMap.put(ColPAT.PAT_BRDR, Patt.B);
+		pattMap.put(ColPAT.PAT_SQUR, Patt.S);
+		pattMap.put(ColPAT.PAT_CROS, Patt.C);
+		pattMap.put(ColPAT.PAT_SALT, Patt.X);
+		pattMap.put(ColPAT.PAT_STRP, Patt.H);
+	}
+	
 	public enum LabelStyle { NONE, RRCT, RECT, ELPS, CIRC, VCLR, HCLR }
 
Index: /applications/editors/josm/plugins/smed2/src/seamap/Rules.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/seamap/Rules.java	(revision 30045)
+++ /applications/editors/josm/plugins/smed2/src/seamap/Rules.java	(revision 30046)
@@ -14,5 +14,7 @@
 import java.awt.geom.AffineTransform;
 import java.util.ArrayList;
-
+import java.util.HashMap;
+
+import s57.S57val;
 import s57.S57val.*;
 import s57.S57att.*;
@@ -28,7 +30,77 @@
 	static int zoom;
 	
-	public static final Color Yland = new Color(0x50b0ff);
-	public static final Color Mline = new Color(0x80c480);
-	public static final Color Msymb = new Color(0xa30075);
+	static String getName(Feature feature) {
+		AttItem name = feature.atts.get(Att.OBJNAM);
+		if (name == null) {
+			name = feature.objs.get(feature.type).get(0).get(Att.OBJNAM);
+		}
+		if (name != null) return (String)name.val;
+		return null;
+	}
+
+	static AttMap getAtts(Feature feature, Obj obj, int idx) {
+		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
+		if (objs == null)
+			return null;
+		else
+			return objs.get(idx);
+	}
+
+	public static Object getAttVal(Feature feature, Obj obj, int idx, Att att) {
+		AttMap atts = null;
+		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
+		if (objs != null)
+			atts = objs.get(idx);
+		if (atts == null)
+			return S57val.nullVal(att);
+		else {
+			AttItem item = atts.get(att);
+			if (item == null)
+				return S57val.nullVal(att);
+			return item.val;
+		}
+	}
+	
+	static Scheme getScheme(Feature feature, Obj obj) {
+		ArrayList<Color> colours = new ArrayList<Color>();
+		for (ColCOL col : (ArrayList<ColCOL>)getAttVal(feature, obj, 0, Att.COLOUR)) {
+			colours.add(Renderer.bodyColours.get(col));
+		}
+		ArrayList<Patt> patterns = new ArrayList<Patt>();
+		for(ColPAT pat: (ArrayList<ColPAT>) getAttVal(feature, obj, 0, Att.COLPAT)) {
+			patterns.add(Renderer.pattMap.get(pat));
+		}
+		return new Scheme(patterns, colours);
+	}
+	
+	static boolean hasObject(Feature feature, Obj obj) {
+		return (feature.objs.containsKey(obj));
+	}
+	
+	static boolean hasAttribute(Feature feature, Obj obj, Att att) {
+		AttMap atts = getAtts(feature, obj, 0);
+		return ((atts != null) && (atts.containsKey(att)));
+	}
+	
+	static boolean testAttribute(Feature feature, Obj obj, Att att, Object val) {
+		AttMap atts = getAtts(feature, obj, 0);
+		if (atts != null) {
+			AttItem item = atts.get(att);
+			if (item != null) {
+				switch (item.conv) {
+				case S:
+				case A:
+					return ((String)item.val).equals(val);
+				case L:
+					return ((ArrayList<?>)item.val).contains(val);
+				case E:
+				case F:
+				case I:
+					return item.val.equals(val);
+				}
+			}
+		}
+		return false;
+	}
 	
 	public static void rules (SeaMap m, int z) {
@@ -77,6 +149,7 @@
 		if ((objects = map.features.get(Obj.SMCFAC)) != null) for (Feature feature : objects) marinas(feature);
 		if ((objects = map.features.get(Obj.BRIDGE)) != null) for (Feature feature : objects) bridges(feature);
+		if ((objects = map.features.get(Obj.PILPNT)) != null) for (Feature feature : objects) lights(feature);
+		if ((objects = map.features.get(Obj.LITMIN)) != null) for (Feature feature : objects) lights(feature);
 		if ((objects = map.features.get(Obj.LITMAJ)) != null) for (Feature feature : objects) lights(feature);
-		if ((objects = map.features.get(Obj.LITMIN)) != null) for (Feature feature : objects) lights(feature);
 		if ((objects = map.features.get(Obj.LIGHTS)) != null) for (Feature feature : objects) lights(feature);
 		if ((objects = map.features.get(Obj.SISTAT)) != null) for (Feature feature : objects) stations(feature);
@@ -108,5 +181,5 @@
 	
 	private static void areas(Feature feature) {
-		String name = Util.getName(feature);
+		String name = getName(feature);
 		switch (feature.type) {
 		case DRGARE:
@@ -121,7 +194,7 @@
 			if (feature.area > 2.0) {
 				if (zoom < 16)
-					Renderer.lineVector(feature, new LineStyle(Mline, 8, new float[] { 50, 50 }, new Color(0x40ffffff, true)));
+					Renderer.lineVector(feature, new LineStyle(Renderer.Mline, 8, new float[] { 50, 50 }, new Color(0x40ffffff, true)));
 				else
-					Renderer.lineVector(feature, new LineStyle(Mline, 8, new float[] { 50, 50 }));
+					Renderer.lineVector(feature, new LineStyle(Renderer.Mline, 8, new float[] { 50, 50 }));
 			} else {
 				if (zoom >= 14)
@@ -136,5 +209,5 @@
 			break;
 		case OSPARE:
-			if (Util.testAttribute(feature, feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
+			if (testAttribute(feature, feature.type, Att.CATPRA, CatPRA.PRA_WFRM)) {
 				Renderer.symbol(feature, Areas.WindFarm);
 				Renderer.lineVector(feature, new LineStyle(Color.black, 20, new float[] { 40, 40 }));
@@ -145,6 +218,6 @@
 		case RESARE:
 			if (zoom >= 12) {
-				Renderer.lineSymbols(feature, Areas.Restricted, 1.0, null, null, 0, Mline);
-				if (Util.testAttribute(feature, feature.type, Att.CATPRA, CatREA.REA_NWAK)) {
+				Renderer.lineSymbols(feature, Areas.Restricted, 1.0, null, null, 0, Renderer.Mline);
+				if (testAttribute(feature, feature.type, Att.CATPRA, CatREA.REA_NWAK)) {
 					Renderer.symbol(feature, Areas.NoWake);
 				}
@@ -152,5 +225,5 @@
 			break;
 		case SEAARE:
-			switch ((CatSEA) Util.getAttVal(feature, feature.type, 0, Att.CATSEA)) {
+			switch ((CatSEA) getAttVal(feature, feature.type, 0, Att.CATSEA)) {
 			case SEA_RECH:
 				if ((zoom >= 10) && (name != null))
@@ -205,5 +278,5 @@
 			if (zoom >= 12) {
 				Renderer.symbol(feature, Areas.Plane);
-				Renderer.lineSymbols(feature, Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Mline);
+				Renderer.lineSymbols(feature, Areas.Restricted, 0.5, Areas.LinePlane, null, 10, Renderer.Mline);
 			}
 			if ((zoom >= 15) && (name != null))
@@ -216,7 +289,7 @@
 	
 	private static void beacons(Feature feature) {
-		BcnSHP shape = (BcnSHP) Util.getAttVal(feature, feature.type, 0, Att.BCNSHP);
+		BcnSHP shape = (BcnSHP) getAttVal(feature, feature.type, 0, Att.BCNSHP);
 		if (((shape == BcnSHP.BCN_PRCH) || (shape == BcnSHP.BCN_WTHY)) && (feature.type == Obj.BCNLAT)) {
-			CatLAM cat = (CatLAM) Util.getAttVal(feature, feature.type, 0, Att.CATLAM);
+			CatLAM cat = (CatLAM) getAttVal(feature, feature.type, 0, Att.CATLAM);
 			switch (cat) {
 			case LAM_PORT:
@@ -233,10 +306,10 @@
 				break;
 			default:
-				Renderer.symbol(feature, Beacons.Stake, Util.getScheme(feature, feature.type));
+				Renderer.symbol(feature, Beacons.Stake, getScheme(feature, feature.type));
 			}
 		} else {
-			Renderer.symbol(feature, Beacons.Shapes.get(shape), Util.getScheme(feature, feature.type));
+			Renderer.symbol(feature, Beacons.Shapes.get(shape), getScheme(feature, feature.type));
 			if (feature.objs.get(Obj.TOPMAR) != null)
-				Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), Util.getScheme(feature, Obj.TOPMAR), Topmarks.BeaconDelta);
+				Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), getScheme(feature, Obj.TOPMAR), Topmarks.BeaconDelta);
 		}
 		Signals.addSignals(feature);
@@ -244,8 +317,8 @@
 	
 	private static void buoys(Feature feature) {
-		BoySHP shape = (BoySHP) Util.getAttVal(feature, feature.type, 0, Att.BOYSHP);
-		Renderer.symbol(feature, Buoys.Shapes.get(shape), Util.getScheme(feature, feature.type));
-		if (Util.hasObject(feature, Obj.TOPMAR)) {
-			Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), Util.getScheme(feature, Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
+		BoySHP shape = (BoySHP) getAttVal(feature, feature.type, 0, Att.BOYSHP);
+		Renderer.symbol(feature, Buoys.Shapes.get(shape), getScheme(feature, feature.type));
+		if (hasObject(feature, Obj.TOPMAR)) {
+			Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), getScheme(feature, Obj.TOPMAR), Topmarks.BuoyDeltas.get(shape));
 		}
 		Signals.addSignals(feature);
@@ -283,5 +356,5 @@
 		if ((zoom >= 16) && (feature.length < 2)) {
 			if (feature.type == Obj.CBLSUB) {
-				Renderer.lineSymbols(feature, Areas.Cable, 0.0, null, null, 0, Mline);
+				Renderer.lineSymbols(feature, Areas.Cable, 0.0, null, null, 0, Renderer.Mline);
 			} else if (feature.type == Obj.CBLOHD) {
 				AttMap atts = feature.objs.get(Obj.CBLOHD).get(0);
@@ -297,10 +370,10 @@
 	private static void distances(Feature feature) {
 		if (zoom >= 14) {
-			if (!Util.testAttribute(feature, Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
+			if (!testAttribute(feature, Obj.DISMAR, Att.CATDIS, CatDIS.DIS_NONI)) {
 				Renderer.symbol(feature, Harbours.DistanceI);
 			} else {
 				Renderer.symbol(feature, Harbours.DistanceU);
 			}
-			if ((zoom >=15) && Util.hasAttribute(feature, Obj.DISMAR, Att.WTWDIS)) {
+			if ((zoom >=15) && hasAttribute(feature, Obj.DISMAR, Att.WTWDIS)) {
 				AttMap atts = feature.objs.get(Obj.DISMAR).get(0);
 				Double dist = (Double) atts.get(Att.WTWDIS).val;
@@ -339,11 +412,11 @@
 		switch (feature.type) {
 		case LITVES:
-			Renderer.symbol(feature, Buoys.Super, Util.getScheme(feature, feature.type));
+			Renderer.symbol(feature, Buoys.Super, getScheme(feature, feature.type));
 			break;
 		case LITFLT:
-			Renderer.symbol(feature, Buoys.Float, Util.getScheme(feature, feature.type));
+			Renderer.symbol(feature, Buoys.Float, getScheme(feature, feature.type));
 			break;
 		case BOYINB:
-			Renderer.symbol(feature, Buoys.Super, Util.getScheme(feature, feature.type));
+			Renderer.symbol(feature, Buoys.Super, getScheme(feature, feature.type));
 			break;
 		default:
@@ -351,5 +424,5 @@
 		}
 		if (feature.objs.get(Obj.TOPMAR) != null)
-			Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), Util.getScheme(feature, Obj.TOPMAR), Topmarks.FloatDelta);
+			Renderer.symbol(feature, Topmarks.Shapes.get(feature.objs.get(Obj.TOPMAR).get(0).get(Att.TOPSHP).val), getScheme(feature, Obj.TOPMAR), Topmarks.FloatDelta);
 		Signals.addSignals(feature);
 	}
@@ -363,15 +436,15 @@
 	
 	private static void harbours(Feature feature) {
-		String name = Util.getName(feature);
+		String name = getName(feature);
 		switch (feature.type) {
 		case ACHBRT:
 			if (zoom >= 14) {
-				Renderer.symbol(feature, Harbours.Anchorage, new Scheme(Mline));
-			Renderer.labelText(feature, name == null ? "" : name, new Font("Arial", Font.PLAIN, 30), LabelStyle.RRCT, Mline, Color.white, new Delta(Handle.BC));
-			}
-			double radius = (Double)Util.getAttVal(feature, Obj.ACHBRT, 0, Att.RADIUS);
+				Renderer.symbol(feature, Harbours.Anchorage, new Scheme(Renderer.Mline));
+			Renderer.labelText(feature, name == null ? "" : name, new Font("Arial", Font.PLAIN, 30), LabelStyle.RRCT, Renderer.Mline, Color.white, new Delta(Handle.BC));
+			}
+			double radius = (Double)getAttVal(feature, Obj.ACHBRT, 0, Att.RADIUS);
 			if (radius != 0) {
-				UniHLU units = (UniHLU)Util.getAttVal(feature, Obj.ACHBRT, 0, Att.HUNITS);
-				Renderer.lineCircle (feature, new LineStyle(Mline, 4, new float[] { 10, 10 }, null), radius, units);
+				UniHLU units = (UniHLU)getAttVal(feature, Obj.ACHBRT, 0, Att.HUNITS);
+				Renderer.lineCircle (feature, new LineStyle(Renderer.Mline, 4, new float[] { 10, 10 }, null), radius, units);
 			}
 			break;
@@ -381,41 +454,41 @@
 					Renderer.symbol(feature, Harbours.Anchorage, new Scheme(Color.black));
 				} else {
-					Renderer.symbol(feature, Harbours.Anchorage, new Scheme(Mline));
-					Renderer.lineSymbols(feature, Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Mline);
+					Renderer.symbol(feature, Harbours.Anchorage, new Scheme(Renderer.Mline));
+					Renderer.lineSymbols(feature, Areas.Restricted, 1.0, Areas.LineAnchor, null, 10, Renderer.Mline);
 				}
 				if ((zoom >= 15) && ((name) != null)) {
-					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 60), LabelStyle.NONE, Mline, null, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
-				}
-				ArrayList<StsSTS> sts = (ArrayList<StsSTS>)Util.getAttVal(feature, Obj.ACHARE, 0, Att.STATUS);
+					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 60), LabelStyle.NONE, Renderer.Mline, null, new Delta(Handle.LC, AffineTransform.getTranslateInstance(70, 0)));
+				}
+				ArrayList<StsSTS> sts = (ArrayList<StsSTS>)getAttVal(feature, Obj.ACHARE, 0, Att.STATUS);
 				if ((zoom >= 15) && (sts != null) && (sts.contains(StsSTS.STS_RESV))) {
-					Renderer.labelText(feature, "Reserved", new Font("Arial", Font.PLAIN, 50), LabelStyle.NONE, Mline, null, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
-				}
-			}
-			ArrayList<CatACH> cats = (ArrayList<CatACH>)Util.getAttVal(feature, Obj.ACHARE, 0, Att.CATACH);
+					Renderer.labelText(feature, "Reserved", new Font("Arial", Font.PLAIN, 50), LabelStyle.NONE, Renderer.Mline, null, new Delta(Handle.TC, AffineTransform.getTranslateInstance(0, 60)));
+				}
+			}
+			ArrayList<CatACH> cats = (ArrayList<CatACH>)getAttVal(feature, Obj.ACHARE, 0, Att.CATACH);
 			int dy = (cats.size() - 1) * -30;
 			for (CatACH cat : cats) {
 				switch (cat) {
 				case ACH_DEEP:
-					Renderer.labelText(feature, "DW", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.labelText(feature, "DW", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Renderer.Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
 				case ACH_TANK:
-					Renderer.labelText(feature, "Tanker", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.labelText(feature, "Tanker", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Renderer.Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
 				case ACH_H24P:
-					Renderer.labelText(feature, "24h", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.labelText(feature, "24h", new Font("Arial", Font.BOLD, 50), LabelStyle.NONE, Renderer.Mline, null, new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
 				case ACH_EXPL:
-					Renderer.symbol(feature, Harbours.Explosives, new Scheme(Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.symbol(feature, Harbours.Explosives, new Scheme(Renderer.Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
 				case ACH_QUAR:
-					Renderer.symbol(feature, Harbours.Hospital, new Scheme(Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.symbol(feature, Harbours.Hospital, new Scheme(Renderer.Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
 				case ACH_SEAP:
-					Renderer.symbol(feature, Areas.Seaplane, new Scheme(Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
+					Renderer.symbol(feature, Areas.Seaplane, new Scheme(Renderer.Mline), new Delta(Handle.RC, AffineTransform.getTranslateInstance(-60, dy)));
 					dy += 60;
 					break;
@@ -425,5 +498,5 @@
 		case BERTHS:
 			if (zoom >= 14) {
-				Renderer.labelText(feature, name == null ? " " : name, new Font("Arial", Font.PLAIN, 40), LabelStyle.RRCT, Mline, Color.white, null);
+				Renderer.labelText(feature, name == null ? " " : name, new Font("Arial", Font.PLAIN, 40), LabelStyle.RRCT, Renderer.Mline, Color.white, null);
 			}
 			break;
@@ -431,10 +504,10 @@
 		  if (zoom >= 16) {
 		  	ArrayList<Symbol> symbols = new ArrayList<Symbol>();
-		  	ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) Util.getAttVal(feature, Obj.BUISGL, 0, Att.FUNCTN);
+		  	ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttVal(feature, Obj.BUISGL, 0, Att.FUNCTN);
 		  	for (FncFNC fnc : fncs) {
 		  		symbols.add(Landmarks.Funcs.get(fnc));
 		  	}
 			  if (feature.objs.containsKey(Obj.SMCFAC))  {
-			  	ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) Util.getAttVal(feature, Obj.SMCFAC, 0, Att.CATSCF);
+			  	ArrayList<CatSCF> scfs = (ArrayList<CatSCF>) getAttVal(feature, Obj.SMCFAC, 0, Att.CATSCF);
 			  	for (CatSCF scf : scfs) {
 			  		symbols.add(Facilities.Cats.get(scf));
@@ -446,5 +519,5 @@
 		case HRBFAC:
 			if (zoom >= 12) {
-				switch ((CatHAF) Util.getAttVal(feature, feature.type, 0, Att.CATHAF)) {
+				switch ((CatHAF) getAttVal(feature, feature.type, 0, Att.CATHAF)) {
 				case HAF_MRNA:
 					Renderer.symbol(feature, Harbours.Marina);
@@ -464,7 +537,7 @@
 	
 	private static void landmarks(Feature feature) {
-		ArrayList<CatLMK> cats = (ArrayList<CatLMK>) Util.getAttVal(feature, feature.type, 0, Att.CATLMK);
+		ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttVal(feature, feature.type, 0, Att.CATLMK);
 		Symbol catSym = Landmarks.Shapes.get(cats.get(0));
-		ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) Util.getAttVal(feature, feature.type, 0, Att.FUNCTN);
+		ArrayList<FncFNC> fncs = (ArrayList<FncFNC>) getAttVal(feature, feature.type, 0, Att.FUNCTN);
 		Symbol fncSym = Landmarks.Funcs.get(fncs.get(0));
 		if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
@@ -501,10 +574,17 @@
 			Renderer.symbol(feature, Beacons.LightMinor);
 			break;
+		case PILPNT:
+			if (hasObject(feature, Obj.LIGHTS))
+				Renderer.symbol(feature, Beacons.LightMinor);
+			else
+				Renderer.symbol(feature, Harbours.Post);
+			break;
 		}
 		Signals.addSignals(feature);
 	}
-	
+
 	private static void locks(Feature feature) {
 	}
+
 	private static void marinas(Feature feature) {
 		if (zoom >= 16) {
@@ -512,7 +592,6 @@
 		}
 	}
-	
 	private static void moorings(Feature feature) {
-		switch ((CatMOR) Util.getAttVal(feature, feature.type, 0, Att.CATMOR)) {
+		switch ((CatMOR) getAttVal(feature, feature.type, 0, Att.CATMOR)) {
 		case MOR_DLPN:
 			Renderer.symbol(feature, Harbours.Dolphin);
@@ -526,8 +605,8 @@
 			break;
 		case MOR_BUOY:
-			BoySHP shape = (BoySHP) Util.getAttVal(feature, feature.type, 0, Att.BOYSHP);
+			BoySHP shape = (BoySHP) getAttVal(feature, feature.type, 0, Att.BOYSHP);
 			if (shape == BoySHP.BOY_UNKN)
 				shape = BoySHP.BOY_SPHR;
-			Renderer.symbol(feature, Buoys.Shapes.get(shape), Util.getScheme(feature, feature.type));
+			Renderer.symbol(feature, Buoys.Shapes.get(shape), getScheme(feature, feature.type));
 			break;
 		}
@@ -751,7 +830,8 @@
 		}
 	}
+
 	private static void obstructions(Feature feature) {
 		if ((zoom >= 14) && (feature.type == Obj.UWTROC)) {
-			WatLEV lvl = (WatLEV) Util.getAttVal(feature, feature.type, 0, Att.WATLEV);
+			WatLEV lvl = (WatLEV) getAttVal(feature, feature.type, 0, Att.WATLEV);
 			switch (lvl) {
 			case LEV_CVRS:
@@ -768,8 +848,9 @@
 		}
 	}
+
 	private static void pipelines(Feature feature) {
 		if (zoom >= 14) {
 			if (feature.type == Obj.PIPSOL) {
-				Renderer.lineSymbols(feature, Areas.Pipeline, 1.0, null, null, 0, Mline);
+				Renderer.lineSymbols(feature, Areas.Pipeline, 1.0, null, null, 0, Renderer.Mline);
 			} else if (feature.type == Obj.PIPOHD) {
 
@@ -777,24 +858,21 @@
 		}
 	}
+
 	private static void platforms(Feature feature) {
-		ArrayList<CatOFP> cats = (ArrayList<CatOFP>)Util.getAttVal(feature, Obj.OFSPLF, 0, Att.CATOFP);
+		ArrayList<CatOFP> cats = (ArrayList<CatOFP>)getAttVal(feature, Obj.OFSPLF, 0, Att.CATOFP);
 		if ((CatOFP) cats.get(0) == CatOFP.OFP_FPSO)
 			Renderer.symbol(feature, Buoys.Storage);
 		else
 			Renderer.symbol(feature, Landmarks.Platform);
-		String name = Util.getName(feature);
+		String name = getName(feature);
 		if ((zoom >= 15) && (name != null))
 			Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 40), LabelStyle.NONE, Color.black, null, new Delta(Handle.BL, AffineTransform.getTranslateInstance(20, -50)));
-/*object_rules(platforms) {
-  if (has_object("fog_signal")) object(fogs);
-  if (has_object("radar_transponder")) object(rtbs);
-  if (has_object("light")) object(lights);
-}
-*/
-	}
+		Signals.addSignals(feature);
+	}
+
 	private static void ports(Feature feature) {
 		if (zoom >= 14) {
 			if (feature.type == Obj.CRANES) {
-				if ((CatCRN) Util.getAttVal(feature, feature.type, 0, Att.CATCRN) == CatCRN.CRN_CONT)
+				if ((CatCRN) getAttVal(feature, feature.type, 0, Att.CATCRN) == CatCRN.CRN_CONT)
 					Renderer.symbol(feature, Harbours.ContainerCrane);
 				else
@@ -802,5 +880,5 @@
 			} else if (feature.type == Obj.HULKES) {
 				Renderer.lineVector(feature, new LineStyle(Color.black, 4, null, new Color(0xffe000)));
-				String name = Util.getName(feature);
+				String name = getName(feature);
 				if ((zoom >= 15) && (name != null))
 					Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 80), LabelStyle.NONE, Color.black, null, null);
@@ -808,4 +886,5 @@
 		}
 	}
+
 	private static void separation(Feature feature) {
 		switch (feature.type) {
@@ -817,5 +896,5 @@
 			else
 				Renderer.lineVector(feature, new LineStyle(new Color(0x80c48080, true), 20, null, null));
-			String name = Util.getName(feature);
+			String name = getName(feature);
 			if ((zoom >= 10) && (name != null))
 				Renderer.labelText(feature, name, new Font("Arial", Font.BOLD, 150), LabelStyle.NONE, new Color(0x80c48080, true), null, null);
@@ -835,9 +914,10 @@
 		}
 	}
+
 	private static void shoreline(Feature feature) {
 		if (zoom >= 12) {
-			switch ((CatSLC) Util.getAttVal(feature, feature.type, 0, Att.CATSLC)) {
+			switch ((CatSLC) getAttVal(feature, feature.type, 0, Att.CATSLC)) {
 			case SLC_TWAL:
-				WatLEV lev = (WatLEV) Util.getAttVal(feature, feature.type, 0, Att.WATLEV);
+				WatLEV lev = (WatLEV) getAttVal(feature, feature.type, 0, Att.WATLEV);
 				if (lev == WatLEV.LEV_CVRS) {
 					Renderer.lineVector(feature, new LineStyle(Color.black, 10, new float[] { 40, 40 }, null));
@@ -852,5 +932,5 @@
 		}
 	}
-	
+
 	private static void stations(Feature feature) {
 		if (zoom >= 14) {
@@ -885,5 +965,5 @@
 		Signals.addSignals(feature);
 	}
-	
+
 	private static void transits(Feature feature) {
 	  if (zoom >= 12) {
@@ -893,18 +973,19 @@
 	  if (zoom >= 15) {
 	  	String str = "";
-			String name = Util.getName(feature);
+			String name = getName(feature);
 			if (name != null) str += name + " ";
-			Double ort = (Double) Util.getAttVal(feature, feature.type, 0, Att.ORIENT);
+			Double ort = (Double) getAttVal(feature, feature.type, 0, Att.ORIENT);
 			if (ort != null) str += ort.toString() + "\u0152";
 			if (!str.isEmpty()) Renderer.lineText(feature, str, new Font("Arial", Font.PLAIN, 80), Color.black, 0.5, -20);
 	  }
 	}
+
 	private static void waterways(Feature feature) {
 		
 	}
-	
+
 	private static void wrecks(Feature feature) {
 		if (zoom >= 14) {
-			CatWRK cat = (CatWRK) Util.getAttVal(feature, feature.type, 0, Att.CATWRK);
+			CatWRK cat = (CatWRK) getAttVal(feature, feature.type, 0, Att.CATWRK);
 			switch (cat) {
 			case WRK_DNGR:
Index: /applications/editors/josm/plugins/smed2/src/seamap/Signals.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/seamap/Signals.java	(revision 30045)
+++ /applications/editors/josm/plugins/smed2/src/seamap/Signals.java	(revision 30046)
@@ -41,5 +41,5 @@
 	public static void radarStations(Feature feature) {
 		Renderer.symbol(feature, Beacons.RadarStation);
-		ArrayList<CatROS> cats = (ArrayList<CatROS>)Util.getAttVal(feature, Obj.RDOSTA, 0, Att.CATROS);
+		ArrayList<CatROS> cats = (ArrayList<CatROS>)Rules.getAttVal(feature, Obj.RDOSTA, 0, Att.CATROS);
 		String str = "";
 		for (CatROS ros : cats) {
Index: plications/editors/josm/plugins/smed2/src/seamap/Util.java
===================================================================
--- /applications/editors/josm/plugins/smed2/src/seamap/Util.java	(revision 30045)
+++ 	(revision )
@@ -1,131 +1,0 @@
-/* Copyright 2013 Malcolm Herring
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
- */
-
-package seamap;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
-
-import s57.S57val;
-import s57.S57val.*;
-import s57.S57att.*;
-import s57.S57obj.*;
-import seamap.SeaMap.*;
-import symbols.Symbols.*;
-
-public class Util {
-
-	static final EnumMap<ColCOL, Color> bodyColours = new EnumMap<ColCOL, Color>(ColCOL.class);
-	static {
-		bodyColours.put(ColCOL.COL_UNK, new Color(0, true));
-		bodyColours.put(ColCOL.COL_WHT, new Color(0xffffff));
-		bodyColours.put(ColCOL.COL_BLK, new Color(0x000000));
-		bodyColours.put(ColCOL.COL_RED, new Color(0xd40000));
-		bodyColours.put(ColCOL.COL_GRN, new Color(0x00d400));
-		bodyColours.put(ColCOL.COL_BLU, Color.blue);
-		bodyColours.put(ColCOL.COL_YEL, new Color(0xffd400));
-		bodyColours.put(ColCOL.COL_GRY, Color.gray);
-		bodyColours.put(ColCOL.COL_BRN, new Color(0x8b4513));
-		bodyColours.put(ColCOL.COL_AMB, new Color(0xfbf00f));
-		bodyColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
-		bodyColours.put(ColCOL.COL_ORG, Color.orange);
-		bodyColours.put(ColCOL.COL_MAG, new Color(0xf000f0));
-		bodyColours.put(ColCOL.COL_PNK, Color.pink);
-	}
-
-	static final EnumMap<ColPAT, Patt> pattMap = new EnumMap<ColPAT, Patt>(ColPAT.class);
-	static {
-		pattMap.put(ColPAT.PAT_UNKN, Patt.Z);
-		pattMap.put(ColPAT.PAT_HORI, Patt.H);
-		pattMap.put(ColPAT.PAT_VERT, Patt.V);
-		pattMap.put(ColPAT.PAT_DIAG, Patt.D);
-		pattMap.put(ColPAT.PAT_BRDR, Patt.B);
-		pattMap.put(ColPAT.PAT_SQUR, Patt.S);
-		pattMap.put(ColPAT.PAT_CROS, Patt.C);
-		pattMap.put(ColPAT.PAT_SALT, Patt.X);
-		pattMap.put(ColPAT.PAT_STRP, Patt.H);
-	}
-	
-	static String getName(Feature feature) {
-		AttItem name = feature.atts.get(Att.OBJNAM);
-		if (name == null) {
-			name = feature.objs.get(feature.type).get(0).get(Att.OBJNAM);
-		}
-		if (name != null) return (String)name.val;
-		return null;
-	}
-
-	static AttMap getAtts(Feature feature, Obj obj, int idx) {
-		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
-		if (objs == null)
-			return null;
-		else
-			return objs.get(idx);
-	}
-
-	public static Object getAttVal(Feature feature, Obj obj, int idx, Att att) {
-		AttMap atts = null;
-		HashMap<Integer, AttMap> objs = feature.objs.get(obj);
-		if (objs != null)
-			atts = objs.get(idx);
-		if (atts == null)
-			return S57val.nullVal(att);
-		else {
-			AttItem item = atts.get(att);
-			if (item == null)
-				return S57val.nullVal(att);
-			return item.val;
-		}
-	}
-	
-	static Scheme getScheme(Feature feature, Obj obj) {
-		ArrayList<Color> colours = new ArrayList<Color>();
-		for (ColCOL col : (ArrayList<ColCOL>)getAttVal(feature, obj, 0, Att.COLOUR)) {
-			colours.add(bodyColours.get(col));
-		}
-		ArrayList<Patt> patterns = new ArrayList<Patt>();
-		for(ColPAT pat: (ArrayList<ColPAT>) getAttVal(feature, obj, 0, Att.COLPAT)) {
-			patterns.add(pattMap.get(pat));
-		}
-		return new Scheme(patterns, colours);
-	}
-	
-	static boolean hasObject(Feature feature, Obj obj) {
-		return (feature.objs.containsKey(obj));
-	}
-	
-	static boolean hasAttribute(Feature feature, Obj obj, Att att) {
-		AttMap atts = getAtts(feature, obj, 0);
-		return ((atts != null) && (atts.containsKey(att)));
-	}
-	
-	static boolean testAttribute(Feature feature, Obj obj, Att att, Object val) {
-		AttMap atts = getAtts(feature, obj, 0);
-		if (atts != null) {
-			AttItem item = atts.get(att);
-			if (item != null) {
-				switch (item.conv) {
-				case S:
-				case A:
-					return ((String)item.val).equals(val);
-				case L:
-					return ((ArrayList<?>)item.val).contains(val);
-				case E:
-				case F:
-				case I:
-					return item.val.equals(val);
-				}
-			}
-		}
-		return false;
-	}
-	
-}
