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

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

sonar - squid:S3052 - Fields should not be initialized to default values

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