Index: /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/jbasemap/src/jbasemap/Jbasemap.java	(revision 35392)
@@ -6,5 +6,5 @@
 import java.awt.geom.Point2D;
 import java.io.BufferedReader;
-import java.io.FileReader;
+import java.io.File;
 import java.io.IOException;
 
@@ -63,4 +63,9 @@
 
         @Override
+        public int grid() {
+            return 0;
+        }
+
+        @Override
         public boolean clip() {
             return true;
@@ -116,16 +121,10 @@
         z2 = Math.pow(2, zoom);
         double scale = 0.1;
+        File in = new File(src);
+        map = new S57map(false);
         try {
-            BufferedReader in = new BufferedReader(new FileReader(src));
-            map = new S57map(false);
-            try {
-                S57osm.OSMmap(in, map, true);
-            } catch (Exception e) {
-                System.err.println("Input data error");
-                System.exit(-1);
-            }
-            in.close();
-        } catch (IOException e) {
-            System.err.println("Input file: " + e.getMessage());
+            S57osm.OSMmap(in, map, true);
+        } catch (Exception e) {
+            System.err.println("Input data error");
             System.exit(-1);
         }
Index: /applications/editors/josm/plugins/seachart/jchart/src/jchart/Jchart.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jchart/src/jchart/Jchart.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/jchart/src/jchart/Jchart.java	(revision 35392)
@@ -8,8 +8,6 @@
 import java.awt.geom.Point2D;
 import java.awt.image.BufferedImage;
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
@@ -132,9 +130,9 @@
             System.exit(-1);
         }
-        BufferedReader in = new BufferedReader(new FileReader(args[0]));
+        File in = new File(args[0]);
         zoom = Integer.parseInt(args[1]);
         map = new S57map(false);
         S57osm.OSMmap(in, map, false);
-        in.close();
+//        in.close();
         context = new Context();
         Point2D size = context.getPoint(new Snode(map.bounds.minlat, map.bounds.maxlon));
Index: /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/jicons/src/jicons/Jicons.java	(revision 35392)
@@ -207,4 +207,9 @@
 
         @Override
+        public int grid() {
+            return 0;
+        }
+
+        @Override
         public Color background(S57map map) {
             return new Color(0, true);
Index: /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java
===================================================================
--- /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/josmtos57/src/josmtos57/Josmtos57.java	(revision 35392)
@@ -6,5 +6,5 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileReader;
+import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -62,5 +62,5 @@
     };
 
-    static BufferedReader in;
+    static File in;
     static FileOutputStream out;
     static S57map map;
@@ -93,15 +93,9 @@
             System.exit(-1);
         }
+        in = new File(args[0]);
         try {
-            in = new BufferedReader(new FileReader(new File(args[0])));
-            try {
-                S57osm.OSMmap(in, map, false);
-            } catch (Exception e) {
-                System.err.println("Input data error");
-                System.exit(-1);
-            }
-            in.close();
-        } catch (IOException e) {
-            System.err.println("Input file: " + e.getMessage());
+            S57osm.OSMmap(in, map, false);
+        } catch (Exception e) {
+            System.err.println("Input data error");
             System.exit(-1);
         }
Index: /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java
===================================================================
--- /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java	(revision 35392)
@@ -73,4 +73,9 @@
         public boolean clip() {
             return false;
+        }
+
+        @Override
+        public int grid() {
+            return 0;
         }
 
@@ -156,8 +161,7 @@
         send = new ArrayList<>();
         deletes = new HashMap<>();
-        BufferedReader in = new BufferedReader(new FileReader(srcdir + xtile + "-" + ytile + "-" + zoom + ".osm"));
+        File in = new File(srcdir + xtile + "-" + ytile + "-" + zoom + ".osm");
         map = new S57map(true);
         S57osm.OSMmap(in, map, false);
-        in.close();
         context = new Context();
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
Index: /applications/editors/josm/plugins/seachart/src/render/Renderer.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/src/render/Renderer.java	(revision 35392)
@@ -25,4 +25,5 @@
 
 import s57.S57map;
+import s57.S57map.Feature;
 import s57.S57map.GeomIterator;
 import s57.S57map.Pflag;
@@ -331,5 +332,5 @@
         if (context.grid() > 0) {
             LineStyle style = new LineStyle(Color.black, (float)2.0);
-            double nspan = 60 * Math.toDegrees(map.bounds.maxlon - map.bounds.minlon) / 5.0;
+            double nspan = 60 * Math.toDegrees(map.bounds.maxlon - map.bounds.minlon) / context.grid();
             double mult = 1.0;
             if (nspan < 1.0) {
@@ -373,5 +374,5 @@
             g2.setPaint(style.line);
             g2.draw(p);
-            double tspan = 60 * Math.toDegrees(map.bounds.maxlat - map.bounds.minlat) / 5.0;
+            double tspan = 60 * Math.toDegrees(map.bounds.maxlat - map.bounds.minlat) / context.grid();
             mult = 1.0;
             if (tspan < 1.0) {
@@ -413,5 +414,19 @@
             g2.setPaint(style.line);
             g2.draw(p);
-        }
+/*            Symbol legend = new Symbol();
+            legend.add(new Instr(Form.BBOX, new Rectangle2D.Double(0, 0, 900, 300)));
+            Path2D.Double path = new Path2D.Double(); path.moveTo(0, 0); path.lineTo(900, 0); path.lineTo(900, 300); path.lineTo(0, 300); path.closePath();
+            legend.add(new Instr(Form.FILL, Color.white));
+            legend.add(new Instr(Form.PGON, path));
+            legend.add(new Instr(Form.TEXT, new Caption("© OpenStreetMap contributors", new Font("Arial", Font.PLAIN, 25), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(450, 300)))));
+            legend.add(new Instr(Form.TEXT, new Caption("Mercator projection", new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(450, 250)))));
+            Point2D point = context.getPoint(new Snode(map.bounds.minlat, map.bounds.minlon));
+            Symbols.drawSymbol(g2, legend, sScale, point.getX(), point.getY(), null, new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, 0)));
+            legend = new Symbol();
+            legend.add(new Instr(Form.BBOX, new Rectangle2D.Double(0, 0, 900, 300)));
+            legend.add(new Instr(Form.TEXT, new Caption("Mercator projection", new Font("Arial", Font.PLAIN, 30), Color.black, new Delta(Handle.BC, AffineTransform.getTranslateInstance(450, 250)))));
+            point = context.getPoint(new Snode(map.bounds.minlat, map.bounds.minlon));
+            Symbols.drawSymbol(g2, legend, sScale, point.getX(), point.getY(), null, new Delta(Handle.BL, AffineTransform.getTranslateInstance(0, 0)));
+*/        }
     }
 
Index: /applications/editors/josm/plugins/seachart/src/s57/S57map.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57map.java	(revision 35392)
@@ -215,5 +215,5 @@
         public ObjMap objs;        // Slave object attributes
 
-        Feature() {
+        public Feature() {
             id = 0;
             reln = Rflag.UNKN;
Index: /applications/editors/josm/plugins/seachart/src/s57/S57osm.java
===================================================================
--- /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 35391)
+++ /applications/editors/josm/plugins/seachart/src/s57/S57osm.java	(revision 35392)
@@ -2,7 +2,15 @@
 package s57;
 
-import java.io.BufferedReader;
+import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 
 import s57.S57att.Att;
@@ -89,5 +97,5 @@
     }
 
-    public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
+    public static void OSMmap(File in, S57map map, boolean bb) throws Exception {
         String k = "";
         String v = "";
@@ -96,9 +104,8 @@
         double lon = 0;
         long id = 0;
-
-        boolean inOsm = false;
-        boolean inNode = false;
-        boolean inWay = false;
-        boolean inRel = false;
+        long ref = 0;
+        String type = "";
+        String role = "";
+
         map.nodes.put(1L, new Snode());
         map.nodes.put(2L, new Snode());
@@ -106,135 +113,113 @@
         map.nodes.put(4L, new Snode());
 
-        String ln;
-        while ((ln = in.readLine()) != null) {
-            if (inOsm) {
-                if (ln.contains("<bounds") && !bb) {
-                    for (String token : ln.split("[ ]+")) {
-                        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;
-                        }
-                    }
-                } else {
-                    if ((inNode || inWay || inRel) && ln.contains("<tag")) {
-                        k = v = "";
-                        String[] token = ln.split("k=");
-                        k = token[1].split("[\"]")[1];
-                        token = token[1].split("v=");
-                        v = token[1].split("[\"]")[1];
-                        if (!k.isEmpty() && !v.isEmpty()) {
-                            map.addTag(k, v);
-                        }
-                    }
-                    if (inNode) {
-                        if (ln.contains("</node")) {
-                            inNode = false;
-                            map.tagsDone(id);
-                        }
-                    } else if (ln.contains("<node")) {
-                        for (String token : ln.split("[ ]+")) {
-                            if (token.matches("^id=.+")) {
-                                id = Long.parseLong(token.split("[\"]")[1]);
-                            } else if (token.matches("^lat=.+")) {
-                                lat = Double.parseDouble(token.split("[\"]")[1]);
-                            } else if (token.matches("^lon=.+")) {
-                                lon = Double.parseDouble(token.split("[\"]")[1]);
-                            }
-                        }
-                        map.addNode(id, lat, lon);
-                        if (ln.contains("/>")) {
-                            map.tagsDone(id);
-                        } else {
-                            inNode = true;
-                        }
-                    } else if (inWay) {
-                        if (ln.contains("<nd")) {
-                            long ref = 0;
-                            for (String token : ln.split("[ ]+")) {
-                                if (token.matches("^ref=.+")) {
-                                    ref = Long.parseLong(token.split("[\"]")[1]);
-                                }
-                            }
-                            try {
-                                map.addToEdge(ref);
-                            } catch (Exception e) {
-                                inWay = false;
-                            }
-                        }
-                        if (ln.contains("</way")) {
-                            inWay = false;
-                            map.tagsDone(id);
-                        }
-                    } else if (ln.contains("<way")) {
-                        for (String token : ln.split("[ ]+")) {
-                            if (token.matches("^id=.+")) {
-                                id = Long.parseLong(token.split("[\"]")[1]);
-                            }
-                        }
-                        map.addEdge(id);
-                        if (ln.contains("/>")) {
-                            map.tagsDone(0);
-                        } else {
-                            inWay = true;
-                        }
-                    } else if (ln.contains("</osm")) {
-                        map.mapDone();
-                        inOsm = false;
-                        break;
-                    } else if (inRel) {
-                        if (ln.contains("<member")) {
-                            String type = "";
-                            String role = "";
-                            long ref = 0;
-                            for (String token : ln.split("[ ]+")) {
-                                if (token.matches("^ref=.+")) {
-                                    ref = Long.parseLong(token.split("[\"]")[1]);
-                                } else if (token.matches("^type=.+")) {
-                                    type = token.split("[\"]")[1];
-                                } else if (token.matches("^role=.+")) {
-                                    String[] str = token.split("[\"]");
-                                    if (str.length > 1) {
-                                        role = token.split("[\"]")[1];
-                                    }
-                                }
-                            }
-                            if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
-                                map.addToArea(ref, role.equals("outer"));
-                        }
-                        if (ln.contains("</relation")) {
-                            inRel = false;
-                            map.tagsDone(id);
-                        }
-                    } else if (ln.contains("<relation")) {
-                        for (String token : ln.split("[ ]+")) {
-                            if (token.matches("^id=.+")) {
-                                id = Long.parseLong(token.split("[\"]")[1]);
-                            }
-                        }
-                        map.addArea(id);
-                        if (ln.contains("/>")) {
-                            map.tagsDone(id);
-                        } else {
-                            inRel = true;
-                        }
-                    }
-                }
-            } else if (ln.contains("<osm")) {
-                inOsm = true;
-            }
-        }
+        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+        Document doc = dBuilder.parse(in);
+        doc.getDocumentElement().normalize();
+        if (!doc.getDocumentElement().getNodeName().equals("osm")) {
+            System.err.println("OSM file format error");
+            System.exit(-1);
+        }
+        NodeList nList = doc.getElementsByTagName("bounds");
+        NamedNodeMap nnmap = nList.item(0).getAttributes();
+        map.bounds.minlat = Math.toRadians(Double.parseDouble(nnmap.getNamedItem("minlat").getNodeValue()));
+        map.nodes.get(2L).lat = map.bounds.minlat;
+        map.nodes.get(3L).lat = map.bounds.minlat;
+        map.bounds.minlon = Math.toRadians(Double.parseDouble(nnmap.getNamedItem("minlon").getNodeValue()));
+        map.nodes.get(1L).lon = map.bounds.minlon;
+        map.nodes.get(2L).lon = map.bounds.minlon;
+        map.bounds.maxlat = Math.toRadians(Double.parseDouble(nnmap.getNamedItem("maxlat").getNodeValue()));
+        map.nodes.get(1L).lat = map.bounds.maxlat;
+        map.nodes.get(4L).lat = map.bounds.maxlat;
+        map.bounds.maxlon = Math.toRadians(Double.parseDouble(nnmap.getNamedItem("maxlon").getNodeValue()));
+        map.nodes.get(3L).lon = map.bounds.maxlon;
+        map.nodes.get(4L).lon = map.bounds.maxlon;
+
+        nList = doc.getElementsByTagName("node");
+        int nLen = nList.getLength();
+        for (int i = 0; i < nLen; i++) {
+            Node nNode = nList.item(i);
+            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+                nnmap = nNode.getAttributes();
+                id = Long.parseLong(nnmap.getNamedItem("id").getNodeValue());
+                lat = Double.parseDouble(nnmap.getNamedItem("lat").getNodeValue());
+                lon = Double.parseDouble(nnmap.getNamedItem("lon").getNodeValue());
+                map.addNode(id, lat, lon);
+                NodeList tList = ((Element)nNode).getElementsByTagName("tag");
+                for (int j = 0; j < tList.getLength(); j++) {
+                    NamedNodeMap ntmap = tList.item(j).getAttributes();
+                    k = ntmap.getNamedItem("k").getNodeValue();
+                    v = ntmap.getNamedItem("v").getNodeValue();
+                    if (!k.isEmpty() && !v.isEmpty()) {
+                        map.addTag(k, v);
+                    }
+                }
+                map.tagsDone(id);
+            }
+        }
+
+        nList = doc.getElementsByTagName("way");
+        nLen = nList.getLength();
+        for (int i = 0; i < nLen; i++) {
+            Node nNode = nList.item(i);
+            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+                nnmap = nNode.getAttributes();
+                id = Long.parseLong(nnmap.getNamedItem("id").getNodeValue());
+                map.addEdge(id);
+                NodeList rList = ((Element)nNode).getElementsByTagName("nd");
+                for (int j = 0; j < rList.getLength(); j++) {
+                    NamedNodeMap nrmap = rList.item(j).getAttributes();
+                    ref = Long.parseLong(nrmap.getNamedItem("ref").getNodeValue());
+                    try {
+                        map.addToEdge(ref);
+                    } catch (Exception e) {
+                        System.err.println("Unknown node in way");
+                        System.exit(-1);
+                    }
+                }
+                NodeList tList = ((Element)nNode).getElementsByTagName("tag");
+                for (int j = 0; j < tList.getLength(); j++) {
+                    NamedNodeMap ntmap = tList.item(j).getAttributes();
+                    k = ntmap.getNamedItem("k").getNodeValue();
+                    v = ntmap.getNamedItem("v").getNodeValue();
+                    if (!k.isEmpty() && !v.isEmpty()) {
+                        map.addTag(k, v);
+                    }
+                }
+                map.tagsDone(id);
+            }
+        }
+
+        nList = doc.getElementsByTagName("relation");
+        nLen = nList.getLength();
+        for (int i = 0; i < nLen; i++) {
+            Node nNode = nList.item(i);
+            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+                nnmap = nNode.getAttributes();
+                id = Long.parseLong(nnmap.getNamedItem("id").getNodeValue());
+                map.addArea(id);
+                NodeList rList = ((Element)nNode).getElementsByTagName("member");
+                for (int j = 0; j < rList.getLength(); j++) {
+                    NamedNodeMap nrmap = rList.item(j).getAttributes();
+                    type = nrmap.getNamedItem("type").getNodeValue();
+                    ref = Long.parseLong(nrmap.getNamedItem("ref").getNodeValue());
+                    role = nrmap.getNamedItem("role").getNodeValue();
+                    if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
+                        map.addToArea(ref, role.equals("outer"));
+                }
+                NodeList tList = ((Element)nNode).getElementsByTagName("tag");
+                for (int j = 0; j < tList.getLength(); j++) {
+                    NamedNodeMap ntmap = tList.item(j).getAttributes();
+                    k = ntmap.getNamedItem("k").getNodeValue();
+                    v = ntmap.getNamedItem("v").getNodeValue();
+                    if (!k.isEmpty() && !v.isEmpty()) {
+                        map.addTag(k, v);
+                    }
+                }
+                map.tagsDone(id);
+            }
+        }
+
+        map.mapDone();
         return;
     }
