source: josm/trunk/src/org/openstreetmap/josm/gui/download/OSMDownloadSource.java@ 12706

Last change on this file since 12706 was 12706, checked in by michael2402, 7 years ago

See #15167: Store the name of the current selected tab.

This also makes the expert mode tab selection more universal

File size: 13.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.download;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Color;
7import java.awt.Dimension;
8import java.awt.Font;
9import java.awt.GridBagLayout;
10import java.util.ArrayList;
11import java.util.List;
12import java.util.concurrent.ExecutionException;
13import java.util.concurrent.Future;
14
15import javax.swing.Icon;
16import javax.swing.JCheckBox;
17import javax.swing.JLabel;
18import javax.swing.JOptionPane;
19import javax.swing.event.ChangeListener;
20
21import org.openstreetmap.josm.Main;
22import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask;
23import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
24import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
25import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
26import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
27import org.openstreetmap.josm.data.Bounds;
28import org.openstreetmap.josm.data.ProjectionBounds;
29import org.openstreetmap.josm.data.ViewportData;
30import org.openstreetmap.josm.data.preferences.BooleanProperty;
31import org.openstreetmap.josm.gui.MainApplication;
32import org.openstreetmap.josm.gui.MapFrame;
33import org.openstreetmap.josm.gui.util.GuiHelper;
34import org.openstreetmap.josm.tools.GBC;
35import org.openstreetmap.josm.tools.ImageProvider;
36import org.openstreetmap.josm.tools.Logging;
37import org.openstreetmap.josm.tools.Pair;
38
39/**
40 * Class defines the way data is fetched from the OSM server.
41 * @since 12652
42 */
43public class OSMDownloadSource implements DownloadSource<OSMDownloadSource.OSMDownloadData> {
44 /**
45 * The simple name for the {@link OSMDownloadSourcePanel}
46 * @since 12706
47 */
48 public static final String SIMPLE_NAME = "osmdownloadpanel";
49
50 @Override
51 public AbstractDownloadSourcePanel<OSMDownloadData> createPanel() {
52 return new OSMDownloadSourcePanel(this);
53 }
54
55 @Override
56 public void doDownload(OSMDownloadData data, DownloadSettings settings) {
57 Bounds bbox = settings.getDownloadBounds()
58 .orElseThrow(() -> new IllegalArgumentException("OSM downloads requires bounds"));
59 boolean zoom = settings.zoomToData();
60 boolean newLayer = settings.asNewLayer();
61 List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
62
63 if (data.isDownloadOSMData()) {
64 DownloadOsmTask task = new DownloadOsmTask();
65 task.setZoomAfterDownload(zoom && !data.isDownloadGPX() && !data.isDownloadNotes());
66 Future<?> future = task.download(newLayer, bbox, null);
67 MainApplication.worker.submit(new PostDownloadHandler(task, future));
68 if (zoom) {
69 tasks.add(new Pair<>(task, future));
70 }
71 }
72
73 if (data.isDownloadGPX()) {
74 DownloadGpsTask task = new DownloadGpsTask();
75 task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadNotes());
76 Future<?> future = task.download(newLayer, bbox, null);
77 MainApplication.worker.submit(new PostDownloadHandler(task, future));
78 if (zoom) {
79 tasks.add(new Pair<>(task, future));
80 }
81 }
82
83 if (data.isDownloadNotes()) {
84 DownloadNotesTask task = new DownloadNotesTask();
85 task.setZoomAfterDownload(zoom && !data.isDownloadOSMData() && !data.isDownloadGPX());
86 Future<?> future = task.download(false, bbox, null);
87 MainApplication.worker.submit(new PostDownloadHandler(task, future));
88 if (zoom) {
89 tasks.add(new Pair<>(task, future));
90 }
91 }
92
93 if (zoom && tasks.size() > 1) {
94 MainApplication.worker.submit(() -> {
95 ProjectionBounds bounds = null;
96 // Wait for completion of download jobs
97 for (Pair<AbstractDownloadTask<?>, Future<?>> p : tasks) {
98 try {
99 p.b.get();
100 ProjectionBounds b = p.a.getDownloadProjectionBounds();
101 if (bounds == null) {
102 bounds = b;
103 } else if (b != null) {
104 bounds.extend(b);
105 }
106 } catch (InterruptedException | ExecutionException ex) {
107 Logging.warn(ex);
108 }
109 }
110 MapFrame map = MainApplication.getMap();
111 // Zoom to the larger download bounds
112 if (map != null && bounds != null) {
113 final ProjectionBounds pb = bounds;
114 GuiHelper.runInEDTAndWait(() -> map.mapView.zoomTo(new ViewportData(pb)));
115 }
116 });
117 }
118 }
119
120 @Override
121 public String getLabel() {
122 return tr("Download from OSM");
123 }
124
125 @Override
126 public boolean onlyExpert() {
127 return false;
128 }
129
130 /**
131 * The GUI representation of the OSM download source.
132 * @since 12652
133 */
134 public static class OSMDownloadSourcePanel extends AbstractDownloadSourcePanel<OSMDownloadData> {
135
136 private final JCheckBox cbDownloadOsmData;
137 private final JCheckBox cbDownloadGpxData;
138 private final JCheckBox cbDownloadNotes;
139 private final JLabel sizeCheck = new JLabel();
140
141 private static final BooleanProperty DOWNLOAD_OSM = new BooleanProperty("download.osm.data", true);
142 private static final BooleanProperty DOWNLOAD_GPS = new BooleanProperty("download.osm.gps", false);
143 private static final BooleanProperty DOWNLOAD_NOTES = new BooleanProperty("download.osm.notes", false);
144
145 /**
146 * Creates a new {@link OSMDownloadSourcePanel}.
147 * @param ds The osm download source the panel is for.
148 */
149 public OSMDownloadSourcePanel(OSMDownloadSource ds) {
150 super(ds);
151 setLayout(new GridBagLayout());
152
153 // size check depends on selected data source
154 final ChangeListener checkboxChangeListener = e ->
155 DownloadDialog.getInstance().getSelectedDownloadArea().ifPresent(this::updateSizeCheck);
156
157 // adding the download tasks
158 add(new JLabel(tr("Data Sources and Types:")), GBC.std().insets(5, 5, 1, 5).anchor(GBC.CENTER));
159 cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
160 cbDownloadOsmData.setToolTipText(tr("Select to download OSM data in the selected download area."));
161 cbDownloadOsmData.getModel().addChangeListener(checkboxChangeListener);
162
163 cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
164 cbDownloadGpxData.setToolTipText(tr("Select to download GPS traces in the selected download area."));
165 cbDownloadGpxData.getModel().addChangeListener(checkboxChangeListener);
166
167 cbDownloadNotes = new JCheckBox(tr("Notes"));
168 cbDownloadNotes.setToolTipText(tr("Select to download notes in the selected download area."));
169 cbDownloadNotes.getModel().addChangeListener(checkboxChangeListener);
170
171 Font labelFont = sizeCheck.getFont();
172 sizeCheck.setFont(labelFont.deriveFont(Font.PLAIN, labelFont.getSize()));
173
174 add(cbDownloadOsmData, GBC.std().insets(1, 5, 1, 5));
175 add(cbDownloadGpxData, GBC.std().insets(1, 5, 1, 5));
176 add(cbDownloadNotes, GBC.eol().insets(1, 5, 1, 5));
177 add(sizeCheck, GBC.eol().anchor(GBC.EAST).insets(5, 5, 5, 2));
178
179 setMinimumSize(new Dimension(450, 115));
180 }
181
182 @Override
183 public OSMDownloadData getData() {
184 return new OSMDownloadData(
185 isDownloadOsmData(),
186 isDownloadNotes(),
187 isDownloadGpxData());
188 }
189
190 @Override
191 public void rememberSettings() {
192 DOWNLOAD_OSM.put(isDownloadOsmData());
193 DOWNLOAD_GPS.put(isDownloadGpxData());
194 DOWNLOAD_NOTES.put(isDownloadNotes());
195 }
196
197 @Override
198 public void restoreSettings() {
199 cbDownloadOsmData.setSelected(DOWNLOAD_OSM.get());
200 cbDownloadGpxData.setSelected(DOWNLOAD_GPS.get());
201 cbDownloadNotes.setSelected(DOWNLOAD_NOTES.get());
202 }
203
204 @Override
205 public boolean checkDownload(DownloadSettings settings) {
206 /*
207 * It is mandatory to specify the area to download from OSM.
208 */
209 if (!settings.getDownloadBounds().isPresent()) {
210 JOptionPane.showMessageDialog(
211 this.getParent(),
212 tr("Please select a download area first."),
213 tr("Error"),
214 JOptionPane.ERROR_MESSAGE
215 );
216
217 return false;
218 }
219
220 /*
221 * Checks if the user selected the type of data to download. At least one the following
222 * must be chosen : raw osm data, gpx data, notes.
223 * If none of those are selected, then the corresponding dialog is shown to inform the user.
224 */
225 if (!isDownloadOsmData() && !isDownloadGpxData() && !isDownloadNotes()) {
226 JOptionPane.showMessageDialog(
227 this.getParent(),
228 tr("<html>Neither <strong>{0}</strong> nor <strong>{1}</strong> nor <strong>{2}</strong> is enabled.<br>"
229 + "Please choose to either download OSM data, or GPX data, or Notes, or all.</html>",
230 cbDownloadOsmData.getText(),
231 cbDownloadGpxData.getText(),
232 cbDownloadNotes.getText()
233 ),
234 tr("Error"),
235 JOptionPane.ERROR_MESSAGE
236 );
237
238 return false;
239 }
240
241 this.rememberSettings();
242
243 return true;
244 }
245
246 /**
247 * Replies true if the user selected to download OSM data
248 *
249 * @return true if the user selected to download OSM data
250 */
251 public boolean isDownloadOsmData() {
252 return cbDownloadOsmData.isSelected();
253 }
254
255 /**
256 * Replies true if the user selected to download GPX data
257 *
258 * @return true if the user selected to download GPX data
259 */
260 public boolean isDownloadGpxData() {
261 return cbDownloadGpxData.isSelected();
262 }
263
264 /**
265 * Replies true if user selected to download notes
266 *
267 * @return true if user selected to download notes
268 */
269 public boolean isDownloadNotes() {
270 return cbDownloadNotes.isSelected();
271 }
272
273 @Override
274 public Icon getIcon() {
275 return ImageProvider.get("download");
276 }
277
278 @Override
279 public void boudingBoxChanged(Bounds bbox) {
280 updateSizeCheck(bbox);
281 }
282
283 @Override
284 public String getSimpleName() {
285 return SIMPLE_NAME;
286 }
287
288 private void updateSizeCheck(Bounds bbox) {
289 if (bbox == null) {
290 sizeCheck.setText(tr("No area selected yet"));
291 sizeCheck.setForeground(Color.darkGray);
292 return;
293 }
294
295 boolean isAreaTooLarge = false;
296 if (!isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
297 isAreaTooLarge = false;
298 } else if (isDownloadNotes() && !isDownloadOsmData() && !isDownloadGpxData()) {
299 // see max_note_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
300 isAreaTooLarge = bbox.getArea() > Main.pref.getDouble("osm-server.max-request-area-notes", 25);
301 } else {
302 // see max_request_area in https://github.com/openstreetmap/openstreetmap-website/blob/master/config/example.application.yml
303 isAreaTooLarge = bbox.getArea() > Main.pref.getDouble("osm-server.max-request-area", 0.25);
304 }
305
306 displaySizeCheckResult(isAreaTooLarge);
307 }
308
309 private void displaySizeCheckResult(boolean isAreaTooLarge) {
310 if (isAreaTooLarge) {
311 sizeCheck.setText(tr("Download area too large; will probably be rejected by server"));
312 sizeCheck.setForeground(Color.red);
313 } else {
314 sizeCheck.setText(tr("Download area ok, size probably acceptable to server"));
315 sizeCheck.setForeground(Color.darkGray);
316 }
317 }
318
319 }
320
321 /**
322 * Encapsulates data that is required to download from the OSM server.
323 */
324 static class OSMDownloadData {
325 private final boolean downloadOSMData;
326 private final boolean downloadNotes;
327 private final boolean downloadGPX;
328
329 OSMDownloadData(boolean downloadOSMData, boolean downloadNotes, boolean downloadGPX) {
330 this.downloadOSMData = downloadOSMData;
331 this.downloadNotes = downloadNotes;
332 this.downloadGPX = downloadGPX;
333 }
334
335 boolean isDownloadOSMData() {
336 return downloadOSMData;
337 }
338
339 boolean isDownloadNotes() {
340 return downloadNotes;
341 }
342
343 boolean isDownloadGPX() {
344 return downloadGPX;
345 }
346 }
347}
Note: See TracBrowser for help on using the repository browser.