Changeset 34838 in osm for applications/editors/josm/plugins/download_along/src/org
- Timestamp:
- 2019-01-17T12:10:13+01:00 (6 years ago)
- 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 7 7 import org.openstreetmap.josm.plugins.PluginInformation; 8 8 9 /** 10 * Plugin to calculate a list of areas around a selection of ways. 11 */ 9 12 public class DownloadAlong extends Plugin { 10 13 -
applications/editors/josm/plugins/download_along/src/org/openstreetmap/josm/plugin/download_along/DownloadAlongWayAction.java
r34503 r34838 11 11 import java.util.ArrayList; 12 12 import java.util.Collection; 13 import java.util.Set;14 15 13 import javax.swing.JOptionPane; 16 14 … … 28 26 import org.openstreetmap.josm.tools.Utils; 29 27 28 /** 29 * Calculate area around selected ways and split it into reasonable parts so 30 * that they can be downloaded. 31 * 32 */ 30 33 class DownloadAlongWayAction extends DownloadAlongAction { 31 34 … … 44 47 @Override 45 48 public void actionPerformed(ActionEvent e) { 46 Set<Way> selectedWays =OsmPrimitive.getFilteredSet(getLayerManager().getEditDataSet().getSelected(), Way.class);49 Collection<Way> selectedWays = getLayerManager().getEditDataSet().getSelectedWays(); 47 50 48 51 if (selectedWays.isEmpty()) { … … 62 65 long start = System.currentTimeMillis(); 63 66 67 double scale = calcScale(selectedWays); 68 64 69 /* 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. 67 75 */ 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) { 68 144 double latsum = 0; 69 145 int latcnt = 0; … … 75 151 } 76 152 } 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)); 135 156 } 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; 140 158 } 141 159
Note:
See TracChangeset
for help on using the changeset viewer.