Changeset 11002 in josm for trunk/src


Ignore:
Timestamp:
2016-09-15T21:39:04+02:00 (8 years ago)
Author:
simon04
Message:

see #11975 - Extract NameFinder for Nominatim queries

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java

    r10611 r11002  
    5151import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
    5252import org.openstreetmap.josm.gui.widgets.JosmComboBox;
     53import org.openstreetmap.josm.io.NameFinder;
     54import org.openstreetmap.josm.io.NameFinder.SearchResult;
    5355import org.openstreetmap.josm.io.OsmTransferException;
    5456import org.openstreetmap.josm.tools.GBC;
    5557import org.openstreetmap.josm.tools.HttpClient;
    5658import org.openstreetmap.josm.tools.ImageProvider;
    57 import org.openstreetmap.josm.tools.OsmUrlToBounds;
    5859import org.openstreetmap.josm.tools.Utils;
    59 import org.xml.sax.Attributes;
    60 import org.xml.sax.InputSource;
    6160import org.xml.sax.SAXException;
    6261import org.xml.sax.SAXParseException;
    63 import org.xml.sax.helpers.DefaultHandler;
    6462
    6563/**
     
    7674    private DownloadDialog parent;
    7775    private static final Server[] SERVERS = new Server[] {
    78         new Server("Nominatim", "https://nominatim.openstreetmap.org/search?format=xml&q=", tr("Class Type"), tr("Bounds"))
     76        new Server("Nominatim", NameFinder.NOMINATIM_URL, tr("Class Type"), tr("Bounds"))
    7977    };
    8078    private final JosmComboBox<Server> server = new JosmComboBox<>(SERVERS);
     
    175173    }
    176174
    177     /**
    178      * Data storage for search results.
    179      */
    180     private static class SearchResult {
    181         public String name;
    182         public String info;
    183         public String nearestPlace;
    184         public String description;
    185         public double lat;
    186         public double lon;
    187         public int zoom;
    188         public Bounds bounds;
    189 
    190         public Bounds getDownloadArea() {
    191             return bounds != null ? bounds : OsmUrlToBounds.positionToBounds(lat, lon, zoom);
    192         }
    193     }
    194 
    195     /**
    196      * A very primitive parser for the name finder's output.
    197      * Structure of xml described here:  http://wiki.openstreetmap.org/index.php/Name_finder
    198      *
    199      */
    200     private static class NameFinderResultParser extends DefaultHandler {
    201         private SearchResult currentResult;
    202         private StringBuilder description;
    203         private int depth;
    204         private final List<SearchResult> data = new LinkedList<>();
    205 
    206         /**
    207          * Detect starting elements.
    208          *
    209          */
    210         @Override
    211         public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
    212         throws SAXException {
    213             depth++;
    214             try {
    215                 if ("searchresults".equals(qName)) {
    216                     // do nothing
    217                 } else if ("named".equals(qName) && (depth == 2)) {
    218                     currentResult = new PlaceSelection.SearchResult();
    219                     currentResult.name = atts.getValue("name");
    220                     currentResult.info = atts.getValue("info");
    221                     if (currentResult.info != null) {
    222                         currentResult.info = tr(currentResult.info);
    223                     }
    224                     currentResult.lat = Double.parseDouble(atts.getValue("lat"));
    225                     currentResult.lon = Double.parseDouble(atts.getValue("lon"));
    226                     currentResult.zoom = Integer.parseInt(atts.getValue("zoom"));
    227                     data.add(currentResult);
    228                 } else if ("description".equals(qName) && (depth == 3)) {
    229                     description = new StringBuilder();
    230                 } else if ("named".equals(qName) && (depth == 4)) {
    231                     // this is a "named" place in the nearest places list.
    232                     String info = atts.getValue("info");
    233                     if ("city".equals(info) || "town".equals(info) || "village".equals(info)) {
    234                         currentResult.nearestPlace = atts.getValue("name");
    235                     }
    236                 } else if ("place".equals(qName) && atts.getValue("lat") != null) {
    237                     currentResult = new PlaceSelection.SearchResult();
    238                     currentResult.name = atts.getValue("display_name");
    239                     currentResult.description = currentResult.name;
    240                     currentResult.info = atts.getValue("class");
    241                     if (currentResult.info != null) {
    242                         currentResult.info = tr(currentResult.info);
    243                     }
    244                     currentResult.nearestPlace = tr(atts.getValue("type"));
    245                     currentResult.lat = Double.parseDouble(atts.getValue("lat"));
    246                     currentResult.lon = Double.parseDouble(atts.getValue("lon"));
    247                     String[] bbox = atts.getValue("boundingbox").split(",");
    248                     currentResult.bounds = new Bounds(
    249                             Double.parseDouble(bbox[0]), Double.parseDouble(bbox[2]),
    250                             Double.parseDouble(bbox[1]), Double.parseDouble(bbox[3]));
    251                     data.add(currentResult);
    252                 }
    253             } catch (NumberFormatException x) {
    254                 Main.error(x); // SAXException does not chain correctly
    255                 throw new SAXException(x.getMessage(), x);
    256             } catch (NullPointerException x) {
    257                 Main.error(x); // SAXException does not chain correctly
    258                 throw new SAXException(tr("Null pointer exception, possibly some missing tags."), x);
    259             }
    260         }
    261 
    262         /**
    263          * Detect ending elements.
    264          */
    265         @Override
    266         public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
    267             if ("description".equals(qName) && description != null) {
    268                 currentResult.description = description.toString();
    269                 description = null;
    270             }
    271             depth--;
    272         }
    273 
    274         /**
    275          * Read characters for description.
    276          */
    277         @Override
    278         public void characters(char[] data, int start, int length) throws SAXException {
    279             if (description != null) {
    280                 description.append(data, start, length);
    281             }
    282         }
    283 
    284         public List<SearchResult> getResult() {
    285             return data;
    286         }
    287     }
    288 
    289175    class SearchAction extends AbstractAction implements DocumentListener {
    290176
     
    376262                }
    377263                try (Reader reader = connection.getResponse().getContentReader()) {
    378                     InputSource inputSource = new InputSource(reader);
    379                     NameFinderResultParser parser = new NameFinderResultParser();
    380                     Utils.parseSafeSAX(inputSource, parser);
    381                     this.data = parser.getResult();
     264                    data = NameFinder.parseSearchResults(reader);
    382265                }
    383266            } catch (SAXParseException e) {
Note: See TracChangeset for help on using the changeset viewer.