Changeset 36230 in osm for applications/editors/josm/plugins
- Timestamp:
- 2024-03-19T17:42:16+01:00 (8 months ago)
- Location:
- applications/editors/josm/plugins/reverter/src/reverter
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/reverter/src/reverter/ChangesetReverter.java
r36042 r36230 15 15 import java.util.List; 16 16 import java.util.Map; 17 import java.util.Optional; 17 18 import java.util.stream.Collectors; 18 19 … … 22 23 import org.openstreetmap.josm.data.conflict.Conflict; 23 24 import org.openstreetmap.josm.data.coor.LatLon; 25 import org.openstreetmap.josm.data.osm.AbstractPrimitive; 24 26 import org.openstreetmap.josm.data.osm.Changeset; 25 27 import org.openstreetmap.josm.data.osm.ChangesetDataSet; … … 273 275 if (progressMonitor.isCanceled()) return; 274 276 nds = rdr.parseOsm(progressMonitor.createSubTaskMonitor(1, true)); 275 for (OsmPrimitive p : nds.allPrimitives()) { 276 if (!p.isIncomplete()) { 277 addMissingId(p); 278 } else { 279 if (ds.getPrimitiveById(p.getPrimitiveId()) == null) { 280 switch (p.getType()) { 281 case NODE: ds.addPrimitive(new Node(p.getUniqueId())); break; 282 case CLOSEDWAY: 283 case WAY: ds.addPrimitive(new Way(p.getUniqueId())); break; 284 case MULTIPOLYGON: 285 case RELATION: ds.addPrimitive(new Relation(p.getUniqueId())); break; 286 default: throw new AssertionError(); 277 ds.update(() -> { 278 for (OsmPrimitive p : nds.allPrimitives()) { 279 if (!p.isIncomplete()) { 280 addMissingId(p); 281 } else { 282 if (ds.getPrimitiveById(p.getPrimitiveId()) == null) { 283 switch (p.getType()) { 284 case NODE: ds.addPrimitive(new Node(p.getUniqueId())); break; 285 case CLOSEDWAY: 286 case WAY: ds.addPrimitive(new Way(p.getUniqueId())); break; 287 case MULTIPOLYGON: 288 case RELATION: ds.addPrimitive(new Relation(p.getUniqueId())); break; 289 default: throw new AssertionError(); 290 } 287 291 } 288 292 } 289 293 } 290 } 294 }); 291 295 } finally { 292 296 progressMonitor.finishTask(); … … 503 507 int num = nodes.size(); 504 508 progressMonitor.beginTask(addChangesetIdPrefix( 505 trn("Checking coordinates of {0} node", "Checking coordinates of {0} nodes", num, num)), num); 506 509 trn("Checking coordinates of {0} node", "Checking coordinates of {0} nodes", num, num)), 510 // downloads == num ticks, then we get the downloaded data (1 tick), then we process the nodes (num ticks) 511 2 * num + 1); 512 513 // Do bulk version fetches first 514 // The objects to get next 515 final Map<Long, Integer> versionMap = nodes.stream() 516 .collect(Collectors.toMap(AbstractPrimitive::getUniqueId, 517 id -> Math.max(1, Optional.ofNullable(ds.getPrimitiveById(id)).orElse(id).getVersion() - 1))); 507 518 try { 508 for (Node n : nodes) {509 if (!n.isDeleted() && !n.isLatLonKnown()) {510 PrimitiveId id = n.getPrimitiveId();511 OsmPrimitive p = ds.getPrimitiveById(id);512 if (p instanceof Node && !((Node) p).isLatLonKnown()) {513 int version = p.getVersion();514 while (version > 1) {515 // find the version that was in use when the current changeset was closed516 --version;517 final OsmServerMultiObjectReader rdr = new OsmServerMultiObjectReader();518 readObjectVersion(rdr, id, version, progressMonitor);519 DataSet history = rdr.parseOsm(progressMonitor.createSubTaskMonitor(1, true));520 if (!history.isEmpty()) {521 Node historyNode = (Node) history.allPrimitives().iterator().next();522 if (historyNode.isLatLonKnown()&& changeset.getClosedAt().isAfter(historyNode.getInstant())) {523 524 break;525 }519 while (!versionMap.isEmpty()) { 520 final OsmServerMultiObjectReader rds = new OsmServerMultiObjectReader(); 521 final ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(num, false); 522 subMonitor.beginTask(tr("Fetching multi-objects"), versionMap.size()); 523 rds.readMultiObjects(OsmPrimitiveType.NODE, versionMap, subMonitor); 524 subMonitor.finishTask(); 525 final DataSet history = rds.parseOsm(progressMonitor.createSubTaskMonitor(0, false)); 526 versionMap.replaceAll((key, value) -> value - 1); 527 versionMap.values().removeIf(i -> i <= 0); 528 ds.update(() -> { 529 for (Node n : nodes) { 530 if (!n.isDeleted() && !n.isLatLonKnown()) { 531 final Node historyNode = (Node) history.getPrimitiveById(n); 532 if (historyNode != null && historyNode.isLatLonKnown() 533 && changeset.getClosedAt().isAfter(historyNode.getInstant())) { 534 n.load(historyNode.save()); 535 versionMap.remove(n.getUniqueId()); 536 progressMonitor.worked(1); 526 537 } 527 538 } 539 if (progressMonitor.isCanceled()) { 540 break; 541 } 528 542 } 543 }); 544 if (progressMonitor.isCanceled()) { 545 break; 529 546 } 530 if (progressMonitor.isCanceled())531 return;532 progressMonitor.worked(1);533 547 } 534 548 } finally { -
applications/editors/josm/plugins/reverter/src/reverter/DataSetCommandMerger.java
r35464 r36230 7 7 import java.util.Collection; 8 8 import java.util.HashMap; 9 import java.util.HashSet; 9 10 import java.util.LinkedHashSet; 10 11 import java.util.LinkedList; 11 12 import java.util.List; 12 13 import java.util.Map; 14 import java.util.Set; 13 15 14 16 import org.openstreetmap.josm.command.ChangeCommand; … … 38 40 private final DataSet targetDataSet; 39 41 40 private final List<Command> cmds = new LinkedList<>();41 private final List<OsmPrimitive> nominalRevertedPrimitives = new LinkedList<>();42 private final List<Command> cmds = new ArrayList<>(); 43 private final Set<OsmPrimitive> nominalRevertedPrimitives = new HashSet<>(); 42 44 43 45 /** … … 60 62 nominalRevertedPrimitives.add(target); 61 63 } 62 Logging.debug("Reverting " + target + " to " +newTarget);64 Logging.debug("Reverting {0} to {1}", target, newTarget); 63 65 } 64 66 } … … 126 128 // Target node has been deleted by a more recent changeset -> conflict 127 129 } else if (sourceNode.isIncomplete() && !conflicts.hasConflictForMy(targetNode)) { 128 localConflicts.add(new Conflict< OsmPrimitive>(targetNode, sourceNode, true));130 localConflicts.add(new Conflict<>(targetNode, sourceNode, true)); 129 131 } else { 130 132 Logging.info("Skipping target node "+targetNode+" for source node "+sourceNode+" while reverting way "+source); -
applications/editors/josm/plugins/reverter/src/reverter/OsmServerMultiObjectReader.java
r35638 r36230 43 43 } 44 44 } 45 46 /** 47 * Generate query strings 48 * @param type The type of the object to get 49 * @param list The map of ids to versions 50 * @return The queries to make 51 */ 45 52 private static List<String> makeQueryStrings(OsmPrimitiveType type, Map<Long,Integer> list) { 46 List<String> result = new ArrayList<>((list.size()+maxQueryIds-1)/maxQueryIds); 53 // This is a "worst-case" calculation. Keep it fast (and err higher rather than lower), not accurate. 54 final int expectedSize = (int) (list.entrySet().stream().mapToLong(entry -> 55 // Keep in mind that 0-3 is 0, 3-32 is 1, 32-316 is 2, and so on when rounding log10. 56 // First the key. 57 Math.round(Math.log10(entry.getKey())) + 1 + 58 // Then the value 59 Math.round(Math.log10(entry.getValue())) + 1 + 60 // And finally the "static" size (',' + 'v') 61 2 62 ).sum() / MAX_QUERY_LENGTH); 63 List<String> result = new ArrayList<>(expectedSize + 1); 47 64 StringBuilder sb = new StringBuilder(); 48 65 int cnt=0; … … 60 77 sb.append(entry.getValue()); 61 78 cnt++; 62 if (cnt >= maxQueryIds) {79 if (cnt >= MAX_QUERY_IDS || sb.length() > MAX_QUERY_LENGTH) { 63 80 result.add(sb.toString()); 64 81 sb.setLength(0); … … 72 89 } 73 90 74 protected static final int maxQueryIds = 128; 91 /** 92 * The maximum ids we want to query. API docs indicate 725 is "safe" for non-versioned objects with 10-digit ids. 93 * Since we use {@link #MAX_QUERY_LENGTH} to avoid issues where we go over the permitted length, we can have a 94 * bigger number here. 95 * @see <a href="https://wiki.openstreetmap.org/wiki/API_v0.6#Multi_fetch:_GET_/api/0.6/[nodes|ways|relations]?#parameters"> 96 * API_v0.6#Multi_fetch 97 * </a> 98 */ 99 protected static final int MAX_QUERY_IDS = 2000; 100 /** 101 * The maximum query length. Docs indicate 8213 characters in the URI is safe. The maximum base length before 102 * query parameters is for relations at 59 characters for 8154 characters in the query parameters. We round down to 103 * 8000 characters. 104 * @see <a href="https://wiki.openstreetmap.org/wiki/API_v0.6#Multi_fetch:_GET_/api/0.6/[nodes|ways|relations]?#parameters"> 105 * API_v0.6#Multi_fetch 106 * </a> 107 */ 108 protected static final int MAX_QUERY_LENGTH = 8000; 109 110 /** 111 * Parse many objects 112 * @param type The object type (<i>must</i> be common between all objects) 113 * @param list The map of object id to object version 114 * @param progressMonitor The progress monitor to update 115 * @throws OsmTransferException If there is an issue getting the data 116 */ 75 117 public void readMultiObjects(OsmPrimitiveType type, Map<Long,Integer> list, ProgressMonitor progressMonitor) throws OsmTransferException { 76 118 for (String query : makeQueryStrings(type,list)) { -
applications/editors/josm/plugins/reverter/src/reverter/RevertChangesetTask.java
r36042 r36230 191 191 return null; 192 192 } 193 GuiHelper.runInEDT(() -> {193 GuiHelper.runInEDT(() -> cmds.get(0).getAffectedDataSet().update(() -> { 194 194 for (Command c : cmds) { 195 195 if (c instanceof ConflictAddCommand) { … … 198 198 c.executeCommand(); 199 199 } 200 }) ;200 })); 201 201 final String desc; 202 202 if (revertType == RevertType.FULL) {
Note:
See TracChangeset
for help on using the changeset viewer.