source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java@ 1690

Last change on this file since 1690 was 1690, checked in by Gubaer, 15 years ago

new: MultiFetchServerObjectReader using APIs Multi Fetch method
update: now uses Multi Fetch to check for deleted primitives on the server
update: now uses Multi Fetch to update the selected primitives with the state from the server
fixed: cleaned up merging in MergeVisitor
new: conflict resolution dialog; now resolves conflicts due to different visibilities
new: replacement for realEqual() on OsmPrimitive and derived classes; realEqual now @deprecated
fixed: cleaning up OsmReader
fixed: progress indication in OsmApi

File size: 6.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.EventQueue;
7import java.awt.event.ActionEvent;
8import java.awt.geom.Area;
9import java.awt.geom.Rectangle2D;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.LinkedList;
14import java.util.List;
15import java.util.Set;
16
17import javax.swing.JOptionPane;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.actions.UpdateSelectionAction;
21import org.openstreetmap.josm.data.osm.DataSet;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
24import org.openstreetmap.josm.gui.layer.Layer;
25import org.openstreetmap.josm.gui.layer.OsmDataLayer;
26
27/**
28 * This class encapsulates the downloading of several bounding boxes that would otherwise be too
29 * large to download in one go. Error messages will be collected for all downloads and displayed
30 * as a list in the end.
31 * @author xeen
32 *
33 */
34public class DownloadOsmTaskList implements Runnable {
35 private List<DownloadTask> osmTasks = new LinkedList<DownloadTask>();
36
37 /**
38 * Downloads a list of areas from the OSM Server
39 * @param newLayer Set to true if all areas should be put into a single new layer
40 * @param The List of Rectangle2D to download
41 */
42 public void download(boolean newLayer, List<Rectangle2D> rects) {
43 if(newLayer) {
44 Layer l = new OsmDataLayer(new DataSet(), tr("Data Layer"), null);
45 Main.main.addLayer(l);
46 Main.map.mapView.setActiveLayer(l);
47 }
48
49 int i = 0;
50 for(Rectangle2D td : rects) {
51 i++;
52 DownloadTask dt = new DownloadOsmTask();
53 dt.download(null, td.getMinY(), td.getMinX(), td.getMaxY(), td.getMaxX(), true,
54 tr("Download {0} of {1} ({2} left)", i, rects.size(), rects.size()-i));
55 osmTasks.add(dt);
56 }
57
58 // If we try to get the error message now the download task will never have been started
59 // and we'd be stuck in a classical dead lock. Instead attach this to the worker and once
60 // run() gets called all downloadTasks have finished and we can grab the error messages.
61 Main.worker.execute(this);
62 }
63
64 /**
65 * Downloads a list of areas from the OSM Server
66 * @param newLayer Set to true if all areas should be put into a single new layer
67 * @param The Collection of Areas to download
68 */
69 public void download(boolean newLayer, Collection<Area> areas) {
70 List<Rectangle2D> rects = new LinkedList<Rectangle2D>();
71 for(Area a : areas) {
72 rects.add(a.getBounds2D());
73 }
74
75 download(newLayer, rects);
76 }
77
78 /**
79 * Grabs and displays the error messages after all download threads have finished.
80 */
81 public void run() {
82 String errors = "";
83
84 for(DownloadTask dt : osmTasks) {
85 String err = dt.getErrorMessage();
86 if(err.equals("")) {
87 continue;
88 }
89 errors += "* " + err + "\r\n";
90 }
91
92 if(! errors.equals("")) {
93 JOptionPane.showMessageDialog(Main.parent,
94 tr("The following errors occurred during mass download:") + "\r\n" + errors,
95 tr("Errors during Download"),
96 JOptionPane.ERROR_MESSAGE);
97 return;
98 }
99
100 Set<Long> myPrimitiveIds = Main.main.editLayer().data.getPrimitiveIds();
101 Set<Long> downloadedIds = getDownloadedIds();
102 myPrimitiveIds.removeAll(downloadedIds);
103 myPrimitiveIds.remove(new Long(0));
104 if (! myPrimitiveIds.isEmpty()) {
105 handlePotentiallyDeletedPrimitives(myPrimitiveIds);
106 }
107 }
108
109 protected void checkPotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) {
110 DataSet ds = Main.main.editLayer().data;
111 ArrayList<OsmPrimitive> toSelect = new ArrayList<OsmPrimitive>();
112 for (Long id : potentiallyDeleted) {
113 OsmPrimitive primitive = ds.getPrimitiveById(id);
114 if (primitive != null) {
115 toSelect.add(primitive);
116 }
117 }
118 ds.setSelected(toSelect);
119 EventQueue.invokeLater(
120 new Runnable() {
121 public void run() {
122 new UpdateSelectionAction().actionPerformed(new ActionEvent(this, 0, ""));
123 }
124 }
125 );
126 }
127
128 protected void handlePotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) {
129 String [] options = {
130 "Check on the server",
131 "Ignore"
132 };
133
134 String message = tr("<html>"
135 + "There are {0} primitives in your local dataset which<br>"
136 + "might be deleted on the server. If you later try to delete or<br>"
137 + "update them the server is likely to report a<br>"
138 + "conflict.<br>"
139 + "<br>"
140 + "Click <strong>{1}</strong> to check the state of these primitives<br>"
141 + "on the server.<br>"
142 + "Click <strong>{2}</strong> to ignore.<br>"
143 + "</html>",
144 potentiallyDeleted.size(), options[0], options[1]
145 );
146
147 int ret = JOptionPane.showOptionDialog(
148 Main.parent,
149 message,
150 tr("Deleted or moved primitives"),
151 JOptionPane.YES_NO_OPTION,
152 JOptionPane.WARNING_MESSAGE,
153 null,
154 options,
155 options[0]
156 );
157 switch(ret) {
158 case JOptionPane.CLOSED_OPTION: return;
159 case JOptionPane.NO_OPTION: return;
160 case JOptionPane.YES_OPTION: checkPotentiallyDeletedPrimitives(potentiallyDeleted); break;
161 }
162 }
163
164 protected boolean wasDownloaded(long id, DataSet ds) {
165 OsmPrimitive primitive = ds.getPrimitiveById(id);
166 return primitive != null;
167 }
168
169 public boolean wasDownloaded(long id) {
170 for (DownloadTask task : osmTasks) {
171 if(task instanceof DownloadOsmTask) {
172 DataSet ds = ((DownloadOsmTask)task).getDownloadedData();
173 if(wasDownloaded(id,ds)) return true;
174 }
175 }
176 return false;
177 }
178
179 public Set<Long> getDownloadedIds() {
180 HashSet<Long> ret = new HashSet<Long>();
181 for (DownloadTask task : osmTasks) {
182 if(task instanceof DownloadOsmTask) {
183 DataSet ds = ((DownloadOsmTask)task).getDownloadedData();
184 ret.addAll(ds.getPrimitiveIds());
185 }
186 }
187 return ret;
188 }
189}
Note: See TracBrowser for help on using the repository browser.