001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.datatransfer.importers; 003 004import java.awt.Component; 005import java.awt.datatransfer.DataFlavor; 006import java.awt.datatransfer.UnsupportedFlavorException; 007import java.io.IOException; 008import java.util.regex.Matcher; 009import java.util.regex.Pattern; 010 011import javax.swing.TransferHandler.TransferSupport; 012 013import org.openstreetmap.josm.actions.OpenLocationAction; 014import org.openstreetmap.josm.data.coor.EastNorth; 015import org.openstreetmap.josm.data.coor.LatLon; 016import org.openstreetmap.josm.gui.MapView; 017import org.openstreetmap.josm.gui.layer.OsmDataLayer; 018 019/** 020 * Handles the paste / drop of an OSM address. 021 * <p> 022 * e.g. http://www.openstreetmap.org/node/123 downloads node 123 023 * 024 * @author Michael Zangl 025 * @since 10881 026 */ 027public class OsmLinkPaster extends AbstractOsmDataPaster { 028 029 static final class NoWarnOpenLocationAction extends OpenLocationAction { 030 @Override 031 protected void warnNoSuitableTasks(String url) { 032 // ignore this. 033 } 034 } 035 036 private static final String OSM_SERVER = "^https?\\://(\\w+\\.)?(osm|openstreetmap)\\.org/"; 037 038 /** 039 * Create a new Osm address paster 040 */ 041 public OsmLinkPaster() { 042 super(DataFlavor.stringFlavor); 043 } 044 045 @Override 046 public boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth pasteAt) 047 throws UnsupportedFlavorException, IOException { 048 if (!supports(support)) { 049 throw new UnsupportedFlavorException(df); 050 } 051 052 String transferData = (String) support.getTransferable().getTransferData(df); 053 if (!new NoWarnOpenLocationAction().openUrl(transferData).isEmpty()) { 054 return true; 055 } 056 057 LatLon ll = parseLatLon(transferData); 058 if (ll != null) { 059 Component comp = support.getComponent(); 060 if (comp instanceof MapView) { 061 ((MapView) comp).zoomTo(ll); 062 } 063 } 064 065 return false; 066 } 067 068 static LatLon parseLatLon(String transferData) { 069 Matcher matcher = Pattern 070 .compile(OSM_SERVER + "#map=(?<zoom>\\d+)/(?<lat>-?\\d+\\.\\d+)/(?<lon>-?\\d+\\.\\d+)$") 071 .matcher(transferData); 072 073 if (!matcher.matches()) { 074 return null; 075 } else { 076 return new LatLon(Double.parseDouble(matcher.group("lat")), Double.parseDouble(matcher.group("lon"))); 077 } 078 } 079}