Index: /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java
===================================================================
--- /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java	(revision 31734)
+++ /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java	(revision 31735)
@@ -11,11 +11,12 @@
 
 import java.io.*;
-import java.util.HashMap;
-import java.util.Scanner;
+import java.util.*;
 import java.util.zip.CRC32;
 
+import s57.S57dat;
 import s57.S57enc;
 import s57.S57map;
 import s57.S57osm;
+import s57.S57dat.*;
 
 public class Josmtos57 {
@@ -37,22 +38,9 @@
 		'I', 'L', '!', 'V', 'O', 'L', 'M', '!', 'I', 'M', 'P', 'L', '!', 'S', 'L', 'A', 'T', '!', 'W', 'L', 'O', 'N', '!', 'N', 'L', 'A', 'T', '!', 'E', 'L', 'O', 'N',
 		'!', 'C', 'R', 'C', 'S', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'A', '(', '2', ')', ',', 'I', '(', '1', '0', ')', ',', '3', 'A', ',', 'A', '(', '3', ')', ',', '4',
-		'R', ',', '2', 'A', ')', 0x1e
-	};
-	
-	static byte[] entry = {
-		//*** 0
-		'0', '0', '1', '0', '1', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '5', '3', ' ', ' ', ' ', '5', '5', '0', '4', // Leader
-		'0', '0', '0', '1', '0', '0', '0', '0', '6', '0', '0', '0', '0', '0',   'C', 'A', 'T', 'D', '0', '0', '0', '4', '2', '0', '0', '0', '0', '6', 0x1e, // Directory
-		'0', '0', '0', '0', '0', 0x1e,
-		//*** 
-		'C', 'D', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', // Record name+number
-		//***
-		'C', 'A', 'T', 'A', 'L', 'O', 'G', '.', '0', '3', '1', 0x1f, // File name
-		0x1f, // File long name
-		'V', '0', '1', 'X', '0', '1', 0x1f, // Volume
-		'A', 'S', 'C', // Implementation
-		0x1f, 0x1f, 0x1f, 0x1f, // minlat, minlon, maxlat, maxlon
-		0x1f, // CRC32
-		0x1f, 0x1e // Comment
+		'R', ',', '2', 'A', ')', 0x1e, 
+		'0', '0', '1', '0', '1', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '5', '3', ' ', ' ', ' ', '5', '5', '0', '4',
+		'0', '0', '0', '1', '0', '0', '0', '0', '6', '0', '0', '0', '0', '0',   'C', 'A', 'T', 'D', '0', '0', '0', '4', '2', '0', '0', '0', '0', '6', 0x1e,
+		'0', '0', '0', '0', '0', 0x1e, 'C', 'D', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', 'C', 'A', 'T', 'A', 'L', 'O', 'G', '.', '0', '3', '1', 0x1f,
+		0x1f, 'V', '0', '1', 'X', '0', '1', 0x1f, 'A', 'S', 'C', 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1e
 	};
 	
@@ -62,8 +50,10 @@
 	static byte[] buf;
 	static HashMap<String, String> meta;
+	static ArrayList<Fparams> fields;
+	static byte[] record;
 	
 	public static void main(String[] args) throws IOException {
 
-		map = new S57map(true);
+		map = new S57map(false);
 		int idx = 0;
 		
@@ -76,8 +66,9 @@
 			meta = new HashMap<String, String>();
 			meta.put("FILE", args[3]);
-//			while (min.hasNext()) {
-//				String[] tokens = min.next().split("=");
-//				meta.put(tokens[0], tokens[1]);
-//			}
+			while (min.hasNext()) {
+				String[] tokens = min.next().split("=");
+				if (tokens.length >= 2)
+					meta.put(tokens[0], tokens[1].split("[ #]")[0]);
+			}
 			min.close();
 		} catch (IOException e) {
@@ -118,8 +109,21 @@
 		out.close();
 		
+		buf = new byte[header.length];
+		System.arraycopy(header, 0, buf, 0, header.length);
+		idx = header.length;
+		int recs = 2;
+		fields = new ArrayList<Fparams>();
+		fields.add(new Fparams(S57field.CATD, new Object[]{ "CD", recs, args[3], "", "V01X01", "BIN", Math.toDegrees(map.bounds.minlat),
+				Math.toDegrees(map.bounds.minlon), Math.toDegrees(map.bounds.maxlat), Math.toDegrees(map.bounds.maxlon), String.format("%08X", crc.getValue()), "" }));
+		record = S57dat.encRecord(String.valueOf(recs++), fields);
+		buf = Arrays.copyOf(buf, (buf.length + record.length));
+		System.arraycopy(record, 0, buf, idx, record.length);
+		idx += record.length;
+
 		try {
 			File file = new File(args[2] + "CATALOG.031");
 			if (file.exists()) file.delete();
 			out = new FileOutputStream(file, false);
+			out.write(buf, 0, idx);
 		} catch (IOException e) {
 			System.err.println("Catalogue file: " + e.getMessage());
Index: /applications/editors/josm/plugins/seachart/src/s57/S57dat.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57dat.java	(revision 31734)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57dat.java	(revision 31735)
@@ -262,8 +262,10 @@
 	public static byte[] encSubf(S57subf subf, Object val) {
 		S57conv conv = convs.get(subf);
-		if (conv.bin == 0) {
+		if ((conv.bin == 0) || asc) {
 			String sval = "";
 			if (val instanceof String) {
 				sval = (String) val;
+			} else if (val instanceof Integer) {
+				sval = ((Integer)val).toString();
 			} else if (val instanceof Long) {
 				sval = ((Long)val).toString();
@@ -328,4 +330,11 @@
 	};
 
+	static boolean asc = false;
+	
+	public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
+		asc = true;
+		return encRecord(Integer.parseInt(i8rn), fparams);
+	}
+	
 	public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
 		ArrayList<Index> index = new ArrayList<Index>();
@@ -380,4 +389,5 @@
 		System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
 		System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
+		asc = false;
 		return fbuf;
 	}
Index: /applications/editors/josm/plugins/seachart/src/s57/S57enc.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57enc.java	(revision 31734)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57enc.java	(revision 31735)
@@ -30,4 +30,5 @@
 
 	private static final byte[] header = {
+		
 		'0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
 		'0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
@@ -126,4 +127,9 @@
 
 	public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
+		
+		//M_COVR & MNSYS in BB if not in map
+		if (!map.features.containsKey(Obj.M_COVR)) {
+			S57osm.OSMmeta(map);
+		}
 
 		byte[] record;
@@ -132,9 +138,9 @@
 		String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
 		ArrayList<Fparams> ds = new ArrayList<Fparams>();
-		ds.add(new Fparams(S57field.DSID, new Object[]{ 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
-		ds.add(new Fparams(S57field.DSSI, new Object[]{ 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }));
+		ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
+		ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }));
 		ArrayList<Fparams> dp = new ArrayList<Fparams>();
-		dp.add(new Fparams(S57field.DSPM, new Object[]{ 20, 2, 2, 23, 23, cscl, 1, 1, 1, 1, 10000000, 10, "" }));
-		
+		dp.add(new Fparams(S57field.DSPM, new Object[] { 20, 2, 2, 23, 23, cscl, 1, 1, 1, 1, 10000000, 10, "" }));
+
 		isols = conns = metas = geos = edges = 0;
 		System.arraycopy(header, 0, buf, 0, header.length);
@@ -147,5 +153,5 @@
 		idx += record.length;
 		recs = 3;
-		
+
 		// Depths
 		Object[] depths = new Object[0];
@@ -153,5 +159,5 @@
 			S57map.Snode node = entry.getValue();
 			if (node.flg == Nflag.DPTH) {
-				Object[] dval = new Object[]{ (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
+				Object[] dval = new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
 				depths = Arrays.copyOf(depths, (depths.length + dval.length));
 				System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
@@ -160,5 +166,5 @@
 		if (depths.length > 0) {
 			fields = new ArrayList<Fparams>();
-			fields.add(new Fparams(S57field.VRID, new Object[]{ 110, -2, 1, 1 }));
+			fields.add(new Fparams(S57field.VRID, new Object[] { 110, -2, 1, 1 }));
 			fields.add(new Fparams(S57field.SG3D, depths));
 			record = S57dat.encRecord(recs++, fields);
@@ -173,6 +179,6 @@
 			if (node.flg == Nflag.ISOL) {
 				fields = new ArrayList<Fparams>();
-				fields.add(new Fparams(S57field.VRID, new Object[]{ 110, hash(entry.getKey()), 1, 1 }));
-				fields.add(new Fparams(S57field.SG2D, new Object[]{ (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
+				fields.add(new Fparams(S57field.VRID, new Object[] { 110, hash(entry.getKey()), 1, 1 }));
+				fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
 				record = S57dat.encRecord(recs++, fields);
 				System.arraycopy(record, 0, buf, idx, record.length);
@@ -181,5 +187,5 @@
 			}
 		}
-		
+
 		// Connected nodes
 		for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
@@ -187,6 +193,6 @@
 			if (node.flg == Nflag.CONN) {
 				fields = new ArrayList<Fparams>();
-				fields.add(new Fparams(S57field.VRID, new Object[]{ 120, hash(entry.getKey()), 1, 1 }));
-				fields.add(new Fparams(S57field.SG2D, new Object[]{ (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
+				fields.add(new Fparams(S57field.VRID, new Object[] { 120, hash(entry.getKey()), 1, 1 }));
+				fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
 				record = S57dat.encRecord(recs++, fields);
 				System.arraycopy(record, 0, buf, idx, record.length);
@@ -195,14 +201,14 @@
 			}
 		}
-		
+
 		// Edges
 		for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
 			S57map.Edge edge = entry.getValue();
 			fields = new ArrayList<Fparams>();
-			fields.add(new Fparams(S57field.VRID, new Object[]{ 130, hash(entry.getKey()), 1, 1 }));
-			fields.add(new Fparams(S57field.VRPT, new Object[]{ (((hash(edge.first) & 0xffffffff) << 8) + 120l), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120l), 255, 255, 2, 255 }));
+			fields.add(new Fparams(S57field.VRID, new Object[] { 130, hash(entry.getKey()), 1, 1 }));
+			fields.add(new Fparams(S57field.VRPT, new Object[] { (((hash(edge.first) & 0xffffffff) << 8) + 120l), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120l), 255, 255, 2, 255 }));
 			Object[] nodes = new Object[0];
 			for (long ref : edge.nodes) {
-				Object[] nval = new Object[]{ (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
+				Object[] nval = new Object[] { (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
 				nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
 				System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
@@ -216,18 +222,30 @@
 			edges++;
 		}
-		
+
 		// Meta & Geo objects
+		boolean soundings = false;
 		for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
 			Obj obj = entry.getKey();
 			for (Feature feature : entry.getValue()) {
+				if (obj == Obj.SOUNDG) {
+					if (soundings) {
+						continue;
+					} else {
+						soundings = true;
+					}
+				}
 				int prim = feature.geom.prim.ordinal();
 				prim = (prim == 0) ? 255 : prim;
 				int grup = ((obj == Obj.DEPARE) || (obj == Obj.DRGARE) || (obj == Obj.FLODOC) || (obj == Obj.HULKES) || (obj == Obj.LNDARE) || (obj == Obj.PONTON) || (obj == Obj.UNSARE)) ? 1 : 2;
-				
+
 				ArrayList<Fparams> geom = new ArrayList<Fparams>();
-				int outers = feature.geom.outers;
+				int outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
 				for (Prim elem : feature.geom.elems) {
 					if (feature.geom.prim == Pflag.POINT) {
-						geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120l : 110l)), 255, 255, 255 }));
+						if (obj == Obj.SOUNDG) {
+							geom.add(new Fparams(S57field.FSPT, new Object[] { ((-2 << 8) + 110l), 255, 255, 255 }));
+						} else {
+							geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120l : 110l)), 255, 255, 255 }));
+						}
 					} else {
 						geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + 130l), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
@@ -240,7 +258,8 @@
 				for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
 					Obj objobj = objs.getKey();
+					boolean master = true;
 					for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
 						ArrayList<Fparams> objatts = new ArrayList<Fparams>();
-						boolean master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
+						master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
 						long id = hash(master ? feature.id : slaveid);
 						objatts.add(new Fparams(S57field.FRID, new Object[] { 100, id, prim, grup, S57obj.encodeType(objobj), 1, 1 }));
@@ -282,5 +301,5 @@
 					while (!slaves.isEmpty()) {
 						long id = slaves.remove(0);
-						Object[] next = new Object[]{ (long)((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)) , 2, "" };
+						Object[] next = new Object[] { (long) ((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)), 2, "" };
 						params = Arrays.copyOf(params, (params.length + next.length));
 						System.arraycopy(next, 0, params, (params.length - next.length), next.length);
@@ -289,5 +308,5 @@
 					objects.get(objects.size() - 1).addAll(refs);
 				}
-				
+
 				for (ArrayList<Fparams> object : objects) {
 					object.addAll(geom);
@@ -303,19 +322,14 @@
 			}
 		}
-		
+
 		// Re-write DSID/DSSI with final totals
 		ds = new ArrayList<Fparams>();
-		ds.add(new Fparams(S57field.DSID, new Object[]{ 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
-		ds.add(new Fparams(S57field.DSSI, new Object[]{ 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
+		ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
+		ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
 		record = S57dat.encRecord(1, ds);
 		System.arraycopy(record, 0, buf, header.length, record.length);
-		
-	return idx;
+
+		return idx;
+	}
+
 }
-
-	public static int encodeCatalogue(S57map map, byte[] buf) throws IndexOutOfBoundsException {
-		
-	return idx;
-}
-
-}
Index: /applications/editors/josm/plugins/seachart/src/s57/S57map.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 31734)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 31735)
@@ -219,18 +219,16 @@
 	}
 	
+	public MapBounds bounds;
 	public NodeTab nodes;
 	public EdgeTab edges;
-
 	public FtrMap features;
 	public FtrTab index;
-	
-	public MapBounds bounds;
-
-	public long cref;
 	public long xref;
+
+	private long cref;
 	private Feature feature;
 	private Edge edge;
 	private KeyVal<?> osm = S57osm.OSMtag("", "");
-	boolean sea;
+	private boolean sea;
 
 	public S57map(boolean s) {
@@ -367,8 +365,7 @@
 
 	// OSM map building methods
-	
+
 	public void addNode(long id, double lat, double lon) {
-		Snode node = new Snode(Math.toRadians(lat), Math.toRadians(lon));
-		nodes.put(id, node);
+		nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
 		feature = new Feature();
 		feature.id = id;
@@ -555,4 +552,5 @@
 	
 	enum Ext {I, N, W, S, E }
+	
 	public void mapDone() {
 		class Land {
@@ -579,7 +577,9 @@
 			for (Feature feature : features.get(Obj.COALNE)) {
 				Feature land = new Feature();
+				land.id = ++xref;
 				land.type = Obj.LNDARE;
 				land.reln = Rflag.MASTER;
 				land.objs.put(Obj.LNDARE, new ObjTab());
+				land.objs.get(Obj.LNDARE).put(0, new AttMap());
 				if (feature.geom.prim == Pflag.AREA) {
 					land.geom = feature.geom;
@@ -587,7 +587,5 @@
 				} else if (feature.geom.prim == Pflag.LINE) {
 					land.geom.prim = Pflag.LINE;
-					for (int i = 0; i < feature.geom.elems.size(); i++) {
-						land.geom.elems.add(feature.geom.elems.get(i));
-					}
+					land.geom.elems.addAll(feature.geom.elems);
 					coasts.add(land);
 				}
Index: /applications/editors/josm/plugins/seachart/src/s57/S57osm.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 31734)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 31735)
@@ -12,6 +12,5 @@
 import java.io.BufferedReader;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.*;
 
 import s57.S57obj.*;
@@ -77,4 +76,8 @@
 		boolean inWay = false;
 		boolean inRel = false;
+		map.nodes.put(1l, map.new Snode());
+		map.nodes.put(2l, map.new Snode());
+		map.nodes.put(3l, map.new Snode());
+		map.nodes.put(4l, map.new Snode());
 
 		String ln;
@@ -85,10 +88,18 @@
 						if (token.matches("^minlat=.+")) {
 							map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+							map.nodes.get(2l).lat = map.bounds.minlat;
+							map.nodes.get(3l).lat = map.bounds.minlat;
 						} else if (token.matches("^minlon=.+")) {
 							map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+							map.nodes.get(1l).lon = map.bounds.minlon;
+							map.nodes.get(2l).lon = map.bounds.minlon;
 						} else if (token.matches("^maxlat=.+")) {
 							map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+							map.nodes.get(1l).lat = map.bounds.maxlat;
+							map.nodes.get(4l).lat = map.bounds.maxlat;
 						} else if (token.matches("^maxlon=.+")) {
 							map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
+							map.nodes.get(3l).lon = map.bounds.maxlon;
+							map.nodes.get(4l).lon = map.bounds.maxlon;
 						}
 					}
@@ -199,4 +210,14 @@
 		return;
 	}
+	
+	public static void OSMmeta(S57map map) {
+		map.addEdge(++map.xref);
+		for (long ref = 0; ref <= 4; ref++) {
+			map.addToEdge((ref == 0) ? 4 : ref);
+		}
+		map.addTag("seamark:type", "coverage");
+		map.addTag("seamark:coverage:category", "coverage");
+		map.tagsDone(map.xref);
+	}
 
 }
