Changeset 34838 in osm for applications/editors/josm


Ignore:
Timestamp:
2019-01-17T12:10:13+01:00 (5 years ago)
Author:
gerdp
Message:

fix #16883 Isn't downloading along all the way

  • refactore the code so that no deprecated methods are used and code complexity is smaller
  • add some javadoc
Location:
applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along/DownloadAlong.java

    r33710 r34838  
    77import org.openstreetmap.josm.plugins.PluginInformation;
    88
     9/**
     10 * Plugin to calculate a list of areas around a selection of ways.
     11 */
    912public class DownloadAlong extends Plugin {
    1013
  • applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along/DownloadAlongWayAction.java

    r34503 r34838  
    1111import java.util.ArrayList;
    1212import java.util.Collection;
    13 import java.util.Set;
    14 
    1513import javax.swing.JOptionPane;
    1614
     
    2826import org.openstreetmap.josm.tools.Utils;
    2927
     28/**
     29 * Calculate area around selected ways and split it into reasonable parts so
     30 * that they can be downloaded.
     31 *
     32 */
    3033class DownloadAlongWayAction extends DownloadAlongAction {
    3134
     
    4447    @Override
    4548    public void actionPerformed(ActionEvent e) {
    46         Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getLayerManager().getEditDataSet().getSelected(), Way.class);
     49        Collection<Way> selectedWays = getLayerManager().getEditDataSet().getSelectedWays();
    4750
    4851        if (selectedWays.isEmpty()) {
     
    6265        long start = System.currentTimeMillis();
    6366
     67        double scale = calcScale(selectedWays);
     68       
    6469        /*
    65          * Find the average latitude for the data we're contemplating, so we
    66          * can know how many metres per degree of longitude we have.
     70         * Compute buffer zone extents and maximum bounding box size. Note
     71         * that the maximum we ever offer is a bbox area of 0.002, while the
     72         * API theoretically supports 0.25, but as soon as you touch any
     73         * built-up area, that kind of bounding box will download forever
     74         * and then stop because it has more than 50k nodes.
    6775         */
     76        double bufferDist = panel.getDistance();
     77        double bufferY = bufferDist / 100000.0;
     78        double bufferX = bufferY / scale;
     79        double maxArea = panel.getArea() / 10000.0 / scale;
     80        Path2D path = new Path2D.Double();
     81        Rectangle2D r = new Rectangle2D.Double();
     82
     83        /*
     84         * Collect the combined area of all points plus buffer zones
     85         * around them. We ignore points that lie closer to the previous
     86         * point than the given buffer size because otherwise this operation
     87         * takes ages.
     88         */
     89        LatLon previous = null;
     90        for (Way way : selectedWays) {
     91            for (Node p : way.getNodes()) {
     92                LatLon c = p.getCoor();
     93                for (LatLon d : calcBetween(previous, c, bufferDist)) {
     94                    // we add a buffer around the point.
     95                    r.setRect(d.lon() - bufferX, d.lat() - bufferY, 2 * bufferX, 2 * bufferY);
     96                    path.append(r, false);
     97                }
     98                previous = c;
     99            }
     100        }
     101        Area a = new Area(path);
     102       
     103        Logging.info("Area computed in " + Utils.getDurationString(System.currentTimeMillis() - start));
     104        confirmAndDownloadAreas(a, maxArea, panel.isDownloadOsmData(), panel.isDownloadGpxData(),
     105                tr("Download from OSM along selected ways"), NullProgressMonitor.INSTANCE);
     106    }
     107
     108    /**
     109     * Calculate list of points between two given points so that the distance between two consecutive points is below a limit.     
     110     * @param p1 first point or null
     111     * @param p2 second point (must not be null)
     112     * @param bufferDist the maximum distance
     113     * @return a list of points with at least one point (p2) and maybe more.
     114     */
     115    private static Collection<? extends LatLon> calcBetween(LatLon p1, LatLon p2, double bufferDist) {
     116        ArrayList<LatLon> intermediateNodes = new ArrayList<>();
     117        intermediateNodes.add(p2);
     118        if (p1 != null && p2.greatCircleDistance(p1) > bufferDist) {
     119            Double d = p2.greatCircleDistance(p1) / bufferDist;
     120            int nbNodes = d.intValue();
     121            if (Logging.isDebugEnabled()) {
     122                Logging.debug(tr("{0} intermediate nodes to download.", nbNodes));
     123                Logging.debug(tr("between {0} {1} and {2} {3}", p2.lat(), p2.lon(), p1.lat(), p1.lon()));
     124            }
     125            double latStep = (p2.lat() - p1.lat()) / (nbNodes + 1);
     126            double lonStep = (p2.lon() - p1.lon()) / (nbNodes + 1);
     127            for (int i = 1; i <= nbNodes; i++) {
     128                LatLon intermediate = new LatLon(p1.lat() + i * latStep, p1.lon() + i * lonStep);
     129                intermediateNodes.add(intermediate);
     130                if (Logging.isTraceEnabled()) {
     131                    Logging.trace(tr("  adding {0} {1}", intermediate.lat(), intermediate.lon()));
     132                }
     133            }
     134        }
     135        return intermediateNodes;
     136    }
     137
     138    /**
     139     * Find the average latitude for the data we're contemplating, so we
     140     * can know how many metres per degree of longitude we have.
     141     * @param selectedWays collection of ways
     142     */
     143    private static double calcScale(Collection<Way> selectedWays) {
    68144        double latsum = 0;
    69145        int latcnt = 0;
     
    75151            }
    76152        }
    77 
    78         double avglat = latsum / latcnt;
    79         double scale = Math.cos(Math.toRadians(avglat));
    80 
    81         /*
    82          * Compute buffer zone extents and maximum bounding box size. Note
    83          * that the maximum we ever offer is a bbox area of 0.002, while the
    84          * API theoretically supports 0.25, but as soon as you touch any
    85          * built-up area, that kind of bounding box will download forever
    86          * and then stop because it has more than 50k nodes.
    87          */
    88         double buffer_dist = panel.getDistance();
    89         double buffer_y = buffer_dist / 100000.0;
    90         double buffer_x = buffer_y / scale;
    91         double max_area = panel.getArea() / 10000.0 / scale;
    92         Path2D path = new Path2D.Double();
    93         Rectangle2D r = new Rectangle2D.Double();
    94 
    95         /*
    96          * Collect the combined area of all gpx points plus buffer zones
    97          * around them. We ignore points that lie closer to the previous
    98          * point than the given buffer size because otherwise this operation
    99          * takes ages.
    100          */
    101         LatLon previous = null;
    102         for (Way way : selectedWays) {
    103             for (Node p : way.getNodes()) {
    104                 LatLon c = p.getCoor();
    105                 ArrayList<LatLon> intermediateNodes = new ArrayList<>();
    106                 if (previous != null && c.greatCircleDistance(previous) > buffer_dist) {
    107                     Double d = c.greatCircleDistance(previous) / buffer_dist;
    108                     int nbNodes = d.intValue();
    109                     if (Logging.isDebugEnabled()) {
    110                         Logging.debug(tr("{0} intermediate nodes to download.", nbNodes));
    111                         Logging.debug(tr("between {0} {1} and {2} {3}", c.lat(), c.lon(), previous.lat(), previous.lon()));
    112                     }
    113                     for (int i = 1; i < nbNodes; i++) {
    114                         intermediateNodes.add(new LatLon(previous.lat()
    115                                 + (i * (c.lat() - previous.lat()) / (nbNodes + 1)), previous.lon()
    116                                 + (i * (c.lon() - previous.lon()) / (nbNodes + 1))));
    117                         if (Logging.isTraceEnabled()) {
    118                             Logging.trace(tr("  adding {0} {1}", previous.lat()
    119                                     + (i * (c.lat() - previous.lat()) / (nbNodes + 1)), previous.lon()
    120                                     + (i * (c.lon() - previous.lon()) / (nbNodes + 1))));
    121                         }
    122                     }
    123                 }
    124                 intermediateNodes.add(c);
    125                 for (LatLon d : intermediateNodes) {
    126                     if (previous == null || d.greatCircleDistance(previous) > buffer_dist) {
    127                         // we add a buffer around the point.
    128                         r.setRect(d.lon() - buffer_x, d.lat() - buffer_y, 2 * buffer_x, 2 * buffer_y);
    129                         path.append(r, false);
    130                         previous = d;
    131                     }
    132                 }
    133                 previous = c;
    134             }
     153        if (latcnt > 0) {
     154            double avglat = latsum / latcnt;
     155            return Math.cos(Math.toRadians(avglat));
    135156        }
    136         Area a = new Area(path);
    137         Logging.info("Area computed in " + Utils.getDurationString(System.currentTimeMillis() - start));
    138         confirmAndDownloadAreas(a, max_area, panel.isDownloadOsmData(), panel.isDownloadGpxData(),
    139                 tr("Download from OSM along selected ways"), NullProgressMonitor.INSTANCE);
     157        return 1;
    140158    }
    141159
Note: See TracChangeset for help on using the changeset viewer.