Ticket #24717: 24717-v1.patch
| File 24717-v1.patch, 7.1 KB (added by , 2 weeks ago) |
|---|
-
src/org/openstreetmap/josm/actions/UpdateDataAction.java
From Mon Sep 17 00:00:00 2001 From: Matt McCutchen <matt@mattmccutchen.net> Date: Thu, 15 Oct 2026 16:21:55 -0400 In PostDownloadProcessor, decide whether to use the full-update algorithm for detecting potentially deleted primitives based on whether the "Update data" action was used rather than comparing the bounding boxes. Fixes a bug where area optimization would confuse the bounding box comparison (#24717). --- .../josm/actions/UpdateDataAction.java | 29 +----------- .../actions/downloadtasks/DownloadTaskList.java | 52 +++++++++++++++++++--- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/org/openstreetmap/josm/actions/UpdateDataAction.java b/src/org/openstreetmap/josm/actions/UpdateDataAction.java index 35f375054c..eabb643b5a 100644
a b import static org.openstreetmap.josm.tools.I18n.tr; 6 6 7 7 import java.awt.event.ActionEvent; 8 8 import java.awt.event.KeyEvent; 9 import java.awt.geom.Area;10 import java.util.List;11 9 import java.util.concurrent.Future; 12 10 import java.util.stream.Collectors; 13 11 … … public class UpdateDataAction extends JosmAction { 61 59 if (!isEnabled() || editLayer == null || !editLayer.isDownloadable()) 62 60 return; 63 61 64 List<Area> areas = editLayer.data.getDataSources().stream() 65 .map(ds -> new Area(ds.bounds.asRect())) 66 .collect(Collectors.toList()); 67 68 // The next two blocks removes every intersection from every DataSource Area 69 // This prevents downloading the same data numerous times at intersections 70 // and also skips smaller bounding boxes that are contained within larger ones entirely. 71 for (int i = 0; i < areas.size(); i++) { 72 for (int j = i+1; j < areas.size(); j++) { 73 areas.get(i).subtract(areas.get(j)); 74 } 75 } 76 77 for (int i = areas.size()-1; i > 0; i--) { 78 for (int j = i-1; j > 0; j--) { 79 areas.get(i).subtract(areas.get(j)); 80 } 81 } 82 83 List<Area> areasToDownload = areas.stream() 84 .filter(a -> !a.isEmpty()) 85 .collect(Collectors.toList()); 86 87 if (areasToDownload.isEmpty()) { 62 if (editLayer.data.getDataSources().isEmpty()) { 88 63 // no bounds defined in the dataset? We update all but the incomplete primitives in the data set 89 64 UpdateSelectionAction.updatePrimitives(editLayer.data.allPrimitives().stream() 90 65 .filter(p -> !p.isNew() && !p.isIncomplete()).collect(Collectors.toList())); … … public class UpdateDataAction extends JosmAction { 92 67 // bounds defined? => use the bbox downloader 93 68 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download data")); 94 69 final Future<?> future = new DownloadTaskList(Config.getPref().getBoolean("update.data.zoom-after-download")) 95 . download(false /* no new layer */, areasToDownload, true, false,monitor);70 .fullUpdate(monitor); 96 71 waitFuture(future, monitor); 97 72 } 98 73 } -
src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java
diff --git a/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java b/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java index f8369409b1..73b56326fa 100644
a b import org.openstreetmap.josm.tools.Utils; 47 47 public class DownloadTaskList { 48 48 private final List<DownloadTask> tasks = new LinkedList<>(); 49 49 private final List<Future<?>> taskFutures = new LinkedList<>(); 50 private boolean isFullUpdate; 50 51 private final boolean zoomAfterDownload; 51 52 private ProgressMonitor progressMonitor; 52 53 … … public class DownloadTaskList { 131 132 } 132 133 } 133 134 135 /** 136 * Fully updates the current edit layer by re-downloading all the layer's 137 * declared bounding boxes from the OSM server. 138 * 139 * For full updates, this method should be preferred to the {@code download} 140 * methods because it uses a more effective algorithm to detect primitives that 141 * may have been deleted from the server; see #24717. 142 * 143 * @param progressMonitor The progress monitor 144 * @return The Future representing the asynchronous download task 145 */ 146 public Future<?> fullUpdate(ProgressMonitor progressMonitor) { 147 OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer(); 148 if (editLayer == null || !editLayer.isDownloadable()) 149 throw new IllegalStateException("The current edit layer is not downloadable."); 150 if (editLayer.data.getDataSources().isEmpty()) 151 throw new IllegalStateException("The current edit layer has no declared bounds."); 152 153 List<Area> areas = editLayer.data.getDataSources().stream() 154 .map(ds -> new Area(ds.bounds.asRect())) 155 .collect(Collectors.toList()); 156 157 // The next two blocks removes every intersection from every DataSource Area 158 // This prevents downloading the same data numerous times at intersections 159 // and also skips smaller bounding boxes that are contained within larger ones entirely. 160 for (int i = 0; i < areas.size(); i++) { 161 for (int j = i+1; j < areas.size(); j++) { 162 areas.get(i).subtract(areas.get(j)); 163 } 164 } 165 166 for (int i = areas.size()-1; i > 0; i--) { 167 for (int j = i-1; j > 0; j--) { 168 areas.get(i).subtract(areas.get(j)); 169 } 170 } 171 172 List<Area> areasToDownload = areas.stream() 173 .filter(a -> !a.isEmpty()) 174 .collect(Collectors.toList()); 175 176 isFullUpdate = true; 177 return download(false /* no new layer */, areasToDownload, true, false, progressMonitor); 178 } 179 134 180 /** 135 181 * Replies the set of ids of all complete, non-new primitives (i.e. those with !primitive.incomplete) 136 182 * @param ds data set … … public class DownloadTaskList { 275 321 .filter(DownloadOsmTask.class::isInstance).map(DownloadOsmTask.class::cast) 276 322 .filter(t -> t.getDownloadedData() != null) 277 323 .collect(Collectors.toList()); 278 final Set<Bounds> tasksBounds = osmTasks.stream()279 .flatMap(t -> t.getDownloadedData().getDataSourceBounds().stream())280 .collect(Collectors.toSet());281 final Set<Bounds> layerBounds = new LinkedHashSet<>(editDataSet.getDataSourceBounds());282 324 final Set<OsmPrimitive> myPrimitives = new LinkedHashSet<>(); 283 if ( layerBounds.equals(tasksBounds)) {325 if (isFullUpdate) { 284 326 // the full edit layer is updated (we have downloaded again all its current bounds) 285 327 myPrimitives.addAll(getCompletePrimitives(editDataSet)); 286 328 for (DownloadOsmTask task : osmTasks) {
