001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.gpx; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.GridBagLayout; 008import java.awt.event.ActionEvent; 009import java.io.File; 010import java.util.ArrayList; 011import java.util.List; 012 013import javax.swing.AbstractAction; 014import javax.swing.JLabel; 015import javax.swing.JOptionPane; 016import javax.swing.JPanel; 017 018import org.openstreetmap.josm.Main; 019import org.openstreetmap.josm.data.gpx.GpxConstants; 020import org.openstreetmap.josm.data.gpx.GpxTrack; 021import org.openstreetmap.josm.data.gpx.GpxTrackSegment; 022import org.openstreetmap.josm.data.gpx.WayPoint; 023import org.openstreetmap.josm.data.osm.DataSet; 024import org.openstreetmap.josm.data.osm.Node; 025import org.openstreetmap.josm.data.osm.Way; 026import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 027import org.openstreetmap.josm.gui.layer.GpxLayer; 028import org.openstreetmap.josm.gui.layer.Layer; 029import org.openstreetmap.josm.gui.layer.OsmDataLayer; 030import org.openstreetmap.josm.gui.layer.markerlayer.Marker; 031import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 032import org.openstreetmap.josm.gui.widgets.UrlLabel; 033import org.openstreetmap.josm.tools.GBC; 034import org.openstreetmap.josm.tools.ImageProvider; 035import org.openstreetmap.josm.tools.date.DateUtils; 036 037/** 038 * An abstract action for a conversion from a {@code T} {@link Layer} to a {@link OsmDataLayer}. 039 * @param <T> the source layer class 040 */ 041public abstract class ConvertToDataLayerAction<T extends Layer> extends AbstractAction { 042 protected final transient T layer; 043 044 protected ConvertToDataLayerAction(final T layer) { 045 super(tr("Convert to data layer"), ImageProvider.get("converttoosm")); 046 this.layer = layer; 047 putValue("help", ht("/Action/ConvertToDataLayer")); 048 } 049 050 /** 051 * Converts a {@link GpxLayer} to a {@link OsmDataLayer}. 052 */ 053 public static class FromGpxLayer extends ConvertToDataLayerAction<GpxLayer> { 054 055 /** 056 * Creates a new {@code FromGpxLayer}. 057 * @param layer the source layer 058 */ 059 public FromGpxLayer(GpxLayer layer) { 060 super(layer); 061 } 062 063 @Override 064 public DataSet convert() { 065 final DataSet ds = new DataSet(); 066 for (GpxTrack trk : layer.data.tracks) { 067 for (GpxTrackSegment segment : trk.getSegments()) { 068 List<Node> nodes = new ArrayList<>(); 069 for (WayPoint p : segment.getWayPoints()) { 070 Node n = new Node(p.getCoor()); 071 String timestr = p.getString(GpxConstants.PT_TIME); 072 if (timestr != null) { 073 n.setTimestamp(DateUtils.fromString(timestr)); 074 } 075 ds.addPrimitive(n); 076 nodes.add(n); 077 } 078 Way w = new Way(); 079 w.setNodes(nodes); 080 ds.addPrimitive(w); 081 } 082 } 083 return ds; 084 } 085 } 086 087 /** 088 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}. 089 */ 090 public static class FromMarkerLayer extends ConvertToDataLayerAction<MarkerLayer> { 091 092 /** 093 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}. 094 */ 095 public FromMarkerLayer(MarkerLayer layer) { 096 super(layer); 097 } 098 099 @Override 100 public DataSet convert() { 101 final DataSet ds = new DataSet(); 102 for (Marker marker : layer.data) { 103 final Node node = new Node(marker.getCoor()); 104 node.put("name", marker.getText()); 105 ds.addPrimitive(node); 106 } 107 return ds; 108 } 109 } 110 111 /** 112 * Performs the conversion to a {@link DataSet}. 113 * @return the resulting dataset 114 */ 115 public abstract DataSet convert(); 116 117 @Override 118 public void actionPerformed(ActionEvent e) { 119 JPanel msg = new JPanel(new GridBagLayout()); 120 msg.add(new JLabel( 121 // CHECKSTYLE.OFF: LineLength 122 tr("<html>Upload of unprocessed GPS data as map data is considered harmful.<br>If you want to upload traces, look here:</html>")), 123 // CHECKSTYLE.ON: LineLength 124 GBC.eol()); 125 msg.add(new UrlLabel(Main.getOSMWebsite() + "/traces", 2), GBC.eop()); 126 if (!ConditionalOptionPaneUtil.showConfirmationDialog("convert_to_data", Main.parent, msg, tr("Warning"), 127 JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION)) { 128 return; 129 } 130 final DataSet ds = convert(); 131 final OsmDataLayer layer = new OsmDataLayer(ds, tr("Converted from: {0}", this.layer.getName()), null); 132 if (this.layer.getAssociatedFile() != null) { 133 layer.setAssociatedFile(new File(this.layer.getAssociatedFile().getParentFile(), this.layer.getAssociatedFile().getName() + ".osm")); 134 } 135 layer.setUploadDiscouraged(true); 136 Main.main.addLayer(layer); 137 Main.main.removeLayer(this.layer); 138 } 139}