Ticket #6386: IdNumberSelection.2.java

File IdNumberSelection.2.java, 6.2 KB (added by brycenesbitt, 15 years ago)

Expanded version. Still needs work: turns out to be tricker than anticipated. Ways returned from the OSM API 0.6 don't include a bounding box. One apparently needs to load every single node and calculate the extents. It may make this entire proposed feature unworkable.

Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.gui.download;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9import java.awt.event.FocusAdapter;
10import java.awt.event.FocusEvent;
11import java.awt.event.KeyEvent;
12import java.io.IOException;
13import java.util.logging.Logger;
14
15import javax.swing.ButtonGroup;
16import javax.swing.JLabel;
17import javax.swing.JPanel;
18import javax.swing.JRadioButton;
19import javax.swing.JTextField;
20import javax.xml.parsers.DocumentBuilder;
21import javax.xml.parsers.DocumentBuilderFactory;
22import javax.xml.parsers.ParserConfigurationException;
23
24import org.openstreetmap.josm.data.Bounds;
25import org.openstreetmap.josm.tools.GBC;
26import org.w3c.dom.Document;
27import org.w3c.dom.NamedNodeMap;
28import org.w3c.dom.Node;
29import org.xml.sax.SAXException;
30/**
31 * ID Number Selector
32 *
33 * Input method for the "Download from OSM" dialog box. Given an OSM element ID number,
34 * it finds the center point and loads small additional area on each side.
35 * Very handy if you've found a problem element in an XML or database dump.
36 *
37 * Example: enter node id 1, to see the first node ever added to OSM
38 *
39 * TODO: finish support for relations / changesets
40 * TODO: offer radius in meters, not degrees
41 *
42 * @author Bryce Nesbitt, April 2011
43 *
44 */
45public class IdNumberSelection implements DownloadSelection {
46 private static final Logger logger = Logger.getLogger(IdNumberSelection.class.getName());
47
48 private DownloadDialog parent;
49 private JTextField osmid = new JTextField(21);
50 private JTextField osmradius = new JTextField(".001",6);
51
52 private JRadioButton radioChangeset = new JRadioButton(tr("Changeset"));
53 private JRadioButton radioRelation = new JRadioButton(tr("Relation"));
54 private JRadioButton radioNode = new JRadioButton(tr("Node"));
55 private JRadioButton radioWay = new JRadioButton(tr("Way"));
56
57 private String lasturl = "";
58 private double lastradius = 0;
59
60 public void addGui(final DownloadDialog gui) {
61 BoundingBoxBuilder bboxbuilder = new BoundingBoxBuilder();
62 osmid.addFocusListener (bboxbuilder);
63 osmid.addActionListener(bboxbuilder);
64 osmradius.addFocusListener (bboxbuilder);
65 osmradius.addActionListener(bboxbuilder);
66 radioRelation.addActionListener(bboxbuilder);
67 radioNode.addActionListener(bboxbuilder);
68 radioWay.addActionListener(bboxbuilder);
69 radioRelation.setMnemonic(KeyEvent.VK_R);
70 radioNode.setMnemonic(KeyEvent.VK_N);
71 radioWay.setMnemonic(KeyEvent.VK_W);
72
73 ButtonGroup radioGroup = new ButtonGroup();
74 radioGroup.add(radioWay);
75 radioGroup.add(radioNode);
76 radioGroup.add(radioRelation);
77 radioRelation.setEnabled(false);
78 radioNode.setEnabled(true);
79 radioWay.setEnabled(false);
80
81 radioNode.setSelected(true);
82
83 final JPanel dlg = new JPanel(new GridBagLayout());
84 dlg.add(new JLabel(tr("Within")), GBC.std().insets(10,20,5,0));
85 dlg.add(osmradius, GBC.std().insets(0,20,0,0));
86 dlg.add(new JLabel(tr("degrees of")), GBC.std().insets(10,20,5,0));
87 dlg.add(radioNode, GBC.std().insets(0,20,0,0));
88 dlg.add(radioWay, GBC.std().insets(0,20,0,0));
89 dlg.add(radioRelation, GBC.std().insets(0,20,0,0));
90 dlg.add(new JLabel(tr("number")), GBC.std().insets(10,20,5,0));
91 dlg.add(osmid, GBC.std().insets(0,20,0,0));
92
93 gui.addDownloadAreaSelector(dlg, tr("ID"));
94 parent = gui;
95 }
96
97 public void setDownloadArea(Bounds area) {
98 }
99
100 class BoundingBoxBuilder extends FocusAdapter implements ActionListener {
101
102 protected void refreshBounds() {
103 double mylon=0,mylat=0,radius=0;
104 String url;
105
106 // Process text input fields
107 // Extract the OSM element ID and radius to use as a center point
108 // for the download.
109 int id;
110 try {
111 id = Integer.parseInt(osmid.getText().trim());
112 radius = Double.parseDouble(osmradius.getText().trim());
113 } catch (NumberFormatException e1) {
114 Bounds b = new Bounds(0,0,0,0);
115 parent.boundingBoxChanged(b, IdNumberSelection.this);
116 return;
117 }
118
119 // Build URL based on object type to look up.
120 if (radioRelation.isSelected()) {
121 url = "http://api.openstreetmap.org/api/0.6/relation/"+id;
122 } else if(radioNode.isSelected()) {
123 url = "http://api.openstreetmap.org/api/0.6/node/"+id;
124 } else {
125 url = "http://api.openstreetmap.org/api/0.6/way/"+id;
126 }
127
128 // Don't requery the API each time a tab is clicked
129 if( url == lasturl && lastradius == radius )
130 return;
131 lasturl = url;
132 lastradius = radius;
133
134 // Use the DOM to load an element from the API, and parse out the lat/lon.
135 try {
136 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
137 DocumentBuilder db = dbf.newDocumentBuilder();
138 logger.info(url);
139 Document doc = db.parse(url);
140 Node node = doc.getElementsByTagName("node").item(0);
141 NamedNodeMap nmap = node.getAttributes();
142 mylat = Double.parseDouble(nmap.getNamedItem("lat").getNodeValue());
143 mylon = Double.parseDouble(nmap.getNamedItem("lon").getNodeValue());
144 } catch (ParserConfigurationException e) {
145 e.printStackTrace();
146 } catch (SAXException e) {
147 e.printStackTrace();
148 } catch (IOException e) {
149 mylat = mylon = 0;
150 }
151
152 Bounds b = new Bounds(mylat-radius,mylon-radius,mylat+radius,mylon+radius);
153 parent.boundingBoxChanged(b, IdNumberSelection.this);
154 }
155 @Override
156 public void focusLost(FocusEvent e) {
157 refreshBounds();
158 }
159 public void actionPerformed(ActionEvent e) {
160 refreshBounds();
161 }
162 }
163}
164