001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.layer.geoimage; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.event.ActionEvent; 007import java.io.IOException; 008import java.util.ArrayList; 009import java.util.List; 010 011import javax.xml.parsers.ParserConfigurationException; 012import javax.xml.xpath.XPathExpressionException; 013 014import org.openstreetmap.josm.actions.JosmAction; 015import org.openstreetmap.josm.data.Bounds; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.PleaseWaitRunnable; 018import org.openstreetmap.josm.io.OsmTransferException; 019import org.openstreetmap.josm.tools.Logging; 020import org.openstreetmap.josm.tools.Mediawiki; 021import org.xml.sax.SAXException; 022 023/** 024 * Loads geocoded images from <a href="https://commons.wikimedia.org/">Wikimedia Commons</a> for the given bounding box. 025 */ 026public class WikimediaCommonsLoader extends PleaseWaitRunnable { 027 protected String apiUrl = "https://commons.wikimedia.org/w/api.php"; 028 protected GeoImageLayer layer; 029 private final Bounds bounds; 030 031 /** 032 * Constructs a new {@code WikimediaCommonsLoader} 033 * @param bounds The bounds to load 034 */ 035 public WikimediaCommonsLoader(Bounds bounds) { 036 super(tr("Load images from Wikimedia Commons")); 037 this.bounds = bounds; 038 } 039 040 @Override 041 protected void realRun() throws SAXException, IOException, OsmTransferException { 042 List<ImageEntry> imageEntries = new ArrayList<>(); 043 try { 044 new Mediawiki(apiUrl).searchGeoImages(bounds, (title, latLon) -> imageEntries.add(new WikimediaCommonsEntry(title, latLon))); 045 } catch (ParserConfigurationException | XPathExpressionException e) { 046 throw new IllegalStateException(e); 047 } 048 Logging.info("Loaded {0} images from Wikimedia Commons", imageEntries.size()); 049 layer = new WikimediaCommonsLayer(imageEntries); 050 } 051 052 @Override 053 protected void finish() { 054 if (layer != null) { 055 MainApplication.getLayerManager().addLayer(layer); 056 } 057 } 058 059 @Override 060 protected void cancel() { 061 // do nothing 062 } 063 064 /** 065 * Load images from Wikimedia Commons 066 * @since 18021 067 */ 068 public static class WikimediaCommonsLoadImagesAction extends JosmAction { 069 /** 070 * Constructs a new {@code WikimediaCommonsLoadImagesAction} 071 */ 072 public WikimediaCommonsLoadImagesAction() { 073 super(tr("Load images from Wikimedia Commons"), "wikimedia_commons", null, null, false); 074 } 075 076 @Override 077 public void actionPerformed(ActionEvent e) { 078 Bounds bounds = MainApplication.getMap().mapView.getRealBounds(); 079 MainApplication.worker.execute(new WikimediaCommonsLoader(bounds)); 080 } 081 082 @Override 083 protected void updateEnabledState() { 084 setEnabled(MainApplication.isDisplayingMapView()); 085 } 086 } 087}