Index: src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 54)
+++ src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 55)
@@ -7,7 +7,11 @@
 import java.awt.event.ActionListener;
 import java.awt.event.InputEvent;
+import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.swing.DefaultListModel;
@@ -20,4 +24,5 @@
 import javax.swing.JTextField;
 import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
@@ -25,4 +30,5 @@
 import org.jdom.JDOMException;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.GeoPoint;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -62,8 +68,11 @@
 	public void actionPerformed(ActionEvent e) {
 		JPanel dlg = new JPanel(new GridBagLayout());
-		
+
+		// World image
 		WorldChooser wc = new WorldChooser();
 		dlg.add(wc, GBC.eop());
-
+		wc.setToolTipText("Move and zoom the image like the main map. Select an area to download by dragging.");
+
+		// Bounding box edits
 		dlg.add(new JLabel("Bounding box"), GBC.eol());
 		dlg.add(new JLabel("min lat"), GBC.std().insets(10,0,5,0));
@@ -75,27 +84,74 @@
 		dlg.add(new JLabel("max lon"), GBC.std().insets(10,0,5,0));
 		dlg.add(latlon[3], GBC.eol());
-
 		if (Main.main.getMapFrame() != null) {
 			MapView mv = Main.main.getMapFrame().mapView;
-			int w = mv.getWidth();
-			int h = mv.getHeight();
-			GeoPoint bottomLeft = mv.getPoint(0, h, true);
-			GeoPoint topRight = mv.getPoint(w, 0, true);
-			if (bottomLeft.isOutSideWorld())
-				bottomLeft = new GeoPoint(-89.999, -179.999); // do not use the Projection constants, since this look better.
-			if (topRight.isOutSideWorld())
-				topRight = new GeoPoint(89.999, 179.999);
-			latlon[0].setText(""+bottomLeft.lat);
-			latlon[1].setText(""+bottomLeft.lon);
-			latlon[2].setText(""+topRight.lat);
-			latlon[3].setText(""+topRight.lon);
-			for (JTextField f : latlon)
-				f.setCaretPosition(0);
+			setEditBounds(new Bounds(
+					mv.getPoint(0, mv.getHeight(), true),
+					mv.getPoint(mv.getWidth(), 0, true)));
 			rawGps.setSelected(mv.getActiveLayer() instanceof RawGpsDataLayer);
 		}
-
 		dlg.add(rawGps, GBC.eop());
 		
-		// load bookmarks
+		// OSM url edit
+		dlg.add(new JLabel("URL from www.openstreetmap.org"), GBC.eol());
+		final JTextField osmUrl = new JTextField();
+		dlg.add(osmUrl, GBC.eop().fill(GBC.HORIZONTAL));
+		final KeyListener osmUrlRefresher = new KeyAdapter(){
+			@Override
+			public void keyTyped(KeyEvent e) {
+				SwingUtilities.invokeLater(new Runnable() {
+					public void run() {
+						try {
+							double latMin = Double.parseDouble(latlon[0].getText());
+							double lonMin = Double.parseDouble(latlon[1].getText());
+							double latMax = Double.parseDouble(latlon[2].getText());
+							double lonMax = Double.parseDouble(latlon[3].getText());
+							double lat = (latMax+latMin)/2;
+							double lon = (lonMax+lonMin)/2;
+							// convert to mercator (for calculation of zoom only)
+							latMin = Math.log(Math.tan(Math.PI/4.0+latMin/180.0*Math.PI/2.0))*180.0/Math.PI;
+							latMax = Math.log(Math.tan(Math.PI/4.0+latMax/180.0*Math.PI/2.0))*180.0/Math.PI;
+							double size = Math.max(Math.abs(latMax-latMin), Math.abs(lonMax-lonMin));
+							int zoom = 0;
+							while (zoom <= 20) {
+								if (size >= 180)
+									break;
+								size *= 2;
+								zoom++;
+							}
+							osmUrl.setText("http://www.openstreetmap.org/index.html?lat="+lat+"&lon="+lon+"&zoom="+zoom);
+						} catch (NumberFormatException x) {
+							osmUrl.setText("");
+						}
+						osmUrl.setCaretPosition(0);
+					}
+				});
+			}
+		};
+		for (JTextField f : latlon)
+			f.addKeyListener(osmUrlRefresher);
+		SwingUtilities.invokeLater(new Runnable() {public void run() {osmUrlRefresher.keyTyped(null);}});
+		osmUrl.addKeyListener(new KeyAdapter(){
+			@Override
+			public void keyTyped(KeyEvent e) {
+				SwingUtilities.invokeLater(new Runnable() {
+					public void run() {
+						Map<String, Double> map = readArgs(osmUrl.getText());
+						try {
+							double size = 180.0 / Math.pow(2, map.get("zoom"));
+							Bounds b = new Bounds(
+									new GeoPoint(map.get("lat") - size/2, map.get("lon") - size), 
+									new GeoPoint(map.get("lat") + size/2, map.get("lon") + size));
+							setEditBounds(b);
+						} catch (Exception x) { // NPE or IAE
+							for (JTextField f : latlon)
+								f.setText("");
+						}
+					}
+				});
+			}
+		});
+		
+		// Bookmarks
 		dlg.add(new JLabel("Bookmarks"), GBC.eol());
 		final BookmarkList bookmarks = new BookmarkList();
@@ -108,8 +164,8 @@
 				}
 				rawGps.setSelected(b == null ? false : b.rawgps);
+				osmUrlRefresher.keyTyped(null);
 			}
 		});
 		wc.addListMarker(bookmarks);
-		wc.addLatLonInputField(latlon);
 		dlg.add(new JScrollPane(bookmarks), GBC.eol().fill());
 
@@ -145,8 +201,10 @@
 		buttons.add(remove);
 		dlg.add(buttons, GBC.eop().fill(GBC.HORIZONTAL));
-		
+
 		Dimension d = dlg.getPreferredSize();
 		wc.setPreferredSize(new Dimension(d.width, d.width/2));
+		wc.addInputFields(latlon, osmUrl, osmUrlRefresher);
 		
+		// Finally: the dialog
 		int r = JOptionPane.showConfirmDialog(Main.main, dlg, "Choose an area", 
 				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
@@ -154,4 +212,11 @@
 			return;
 
+		startDownload();
+	}
+
+	/**
+	 * Read the values from the edit fields and start the download.
+	 */
+	private void startDownload() {
 		Bookmark b = readBookmark();
 		if (b == null) {
@@ -161,5 +226,4 @@
 		
 		final OsmServerReader osmReader = new OsmServerReader(b.latlon[0], b.latlon[1], b.latlon[2], b.latlon[3]);
-		
 		new Thread(new PleaseWaitRunnable("Downloading data"){
 			@Override
@@ -229,3 +293,43 @@
 		}
 	}
+	
+	
+	/**
+	 * Extrakt URL arguments.
+	 */
+	private Map<String, Double> readArgs(String s) {
+		int i = s.indexOf('?');
+		if (i == -1)
+			return new HashMap<String, Double>();
+		String[] args = s.substring(i+1).split("&");
+		HashMap<String, Double> map = new HashMap<String, Double>();
+		for (String arg : args) {
+			int eq = arg.indexOf('=');
+			if (eq != -1) {
+				try {
+					map.put(arg.substring(0, eq), Double.parseDouble(arg.substring(eq + 1)));
+				} catch (NumberFormatException e) {
+				}				
+			}
+		}
+		return map;
+	}
+	
+	/**
+	 * Set the four edit fields to the given bounds coordinates.
+	 */
+	private void setEditBounds(Bounds b) {
+		GeoPoint bottomLeft = b.min;
+		GeoPoint topRight = b.max;
+		if (bottomLeft.isOutSideWorld())
+			bottomLeft = new GeoPoint(-89.999, -179.999); // do not use the Projection constants, since this looks better.
+		if (topRight.isOutSideWorld())
+			topRight = new GeoPoint(89.999, 179.999);
+		latlon[0].setText(""+bottomLeft.lat);
+		latlon[1].setText(""+bottomLeft.lon);
+		latlon[2].setText(""+topRight.lat);
+		latlon[3].setText(""+topRight.lon);
+		for (JTextField f : latlon)
+			f.setCaretPosition(0);
+	}
 }
Index: src/org/openstreetmap/josm/gui/WorldChooser.java
===================================================================
--- src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 54)
+++ src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 55)
@@ -144,8 +144,5 @@
 	 * @param field Must have exactly 4 entries (min lat to max lon)
 	 */
-	public void addLatLonInputField(final JTextField[] field) {
-		if (field.length != 4)
-			throw new IllegalArgumentException();
-
+	public void addInputFields(final JTextField[] field, JTextField osmUrl, final KeyListener osmUrlRefresher) {
 		// listener that invokes updateMarkerFromTextField after all
 		// messages are dispatched and so text fields are updated.
@@ -163,4 +160,5 @@
 		for (JTextField f : field)
 			f.addKeyListener(listener);
+		osmUrl.addKeyListener(listener);
 
 		SelectionEnded selListener = new SelectionEnded(){
@@ -175,4 +173,5 @@
 				for (JTextField f : field)
 					f.setCaretPosition(0);
+				osmUrlRefresher.keyTyped(null);
 				repaint();
 			}
