- Timestamp:
- 2019-04-05T09:35:22+02:00 (6 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/DownloadAlongAction.java
r14868 r14962 6 6 import java.awt.GraphicsEnvironment; 7 7 import java.awt.GridBagLayout; 8 import java.awt.event.ActionEvent; 8 9 import java.awt.geom.Area; 10 import java.awt.geom.Path2D; 11 import java.awt.geom.PathIterator; 9 12 import java.awt.geom.Rectangle2D; 10 13 import java.util.ArrayList; … … 18 21 19 22 import org.openstreetmap.josm.actions.downloadtasks.DownloadTaskList; 23 import org.openstreetmap.josm.data.coor.LatLon; 20 24 import org.openstreetmap.josm.gui.MainApplication; 21 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 25 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 26 import org.openstreetmap.josm.gui.layer.gpx.DownloadAlongPanel; 27 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 22 28 import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor; 23 29 import org.openstreetmap.josm.tools.GBC; 30 import org.openstreetmap.josm.tools.Logging; 24 31 import org.openstreetmap.josm.tools.Shortcut; 32 import org.openstreetmap.josm.tools.Utils; 25 33 26 34 /** … … 29 37 */ 30 38 public abstract class DownloadAlongAction extends JosmAction { 39 40 /** 41 * Sub classes must override this method. 42 * @return the task to start or null if nothing to do 43 */ 44 protected abstract PleaseWaitRunnable createTask(); 31 45 32 46 /** … … 98 112 * @param gpxDownload Set to true if GPX data should be downloaded 99 113 * @param title the title string for the confirmation dialog 100 * @param progressMonitor the progress monitor 101 */ 102 protected static void confirmAndDownloadAreas(Area a, double maxArea, boolean osmDownload, boolean gpxDownload, String title, 103 ProgressMonitor progressMonitor) { 114 */ 115 protected static void confirmAndDownloadAreas(Area a, double maxArea, boolean osmDownload, boolean gpxDownload, String title) { 104 116 List<Rectangle2D> toDownload = new ArrayList<>(); 105 117 addToDownload(a, a.getBounds(), toDownload, maxArea); … … 119 131 waitFuture(future, monitor); 120 132 } 133 134 /** 135 * Calculate list of points between two given points so that the distance between two consecutive points is below a limit. 136 * @param p1 first point or null 137 * @param p2 second point (must not be null) 138 * @param bufferDist the maximum distance 139 * @return a list of points with at least one point (p2) and maybe more. 140 */ 141 protected static Collection<LatLon> calcBetweenPoints(LatLon p1, LatLon p2, double bufferDist) { 142 ArrayList<LatLon> intermediateNodes = new ArrayList<>(); 143 intermediateNodes.add(p2); 144 if (p1 != null && p2.greatCircleDistance(p1) > bufferDist) { 145 Double d = p2.greatCircleDistance(p1) / bufferDist; 146 int nbNodes = d.intValue(); 147 if (Logging.isDebugEnabled()) { 148 Logging.debug(tr("{0} intermediate nodes to download.", nbNodes)); 149 Logging.debug(tr("between {0} {1} and {2} {3}", p2.lat(), p2.lon(), p1.lat(), p1.lon())); 150 } 151 double latStep = (p2.lat() - p1.lat()) / (nbNodes + 1); 152 double lonStep = (p2.lon() - p1.lon()) / (nbNodes + 1); 153 for (int i = 1; i <= nbNodes; i++) { 154 LatLon intermediate = new LatLon(p1.lat() + i * latStep, p1.lon() + i * lonStep); 155 intermediateNodes.add(intermediate); 156 if (Logging.isTraceEnabled()) { 157 Logging.trace(tr(" adding {0} {1}", intermediate.lat(), intermediate.lon())); 158 } 159 } 160 } 161 return intermediateNodes; 162 } 163 164 /** 165 * Create task that downloads areas along the given path using the values specified in the panel. 166 * @param alongPath the path along which the areas are to be downloaded 167 * @param panel the panel that was displayed to the user and now contains his selections 168 * @param confirmTitle the title to display in the confirmation panel 169 * @return the task or null if canceled by user 170 */ 171 protected PleaseWaitRunnable createCalcTask(Path2D alongPath, DownloadAlongPanel panel, String confirmTitle) { 172 /* 173 * Find the average latitude for the data we're contemplating, so we can know how many 174 * metres per degree of longitude we have. 175 */ 176 double latsum = 0; 177 int latcnt = 0; 178 final PathIterator pit = alongPath.getPathIterator(null); 179 final double[] res = new double[6]; 180 while (!pit.isDone()) { 181 int type = pit.currentSegment(res); 182 if (type == PathIterator.SEG_LINETO || type == PathIterator.SEG_MOVETO) { 183 latsum += res[1]; 184 latcnt++; 185 } 186 pit.next(); 187 } 188 if (latcnt == 0) { 189 return null; 190 } 191 final double avglat = latsum / latcnt; 192 final double scale = Math.cos(Utils.toRadians(avglat)); 193 194 /* 195 * Compute buffer zone extents and maximum bounding box size. Note that the maximum we 196 * ever offer is a bbox area of 0.002, while the API theoretically supports 0.25, but as 197 * soon as you touch any built-up area, that kind of bounding box will download forever 198 * and then stop because it has more than 50k nodes. 199 */ 200 final double bufferDist = panel.getDistance(); 201 final double maxArea = panel.getArea() / 10000.0 / scale; 202 final double bufferY = bufferDist / 100000.0; 203 final double bufferX = bufferY / scale; 204 final int totalTicks = latcnt; 205 // guess if a progress bar might be useful. 206 final boolean displayProgress = totalTicks > 20_000 && bufferY < 0.01; 207 208 class CalculateDownloadArea extends PleaseWaitRunnable { 209 210 private final Path2D downloadPath = new Path2D.Double(); 211 private boolean cancel; 212 private int ticks; 213 private final Rectangle2D r = new Rectangle2D.Double(); 214 215 CalculateDownloadArea() { 216 super(tr("Calculating Download Area"), displayProgress ? null : NullProgressMonitor.INSTANCE, false); 217 } 218 219 @Override 220 protected void cancel() { 221 cancel = true; 222 } 223 224 @Override 225 protected void finish() { 226 // Do nothing 227 } 228 229 @Override 230 protected void afterFinish() { 231 if (cancel) { 232 return; 233 } 234 confirmAndDownloadAreas(new Area(downloadPath), maxArea, panel.isDownloadOsmData(), panel.isDownloadGpxData(), 235 confirmTitle); 236 } 237 238 /** 239 * increase tick count by one, report progress every 100 ticks 240 */ 241 private void tick() { 242 ticks++; 243 if (ticks % 100 == 0) { 244 progressMonitor.worked(100); 245 } 246 } 247 248 /** 249 * calculate area enclosing a single point 250 */ 251 private void calcAreaForWayPoint(LatLon c) { 252 r.setRect(c.lon() - bufferX, c.lat() - bufferY, 2 * bufferX, 2 * bufferY); 253 downloadPath.append(r, false); 254 } 255 256 @Override 257 protected void realRun() { 258 progressMonitor.setTicksCount(totalTicks); 259 PathIterator pit = alongPath.getPathIterator(null); 260 double[] res = new double[6]; 261 LatLon previous = null; 262 while (!pit.isDone()) { 263 int type = pit.currentSegment(res); 264 LatLon c = new LatLon(res[1], res[0]); 265 if (type == PathIterator.SEG_LINETO) { 266 tick(); 267 for (LatLon d : calcBetweenPoints(previous, c, bufferDist)) { 268 calcAreaForWayPoint(d); 269 } 270 previous = c; 271 } else if (type == PathIterator.SEG_MOVETO) { 272 previous = c; 273 tick(); 274 calcAreaForWayPoint(c); 275 } 276 pit.next(); 277 } 278 } 279 } 280 281 return new CalculateDownloadArea(); 282 } 283 284 @Override 285 public void actionPerformed(ActionEvent e) { 286 PleaseWaitRunnable task = createTask(); 287 if (task != null) { 288 MainApplication.worker.submit(task); 289 } 290 } 121 291 } -
trunk/src/org/openstreetmap/josm/gui/MainMenu.java
r14648 r14962 43 43 import org.openstreetmap.josm.actions.DistributeAction; 44 44 import org.openstreetmap.josm.actions.DownloadAction; 45 import org.openstreetmap.josm.actions.DownloadAlongWayAction; 45 46 import org.openstreetmap.josm.actions.DownloadNotesInViewAction; 46 47 import org.openstreetmap.josm.actions.DownloadOsmInViewAction; 47 48 import org.openstreetmap.josm.actions.DownloadPrimitiveAction; 48 49 import org.openstreetmap.josm.actions.DownloadReferrersAction; 50 import org.openstreetmap.josm.actions.DrawBoundariesOfDownloadedDataAction; 49 51 import org.openstreetmap.josm.actions.DuplicateAction; 50 52 import org.openstreetmap.josm.actions.ExitAction; … … 53 55 import org.openstreetmap.josm.actions.FullscreenToggleAction; 54 56 import org.openstreetmap.josm.actions.GpxExportAction; 55 import org.openstreetmap.josm.actions.DrawBoundariesOfDownloadedDataAction;56 57 import org.openstreetmap.josm.actions.HelpAction; 57 58 import org.openstreetmap.josm.actions.HistoryInfoAction; … … 282 283 /** Tools / Update multipolygon */ 283 284 public final CreateMultipolygonAction updateMultipolygon = new CreateMultipolygonAction(true); 285 /** Tools / Download along way */ 286 public final DownloadAlongWayAction downloadAlongWay = new DownloadAlongWayAction(); 284 287 285 288 /* Selection menu */ … … 816 819 add(toolsMenu, createMultipolygon); 817 820 add(toolsMenu, updateMultipolygon); 821 add(toolsMenu, downloadAlongWay); 818 822 819 823 // -- changeset manager toggle action -
trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java
r14875 r14962 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.event.ActionEvent;7 import java.awt.geom.Area;8 6 import java.awt.geom.Path2D; 9 import java.awt.geom.Rectangle2D;10 7 11 8 import org.openstreetmap.josm.actions.DownloadAlongAction; 12 import org.openstreetmap.josm.data.coor.LatLon;13 9 import org.openstreetmap.josm.data.gpx.GpxData; 14 10 import org.openstreetmap.josm.data.gpx.GpxTrack; 15 11 import org.openstreetmap.josm.data.gpx.GpxTrackSegment; 16 12 import org.openstreetmap.josm.data.gpx.WayPoint; 17 import org.openstreetmap.josm.gui.MainApplication;18 13 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 19 14 import org.openstreetmap.josm.gui.help.HelpUtil; 20 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;21 import org.openstreetmap.josm.tools.Utils;22 15 23 16 /** … … 51 44 } 52 45 53 PleaseWaitRunnable createTask() { 46 @Override 47 protected PleaseWaitRunnable createTask() { 54 48 final DownloadAlongPanel panel = new DownloadAlongPanel( 55 49 PREF_DOWNLOAD_ALONG_TRACK_OSM, PREF_DOWNLOAD_ALONG_TRACK_GPS, … … 62 56 final int near = panel.getNear(); 63 57 64 /* 65 * Find the average latitude for the data we're contemplating, so we can know how many 66 * metres per degree of longitude we have. 67 */ 68 double latsum = 0; 69 int latcnt = 0; 58 // Convert the GPX data into a Path2D. 59 Path2D gpxPath = new Path2D.Double(); 70 60 if (near == NEAR_TRACK || near == NEAR_BOTH) { 71 61 for (GpxTrack trk : data.tracks) { 72 62 for (GpxTrackSegment segment : trk.getSegments()) { 63 boolean first = true; 73 64 for (WayPoint p : segment.getWayPoints()) { 74 latsum += p.lat(); 75 latcnt++; 65 if (first) { 66 gpxPath.moveTo(p.lon(), p.lat()); 67 first = false; 68 } else { 69 gpxPath.lineTo(p.lon(), p.lat()); 70 } 76 71 } 77 72 } … … 80 75 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) { 81 76 for (WayPoint p : data.waypoints) { 82 latsum += p.getCoor().lat();83 latcnt++;77 gpxPath.moveTo(p.lon(), p.lat()); 78 gpxPath.closePath(); 84 79 } 85 80 } 86 if (latcnt == 0) { 87 return null; 88 } 89 double avglat = latsum / latcnt; 90 double scale = Math.cos(Utils.toRadians(avglat)); 91 /* 92 * Compute buffer zone extents and maximum bounding box size. Note that the maximum we 93 * ever offer is a bbox area of 0.002, while the API theoretically supports 0.25, but as 94 * soon as you touch any built-up area, that kind of bounding box will download forever 95 * and then stop because it has more than 50k nodes. 96 */ 97 final double bufferDist = panel.getDistance(); 98 final double maxArea = panel.getArea() / 10000.0 / scale; 99 final double bufferY = bufferDist / 100000.0; 100 final double bufferX = bufferY / scale; 101 final int totalTicks = latcnt; 102 // guess if a progress bar might be useful. 103 final boolean displayProgress = totalTicks > 200_000 && bufferY < 0.01; 104 105 class CalculateDownloadArea extends PleaseWaitRunnable { 106 107 private final Path2D path = new Path2D.Double(); 108 private boolean cancel; 109 private int ticks; 110 private final Rectangle2D r = new Rectangle2D.Double(); 111 112 CalculateDownloadArea() { 113 super(tr("Calculating Download Area"), displayProgress ? null : NullProgressMonitor.INSTANCE, false); 114 } 115 116 @Override 117 protected void cancel() { 118 cancel = true; 119 } 120 121 @Override 122 protected void finish() { 123 // Do nothing 124 } 125 126 @Override 127 protected void afterFinish() { 128 if (cancel) { 129 return; 130 } 131 confirmAndDownloadAreas(new Area(path), maxArea, panel.isDownloadOsmData(), panel.isDownloadGpxData(), 132 tr("Download from OSM along this track"), progressMonitor); 133 } 134 135 /** 136 * increase tick count by one, report progress every 100 ticks 137 */ 138 private void tick() { 139 ticks++; 140 if (ticks % 100 == 0) { 141 progressMonitor.worked(100); 142 } 143 } 144 145 /** 146 * calculate area for single, given way point and return new LatLon if the 147 * way point has been used to modify the area. 148 */ 149 private LatLon calcAreaForWayPoint(WayPoint p, LatLon previous) { 150 tick(); 151 LatLon c = p.getCoor(); 152 if (previous == null || c.greatCircleDistance(previous) > bufferDist) { 153 // we add a buffer around the point. 154 r.setRect(c.lon() - bufferX, c.lat() - bufferY, 2 * bufferX, 2 * bufferY); 155 path.append(r, false); 156 return c; 157 } 158 return previous; 159 } 160 161 @Override 162 protected void realRun() { 163 progressMonitor.setTicksCount(totalTicks); 164 /* 165 * Collect the combined area of all gpx points plus buffer zones around them. We ignore 166 * points that lie closer to the previous point than the given buffer size because 167 * otherwise this operation takes ages. 168 */ 169 LatLon previous = null; 170 if (near == NEAR_TRACK || near == NEAR_BOTH) { 171 for (GpxTrack trk : data.tracks) { 172 for (GpxTrackSegment segment : trk.getSegments()) { 173 for (WayPoint p : segment.getWayPoints()) { 174 if (cancel) { 175 return; 176 } 177 previous = calcAreaForWayPoint(p, previous); 178 } 179 } 180 } 181 } 182 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) { 183 for (WayPoint p : data.waypoints) { 184 if (cancel) { 185 return; 186 } 187 previous = calcAreaForWayPoint(p, previous); 188 } 189 } 190 } 191 } 192 193 return new CalculateDownloadArea(); 194 } 195 196 @Override 197 public void actionPerformed(ActionEvent e) { 198 PleaseWaitRunnable task = createTask(); 199 if (task != null) { 200 MainApplication.worker.submit(task); 201 } 81 return createCalcTask(gpxPath, panel, tr("Download from OSM along this track")); 202 82 } 203 83 } -
trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
r14924 r14962 146 146 new DeprecatedPlugin("videomapping", tr("no longer required")), 147 147 new DeprecatedPlugin("public_transport_layer", tr("replaced by new {0} plugin", "pt_assistant")), 148 new DeprecatedPlugin("lakewalker", tr("replaced by new {0} plugin", "scanaerial")) 148 new DeprecatedPlugin("lakewalker", tr("replaced by new {0} plugin", "scanaerial")), 149 new DeprecatedPlugin("download_along", inCore) 149 150 ); 150 151 }
Note:
See TracChangeset
for help on using the changeset viewer.