source: josm/trunk/src/org/openstreetmap/josm/io/GpxExporter.java@ 11710

Last change on this file since 11710 was 11620, checked in by Don-vip, 7 years ago

checkstyle - enable CatchParameterName rule

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionListener;
8import java.awt.event.KeyAdapter;
9import java.awt.event.KeyEvent;
10import java.io.File;
11import java.io.IOException;
12import java.io.OutputStream;
13import java.text.MessageFormat;
14import java.time.Year;
15import java.util.Optional;
16
17import javax.swing.JButton;
18import javax.swing.JCheckBox;
19import javax.swing.JLabel;
20import javax.swing.JList;
21import javax.swing.JOptionPane;
22import javax.swing.JPanel;
23import javax.swing.JScrollPane;
24import javax.swing.ListSelectionModel;
25
26import org.openstreetmap.josm.Main;
27import org.openstreetmap.josm.data.gpx.GpxConstants;
28import org.openstreetmap.josm.data.gpx.GpxData;
29import org.openstreetmap.josm.gui.ExtendedDialog;
30import org.openstreetmap.josm.gui.layer.GpxLayer;
31import org.openstreetmap.josm.gui.layer.Layer;
32import org.openstreetmap.josm.gui.layer.OsmDataLayer;
33import org.openstreetmap.josm.gui.widgets.JosmTextArea;
34import org.openstreetmap.josm.gui.widgets.JosmTextField;
35import org.openstreetmap.josm.tools.CheckParameterUtil;
36import org.openstreetmap.josm.tools.GBC;
37
38/**
39 * Exports data to a .gpx file. Data may be native GPX or OSM data which will be converted.
40 * @since 1949
41 */
42public class GpxExporter extends FileExporter implements GpxConstants {
43
44 private static final String GPL_WARNING = "<html><font color='red' size='-2'>"
45 + tr("Note: GPL is not compatible with the OSM license. Do not upload GPL licensed tracks.") + "</html>";
46
47 private static final String[] LICENSES = {
48 "Creative Commons By-SA",
49 "Open Database License (ODbL)",
50 "public domain",
51 "GNU Lesser Public License (LGPL)",
52 "BSD License (MIT/X11)"};
53
54 private static final String[] URLS = {
55 "https://creativecommons.org/licenses/by-sa/3.0",
56 "http://opendatacommons.org/licenses/odbl/1.0",
57 "public domain",
58 "https://www.gnu.org/copyleft/lesser.html",
59 "http://www.opensource.org/licenses/bsd-license.php"};
60
61 /**
62 * Constructs a new {@code GpxExporter}.
63 */
64 public GpxExporter() {
65 super(GpxImporter.getFileFilter());
66 }
67
68 @Override
69 public boolean acceptFile(File pathname, Layer layer) {
70 if (!(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
71 return false;
72 return super.acceptFile(pathname, layer);
73 }
74
75 @Override
76 public void exportData(File file, Layer layer) throws IOException {
77 CheckParameterUtil.ensureParameterNotNull(layer, "layer");
78 if (!(layer instanceof OsmDataLayer) && !(layer instanceof GpxLayer))
79 throw new IllegalArgumentException(MessageFormat.format("Expected instance of OsmDataLayer or GpxLayer. Got ''{0}''.", layer
80 .getClass().getName()));
81 CheckParameterUtil.ensureParameterNotNull(file, "file");
82
83 String fn = file.getPath();
84 if (fn.indexOf('.') == -1) {
85 fn += ".gpx";
86 file = new File(fn);
87 }
88
89 // open the dialog asking for options
90 JPanel p = new JPanel(new GridBagLayout());
91
92 GpxData gpxData;
93 // At this moment, we only need to know the attributes of the GpxData,
94 // conversion of OsmDataLayer (if needed) will be done after the dialog is closed.
95 if (layer instanceof GpxLayer) {
96 gpxData = ((GpxLayer) layer).data;
97 } else {
98 gpxData = new GpxData();
99 }
100
101 p.add(new JLabel(tr("GPS track description")), GBC.eol());
102 JosmTextArea desc = new JosmTextArea(3, 40);
103 desc.setWrapStyleWord(true);
104 desc.setLineWrap(true);
105 desc.setText(gpxData.getString(META_DESC));
106 p.add(new JScrollPane(desc), GBC.eop().fill(GBC.BOTH));
107
108 JCheckBox author = new JCheckBox(tr("Add author information"), Main.pref.getBoolean("lastAddAuthor", true));
109 p.add(author, GBC.eol());
110
111 JLabel nameLabel = new JLabel(tr("Real name"));
112 p.add(nameLabel, GBC.std().insets(10, 0, 5, 0));
113 JosmTextField authorName = new JosmTextField();
114 p.add(authorName, GBC.eol().fill(GBC.HORIZONTAL));
115 nameLabel.setLabelFor(authorName);
116
117 JLabel emailLabel = new JLabel(tr("E-Mail"));
118 p.add(emailLabel, GBC.std().insets(10, 0, 5, 0));
119 JosmTextField email = new JosmTextField();
120 p.add(email, GBC.eol().fill(GBC.HORIZONTAL));
121 emailLabel.setLabelFor(email);
122
123 JLabel copyrightLabel = new JLabel(tr("Copyright (URL)"));
124 p.add(copyrightLabel, GBC.std().insets(10, 0, 5, 0));
125 JosmTextField copyright = new JosmTextField();
126 p.add(copyright, GBC.std().fill(GBC.HORIZONTAL));
127 copyrightLabel.setLabelFor(copyright);
128
129 JButton predefined = new JButton(tr("Predefined"));
130 p.add(predefined, GBC.eol().insets(5, 0, 0, 0));
131
132 JLabel copyrightYearLabel = new JLabel(tr("Copyright year"));
133 p.add(copyrightYearLabel, GBC.std().insets(10, 0, 5, 5));
134 JosmTextField copyrightYear = new JosmTextField("");
135 p.add(copyrightYear, GBC.eol().fill(GBC.HORIZONTAL));
136 copyrightYearLabel.setLabelFor(copyrightYear);
137
138 JLabel warning = new JLabel("<html><font size='-2'>&nbsp;</html");
139 p.add(warning, GBC.eol().fill(GBC.HORIZONTAL).insets(15, 0, 0, 0));
140 addDependencies(gpxData, author, authorName, email, copyright, predefined, copyrightYear, nameLabel, emailLabel,
141 copyrightLabel, copyrightYearLabel, warning);
142
143 p.add(new JLabel(tr("Keywords")), GBC.eol());
144 JosmTextField keywords = new JosmTextField();
145 keywords.setText(gpxData.getString(META_KEYWORDS));
146 p.add(keywords, GBC.eop().fill(GBC.HORIZONTAL));
147
148 ExtendedDialog ed = new ExtendedDialog(Main.parent,
149 tr("Export options"),
150 new String[] {tr("Export and Save"), tr("Cancel")});
151 ed.setButtonIcons(new String[] {"exportgpx", "cancel"});
152 ed.setContent(p);
153 ed.showDialog();
154
155 if (ed.getValue() != 1) {
156 setCanceled(true);
157 return;
158 }
159 setCanceled(false);
160
161 Main.pref.put("lastAddAuthor", author.isSelected());
162 if (!authorName.getText().isEmpty()) {
163 Main.pref.put("lastAuthorName", authorName.getText());
164 }
165 if (!copyright.getText().isEmpty()) {
166 Main.pref.put("lastCopyright", copyright.getText());
167 }
168
169 if (layer instanceof OsmDataLayer) {
170 gpxData = ((OsmDataLayer) layer).toGpxData();
171 } else if (layer instanceof GpxLayer) {
172 gpxData = ((GpxLayer) layer).data;
173 } else {
174 gpxData = OsmDataLayer.toGpxData(Main.getLayerManager().getEditDataSet(), file);
175 }
176
177 // add author and copyright details to the gpx data
178 if (author.isSelected()) {
179 if (!authorName.getText().isEmpty()) {
180 gpxData.put(META_AUTHOR_NAME, authorName.getText());
181 gpxData.put(META_COPYRIGHT_AUTHOR, authorName.getText());
182 }
183 if (!email.getText().isEmpty()) {
184 gpxData.put(META_AUTHOR_EMAIL, email.getText());
185 }
186 if (!copyright.getText().isEmpty()) {
187 gpxData.put(META_COPYRIGHT_LICENSE, copyright.getText());
188 }
189 if (!copyrightYear.getText().isEmpty()) {
190 gpxData.put(META_COPYRIGHT_YEAR, copyrightYear.getText());
191 }
192 }
193
194 // add the description to the gpx data
195 if (!desc.getText().isEmpty()) {
196 gpxData.put(META_DESC, desc.getText());
197 }
198
199 // add keywords to the gpx data
200 if (!keywords.getText().isEmpty()) {
201 gpxData.put(META_KEYWORDS, keywords.getText());
202 }
203
204 try (OutputStream fo = Compression.getCompressedFileOutputStream(file)) {
205 new GpxWriter(fo).write(gpxData);
206 fo.flush();
207 } catch (IOException ex) {
208 Main.error(ex);
209 JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}:\n{1}", fn, ex.getMessage()),
210 tr("Error"), JOptionPane.ERROR_MESSAGE);
211 }
212 }
213
214 private static void enableCopyright(final GpxData data, final JosmTextField copyright, final JButton predefined,
215 final JosmTextField copyrightYear, final JLabel copyrightLabel, final JLabel copyrightYearLabel,
216 final JLabel warning, boolean enable) {
217 copyright.setEnabled(enable);
218 predefined.setEnabled(enable);
219 copyrightYear.setEnabled(enable);
220 copyrightLabel.setEnabled(enable);
221 copyrightYearLabel.setEnabled(enable);
222 warning.setText(enable ? GPL_WARNING : "<html><font size='-2'>&nbsp;</html");
223
224 if (enable) {
225 if (copyrightYear.getText().isEmpty()) {
226 copyrightYear.setText(Optional.ofNullable(data.getString(META_COPYRIGHT_YEAR)).orElseGet(
227 () -> Year.now().toString()));
228 }
229 if (copyright.getText().isEmpty()) {
230 copyright.setText(Optional.ofNullable(data.getString(META_COPYRIGHT_LICENSE)).orElseGet(
231 () -> Main.pref.get("lastCopyright", "https://creativecommons.org/licenses/by-sa/2.5")));
232 copyright.setCaretPosition(0);
233 }
234 } else {
235 copyrightYear.setText("");
236 copyright.setText("");
237 }
238 }
239
240 // CHECKSTYLE.OFF: ParameterNumber
241
242 /**
243 * Add all those listeners to handle the enable state of the fields.
244 * @param data GPX data
245 * @param author Author checkbox
246 * @param authorName Author name textfield
247 * @param email E-mail textfield
248 * @param copyright Copyright textfield
249 * @param predefined Predefined button
250 * @param copyrightYear Copyright year textfield
251 * @param nameLabel Name label
252 * @param emailLabel E-mail label
253 * @param copyrightLabel Copyright label
254 * @param copyrightYearLabel Copyright year label
255 * @param warning Warning label
256 */
257 private static void addDependencies(
258 final GpxData data,
259 final JCheckBox author,
260 final JosmTextField authorName,
261 final JosmTextField email,
262 final JosmTextField copyright,
263 final JButton predefined,
264 final JosmTextField copyrightYear,
265 final JLabel nameLabel,
266 final JLabel emailLabel,
267 final JLabel copyrightLabel,
268 final JLabel copyrightYearLabel,
269 final JLabel warning) {
270
271 // CHECKSTYLE.ON: ParameterNumber
272 ActionListener authorActionListener = e -> {
273 boolean b = author.isSelected();
274 authorName.setEnabled(b);
275 email.setEnabled(b);
276 nameLabel.setEnabled(b);
277 emailLabel.setEnabled(b);
278 if (b) {
279 authorName.setText(Optional.ofNullable(data.getString(META_AUTHOR_NAME)).orElseGet(() -> Main.pref.get("lastAuthorName")));
280 email.setText(Optional.ofNullable(data.getString(META_AUTHOR_EMAIL)).orElseGet(() -> Main.pref.get("lastAuthorEmail")));
281 } else {
282 authorName.setText("");
283 email.setText("");
284 }
285 boolean isAuthorSet = !authorName.getText().isEmpty();
286 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning,
287 b && isAuthorSet);
288 };
289 author.addActionListener(authorActionListener);
290
291 KeyAdapter authorNameListener = new KeyAdapter() {
292 @Override public void keyReleased(KeyEvent e) {
293 boolean b = !authorName.getText().isEmpty() && author.isSelected();
294 GpxExporter.enableCopyright(data, copyright, predefined, copyrightYear, copyrightLabel, copyrightYearLabel, warning, b);
295 }
296 };
297 authorName.addKeyListener(authorNameListener);
298
299 predefined.addActionListener(e -> {
300 JList<String> l = new JList<>(LICENSES);
301 l.setVisibleRowCount(LICENSES.length);
302 l.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
303 int answer = JOptionPane.showConfirmDialog(
304 Main.parent,
305 new JScrollPane(l),
306 tr("Choose a predefined license"),
307 JOptionPane.OK_CANCEL_OPTION,
308 JOptionPane.QUESTION_MESSAGE
309 );
310 if (answer != JOptionPane.OK_OPTION || l.getSelectedIndex() == -1)
311 return;
312 StringBuilder license = new StringBuilder();
313 for (int i : l.getSelectedIndices()) {
314 if (i == 2) {
315 license = new StringBuilder("public domain");
316 break;
317 }
318 if (license.length() > 0) {
319 license.append(", ");
320 }
321 license.append(URLS[i]);
322 }
323 copyright.setText(license.toString());
324 copyright.setCaretPosition(0);
325 });
326
327 authorActionListener.actionPerformed(null);
328 authorNameListener.keyReleased(null);
329 }
330}
Note: See TracBrowser for help on using the repository browser.