Changeset 3094 in josm


Ignore:
Timestamp:
07.03.2010 18:48:56 (2 years ago)
Author:
Gubaer
Message:

Improved widget for selecting a bounding box based on a grid of OSM tiles (see Haiti Lessons Learned?).
Also moving the various widgets for selecting a bounding box into a new package org.openstreetmap.josm.gui.bbox. Going to need them shortly in the Changeset Query Dialog and in an upcoming XAPI plugin.

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
5 added
1 deleted
2 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/bbox/SizeButton.java

    r3090 r3094  
    11// License: GPL. Copyright 2007 by Tim Haussmann 
    2 package org.openstreetmap.josm.gui.download; 
     2package org.openstreetmap.josm.gui.bbox; 
    33 
    44import java.awt.Graphics; 
  • trunk/src/org/openstreetmap/josm/gui/bbox/SourceButton.java

    r3090 r3094  
    1 package org.openstreetmap.josm.gui.download; 
     1package org.openstreetmap.josm.gui.bbox; 
    22 
    33import java.awt.Graphics; 
  • trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java

    r3083 r3094  
    55import static org.openstreetmap.josm.tools.I18n.tr; 
    66 
    7 import java.awt.BorderLayout; 
    8 import java.awt.Color; 
    9 import java.awt.Dimension; 
    10 import java.awt.Graphics; 
    11 import java.awt.Point; 
    12 import java.awt.Rectangle; 
    13 import java.awt.Toolkit; 
    14 import java.util.Vector; 
     7import java.beans.PropertyChangeEvent; 
     8import java.beans.PropertyChangeListener; 
    159 
    1610import javax.swing.JPanel; 
    1711 
    18 import org.openstreetmap.gui.jmapviewer.Coordinate; 
    19 import org.openstreetmap.gui.jmapviewer.JMapViewer; 
    20 import org.openstreetmap.gui.jmapviewer.MapMarkerDot; 
    21 import org.openstreetmap.gui.jmapviewer.MemoryTileCache; 
    22 import org.openstreetmap.gui.jmapviewer.OsmFileCacheTileLoader; 
    23 import org.openstreetmap.gui.jmapviewer.OsmMercator; 
    24 import org.openstreetmap.gui.jmapviewer.OsmTileLoader; 
    25 import org.openstreetmap.gui.jmapviewer.OsmTileSource; 
    26 import org.openstreetmap.gui.jmapviewer.interfaces.MapMarker; 
    27 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader; 
    28 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 
    29 import org.openstreetmap.josm.Main; 
    3012import org.openstreetmap.josm.data.Bounds; 
    31 import org.openstreetmap.josm.data.coor.LatLon; 
     13import org.openstreetmap.josm.gui.bbox.BBoxChooser; 
     14import org.openstreetmap.josm.gui.bbox.SlippyMapBBoxChooser; 
    3215 
    3316/** 
     
    3720 * 
    3821 */ 
    39 public class SlippyMapChooser extends JMapViewer implements DownloadSelection { 
     22public class SlippyMapChooser extends JPanel implements DownloadSelection, PropertyChangeListener{ 
    4023 
    4124    private DownloadDialog iGui; 
    42  
    43     // upper left and lower right corners of the selection rectangle (x/y on 
    44     // ZOOM_MAX) 
    45     Point iSelectionRectStart; 
    46     Point iSelectionRectEnd; 
    47  
    48     private SizeButton iSizeButton = new SizeButton(); 
    49     private SourceButton iSourceButton = new SourceButton(); 
    50  
    51     // standard dimension 
    52     private Dimension iDownloadDialogDimension; 
    53  
    54     private TileSource[] sources = { new OsmTileSource.Mapnik(), new OsmTileSource.TilesAtHome(), 
    55             new OsmTileSource.CycleMap() }; 
    56     TileLoader cachedLoader; 
    57     TileLoader uncachedLoader; 
    58     JPanel slipyyMapTabPanel; 
     25    private SlippyMapBBoxChooser pnlSlippyMapBBoxChooser; 
    5926 
    6027    /** 
     
    6229     */ 
    6330    public SlippyMapChooser() { 
    64         super(); 
    65         try { 
    66             cachedLoader = new OsmFileCacheTileLoader(this); 
    67         } catch(SecurityException e) { 
    68             // set to null if a SecurityException was thrown 
    69             // while creating the cachedLoader 
    70             // 
    71             cachedLoader = null; 
    72         } 
    73         uncachedLoader = new OsmTileLoader(this); 
    74         setZoomContolsVisible(false); 
    75         setMapMarkerVisible(false); 
    76         setMinimumSize(new Dimension(350, 350 / 2)); 
    77         // We need to set an initial size - this prevents a wrong zoom selection for 
    78         // the area before the component has been displayed the first time 
    79         setBounds(new Rectangle(getMinimumSize())); 
    80         if (cachedLoader == null) { 
    81             setFileCacheEnabled(false); 
    82         } else { 
    83             setFileCacheEnabled(Main.pref.getBoolean("slippy_map_chooser.file_cache", true)); 
    84         } 
    85         setMaxTilesInMemory(Main.pref.getInteger("slippy_map_chooser.max_tiles", 1000)); 
    86  
    87         String mapStyle = Main.pref.get("slippy_map_chooser.mapstyle", "mapnik"); 
    88         if (mapStyle.equals("osmarender")) { 
    89             iSourceButton.setMapStyle(SourceButton.OSMARENDER); 
    90             this.setTileSource(sources[1]); 
    91         } else if (mapStyle.equals("cyclemap")) { 
    92             iSourceButton.setMapStyle(SourceButton.CYCLEMAP); 
    93             this.setTileSource(sources[2]); 
    94         } else { 
    95             if (!mapStyle.equals("mapnik")) { 
    96                 Main.pref.put("slippy_map_chooser.mapstyle", "mapnik"); 
    97             } 
    98         } 
    99     } 
    100  
    101     public void setMaxTilesInMemory(int tiles) { 
    102         ((MemoryTileCache) getTileCache()).setCacheSize(tiles); 
    103     } 
    104  
    105     public void setFileCacheEnabled(boolean enabled) { 
    106         if (enabled) { 
    107             setTileLoader(cachedLoader); 
    108         } else { 
    109             setTileLoader(uncachedLoader); 
    110         } 
     31        pnlSlippyMapBBoxChooser = new SlippyMapBBoxChooser(); 
     32        pnlSlippyMapBBoxChooser.addPropertyChangeListener(this); 
    11133    } 
    11234 
    11335    public void addGui(final DownloadDialog gui) { 
    11436        iGui = gui; 
    115         slipyyMapTabPanel = new JPanel(); 
    116         slipyyMapTabPanel.setLayout(new BorderLayout()); 
    117         slipyyMapTabPanel.add(this, BorderLayout.CENTER); 
    118         iGui.addDownloadAreaSelector(slipyyMapTabPanel, tr("Slippy map")); 
    119         new OsmMapControl(this, slipyyMapTabPanel, iSizeButton, iSourceButton); 
     37        iGui.addDownloadAreaSelector(pnlSlippyMapBBoxChooser, tr("Slippy map")); 
    12038    } 
    12139 
    122     protected Point getTopLeftCoordinates() { 
    123         return new Point(center.x - (getWidth() / 2), center.y - (getHeight() / 2)); 
     40 
     41    public void setDownloadArea(Bounds area) { 
     42        pnlSlippyMapBBoxChooser.setBoundingBox(area); 
    12443    } 
    12544 
    126     /** 
    127      * Draw the map. 
    128      */ 
    12945    @Override 
    130     public void paint(Graphics g) { 
    131         try { 
    132             super.paint(g); 
    133  
    134             // draw selection rectangle 
    135             if (iSelectionRectStart != null && iSelectionRectEnd != null) { 
    136  
    137                 int zoomDiff = MAX_ZOOM - zoom; 
    138                 Point tlc = getTopLeftCoordinates(); 
    139                 int x_min = (iSelectionRectStart.x >> zoomDiff) - tlc.x; 
    140                 int y_min = (iSelectionRectStart.y >> zoomDiff) - tlc.y; 
    141                 int x_max = (iSelectionRectEnd.x >> zoomDiff) - tlc.x; 
    142                 int y_max = (iSelectionRectEnd.y >> zoomDiff) - tlc.y; 
    143  
    144                 int w = x_max - x_min; 
    145                 int h = y_max - y_min; 
    146                 g.setColor(new Color(0.9f, 0.7f, 0.7f, 0.6f)); 
    147                 g.fillRect(x_min, y_min, w, h); 
    148  
    149                 g.setColor(Color.BLACK); 
    150                 g.drawRect(x_min, y_min, w, h); 
    151  
     46    public void propertyChange(PropertyChangeEvent evt) { 
     47        if (evt.getPropertyName().equals(BBoxChooser.BBOX_PROP)) { 
     48            if (iGui != null) { 
     49                iGui.boundingBoxChanged((Bounds)evt.getNewValue(), this); 
    15250            } 
    153  
    154             iSizeButton.paint(g); 
    155             iSourceButton.paint(g); 
    156         } catch (Exception e) { 
    157             e.printStackTrace(); 
    15851        } 
    15952    } 
    160  
    161     public void setDownloadArea(Bounds area) { 
    162         if (area == null) 
    163             return; 
    164  
    165         // test if a bounding box has been set 
    166         if (area.getMin().lat() == 0.0 && area.getMin().lon() == 0.0 && area.getMax().lat() == 0.0 && area.getMax().lon() == 0.0) 
    167             return; 
    168  
    169         int y1 = OsmMercator.LatToY(area.getMin().lat(), MAX_ZOOM); 
    170         int y2 = OsmMercator.LatToY(area.getMax().lat(), MAX_ZOOM); 
    171         int x1 = OsmMercator.LonToX(area.getMin().lon(), MAX_ZOOM); 
    172         int x2 = OsmMercator.LonToX(area.getMax().lon(), MAX_ZOOM); 
    173  
    174         iSelectionRectStart = new Point(Math.min(x1, x2), Math.min(y1, y2)); 
    175         iSelectionRectEnd = new Point(Math.max(x1, x2), Math.max(y1, y2)); 
    176  
    177         // calc the screen coordinates for the new selection rectangle 
    178         MapMarkerDot xmin_ymin = new MapMarkerDot(area.getMin().lat(), area.getMin().lon()); 
    179         MapMarkerDot xmax_ymax = new MapMarkerDot(area.getMax().lat(), area.getMax().lon()); 
    180  
    181         Vector<MapMarker> marker = new Vector<MapMarker>(2); 
    182         marker.add(xmin_ymin); 
    183         marker.add(xmax_ymax); 
    184         setMapMarkerList(marker); 
    185         setDisplayToFitMapMarkers(); 
    186         zoomOut(); 
    187     } 
    188  
    189     /** 
    190      * Callback for the OsmMapControl. (Re-)Sets the start and end point of the 
    191      * selection rectangle. 
    192      * 
    193      * @param aStart 
    194      * @param aEnd 
    195      */ 
    196     public void setSelection(Point aStart, Point aEnd) { 
    197         if (aStart == null || aEnd == null || aStart.x == aEnd.x || aStart.y == aEnd.y) 
    198             return; 
    199  
    200         Point p_max = new Point(Math.max(aEnd.x, aStart.x), Math.max(aEnd.y, aStart.y)); 
    201         Point p_min = new Point(Math.min(aEnd.x, aStart.x), Math.min(aEnd.y, aStart.y)); 
    202  
    203         Point tlc = getTopLeftCoordinates(); 
    204         int zoomDiff = MAX_ZOOM - zoom; 
    205         Point pEnd = new Point(p_max.x + tlc.x, p_max.y + tlc.y); 
    206         Point pStart = new Point(p_min.x + tlc.x, p_min.y + tlc.y); 
    207  
    208         pEnd.x <<= zoomDiff; 
    209         pEnd.y <<= zoomDiff; 
    210         pStart.x <<= zoomDiff; 
    211         pStart.y <<= zoomDiff; 
    212  
    213         iSelectionRectStart = pStart; 
    214         iSelectionRectEnd = pEnd; 
    215  
    216         Coordinate l1 = getPosition(p_max); 
    217         Coordinate l2 = getPosition(p_min); 
    218         Bounds b = new Bounds( 
    219                 new LatLon( 
    220                         Math.min(l2.getLat(), l1.getLat()), 
    221                         Math.min(l1.getLon(), l2.getLon()) 
    222                 ), 
    223                 new LatLon( 
    224                         Math.max(l2.getLat(), l1.getLat()), 
    225                         Math.max(l1.getLon(), l2.getLon())) 
    226         ); 
    227         iGui.boundingBoxChanged(b, this); 
    228         repaint(); 
    229     } 
    230  
    231     /** 
    232      * Performs resizing of the DownloadDialog in order to enlarge or shrink the 
    233      * map. 
    234      */ 
    235     public void resizeSlippyMap() { 
    236         int w, h; 
    237  
    238         // retrieve the size of the display 
    239         Dimension iScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
    240  
    241         // enlarge 
    242         if(iDownloadDialogDimension == null) { 
    243             // make the each dimension 90% of the absolute display size 
    244             w = iScreenSize.width * 90 / 100; 
    245             h = iScreenSize.height * 90 / 100; 
    246             iDownloadDialogDimension = iGui.getSize(); 
    247         } 
    248         // shrink 
    249         else { 
    250             // set the size back to the initial dimensions 
    251             w = iDownloadDialogDimension.width; 
    252             h = iDownloadDialogDimension.height; 
    253             iDownloadDialogDimension = null; 
    254         } 
    255  
    256         // resize and center the DownloadDialog 
    257         iGui.setBounds((iScreenSize.width - w) / 2, (iScreenSize.height - h) / 2, w, h); 
    258  
    259         repaint(); 
    260     } 
    261  
    262     public void toggleMapSource(int mapSource) { 
    263         this.tileController.setTileCache(new MemoryTileCache()); 
    264         if (mapSource == SourceButton.MAPNIK) { 
    265             this.setTileSource(sources[0]); 
    266             Main.pref.put("slippy_map_chooser.mapstyle", "mapnik"); 
    267         } else if (mapSource == SourceButton.CYCLEMAP) { 
    268             this.setTileSource(sources[2]); 
    269             Main.pref.put("slippy_map_chooser.mapstyle", "cyclemap"); 
    270         } else { 
    271             this.setTileSource(sources[1]); 
    272             Main.pref.put("slippy_map_chooser.mapstyle", "osmarender"); 
    273         } 
    274     } 
    275  
    27653} 
  • trunk/src/org/openstreetmap/josm/gui/download/TileSelection.java

    r3083 r3094  
    44import static org.openstreetmap.josm.tools.I18n.tr; 
    55 
    6 import java.awt.Dimension; 
    7 import java.awt.GridBagLayout; 
    8 import java.awt.event.FocusAdapter; 
    9 import java.awt.event.FocusEvent; 
    10 import java.awt.event.FocusListener; 
    11  
    12 import javax.swing.JLabel; 
    13 import javax.swing.JPanel; 
    14 import javax.swing.JSpinner; 
    15 import javax.swing.JTextField; 
    16 import javax.swing.SpinnerNumberModel; 
     6import java.beans.PropertyChangeEvent; 
     7import java.beans.PropertyChangeListener; 
    178 
    189import org.openstreetmap.josm.data.Bounds; 
    19 import org.openstreetmap.josm.data.coor.LatLon; 
    20 import org.openstreetmap.josm.tools.GBC; 
     10import org.openstreetmap.josm.gui.bbox.BBoxChooser; 
     11import org.openstreetmap.josm.gui.bbox.TileSelectionBBoxChooser; 
    2112/** 
    2213 * Tile selector. 
     
    2718 * 
    2819 */ 
    29 public class TileSelection implements DownloadSelection { 
     20public class TileSelection implements DownloadSelection, PropertyChangeListener { 
    3021 
    31     private JTextField tileX0 = new JTextField(7); 
    32     private JTextField tileY0 = new JTextField(7); 
    33     private JTextField tileX1 = new JTextField(7); 
    34     private JTextField tileY1 = new JTextField(7); 
    35     private JSpinner tileZ = new JSpinner(new SpinnerNumberModel(12, 10, 18, 1)); 
     22    private TileSelectionBBoxChooser chooser; 
     23    private DownloadDialog parent; 
     24 
     25    protected void build() { 
     26        chooser = new TileSelectionBBoxChooser(); 
     27        chooser.addPropertyChangeListener(this); 
     28    } 
     29 
     30    public TileSelection() { 
     31        build(); 
     32    } 
    3633 
    3734    public void addGui(final DownloadDialog gui) { 
    38  
    39         JPanel smpanel = new JPanel(new GridBagLayout()); 
    40         smpanel.add(new JLabel(tr("zoom level")), GBC.std().insets(0,0,10,0)); 
    41         smpanel.add(new JLabel(tr("x from")), GBC.std().insets(10,0,5,0)); 
    42         smpanel.add(tileX0, GBC.std()); 
    43         smpanel.add(new JLabel(tr("to")), GBC.std().insets(10,0,5,0)); 
    44         smpanel.add(tileX1, GBC.eol()); 
    45         smpanel.add(tileZ, GBC.std().insets(0,0,10,0)); 
    46         smpanel.add(new JLabel(tr("y from")), GBC.std().insets(10,0,5,0)); 
    47         smpanel.add(tileY0, GBC.std()); 
    48         smpanel.add(new JLabel(tr("to")), GBC.std().insets(10,0,5,0)); 
    49         smpanel.add(tileY1, GBC.eol()); 
    50  
    51         final FocusListener dialogUpdater = new FocusAdapter() { 
    52             @Override public void focusLost(FocusEvent e) { 
    53                 try { 
    54                     int zoomlvl = (Integer) tileZ.getValue(); 
    55                     int fromx = Integer.parseInt(tileX0.getText()); 
    56                     int tox = fromx; 
    57                     if (tileX1.getText().length()>0) { 
    58                         tox = Integer.parseInt(tileX1.getText()); 
    59                     } 
    60                     if (tox<fromx) { int i = fromx; fromx=tox; tox=i; } 
    61  
    62                     int fromy = Integer.parseInt(tileY0.getText()); 
    63                     int toy = fromy; 
    64                     if (tileY1.getText().length()>0) { 
    65                         toy = Integer.parseInt(tileY1.getText()); 
    66                     } 
    67                     if (toy<fromy) { int i = fromy; fromy=toy; toy=i; } 
    68  
    69                     Bounds b = new Bounds( 
    70                             new LatLon(tileYToLat(zoomlvl, toy + 1), tileXToLon(zoomlvl, fromx)), 
    71                             new LatLon(tileYToLat(zoomlvl, fromy), tileXToLon(zoomlvl, tox + 1)) 
    72                             ); 
    73                     gui.boundingBoxChanged(b, TileSelection.this); 
    74                     //repaint(); 
    75                 } catch (NumberFormatException x) { 
    76                     // ignore 
    77                 } 
    78             } 
    79         }; 
    80  
    81         for (JTextField f : new JTextField[] { tileX0, tileX1, tileY0, tileY1 }) { 
    82             f.setMinimumSize(new Dimension(100,new JTextField().getMinimumSize().height)); 
    83             f.addFocusListener(dialogUpdater); 
    84         } 
    85  
    86         gui.addDownloadAreaSelector(smpanel, tr("Tile Numbers")); 
     35        gui.addDownloadAreaSelector(chooser, tr("Tile Numbers")); 
     36        parent = gui; 
    8737    } 
    8838 
    8939    public void setDownloadArea(Bounds area) { 
    90         if (area == null) 
    91             return; 
    92         int z = ((Integer) tileZ.getValue()).intValue(); 
    93         tileX0.setText(Integer.toString(lonToTileX(z, area.getMin().lon()))); 
    94         tileX1.setText(Integer.toString(lonToTileX(z, area.getMax().lon()-.00001))); 
    95         tileY0.setText(Integer.toString(latToTileY(z, area.getMax().lat()-.00001))); 
    96         tileY1.setText(Integer.toString(latToTileY(z, area.getMin().lat()))); 
     40        chooser.setBoundingBox(area); 
    9741    } 
    9842 
    99     public static int latToTileY(int zoom, double lat) { 
    100         if ((zoom < 3) || (zoom > 18)) return -1; 
    101         double l = lat / 180 * Math.PI; 
    102         double pf = Math.log(Math.tan(l) + (1/Math.cos(l))); 
    103         return (int) ((1<<(zoom-1)) * (Math.PI - pf) / Math.PI); 
    104     } 
    105  
    106     public static int lonToTileX(int zoom, double lon) { 
    107         if ((zoom < 3) || (zoom > 18)) return -1; 
    108         return (int) ((1<<(zoom-3)) * (lon + 180.0) / 45.0); 
    109     } 
    110  
    111     public static double tileYToLat(int zoom, int y) { 
    112         if ((zoom < 3) || (zoom > 18)) return Double.MIN_VALUE; 
    113         return Math.atan(Math.sinh(Math.PI - (Math.PI*y / (1<<(zoom-1))))) * 180 / Math.PI; 
    114     } 
    115  
    116     public static double tileXToLon(int zoom, int x) { 
    117         if ((zoom < 3) || (zoom > 18)) return Double.MIN_VALUE; 
    118         return x * 45.0 / (1<<(zoom-3)) - 180.0; 
    119  
     43    @Override 
     44    public void propertyChange(PropertyChangeEvent evt) { 
     45        if (evt.getPropertyName().equals(BBoxChooser.BBOX_PROP)) { 
     46            Bounds bbox = (Bounds)evt.getNewValue(); 
     47            parent.boundingBoxChanged(bbox, this); 
     48        } 
    12049    } 
    12150} 
Note: See TracChangeset for help on using the changeset viewer.