// License: GPL. For details, see LICENSE file. package seachart; import java.awt.event.ActionEvent; import java.util.Map.Entry; import javax.swing.SwingUtilities; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.JosmAction; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.imagery.ImageryInfo; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; 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.data.osm.event.AbstractDatasetChangedEvent; import org.openstreetmap.josm.data.osm.event.DataChangedEvent; import org.openstreetmap.josm.data.osm.event.DataSetListener; import org.openstreetmap.josm.data.osm.event.NodeMovedEvent; import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent; import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent; import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent; import org.openstreetmap.josm.data.osm.event.TagsChangedEvent; import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent; import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent; import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent; import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener; import org.openstreetmap.josm.gui.layer.OsmDataLayer; import s57.S57map; /** * @author Malcolm Herring */ public class SeachartAction extends JosmAction implements ActiveLayerChangeListener, LayerChangeListener { private static String title = "SeaChart"; private boolean isOpen = false; public static ChartImage rendering; public static S57map map = null; public DataSet data = null; private final DataSetListener dataSetListener = new DataSetListener() { @Override public void dataChanged(DataChangedEvent e) { makeChart(); } @Override public void nodeMoved(NodeMovedEvent e) { makeChart(); } @Override public void otherDatasetChange(AbstractDatasetChangedEvent e) { makeChart(); } @Override public void primitivesAdded(PrimitivesAddedEvent e) { makeChart(); } @Override public void primitivesRemoved(PrimitivesRemovedEvent e) { makeChart(); } @Override public void relationMembersChanged(RelationMembersChangedEvent e) { makeChart(); } @Override public void tagsChanged(TagsChangedEvent e) { makeChart(); } @Override public void wayNodesChanged(WayNodesChangedEvent e) { makeChart(); } }; public SeachartAction() { super(title, "SC", title, null, true); } @Override public void layerAdded(LayerAddEvent e) { } @Override public void layerRemoving(LayerRemoveEvent e) { if ("SeaChart".equals(e.getRemovedLayer().getName())) { closeChartLayer(); } } @Override public void layerOrderChanged(LayerOrderChangeEvent e) { } @Override public void actionPerformed(ActionEvent arg0) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (!isOpen) createChartLayer(); isOpen = true; } }); } protected void createChartLayer() { rendering = new ChartImage(new ImageryInfo("SeaChart")); rendering.setBackgroundLayer(true); Main.getLayerManager().addLayer(rendering); Main.getLayerManager().addAndFireActiveLayerChangeListener(this); Main.getLayerManager().addLayerChangeListener(this); } public void closeChartLayer() { if (isOpen) { try { Main.getLayerManager().removeActiveLayerChangeListener(this); Main.getLayerManager().removeLayerChangeListener(this); Main.getLayerManager().removeLayer(rendering); } catch (Exception e) { // Assume that this can't be serious? System.err.println(e); } } isOpen = false; } @Override public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) { OsmDataLayer oldLayer = e.getPreviousEditLayer(); if (oldLayer != null) { oldLayer.data.removeDataSetListener(dataSetListener); } OsmDataLayer newLayer = Main.getLayerManager().getEditLayer(); if (newLayer != null) { newLayer.data.addDataSetListener(dataSetListener); data = newLayer.data; makeChart(); } else { data = null; map = null; } } void makeChart() { map = new S57map(false); if (data != null) { double minlat = 90; double maxlat = -90; double minlon = 180; double maxlon = -180; for (Bounds bounds : data.getDataSourceBounds()) { if (bounds.getMinLat() < minlat) { minlat = bounds.getMinLat(); } if (bounds.getMaxLat() > maxlat) { maxlat = bounds.getMaxLat(); } if (bounds.getMinLon() < minlon) { minlon = bounds.getMinLon(); } if (bounds.getMaxLon() > maxlon) { maxlon = bounds.getMaxLon(); } } map.addNode(1, maxlat, minlon); map.addNode(2, minlat, minlon); map.addNode(3, minlat, maxlon); map.addNode(4, maxlat, maxlon); map.bounds.minlat = Math.toRadians(minlat); map.bounds.maxlat = Math.toRadians(maxlat); map.bounds.minlon = Math.toRadians(minlon); map.bounds.maxlon = Math.toRadians(maxlon); for (Node node : data.getNodes()) { LatLon coor = node.getCoor(); if (coor != null) { map.addNode(node.getUniqueId(), coor.lat(), coor.lon()); for (Entry<String, String> entry : node.getKeys().entrySet()) { map.addTag(entry.getKey(), entry.getValue()); } map.tagsDone(node.getUniqueId()); } } for (Way way : data.getWays()) { if (way.getNodesCount() > 0) { map.addEdge(way.getUniqueId()); for (Node node : way.getNodes()) { map.addToEdge((node.getUniqueId())); } for (Entry<String, String> entry : way.getKeys().entrySet()) { map.addTag(entry.getKey(), entry.getValue()); } map.tagsDone(way.getUniqueId()); } } for (Relation rel : data.getRelations()) { if (rel.isMultipolygon() && (rel.getMembersCount() > 0)) { map.addArea(rel.getUniqueId()); for (RelationMember mem : rel.getMembers()) { if (mem.getType() == OsmPrimitiveType.WAY) map.addToArea(mem.getUniqueId(), (mem.getRole().equals("outer"))); } for (Entry<String, String> entry : rel.getKeys().entrySet()) { map.addTag(entry.getKey(), entry.getValue()); } map.tagsDone(rel.getUniqueId()); } } map.mapDone(); if (rendering != null) rendering.zoomChanged(); } } }