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 * @param layer marker layer 095 */ 096 public FromMarkerLayer(MarkerLayer layer) { 097 super(layer); 098 } 099 100 @Override 101 public DataSet convert() { 102 final DataSet ds = new DataSet(); 103 for (Marker marker : layer.data) { 104 final Node node = new Node(marker.getCoor()); 105 node.put("name", marker.getText()); 106 ds.addPrimitive(node); 107 } 108 return ds; 109 } 110 } 111 112 /** 113 * Performs the conversion to a {@link DataSet}. 114 * @return the resulting dataset 115 */ 116 public abstract DataSet convert(); 117 118 @Override 119 public void actionPerformed(ActionEvent e) { 120 JPanel msg = new JPanel(new GridBagLayout()); 121 msg.add(new JLabel( 122 // CHECKSTYLE.OFF: LineLength 123 tr("<html>Upload of unprocessed GPS data as map data is considered harmful.<br>If you want to upload traces, look here:</html>")), 124 // CHECKSTYLE.ON: LineLength 125 GBC.eol()); 126 msg.add(new UrlLabel(Main.getOSMWebsite() + "/traces", 2), GBC.eop()); 127 if (!ConditionalOptionPaneUtil.showConfirmationDialog("convert_to_data", Main.parent, msg, tr("Warning"), 128 JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION)) { 129 return; 130 } 131 final DataSet ds = convert(); 132 final OsmDataLayer layer = new OsmDataLayer(ds, tr("Converted from: {0}", this.layer.getName()), null); 133 if (this.layer.getAssociatedFile() != null) { 134 layer.setAssociatedFile(new File(this.layer.getAssociatedFile().getParentFile(), this.layer.getAssociatedFile().getName() + ".osm")); 135 } 136 layer.setUploadDiscouraged(true); 137 Main.main.addLayer(layer); 138 Main.main.removeLayer(this.layer); 139 } 140}