| 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others
|
|---|
| 2 | package org.openstreetmap.josm.gui.download;
|
|---|
| 3 |
|
|---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
|---|
| 5 |
|
|---|
| 6 | import java.awt.BorderLayout;
|
|---|
| 7 | import java.awt.Color;
|
|---|
| 8 | import java.awt.Dimension;
|
|---|
| 9 | import java.awt.Graphics;
|
|---|
| 10 | import java.awt.Point;
|
|---|
| 11 | import java.awt.Rectangle;
|
|---|
| 12 | import java.beans.PropertyChangeListener;
|
|---|
| 13 | import java.net.URL;
|
|---|
| 14 |
|
|---|
| 15 | import javax.swing.ImageIcon;
|
|---|
| 16 | import javax.swing.JLabel;
|
|---|
| 17 | import javax.swing.JPanel;
|
|---|
| 18 |
|
|---|
| 19 | import org.openstreetmap.josm.Main;
|
|---|
| 20 | import org.openstreetmap.josm.data.coor.EastNorth;
|
|---|
| 21 | import org.openstreetmap.josm.data.coor.LatLon;
|
|---|
| 22 | import org.openstreetmap.josm.data.projection.Projection;
|
|---|
| 23 | import org.openstreetmap.josm.gui.MapMover;
|
|---|
| 24 | import org.openstreetmap.josm.gui.MapScaler;
|
|---|
| 25 | import org.openstreetmap.josm.gui.NavigatableComponent;
|
|---|
| 26 | import org.openstreetmap.josm.gui.SelectionManager;
|
|---|
| 27 | import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 | /**
|
|---|
| 31 | * A component that let the user select a lat/lon bounding box from zooming
|
|---|
| 32 | * into the world as a picture and selecting a region.
|
|---|
| 33 | *
|
|---|
| 34 | * The component has to be of the aspect ration 2:1 to look good.
|
|---|
| 35 | *
|
|---|
| 36 | * @author imi
|
|---|
| 37 | */
|
|---|
| 38 | public class WorldChooser extends NavigatableComponent implements DownloadSelection {
|
|---|
| 39 |
|
|---|
| 40 | /**
|
|---|
| 41 | * The world as picture.
|
|---|
| 42 | */
|
|---|
| 43 | private ImageIcon world;
|
|---|
| 44 |
|
|---|
| 45 | /**
|
|---|
| 46 | * Maximum scale level
|
|---|
| 47 | */
|
|---|
| 48 | private double scaleMax;
|
|---|
| 49 |
|
|---|
| 50 | /**
|
|---|
| 51 | * Mark this rectangle (lat/lon values) when painting.
|
|---|
| 52 | */
|
|---|
| 53 | private EastNorth markerMin, markerMax;
|
|---|
| 54 |
|
|---|
| 55 | private Projection projection;
|
|---|
| 56 |
|
|---|
| 57 | /**
|
|---|
| 58 | * Create the chooser component.
|
|---|
| 59 | */
|
|---|
| 60 | public WorldChooser() {
|
|---|
| 61 | URL path = Main.class.getResource("/images/world.jpg");
|
|---|
| 62 | world = new ImageIcon(path);
|
|---|
| 63 | center = new EastNorth(world.getIconWidth()/2, world.getIconHeight()/2);
|
|---|
| 64 | setPreferredSize(new Dimension(400, 200));
|
|---|
| 65 |
|
|---|
| 66 | projection = new Projection() {
|
|---|
| 67 | public EastNorth latlon2eastNorth(LatLon p) {
|
|---|
| 68 | return new EastNorth(
|
|---|
| 69 | (p.lon()+180) / 360 * world.getIconWidth(),
|
|---|
| 70 | (p.lat()+90) / 180 * world.getIconHeight());
|
|---|
| 71 | }
|
|---|
| 72 | public LatLon eastNorth2latlon(EastNorth p) {
|
|---|
| 73 | return new LatLon(
|
|---|
| 74 | p.north()*180/world.getIconHeight() - 90,
|
|---|
| 75 | p.east()*360/world.getIconWidth() - 180);
|
|---|
| 76 | }
|
|---|
| 77 | @Override public String toString() {
|
|---|
| 78 | return "WorldChooser";
|
|---|
| 79 | }
|
|---|
| 80 | public String getCacheDirectoryName() {
|
|---|
| 81 | throw new UnsupportedOperationException();
|
|---|
| 82 | }
|
|---|
| 83 | public double scaleFactor() {
|
|---|
| 84 | return 1.0 / world.getIconWidth();
|
|---|
| 85 | }
|
|---|
| 86 |
|
|---|
| 87 | };
|
|---|
| 88 |
|
|---|
| 89 | MapScaler scaler = new MapScaler(this, projection);
|
|---|
| 90 | add(scaler);
|
|---|
| 91 | scaler.setLocation(10,10);
|
|---|
| 92 |
|
|---|
| 93 | setMinimumSize(new Dimension(350, 350/2));
|
|---|
| 94 | }
|
|---|
| 95 |
|
|---|
| 96 | public void addGui(final DownloadDialog gui) {
|
|---|
| 97 | JPanel temp = new JPanel();
|
|---|
| 98 | temp.setLayout(new BorderLayout());
|
|---|
| 99 | temp.add(this, BorderLayout.CENTER);
|
|---|
| 100 | temp.add(new JLabel(tr("You can use the mouse or Ctrl+Arrow keys/./ to zoom and pan.")), BorderLayout.SOUTH);
|
|---|
| 101 | gui.tabpane.add(temp, "Map");
|
|---|
| 102 | new MapMover(this, temp);
|
|---|
| 103 | SelectionEnded selListener = new SelectionEnded(){
|
|---|
| 104 | public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
|
|---|
| 105 | markerMin = getEastNorth(r.x, r.y+r.height);
|
|---|
| 106 | markerMax = getEastNorth(r.x+r.width, r.y);
|
|---|
| 107 | LatLon min = getProjection().eastNorth2latlon(markerMin);
|
|---|
| 108 | LatLon max = getProjection().eastNorth2latlon(markerMax);
|
|---|
| 109 | gui.minlat = min.lat();
|
|---|
| 110 | gui.minlon = min.lon();
|
|---|
| 111 | gui.maxlat = max.lat();
|
|---|
| 112 | gui.maxlon = max.lon();
|
|---|
| 113 | gui.boundingBoxChanged(WorldChooser.this);
|
|---|
| 114 | repaint();
|
|---|
| 115 | }
|
|---|
| 116 | public void addPropertyChangeListener(PropertyChangeListener listener) {}
|
|---|
| 117 | public void removePropertyChangeListener(PropertyChangeListener listener) {}
|
|---|
| 118 | };
|
|---|
| 119 | SelectionManager sm = new SelectionManager(selListener, false, this);
|
|---|
| 120 | sm.register(this);
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 | public void boundingBoxChanged(DownloadDialog gui) {
|
|---|
| 124 | markerMin = getProjection().latlon2eastNorth(new LatLon(gui.minlat, gui.minlon));
|
|---|
| 125 | markerMax = getProjection().latlon2eastNorth(new LatLon(gui.maxlat, gui.maxlon));
|
|---|
| 126 | repaint();
|
|---|
| 127 | }
|
|---|
| 128 |
|
|---|
| 129 | /**
|
|---|
| 130 | * Set the scale as well as the preferred size.
|
|---|
| 131 | */
|
|---|
| 132 | @Override public void setPreferredSize(Dimension preferredSize) {
|
|---|
| 133 | super.setPreferredSize(preferredSize);
|
|---|
| 134 | scale = world.getIconWidth()/preferredSize.getWidth();
|
|---|
| 135 | scaleMax = scale;
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 | /**
|
|---|
| 139 | * Draw the current selected region.
|
|---|
| 140 | */
|
|---|
| 141 | @Override public void paint(Graphics g) {
|
|---|
| 142 | EastNorth tl = getEastNorth(0,0);
|
|---|
| 143 | EastNorth br = getEastNorth(getWidth(),getHeight());
|
|---|
| 144 | g.drawImage(world.getImage(),0,0,getWidth(),getHeight(),(int)tl.east(),(int)tl.north(),(int)br.east(),(int)br.north(), null);
|
|---|
| 145 |
|
|---|
| 146 | // draw marker rect
|
|---|
| 147 | if (markerMin != null && markerMax != null) {
|
|---|
| 148 | Point p1 = getPoint(markerMin);
|
|---|
| 149 | Point p2 = getPoint(markerMax);
|
|---|
| 150 | double x = Math.min(p1.x, p2.x);
|
|---|
| 151 | double y = Math.min(p1.y, p2.y);
|
|---|
| 152 | double w = Math.max(p1.x, p2.x) - x;
|
|---|
| 153 | double h = Math.max(p1.y, p2.y) - y;
|
|---|
| 154 | if (w < 1)
|
|---|
| 155 | w = 1;
|
|---|
| 156 | if (h < 1)
|
|---|
| 157 | h = 1;
|
|---|
| 158 | g.setColor(Color.YELLOW);
|
|---|
| 159 | g.drawRect((int)x, (int)y, (int)w, (int)h);
|
|---|
| 160 | }
|
|---|
| 161 | super.paint(g);
|
|---|
| 162 | }
|
|---|
| 163 |
|
|---|
| 164 | @Override public void zoomTo(EastNorth newCenter, double scale) {
|
|---|
| 165 | if (getWidth() != 0 && scale > scaleMax) {
|
|---|
| 166 | scale = scaleMax;
|
|---|
| 167 | newCenter = center;
|
|---|
| 168 | }
|
|---|
| 169 | super.zoomTo(newCenter, scale);
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | /**
|
|---|
| 173 | * Always use our image projection mode.
|
|---|
| 174 | */
|
|---|
| 175 | @Override protected Projection getProjection() {
|
|---|
| 176 | return projection;
|
|---|
| 177 | }
|
|---|
| 178 | }
|
|---|