Ticket #11975: 0002-Evaluate-extended-Overpass-querty-geocodeArea.patch
File 0002-Evaluate-extended-Overpass-querty-geocodeArea.patch, 8.6 KB (added by , 9 years ago) |
---|
-
src/org/openstreetmap/josm/io/NameFinder.java
From 07c64bddd756f1bbaa36ee80dbf7052b4df4c278 Mon Sep 17 00:00:00 2001 From: Simon Legner <Simon.Legner@gmail.com> Date: Thu, 4 Aug 2016 22:34:12 +0200 Subject: [PATCH 2/2] Evaluate extended Overpass querty `geocodeArea` --- src/org/openstreetmap/josm/io/NameFinder.java | 9 ++++ .../josm/io/OverpassDownloadReader.java | 5 +-- .../josm/tools/OverpassTurboQueryWizard.java | 49 ++++++++++++++++++++++ .../josm/tools/OverpassTurboQueryWizardTest.java | 32 +++++++++++++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/org/openstreetmap/josm/io/NameFinder.java b/src/org/openstreetmap/josm/io/NameFinder.java index c7f9256..6bdb981 100644
a b 13 13 14 14 import org.openstreetmap.josm.Main; 15 15 import org.openstreetmap.josm.data.Bounds; 16 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 17 import org.openstreetmap.josm.data.osm.PrimitiveId; 18 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 16 19 import org.openstreetmap.josm.tools.HttpClient; 17 20 import org.openstreetmap.josm.tools.OsmUrlToBounds; 18 21 import org.openstreetmap.josm.tools.UncheckedParseException; … … private NameFinder() { 65 68 public double lon; 66 69 public int zoom; 67 70 public Bounds bounds; 71 public PrimitiveId osmId; 68 72 69 73 public Bounds getDownloadArea() { 70 74 return bounds != null ? bounds : OsmUrlToBounds.positionToBounds(lat, lon, zoom); … … public void startElement(String namespaceURI, String localName, String qName, At 125 129 currentResult.bounds = new Bounds( 126 130 Double.parseDouble(bbox[0]), Double.parseDouble(bbox[2]), 127 131 Double.parseDouble(bbox[1]), Double.parseDouble(bbox[3])); 132 final String osmId = atts.getValue("osm_id"); 133 final String osmType = atts.getValue("osm_type"); 134 if (osmId != null && osmType != null) { 135 currentResult.osmId = new SimplePrimitiveId(Long.parseLong(osmId), OsmPrimitiveType.from(osmType)); 136 } 128 137 data.add(currentResult); 129 138 } 130 139 } catch (NumberFormatException x) { -
src/org/openstreetmap/josm/io/OverpassDownloadReader.java
diff --git a/src/org/openstreetmap/josm/io/OverpassDownloadReader.java b/src/org/openstreetmap/josm/io/OverpassDownloadReader.java index be43043..cfbb637 100644
a b protected String getRequestForBbox(double lon1, double lat1, double lon2, double 50 50 if (overpassQuery.isEmpty()) 51 51 return super.getRequestForBbox(lon1, lat1, lon2, lat2); 52 52 else { 53 String realQuery = completeOverpassQuery(overpassQuery); 54 return "interpreter?data=" + Utils.encodeUrl(realQuery) 55 + "&bbox=" + lon1 + ',' + lat1 + ',' + lon2 + ',' + lat2; 53 return "interpreter?data=" + Utils.encodeUrl(overpassQuery) 54 + (!overpassQuery.contains("searchArea") ? "&bbox=" + lon1 + ',' + lat1 + ',' + lon2 + ',' + lat2 : ""); 56 55 } 57 56 } 58 57 -
src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java
diff --git a/src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java b/src/org/openstreetmap/josm/tools/OverpassTurboQueryWizard.java index f0020d9..555a525 100644
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.tools; 3 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 4 6 import java.io.IOException; 5 7 import java.io.Reader; 8 import java.util.EnumMap; 9 import java.util.List; 10 import java.util.regex.Matcher; 11 import java.util.regex.Pattern; 6 12 7 13 import javax.script.Invocable; 8 14 import javax.script.ScriptEngine; … … 10 16 import javax.script.ScriptException; 11 17 12 18 import org.openstreetmap.josm.Main; 19 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 20 import org.openstreetmap.josm.data.osm.PrimitiveId; 13 21 import org.openstreetmap.josm.io.CachedFile; 22 import org.openstreetmap.josm.io.NameFinder; 14 23 15 24 /** 16 25 * Uses <a href="https://github.com/tyrasd/overpass-wizard/">Overpass Turbo query wizard</a> code (MIT Licensed) … … public String constructQuery(String search) { 70 79 String query = (String) result; 71 80 if (query != null) { 72 81 query = query.replace("[bbox:{{bbox}}]", ""); 82 query = expandExtendedQueries(query); 73 83 } 74 84 return query; 75 85 } catch (NoSuchMethodException e) { … … public String constructQuery(String search) { 78 88 throw new UncheckedParseException("Failed to execute OverpassTurboQueryWizard", e); 79 89 } 80 90 } 91 92 /** 93 * Evaluates some features of overpass turbo extended query syntax. 94 * See https://wiki.openstreetmap.org/wiki/Overpass_turbo/Extended_Overpass_Turbo_Queries 95 */ 96 static String expandExtendedQueries(String query) { 97 final StringBuffer sb = new StringBuffer(); 98 final Matcher matcher = Pattern.compile("\\{\\{(geocodeArea):([^}]+)\\}\\}").matcher(query); 99 while (matcher.find()) { 100 try { 101 switch (matcher.group(1)) { 102 case "geocodeArea": 103 matcher.appendReplacement(sb, geocodeArea(matcher.group(2))); 104 } 105 } catch (Exception ex) { 106 final String msg = tr("Failed to evaluate {0}", matcher.group()); 107 Main.warn(ex, msg); 108 matcher.appendReplacement(sb, "// " + msg + "\n"); 109 } 110 } 111 matcher.appendTail(sb); 112 query = sb.toString(); 113 return query; 114 } 115 116 private static String geocodeArea(String area) { 117 // Offsets defined in https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#By_element_id 118 final EnumMap<OsmPrimitiveType, Long> idOffset = new EnumMap<>(OsmPrimitiveType.class); 119 idOffset.put(OsmPrimitiveType.NODE, 0L); 120 idOffset.put(OsmPrimitiveType.WAY, 2400000000L); 121 idOffset.put(OsmPrimitiveType.RELATION, 3600000000L); 122 try { 123 final List<NameFinder.SearchResult> results = NameFinder.queryNominatim(area); 124 final PrimitiveId osmId = results.iterator().next().osmId; 125 return String.format("area(%d)", osmId.getUniqueId() + idOffset.get(osmId.getType())); 126 } catch (IOException ex) { 127 throw new UncheckedParseException(ex); 128 } 129 } 81 130 } -
test/unit/org/openstreetmap/josm/tools/OverpassTurboQueryWizardTest.java
diff --git a/test/unit/org/openstreetmap/josm/tools/OverpassTurboQueryWizardTest.java b/test/unit/org/openstreetmap/josm/tools/OverpassTurboQueryWizardTest.java index 125042f..2a7226f 100644
a b 14 14 */ 15 15 public class OverpassTurboQueryWizardTest { 16 16 /** 17 * Base test environment is enough17 * Some of this depends on preferences. 18 18 */ 19 19 @Rule 20 20 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 21 public JOSMTestRules test = new JOSMTestRules() ;21 public JOSMTestRules test = new JOSMTestRules().preferences(); 22 22 23 23 /** 24 24 * Test key=value. … … public void testKeyValue() { 38 38 } 39 39 40 40 /** 41 * Tests evaluating the extended query feature {@code geocodeArea}. 42 */ 43 @Test 44 public void testGeocodeArea() { 45 final String query = OverpassTurboQueryWizard.getInstance().constructQuery("amenity=drinking_water in London"); 46 assertEquals("" + 47 "[out:xml][timeout:25];\n" + 48 "area(3600065606)->.searchArea;\n" + 49 "(\n" + 50 " node[\"amenity\"=\"drinking_water\"](area.searchArea);\n" + 51 " way[\"amenity\"=\"drinking_water\"](area.searchArea);\n" + 52 " relation[\"amenity\"=\"drinking_water\"](area.searchArea);\n" + 53 ");\n" + 54 "(._;>;);\n" + 55 "out meta;", query); 56 } 57 58 /** 59 * Tests evaluating the extended query feature {@code geocodeArea}. 60 */ 61 @Test 62 public void testGeocodeUnknownArea() { 63 final String query = OverpassTurboQueryWizard.expandExtendedQueries("{{geocodeArea:foo-bar-baz-does-not-exist}}"); 64 assertEquals("// Failed to evaluate {{geocodeArea:foo-bar-baz-does-not-exist}}\n", query); 65 66 } 67 68 /** 41 69 * Test erroneous value. 42 70 */ 43 71 @Test(expected = UncheckedParseException.class)