Ticket #19885: 19885-wip.patch
File 19885-wip.patch, 19.5 KB (added by , 4 years ago) |
---|
-
src/org/openstreetmap/josm/actions/CreateCircleAction.java
15 15 import javax.swing.JOptionPane; 16 16 17 17 import org.openstreetmap.josm.command.AddCommand; 18 import org.openstreetmap.josm.command.Change Command;18 import org.openstreetmap.josm.command.ChangeNodesCommand; 19 19 import org.openstreetmap.josm.command.Command; 20 20 import org.openstreetmap.josm.command.SequenceCommand; 21 21 import org.openstreetmap.josm.data.UndoRedoHandler; … … 233 233 newWay.setNodes(nodesToAdd); 234 234 cmds.add(new AddCommand(ds, newWay)); 235 235 } else { 236 Way newWay = new Way(existingWay); 237 newWay.setNodes(nodesToAdd); 238 cmds.add(new ChangeCommand(ds, existingWay, newWay)); 236 cmds.add(new ChangeNodesCommand(ds, existingWay, nodesToAdd)); 239 237 } 240 238 241 239 UndoRedoHandler.getInstance().add(new SequenceCommand(tr("Create Circle"), cmds)); -
src/org/openstreetmap/josm/actions/SimplifyWayAction.java
30 30 import javax.swing.event.ChangeEvent; 31 31 import javax.swing.event.ChangeListener; 32 32 33 import org.openstreetmap.josm.command.Change Command;33 import org.openstreetmap.josm.command.ChangeNodesCommand; 34 34 import org.openstreetmap.josm.command.Command; 35 35 import org.openstreetmap.josm.command.DeleteCommand; 36 36 import org.openstreetmap.josm.command.SequenceCommand; … … 410 410 if (delNodes.isEmpty()) return null; 411 411 412 412 Collection<Command> cmds = new LinkedList<>(); 413 Way newWay = new Way(w); 414 newWay.setNodes(newNodes); 415 cmds.add(new ChangeCommand(w, newWay)); 413 cmds.add(new ChangeNodesCommand(w, newNodes)); 416 414 cmds.add(new DeleteCommand(w.getDataSet(), delNodes)); 417 415 w.getDataSet().clearSelection(delNodes); 418 416 return new SequenceCommand( -
src/org/openstreetmap/josm/actions/corrector/TagCorrector.java
194 194 // save the clone 195 195 if (!keysChanged.isEmpty()) { 196 196 commands.add(new ChangeCommand(dataSet, primitive, clone)); 197 } else { 198 clone.removeFromChildren(); 197 199 } 198 200 } 199 201 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) { -
src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
489 489 if (deleteCmd != null) { 490 490 UndoRedoHandler.getInstance().add(deleteCmd); 491 491 } 492 newWay.setNodes(null); 492 493 } else { 493 494 UndoRedoHandler.getInstance().add(new ChangeCommand(targetWay, newWay)); 494 495 } -
src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
22 22 23 23 import org.openstreetmap.josm.actions.MergeNodesAction; 24 24 import org.openstreetmap.josm.command.AddCommand; 25 import org.openstreetmap.josm.command.Change Command;25 import org.openstreetmap.josm.command.ChangeNodesCommand; 26 26 import org.openstreetmap.josm.command.Command; 27 27 import org.openstreetmap.josm.command.MoveCommand; 28 28 import org.openstreetmap.josm.command.RotateCommand; … … 1243 1243 Way w = virtualWay.way; 1244 1244 Way wnew = new Way(w); 1245 1245 wnew.addNode(virtualWay.lowerIndex + 1, virtualNode); 1246 virtualCmds.add(new ChangeCommand(ds, w, wnew)); 1246 virtualCmds.add(new ChangeNodesCommand(ds, w, wnew.getNodes())); 1247 wnew.removeFromChildren(); 1247 1248 } 1248 1249 virtualCmds.add(new MoveCommand(ds, virtualNode, startEN, currentEN)); 1249 1250 String text = trn("Add and move a virtual new node to way", -
src/org/openstreetmap/josm/command/Command.java
227 227 for (OsmPrimitive osm : primitives) { 228 228 if (osm.isIncomplete()) { 229 229 res |= IS_INCOMPLETE; 230 } else if (( osm.isOutsideDownloadArea()230 } else if ((res & IS_OUTSIDE) == 0 && (osm.isOutsideDownloadArea() 231 231 || (osm instanceof Node && !osm.isNew() && osm.getDataSet() != null && osm.getDataSet().getDataSourceBounds().isEmpty())) 232 232 && (ignore == null || !ignore.contains(osm))) { 233 233 res |= IS_OUTSIDE; -
src/org/openstreetmap/josm/command/DeleteCommand.java
184 184 @Override 185 185 public boolean executeCommand() { 186 186 ensurePrimitivesAreInDataset(); 187 // Make copy and remove all references (to prevent inconsistent dataset (delete referenced) while command is executed)188 for (OsmPrimitive osm: toDelete) {189 if (osm.isDeleted())190 throw new IllegalArgumentException(osm + " is already deleted");191 clonedPrimitives.put(osm, osm.save());192 187 193 if (osm instanceof Way) { 194 ((Way) osm).setNodes(null); 195 } else if (osm instanceof Relation) { 196 ((Relation) osm).setMembers(null); 188 getAffectedDataSet().update(() -> { 189 // Make copy and remove all references (to prevent inconsistent dataset (delete referenced) while command is executed) 190 for (OsmPrimitive osm : toDelete) { 191 if (osm.isDeleted()) 192 throw new IllegalArgumentException(osm + " is already deleted"); 193 clonedPrimitives.put(osm, osm.save()); 194 195 if (osm instanceof Way) { 196 ((Way) osm).setNodes(null); 197 } else if (osm instanceof Relation) { 198 ((Relation) osm).setMembers(null); 199 } 197 200 } 198 }199 201 200 for (OsmPrimitive osm: toDelete) {201 osm.setDeleted(true);202 }203 202 for (OsmPrimitive osm : toDelete) { 203 osm.setDeleted(true); 204 } 205 }); 204 206 return true; 205 207 } 206 208 … … 208 210 public void undoCommand() { 209 211 ensurePrimitivesAreInDataset(); 210 212 211 for (OsmPrimitive osm: toDelete) { 212 osm.setDeleted(false); 213 } 213 getAffectedDataSet().update(() -> { 214 for (OsmPrimitive osm : toDelete) { 215 osm.setDeleted(false); 216 } 214 217 215 for (Entry<OsmPrimitive, PrimitiveData> entry: clonedPrimitives.entrySet()) { 216 entry.getKey().load(entry.getValue()); 217 } 218 for (Entry<OsmPrimitive, PrimitiveData> entry : clonedPrimitives.entrySet()) { 219 entry.getKey().load(entry.getValue()); 220 } 221 }); 218 222 } 219 223 220 224 @Override … … 426 430 Collection<Command> cmds = new LinkedList<>(); 427 431 Set<Node> nodesToRemove = new HashSet<>(Utils.filteredCollection(primitivesToDelete, Node.class)); 428 432 for (Way w : waysToBeChanged) { 429 Way wnew = new Way(w); 430 wnew.removeNodes(nodesToRemove); 431 if (wnew.getNodesCount() < 2) { 433 if (primitivesToDelete.contains(w)) 434 continue; 435 List<Node> remainingNodes = w.calculateRemoveNodes(nodesToRemove); 436 if (remainingNodes.size() < 2) { 432 437 primitivesToDelete.add(w); 433 438 } else { 434 cmds.add(new ChangeNodesCommand(w, wnew.getNodes()));439 cmds.add(new ChangeNodesCommand(w, remainingNodes)); 435 440 } 436 441 } 437 442 -
src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java
68 68 } 69 69 70 70 /** 71 * Checks for womplete ways with incomplete nodes.71 * Checks for complete ways with incomplete nodes. 72 72 */ 73 73 public void checkCompleteWaysWithIncompleteNodes() { 74 74 final Stopwatch stopwatch = Stopwatch.createStarted(); … … 182 182 printElapsedTime(stopwatch); 183 183 } 184 184 185 private void searchParentsWithoutDataset() { 186 final Stopwatch stopwatch = Stopwatch.createStarted(); 187 long dubiousParents = 0; 188 for (OsmPrimitive p : dataSet.allPrimitives()) { 189 dubiousParents += p.checkReferrersWithoutDataset(false); 190 } 191 if (dubiousParents > 0) { 192 printError("WARN - Memory leak", 193 "Dataset contains %d pointers to parents which do not belong to the dataset", dubiousParents); 194 } 195 printElapsedTime(stopwatch); 196 197 } 198 185 199 private void printElapsedTime(Stopwatch stopwatch) { 186 200 if (Logging.isDebugEnabled()) { 187 201 StackTraceElement item = Thread.currentThread().getStackTrace()[2]; … … 203 217 searchNodes(); 204 218 searchWays(); 205 219 checkZeroNodesWays(); 220 searchParentsWithoutDataset(); 206 221 printElapsedTime(stopwatch); 207 222 if (errorCount > MAX_ERRORS) { 208 223 writer.println((errorCount - MAX_ERRORS) + " more..."); -
src/org/openstreetmap/josm/data/osm/Node.java
394 394 protected void updateDirectionFlags() { 395 395 // Nodes do not need/have a direction, greatly improves performance, see #18886 396 396 } 397 398 @Override 399 public void removeFromChildren() { 400 // nothing to do 401 } 397 402 } -
src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
787 787 } 788 788 789 789 /** 790 * Find all referrers which have no dataset. 791 * @param doRemove if {@code true} remove the found referrers 792 * @return number of (possibly removed) referrers without a dataset 793 */ 794 final int checkReferrersWithoutDataset(boolean doRemove) { 795 if (dataSet == null) { 796 return 0; 797 } 798 if (doRemove) 799 checkDatasetNotReadOnly(); 800 801 if (referrers == null) { 802 return 0; 803 } 804 if (referrers instanceof OsmPrimitive) { 805 if (((OsmPrimitive) referrers).getDataSet() == null) { 806 if (doRemove) 807 referrers = null; 808 return 1; 809 } 810 return 0; 811 } 812 OsmPrimitive[] array = ((OsmPrimitive[]) referrers); 813 long oldCount = array.length; 814 long badCount = Arrays.stream(array).filter(p -> p.getDataSet() == null).count(); 815 if (badCount > 0 && doRemove) { 816 OsmPrimitive[] smaller = new OsmPrimitive[(int) (oldCount - badCount)]; 817 int k = 0; 818 for (int i = 0; i < oldCount; i++) { 819 if (array[i].getDataSet() != null) 820 smaller[k++] = array[i]; 821 } 822 referrers = smaller; 823 } 824 return (int) badCount; 825 } 826 827 /** 790 828 * <p>Visits {@code visitor} for all referrers.</p> 791 829 * 792 830 * @param visitor the visitor. Ignored, if null. … … 1146 1184 * @since 11269 1147 1185 */ 1148 1186 protected abstract void addToBBox(BBox box, Set<PrimitiveId> visited); 1187 1188 /** 1189 * If this primitive has children, 1190 * @since xxx 1191 */ 1192 public abstract void removeFromChildren(); 1149 1193 } -
src/org/openstreetmap/josm/data/osm/Relation.java
563 563 public UniqueIdGenerator getIdGenerator() { 564 564 return idGenerator; 565 565 } 566 567 @Override 568 public void removeFromChildren() { 569 setMembers(null); 570 } 571 566 572 } -
src/org/openstreetmap/josm/data/osm/Way.java
363 363 if (selection == null || isIncomplete()) return; 364 364 boolean locked = writeLock(); 365 365 try { 366 boolean closed = isClosed() && selection.contains(lastNode()); 367 List<Node> copy = Arrays.stream(nodes) 368 .filter(n -> !selection.contains(n)) 369 .collect(Collectors.toList()); 370 371 int i = copy.size(); 372 if (closed && i > 2) { 373 copy.add(copy.get(0)); 374 } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) { 375 copy.remove(i-1); 376 } 377 setNodes(removeDouble(copy)); 366 setNodes(calculateRemoveNodes(selection)); 378 367 for (Node n : selection) { 379 368 n.clearCachedStyle(); 380 369 } … … 384 373 } 385 374 386 375 /** 376 * Calculate the remaining nodes after a removal of the given set of {@link Node nodes} from this way. 377 * @param selection The selection of nodes to remove. Ignored, if null 378 * @return result of the removal, can be empty 379 * @since xxx 380 */ 381 public List<Node> calculateRemoveNodes(Set<? extends Node> selection) { 382 if (selection == null || isIncomplete()) 383 return getNodes(); 384 boolean closed = isClosed() && selection.contains(lastNode()); 385 List<Node> copy = Arrays.stream(nodes) 386 .filter(n -> !selection.contains(n)) 387 .collect(Collectors.toList()); 388 389 int i = copy.size(); 390 if (closed && i > 2) { 391 copy.add(copy.get(0)); 392 } else if (i >= 2 && i <= 3 && copy.get(0) == copy.get(i-1)) { 393 copy.remove(i-1); 394 } 395 return removeDouble(copy); 396 } 397 398 /** 387 399 * Adds a node to the end of the list of nodes. Ignored, if n is null. 388 400 * 389 401 * @param n the node. Ignored, if null … … 756 768 public UniqueIdGenerator getIdGenerator() { 757 769 return idGenerator; 758 770 } 771 772 @Override 773 public void removeFromChildren() { 774 setNodes(null); 775 } 776 759 777 } -
src/org/openstreetmap/josm/data/osm/visitor/paint/AbstractMapRenderer.java
12 12 import org.openstreetmap.josm.data.osm.INode; 13 13 import org.openstreetmap.josm.data.osm.IWay; 14 14 import org.openstreetmap.josm.data.osm.OsmData; 15 import org.openstreetmap.josm.data.osm.Way; 15 16 import org.openstreetmap.josm.data.osm.WaySegment; 16 17 import org.openstreetmap.josm.gui.MapViewState; 17 18 import org.openstreetmap.josm.gui.MapViewState.MapViewPoint; … … 148 149 path = new GeneralPath(); 149 150 for (WaySegment wseg: data.getHighlightedVirtualNodes()) { 150 151 if (wseg.way.isUsable() && !wseg.way.isDisabled()) { 151 visitVirtual(path, wseg.toWay()); 152 Way tmpWay = wseg.toWay(); 153 visitVirtual(path, tmpWay); 154 tmpWay.removeFromChildren(); 152 155 } 153 156 } 154 157 g.setColor(highlightColor); -
src/org/openstreetmap/josm/data/validation/tests/Coastlines.java
13 13 import java.util.List; 14 14 import java.util.Set; 15 15 16 import org.openstreetmap.josm.command.Change Command;16 import org.openstreetmap.josm.command.ChangeNodesCommand; 17 17 import org.openstreetmap.josm.command.Command; 18 18 import org.openstreetmap.josm.data.osm.Node; 19 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 260 260 Iterator<? extends OsmPrimitive> it = testError.getPrimitives().iterator(); 261 261 if (it.hasNext()) { 262 262 Way way = (Way) it.next(); 263 Way newWay = new Way(way);264 263 265 List<Node> nodesCopy = newWay.getNodes();264 List<Node> nodesCopy = way.getNodes(); 266 265 Collections.reverse(nodesCopy); 267 newWay.setNodes(nodesCopy);268 266 269 return new Change Command(way, newWay);267 return new ChangeNodesCommand(way, nodesCopy); 270 268 } 271 269 } 272 270 return null; -
src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
987 987 if (countDeprecated(clone) > unchangedDeprecated) 988 988 iter.remove(); 989 989 } 990 clone.removeFromChildren(); 990 991 } 991 992 992 993 private int countDeprecated(OsmPrimitive p) { -
src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
950 950 relation.addMember(new RelationMember(roles.size() == 1 ? roles.iterator().next() : "", p)); 951 951 modified = true; 952 952 } 953 return modified ? new ChangeCommand(orig, relation) : null; 953 if (!modified) { 954 relation.removeFromChildren(); 955 return null; 956 } 957 return new ChangeCommand(orig, relation); 954 958 } catch (AddAbortException ign) { 955 959 Logging.trace(ign); 956 960 return null;