Changeset 32626 in osm for applications/editors/josm/plugins/wikipedia
- Timestamp:
- 2016-07-10T22:57:01+02:00 (9 years ago)
- Location:
- applications/editors/josm/plugins/wikipedia
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikidataItemSearchDialog.java
r32625 r32626 10 10 import java.util.Collections; 11 11 import java.util.List; 12 import java.util.Locale; 12 13 import java.util.concurrent.Executors; 13 14 import java.util.concurrent.TimeUnit; … … 103 104 final List<WikipediaApp.WikidataEntry> entries = query == null || query.isEmpty() 104 105 ? Collections.<WikipediaApp.WikidataEntry>emptyList() 105 : WikipediaApp.getWikidataEntriesForQuery(WikipediaToggleDialog.wikipediaLang.get(), query); 106 : WikipediaApp.getWikidataEntriesForQuery(WikipediaToggleDialog.wikipediaLang.get(), query, Locale.getDefault()); 106 107 GuiHelper.runInEDT(new Runnable() { 107 108 @Override -
applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaApp.java
r32625 r32626 27 27 import javax.xml.xpath.XPathConstants; 28 28 import javax.xml.xpath.XPathExpression; 29 import javax.xml.xpath.XPathExpressionException; 29 30 import javax.xml.xpath.XPathFactory; 30 31 … … 86 87 final Document doc = DOCUMENT_BUILDER.parse(in); 87 88 final NodeList nodes = (NodeList) xpathPlacemark.evaluate(doc, XPathConstants.NODESET); 88 final List<String> names = new ArrayList<>(nodes.getLength());89 89 final List<WikipediaEntry> entries = new ArrayList<>(nodes.getLength()); 90 90 for (int i = 0; i < nodes.getLength(); i++) { 91 91 final Node node = nodes.item(i); 92 92 final String name = xpathName.evaluate(node); 93 names.add(name);94 93 final LatLon latLon = new LatLon(( 95 94 (double) xpathLat.evaluate(node, XPathConstants.NUMBER)), 96 95 (double) xpathLon.evaluate(node, XPathConstants.NUMBER)); 97 96 if ("wikidata".equals(wikipediaLang)) { 98 entries.add(new WikidataEntry(name, null, latLon)); 97 entries.add(new WikidataEntry(name, null, latLon, null)); 99 98 } else { 100 99 entries.add(new WikipediaEntry(wikipediaLang, name, name, latLon … … 103 102 } 104 103 if ("wikidata".equals(wikipediaLang)) { 105 final Map<String, String> labels = new HashMap<>();106 for (final List<String> chunk : partitionList(names, 50)) {107 labels.putAll(getLabelForWikidata(chunk, Locale.getDefault()));108 }109 104 final List<WikipediaEntry> entriesWithLabel = new ArrayList<>(nodes.getLength()); 110 for (WikipediaEntry entry :entries) {111 entriesWithLabel.add (newWikidataEntry(entry.wikipediaArticle, labels.get(entry.wikipediaArticle), entry.coordinate));105 for (final List<WikipediaEntry> chunk : partitionList(entries, 50)) { 106 entriesWithLabel.addAll(getLabelForWikidata(chunk, Locale.getDefault())); 112 107 } 113 108 return entriesWithLabel; … … 121 116 } 122 117 123 static List<WikidataEntry> getWikidataEntriesForQuery(final String language, final String query) { 118 static List<WikidataEntry> getWikidataEntriesForQuery(final String languageForQuery, final String query, final Locale localeForLabels) { 124 119 try { 125 120 final String url = "https://www.wikidata.org/w/api.php" + 126 121 "?action=wbsearchentities" + 127 "&language=" + language + 122 "&language=" + languageForQuery + 128 123 "&strictlanguage=false" + 129 124 "&search=" + Utils.encodeUrl(query) + … … 135 130 final NodeList nodes = (NodeList) X_PATH.compile("//entity").evaluate(xml, XPathConstants.NODESET); 136 131 final XPathExpression xpathId = X_PATH.compile("@id"); 137 final XPathExpression xpathLabel = X_PATH.compile("@label");138 132 for (int i = 0; i < nodes.getLength(); i++) { 139 133 final Node node = nodes.item(i); 140 134 final String id = (String) xpathId.evaluate(node, XPathConstants.STRING); 141 final String label = (String) xpathLabel.evaluate(node, XPathConstants.STRING); 142 r.add(new WikidataEntry(id, label, null)); 143 } 144 } 145 return r; 135 r.add(new WikidataEntry(id, null, null, null)); 136 } 137 } 138 return getLabelForWikidata(r, localeForLabels); 146 139 } catch (Exception ex) { 147 140 throw new RuntimeException(ex); … … 277 270 278 271 static String getLabelForWikidata(String wikidataId, Locale locale, String ... preferredLanguage) { 279 return getLabelForWikidata(Collections.singleton(wikidataId), locale, preferredLanguage).get(wikidataId); 280 } 281 282 static Map<String, String> getLabelForWikidata(Collection<String> wikidataIds, Locale locale, String ... preferredLanguage) { 283 try { 284 for (final String wikidataId : wikidataIds) { 285 ensureValidWikidataId(wikidataId); 286 } 272 try { 273 return getLabelForWikidata(Collections.singleton(new WikidataEntry(wikidataId, null, null, null)), locale, preferredLanguage).get(0).label; 274 } catch (IndexOutOfBoundsException ignore) { 275 return null; 276 } 277 } 278 279 static List<WikidataEntry> getLabelForWikidata(Collection<? extends WikipediaEntry> entries, Locale locale, String ... preferredLanguage) { 280 final Collection<String> wikidataIds = Utils.transform(entries, new Function<WikipediaEntry, String>() { 281 @Override 282 public String apply(WikipediaEntry x) { 283 return x.wikipediaArticle; 284 } 285 }); 286 try { 287 287 final String url = "https://www.wikidata.org/w/api.php" + 288 288 "?action=wbgetentities" + 289 "&props=labels" + 289 "&props=labels|descriptions" + 290 290 "&ids=" + Utils.join("|", wikidataIds) + 291 291 "&format=xml"; … … 298 298 languages.add("en"); 299 299 languages.add(null); 300 final Map<String, String> r = newHashMap<>();300 final List<WikidataEntry> r = new ArrayList<>(entries.size()); 301 301 try (final InputStream in = HttpClient.create(new URL(url)).setReasonForRequest("Wikipedia").connect().getContent()) { 302 302 final Document xml = DOCUMENT_BUILDER.parse(in); 303 for (final String wikidataId : wikidataIds) { 304 final Node entity = (Node) X_PATH.compile("//entity[@id='" + wikidataId + "']").evaluate(xml, XPathConstants.NODE); 305 for (String language : languages) { 306 final String label = (String) X_PATH.compile(language != null 307 ? "./labels/label[@language='" + language + "']/@value" 308 : "./labels/label/@value" 309 ).evaluate(entity, XPathConstants.STRING); 310 if (label != null && !label.isEmpty()) { 311 r.put(wikidataId, label); 312 break; 313 } 314 } 303 for (final WikipediaEntry entry : entries) { 304 final Node entity = (Node) X_PATH.compile("//entity[@id='" + entry.wikipediaArticle + "']").evaluate(xml, XPathConstants.NODE); 305 r.add(new WikidataEntry( 306 entry.wikipediaArticle, 307 getFirstField(languages, "label", entity), 308 entry.coordinate, 309 getFirstField(languages, "description", entity) 310 )); 315 311 } 316 312 } … … 319 315 throw new RuntimeException(ex); 320 316 } 317 } 318 319 private static String getFirstField(Iterable<String> languages, String field, Node entity) throws XPathExpressionException { 320 for (String language : languages) { 321 final String label = (String) X_PATH.compile(language != null 322 ? ".//" + field + "[@language='" + language + "']/@value" 323 : ".//" + field + "/@value" 324 ).evaluate(entity, XPathConstants.STRING); 325 if (label != null && !label.isEmpty()) { 326 return label; 327 } 328 } 329 return null; 321 330 } 322 331 … … 486 495 static class WikidataEntry extends WikipediaEntry { 487 496 488 WikidataEntry(String id, String label, LatLon coordinate) { 497 final String description; 498 499 WikidataEntry(String id, String label, LatLon coordinate, String description) { 489 500 super("wikidata", id, label, coordinate); 501 this.description = description; 490 502 ensureValidWikidataId(id); 491 503 } … … 498 510 @Override 499 511 public String getLabelText() { 500 return getLabelText(label, wikipediaArticle); 512 final String descriptionInParen = description == null ? "" : (" (" + description + ")"); 513 return getLabelText(label, wikipediaArticle + descriptionInParen); 501 514 } 502 515 -
applications/editors/josm/plugins/wikipedia/test/unit/org/wikipedia/WikipediaAppTest.java
r32625 r32626 151 151 @Test 152 152 public void testForQuery() throws Exception { 153 final List<WikipediaApp.WikidataEntry> entries = WikipediaApp.getWikidataEntriesForQuery("de", "Österreich"); 154 assertThat(entries.get(0).wikipediaArticle, is("Q40")); 155 assertThat(entries.get(0).wikipediaLang, is("wikidata")); 156 // assertThat(entries.get(0).label, is("Österreich")); 153 final List<WikipediaApp.WikidataEntry> de = WikipediaApp.getWikidataEntriesForQuery("de", "Österreich", Locale.GERMAN); 154 final List<WikipediaApp.WikidataEntry> en = WikipediaApp.getWikidataEntriesForQuery("de", "Österreich", Locale.ENGLISH); 155 assertThat(de.get(0).wikipediaArticle, is("Q40")); 156 assertThat(de.get(0).wikipediaLang, is("wikidata")); 157 assertThat(de.get(0).label, is("Österreich")); 158 assertThat(de.get(0).description, is("Staat in Mitteleuropa")); 159 assertThat(en.get(0).label, is("Austria")); 160 assertThat(en.get(0).description, is("country in Central Europe")); 157 161 } 158 162 … … 188 192 // not found -> null 189 193 assertThat(WikipediaApp.getLabelForWikidata("Q" + Long.MAX_VALUE, Locale.ENGLISH), nullValue()); 190 final Map<String, String> twoLabels = WikipediaApp.getLabelForWikidata(Arrays.asList("Q84", "Q1741"), Locale.GERMAN); 191 assertThat(twoLabels.get("Q84"), is("London")); 192 assertThat(twoLabels.get("Q1741"), is("Wien")); 194 final WikipediaApp.WikidataEntry q84 = new WikipediaApp.WikidataEntry("Q84", null, null, null); 195 final WikipediaApp.WikidataEntry q1741 = new WikipediaApp.WikidataEntry("Q1741", null, null, null); 196 final List<WikipediaApp.WikidataEntry> twoLabels = WikipediaApp.getLabelForWikidata(Arrays.asList(q84, q1741), Locale.GERMAN); 197 assertThat(twoLabels.get(0).label, is("London")); 198 assertThat(twoLabels.get(1).label, is("Wien")); 193 199 } 194 200
Note:
See TracChangeset
for help on using the changeset viewer.