source: josm/trunk/src/org/openstreetmap/josm/actions/OverpassDownloadAction.java@ 8727

Last change on this file since 8727 was 8727, checked in by Don-vip, 9 years ago

update to Checkstyle 6.10.1

File size: 10.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Component;
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.io.UnsupportedEncodingException;
11import java.net.URLEncoder;
12import java.util.ArrayList;
13import java.util.Arrays;
14import java.util.Collections;
15import java.util.concurrent.Future;
16
17import javax.swing.AbstractAction;
18import javax.swing.JButton;
19import javax.swing.JLabel;
20import javax.swing.JOptionPane;
21import javax.swing.JPanel;
22import javax.swing.JScrollPane;
23
24import org.openstreetmap.josm.Main;
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.DataSource;
29import org.openstreetmap.josm.data.osm.DataSet;
30import org.openstreetmap.josm.data.preferences.CollectionProperty;
31import org.openstreetmap.josm.data.preferences.StringProperty;
32import org.openstreetmap.josm.gui.HelpAwareOptionPane;
33import org.openstreetmap.josm.gui.download.DownloadDialog;
34import org.openstreetmap.josm.gui.progress.ProgressMonitor;
35import org.openstreetmap.josm.gui.util.GuiHelper;
36import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
37import org.openstreetmap.josm.gui.widgets.JosmTextArea;
38import org.openstreetmap.josm.io.BoundingBoxDownloader;
39import org.openstreetmap.josm.io.OsmTransferException;
40import org.openstreetmap.josm.tools.GBC;
41import org.openstreetmap.josm.tools.Shortcut;
42import org.openstreetmap.josm.tools.Utils;
43
44/**
45 * Download map data from Overpass API server.
46 * @since 8684
47 */
48public class OverpassDownloadAction extends JosmAction {
49
50 /**
51 * Constructs a new {@code OverpassDownloadAction}.
52 */
53 public OverpassDownloadAction() {
54 super(tr("Download from Overpass API ..."), "download-overpass", tr("Download map data from Overpass API server."),
55 // CHECKSTYLE.OFF: LineLength
56 Shortcut.registerShortcut("file:download-overpass", tr("File: {0}", tr("Download from Overpass API ...")), KeyEvent.VK_DOWN, Shortcut.ALT_SHIFT),
57 // CHECKSTYLE.ON: LineLength
58 true, "overpassdownload/download", true);
59 putValue("help", ht("/Action/OverpassDownload"));
60 }
61
62 @Override
63 public void actionPerformed(ActionEvent e) {
64 OverpassDownloadDialog dialog = OverpassDownloadDialog.getInstance();
65 dialog.restoreSettings();
66 dialog.setVisible(true);
67 if (!dialog.isCanceled()) {
68 dialog.rememberSettings();
69 Bounds area = dialog.getSelectedDownloadArea();
70 DownloadOsmTask task = new DownloadOsmTask();
71 Future<?> future = task.download(
72 new OverpassDownloadReader(area, dialog.getOverpassServer(), dialog.getOverpassQuery()),
73 dialog.isNewLayerRequired(), area, null);
74 Main.worker.submit(new PostDownloadHandler(task, future));
75 }
76 }
77
78 static final class OverpassDownloadDialog extends DownloadDialog {
79
80 protected HistoryComboBox overpassServer;
81 protected HistoryComboBox overpassWizard;
82 protected JosmTextArea overpassQuery;
83 private static OverpassDownloadDialog instance;
84 static final StringProperty OVERPASS_SERVER = new StringProperty("download.overpass.server", "http://overpass-api.de/api/");
85 static final CollectionProperty OVERPASS_SERVER_HISTORY = new CollectionProperty("download.overpass.servers",
86 Arrays.asList("http://overpass-api.de/api/", "http://overpass.osm.rambler.ru/cgi/"));
87 static final CollectionProperty OVERPASS_WIZARD_HISTORY = new CollectionProperty("download.overpass.wizard", new ArrayList<String>());
88
89 private OverpassDownloadDialog(Component parent) {
90 super(parent, ht("/Action/OverpassDownload"));
91 cbDownloadOsmData.setEnabled(false);
92 cbDownloadOsmData.setSelected(false);
93 cbDownloadGpxData.setVisible(false);
94 cbDownloadNotes.setVisible(false);
95 cbStartup.setVisible(false);
96 }
97
98 public static OverpassDownloadDialog getInstance() {
99 if (instance == null) {
100 instance = new OverpassDownloadDialog(Main.parent);
101 }
102 return instance;
103 }
104
105 @Override
106 protected void buildMainPanelAboveDownloadSelections(JPanel pnl) {
107
108 pnl.add(new JLabel(), GBC.eol()); // needed for the invisible checkboxes cbDownloadGpxData, cbDownloadNotes
109
110 final String tooltip = tr("Builds an Overpass query using the Overpass Turbo query wizard");
111 overpassWizard = new HistoryComboBox();
112 overpassWizard.setToolTipText(tooltip);
113 final JButton buildQuery = new JButton(tr("Build query"));
114 buildQuery.addActionListener(new AbstractAction() {
115 @Override
116 public void actionPerformed(ActionEvent e) {
117 final String overpassWizardText = overpassWizard.getText();
118 try {
119 overpassQuery.setText(OverpassTurboQueryWizard.getInstance().constructQuery(overpassWizardText));
120 } catch (OverpassTurboQueryWizard.ParseException ex) {
121 HelpAwareOptionPane.showOptionDialog(
122 Main.parent,
123 tr("<html>The Overpass wizard could not parse the following query:"
124 + Utils.joinAsHtmlUnorderedList(Collections.singleton(overpassWizardText))),
125 tr("Parse error"),
126 JOptionPane.ERROR_MESSAGE,
127 null
128 );
129 }
130 }
131 });
132 buildQuery.setToolTipText(tooltip);
133 pnl.add(buildQuery, GBC.std().insets(5, 5, 5, 5));
134 pnl.add(overpassWizard, GBC.eol().fill(GBC.HORIZONTAL));
135
136 overpassQuery = new JosmTextArea("[timeout:15];", 8, 80);
137 overpassQuery.setFont(GuiHelper.getMonospacedFont(overpassQuery));
138 JScrollPane scrollPane = new JScrollPane(overpassQuery);
139 pnl.add(new JLabel(tr("Overpass query: ")), GBC.std().insets(5, 5, 5, 5));
140 GBC gbc = GBC.eol().fill(GBC.HORIZONTAL);
141 gbc.ipady = 200;
142 pnl.add(scrollPane, gbc);
143
144 overpassServer = new HistoryComboBox();
145 pnl.add(new JLabel(tr("Overpass server: ")), GBC.std().insets(5, 5, 5, 5));
146 pnl.add(overpassServer, GBC.eol().fill(GBC.HORIZONTAL));
147
148 }
149
150 public String getOverpassServer() {
151 return overpassServer.getText();
152 }
153
154 public String getOverpassQuery() {
155 return overpassQuery.getText();
156 }
157
158 @Override
159 public void restoreSettings() {
160 super.restoreSettings();
161 overpassServer.setPossibleItems(OVERPASS_SERVER_HISTORY.get());
162 overpassServer.setText(OVERPASS_SERVER.get());
163 overpassWizard.setPossibleItems(OVERPASS_WIZARD_HISTORY.get());
164 }
165
166 @Override
167 public void rememberSettings() {
168 super.rememberSettings();
169 overpassWizard.addCurrentItemToHistory();
170 OVERPASS_SERVER.put(getOverpassServer());
171 OVERPASS_SERVER_HISTORY.put(overpassServer.getHistory());
172 OVERPASS_WIZARD_HISTORY.put(overpassWizard.getHistory());
173 }
174
175 }
176
177 static class OverpassDownloadReader extends BoundingBoxDownloader {
178
179 final String overpassServer;
180 final String overpassQuery;
181
182 public OverpassDownloadReader(Bounds downloadArea, String overpassServer, String overpassQuery) {
183 super(downloadArea);
184 this.overpassServer = overpassServer;
185 this.overpassQuery = overpassQuery.trim();
186 }
187
188 @Override
189 protected String getBaseUrl() {
190 return overpassServer;
191 }
192
193 @Override
194 protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
195 if (overpassQuery.isEmpty())
196 return super.getRequestForBbox(lon1, lat1, lon2, lat2);
197 else {
198 String realQuery = completeOverpassQuery(overpassQuery);
199 try {
200 return "interpreter?data=" + URLEncoder.encode(realQuery, "UTF-8")
201 + "&bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
202 } catch (UnsupportedEncodingException e) {
203 throw new IllegalStateException();
204 }
205 }
206 }
207
208 private String completeOverpassQuery(String query) {
209 int firstColon = query.indexOf(";");
210 if (firstColon == -1) {
211 return "[bbox];" + query;
212 }
213 int bboxPos = query.indexOf("[bbox");
214 if (bboxPos > -1 && bboxPos < firstColon) {
215 return query;
216 }
217
218 int bracketCount = 0;
219 int pos = 0;
220 for (; pos < firstColon; ++pos) {
221 if (query.charAt(pos) == '[')
222 ++bracketCount;
223 else if (query.charAt(pos) == '[')
224 --bracketCount;
225 else if (bracketCount == 0) {
226 if (!Character.isWhitespace(query.charAt(pos)))
227 break;
228 }
229 }
230
231 if (pos < firstColon) {
232 // We start with a statement, not with declarations
233 return "[bbox];" + query;
234 }
235
236 // We start with declarations. Add just one more declaration in this case.
237 return "[bbox]" + query;
238 }
239
240 @Override
241 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
242
243 DataSet ds = super.parseOsm(progressMonitor);
244
245 // add bounds if necessary (note that Overpass API does not return bounds in the response XML)
246 if (ds != null && ds.dataSources.isEmpty()) {
247 if (crosses180th) {
248 Bounds bounds = new Bounds(lat1, lon1, lat2, 180.0);
249 DataSource src = new DataSource(bounds, getBaseUrl());
250 ds.dataSources.add(src);
251
252 bounds = new Bounds(lat1, -180.0, lat2, lon2);
253 src = new DataSource(bounds, getBaseUrl());
254 ds.dataSources.add(src);
255 } else {
256 Bounds bounds = new Bounds(lat1, lon1, lat2, lon2);
257 DataSource src = new DataSource(bounds, getBaseUrl());
258 ds.dataSources.add(src);
259 }
260 }
261
262 return ds;
263 }
264 }
265}
Note: See TracBrowser for help on using the repository browser.