/* Copyright 2014 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 panels; import java.awt.Color; import java.awt.Dimension; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import javax.swing.JFileChooser; import javax.swing.JPanel; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.OsmPrimitiveType; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.RelationMember; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import s57.S57att; import s57.S57att.Att; import s57.S57dec; import s57.S57map; import s57.S57map.AttMap; import s57.S57map.Feature; import s57.S57map.GeomIterator; import s57.S57map.ObjTab; import s57.S57map.Pflag; import s57.S57map.Prim; import s57.S57map.Rflag; import s57.S57map.Snode; import s57.S57obj; import s57.S57obj.Obj; import s57.S57val; import s57.S57val.AttVal; public class PanelS57 extends JPanel { ArrayList<Obj> types = new ArrayList<>(); S57map map; HashMap<Long, Long> uids = new HashMap<>(); public PanelS57() { setLayout(null); setSize(new Dimension(480, 480)); setVisible(false); } public void startImport(File inf) throws IOException { FileInputStream in = new FileInputStream(inf); PanelMain.setStatus("Select OSM types file", Color.yellow); JFileChooser ifc = new JFileChooser(Main.pref.get("smed2plugin.typesfile")); ifc.setSelectedFile(new File(Main.pref.get("smed2plugin.typesfile"))); int returnVal = ifc.showOpenDialog(Main.parent); if (returnVal == JFileChooser.APPROVE_OPTION) { Main.pref.put("smed2plugin.typesfile", ifc.getSelectedFile().getPath()); Scanner tin = new Scanner(new FileInputStream(ifc.getSelectedFile())); while (tin.hasNext()) { Obj type = S57obj.enumType(tin.next()); if (type != Obj.UNKOBJ) types.add(type); } tin.close(); } map = new S57map(true); S57dec.decodeChart(in, map); in.close(); DataSet data = new DataSet(); data.setUploadDiscouraged(true); for (long id : map.index.keySet()) { Feature feature = map.index.get(id); String type = S57obj.stringType(feature.type); if (!type.isEmpty() && (types.isEmpty() || types.contains(feature.type))) { if (feature.reln == Rflag.MASTER) { if (feature.geom.prim == Pflag.POINT) { for (Prim prim : feature.geom.elems) { long ref = prim.id; Snode snode; while ((snode = map.nodes.get(ref)) != null) { if (!uids.containsKey(ref)) { Node node = new Node(0, 1); node.setCoor((new LatLon(Math.toDegrees(snode.lat), Math.toDegrees(snode.lon)))); data.addPrimitive(node); addKeys(node, feature, type); uids.put(ref, node.getUniqueId()); } ref++; } } } } } } for (long id : map.index.keySet()) { Feature feature = map.index.get(id); String type = S57obj.stringType(feature.type); if (!type.isEmpty() && (types.isEmpty() || types.contains(feature.type))) { if (feature.reln == Rflag.MASTER) { if ((feature.geom.prim == Pflag.LINE) || ((feature.geom.prim == Pflag.AREA) && (feature.geom.outers == 1) && (feature.geom.inners == 0))) { GeomIterator git = map.new GeomIterator(feature.geom); while (git.hasComp()) { git.nextComp(); while (git.hasEdge()) { git.nextEdge(); while (git.hasNode()) { long ref = git.nextRef(); Snode snode = map.nodes.get(ref); if (!uids.containsKey(ref)) { Node node = new Node(0, 1); node.setCoor((new LatLon(Math.toDegrees(snode.lat), Math.toDegrees(snode.lon)))); data.addPrimitive(node); uids.put(ref, node.getUniqueId()); } } } } git = map.new GeomIterator(feature.geom); while (git.hasComp()) { git.nextComp(); Way way = new Way(0, 1); data.addPrimitive(way); while (git.hasEdge()) { git.nextEdge(); while (git.hasNode()) { long ref = git.nextRef(); way.addNode((Node) data.getPrimitiveById(uids.get(ref), OsmPrimitiveType.NODE)); } } addKeys(way, feature, type); } } else if (feature.geom.prim == Pflag.AREA) { GeomIterator git = map.new GeomIterator(feature.geom); while (git.hasComp()) { git.nextComp(); while (git.hasEdge()) { git.nextEdge(); while (git.hasNode()) { long ref = git.nextRef(); Snode snode = map.nodes.get(ref); if (!uids.containsKey(ref)) { Node node = new Node(0, 1); node.setCoor((new LatLon(Math.toDegrees(snode.lat), Math.toDegrees(snode.lon)))); data.addPrimitive(node); uids.put(ref, node.getUniqueId()); } } } } git = map.new GeomIterator(feature.geom); while (git.hasComp()) { long ref = git.nextComp(); Way way = new Way(0, 1); uids.put(ref, way.getUniqueId()); data.addPrimitive(way); while (git.hasEdge()) { git.nextEdge(); while (git.hasNode()) { ref = git.nextRef(); way.addNode((Node) data.getPrimitiveById(uids.get(ref), OsmPrimitiveType.NODE)); } } } Relation rel = new Relation(0, 1); data.addPrimitive(rel); git = map.new GeomIterator(feature.geom); int outers = feature.geom.outers; while (git.hasComp()) { long ref = git.nextComp(); if (outers-- > 0) { rel.addMember(new RelationMember("outer", data.getPrimitiveById(uids.get(ref), OsmPrimitiveType.WAY))); } else { rel.addMember(new RelationMember("inner", data.getPrimitiveById(uids.get(ref), OsmPrimitiveType.WAY))); } } addKeys(rel, feature, type); } } } } OsmDataLayer layer = new OsmDataLayer(data, "S-57 Import", null); Main.getLayerManager().addLayer(layer); Main.map.mapView.zoomTo(new Bounds(Math.toDegrees(map.bounds.minlat), Math.toDegrees(map.bounds.minlon), Math.toDegrees(map.bounds.maxlat), Math.toDegrees(map.bounds.maxlon))); PanelMain.setStatus("Import done", Color.green); } void addKeys(OsmPrimitive prim, Feature feature, String type) { HashMap<String, String> keys = new HashMap<>(); if (prim instanceof Relation) { keys.put("type", "multipolygon"); } keys.put("seamark:type", type); if (feature.type == Obj.SOUNDG) { Snode snode = map.nodes.get(feature.geom.elems.get(0).id); if (snode.flg == S57map.Nflag.DPTH) { keys.put("seamark:sounding:depth", ((Double) snode.val).toString()); } } for (Map.Entry<Att, AttVal<?>> item : feature.atts.entrySet()) { String attstr = S57att.stringAttribute(item.getKey()); String valstr = S57val.stringValue(item.getValue(), item.getKey()); if (!attstr.isEmpty() && !valstr.isEmpty()) { keys.put(("seamark:" + type + ":" + attstr), valstr); } } for (Obj obj : feature.objs.keySet()) { ObjTab tab = feature.objs.get(obj); for (int ix : tab.keySet()) { type = S57obj.stringType(obj); AttMap atts = tab.get(ix); for (Map.Entry<Att, AttVal<?>> item : atts.entrySet()) { String attstr = S57att.stringAttribute(item.getKey()); String valstr = S57val.stringValue(item.getValue(), item.getKey()); if (!attstr.isEmpty() && !valstr.isEmpty()) { if ((ix == 0) && (tab.size() == 1)) { keys.put(("seamark:" + type + ":" + attstr), valstr); } else { keys.put(("seamark:" + type + ":" + (ix+1) + ":" + attstr), valstr); } } } } } prim.setKeys(keys); } public void startExport(File outf) throws IOException { } }