Changeset 4323 in josm
- Timestamp:
- 2011-08-20T17:05:16+02:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
r4282 r4323 65 65 import org.openstreetmap.josm.gui.MapView; 66 66 import org.openstreetmap.josm.gui.NavigatableComponent; 67 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 67 68 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 68 69 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; … … 72 73 import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 73 74 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; 75 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 74 76 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 75 77 import org.openstreetmap.josm.io.JpgImporter; … … 828 830 */ 829 831 public class DownloadAlongTrackAction extends AbstractAction { 832 final static int NEAR_TRACK=0; 833 final static int NEAR_WAYPOINTS=1; 834 final static int NEAR_BOTH=2; 835 final Integer dist[] = { 5000, 500, 50 }; 836 final Integer area[] = { 20, 10, 5, 1 }; 837 830 838 public DownloadAlongTrackAction() { 831 839 super(tr("Download from OSM along this track"), ImageProvider.get("downloadalongtrack")); … … 834 842 @Override 835 843 public void actionPerformed(ActionEvent e) { 844 /* 845 * build selection dialog 846 */ 836 847 JPanel msg = new JPanel(new GridBagLayout()); 837 Integer dist[] = { 5000, 500, 50 };838 Integer area[] = { 20, 10, 5, 1 };839 848 840 849 msg.add(new JLabel(tr("Download everything within:")), GBC.eol()); … … 858 867 msg.add(new JLabel(tr("Download near:")), GBC.eol()); 859 868 JList downloadNear = new JList(new String[] { tr("track only"), tr("waypoints only"), tr("track and waypoints") }); 860 int NEAR_TRACK=0;861 int NEAR_WAYPOINTS=1;862 int NEAR_BOTH=2;863 869 864 870 downloadNear.setSelectedIndex(Main.pref.getInteger(PREF_DOWNLOAD_ALONG_TRACK_NEAR, 0)); … … 882 888 Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_DISTANCE, buffer.getSelectedIndex()); 883 889 Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_AREA, maxRect.getSelectedIndex()); 884 int near = downloadNear.getSelectedIndex(); 890 final int near = downloadNear.getSelectedIndex(); 885 891 Main.pref.putInteger(PREF_DOWNLOAD_ALONG_TRACK_NEAR, near); 886 892 … … 920 926 */ 921 927 Integer i = buffer.getSelectedIndex(); 922 int buffer_dist = dist[i < 0 ? 0 : i]; 923 double buffer_y = buffer_dist / 100000.0; 924 double buffer_x = buffer_y / scale; 928 final int buffer_dist = dist[i < 0 ? 0 : i]; 925 929 i = maxRect.getSelectedIndex(); 926 double max_area = area[i < 0 ? 0 : i] / 10000.0 / scale; 927 Area a = new Area(); 928 Rectangle2D r = new Rectangle2D.Double(); 929 930 /* 931 * Collect the combined area of all gpx points plus buffer zones around them. We ignore 932 * points that lie closer to the previous point than the given buffer size because 933 * otherwise this operation takes ages. 934 */ 935 LatLon previous = null; 936 if (near == NEAR_TRACK || near == NEAR_BOTH) { 937 for (GpxTrack trk : data.tracks) { 938 for (GpxTrackSegment segment : trk.getSegments()) { 939 for (WayPoint p : segment.getWayPoints()) { 940 LatLon c = p.getCoor(); 941 if (previous == null || c.greatCircleDistance(previous) > buffer_dist) { 942 // we add a buffer around the point. 943 r.setRect(c.lon() - buffer_x, c.lat() - buffer_y, 2 * buffer_x, 2 * buffer_y); 944 a.add(new Area(r)); 945 previous = c; 946 } 947 } 948 } 949 } 950 } 951 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) { 952 for (WayPoint p : data.waypoints) { 930 final double max_area = area[i < 0 ? 0 : i] / 10000.0 / scale; 931 final double buffer_y = buffer_dist / 100000.0; 932 final double buffer_x = buffer_y / scale; 933 934 final int totalTicks = latcnt; 935 // guess if a progress bar might be useful. 936 final boolean displayProgress = totalTicks > 2000 && buffer_y < 0.01; 937 938 class CalculateDownloadArea extends PleaseWaitRunnable { 939 private Area a = new Area(); 940 private boolean cancel = false; 941 private int ticks = 0; 942 private Rectangle2D r = new Rectangle2D.Double(); 943 944 public CalculateDownloadArea() { 945 super(tr("Calculating Download Area"), 946 (displayProgress ? null : NullProgressMonitor.INSTANCE), 947 false); 948 } 949 950 @Override 951 protected void cancel() { 952 cancel = true; 953 } 954 955 @Override 956 protected void finish() { 957 if(cancel) 958 return; 959 confirmAndDownloadAreas(a, max_area, progressMonitor); 960 } 961 962 /** 963 * increase tick count by one, report progress every 100 ticks 964 */ 965 private void tick() { 966 ticks++; 967 if(ticks % 100 == 0) { 968 progressMonitor.worked(100); 969 } 970 } 971 972 /** 973 * calculate area for single, given way point and return new LatLon if the 974 * way point has been used to modify the area. 975 */ 976 private LatLon calcAreaForWayPoint(WayPoint p, LatLon previous) { 977 tick(); 953 978 LatLon c = p.getCoor(); 954 979 if (previous == null || c.greatCircleDistance(previous) > buffer_dist) { … … 956 981 r.setRect(c.lon() - buffer_x, c.lat() - buffer_y, 2 * buffer_x, 2 * buffer_y); 957 982 a.add(new Area(r)); 958 previous = c; 959 } 960 } 961 } 962 963 /* 964 * Area "a" now contains the hull that we would like to download data for. however we 965 * can only download rectangles, so the following is an attempt at finding a number of 966 * rectangles to download. 967 * 968 * The idea is simply: Start out with the full bounding box. If it is too large, then 969 * split it in half and repeat recursively for each half until you arrive at something 970 * small enough to download. The algorithm is improved by always using the intersection 971 * between the rectangle and the actual desired area. For example, if you have a track 972 * that goes like this: +----+ | /| | / | | / | |/ | +----+ then we would first look at 973 * downloading the whole rectangle (assume it's too big), after that we split it in half 974 * (upper and lower half), but we donot request the full upper and lower rectangle, only 975 * the part of the upper/lower rectangle that actually has something in it. 976 */ 977 983 return c; 984 } 985 return previous; 986 } 987 988 @Override 989 protected void realRun() { 990 progressMonitor.setTicksCount(totalTicks); 991 /* 992 * Collect the combined area of all gpx points plus buffer zones around them. We ignore 993 * points that lie closer to the previous point than the given buffer size because 994 * otherwise this operation takes ages. 995 */ 996 LatLon previous = null; 997 if (near == NEAR_TRACK || near == NEAR_BOTH) { 998 for (GpxTrack trk : data.tracks) { 999 for (GpxTrackSegment segment : trk.getSegments()) { 1000 for (WayPoint p : segment.getWayPoints()) { 1001 if(cancel) 1002 return; 1003 previous = calcAreaForWayPoint(p, previous); 1004 } 1005 } 1006 } 1007 } 1008 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) { 1009 for (WayPoint p : data.waypoints) { 1010 if(cancel) 1011 return; 1012 previous = calcAreaForWayPoint(p, previous); 1013 } 1014 } 1015 } 1016 } 1017 1018 Main.worker.submit(new CalculateDownloadArea()); 1019 } 1020 1021 /** 1022 * Area "a" contains the hull that we would like to download data for. however we 1023 * can only download rectangles, so the following is an attempt at finding a number of 1024 * rectangles to download. 1025 * 1026 * The idea is simply: Start out with the full bounding box. If it is too large, then 1027 * split it in half and repeat recursively for each half until you arrive at something 1028 * small enough to download. The algorithm is improved by always using the intersection 1029 * between the rectangle and the actual desired area. For example, if you have a track 1030 * that goes like this: +----+ | /| | / | | / | |/ | +----+ then we would first look at 1031 * downloading the whole rectangle (assume it's too big), after that we split it in half 1032 * (upper and lower half), but we donot request the full upper and lower rectangle, only 1033 * the part of the upper/lower rectangle that actually has something in it. 1034 * 1035 * This functions calculates the rectangles, asks the user to continue and downloads 1036 * the areas if applicable. 1037 */ 1038 private void confirmAndDownloadAreas(Area a, double max_area, ProgressMonitor progressMonitor) { 978 1039 List<Rectangle2D> toDownload = new ArrayList<Rectangle2D>(); 979 1040 980 1041 addToDownload(a, a.getBounds(), toDownload, max_area); 981 1042 982 msg = new JPanel(new GridBagLayout()); 1043 if(toDownload.size() == 0) 1044 return; 1045 1046 JPanel msg = new JPanel(new GridBagLayout()); 983 1047 984 1048 msg.add(new JLabel( … … 988 1052 989 1053 if (toDownload.size() > 1) { 990 ret = JOptionPane.showConfirmDialog( 1054 // hide progress dialog before displaying another pop up. Really closing the 1055 // dialog will be handled by PleaseWaitRunnable. 1056 if (progressMonitor instanceof PleaseWaitProgressMonitor) { 1057 ((PleaseWaitProgressMonitor) progressMonitor).getDialog().setVisible(false); 1058 } 1059 1060 int ret = JOptionPane.showConfirmDialog( 991 1061 Main.parent, 992 1062 msg,
Note:
See TracChangeset
for help on using the changeset viewer.