Changeset 14962 in josm for trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java
- Timestamp:
- 2019-04-05T09:35:22+02:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.