Changeset 28485 in osm for applications/editors/josm


Ignore:
Timestamp:
2012-07-14T10:53:58+02:00 (12 years ago)
Author:
simon04
Message:

JOSM/wikipedia: refactoring

Location:
applications/editors/josm/plugins/wikipedia/src/org/wikipedia
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/wikipedia/src/org/wikipedia/WikipediaToggleDialog.java

    r28483 r28485  
    77import java.awt.event.MouseAdapter;
    88import java.awt.event.MouseEvent;
    9 import java.io.IOException;
    10 import java.io.UnsupportedEncodingException;
    11 import java.net.URL;
    12 import java.net.URLDecoder;
    13 import java.net.URLEncoder;
    14 import java.util.ArrayList;
    159import java.util.Arrays;
    16 import java.util.Collection;
    1710import java.util.Collections;
    18 import java.util.HashMap;
    1911import java.util.HashSet;
    2012import java.util.List;
    21 import java.util.Map;
    22 import java.util.Scanner;
    2313import java.util.Set;
    24 import java.util.regex.Matcher;
    25 import java.util.regex.Pattern;
    2614import javax.swing.AbstractAction;
    2715import javax.swing.DefaultListCellRenderer;
     
    3018import javax.swing.JList;
    3119import javax.swing.JOptionPane;
    32 import javax.xml.parsers.DocumentBuilderFactory;
    33 import javax.xml.xpath.XPathConstants;
    34 import javax.xml.xpath.XPathExpression;
    35 import javax.xml.xpath.XPathFactory;
    3620import org.openstreetmap.josm.Main;
    3721import org.openstreetmap.josm.actions.search.SearchAction;
     
    5337import org.openstreetmap.josm.tools.LanguageInfo;
    5438import org.openstreetmap.josm.tools.OpenBrowser;
    55 import org.openstreetmap.josm.tools.Utils;
    56 import org.w3c.dom.Document;
    57 import org.w3c.dom.NodeList;
     39import org.wikipedia.WikipediaApp.WikipediaEntry;
    5840
    5941public class WikipediaToggleDialog extends ToggleDialog implements MapView.EditLayerChangeListener, DataSetListenerAdapter.Listener {
     
    11597    };
    11698
    117     static class WikipediaLangArticle {
    118 
    119         final String lang, article;
    120 
    121         public WikipediaLangArticle(String lang, String article) {
    122             this.lang = lang;
    123             this.article = article;
    124         }
    125 
    126         public static WikipediaLangArticle parseFromUrl(String url) {
    127             if (url == null) {
    128                 return null;
    129             }
    130             // decode URL for nicer value
    131             url = decodeURL(url);
    132             // extract Wikipedia language and
    133             final Matcher m = Pattern.compile("https?://(\\w*)\\.wikipedia\\.org/wiki/(.*)").matcher(url);
    134             if (!m.matches()) {
    135                 return null;
    136             }
    137             return new WikipediaLangArticle(m.group(1), m.group(2));
    138         }
    139     }
    140 
    141     static class WikipediaEntry implements Comparable<WikipediaEntry> {
    142 
    143         final String name, description;
    144         final String wikipediaLang, wikipediaArticle;
    145         final LatLon coordinate;
    146         private Boolean wiwosmStatus;
    147 
    148         public WikipediaEntry(String name, String description, LatLon coordinate) {
    149             this.name = name;
    150             this.description = description;
    151             this.coordinate = coordinate;
    152 
    153             final WikipediaLangArticle wp = WikipediaLangArticle.parseFromUrl(getHrefFromDescription());
    154             if (wp == null) {
    155                 System.err.println("Could not extract Wikipedia tag from: " + getHrefFromDescription());
    156             }
    157             this.wikipediaLang = wp == null ? null : wp.lang;
    158             this.wikipediaArticle = wp == null ? null : wp.article;
    159         }
    160 
    161         public WikipediaEntry(String name, String wikipediaLang, String wikipediaArticle) {
    162             this.name = name;
    163             this.description = null;
    164             this.wikipediaLang = wikipediaLang;
    165             this.wikipediaArticle = wikipediaArticle;
    166             this.coordinate = null;
    167         }
    168 
    169         protected final String getHrefFromDescription() {
    170             if (description == null) {
    171                 return null;
    172             }
    173             final Matcher m = Pattern.compile(".*href=\"(.+?)\".*").matcher(description);
    174             if (m.matches()) {
    175                 return m.group(1);
    176             } else {
    177                 System.err.println("Could not parse URL from: " + description);
    178                 return null;
    179             }
    180         }
    181 
    182         protected final Tag createWikipediaTag() {
    183             return new Tag("wikipedia", wikipediaLang + ":" + wikipediaArticle);
    184         }
    185 
    186         private void updateWiwosmStatus() {
    187             try {
    188                 final String url = "http://toolserver.org/~master/osmjson/getGeoJSON.php?action=check"
    189                         + "&lang=" + wikipediaLang
    190                         + "&article=" + encodeURL(wikipediaArticle);
    191                 System.out.println("Wikipedia: GET " + url);
    192                 final Scanner scanner = new Scanner(new URL(url).openStream());
    193                 wiwosmStatus = scanner.hasNextInt() && scanner.nextInt() == 1;
    194             } catch (IOException ex) {
    195                 throw new RuntimeException(ex);
    196             }
    197         }
    198 
    199         public void setWiwosmStatus(Boolean wiwosmStatus) {
    200             this.wiwosmStatus = wiwosmStatus;
    201         }
    202 
    203         public Boolean getWiwosmStatus() {
    204             return wiwosmStatus;
    205         }
    206 
    207         @Override
    208         public String toString() {
    209             return name;
    210         }
    211 
    212         @Override
    213         public int compareTo(WikipediaEntry o) {
    214             return name.compareTo(o.name);
    215         }
    216     }
    217 
    218     private void setWikipediaEntries(Collection<WikipediaEntry> entries) {
    219         Collection<String> articleNames = new ArrayList<String>();
    220         for (WikipediaEntry i : entries) {
    221             articleNames.add(i.wikipediaArticle);
    222         }
    223         Map<String, Boolean> status = new HashMap<String, Boolean>();
    224         if (!articleNames.isEmpty()) {
    225             final String url = "http://toolserver.org/~master/osmjson/getGeoJSON.php?action=check"
    226                     + "&lang=" + wikipediaLang.get()
    227                     + "&articles=" + encodeURL(Utils.join(",", articleNames));
    228             System.out.println("Wikipedia: GET " + url);
    229 
    230             try {
    231                 final Scanner scanner = new Scanner(new URL(url).openStream()).useDelimiter("\n");
    232                 while (scanner.hasNext()) {
    233                     //[article]\t[0|1]
    234                     final String line = scanner.next();
    235                     final String[] x = line.split("\t");
    236                     if (x.length == 2) {
    237                         status.put(x[0], "1".equals(x[1]));
    238                     } else {
    239                         System.err.println("Unknown element " + line);
    240                     }
    241                 }
    242             } catch (Exception ex) {
    243                 throw new RuntimeException(ex);
    244             }
    245         }
    246 
     99    private void setWikipediaEntries(List<WikipediaEntry> entries) {
     100        Collections.sort(entries);
     101        WikipediaApp.updateWIWOSMStatus(wikipediaLang.get(), entries);
    247102        model.clear();
    248103        for (WikipediaEntry i : entries) {
    249             i.setWiwosmStatus(status.get(i.wikipediaArticle));
    250104            model.addElement(i);
    251105        }
     
    265119                LatLon min = Main.map.mapView.getLatLon(0, Main.map.mapView.getHeight());
    266120                LatLon max = Main.map.mapView.getLatLon(Main.map.mapView.getWidth(), 0);
    267                 final String bbox = min.lon() + "," + min.lat() + "," + max.lon() + "," + max.lat();
    268                 // construct url
    269                 final String url = "http://toolserver.org/~kolossos/geoworld/marks.php?"
    270                         + "bbox=" + bbox + "&LANG=" + wikipediaLang.get();
    271                 System.out.println("Wikipedia: GET " + url);
    272                 // parse XML document
    273                 final XPathExpression xpathPlacemark = XPathFactory.newInstance().newXPath().compile("//Placemark");
    274                 final XPathExpression xpathName = XPathFactory.newInstance().newXPath().compile("name/text()");
    275                 final XPathExpression xpathCoord = XPathFactory.newInstance().newXPath().compile("Point/coordinates/text()");
    276                 final XPathExpression xpathDescr = XPathFactory.newInstance().newXPath().compile("description");
    277                 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new URL(url).openStream());
    278                 NodeList nodes = (NodeList) xpathPlacemark.evaluate(doc, XPathConstants.NODESET);
    279                 // construct WikipediaEntry for each XML element
    280                 List<WikipediaEntry> entries = new ArrayList<WikipediaEntry>(nodes.getLength());
    281                 for (int i = 0; i < nodes.getLength(); i++) {
    282                     final String[] coord = xpathCoord.evaluate(nodes.item(i)).split(",");
    283                     if (coord.length <= 2) {
    284                         continue;
    285                     }
    286                     final String name = xpathName.evaluate(nodes.item(i));
    287                     final String descr = xpathDescr.evaluate(nodes.item(i));
    288                     entries.add(new WikipediaEntry(name, descr,
    289                             new LatLon(Double.parseDouble(coord[1]), Double.parseDouble(coord[0]))));
    290                 }
    291                 Collections.sort(entries);
     121                List<WikipediaEntry> entries = WikipediaApp.getEntriesFromCoordinates(
     122                        wikipediaLang.get(), min, max);
    292123                // add entries to list model
    293124                setWikipediaEntries(entries);
     
    308139        @Override
    309140        public void actionPerformed(ActionEvent e) {
    310             try {
    311                 final String category = JOptionPane.showInputDialog(
    312                         Main.parent,
    313                         tr("Enter the Wikipedia category"));
    314                 if (category == null) {
    315                     return;
    316                 }
    317                 final String url = "http://toolserver.org/~daniel/WikiSense/CategoryIntersect.php?"
    318                         + "wikilang=" + wikipediaLang.get()
    319                         + "&wikifam=.wikipedia.org"
    320                         + "&basecat=" + encodeURL(category)
    321                         + "&basedeep=3&templates=&mode=al&format=csv";
    322                 System.out.println("Wikipedia: GET " + url);
    323                 final Scanner scanner = new Scanner(new URL(url).openStream()).useDelimiter("\n");
    324                 final List<WikipediaEntry> entries = new ArrayList<WikipediaEntry>();
    325                 while (scanner.hasNext()) {
    326                     final String article = scanner.next().split("\t")[1].replace("_", " ");
    327                     entries.add(new WikipediaEntry(article, wikipediaLang.get(), article));
    328                 }
    329                 Collections.sort(entries);
    330                 setWikipediaEntries(entries);
    331                 setTitle(/* I18n: [language].Wikipedia.org: [category] */ tr("{0}.Wikipedia.org: {1}", wikipediaLang.get(), category));
    332             } catch (IOException ex) {
    333                 throw new RuntimeException(ex);
    334             }
     141            final String category = JOptionPane.showInputDialog(
     142                    Main.parent,
     143                    tr("Enter the Wikipedia category"));
     144            if (category == null) {
     145                return;
     146            }
     147            List<WikipediaEntry> entries = WikipediaApp.getEntriesFromCategory(wikipediaLang.get(), category);
     148            setWikipediaEntries(entries);
     149            setTitle(/* I18n: [language].Wikipedia.org: [category] */ tr("{0}.Wikipedia.org: {1}", wikipediaLang.get(), category));
    335150        }
    336151    }
     
    346161        public void actionPerformed(ActionEvent e) {
    347162            if (list.getSelectedValue() != null) {
    348                 WikipediaEntry entry = (WikipediaEntry) list.getSelectedValue();
    349                 final String url;
    350                 if (entry.getHrefFromDescription() != null) {
    351                     url = entry.getHrefFromDescription();
    352                 } else {
    353                     url = "http://" + entry.wikipediaLang + ".wikipedia.org/wiki/"
    354                             + encodeURL(entry.wikipediaArticle.replace(" ", "_"));
    355                 }
     163                final String url = ((WikipediaEntry) list.getSelectedValue()).getBrowserUrl();
    356164                System.out.println("Wikipedia: opening " + url);
    357165                OpenBrowser.displayUrl(url);
     
    405213        if (Main.main != null && Main.main.getCurrentDataSet() != null) {
    406214            for (final OsmPrimitive p : Main.main.getCurrentDataSet().allPrimitives()) {
    407                 articles.addAll(getWikipediaArticles(p));
    408             }
    409         }
    410     }
    411 
    412     protected Collection<String> getWikipediaArticles(OsmPrimitive p) {
    413         Collection<String> r = new ArrayList<String>();
    414         final Map<String, String> tags = p.getKeys();
    415         // consider wikipedia=[lang]:*
    416         final String wp = tags.get("wikipedia");
    417         if (wp != null && wp.startsWith("http")) {
    418             //wikipedia=http...
    419             final WikipediaLangArticle item = WikipediaLangArticle.parseFromUrl(wp);
    420             if (item != null && wikipediaLang.get().equals(item.lang)) {
    421                 r.add(item.article.replace("_", " "));
    422             }
    423         } else if (wp != null) {
    424             //wikipedia=[lang]:[article]
    425             String[] item = decodeURL(wp).split(":", 2);
    426             if (item.length == 2 && wikipediaLang.get().equals(item[0])) {
    427                 r.add(item[1].replace("_", " "));
    428             }
    429         }
    430         // consider wikipedia:[lang]=*
    431         final String wpLang = tags.get("wikipedia:" + wikipediaLang.get());
    432         if (wpLang != null && wpLang.startsWith("http")) {
    433             //wikipedia:[lang]=http...
    434             final WikipediaLangArticle item = WikipediaLangArticle.parseFromUrl(wpLang);
    435             if (wikipediaLang.get().equals(item.lang)) {
    436                 r.add(item.article.replace("_", " "));
    437             }
    438         } else if (wpLang != null) {
    439             //wikipedia:[lang]=[lang]:[article]
    440             //wikipedia:[lang]=[article]
    441             String[] item = decodeURL(wpLang).split(":", 2);
    442             r.add(item[item.length == 2 ? 1 : 0].replace("_", " "));
    443         }
    444         return r;
     215                articles.addAll(WikipediaApp.getWikipediaArticles(wikipediaLang.get(), p));
     216            }
     217        }
    445218    }
    446219
     
    472245        list.repaint();
    473246    }
    474 
    475     public static String decodeURL(String url) {
    476         try {
    477             return URLDecoder.decode(url, "UTF-8");
    478         } catch (UnsupportedEncodingException ex) {
    479             throw new IllegalStateException(ex);
    480         }
    481     }
    482 
    483     public static String encodeURL(String url) {
    484         try {
    485             return URLEncoder.encode(url, "UTF-8");
    486         } catch (UnsupportedEncodingException ex) {
    487             throw new IllegalStateException(ex);
    488         }
    489     }
    490247}
Note: See TracChangeset for help on using the changeset viewer.