Changeset 6054 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2013-07-06T21:15:51+02:00 (11 years ago)
Author:
Don-vip
Message:

see #2283 - download GPX data along a track + code refactorization to simplify download_along plugin as well

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/Preferences.java

    r5977 r6054  
    16331633    public void removeObsolete() {
    16341634        String[] obsolete = {
    1635                 "color.Imagery fade",              // 08/2012 - wrong property caused by #6723, can be removed mid-2013
     1635                "downloadAlong.downloadAlongTrack.distance",   // 07/2013 - can be removed mid-2014. Replaced by downloadAlongWay.distance
     1636                "downloadAlong.downloadAlongTrack.area",       // 07/2013 - can be removed mid-2014. Replaced by downloadAlongWay.area
     1637                "gpxLayer.downloadAlongTrack.distance",        // 07/2013 - can be removed mid-2014. Replaced by downloadAlongTrack.distance
     1638                "gpxLayer.downloadAlongTrack.area",            // 07/2013 - can be removed mid-2014. Replaced by downloadAlongTrack.area
     1639                "gpxLayer.downloadAlongTrack.near",            // 07/2013 - can be removed mid-2014. Replaced by downloadAlongTrack.near
    16361640        };
    16371641        for (String key : obsolete) {
  • trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java

    r6053 r6054  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.GridBagLayout;
    76import java.awt.event.ActionEvent;
    87import java.awt.geom.Area;
    98import java.awt.geom.Rectangle2D;
    10 import java.util.ArrayList;
    11 import java.util.Collection;
    12 import java.util.List;
    13 import java.util.concurrent.Future;
    14 
    15 import javax.swing.AbstractAction;
    16 import javax.swing.JLabel;
    17 import javax.swing.JList;
    18 import javax.swing.JOptionPane;
    19 import javax.swing.JPanel;
    209
    2110import org.openstreetmap.josm.Main;
    22 import org.openstreetmap.josm.actions.downloadtasks.DownloadTaskList;
     11import org.openstreetmap.josm.actions.DownloadAlongAction;
    2312import org.openstreetmap.josm.data.coor.LatLon;
    2413import org.openstreetmap.josm.data.gpx.GpxData;
     
    2716import org.openstreetmap.josm.data.gpx.WayPoint;
    2817import org.openstreetmap.josm.gui.PleaseWaitRunnable;
     18import org.openstreetmap.josm.gui.help.HelpUtil;
    2919import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    30 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
    31 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    32 import org.openstreetmap.josm.tools.GBC;
    33 import org.openstreetmap.josm.tools.ImageProvider;
    3420
    3521/**
     
    3824 * @author fred
    3925 */
    40 public class DownloadAlongTrackAction extends AbstractAction {
     26public class DownloadAlongTrackAction extends DownloadAlongAction {
     27   
    4128    static final int NEAR_TRACK = 0;
    4229    static final int NEAR_WAYPOINTS = 1;
    4330    static final int NEAR_BOTH = 2;
    44    
    45     private static final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "gpxLayer.downloadAlongTrack.distance";
    46     private static final String PREF_DOWNLOAD_ALONG_TRACK_AREA = "gpxLayer.downloadAlongTrack.area";
    47     private static final String PREF_DOWNLOAD_ALONG_TRACK_NEAR = "gpxLayer.downloadAlongTrack.near";
    4831
    49    
    50     private final Integer[] dist = {5000, 500, 50};
    51     private final Integer[] area = {20, 10, 5, 1};
     32    private static final String PREF_DOWNLOAD_ALONG_TRACK_OSM = "downloadAlongTrack.download.osm";
     33    private static final String PREF_DOWNLOAD_ALONG_TRACK_GPS = "downloadAlongTrack.download.gps";
     34
     35    private static final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "downloadAlongTrack.distance";
     36    private static final String PREF_DOWNLOAD_ALONG_TRACK_AREA = "downloadAlongTrack.area";
     37    private static final String PREF_DOWNLOAD_ALONG_TRACK_NEAR = "downloadAlongTrack.near";
    5238   
    5339    private final GpxData data;
    5440
     41    /**
     42     * Constructs a new {@code DownloadAlongTrackAction}
     43     * @param data The GPX data used to download along
     44     */
    5545    public DownloadAlongTrackAction(GpxData data) {
    56         super(tr("Download from OSM along this track"), ImageProvider.get("downloadalongtrack"));
     46        super(tr("Download from OSM along this track"), "downloadalongtrack", null, null, true);
    5747        this.data = data;
    5848    }
     
    6050    @Override
    6151    public void actionPerformed(ActionEvent e) {
    62         /*
    63          * build selection dialog
    64          */
    65         JPanel msg = new JPanel(new GridBagLayout());
    66         msg.add(new JLabel(tr("Download everything within:")), GBC.eol());
    67         String[] s = new String[dist.length];
    68         for (int i = 0; i < dist.length; ++i) {
    69             s[i] = tr("{0} meters", dist[i]);
     52       
     53        final DownloadAlongPanel panel = new DownloadAlongPanel(
     54                PREF_DOWNLOAD_ALONG_TRACK_OSM, PREF_DOWNLOAD_ALONG_TRACK_GPS,
     55                PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, PREF_DOWNLOAD_ALONG_TRACK_AREA, PREF_DOWNLOAD_ALONG_TRACK_NEAR);
     56
     57        if (0 != panel.showInDownloadDialog(tr("Download from OSM along this track"), HelpUtil.ht("/Action/DownloadAlongTrack"))) {
     58            return;
    7059        }
    71         JList buffer = new JList(s);
    72         buffer.setSelectedIndex(Main.pref.getInteger(PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, 0));
    73         msg.add(buffer, GBC.eol());
    74         msg.add(new JLabel(tr("Maximum area per request:")), GBC.eol());
    75         s = new String[area.length];
    76         for (int i = 0; i < area.length; ++i) {
    77             s[i] = tr("{0} sq km", area[i]);
    78         }
    79         JList maxRect = new JList(s);
    80         maxRect.setSelectedIndex(Main.pref.getInteger(PREF_DOWNLOAD_ALONG_TRACK_AREA, 0));
    81         msg.add(maxRect, GBC.eol());
    82         msg.add(new JLabel(tr("Download near:")), GBC.eol());
    83         JList downloadNear = new JList(new String[]{tr("track only"), tr("waypoints only"), tr("track and waypoints")});
    84         downloadNear.setSelectedIndex(Main.pref.getInteger(PREF_DOWNLOAD_ALONG_TRACK_NEAR, 0));
    85         msg.add(downloadNear, GBC.eol());
    86         int ret = JOptionPane.showConfirmDialog(Main.parent, msg, tr("Download from OSM along this track"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
    87         switch (ret) {
    88             case JOptionPane.CANCEL_OPTION:
    89             case JOptionPane.CLOSED_OPTION:
    90                 return;
    91             default:
    92         // continue
    93         }
    94         Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, buffer.getSelectedIndex());
    95         Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_AREA, maxRect.getSelectedIndex());
    96         final int near = downloadNear.getSelectedIndex();
    97         Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_NEAR, near);
     60       
     61        final int near = panel.getNear();
     62
    9863        /*
    9964         * Find the average latitude for the data we're contemplating, so we can know how many
     
    12691         * and then stop because it has more than 50k nodes.
    12792         */
    128         Integer i = buffer.getSelectedIndex();
    129         final int buffer_dist = dist[i < 0 ? 0 : i];
    130         i = maxRect.getSelectedIndex();
    131         final double max_area = area[i < 0 ? 0 : i] / 10000.0 / scale;
     93        final double buffer_dist = panel.getDistance();
     94        final double max_area = panel.getArea() / 10000.0 / scale;
    13295        final double buffer_y = buffer_dist / 100000.0;
    13396        final double buffer_x = buffer_y / scale;
     
    161124                    return;
    162125                }
    163                 confirmAndDownloadAreas(a, max_area, progressMonitor);
     126                confirmAndDownloadAreas(a, max_area, panel.isDownloadOsmData(), panel.isDownloadGpxData(),
     127                        tr("Download from OSM along this track"), progressMonitor);
    164128            }
    165129
     
    223187        Main.worker.submit(new CalculateDownloadArea());
    224188    }
    225 
    226     /**
    227      * Area "a" contains the hull that we would like to download data for. however we
    228      * can only download rectangles, so the following is an attempt at finding a number of
    229      * rectangles to download.
    230      *
    231      * The idea is simply: Start out with the full bounding box. If it is too large, then
    232      * split it in half and repeat recursively for each half until you arrive at something
    233      * small enough to download. The algorithm is improved by always using the intersection
    234      * between the rectangle and the actual desired area. For example, if you have a track
    235      * that goes like this: +----+ | /| | / | | / | |/ | +----+ then we would first look at
    236      * downloading the whole rectangle (assume it's too big), after that we split it in half
    237      * (upper and lower half), but we donot request the full upper and lower rectangle, only
    238      * the part of the upper/lower rectangle that actually has something in it.
    239      *
    240      * This functions calculates the rectangles, asks the user to continue and downloads
    241      * the areas if applicable.
    242      */
    243     private void confirmAndDownloadAreas(Area a, double max_area, ProgressMonitor progressMonitor) {
    244         List<Rectangle2D> toDownload = new ArrayList<Rectangle2D>();
    245         addToDownload(a, a.getBounds(), toDownload, max_area);
    246         if (toDownload.isEmpty()) {
    247             return;
    248         }
    249         JPanel msg = new JPanel(new GridBagLayout());
    250         msg.add(new JLabel(tr("<html>This action will require {0} individual<br>" + "download requests. Do you wish<br>to continue?</html>", toDownload.size())), GBC.eol());
    251         if (toDownload.size() > 1) {
    252             int ret = JOptionPane.showConfirmDialog(Main.parent, msg, tr("Download from OSM along this track"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
    253             switch (ret) {
    254                 case JOptionPane.CANCEL_OPTION:
    255                 case JOptionPane.CLOSED_OPTION:
    256                     return;
    257                 default:
    258             // continue
    259             }
    260         }
    261         final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download data"));
    262         final Future<?> future = new DownloadTaskList().download(false, toDownload, true, false, monitor);
    263         Main.worker.submit(new Runnable() {
    264             @Override
    265             public void run() {
    266                 try {
    267                     future.get();
    268                 } catch (Exception e) {
    269                     e.printStackTrace();
    270                     return;
    271                 }
    272                 monitor.close();
    273             }
    274         });
    275     }
    276    
    277      private static void addToDownload(Area a, Rectangle2D r, Collection<Rectangle2D> results, double max_area) {
    278         Area tmp = new Area(r);
    279         // intersect with sought-after area
    280         tmp.intersect(a);
    281         if (tmp.isEmpty()) {
    282              return;
    283          }
    284         Rectangle2D bounds = tmp.getBounds2D();
    285         if (bounds.getWidth() * bounds.getHeight() > max_area) {
    286             // the rectangle gets too large; split it and make recursive call.
    287             Rectangle2D r1;
    288             Rectangle2D r2;
    289             if (bounds.getWidth() > bounds.getHeight()) {
    290                 // rectangles that are wider than high are split into a left and right half,
    291                 r1 = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth() / 2, bounds.getHeight());
    292                 r2 = new Rectangle2D.Double(bounds.getX() + bounds.getWidth() / 2, bounds.getY(),
    293                         bounds.getWidth() / 2, bounds.getHeight());
    294             } else {
    295                 // others into a top and bottom half.
    296                 r1 = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight() / 2);
    297                 r2 = new Rectangle2D.Double(bounds.getX(), bounds.getY() + bounds.getHeight() / 2, bounds.getWidth(),
    298                         bounds.getHeight() / 2);
    299             }
    300             addToDownload(a, r1, results, max_area);
    301             addToDownload(a, r2, results, max_area);
    302         } else {
    303             results.add(bounds);
    304         }
    305     }
    306    
    307189}
Note: See TracChangeset for help on using the changeset viewer.