| 1 | // License: GPL. See LICENSE file for details.
|
|---|
| 2 | package org.openstreetmap.josm.gui.download;
|
|---|
| 3 |
|
|---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
|---|
| 5 |
|
|---|
| 6 | import java.awt.GridBagLayout;
|
|---|
| 7 | import java.awt.event.ActionEvent;
|
|---|
| 8 | import java.awt.event.ActionListener;
|
|---|
| 9 | import java.awt.event.FocusAdapter;
|
|---|
| 10 | import java.awt.event.FocusEvent;
|
|---|
| 11 | import java.awt.event.KeyEvent;
|
|---|
| 12 | import java.io.IOException;
|
|---|
| 13 | import java.util.logging.Logger;
|
|---|
| 14 |
|
|---|
| 15 | import javax.swing.ButtonGroup;
|
|---|
| 16 | import javax.swing.JLabel;
|
|---|
| 17 | import javax.swing.JPanel;
|
|---|
| 18 | import javax.swing.JRadioButton;
|
|---|
| 19 | import javax.swing.JTextField;
|
|---|
| 20 | import javax.xml.parsers.DocumentBuilder;
|
|---|
| 21 | import javax.xml.parsers.DocumentBuilderFactory;
|
|---|
| 22 | import javax.xml.parsers.ParserConfigurationException;
|
|---|
| 23 |
|
|---|
| 24 | import org.openstreetmap.josm.data.Bounds;
|
|---|
| 25 | import org.openstreetmap.josm.tools.GBC;
|
|---|
| 26 | import org.w3c.dom.Document;
|
|---|
| 27 | import org.w3c.dom.NamedNodeMap;
|
|---|
| 28 | import org.w3c.dom.Node;
|
|---|
| 29 | import 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 | */
|
|---|
| 45 | public 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 |
|
|---|