source: josm/trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java@ 10001

Last change on this file since 10001 was 10001, checked in by Don-vip, 8 years ago

sonar - Local variable and method parameter names should comply with a naming convention

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer.gpx;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.geom.Area;
8import java.awt.geom.Rectangle2D;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.actions.DownloadAlongAction;
12import org.openstreetmap.josm.data.coor.LatLon;
13import org.openstreetmap.josm.data.gpx.GpxData;
14import org.openstreetmap.josm.data.gpx.GpxTrack;
15import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
16import org.openstreetmap.josm.data.gpx.WayPoint;
17import org.openstreetmap.josm.gui.PleaseWaitRunnable;
18import org.openstreetmap.josm.gui.help.HelpUtil;
19import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
20
21/**
22 * Action that issues a series of download requests to the API, following the GPX track.
23 *
24 * @author fred
25 * @since 5715
26 */
27public class DownloadAlongTrackAction extends DownloadAlongAction {
28
29 private static final int NEAR_TRACK = 0;
30 private static final int NEAR_WAYPOINTS = 1;
31 private static final int NEAR_BOTH = 2;
32
33 private static final String PREF_DOWNLOAD_ALONG_TRACK_OSM = "downloadAlongTrack.download.osm";
34 private static final String PREF_DOWNLOAD_ALONG_TRACK_GPS = "downloadAlongTrack.download.gps";
35
36 private static final String PREF_DOWNLOAD_ALONG_TRACK_DISTANCE = "downloadAlongTrack.distance";
37 private static final String PREF_DOWNLOAD_ALONG_TRACK_AREA = "downloadAlongTrack.area";
38 private static final String PREF_DOWNLOAD_ALONG_TRACK_NEAR = "downloadAlongTrack.near";
39
40 private final transient GpxData data;
41
42 /**
43 * Constructs a new {@code DownloadAlongTrackAction}
44 * @param data The GPX data used to download along
45 */
46 public DownloadAlongTrackAction(GpxData data) {
47 super(tr("Download from OSM along this track"), "downloadalongtrack", null, null, false);
48 this.data = data;
49 }
50
51 PleaseWaitRunnable createTask() {
52 final DownloadAlongPanel panel = new DownloadAlongPanel(
53 PREF_DOWNLOAD_ALONG_TRACK_OSM, PREF_DOWNLOAD_ALONG_TRACK_GPS,
54 PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, PREF_DOWNLOAD_ALONG_TRACK_AREA, PREF_DOWNLOAD_ALONG_TRACK_NEAR);
55
56 if (0 != panel.showInDownloadDialog(tr("Download from OSM along this track"), HelpUtil.ht("/Action/DownloadAlongTrack"))) {
57 return null;
58 }
59
60 final int near = panel.getNear();
61
62 /*
63 * Find the average latitude for the data we're contemplating, so we can know how many
64 * metres per degree of longitude we have.
65 */
66 double latsum = 0;
67 int latcnt = 0;
68 if (near == NEAR_TRACK || near == NEAR_BOTH) {
69 for (GpxTrack trk : data.tracks) {
70 for (GpxTrackSegment segment : trk.getSegments()) {
71 for (WayPoint p : segment.getWayPoints()) {
72 latsum += p.getCoor().lat();
73 latcnt++;
74 }
75 }
76 }
77 }
78 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) {
79 for (WayPoint p : data.waypoints) {
80 latsum += p.getCoor().lat();
81 latcnt++;
82 }
83 }
84 if (latcnt == 0) {
85 return null;
86 }
87 double avglat = latsum / latcnt;
88 double scale = Math.cos(Math.toRadians(avglat));
89 /*
90 * Compute buffer zone extents and maximum bounding box size. Note that the maximum we
91 * ever offer is a bbox area of 0.002, while the API theoretically supports 0.25, but as
92 * soon as you touch any built-up area, that kind of bounding box will download forever
93 * and then stop because it has more than 50k nodes.
94 */
95 final double bufferDist = panel.getDistance();
96 final double maxArea = panel.getArea() / 10000.0 / scale;
97 final double bufferY = bufferDist / 100000.0;
98 final double bufferX = bufferY / scale;
99 final int totalTicks = latcnt;
100 // guess if a progress bar might be useful.
101 final boolean displayProgress = totalTicks > 2000 && bufferY < 0.01;
102
103 class CalculateDownloadArea extends PleaseWaitRunnable {
104
105 private final Area a = new Area();
106 private boolean cancel;
107 private int ticks;
108 private final Rectangle2D r = new Rectangle2D.Double();
109
110 CalculateDownloadArea() {
111 super(tr("Calculating Download Area"), displayProgress ? null : NullProgressMonitor.INSTANCE, false);
112 }
113
114 @Override
115 protected void cancel() {
116 cancel = true;
117 }
118
119 @Override
120 protected void finish() {
121 }
122
123 @Override
124 protected void afterFinish() {
125 if (cancel) {
126 return;
127 }
128 confirmAndDownloadAreas(a, maxArea, panel.isDownloadOsmData(), panel.isDownloadGpxData(),
129 tr("Download from OSM along this track"), progressMonitor);
130 }
131
132 /**
133 * increase tick count by one, report progress every 100 ticks
134 */
135 private void tick() {
136 ticks++;
137 if (ticks % 100 == 0) {
138 progressMonitor.worked(100);
139 }
140 }
141
142 /**
143 * calculate area for single, given way point and return new LatLon if the
144 * way point has been used to modify the area.
145 */
146 private LatLon calcAreaForWayPoint(WayPoint p, LatLon previous) {
147 tick();
148 LatLon c = p.getCoor();
149 if (previous == null || c.greatCircleDistance(previous) > bufferDist) {
150 // we add a buffer around the point.
151 r.setRect(c.lon() - bufferX, c.lat() - bufferY, 2 * bufferX, 2 * bufferY);
152 a.add(new Area(r));
153 return c;
154 }
155 return previous;
156 }
157
158 @Override
159 protected void realRun() {
160 progressMonitor.setTicksCount(totalTicks);
161 /*
162 * Collect the combined area of all gpx points plus buffer zones around them. We ignore
163 * points that lie closer to the previous point than the given buffer size because
164 * otherwise this operation takes ages.
165 */
166 LatLon previous = null;
167 if (near == NEAR_TRACK || near == NEAR_BOTH) {
168 for (GpxTrack trk : data.tracks) {
169 for (GpxTrackSegment segment : trk.getSegments()) {
170 for (WayPoint p : segment.getWayPoints()) {
171 if (cancel) {
172 return;
173 }
174 previous = calcAreaForWayPoint(p, previous);
175 }
176 }
177 }
178 }
179 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) {
180 for (WayPoint p : data.waypoints) {
181 if (cancel) {
182 return;
183 }
184 previous = calcAreaForWayPoint(p, previous);
185 }
186 }
187 }
188 }
189
190 return new CalculateDownloadArea();
191 }
192
193 @Override
194 public void actionPerformed(ActionEvent e) {
195 PleaseWaitRunnable task = createTask();
196 if (task != null) {
197 Main.worker.submit(task);
198 }
199 }
200}
Note: See TracBrowser for help on using the repository browser.