source: josm/trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java@ 11089

Last change on this file since 11089 was 11089, checked in by simon04, 8 years ago

fix #13717 - Enhance and allow customization of tag mapping when converting GPX markers to OSM data

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer.gpx;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.GridBagLayout;
8import java.awt.event.ActionEvent;
9import java.io.File;
10import java.util.ArrayList;
11import java.util.Arrays;
12import java.util.Collection;
13import java.util.Iterator;
14import java.util.List;
15import java.util.Optional;
16
17import javax.swing.AbstractAction;
18import javax.swing.JLabel;
19import javax.swing.JOptionPane;
20import javax.swing.JPanel;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.data.gpx.GpxConstants;
24import org.openstreetmap.josm.data.gpx.GpxTrack;
25import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
26import org.openstreetmap.josm.data.gpx.WayPoint;
27import org.openstreetmap.josm.data.osm.DataSet;
28import org.openstreetmap.josm.data.osm.Node;
29import org.openstreetmap.josm.data.osm.Way;
30import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
31import org.openstreetmap.josm.gui.layer.GpxLayer;
32import org.openstreetmap.josm.gui.layer.Layer;
33import org.openstreetmap.josm.gui.layer.OsmDataLayer;
34import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
35import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
36import org.openstreetmap.josm.gui.widgets.UrlLabel;
37import org.openstreetmap.josm.tools.GBC;
38import org.openstreetmap.josm.tools.ImageProvider;
39import org.openstreetmap.josm.tools.Logging;
40import org.openstreetmap.josm.tools.date.DateUtils;
41
42/**
43 * An abstract action for a conversion from a {@code T} {@link Layer} to a {@link OsmDataLayer}.
44 * @param <T> the source layer class
45 */
46public abstract class ConvertToDataLayerAction<T extends Layer> extends AbstractAction {
47 protected final transient T layer;
48
49 protected ConvertToDataLayerAction(final T layer) {
50 super(tr("Convert to data layer"), ImageProvider.get("converttoosm"));
51 this.layer = layer;
52 putValue("help", ht("/Action/ConvertToDataLayer"));
53 }
54
55 /**
56 * Converts a {@link GpxLayer} to a {@link OsmDataLayer}.
57 */
58 public static class FromGpxLayer extends ConvertToDataLayerAction<GpxLayer> {
59
60 /**
61 * Creates a new {@code FromGpxLayer}.
62 * @param layer the source layer
63 */
64 public FromGpxLayer(GpxLayer layer) {
65 super(layer);
66 }
67
68 @Override
69 public DataSet convert() {
70 final DataSet ds = new DataSet();
71 for (GpxTrack trk : layer.data.tracks) {
72 for (GpxTrackSegment segment : trk.getSegments()) {
73 List<Node> nodes = new ArrayList<>();
74 for (WayPoint p : segment.getWayPoints()) {
75 Node n = new Node(p.getCoor());
76 String timestr = p.getString(GpxConstants.PT_TIME);
77 if (timestr != null) {
78 n.setTimestamp(DateUtils.fromString(timestr));
79 }
80 ds.addPrimitive(n);
81 nodes.add(n);
82 }
83 Way w = new Way();
84 w.setNodes(nodes);
85 ds.addPrimitive(w);
86 }
87 }
88 return ds;
89 }
90 }
91
92 /**
93 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}.
94 */
95 public static class FromMarkerLayer extends ConvertToDataLayerAction<MarkerLayer> {
96
97 /**
98 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}.
99 * @param layer marker layer
100 */
101 public FromMarkerLayer(MarkerLayer layer) {
102 super(layer);
103 }
104
105 @Override
106 public DataSet convert() {
107 final DataSet ds = new DataSet();
108 for (Marker marker : layer.data) {
109 final Node node = new Node(marker.getCoor());
110 final Collection<String> mapping = Main.pref.getCollection("gpx.to-osm-mapping",
111 Arrays.asList("name", "name", "desc", "description", "cmt", "note", "sym", "gpxicon"));
112 if (mapping.size() % 2 == 0) {
113 final Iterator<String> it = mapping.iterator();
114 while (it.hasNext()) {
115 final String gpxKey = it.next();
116 final String osmKey = it.next();
117 Optional.ofNullable(marker.getTemplateValue(gpxKey, false))
118 .map(String::valueOf)
119 .ifPresent(s -> node.put(osmKey, s));
120 }
121 } else {
122 Logging.warn("Invalid gpx.to-osm-mapping Einstein setting: expecting even number of entries");
123 }
124 ds.addPrimitive(node);
125 }
126 return ds;
127 }
128 }
129
130 /**
131 * Performs the conversion to a {@link DataSet}.
132 * @return the resulting dataset
133 */
134 public abstract DataSet convert();
135
136 @Override
137 public void actionPerformed(ActionEvent e) {
138 JPanel msg = new JPanel(new GridBagLayout());
139 msg.add(new JLabel(
140 // CHECKSTYLE.OFF: LineLength
141 tr("<html>Upload of unprocessed GPS data as map data is considered harmful.<br>If you want to upload traces, look here:</html>")),
142 // CHECKSTYLE.ON: LineLength
143 GBC.eol());
144 msg.add(new UrlLabel(Main.getOSMWebsite() + "/traces", 2), GBC.eop());
145 if (!ConditionalOptionPaneUtil.showConfirmationDialog("convert_to_data", Main.parent, msg, tr("Warning"),
146 JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION)) {
147 return;
148 }
149 final DataSet ds = convert();
150 final OsmDataLayer layer = new OsmDataLayer(ds, tr("Converted from: {0}", this.layer.getName()), null);
151 if (this.layer.getAssociatedFile() != null) {
152 layer.setAssociatedFile(new File(this.layer.getAssociatedFile().getParentFile(), this.layer.getAssociatedFile().getName() + ".osm"));
153 }
154 layer.setUploadDiscouraged(true);
155 Main.getLayerManager().addLayer(layer);
156 Main.getLayerManager().removeLayer(this.layer);
157 }
158}
Note: See TracBrowser for help on using the repository browser.