Ticket #19061: 19061.2.patch
| File 19061.2.patch, 248.9 KB (added by , 6 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/AlignInLineAction.java
25 25 import org.openstreetmap.josm.data.osm.DataSet; 26 26 import org.openstreetmap.josm.data.osm.Node; 27 27 import org.openstreetmap.josm.data.osm.OsmPrimitive; 28 import org.openstreetmap.josm.data.osm.Relation; 28 29 import org.openstreetmap.josm.data.osm.Way; 29 30 import org.openstreetmap.josm.gui.Notification; 30 31 import org.openstreetmap.josm.tools.Logging; … … 172 173 return; 173 174 174 175 try { 175 Command cmd = buildCommand(getLayerManager().getEditDataSet());176 Command<OsmPrimitive, Node, Way, Relation> cmd = buildCommand(getLayerManager().getEditDataSet()); 176 177 if (cmd != null) { 177 178 UndoRedoHandler.getInstance().add(cmd); 178 179 } … … 191 192 * @throws InvalidSelection if a polygon is selected, or if a node is used by 3 or more ways 192 193 * @since 13108 193 194 */ 194 public Command buildCommand(DataSet ds) throws InvalidSelection {195 public Command<OsmPrimitive, Node, Way, Relation> buildCommand(DataSet ds) throws InvalidSelection { 195 196 List<Node> selectedNodes = new ArrayList<>(ds.getSelectedNodes()); 196 197 List<Way> selectedWays = new ArrayList<>(ds.getSelectedWays()); 197 198 selectedWays.removeIf(w -> w.isIncomplete() || w.isEmpty()); … … 230 231 * @return Command that perform action. 231 232 * @throws InvalidSelection If the nodes have same coordinates. 232 233 */ 233 private static Command alignOnlyNodes(List<Node> nodes) throws InvalidSelection {234 private static Command<OsmPrimitive, Node, Way, Relation> alignOnlyNodes(List<Node> nodes) throws InvalidSelection { 234 235 // Choose nodes used as anchor points for projection. 235 236 Node[] anchors = nodePairFurthestApart(nodes); 236 Collection<Command > cmds = new ArrayList<>(nodes.size());237 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new ArrayList<>(nodes.size()); 237 238 Line line = new Line(anchors[0], anchors[1]); 238 239 for (Node node: nodes) { 239 240 if (node != anchors[0] && node != anchors[1]) … … 248 249 * @return Command that perform action 249 250 * @throws InvalidSelection if a polygon is selected, or if a node is used by 3 or more ways 250 251 */ 251 private static Command alignMultiWay(Collection<Way> ways) throws InvalidSelection {252 private static Command<OsmPrimitive, Node, Way, Relation> alignMultiWay(Collection<Way> ways) throws InvalidSelection { 252 253 // Collect all nodes and compute line equation 253 254 Set<Node> nodes = new HashSet<>(); 254 255 Map<Way, Line> lines = new HashMap<>(); … … 263 264 if (nodes.isEmpty()) { 264 265 throw new InvalidSelection(tr("Intersection of three or more ways can not be solved. Abort.")); 265 266 } 266 Collection<Command > cmds = new ArrayList<>(nodes.size());267 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new ArrayList<>(nodes.size()); 267 268 List<Way> referers = new ArrayList<>(ways.size()); 268 269 for (Node n: nodes) { 269 270 referers.clear(); … … 346 347 * @return Command that perform action 347 348 * @throws InvalidSelection if more than 2 lines 348 349 */ 349 private static Command alignSingleNode(Node node, List<Line> lines) throws InvalidSelection {350 private static Command<OsmPrimitive, Node, Way, Relation> alignSingleNode(Node node, List<Line> lines) throws InvalidSelection { 350 351 if (lines.size() == 1) 351 352 return lines.get(0).projectionCommand(node); 352 353 else if (lines.size() == 2) … … 404 405 * @param n Node to be projected 405 406 * @return The command that do the projection of this node 406 407 */ 407 public Command projectionCommand(Node n) {408 public Command<OsmPrimitive, Node, Way, Relation> projectionCommand(Node n) { 408 409 double s = (xM - n.getEastNorth().getX()) * a + (yM - n.getEastNorth().getY()) * b; 409 return new MoveCommand (n, a*s, b*s);410 return new MoveCommand<>(n, a*s, b*s); 410 411 } 411 412 412 413 /** … … 416 417 * @return The command that move the node 417 418 * @throws InvalidSelection if two parallels ways found 418 419 */ 419 public Command intersectionCommand(Node n, Line other) throws InvalidSelection {420 public Command<OsmPrimitive, Node, Way, Relation> intersectionCommand(Node n, Line other) throws InvalidSelection { 420 421 double d = this.a * other.b - other.a * this.b; 421 422 if (Math.abs(d) < 10e-6) 422 423 // parallels lines … … 423 424 throw new InvalidSelection(tr("Two parallels ways found. Abort.")); 424 425 double x = (this.b * other.c - other.b * this.c) / d; 425 426 double y = (other.a * this.c - this.a * other.c) / d; 426 return new MoveCommand (n, x - n.getEastNorth().getX(), y - n.getEastNorth().getY());427 return new MoveCommand<>(n, x - n.getEastNorth().getX(), y - n.getEastNorth().getY()); 427 428 } 428 429 } 429 430 -
src/org/openstreetmap/josm/actions/CreateCircleAction.java
25 25 import org.openstreetmap.josm.data.osm.DataSet; 26 26 import org.openstreetmap.josm.data.osm.Node; 27 27 import org.openstreetmap.josm.data.osm.OsmPrimitive; 28 import org.openstreetmap.josm.data.osm.Relation; 28 29 import org.openstreetmap.josm.data.osm.Way; 29 30 import org.openstreetmap.josm.data.projection.ProjectionRegistry; 30 31 import org.openstreetmap.josm.gui.Notification; … … 199 200 numberOfNodesInCircle >= nodes.size() ? (numberOfNodesInCircle - nodes.size()) : 0); 200 201 201 202 // now we can start doing things to OSM data 202 Collection<Command > cmds = new LinkedList<>();203 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new LinkedList<>(); 203 204 204 205 // build a way for the circle 205 206 List<Node> nodesToAdd = new ArrayList<>(); … … 219 220 } 220 221 Node n = new Node(ll); 221 222 nodesToAdd.add(n); 222 cmds.add(new AddCommand (ds, n));223 cmds.add(new AddCommand<>(ds, n)); 223 224 } 224 225 } 225 226 nodesToAdd.add(nodesToAdd.get(0)); // close the circle … … 231 232 if (existingWay == null) { 232 233 Way newWay = new Way(); 233 234 newWay.setNodes(nodesToAdd); 234 cmds.add(new AddCommand (ds, newWay));235 cmds.add(new AddCommand<>(ds, newWay)); 235 236 } else { 236 237 Way newWay = new Way(existingWay); 237 238 newWay.setNodes(nodesToAdd); 238 cmds.add(new ChangeCommand (ds, existingWay, newWay));239 cmds.add(new ChangeCommand<>(ds, existingWay, newWay)); 239 240 } 240 241 241 242 UndoRedoHandler.getInstance().add(new SequenceCommand(tr("Create Circle"), cmds)); -
src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java
32 32 import org.openstreetmap.josm.data.UndoRedoHandler; 33 33 import org.openstreetmap.josm.data.osm.DataSet; 34 34 import org.openstreetmap.josm.data.osm.IPrimitive; 35 import org.openstreetmap.josm.data.osm.Node; 35 36 import org.openstreetmap.josm.data.osm.OsmPrimitive; 36 37 import org.openstreetmap.josm.data.osm.OsmUtils; 37 38 import org.openstreetmap.josm.data.osm.Relation; … … 109 110 if (commandAndRelation == null) { 110 111 return; 111 112 } 112 final Command command = commandAndRelation.a;113 final Command<OsmPrimitive, Node, Way, Relation> command = commandAndRelation.a; 113 114 final Relation relation = commandAndRelation.b; 114 115 115 116 // to avoid EDT violations … … 329 330 final Relation existingRelation = rr.a; 330 331 final Relation relation = rr.b; 331 332 332 final List<Command > list = removeTagsFromWaysIfNeeded(relation);333 final List<Command<OsmPrimitive, Node, Way, Relation>> list = removeTagsFromWaysIfNeeded(relation); 333 334 final String commandName; 334 335 if (existingRelation == null) { 335 list.add(new AddCommand (selectedWays.iterator().next().getDataSet(), relation));336 list.add(new AddCommand<>(selectedWays.iterator().next().getDataSet(), relation)); 336 337 commandName = getName(false); 337 338 } else { 338 339 if (!unchanged) { 339 list.add(new ChangeCommand (existingRelation, relation));340 list.add(new ChangeCommand<>(existingRelation, relation)); 340 341 } 341 342 if (list.isEmpty()) { 342 343 if (unchanged) { … … 388 389 * @param relation the multipolygon style relation to process 389 390 * @return a list of commands to execute 390 391 */ 391 public static List<Command > removeTagsFromWaysIfNeeded(Relation relation) {392 public static List<Command<OsmPrimitive, Node, Way, Relation>> removeTagsFromWaysIfNeeded(Relation relation) { 392 393 Map<String, String> values = new HashMap<>(relation.getKeys()); 393 394 394 395 List<Way> innerWays = new ArrayList<>(); … … 442 443 443 444 values.put("area", OsmUtils.TRUE_VALUE); 444 445 445 List<Command > commands = new ArrayList<>();446 List<Command<OsmPrimitive, Node, Way, Relation>> commands = new ArrayList<>(); 446 447 boolean moveTags = Config.getPref().getBoolean("multipoly.movetags", true); 447 448 448 449 for (Entry<String, String> entry : values.entrySet()) { … … 490 491 if (ds == null) { 491 492 ds = MainApplication.getLayerManager().getEditDataSet(); 492 493 } 493 commands.add(new ChangeCommand (ds, relation, r2));494 commands.add(new ChangeCommand<>(ds, relation, r2)); 494 495 } 495 496 } 496 497 -
src/org/openstreetmap/josm/actions/DeleteAction.java
15 15 16 16 import org.openstreetmap.josm.command.DeleteCommand.DeletionCallback; 17 17 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 18 import org.openstreetmap.josm.data.osm.IPrimitive; 19 import org.openstreetmap.josm.data.osm.IRelation; 18 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Relation;20 21 import org.openstreetmap.josm.data.osm.RelationToChildReference; 21 22 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 22 23 import org.openstreetmap.josm.gui.MainApplication; … … 37 38 */ 38 39 public static final DeletionCallback defaultDeletionCallback = new DeletionCallback() { 39 40 @Override 40 public boolean checkAndConfirmOutlyingDelete(Collection<? extends OsmPrimitive> primitives,41 Collection<? extends OsmPrimitive> ignore) {41 public boolean checkAndConfirmOutlyingDelete(Collection<? extends IPrimitive> primitives, 42 Collection<? extends IPrimitive> ignore) { 42 43 return DeleteAction.checkAndConfirmOutlyingDelete(primitives, ignore); 43 44 } 44 45 45 46 @Override 46 public boolean confirmRelationDeletion(Collection< Relation> relations) {47 public boolean confirmRelationDeletion(Collection<? extends IRelation<?>> relations) { 47 48 return DeleteAction.confirmRelationDeletion(relations); 48 49 } 49 50 … … 91 92 * @return true, if operating on outlying primitives is OK; false, otherwise 92 93 * @since 12749 (moved from DeleteCommand) 93 94 */ 94 public static boolean checkAndConfirmOutlyingDelete(Collection<? extends OsmPrimitive> primitives,95 Collection<? extends OsmPrimitive> ignore) {95 public static boolean checkAndConfirmOutlyingDelete(Collection<? extends IPrimitive> primitives, 96 Collection<? extends IPrimitive> ignore) { 96 97 return checkAndConfirmOutlyingOperation("delete", 97 98 tr("Delete confirmation"), 98 99 tr("You are about to delete nodes outside of the area you have downloaded." … … 113 114 * @return {@code true} if user confirms the deletion 114 115 * @since 12760 115 116 */ 116 public static boolean confirmRelationDeletion(Collection< Relation> relations) {117 public static boolean confirmRelationDeletion(Collection<? extends IRelation<?>> relations) { 117 118 JPanel msg = new JPanel(new GridBagLayout()); 118 119 msg.add(new JMultilineLabel("<html>" + trn( 119 120 "You are about to delete {0} relation: {1}" -
src/org/openstreetmap/josm/actions/JoinAreasAction.java
57 57 */ 58 58 public class JoinAreasAction extends JosmAction { 59 59 // This will be used to commit commands and unite them into one large command sequence at the end 60 private final transient LinkedList<Command > executedCmds = new LinkedList<>();61 private final transient LinkedList<Command > cmds = new LinkedList<>();60 private final transient LinkedList<Command<OsmPrimitive, Node, Way, Relation>> executedCmds = new LinkedList<>(); 61 private final transient LinkedList<Command<OsmPrimitive, Node, Way, Relation>> cmds = new LinkedList<>(); 62 62 private DataSet ds; 63 63 private final transient List<Relation> addedRelations = new LinkedList<>(); 64 64 private final boolean addUndoRedo; … … 590 590 cmds.clear(); 591 591 if (!executedCmds.isEmpty()) { 592 592 // revert all executed commands 593 ds = executedCmds.getFirst().getAffectedDataSet();593 ds = (DataSet) executedCmds.getFirst().getAffectedDataSet(); 594 594 ds.update(() -> { 595 595 while (!executedCmds.isEmpty()) { 596 596 executedCmds.removeLast().undoCommand(); … … 1740 1740 } 1741 1741 1742 1742 private static class JoinAreaCommand extends SequenceCommand { 1743 JoinAreaCommand(Collection<Command > sequenz) {1743 JoinAreaCommand(Collection<Command<OsmPrimitive, Node, Way, Relation>> sequenz) { 1744 1744 super(tr("Joined overlapping areas"), sequenz, true); 1745 1745 setSequenceComplete(true); 1746 1746 } … … 1747 1747 1748 1748 @Override 1749 1749 public void undoCommand() { 1750 getAffectedDataSet().update(super::undoCommand);1750 ((DataSet) getAffectedDataSet()).update(super::undoCommand); 1751 1751 } 1752 1752 1753 1753 @Override 1754 1754 public boolean executeCommand() { 1755 return getAffectedDataSet().update(super::executeCommand);1755 return ((DataSet) getAffectedDataSet()).update(super::executeCommand); 1756 1756 } 1757 1757 } 1758 1758 } -
src/org/openstreetmap/josm/actions/JoinNodeWayAction.java
29 29 import org.openstreetmap.josm.data.UndoRedoHandler; 30 30 import org.openstreetmap.josm.data.coor.EastNorth; 31 31 import org.openstreetmap.josm.data.osm.DataSet; 32 import org.openstreetmap.josm.data.osm.IPrimitive; 32 33 import org.openstreetmap.josm.data.osm.Node; 33 34 import org.openstreetmap.josm.data.osm.OsmPrimitive; 35 import org.openstreetmap.josm.data.osm.Relation; 34 36 import org.openstreetmap.josm.data.osm.Way; 35 37 import org.openstreetmap.josm.data.osm.WaySegment; 36 38 import org.openstreetmap.josm.data.projection.ProjectionRegistry; … … 92 94 return; 93 95 DataSet ds = getLayerManager().getEditDataSet(); 94 96 Collection<Node> selectedNodes = ds.getSelectedNodes(); 95 Collection<Command > cmds = new LinkedList<>();97 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new LinkedList<>(); 96 98 Map<Way, MultiMap<Integer, Node>> data = new LinkedHashMap<>(); 97 99 98 100 // If the user has selected some ways, only join the node to these. … … 101 103 // Planning phase: decide where we'll insert the nodes and put it all in "data" 102 104 MapView mapView = MainApplication.getMap().mapView; 103 105 for (Node node : selectedNodes) { 104 List<WaySegment > wss = mapView.getNearestWaySegments(mapView.getPoint(node), OsmPrimitive::isSelectable);106 List<WaySegment<Node, Way>> wss = mapView.getNearestWaySegments(mapView.getPoint(node), IPrimitive::isSelectable); 105 107 // we cannot trust the order of elements in wss because it was calculated based on rounded position value of node 106 TreeMap<Double, List<WaySegment >> nearestMap = new TreeMap<>();108 TreeMap<Double, List<WaySegment<Node, Way>>> nearestMap = new TreeMap<>(); 107 109 EastNorth en = node.getEastNorth(); 108 for (WaySegment ws : wss) {110 for (WaySegment<Node, Way> ws : wss) { 109 111 // Maybe cleaner to pass a "isSelected" predicate to getNearestWaySegments, but this is less invasive. 110 112 if (restrictToSelectedWays && !ws.way.isSelected()) { 111 113 continue; … … 119 121 ws.getSecondNode().getEastNorth(), en)); 120 122 // resolution in numbers with large exponent not needed here.. 121 123 distSq = Double.longBitsToDouble(Double.doubleToLongBits(distSq) >> 32 << 32); 122 List<WaySegment > wslist = nearestMap.computeIfAbsent(distSq, k -> new LinkedList<>());124 List<WaySegment<Node, Way>> wslist = nearestMap.computeIfAbsent(distSq, k -> new LinkedList<>()); 123 125 wslist.add(ws); 124 126 } 125 127 Set<Way> seenWays = new HashSet<>(); 126 128 Double usedDist = null; 127 129 while (!nearestMap.isEmpty()) { 128 Entry<Double, List<WaySegment >> entry = nearestMap.pollFirstEntry();130 Entry<Double, List<WaySegment<Node, Way>>> entry = nearestMap.pollFirstEntry(); 129 131 if (usedDist != null) { 130 132 double delta = entry.getKey() - usedDist; 131 133 if (delta > 1e-4) 132 134 break; 133 135 } 134 for (WaySegment ws : entry.getValue()) {136 for (WaySegment<Node, Way> ws : entry.getValue()) { 135 137 // only use the closest WaySegment of each way and ignore those that already contain the node 136 138 if (!ws.getFirstNode().equals(node) && !ws.getSecondNode().equals(node) 137 139 && !seenWays.contains(ws.way)) { … … 179 181 } 180 182 continue; 181 183 } 182 MoveCommand c = new MoveCommand(node,184 MoveCommand<OsmPrimitive, Node, Way, Relation> c = new MoveCommand<>(node, 183 185 ProjectionRegistry.getProjection().eastNorth2latlon(newPosition)); 184 186 cmds.add(c); 185 187 movedNodes.put(node, newPosition); … … 193 195 } 194 196 Way wnew = new Way(w); 195 197 wnew.setNodes(wayNodes); 196 cmds.add(new ChangeCommand (ds, w, wnew));198 cmds.add(new ChangeCommand<>(ds, w, wnew)); 197 199 } 198 200 199 201 if (cmds.isEmpty()) return; 200 UndoRedoHandler.getInstance().add(new SequenceCommand (getValue(NAME).toString(), cmds));202 UndoRedoHandler.getInstance().add(new SequenceCommand<>(getValue(NAME).toString(), cmds)); 201 203 } 202 204 203 205 /** -
src/org/openstreetmap/josm/actions/JosmAction.java
18 18 import org.openstreetmap.josm.command.Command; 19 19 import org.openstreetmap.josm.data.osm.DataSelectionListener; 20 20 import org.openstreetmap.josm.data.osm.DataSet; 21 import org.openstreetmap.josm.data.osm.IPrimitive; 21 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 22 23 import org.openstreetmap.josm.data.osm.OsmUtils; 23 24 import org.openstreetmap.josm.data.osm.event.SelectionEventManager; … … 507 508 */ 508 509 public static boolean checkAndConfirmOutlyingOperation(String operation, 509 510 String dialogTitle, String outsideDialogMessage, String incompleteDialogMessage, 510 Collection<? extends OsmPrimitive> primitives,511 Collection<? extends OsmPrimitive> ignore) {511 Collection<? extends IPrimitive> primitives, 512 Collection<? extends IPrimitive> ignore) { 512 513 int checkRes = Command.checkOutlyingOrIncompleteOperation(primitives, ignore); 513 514 if ((checkRes & Command.IS_OUTSIDE) != 0) { 514 515 JPanel msg = new JPanel(new GridBagLayout()); -
src/org/openstreetmap/josm/actions/MergeNodesAction.java
29 29 import org.openstreetmap.josm.data.coor.EastNorth; 30 30 import org.openstreetmap.josm.data.coor.LatLon; 31 31 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 32 import org.openstreetmap.josm.data.osm.INode; 33 import org.openstreetmap.josm.data.osm.IPrimitive; 32 34 import org.openstreetmap.josm.data.osm.Node; 33 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; 34 36 import org.openstreetmap.josm.data.osm.OsmUtils; … … 47 49 import org.openstreetmap.josm.tools.Logging; 48 50 import org.openstreetmap.josm.tools.Shortcut; 49 51 import org.openstreetmap.josm.tools.UserCancelException; 52 import org.openstreetmap.josm.tools.Utils; 50 53 51 54 /** 52 55 * Merges a collection of nodes into one node. … … 81 84 82 85 if (selectedNodes.size() == 1) { 83 86 MapView mapView = MainApplication.getMap().mapView; 84 List< Node> nearestNodes = mapView.getNearestNodes(85 mapView.getPoint(selectedNodes.get(0)), selectedNodes, OsmPrimitive::isUsable);87 List<INode> nearestNodes = mapView.getNearestNodes( 88 mapView.getPoint(selectedNodes.get(0)), new ArrayList<>(selectedNodes), IPrimitive::isUsable); 86 89 if (nearestNodes.isEmpty()) { 87 90 new Notification( 88 91 tr("Please select at least two nodes to merge or one node that is close to another node.")) … … 90 93 .show(); 91 94 return; 92 95 } 93 selectedNodes.addAll(nearestNodes);96 nearestNodes.forEach(n -> selectedNodes.add((Node) n)); 94 97 } 95 98 96 99 Node targetNode = selectTargetNode(selectedNodes); … … 169 172 * @param candidates the collection of candidate nodes 170 173 * @return the selected target node 171 174 */ 172 public static Node selectTargetNode(Collection<Node> candidates) {173 N odeoldestNode = null;174 N odetargetNode = null;175 N odelastNode = null;176 for (N oden : candidates) {175 public static <N extends INode> N selectTargetNode(Collection<N> candidates) { 176 N oldestNode = null; 177 N targetNode = null; 178 N lastNode = null; 179 for (N n : candidates) { 177 180 if (!n.isNew()) { 178 181 // Among existing nodes, try to keep the oldest used one 179 182 if (!n.getReferrers().isEmpty()) { … … 292 295 * @throws IllegalArgumentException if {@code layer} is null 293 296 * @since 12689 294 297 */ 295 public static Command mergeNodes(Collection<Node> nodes, NodetargetLocationNode) {298 public static <N extends INode> Command<?, N, ?, ?> mergeNodes(Collection<N> nodes, N targetLocationNode) { 296 299 if (nodes == null) { 297 300 return null; 298 301 } 299 Set<N ode> allNodes = new HashSet<>(nodes);302 Set<N> allNodes = new HashSet<>(nodes); 300 303 allNodes.add(targetLocationNode); 301 N odetargetNode = selectTargetNode(allNodes);304 N targetNode = selectTargetNode(allNodes); 302 305 if (targetNode == null) { 303 306 return null; 304 307 } … … 314 317 * @return The command necessary to run in order to perform action, or {@code null} if there is nothing to do 315 318 * @throws IllegalArgumentException if layer is null 316 319 */ 317 public static Command mergeNodes(Collection<Node> nodes, Node targetNode, NodetargetLocationNode) {320 public static <N extends INode> Command<?, N, ?, ?> mergeNodes(Collection<N> nodes, N targetNode, N targetLocationNode) { 318 321 CheckParameterUtil.ensureParameterNotNull(targetNode, "targetNode"); 319 322 if (nodes == null) { 320 323 return null; … … 325 328 326 329 // the nodes we will have to delete 327 330 // 328 Collection<N ode> nodesToDelete = new HashSet<>(nodes);331 Collection<N> nodesToDelete = new HashSet<>(nodes); 329 332 nodesToDelete.remove(targetNode); 330 333 331 334 // fix the ways referring to at least one of the merged nodes 332 335 // 333 List<Command > wayFixCommands = fixParentWays(nodesToDelete, targetNode);336 List<Command<?, N, ?, ?>> wayFixCommands = fixParentWays(nodesToDelete, targetNode); 334 337 if (wayFixCommands == null) { 335 338 return null; 336 339 } 337 List<Command > cmds = new LinkedList<>(wayFixCommands);340 List<Command<?, N, ?, ?>> cmds = new LinkedList<>(wayFixCommands); 338 341 339 342 // build the commands 340 343 // … … 341 344 if (!targetNode.equals(targetLocationNode)) { 342 345 LatLon targetLocationCoor = targetLocationNode.getCoor(); 343 346 if (!Objects.equals(targetNode.getCoor(), targetLocationCoor)) { 344 N ode newTargetNode = new Node(targetNode);347 N newTargetNode = Utils.clone(targetNode); 345 348 newTargetNode.setCoor(targetLocationCoor); 346 cmds.add(new ChangeCommand (targetNode, newTargetNode));349 cmds.add(new ChangeCommand<>(targetNode, newTargetNode)); 347 350 } 348 351 } 349 352 cmds.addAll(CombinePrimitiveResolverDialog.launchIfNecessary(nodeTags, nodes, Collections.singleton(targetNode))); 350 353 if (!nodesToDelete.isEmpty()) { 351 cmds.add(new DeleteCommand (nodesToDelete));354 cmds.add(new DeleteCommand<>(nodesToDelete)); 352 355 } 353 356 if (cmds.size() == 1) 354 357 return cmds.get(0); -
src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
18 18 import org.openstreetmap.josm.command.DeleteCommand; 19 19 import org.openstreetmap.josm.data.UndoRedoHandler; 20 20 import org.openstreetmap.josm.data.osm.DataSet; 21 import org.openstreetmap.josm.data.osm. Node;22 import org.openstreetmap.josm.data.osm. OsmPrimitive;21 import org.openstreetmap.josm.data.osm.INode; 22 import org.openstreetmap.josm.data.osm.IPrimitive; 23 23 import org.openstreetmap.josm.data.osm.Relation; 24 24 import org.openstreetmap.josm.data.osm.WaySegment; 25 25 import org.openstreetmap.josm.gui.MainApplication; … … 90 90 91 91 private static class DeleteParameters { 92 92 private DeleteMode mode; 93 private Node nearestNode;93 private INode nearestNode; 94 94 private WaySegment nearestSegment; 95 95 } 96 96 … … 195 195 * handles everything related to highlighting primitives and way 196 196 * segments for the given pointer position (via MouseEvent) and modifiers. 197 197 * @param e current mouse event 198 * @param modifiers extended mouse modifiers, not necessar ly taken from the given mouse event198 * @param modifiers extended mouse modifiers, not necessarily taken from the given mouse event 199 199 */ 200 200 private void addHighlighting(MouseEvent e, int modifiers) { 201 201 if (!drawTargetHighlight) … … 212 212 // silent operation and SplitWayAction will show dialogs. A lot. 213 213 Command delCmd = buildDeleteCommands(e, modifiers, true); 214 214 // all other cases delete OsmPrimitives directly, so we can safely do the following 215 repaintIfRequired(delCmd == null ? Collections.emptySet() : new HashSet< >(delCmd.getParticipatingPrimitives()), null);215 repaintIfRequired(delCmd == null ? Collections.emptySet() : new HashSet<IPrimitive>(delCmd.getParticipatingPrimitives()), null); 216 216 } 217 217 } 218 218 219 private void repaintIfRequired(Set< OsmPrimitive> newHighlights, WaySegment newHighlightedWaySegment) {219 private void repaintIfRequired(Set<IPrimitive> newHighlights, WaySegment newHighlightedWaySegment) { 220 220 boolean needsRepaint = false; 221 221 OsmDataLayer editLayer = getLayerManager().getEditLayer(); 222 222 … … 364 364 DeleteParameters result = new DeleteParameters(); 365 365 366 366 MapView mapView = MainApplication.getMap().mapView; 367 result.nearestNode = mapView.getNearestNode(e.getPoint(), OsmPrimitive::isSelectable);367 result.nearestNode = mapView.getNearestNode(e.getPoint(), IPrimitive::isSelectable); 368 368 if (result.nearestNode == null) { 369 result.nearestSegment = mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive::isSelectable);369 result.nearestSegment = mapView.getNearestWaySegment(e.getPoint(), IPrimitive::isSelectable); 370 370 if (result.nearestSegment != null) { 371 371 if (shift) { 372 372 result.mode = DeleteMode.segment; -
src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
39 39 import org.openstreetmap.josm.data.coor.EastNorth; 40 40 import org.openstreetmap.josm.data.osm.DataIntegrityProblemException; 41 41 import org.openstreetmap.josm.data.osm.DataSet; 42 import org.openstreetmap.josm.data.osm.INode; 43 import org.openstreetmap.josm.data.osm.IPrimitive; 44 import org.openstreetmap.josm.data.osm.IRelation; 45 import org.openstreetmap.josm.data.osm.IWay; 42 46 import org.openstreetmap.josm.data.osm.Node; 43 47 import org.openstreetmap.josm.data.osm.OsmPrimitive; 44 48 import org.openstreetmap.josm.data.osm.Way; … … 78 82 private boolean nodeDragWithoutCtrl; 79 83 80 84 private long mouseDownTime; 81 private transient WaySegment selectedSegment;82 private transient Node selectedNode;85 private transient WaySegment<INode, IWay<INode>> selectedSegment; 86 private transient INode selectedNode; 83 87 private Color mainColor; 84 88 private transient Stroke mainStroke; 85 89 … … 106 110 /** 107 111 * Collection of nodes that is moved 108 112 */ 109 private transient List< Node> movingNodeList;113 private transient List<INode> movingNodeList; 110 114 111 115 /** 112 116 * The direction that is currently active. … … 141 145 /** 142 146 * the command that performed last move. 143 147 */ 144 private transient MoveCommand moveCommand;148 private transient MoveCommand<?, ?, ?, ?> moveCommand; 145 149 /** 146 150 * The command used for dual alignment movement. 147 151 * Needs to be separate, due to two nodes moving in different directions. 148 152 */ 149 private transient MoveCommand moveCommand2;153 private transient MoveCommand<?, ?, ?, ?> moveCommand2; 150 154 151 155 /** The cursor for the 'create_new' mode. */ 152 156 private final Cursor cursorCreateNew; … … 392 396 requestFocusInMapView(); 393 397 updateKeyModifiers(e); 394 398 395 selectedNode = map.mapView.getNearestNode(e.getPoint(), OsmPrimitive::isSelectable);396 selectedSegment = map.mapView.getNearestWaySegment(e.getPoint(), OsmPrimitive::isSelectable);399 selectedNode = map.mapView.getNearestNode(e.getPoint(), IPrimitive::isSelectable); 400 selectedSegment = map.mapView.getNearestWaySegment(e.getPoint(), IPrimitive::isSelectable); 397 401 398 402 // If nothing gets caught, stay in select mode 399 403 if (selectedSegment == null && selectedNode == null) return; … … 488 492 // move nodes to new position 489 493 if (moveCommand == null || moveCommand2 == null) { 490 494 // make a new move commands 491 moveCommand = new MoveCommand(movingNodeList.get(0), movement1.getX(), movement1.getY()); 492 moveCommand2 = new MoveCommand(movingNodeList.get(1), movement2.getX(), movement2.getY()); 493 Command c = new SequenceCommand(tr("Extrude Way"), moveCommand, moveCommand2); 495 MoveCommand<IPrimitive, INode, IWay<INode>, IRelation<?>> tCommand = new MoveCommand<>(movingNodeList.get(0), movement1.getX(), movement1.getY()); 496 MoveCommand<IPrimitive, INode, IWay<INode>, IRelation<?>> tCommand2 = new MoveCommand<>(movingNodeList.get(1), movement2.getX(), movement2.getY()); 497 moveCommand = tCommand; 498 moveCommand2 = tCommand2; 499 Command<?, ?, ?, ?> c = new SequenceCommand<>(tr("Extrude Way"), tCommand, tCommand2); 494 500 UndoRedoHandler.getInstance().add(c); 495 501 } else { 496 502 // reuse existing move commands … … 505 511 //move nodes to new position 506 512 if (moveCommand == null) { 507 513 //make a new move command 508 moveCommand = new MoveCommand (new ArrayList<OsmPrimitive>(movingNodeList), bestMovement);514 moveCommand = new MoveCommand<>(new ArrayList<IPrimitive>(movingNodeList), bestMovement); 509 515 UndoRedoHandler.getInstance().add(moveCommand); 510 516 } else { 511 517 //reuse existing move command -
src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
35 35 import org.openstreetmap.josm.data.osm.DataSet; 36 36 import org.openstreetmap.josm.data.osm.Node; 37 37 import org.openstreetmap.josm.data.osm.OsmPrimitive; 38 import org.openstreetmap.josm.data.osm.Relation; 38 39 import org.openstreetmap.josm.data.osm.Way; 39 40 import org.openstreetmap.josm.data.osm.WaySegment; 40 41 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; … … 88 89 89 90 private transient Way targetWay; 90 91 private transient Node candidateNode; 91 private transient WaySegment candidateSegment;92 private transient WaySegment<Node, Way> candidateSegment; 92 93 93 94 private Point mousePos; 94 95 private boolean dragging; … … 437 438 438 439 if (ctrl && !alt && candidateSegment != null) { 439 440 // Add a new node to the highlighted segment. 440 Collection<WaySegment > virtualSegments = new LinkedList<>();441 Collection<WaySegment<Node, Way>> virtualSegments = new LinkedList<>(); 441 442 442 443 // Check if other ways have the same segment. 443 444 // We have to make sure that we add the new node to all of them. … … 445 446 commonParentWays.retainAll(candidateSegment.getSecondNode().getParentWays()); 446 447 for (Way w : commonParentWays) { 447 448 for (int i = 0; i < w.getNodesCount() - 1; i++) { 448 WaySegment testWS = new WaySegment(w, i);449 WaySegment<Node, Way> testWS = new WaySegment<>(w, i); 449 450 if (testWS.isSimilar(candidateSegment)) { 450 451 virtualSegments.add(testWS); 451 452 } … … 452 453 } 453 454 } 454 455 455 Collection<Command > virtualCmds = new LinkedList<>();456 Collection<Command<OsmPrimitive, Node, Way, Relation>> virtualCmds = new LinkedList<>(); 456 457 // Create the new node 457 458 Node virtualNode = new Node(mv.getEastNorth(mousePos.x, mousePos.y)); 458 virtualCmds.add(new AddCommand (ds, virtualNode));459 virtualCmds.add(new AddCommand<>(ds, virtualNode)); 459 460 460 461 // Adding the node to all segments found 461 for (WaySegment virtualSegment : virtualSegments) {462 for (WaySegment<Node, Way> virtualSegment : virtualSegments) { 462 463 Way w = virtualSegment.way; 463 464 Way wnew = new Way(w); 464 465 wnew.addNode(virtualSegment.lowerIndex + 1, virtualNode); 465 virtualCmds.add(new ChangeCommand (w, wnew));466 virtualCmds.add(new ChangeCommand<>(w, wnew)); 466 467 } 467 468 468 469 // Finishing the sequence command … … 485 486 nodes.remove(candidateNode); 486 487 newWay.setNodes(nodes); 487 488 if (nodes.size() < 2) { 488 final Command deleteCmd = DeleteCommand.delete(Collections.singleton(targetWay), true);489 final Command<OsmPrimitive, Node, Way, Relation> deleteCmd = DeleteCommand.delete(Collections.singleton(targetWay), true); 489 490 if (deleteCmd != null) { 490 491 UndoRedoHandler.getInstance().add(deleteCmd); 491 492 } 492 493 } else { 493 UndoRedoHandler.getInstance().add(new ChangeCommand (targetWay, newWay));494 UndoRedoHandler.getInstance().add(new ChangeCommand<>(targetWay, newWay)); 494 495 } 495 496 } else if (candidateNode.isTagged()) { 496 497 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), … … 497 498 tr("Cannot delete node that has tags"), 498 499 tr("Error"), JOptionPane.ERROR_MESSAGE); 499 500 } else { 500 final Command deleteCmd = DeleteCommand.delete(Collections.singleton(candidateNode), true);501 final Command<OsmPrimitive, Node, Way, Relation> deleteCmd = DeleteCommand.delete(Collections.singleton(candidateNode), true); 501 502 if (deleteCmd != null) { 502 503 UndoRedoHandler.getInstance().add(deleteCmd); 503 504 } … … 509 510 EastNorth cursorEN = mv.getEastNorth(mousePos.x, mousePos.y); 510 511 511 512 UndoRedoHandler.getInstance().add( 512 new MoveCommand (candidateNode, cursorEN.east() - nodeEN.east(), cursorEN.north() - nodeEN.north()));513 new MoveCommand<>(candidateNode, cursorEN.east() - nodeEN.east(), cursorEN.north() - nodeEN.north())); 513 514 } 514 515 } 515 516 -
src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java
6 6 import java.util.List; 7 7 8 8 import org.openstreetmap.josm.data.coor.EastNorth; 9 import org.openstreetmap.josm.data.osm.INode; 10 import org.openstreetmap.josm.data.osm.IPrimitive; 9 11 import org.openstreetmap.josm.data.osm.Node; 10 import org.openstreetmap.josm.data.osm.OsmPrimitive;11 12 import org.openstreetmap.josm.data.osm.Way; 12 13 import org.openstreetmap.josm.data.osm.WaySegment; 13 14 import org.openstreetmap.josm.gui.MainApplication; … … 40 41 return null; 41 42 } 42 43 43 Node node = mv.getNearestNode(p, OsmPrimitive::isSelectable);44 INode node = mv.getNearestNode(p, IPrimitive::isSelectable); 44 45 Way candidate = null; 45 46 46 47 if (node != null) { 47 final Collection< OsmPrimitive> candidates =node.getReferrers();48 for ( OsmPrimitive refferer : candidates) {48 final Collection<IPrimitive> candidates = (Collection<IPrimitive>) node.getReferrers(); 49 for (IPrimitive refferer : candidates) { 49 50 if (refferer instanceof Way) { 50 51 candidate = (Way) refferer; 51 52 break; … … 56 57 } 57 58 } 58 59 59 return MainApplication.getMap().mapView.getNearestWay(p, OsmPrimitive::isSelectable);60 return MainApplication.getMap().mapView.getNearestWay(p, IPrimitive::isSelectable); 60 61 } 61 62 62 63 /** … … 125 126 * @param p the cursor position 126 127 * @return nearest way segment to cursor 127 128 */ 128 public static WaySegment findCandidateSegment(MapView mv, Way w, Point p) {129 public static WaySegment<Node, Way> findCandidateSegment(MapView mv, Way w, Point p) { 129 130 if (mv == null || w == null || p == null) { 130 131 return null; 131 132 } … … 172 173 } 173 174 174 175 } 175 return candidate != -1 ? new WaySegment (w, candidate) : null;176 return candidate != -1 ? new WaySegment<Node, Way>(w, candidate) : null; 176 177 } 177 178 } -
src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
11 11 import java.awt.event.KeyEvent; 12 12 import java.awt.event.MouseEvent; 13 13 import java.awt.geom.Point2D; 14 import java.util.ArrayList; 14 15 import java.util.Collection; 15 16 import java.util.Collections; 16 17 import java.util.HashSet; … … 32 33 import org.openstreetmap.josm.data.UndoRedoHandler; 33 34 import org.openstreetmap.josm.data.coor.EastNorth; 34 35 import org.openstreetmap.josm.data.osm.DataSet; 36 import org.openstreetmap.josm.data.osm.INode; 37 import org.openstreetmap.josm.data.osm.IPrimitive; 38 import org.openstreetmap.josm.data.osm.IRelation; 39 import org.openstreetmap.josm.data.osm.IWay; 35 40 import org.openstreetmap.josm.data.osm.Node; 36 41 import org.openstreetmap.josm.data.osm.OsmData; 37 42 import org.openstreetmap.josm.data.osm.OsmPrimitive; 43 import org.openstreetmap.josm.data.osm.Relation; 38 44 import org.openstreetmap.josm.data.osm.Way; 39 45 import org.openstreetmap.josm.data.osm.WaySegment; 40 46 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; … … 183 189 * to remove the highlight from them again as otherwise the whole data 184 190 * set would have to be checked. 185 191 */ 186 private transient Optional< OsmPrimitive> currentHighlight = Optional.empty();192 private transient Optional<IPrimitive> currentHighlight = Optional.empty(); 187 193 188 194 /** 189 195 * Create a new SelectAction … … 257 263 * @return {@code true} if repaint is required 258 264 */ 259 265 private boolean giveUserFeedback(MouseEvent e, int modifiers) { 260 Optional< OsmPrimitive> c = Optional.ofNullable(266 Optional<IPrimitive> c = Optional.ofNullable( 261 267 mv.getNearestNodeOrWay(e.getPoint(), mv.isSelectablePredicate, true)); 262 268 263 269 updateKeyModifiersEx(modifiers); 264 270 determineMapMode(c.isPresent()); 265 271 266 Optional< OsmPrimitive> newHighlight = Optional.empty();272 Optional<IPrimitive> newHighlight = Optional.empty(); 267 273 268 274 virtualManager.clear(); 269 275 if (mode == Mode.MOVE && !dragInProgress() && virtualManager.activateVirtualNodeNearPoint(e.getPoint())) { … … 300 306 * @param nearbyStuff primitives near the cursor 301 307 * @return the cursor that should be displayed 302 308 */ 303 private Cursor getCursor( OsmPrimitive nearbyStuff) {309 private Cursor getCursor(IPrimitive nearbyStuff) { 304 310 String c = "rect"; 305 311 switch(mode) { 306 312 case MOVE: … … 308 314 c = "virtual_node"; 309 315 break; 310 316 } 311 final OsmPrimitive osm = nearbyStuff;317 final IPrimitive osm = nearbyStuff; 312 318 313 319 if (dragInProgress()) { 314 320 // only consider merge if ctrl is pressed and there are nodes in … … 319 325 } 320 326 // only show merge to node cursor if nearby node and that node is currently 321 327 // not being dragged 322 final boolean hasTarget = osm instanceof Node && !osm.isSelected();328 final boolean hasTarget = osm instanceof INode && !osm.isSelected(); 323 329 c = hasTarget ? "merge_to_node" : "merge"; 324 330 break; 325 331 } 326 332 327 c = (osm instanceof Node) ? "node" : c;328 c = (osm instanceof Way) ? "way" : c;333 c = (osm instanceof INode) ? "node" : c; 334 c = (osm instanceof IWay) ? "way" : c; 329 335 if (shift) { 330 336 c += "_add"; 331 337 } else if (ctrl) { … … 369 375 return true; 370 376 } 371 377 372 private boolean repaintIfRequired(Optional< OsmPrimitive> newHighlight) {378 private boolean repaintIfRequired(Optional<IPrimitive> newHighlight) { 373 379 if (!drawTargetHighlight || currentHighlight.equals(newHighlight)) 374 380 return false; 375 381 currentHighlight.ifPresent(osm -> osm.setHighlighted(false)); … … 413 419 414 420 // primitives under cursor are stored in c collection 415 421 416 OsmPrimitive nearestPrimitive = mv.getNearestNodeOrWay(e.getPoint(), mv.isSelectablePredicate, true);422 IPrimitive nearestPrimitive = mv.getNearestNodeOrWay(e.getPoint(), mv.isSelectablePredicate, true); 417 423 418 424 determineMapMode(nearestPrimitive != null); 419 425 … … 437 443 if (!cancelDrawMode && nearestPrimitive instanceof Way) { 438 444 virtualManager.activateVirtualNodeNearPoint(e.getPoint()); 439 445 } 440 OsmPrimitive toSelect = cycleManager.cycleSetup(nearestPrimitive, e.getPoint());446 IPrimitive toSelect = cycleManager.cycleSetup(nearestPrimitive, e.getPoint()); 441 447 selectPrims(asColl(toSelect), false, false); 442 448 useLastMoveCommandIfPossible(); 443 449 // Schedule a timer to update status line "initialMoveDelay+1" ms in the future … … 510 516 // If ctrl is pressed we are in merge mode. Look for a nearby node, 511 517 // highlight it and adjust the cursor accordingly. 512 518 final boolean canMerge = ctrl && !getLayerManager().getEditDataSet().getSelectedNodes().isEmpty(); 513 final OsmPrimitive p = canMerge ? findNodeToMergeTo(e.getPoint()) : null;519 final IPrimitive p = canMerge ? findNodeToMergeTo(e.getPoint()) : null; 514 520 boolean needsRepaint = removeHighlighting(); 515 521 if (p != null) { 516 522 p.setHighlighted(true); … … 603 609 selectPrims(cycleManager.cyclePrims(), true, false); 604 610 605 611 // If the user double-clicked a node, change to draw mode 606 Collection< OsmPrimitive> c = ds.getSelected();607 if (e.getClickCount() >= 2 && c.size() == 1 && c.iterator().next() instanceof Node) {612 Collection<IPrimitive> c = new ArrayList<>(ds.getSelected()); 613 if (e.getClickCount() >= 2 && c.size() == 1 && c.iterator().next() instanceof INode) { 608 614 // We need to do it like this as otherwise drawAction will see a double 609 615 // click and switch back to SelectMode 610 616 MainApplication.worker.execute(() -> map.selectDrawTool(true)); … … 698 704 // Currently we support only transformations which do not affect relations. 699 705 // So don't add them in the first place to make handling easier 700 706 DataSet ds = getLayerManager().getEditDataSet(); 701 Collection< OsmPrimitive> selection = ds.getSelectedNodesAndWays();707 Collection<IPrimitive> selection = new ArrayList<>(ds.getSelectedNodesAndWays()); 702 708 if (selection.isEmpty()) { // if nothing was selected to drag, just select nearest node/way to the cursor 703 709 ds.setSelected(mv.getNearestNodeOrWay(mv.getPoint(startEN), mv.isSelectablePredicate, true)); 704 710 } 705 711 706 Collection< Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);712 Collection<INode> affectedNodes = new ArrayList<>(AllNodesVisitor.getAllNodes(selection)); 707 713 // for these transformations, having only one node makes no sense - quit silently 708 714 if (affectedNodes.size() < 2 && (mode == Mode.ROTATE || mode == Mode.SCALE)) { 709 715 return false; … … 721 727 moveCmd = new MoveCommand(selection, startEN, currentEN); 722 728 UndoRedoHandler.getInstance().add(moveCmd); 723 729 } 724 for ( Node n : affectedNodes) {730 for (INode n : affectedNodes) { 725 731 if (n.isOutSideWorld()) { 726 732 // Revert move 727 733 if (moveCmd != null) { … … 761 767 } 762 768 } 763 769 764 Collection< Way> ways = ds.getSelectedWays();770 Collection<IWay<?>> ways = new ArrayList<>(ds.getSelectedWays()); 765 771 if (doesImpactStatusLine(affectedNodes, ways)) { 766 772 MainApplication.getMap().statusLine.setDist(ways); 767 773 } 774 Logging.getLastErrorAndWarnings(); 768 775 return true; 769 776 }); 770 777 } 771 778 } 772 779 773 private static boolean doesImpactStatusLine(Collection< Node> affectedNodes, Collection<Way> selectedWays) {774 for ( Wayw : selectedWays) {775 for ( Node n : w.getNodes()) {780 private static boolean doesImpactStatusLine(Collection<INode> affectedNodes, Collection<IWay<?>> selectedWays) { 781 for (IWay<?> w : selectedWays) { 782 for (INode n : w.getNodes()) { 776 783 if (affectedNodes.contains(n)) { 777 784 return true; 778 785 } … … 791 798 return; 792 799 } 793 800 Command c = getLastCommandInDataset(dataSet); 794 Collection< Node> affectedNodes = AllNodesVisitor.getAllNodes(dataSet.getSelected());801 Collection<? extends INode> affectedNodes = AllNodesVisitor.getAllNodes(dataSet.getSelected()); 795 802 if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand) c).getParticipatingPrimitives())) { 796 803 // old command was created with different base point of movement, we need to recalculate it 797 804 ((MoveCommand) c).changeStartPoint(startEN); … … 803 810 * @param ds The data set the command needs to be in. 804 811 * @return last command 805 812 */ 806 private static Command getLastCommandInDataset(DataSetds) {807 Command lastCommand = UndoRedoHandler.getInstance().getLastCommand();813 private static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> getLastCommandInDataset(OsmData<O, N, W, R> ds) { 814 Command<O, N, W, R> lastCommand = UndoRedoHandler.getInstance().getLastCommand(); 808 815 if (lastCommand instanceof SequenceCommand) { 809 lastCommand = ( (SequenceCommand) lastCommand).getLastCommand();816 lastCommand = (Command<O, N, W, R>) ((SequenceCommand) lastCommand).getLastCommand(); 810 817 } 811 818 if (lastCommand != null && ds.equals(lastCommand.getAffectedDataSet())) { 812 819 return lastCommand; … … 830 837 ed.toggleEnable("movedHiddenElements"); 831 838 showConfirmMoveDialog(ed); 832 839 } 833 Set< Node> nodes = new HashSet<>();840 Set<INode> nodes = new HashSet<>(); 834 841 int max = Config.getPref().getInt("warn.move.maxelements", 20); 835 for ( OsmPrimitive osm : getLayerManager().getEditDataSet().getSelected()) {836 if (osm instanceof Way) {837 nodes.addAll((( Way) osm).getNodes());838 } else if (osm instanceof Node) {839 nodes.add(( Node) osm);842 for (IPrimitive osm : getLayerManager().getEditDataSet().getSelected()) { 843 if (osm instanceof IWay) { 844 nodes.addAll(((IWay<?>) osm).getNodes()); 845 } else if (osm instanceof INode) { 846 nodes.add((INode) osm); 840 847 } 841 848 if (nodes.size() > max) { 842 849 break; … … 875 882 } 876 883 877 884 private boolean movesHiddenWay() { 878 DataSet ds = getLayerManager().getEditDataSet(); 879 final Collection< Node> elementsToTest = new HashSet<>(ds.getSelectedNodes());880 for ( Wayosm : ds.getSelectedWays()) {885 DataSet ds = getLayerManager().getEditDataSet(); // TODO replace 886 final Collection<INode> elementsToTest = new HashSet<>(ds.getSelectedNodes()); 887 for (IWay<?> osm : ds.getSelectedWays()) { 881 888 elementsToTest.addAll(osm.getNodes()); 882 889 } 883 890 return elementsToTest.stream() 884 .flatMap(n -> n. referrers(Way.class))885 .anyMatch( Way::isDisabledAndHidden);891 .flatMap(n -> n.getReferrers().stream().filter(IWay.class::isInstance).map(IWay.class::cast)) 892 .anyMatch(IWay::isDisabledAndHidden); 886 893 } 887 894 888 895 /** … … 897 904 if (selNodes.isEmpty()) 898 905 return; 899 906 900 Node target = findNodeToMergeTo(p);907 INode target = findNodeToMergeTo(p); 901 908 if (target == null) 902 909 return; 903 910 904 911 if (selNodes.size() == 1) { 905 912 // Move all selected primitive to preserve shape #10748 906 Collection< OsmPrimitive> selection = ds.getSelectedNodesAndWays();907 Collection< Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);913 Collection<IPrimitive> selection = new HashSet<>(ds.getSelectedNodesAndWays()); 914 Collection<INode> affectedNodes = AllNodesVisitor.getAllNodes(selection); 908 915 Command c = getLastCommandInDataset(ds); 909 916 ds.update(() -> { 910 917 if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand) c).getParticipatingPrimitives())) { 911 Node selectedNode = selNodes.iterator().next();918 INode selectedNode = selNodes.iterator().next(); 912 919 EastNorth selectedEN = selectedNode.getEastNorth(); 913 920 EastNorth targetEN = target.getEastNorth(); 914 921 ((MoveCommand) c).moveAgain(targetEN.getX() - selectedEN.getX(), … … 917 924 }); 918 925 } 919 926 920 Collection< Node> nodesToMerge = new LinkedList<>(selNodes);927 Collection<INode> nodesToMerge = new LinkedList<>(selNodes); 921 928 nodesToMerge.add(target); 922 929 mergeNodes(MainApplication.getLayerManager().getEditLayer(), nodesToMerge, target); 923 930 } … … 929 936 * @param nodes the collection of nodes. Ignored if null 930 937 * @param targetLocationNode this node's location will be used for the target node 931 938 */ 932 public void mergeNodes(OsmDataLayer layer, Collection< Node> nodes,933 Node targetLocationNode) {939 public void mergeNodes(OsmDataLayer layer, Collection<INode> nodes, 940 INode targetLocationNode) { 934 941 MergeNodesAction.doMergeNodes(layer, nodes, targetLocationNode); 935 942 } 936 943 … … 940 947 * @param p mouse position 941 948 * @return node to merge to, or null 942 949 */ 943 private Node findNodeToMergeTo(Point p) {944 Collection< Node> target = mv.getNearestNodes(p,945 getLayerManager().getEditDataSet().getSelectedNodes(),950 private INode findNodeToMergeTo(Point p) { 951 Collection<INode> target = mv.getNearestNodes(p, 952 new ArrayList<>(getLayerManager().getEditDataSet().getSelectedNodes()), 946 953 mv.isSelectablePredicate); 947 954 return target.isEmpty() ? null : target.iterator().next(); 948 955 } 949 956 950 private void selectPrims(Collection< OsmPrimitive> prims, boolean released, boolean area) {951 DataSet ds = getLayerManager().getActiveDataSet();957 private void selectPrims(Collection<IPrimitive> prims, boolean released, boolean area) { 958 OsmData<?, ?, ?, ?> ds = getLayerManager().getActiveData(); 952 959 953 960 // not allowed together: do not change dataset selection, return early 954 961 // Virtual Ways: if non-empty the cursor is above a virtual node. So don't highlight … … 1027 1034 private final transient CycleManager cycleManager = new CycleManager(); 1028 1035 private final transient VirtualManager virtualManager = new VirtualManager(); 1029 1036 1030 private class CycleManager {1037 private class CycleManager<T extends IPrimitive> { 1031 1038 1032 private Collection< OsmPrimitive> cycleList = Collections.emptyList();1039 private Collection<T> cycleList = Collections.emptyList(); 1033 1040 private boolean cyclePrims; 1034 private OsmPrimitive cycleStart;1041 private IPrimitive cycleStart; 1035 1042 private boolean waitForMouseUpParameter; 1036 1043 private boolean multipleMatchesParameter; 1037 1044 /** … … 1048 1055 * @param p point where user clicked 1049 1056 * @return OsmPrimitive to be selected 1050 1057 */ 1051 private OsmPrimitive cycleSetup(OsmPrimitivenearest, Point p) {1052 OsmPrimitiveosm = null;1058 private T cycleSetup(T nearest, Point p) { 1059 T osm = null; 1053 1060 1054 1061 if (nearest != null) { 1055 1062 osm = nearest; … … 1070 1077 cyclePrims = false; 1071 1078 1072 1079 // find first already selected element in cycle list 1073 OsmPrimitiveold = osm;1074 for ( OsmPrimitiveo : cycleList) {1080 T old = osm; 1081 for (T o : cycleList) { 1075 1082 if (o.isSelected()) { 1076 1083 cyclePrims = true; 1077 1084 osm = o; … … 1105 1112 * <code>cycleList</code> field 1106 1113 * @return the next element of cycle list 1107 1114 */ 1108 private Collection< OsmPrimitive> cyclePrims() {1115 private Collection<IPrimitive> cyclePrims() { 1109 1116 if (cycleList.size() <= 1) { 1110 1117 // no real cycling, just return one-element collection with nearest primitive in it 1111 1118 return cycleList; … … 1113 1120 // updateKeyModifiers() already called before! 1114 1121 1115 1122 DataSet ds = getLayerManager().getActiveDataSet(); 1116 OsmPrimitive first = cycleList.iterator().next(), foundInDS = null;1117 OsmPrimitive nxt = first;1123 IPrimitive first = cycleList.iterator().next(), foundInDS = null; 1124 IPrimitive nxt = first; 1118 1125 1119 1126 if (cyclePrims && shift) { 1120 for (Iterator< OsmPrimitive> i = cycleList.iterator(); i.hasNext();) {1127 for (Iterator<IPrimitive> i = cycleList.iterator(); i.hasNext();) { 1121 1128 nxt = i.next(); 1122 1129 if (!nxt.isSelected()) { 1123 1130 break; // take first primitive in cycleList not in sel … … 1125 1132 } 1126 1133 // if primitives 1,2,3 are under cursor, [Alt-press] [Shift-release] gives 1 -> 12 -> 123 1127 1134 } else { 1128 for (Iterator< OsmPrimitive> i = cycleList.iterator(); i.hasNext();) {1135 for (Iterator<IPrimitive> i = cycleList.iterator(); i.hasNext();) { 1129 1136 nxt = i.next(); 1130 1137 if (nxt.isSelected()) { 1131 1138 foundInDS = nxt; … … 1168 1175 private class VirtualManager { 1169 1176 1170 1177 private Node virtualNode; 1171 private Collection<WaySegment > virtualWays = new LinkedList<>();1178 private Collection<WaySegment<?, ?>> virtualWays = new LinkedList<>(); 1172 1179 private int nodeVirtualSize; 1173 1180 private int virtualSnapDistSq2; 1174 1181 private int virtualSpace; … … 1194 1201 private boolean activateVirtualNodeNearPoint(Point p) { 1195 1202 if (nodeVirtualSize > 0) { 1196 1203 1197 Collection<WaySegment > selVirtualWays = new LinkedList<>();1198 Pair< Node,Node> vnp = null, wnp = new Pair<>(null, null);1204 Collection<WaySegment<?, ?>> selVirtualWays = new LinkedList<>(); 1205 Pair<INode, INode> vnp = null, wnp = new Pair<>(null, null); 1199 1206 1200 for (WaySegment ws : mv.getNearestWaySegments(p, mv.isSelectablePredicate)) {1201 Wayw = ws.way;1207 for (WaySegment<?, ?> ws : mv.getNearestWaySegments(p, mv.isSelectablePredicate)) { 1208 IWay<?> w = ws.way; 1202 1209 1203 1210 wnp.a = w.getNode(ws.lowerIndex); 1204 1211 wnp.b = w.getNode(ws.lowerIndex + 1); … … 1237 1244 if (startEN == null) // #13724, #14712, #15087 1238 1245 return; 1239 1246 DataSet ds = getLayerManager().getEditDataSet(); 1240 Collection<Command > virtualCmds = new LinkedList<>();1241 virtualCmds.add(new AddCommand (ds, virtualNode));1242 for (WaySegment virtualWay : virtualWays) {1247 Collection<Command<OsmPrimitive, Node, Way, Relation>> virtualCmds = new LinkedList<>(); 1248 virtualCmds.add(new AddCommand<>(ds, virtualNode)); 1249 for (WaySegment<Node, Way> virtualWay : virtualWays) { 1243 1250 Way w = virtualWay.way; 1244 1251 Way wnew = new Way(w); 1245 1252 wnew.addNode(virtualWay.lowerIndex + 1, virtualNode); 1246 virtualCmds.add(new ChangeCommand (ds, w, wnew));1253 virtualCmds.add(new ChangeCommand<>(ds, w, wnew)); 1247 1254 } 1248 virtualCmds.add(new MoveCommand (ds, virtualNode, startEN, currentEN));1255 virtualCmds.add(new MoveCommand<>(ds, virtualNode, startEN, currentEN)); 1249 1256 String text = trn("Add and move a virtual new node to way", 1250 1257 "Add and move a virtual new node to {0} ways", virtualWays.size(), 1251 1258 virtualWays.size()); -
src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java
15 15 import org.openstreetmap.josm.data.UndoRedoHandler; 16 16 import org.openstreetmap.josm.data.osm.DataSelectionListener; 17 17 import org.openstreetmap.josm.data.osm.IPrimitive; 18 import org.openstreetmap.josm.data.osm.Node; 18 19 import org.openstreetmap.josm.data.osm.OsmData; 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 21 import org.openstreetmap.josm.data.osm.OsmUtils; 20 22 import org.openstreetmap.josm.data.osm.Relation; 23 import org.openstreetmap.josm.data.osm.Way; 21 24 import org.openstreetmap.josm.gui.MainApplication; 22 25 import org.openstreetmap.josm.gui.Notification; 23 26 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor; … … 40 43 41 44 @Override 42 45 public void actionPerformed(ActionEvent e) { 43 Collection<Command > cmds = new LinkedList<>();46 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new LinkedList<>(); 44 47 for (Relation orig : Utils.filteredCollection(relations, Relation.class)) { 45 Command c = GenericRelationEditor.addPrimitivesToRelation(orig, MainApplication.getLayerManager().getActiveDataSet().getSelected());48 Command<OsmPrimitive, Node, Way, Relation> c = GenericRelationEditor.addPrimitivesToRelation(orig, MainApplication.getLayerManager().getActiveDataSet().getSelected()); 46 49 if (c != null) { 47 50 cmds.add(c); 48 51 } -
src/org/openstreetmap/josm/actions/upload/FixDataHook.java
16 16 import org.openstreetmap.josm.command.SequenceCommand; 17 17 import org.openstreetmap.josm.data.APIDataSet; 18 18 import org.openstreetmap.josm.data.UndoRedoHandler; 19 import org.openstreetmap.josm.data.osm.Node; 19 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 20 21 import org.openstreetmap.josm.data.osm.Relation; 22 import org.openstreetmap.josm.data.osm.Way; 21 23 import org.openstreetmap.josm.spi.preferences.Config; 22 24 import org.openstreetmap.josm.tools.Utils; 23 25 … … 187 189 @Override 188 190 public boolean checkUpload(APIDataSet apiDataSet) { 189 191 if (Config.getPref().getBoolean("fix.data.on.upload", true)) { 190 Collection<Command > cmds = new LinkedList<>();192 Collection<Command<OsmPrimitive, Node, Way, Relation>> cmds = new LinkedList<>(); 191 193 192 194 for (OsmPrimitive osm : apiDataSet.getPrimitives()) { 193 195 Map<String, String> keys = new HashMap<>(osm.getKeys()); -
src/org/openstreetmap/josm/command/AbstractNodesCommand.java
6 6 7 7 import javax.swing.Icon; 8 8 9 import org.openstreetmap.josm.data.osm.DataSet; 10 import org.openstreetmap.josm.data.osm.Node; 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 9 import org.openstreetmap.josm.data.osm.INode; 10 import org.openstreetmap.josm.data.osm.IPrimitive; 11 import org.openstreetmap.josm.data.osm.IRelation; 12 import org.openstreetmap.josm.data.osm.IWay; 13 import org.openstreetmap.josm.data.osm.OsmData; 12 14 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 13 import org.openstreetmap.josm.data.osm.Way;14 15 import org.openstreetmap.josm.tools.ImageProvider; 15 16 16 17 /** 17 18 * Abstracts superclass of {@link ChangeNodesCommand} / {@link RemoveNodesCommand}. 19 * @param <O> the base type of primitives 20 * @param <N> type representing nodes 21 * @param <W> type representing ways 22 * @param <R> type representing relations 18 23 * @param <C> type of nodes collection used for this command 19 24 * @since 15013 20 25 */ 21 public abstract class AbstractNodesCommand< C extends Collection<Node>> extends Command{26 public abstract class AbstractNodesCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>, C extends Collection<N>> extends Command<O, N, W, R> { 22 27 23 protected final W ayway;28 protected final W way; 24 29 protected final C cmdNodes; 25 30 26 31 /** … … 28 33 * @param way The way to modify 29 34 * @param cmdNodes The collection of nodes for this command 30 35 */ 31 protected AbstractNodesCommand(W ayway, C cmdNodes) {36 protected AbstractNodesCommand(W way, C cmdNodes) { 32 37 this(way.getDataSet(), way, cmdNodes); 33 38 } 34 39 … … 38 43 * @param way The way to modify 39 44 * @param cmdNodes The collection of nodes for this command 40 45 */ 41 protected AbstractNodesCommand( DataSet ds, Wayway, C cmdNodes) {46 protected AbstractNodesCommand(OsmData<O, N, W, R> ds, W way, C cmdNodes) { 42 47 super(ds); 43 48 this.way = Objects.requireNonNull(way, "way"); 44 49 this.cmdNodes = Objects.requireNonNull(cmdNodes, "cmdNodes"); … … 57 62 return true; 58 63 } 59 64 65 @SuppressWarnings("unchecked") 60 66 @Override 61 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {62 modified.add( way);67 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 68 modified.add((O) way); 63 69 } 64 70 65 71 @Override … … 77 83 if (this == obj) return true; 78 84 if (obj == null || getClass() != obj.getClass()) return false; 79 85 if (!super.equals(obj)) return false; 80 AbstractNodesCommand<? > that = (AbstractNodesCommand<?>) obj;86 AbstractNodesCommand<?, ?, ?, ?, ?> that = (AbstractNodesCommand<?, ?, ?, ?, ?>) obj; 81 87 return Objects.equals(way, that.way) && 82 88 Objects.equals(cmdNodes, that.cmdNodes); 83 89 } -
src/org/openstreetmap/josm/command/AddCommand.java
10 10 11 11 import javax.swing.Icon; 12 12 13 import org.openstreetmap.josm.data.osm.DataSet;14 13 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 15 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 import org.openstreetmap.josm.data.osm.INode; 15 import org.openstreetmap.josm.data.osm.IPrimitive; 16 import org.openstreetmap.josm.data.osm.IRelation; 17 import org.openstreetmap.josm.data.osm.IWay; 18 import org.openstreetmap.josm.data.osm.OsmData; 16 19 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 17 20 import org.openstreetmap.josm.data.osm.Way; 18 21 import org.openstreetmap.josm.tools.ImageProvider; … … 23 26 * See {@link ChangeCommand} for comments on relation back references. 24 27 * 25 28 * @author imi 29 * @param <O> the base type of primitives 30 * @param <N> type representing nodes 31 * @param <W> type representing ways 32 * @param <R> type representing relations 26 33 */ 27 public class AddCommand extends Command{34 public class AddCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 28 35 29 36 /** 30 37 * The primitive to add to the dataset. 31 38 */ 32 private final O smPrimitiveosm;39 private final O osm; 33 40 34 41 /** 35 42 * Creates the command and specify the element to add in the context of the given data set. … … 37 44 * @param osm The primitive to add 38 45 * @since 11240 39 46 */ 40 public AddCommand( DataSet data, OsmPrimitiveosm) {47 public AddCommand(OsmData<O, N, W, R> data, O osm) { 41 48 super(data); 42 49 this.osm = Objects.requireNonNull(osm, "osm"); 43 50 } 44 51 45 protected static final void checkNodeStyles(OsmPrimitiveosm) {52 protected static final <O extends IPrimitive> void checkNodeStyles(O osm) { 46 53 if (osm instanceof Way) { 47 54 // Fix #10557 - node icon not updated after undoing/redoing addition of a way 48 55 ((Way) osm).clearCachedNodeStyles(); … … 64 71 } 65 72 66 73 @Override 67 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {74 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 68 75 added.add(osm); 69 76 } 70 77 … … 86 93 } 87 94 88 95 @Override 89 public Collection<O smPrimitive> getParticipatingPrimitives() {96 public Collection<O> getParticipatingPrimitives() { 90 97 return Collections.singleton(osm); 91 98 } 92 99 … … 100 107 if (this == obj) return true; 101 108 if (obj == null || getClass() != obj.getClass()) return false; 102 109 if (!super.equals(obj)) return false; 103 AddCommand that = (AddCommand) obj;110 AddCommand<?, ?, ?, ?> that = (AddCommand<?, ?, ?, ?>) obj; 104 111 return Objects.equals(osm, that.osm); 105 112 } 106 113 } -
src/org/openstreetmap/josm/command/AddPrimitivesCommand.java
13 13 14 14 import javax.swing.Icon; 15 15 16 import org.openstreetmap.josm.data.osm.DataSet; 16 import org.openstreetmap.josm.data.osm.INode; 17 import org.openstreetmap.josm.data.osm.IPrimitive; 18 import org.openstreetmap.josm.data.osm.IRelation; 19 import org.openstreetmap.josm.data.osm.IWay; 17 20 import org.openstreetmap.josm.data.osm.Node; 18 21 import org.openstreetmap.josm.data.osm.NodeData; 22 import org.openstreetmap.josm.data.osm.OsmData; 19 23 import org.openstreetmap.josm.data.osm.OsmPrimitive; 20 24 import org.openstreetmap.josm.data.osm.PrimitiveData; 21 25 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 23 27 24 28 /** 25 29 * Add primitives to a data layer. 30 * @param <O> the base type of primitives 31 * @param <N> type representing nodes 32 * @param <W> type representing ways 33 * @param <R> type representing relations 26 34 * @since 2305 27 35 */ 28 public class AddPrimitivesCommand extends Command{36 public class AddPrimitivesCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 29 37 30 38 private List<PrimitiveData> data; 31 39 private Collection<PrimitiveData> toSelect; … … 32 40 private List<PrimitiveData> preExistingData; 33 41 34 42 // only filled on undo 35 private List<O smPrimitive> createdPrimitives;43 private List<O> createdPrimitives; 36 44 37 45 /** 38 46 * Constructs a new {@code AddPrimitivesCommand} to add data to the given data set. … … 41 49 * @param ds The target data set. Must not be {@code null} 42 50 * @since 12718 43 51 */ 44 public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, DataSetds) {52 public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, OsmData<O, N, W, R> ds) { 45 53 super(ds); 46 54 init(data, toSelect); 47 55 } … … 52 60 * @param ds The target data set. Must not be {@code null} 53 61 * @since 12726 54 62 */ 55 public AddPrimitivesCommand(List<PrimitiveData> data, DataSetds) {63 public AddPrimitivesCommand(List<PrimitiveData> data, OsmData<O, N, W, R> ds) { 56 64 this(data, data, ds); 57 65 } 58 66 … … 68 76 69 77 @Override 70 78 public boolean executeCommand() { 71 DataSetds = getAffectedDataSet();79 OsmData<O, N, W, R> ds = getAffectedDataSet(); 72 80 if (createdPrimitives == null) { // first time execution 73 81 List<OsmPrimitive> newPrimitives = new ArrayList<>(data.size()); 74 82 preExistingData = new ArrayList<>(); 75 83 76 84 for (PrimitiveData pd : data) { 77 O smPrimitiveprimitive = ds.getPrimitiveById(pd);85 O primitive = ds.getPrimitiveById(pd); 78 86 boolean created = primitive == null; 79 87 if (primitive == null) { 80 88 primitive = pd.getType().newInstance(pd.getUniqueId(), true); … … 100 108 } else { // redo 101 109 // When redoing this command, we have to add the same objects, otherwise 102 110 // a subsequent command (e.g. MoveCommand) cannot be redone. 103 for (O smPrimitiveosm : createdPrimitives) {111 for (O osm : createdPrimitives) { 104 112 if (preExistingData.stream().anyMatch(pd -> pd.getUniqueId() == osm.getUniqueId())) { 105 113 Optional<PrimitiveData> o = data.stream().filter(pd -> pd.getUniqueId() == osm.getUniqueId()).findAny(); 106 114 if (o.isPresent()) { … … 118 126 } 119 127 120 128 @Override public void undoCommand() { 121 DataSetds = getAffectedDataSet();129 OsmData<O, N, W, R> ds = getAffectedDataSet(); 122 130 if (createdPrimitives == null) { 123 131 createdPrimitives = new ArrayList<>(data.size()); 124 132 for (PrimitiveData pd : data) { 125 O smPrimitivep = ds.getPrimitiveById(pd);133 O p = ds.getPrimitiveById(pd); 126 134 createdPrimitives.add(p); 127 135 } 128 136 createdPrimitives = PurgeCommand.topoSort(createdPrimitives); 129 137 } 130 for (O smPrimitiveosm : createdPrimitives) {138 for (O osm : createdPrimitives) { 131 139 Optional<PrimitiveData> previous = preExistingData.stream().filter(pd -> pd.getUniqueId() == osm.getUniqueId()).findAny(); 132 140 if (previous.isPresent()) { 133 141 osm.load(previous.get()); … … 149 157 } 150 158 151 159 @Override 152 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted,153 Collection<O smPrimitive> added) {160 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, 161 Collection<O> added) { 154 162 // Does nothing because we don't want to create OsmPrimitives. 155 163 } 156 164 157 165 @Override 158 public Collection< ? extends OsmPrimitive> getParticipatingPrimitives() {166 public Collection<O> getParticipatingPrimitives() { 159 167 if (createdPrimitives != null) 160 168 return createdPrimitives; 161 169 162 Collection<O smPrimitive> prims = new HashSet<>();170 Collection<O> prims = new HashSet<>(); 163 171 for (PrimitiveData d : data) { 164 172 prims.add(Optional.ofNullable(getAffectedDataSet().getPrimitiveById(d)).orElseThrow( 165 173 () -> new JosmRuntimeException("No primitive found for " + d))); … … 177 185 if (this == obj) return true; 178 186 if (obj == null || getClass() != obj.getClass()) return false; 179 187 if (!super.equals(obj)) return false; 180 AddPrimitivesCommand that = (AddPrimitivesCommand) obj;188 AddPrimitivesCommand<?, ?, ?, ?> that = (AddPrimitivesCommand<?, ?, ?, ?>) obj; 181 189 return Objects.equals(data, that.data) && 182 190 Objects.equals(toSelect, that.toSelect) && 183 191 Objects.equals(preExistingData, that.preExistingData) && -
src/org/openstreetmap/josm/command/ChangeCommand.java
9 9 10 10 import javax.swing.Icon; 11 11 12 import org.openstreetmap.josm.data.osm.DataSet;13 12 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 13 import org.openstreetmap.josm.data.osm.INode; 14 import org.openstreetmap.josm.data.osm.IPrimitive; 15 import org.openstreetmap.josm.data.osm.IRelation; 16 import org.openstreetmap.josm.data.osm.IWay; 17 import org.openstreetmap.josm.data.osm.OsmData; 15 18 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 16 19 import org.openstreetmap.josm.data.osm.Way; 17 20 import org.openstreetmap.josm.tools.CheckParameterUtil; … … 19 22 20 23 /** 21 24 * Command that basically replaces one OSM primitive by another of the same type. 25 * @param <O> the base type of primitives 26 * @param <N> type representing nodes 27 * @param <W> type representing ways 28 * @param <R> type representing relations 22 29 * 23 30 * @since 93 24 31 */ 25 public class ChangeCommand extends Command{32 public class ChangeCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 26 33 27 private final O smPrimitiveosm;28 private final O smPrimitivenewOsm;34 private final O osm; 35 private final O newOsm; 29 36 30 37 /** 31 38 * Constructs a new {@code ChangeCommand} in the context of {@code osm} data set. … … 33 40 * @param newOsm The new primitive 34 41 * @throws IllegalArgumentException if sanity checks fail 35 42 */ 36 public ChangeCommand(O smPrimitive osm, OsmPrimitivenewOsm) {43 public ChangeCommand(O osm, O newOsm) { 37 44 this(osm.getDataSet(), osm, newOsm); 38 45 } 39 46 … … 45 52 * @throws IllegalArgumentException if sanity checks fail 46 53 * @since 11240 47 54 */ 48 public ChangeCommand( DataSet data, OsmPrimitive osm, OsmPrimitivenewOsm) {55 public ChangeCommand(OsmData<O, N, W, R> data, O osm, O newOsm) { 49 56 super(data); 50 57 this.osm = osm; 51 58 this.newOsm = newOsm; … … 70 77 } 71 78 72 79 @Override 73 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {80 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 74 81 modified.add(osm); 75 82 } 76 83 … … 96 103 * @return the original OSM primitive to modify 97 104 * @since 14283 98 105 */ 99 public final O smPrimitivegetOsmPrimitive() {106 public final O getOsmPrimitive() { 100 107 return osm; 101 108 } 102 109 … … 105 112 * @return the new OSM primitive 106 113 * @since 14283 107 114 */ 108 public final O smPrimitivegetNewOsmPrimitive() {115 public final O getNewOsmPrimitive() { 109 116 return newOsm; 110 117 } 111 118 … … 119 126 if (this == obj) return true; 120 127 if (obj == null || getClass() != obj.getClass()) return false; 121 128 if (!super.equals(obj)) return false; 122 ChangeCommand that = (ChangeCommand) obj;129 ChangeCommand<?, ?, ?, ?> that = (ChangeCommand<?, ?, ?, ?>) obj; 123 130 return Objects.equals(osm, that.osm) && 124 131 Objects.equals(newOsm, that.newOsm); 125 132 } -
src/org/openstreetmap/josm/command/ChangeNodesCommand.java
5 5 6 6 import java.util.List; 7 7 8 import org.openstreetmap.josm.data.osm.DataSet;9 8 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 10 import org.openstreetmap.josm.data.osm.Node; 11 import org.openstreetmap.josm.data.osm.Way; 9 import org.openstreetmap.josm.data.osm.INode; 10 import org.openstreetmap.josm.data.osm.IPrimitive; 11 import org.openstreetmap.josm.data.osm.IRelation; 12 import org.openstreetmap.josm.data.osm.IWay; 13 import org.openstreetmap.josm.data.osm.OsmData; 12 14 13 15 /** 14 16 * Command that changes the nodes list of a way. … … 17 19 * tool of the validator, when processing large data sets.) 18 20 * 19 21 * @author Imi 22 * @param <O> the base type of primitives 23 * @param <N> type representing nodes 24 * @param <W> type representing ways 25 * @param <R> type representing relations 20 26 */ 21 public class ChangeNodesCommand extends AbstractNodesCommand<List<Node>> {27 public class ChangeNodesCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends AbstractNodesCommand<O, N, W, R, List<N>> { 22 28 23 29 /** 24 30 * Constructs a new {@code ChangeNodesCommand}. … … 25 31 * @param way The way to modify 26 32 * @param newNodes The new list of nodes for the given way 27 33 */ 28 public ChangeNodesCommand(W ay way, List<Node> newNodes) {34 public ChangeNodesCommand(W way, List<N> newNodes) { 29 35 super(way.getDataSet(), way, newNodes); 30 36 } 31 37 … … 36 42 * @param newNodes The new list of nodes for the given way 37 43 * @since 12726 38 44 */ 39 public ChangeNodesCommand( DataSet ds, Way way, List<Node> newNodes) {45 public ChangeNodesCommand(OsmData<O, N, W, R> ds, W way, List<N> newNodes) { 40 46 super(ds, way, newNodes); 41 47 } 42 48 -
src/org/openstreetmap/josm/command/ChangePropertyCommand.java
18 18 19 19 import org.openstreetmap.josm.data.osm.DataSet; 20 20 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 21 import org.openstreetmap.josm.data.osm.Node; 21 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 22 23 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 24 import org.openstreetmap.josm.data.osm.Relation; 25 import org.openstreetmap.josm.data.osm.Way; 23 26 import org.openstreetmap.josm.tools.I18n; 24 27 import org.openstreetmap.josm.tools.ImageProvider; 25 28 … … 30 33 * @author imi 31 34 * @since 24 32 35 */ 33 public class ChangePropertyCommand extends Command {36 public class ChangePropertyCommand extends Command<OsmPrimitive, Node, Way, Relation> { 34 37 35 38 static final class OsmPseudoCommand implements PseudoCommand { 36 39 private final OsmPrimitive osm; -
src/org/openstreetmap/josm/command/ChangePropertyKeyCommand.java
15 15 import javax.swing.Icon; 16 16 17 17 import org.openstreetmap.josm.data.osm.DataSet; 18 import org.openstreetmap.josm.data.osm.Node; 18 19 import org.openstreetmap.josm.data.osm.OsmPrimitive; 20 import org.openstreetmap.josm.data.osm.Relation; 21 import org.openstreetmap.josm.data.osm.Way; 19 22 import org.openstreetmap.josm.data.validation.util.NameVisitor; 20 23 import org.openstreetmap.josm.tools.ImageProvider; 21 24 … … 23 26 * Command that replaces the key of one or several objects 24 27 * @since 3669 25 28 */ 26 public class ChangePropertyKeyCommand extends Command {29 public class ChangePropertyKeyCommand extends Command<OsmPrimitive, Node, Way, Relation> { 27 30 static final class SinglePrimitivePseudoCommand implements PseudoCommand { 28 31 private final String name; 29 32 private final OsmPrimitive osm; -
src/org/openstreetmap/josm/command/ChangeRelationMemberRoleCommand.java
10 10 11 11 import org.openstreetmap.josm.data.osm.DataSet; 12 12 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 13 import org.openstreetmap.josm.data.osm.Node; 13 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 15 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 15 16 import org.openstreetmap.josm.data.osm.Relation; 16 17 import org.openstreetmap.josm.data.osm.RelationMember; 18 import org.openstreetmap.josm.data.osm.Way; 17 19 import org.openstreetmap.josm.tools.ImageProvider; 18 20 19 21 /** … … 21 23 * 22 24 * @author Teemu Koskinen <teemu.koskinen@mbnet.fi> 23 25 */ 24 public class ChangeRelationMemberRoleCommand extends Command {26 public class ChangeRelationMemberRoleCommand extends Command<OsmPrimitive, Node, Way, Relation> { 25 27 26 28 // The relation to be changed 27 29 private final Relation relation; -
src/org/openstreetmap/josm/command/Command.java
12 12 import org.openstreetmap.josm.data.coor.EastNorth; 13 13 import org.openstreetmap.josm.data.coor.LatLon; 14 14 import org.openstreetmap.josm.data.osm.DataSet; 15 import org.openstreetmap.josm.data.osm.INode; 16 import org.openstreetmap.josm.data.osm.IPrimitive; 17 import org.openstreetmap.josm.data.osm.IRelation; 18 import org.openstreetmap.josm.data.osm.IWay; 15 19 import org.openstreetmap.josm.data.osm.Node; 20 import org.openstreetmap.josm.data.osm.OsmData; 16 21 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 22 import org.openstreetmap.josm.data.osm.PrimitiveData; 18 import org.openstreetmap.josm.data.osm.Relation; 19 import org.openstreetmap.josm.data.osm.Way; 20 import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor; 23 import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 21 24 import org.openstreetmap.josm.tools.CheckParameterUtil; 22 25 23 26 /** … … 27 30 * The command remembers the {@link DataSet} it is operating on. 28 31 * 29 32 * @author imi 33 * @param <O> the base type of primitives 34 * @param <N> type representing nodes 35 * @param <W> type representing ways 36 * @param <R> type representing relations 30 37 * @since 21 (creation) 31 38 * @since 10599 (signature) 32 39 */ 33 public abstract class Command implements PseudoCommand {40 public abstract class Command<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> implements PseudoCommand { 34 41 35 42 /** IS_OK : operation is okay */ 36 43 public static final int IS_OK = 0; … … 39 46 /** IS_INCOMPLETE: operation on incomplete target */ 40 47 public static final int IS_INCOMPLETE = 2; 41 48 42 private static final class CloneVisitor implements OsmPrimitiveVisitor{43 final Map<O smPrimitive, PrimitiveData> orig = new LinkedHashMap<>();49 private static final class CloneVisitor<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> implements PrimitiveVisitor<N, W, R> { 50 final Map<O, PrimitiveData> orig = new LinkedHashMap<>(); 44 51 45 52 @Override 46 public void visit(N oden) {53 public void visit(N n) { 47 54 orig.put(n, n.save()); 48 55 } 49 56 50 57 @Override 51 public void visit(W ayw) {58 public void visit(W w) { 52 59 orig.put(w, w.save()); 53 60 } 54 61 55 62 @Override 56 public void visit(R elatione) {63 public void visit(R e) { 57 64 orig.put(e, e.save()); 58 65 } 59 66 } … … 71 78 * Constructs a new {@code OldNodeState} for the given node. 72 79 * @param node The node whose state has to be remembered 73 80 */ 74 public OldNodeState( Node node) {81 public OldNodeState(INode node) { 75 82 latLon = node.getCoor(); 76 83 eastNorth = node.getEastNorth(); 77 84 modified = node.isModified(); … … 122 129 } 123 130 124 131 /** the map of OsmPrimitives in the original state to OsmPrimitives in cloned state */ 125 private Map<O smPrimitive, PrimitiveData> cloneMap = new HashMap<>();132 private Map<O, PrimitiveData> cloneMap = new HashMap<>(); 126 133 127 134 /** the dataset which this command is applied to */ 128 private final DataSetdata;135 private final OsmData<O, N, W, R> data; 129 136 130 137 /** 131 138 * Creates a new command in the context of a specific data set, without data layer … … 134 141 * @throws IllegalArgumentException if data is null 135 142 * @since 11240 136 143 */ 137 public Command( DataSetdata) {144 public Command(OsmData<O, N, W, R> data) { 138 145 CheckParameterUtil.ensureParameterNotNull(data, "data"); 139 146 this.data = data; 140 147 } … … 147 154 * @return true 148 155 */ 149 156 public boolean executeCommand() { 150 CloneVisitor visitor = new CloneVisitor();151 Collection<O smPrimitive> all = new ArrayList<>();157 CloneVisitor<O, N, W, R> visitor = new CloneVisitor<>(); 158 Collection<O> all = new ArrayList<>(); 152 159 fillModifiedData(all, all, all); 153 for (O smPrimitiveosm : all) {160 for (O osm : all) { 154 161 osm.accept(visitor); 155 162 } 156 163 cloneMap = visitor.orig; … … 165 172 * This implementation undoes all objects stored by a former call to executeCommand. 166 173 */ 167 174 public void undoCommand() { 168 for (Entry<O smPrimitive, PrimitiveData> e : cloneMap.entrySet()) {169 O smPrimitiveprimitive = e.getKey();175 for (Entry<O, PrimitiveData> e : cloneMap.entrySet()) { 176 O primitive = e.getKey(); 170 177 if (primitive.getDataSet() != null) { 171 178 e.getKey().load(e.getValue()); 172 179 } … … 188 195 * @return The data set. May be <code>null</code> if no layer was set and no edit layer was found. 189 196 * @since 10467 190 197 */ 191 public DataSetgetAffectedDataSet() {198 public OsmData<O, N, W, R> getAffectedDataSet() { 192 199 return data; 193 200 } 194 201 … … 200 207 * @param deleted The deleted primitives 201 208 * @param added The added primitives 202 209 */ 203 public abstract void fillModifiedData(Collection<O smPrimitive> modified,204 Collection<O smPrimitive> deleted,205 Collection<O smPrimitive> added);210 public abstract void fillModifiedData(Collection<O> modified, 211 Collection<O> deleted, 212 Collection<O> added); 206 213 207 214 /** 208 215 * Return the primitives that take part in this command. … … 209 216 * The collection is computed during execution. 210 217 */ 211 218 @Override 212 public Collection<? extends O smPrimitive> getParticipatingPrimitives() {219 public Collection<? extends O> getParticipatingPrimitives() { 213 220 return cloneMap.keySet(); 214 221 } 215 222 … … 221 228 * @return true, if operating on outlying primitives is OK; false, otherwise 222 229 */ 223 230 public static int checkOutlyingOrIncompleteOperation( 224 Collection<? extends OsmPrimitive> primitives,225 Collection<? extends OsmPrimitive> ignore) {231 Collection<? extends IPrimitive> primitives, 232 Collection<? extends IPrimitive> ignore) { 226 233 int res = 0; 227 for ( OsmPrimitive osm : primitives) {234 for (IPrimitive osm : primitives) { 228 235 if (osm.isIncomplete()) { 229 236 res |= IS_INCOMPLETE; 230 } else if (osm .isOutsideDownloadArea()237 } else if (osm instanceof OsmPrimitive && ((OsmPrimitive) osm).isOutsideDownloadArea() 231 238 && (ignore == null || !ignore.contains(osm))) { 232 239 res |= IS_OUTSIDE; 233 240 } … … 242 249 * @throws AssertionError if no {@link DataSet} is set or if any primitive does not belong to that dataset. 243 250 */ 244 251 protected void ensurePrimitivesAreInDataset() { 245 for ( OsmPrimitive primitive : this.getParticipatingPrimitives()) {252 for (IPrimitive primitive : this.getParticipatingPrimitives()) { 246 253 if (primitive.getDataSet() != this.getAffectedDataSet()) { 247 254 throw new AssertionError("Primitive is of wrong data set for this command: " + primitive); 248 255 } … … 258 265 public boolean equals(Object obj) { 259 266 if (this == obj) return true; 260 267 if (obj == null || getClass() != obj.getClass()) return false; 261 Command command = (Command) obj;268 Command<?, ?, ?, ?> command = (Command<?, ?, ?, ?>) obj; 262 269 return Objects.equals(cloneMap, command.cloneMap) && 263 270 Objects.equals(data, command.data); 264 271 } -
src/org/openstreetmap/josm/command/DeleteCommand.java
22 22 23 23 import javax.swing.Icon; 24 24 25 import org.openstreetmap.josm.data.osm.DataSet;26 25 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 27 import org.openstreetmap.josm.data.osm.Node; 26 import org.openstreetmap.josm.data.osm.INode; 27 import org.openstreetmap.josm.data.osm.IPrimitive; 28 import org.openstreetmap.josm.data.osm.IRelation; 29 import org.openstreetmap.josm.data.osm.IWay; 30 import org.openstreetmap.josm.data.osm.OsmData; 28 31 import org.openstreetmap.josm.data.osm.OsmPrimitive; 29 32 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 30 33 import org.openstreetmap.josm.data.osm.PrimitiveData; 31 import org.openstreetmap.josm.data.osm.Relation;32 34 import org.openstreetmap.josm.data.osm.RelationToChildReference; 33 import org.openstreetmap.josm.data.osm.Way;34 35 import org.openstreetmap.josm.data.osm.WaySegment; 35 36 import org.openstreetmap.josm.tools.CheckParameterUtil; 36 37 import org.openstreetmap.josm.tools.ImageProvider; … … 40 41 * A command to delete a number of primitives from the dataset. 41 42 * To be used correctly, this class requires an initial call to {@link #setDeletionCallback(DeletionCallback)} to 42 43 * allow interactive confirmation actions. 44 * @param <O> the base type of primitives 45 * @param <N> type representing nodes 46 * @param <W> type representing ways 47 * @param <R> type representing relations 43 48 * @since 23 44 49 */ 45 public class DeleteCommand extends Command{50 public class DeleteCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 46 51 private static final class DeleteChildCommand implements PseudoCommand { 47 private final OsmPrimitive osm;52 private final IPrimitive osm; 48 53 49 private DeleteChildCommand( OsmPrimitive osm) {54 private DeleteChildCommand(IPrimitive osm) { 50 55 this.osm = osm; 51 56 } 52 57 … … 61 66 } 62 67 63 68 @Override 64 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {69 public Collection<? extends IPrimitive> getParticipatingPrimitives() { 65 70 return Collections.singleton(osm); 66 71 } 67 72 … … 83 88 * @param ignore {@code null} or a primitive to be ignored 84 89 * @return true, if operating on outlying primitives is OK; false, otherwise 85 90 */ 86 boolean checkAndConfirmOutlyingDelete(Collection<? extends OsmPrimitive> primitives, Collection<? extends OsmPrimitive> ignore);91 boolean checkAndConfirmOutlyingDelete(Collection<? extends IPrimitive> primitives, Collection<? extends IPrimitive> ignore); 87 92 88 93 /** 89 94 * Confirm before deleting a relation, as it is a common newbie error. … … 91 96 * @return {@code true} if user confirms the deletion 92 97 * @since 12760 93 98 */ 94 boolean confirmRelationDeletion(Collection< Relation> relations);99 boolean confirmRelationDeletion(Collection<? extends IRelation<?>> relations); 95 100 96 101 /** 97 102 * Confirm before removing a collection of primitives from their parent relations. … … 117 122 /** 118 123 * The primitives that get deleted. 119 124 */ 120 private final Collection< ? extends OsmPrimitive> toDelete;121 private final Map<O smPrimitive, PrimitiveData> clonedPrimitives = new HashMap<>();125 private final Collection<O> toDelete; 126 private final Map<O, PrimitiveData> clonedPrimitives = new HashMap<>(); 122 127 123 128 /** 124 129 * Constructor. Deletes a collection of primitives in the current edit layer. … … 126 131 * @param data the primitives to delete. Must neither be null nor empty, and belong to a data set 127 132 * @throws IllegalArgumentException if data is null or empty 128 133 */ 129 public DeleteCommand(Collection<? extends O smPrimitive> data) {134 public DeleteCommand(Collection<? extends O> data) { 130 135 this(data.iterator().next().getDataSet(), data); 131 136 } 132 137 … … 136 141 * @param data the primitive to delete. Must not be null. 137 142 * @throws IllegalArgumentException if data is null 138 143 */ 139 public DeleteCommand(O smPrimitivedata) {144 public DeleteCommand(O data) { 140 145 this(Collections.singleton(data)); 141 146 } 142 147 … … 149 154 * @throws IllegalArgumentException if layer is null 150 155 * @since 12718 151 156 */ 152 public DeleteCommand( DataSet dataset, OsmPrimitivedata) {157 public DeleteCommand(OsmData<O, N, W, R> dataset, O data) { 153 158 this(dataset, Collections.singleton(data)); 154 159 } 155 160 … … 162 167 * @throws IllegalArgumentException if data is null or empty 163 168 * @since 11240 164 169 */ 165 public DeleteCommand( DataSet dataset, Collection<? extends OsmPrimitive> data) {170 public DeleteCommand(OsmData<O, N, W, R> dataset, Collection<? extends O> data) { 166 171 super(dataset); 167 172 CheckParameterUtil.ensureParameterNotNull(data, "data"); 168 this.toDelete = data;173 this.toDelete = new HashSet<>(data); 169 174 checkConsistency(); 170 175 } 171 176 … … 173 178 if (toDelete.isEmpty()) { 174 179 throw new IllegalArgumentException(tr("At least one object to delete required, got empty collection")); 175 180 } 176 for (O smPrimitivep : toDelete) {181 for (O p : toDelete) { 177 182 if (p == null) { 178 183 throw new IllegalArgumentException("Primitive to delete must not be null"); 179 184 } else if (p.getDataSet() == null) { … … 186 191 public boolean executeCommand() { 187 192 ensurePrimitivesAreInDataset(); 188 193 // Make copy and remove all references (to prevent inconsistent dataset (delete referenced) while command is executed) 189 for (O smPrimitiveosm: toDelete) {194 for (O osm: toDelete) { 190 195 if (osm.isDeleted()) 191 196 throw new IllegalArgumentException(osm + " is already deleted"); 192 197 clonedPrimitives.put(osm, osm.save()); 193 198 194 if (osm instanceof Way) {195 (( Way) osm).setNodes(null);196 } else if (osm instanceof Relation) {197 (( Relation) osm).setMembers(null);199 if (osm instanceof IWay<?>) { 200 ((IWay<?>) osm).setNodes(null); 201 } else if (osm instanceof IRelation<?>) { 202 ((IRelation<?>) osm).setMembers(null); 198 203 } 199 204 } 200 205 201 for (O smPrimitiveosm: toDelete) {206 for (O osm: toDelete) { 202 207 osm.setDeleted(true); 203 208 } 204 209 … … 209 214 public void undoCommand() { 210 215 ensurePrimitivesAreInDataset(); 211 216 212 for (O smPrimitiveosm: toDelete) {217 for (O osm: toDelete) { 213 218 osm.setDeleted(false); 214 219 } 215 220 216 for (Entry<O smPrimitive, PrimitiveData> entry: clonedPrimitives.entrySet()) {221 for (Entry<O, PrimitiveData> entry: clonedPrimitives.entrySet()) { 217 222 entry.getKey().load(entry.getValue()); 218 223 } 219 224 } 220 225 221 226 @Override 222 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {227 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 223 228 // Do nothing 224 229 } 225 230 226 231 private EnumSet<OsmPrimitiveType> getTypesToDelete() { 227 232 EnumSet<OsmPrimitiveType> typesToDelete = EnumSet.noneOf(OsmPrimitiveType.class); 228 for (O smPrimitiveosm : toDelete) {233 for (O osm : toDelete) { 229 234 typesToDelete.add(OsmPrimitiveType.from(osm)); 230 235 } 231 236 return typesToDelete; … … 234 239 @Override 235 240 public String getDescriptionText() { 236 241 if (toDelete.size() == 1) { 237 O smPrimitiveprimitive = toDelete.iterator().next();242 O primitive = toDelete.iterator().next(); 238 243 String msg; 239 244 switch(OsmPrimitiveType.from(primitive)) { 240 245 case NODE: msg = marktr("Delete node {0}"); break; … … 278 283 return null; 279 284 else { 280 285 List<PseudoCommand> children = new ArrayList<>(toDelete.size()); 281 for (final O smPrimitiveosm : toDelete) {286 for (final O osm : toDelete) { 282 287 children.add(new DeleteChildCommand(osm)); 283 288 } 284 289 return children; … … 286 291 } 287 292 } 288 293 289 @Override public Collection< ? extends OsmPrimitive> getParticipatingPrimitives() {294 @Override public Collection<O> getParticipatingPrimitives() { 290 295 return toDelete; 291 296 } 292 297 … … 303 308 * @throws IllegalArgumentException if layer is null 304 309 * @since 12718 305 310 */ 306 public static Command deleteWithReferences(Collection<? extends OsmPrimitive> selection, boolean silent) {311 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> deleteWithReferences(Collection<O> selection, boolean silent) { 307 312 if (selection == null || selection.isEmpty()) return null; 308 Set<O smPrimitive> parents = OsmPrimitive.getReferrer(selection);313 Set<O> parents = OsmPrimitive.getReferrer(selection); 309 314 parents.addAll(selection); 310 315 311 316 if (parents.isEmpty()) … … 312 317 return null; 313 318 if (!silent && !callback.checkAndConfirmOutlyingDelete(parents, null)) 314 319 return null; 315 return new DeleteCommand (parents.iterator().next().getDataSet(), parents);320 return new DeleteCommand<>(parents.iterator().next().getDataSet(), parents); 316 321 } 317 322 318 323 /** … … 327 332 * @throws IllegalArgumentException if layer is null 328 333 * @since 12718 329 334 */ 330 public static Command deleteWithReferences(Collection<? extends OsmPrimitive> selection) {335 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> deleteWithReferences(Collection<? extends O> selection) { 331 336 return deleteWithReferences(selection, false); 332 337 } 333 338 … … 344 349 * @return command a command to perform the deletions, or null if there is nothing to delete. 345 350 * @since 12718 346 351 */ 347 public static Command delete(Collection<? extends OsmPrimitive> selection) {352 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> delete(Collection<O> selection) { 348 353 return delete(selection, true, false); 349 354 } 350 355 … … 359 364 * @return the collection of nodes referred to by primitives in <code>primitivesToDelete</code> which 360 365 * can be deleted too 361 366 */ 362 protected static Collection< Node> computeNodesToDelete(Collection<OsmPrimitive> primitivesToDelete) {363 Collection< Node> nodesToDelete = new HashSet<>();364 for ( Way way : Utils.filteredCollection(primitivesToDelete,Way.class)) {365 for ( Node n : way.getNodes()) {367 protected static Collection<INode> computeNodesToDelete(Collection<IPrimitive> primitivesToDelete) { 368 Collection<INode> nodesToDelete = new HashSet<>(); 369 for (IWay<?> way : Utils.filteredCollection(primitivesToDelete, IWay.class)) { 370 for (INode n : way.getNodes()) { 366 371 if (n.isTagged()) { 367 372 continue; 368 373 } 369 Collection< OsmPrimitive> referringPrimitives = n.getReferrers();374 Collection<IPrimitive> referringPrimitives = new HashSet<>(n.getReferrers()); 370 375 referringPrimitives.removeAll(primitivesToDelete); 371 376 int count = 0; 372 for ( OsmPrimitive p : referringPrimitives) {377 for (IPrimitive p : referringPrimitives) { 373 378 if (!p.isDeleted()) { 374 379 count++; 375 380 } … … 396 401 * @return command a command to perform the deletions, or null if there is nothing to delete. 397 402 * @since 12718 398 403 */ 399 public static Command delete(Collection<? extends OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {404 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> delete(Collection<? extends O> selection, boolean alsoDeleteNodesInWay) { 400 405 return delete(selection, alsoDeleteNodesInWay, false /* not silent */); 401 406 } 402 407 … … 415 420 * @return command a command to perform the deletions, or null if there is nothing to delete. 416 421 * @since 12718 417 422 */ 418 public static Command delete(Collection<? extends OsmPrimitive> selection, boolean alsoDeleteNodesInWay, boolean silent) {423 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> delete(Collection<? extends O> selection, boolean alsoDeleteNodesInWay, boolean silent) { 419 424 if (selection == null || selection.isEmpty()) 420 425 return null; 421 426 422 Set< OsmPrimitive> primitivesToDelete = new HashSet<>(selection);427 Set<IPrimitive> primitivesToDelete = new HashSet<>(selection); 423 428 424 Collection<R elation> relationsToDelete = Utils.filteredCollection(primitivesToDelete, Relation.class);429 Collection<R> relationsToDelete = Utils.filteredCollection(primitivesToDelete, R); 425 430 if (!relationsToDelete.isEmpty() && !silent && !callback.confirmRelationDeletion(relationsToDelete)) 426 431 return null; 427 432 428 433 if (alsoDeleteNodesInWay) { 429 434 // delete untagged nodes only referenced by primitives in primitivesToDelete, too 430 Collection< Node> nodesToDelete = computeNodesToDelete(primitivesToDelete);435 Collection<INode> nodesToDelete = computeNodesToDelete(primitivesToDelete); 431 436 primitivesToDelete.addAll(nodesToDelete); 432 437 } 433 438 434 439 if (!silent && !callback.checkAndConfirmOutlyingDelete( 435 primitivesToDelete, Utils.filteredCollection(primitivesToDelete, Way.class)))440 primitivesToDelete, Utils.filteredCollection(primitivesToDelete, IWay.class))) 436 441 return null; 437 442 438 Collection< Way> waysToBeChanged = primitivesToDelete.stream()439 .flatMap(p -> p. referrers(Way.class))443 Collection<IWay<?>> waysToBeChanged = primitivesToDelete.stream() 444 .flatMap(p -> p.getReferrers().stream().filter(IWay.class::isInstance).map(IWay.class::cast)) 440 445 .collect(Collectors.toSet()); 441 446 442 447 Collection<Command> cmds = new LinkedList<>(); 443 Set< Node> nodesToRemove = new HashSet<>(Utils.filteredCollection(primitivesToDelete,Node.class));444 for ( Wayw : waysToBeChanged) {445 Way wnew = new Way(w);448 Set<INode> nodesToRemove = new HashSet<>(Utils.filteredCollection(primitivesToDelete, INode.class)); 449 for (IWay<?> w : waysToBeChanged) { 450 IWay<?> wnew = Utils.clone(w); 446 451 wnew.removeNodes(nodesToRemove); 447 452 if (wnew.getNodesCount() < 2) { 448 453 primitivesToDelete.add(w); … … 463 468 464 469 // remove the objects from their parent relations 465 470 // 466 final Set< Relation> relationsToBeChanged = primitivesToDelete.stream()467 .flatMap(p -> p. referrers(Relation.class))471 final Set<IRelation<?>> relationsToBeChanged = primitivesToDelete.stream() 472 .flatMap(p -> p.getReferrers().stream().filter(IRelation.class::isInstance).map(IRelation.class::cast)) 468 473 .collect(Collectors.toSet()); 469 for ( Relationcur : relationsToBeChanged) {470 Relation rel = new Relation(cur);474 for (IRelation<?> cur : relationsToBeChanged) { 475 IRelation<?> rel = Utils.clone(cur); 471 476 rel.removeMembersFor(primitivesToDelete); 472 477 cmds.add(new ChangeCommand(cur, rel)); 473 478 } … … 475 480 // build the delete command 476 481 // 477 482 if (!primitivesToDelete.isEmpty()) { 478 cmds.add(new DeleteCommand (primitivesToDelete.iterator().next().getDataSet(), primitivesToDelete));483 cmds.add(new DeleteCommand<>(primitivesToDelete.iterator().next().getDataSet(), primitivesToDelete)); 479 484 } 480 485 481 return newSequenceCommand(tr("Delete"), cmds);486 return SequenceCommand.createSimplifiedSequenceCommand(tr("Delete"), cmds); 482 487 } 483 488 484 489 /** … … 487 492 * @return A matching command to safely delete that segment. 488 493 * @since 12718 489 494 */ 490 public static Command deleteWaySegment(WaySegmentws) {495 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> deleteWaySegment(WaySegment<N, W> ws) { 491 496 if (ws.way.getNodesCount() < 3) 492 497 return delete(Collections.singleton(ws.way), false); 493 498 … … 494 499 if (ws.way.isClosed()) { 495 500 // If the way is circular (first and last nodes are the same), the way shouldn't be splitted 496 501 497 List<N ode> n = new ArrayList<>();502 List<N> n = new ArrayList<>(); 498 503 499 504 n.addAll(ws.way.getNodes().subList(ws.lowerIndex + 1, ws.way.getNodesCount() - 1)); 500 505 n.addAll(ws.way.getNodes().subList(0, ws.lowerIndex + 1)); 501 506 502 W ay wnew = new Way(ws.way);507 W wnew = Utils.clone(ws.way); 503 508 wnew.setNodes(n); 504 509 505 510 return new ChangeCommand(ws.way, wnew); 506 511 } 507 512 508 List<N ode> n1 = new ArrayList<>();509 List<N ode> n2 = new ArrayList<>();513 List<N> n1 = new ArrayList<>(); 514 List<N> n2 = new ArrayList<>(); 510 515 511 516 n1.addAll(ws.way.getNodes().subList(0, ws.lowerIndex + 1)); 512 517 n2.addAll(ws.way.getNodes().subList(ws.lowerIndex + 1, ws.way.getNodesCount())); 513 518 514 W ay wnew = new Way(ws.way);519 W wnew = Utils.clone(ws.way); 515 520 516 521 if (n1.size() < 2) { 517 522 wnew.setNodes(n2); -
src/org/openstreetmap/josm/command/MoveCommand.java
10 10 import java.util.List; 11 11 import java.util.NoSuchElementException; 12 12 import java.util.Objects; 13 import java.util.stream.Collectors; 13 14 14 15 import javax.swing.Icon; 15 16 16 17 import org.openstreetmap.josm.data.coor.EastNorth; 17 18 import org.openstreetmap.josm.data.coor.LatLon; 18 import org.openstreetmap.josm.data.osm.DataSet; 19 import org.openstreetmap.josm.data.osm.Node; 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.INode; 20 import org.openstreetmap.josm.data.osm.IPrimitive; 21 import org.openstreetmap.josm.data.osm.IRelation; 22 import org.openstreetmap.josm.data.osm.IWay; 23 import org.openstreetmap.josm.data.osm.OsmData; 21 24 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 22 25 import org.openstreetmap.josm.data.projection.ProjectionRegistry; 23 26 import org.openstreetmap.josm.tools.ImageProvider; … … 27 30 * to collect several MoveCommands into one command. 28 31 * 29 32 * @author imi 33 * @param <O> the base type of primitives 34 * @param <N> type representing nodes 35 * @param <W> type representing ways 36 * @param <R> type representing relations 30 37 */ 31 public class MoveCommand extends Command{38 public class MoveCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 32 39 /** 33 40 * The objects that should be moved. 34 41 */ 35 private Collection<N ode> nodes = new LinkedList<>();42 private Collection<N> nodes = new LinkedList<>(); 36 43 /** 37 44 * Starting position, base command point, current (mouse-drag) position = startEN + (x,y) = 38 45 */ … … 61 68 * @param x X difference movement. Coordinates are in northern/eastern 62 69 * @param y Y difference movement. Coordinates are in northern/eastern 63 70 */ 64 public MoveCommand(O smPrimitiveosm, double x, double y) {71 public MoveCommand(O osm, double x, double y) { 65 72 this(Collections.singleton(osm), x, y); 66 73 } 67 74 … … 70 77 * @param node The node to move 71 78 * @param position The new location (lat/lon) 72 79 */ 73 public MoveCommand(N odenode, LatLon position) {74 this(Collections.singleton((O smPrimitive) node),80 public MoveCommand(N node, LatLon position) { 81 this(Collections.singleton((O) node), 75 82 ProjectionRegistry.getProjection().latlon2eastNorth(position).subtract(node.getEastNorth())); 76 83 } 77 84 … … 80 87 * @param objects The primitives to move 81 88 * @param offset The movement vector 82 89 */ 83 public MoveCommand(Collection<O smPrimitive> objects, EastNorth offset) {90 public MoveCommand(Collection<O> objects, EastNorth offset) { 84 91 this(objects, offset.getX(), offset.getY()); 85 92 } 86 93 … … 92 99 * @throws NullPointerException if objects is null or contain null item 93 100 * @throws NoSuchElementException if objects is empty 94 101 */ 95 public MoveCommand(Collection<O smPrimitive> objects, double x, double y) {102 public MoveCommand(Collection<O> objects, double x, double y) { 96 103 this(objects.iterator().next().getDataSet(), objects, x, y); 97 104 } 98 105 … … 106 113 * @throws NoSuchElementException if objects is empty 107 114 * @since 12759 108 115 */ 109 public MoveCommand( DataSet ds, Collection<OsmPrimitive> objects, double x, double y) {116 public MoveCommand(OsmData<O, N, W, R> ds, Collection<O> objects, double x, double y) { 110 117 super(ds); 111 118 startEN = null; 112 119 saveCheckpoint(); // (0,0) displacement will be saved … … 114 121 this.y = y; 115 122 Objects.requireNonNull(objects, "objects"); 116 123 this.nodes = AllNodesVisitor.getAllNodes(objects); 117 for ( Node n : this.nodes) {124 for (INode n : this.nodes) { 118 125 oldState.add(new OldNodeState(n)); 119 126 } 120 127 } … … 127 134 * @param end The ending position (northern/eastern) 128 135 * @since 12759 129 136 */ 130 public MoveCommand( DataSet ds, Collection<OsmPrimitive> objects, EastNorth start, EastNorth end) {137 public MoveCommand(OsmData<O, N, W, R> ds, Collection<O> objects, EastNorth start, EastNorth end) { 131 138 this(Objects.requireNonNull(ds, "ds"), 132 139 Objects.requireNonNull(objects, "objects"), 133 140 Objects.requireNonNull(end, "end").getX() - Objects.requireNonNull(start, "start").getX(), … … 141 148 * @param start The starting position (northern/eastern) 142 149 * @param end The ending position (northern/eastern) 143 150 */ 144 public MoveCommand(Collection<O smPrimitive> objects, EastNorth start, EastNorth end) {151 public MoveCommand(Collection<O> objects, EastNorth start, EastNorth end) { 145 152 this(Objects.requireNonNull(objects, "objects").iterator().next().getDataSet(), objects, start, end); 146 153 } 147 154 … … 153 160 * @param end The ending position (northern/eastern) 154 161 * @since 12759 155 162 */ 156 public MoveCommand( DataSet ds, OsmPrimitivep, EastNorth start, EastNorth end) {163 public MoveCommand(OsmData<O, N, W, R> ds, O p, EastNorth start, EastNorth end) { 157 164 this(ds, Collections.singleton(Objects.requireNonNull(p, "p")), start, end); 158 165 } 159 166 … … 163 170 * @param start The starting position (northern/eastern) 164 171 * @param end The ending position (northern/eastern) 165 172 */ 166 public MoveCommand(O smPrimitivep, EastNorth start, EastNorth end) {173 public MoveCommand(O p, EastNorth start, EastNorth end) { 167 174 this(Collections.singleton(Objects.requireNonNull(p, "p")), start, end); 168 175 } 169 176 … … 179 186 * @param y Y difference movement. Coordinates are in northern/eastern 180 187 */ 181 188 public void moveAgain(double x, double y) { 182 for ( Node n : nodes) {189 for (INode n : nodes) { 183 190 EastNorth eastNorth = n.getEastNorth(); 184 191 if (eastNorth != null) { 185 192 n.setEastNorth(eastNorth.add(x, y)); … … 239 246 240 247 private void updateCoordinates() { 241 248 Iterator<OldNodeState> it = oldState.iterator(); 242 for ( Node n : nodes) {249 for (INode n : nodes) { 243 250 OldNodeState os = it.next(); 244 251 if (os.getEastNorth() != null) { 245 252 n.setEastNorth(os.getEastNorth().add(x, y)); … … 251 258 public boolean executeCommand() { 252 259 ensurePrimitivesAreInDataset(); 253 260 254 for ( Node n : nodes) {261 for (INode n : nodes) { 255 262 // in case #3892 happens again 256 263 if (n == null) 257 264 throw new AssertionError("null detected in node list"); … … 269 276 ensurePrimitivesAreInDataset(); 270 277 271 278 Iterator<OldNodeState> it = oldState.iterator(); 272 for ( Node n : nodes) {279 for (INode n : nodes) { 273 280 OldNodeState os = it.next(); 274 281 n.setCoor(os.getLatLon()); 275 282 n.setModified(os.isModified()); … … 277 284 } 278 285 279 286 @Override 280 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {281 for ( OsmPrimitiveosm : nodes) {282 modified.add( osm);287 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 288 for (N osm : nodes) { 289 modified.add((O) osm); 283 290 } 284 291 } 285 292 … … 294 301 } 295 302 296 303 @Override 297 public Collection< Node> getParticipatingPrimitives() {298 return nodes ;304 public Collection<? extends O> getParticipatingPrimitives() { 305 return nodes.stream().map(n -> (O) n).collect(Collectors.toList()); 299 306 } 300 307 301 308 /** -
src/org/openstreetmap/josm/command/PseudoCommand.java
5 5 6 6 import javax.swing.Icon; 7 7 8 import org.openstreetmap.josm.data.osm. OsmPrimitive;8 import org.openstreetmap.josm.data.osm.IPrimitive; 9 9 10 10 /** 11 11 * PseudoCommand is a reduced form of a command. It can be presented in a tree view … … 34 34 * Return the primitives that take part in this command. 35 35 * @return primitives that take part in this command 36 36 */ 37 Collection<? extends OsmPrimitive> getParticipatingPrimitives();37 Collection<? extends IPrimitive> getParticipatingPrimitives(); 38 38 39 39 /** 40 40 * Returns the subcommands of this command. -
src/org/openstreetmap/josm/command/PurgeCommand.java
5 5 6 6 import java.util.ArrayList; 7 7 import java.util.Collection; 8 import java.util.Collections; 8 9 import java.util.HashMap; 9 10 import java.util.HashSet; 10 11 import java.util.Iterator; … … 17 18 18 19 import org.openstreetmap.josm.data.conflict.Conflict; 19 20 import org.openstreetmap.josm.data.conflict.ConflictCollection; 20 import org.openstreetmap.josm.data.osm.DataSet; 21 import org.openstreetmap.josm.data.osm.INode; 22 import org.openstreetmap.josm.data.osm.IPrimitive; 23 import org.openstreetmap.josm.data.osm.IRelation; 24 import org.openstreetmap.josm.data.osm.IWay; 21 25 import org.openstreetmap.josm.data.osm.Node; 22 26 import org.openstreetmap.josm.data.osm.NodeData; 27 import org.openstreetmap.josm.data.osm.OsmData; 23 28 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 29 import org.openstreetmap.josm.data.osm.PrimitiveData; 25 30 import org.openstreetmap.josm.data.osm.PrimitiveId; … … 34 39 35 40 /** 36 41 * Command, to purge a list of primitives. 42 * @param <O> the base type of primitives 43 * @param <N> type representing nodes 44 * @param <W> type representing ways 45 * @param <R> type representing relations 37 46 */ 38 public class PurgeCommand extends Command{39 protected List<O smPrimitive> toPurge;47 public class PurgeCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 48 protected List<O> toPurge; 40 49 protected Storage<PrimitiveData> makeIncompleteData; 41 50 42 51 protected Map<PrimitiveId, PrimitiveData> makeIncompleteDataByPrimId; … … 54 63 * @param makeIncomplete primitives to make incomplete 55 64 * @since 11240 56 65 */ 57 public PurgeCommand( DataSet data, Collection<OsmPrimitive> toPurge, Collection<OsmPrimitive> makeIncomplete) {66 public PurgeCommand(OsmData<O, N, W, R> data, Collection<O> toPurge, Collection<O> makeIncomplete) { 58 67 super(data); 59 68 init(toPurge, makeIncomplete); 60 69 } 61 70 62 private void init(Collection<O smPrimitive> toPurge, Collection<OsmPrimitive> makeIncomplete) {71 private void init(Collection<O> toPurge, Collection<O> makeIncomplete) { 63 72 /** 64 73 * The topological sort is to avoid missing way nodes and missing 65 74 * relation members when adding primitives back to the dataset on undo. … … 72 81 saveIncomplete(makeIncomplete); 73 82 } 74 83 75 protected final void saveIncomplete(Collection<O smPrimitive> makeIncomplete) {84 protected final void saveIncomplete(Collection<O> makeIncomplete) { 76 85 makeIncompleteData = new Storage<>(new Storage.PrimitiveIdHash()); 77 86 makeIncompleteDataByPrimId = makeIncompleteData.foreignKey(new Storage.PrimitiveIdHash()); 78 87 79 for (O smPrimitiveosm : makeIncomplete) {88 for (O osm : makeIncomplete) { 80 89 makeIncompleteData.add(osm.save()); 81 90 } 82 91 } … … 89 98 getAffectedDataSet().clearSelection(toPurge); 90 99 // Loop from back to front to keep referential integrity. 91 100 for (int i = toPurge.size()-1; i >= 0; --i) { 92 O smPrimitiveosm = toPurge.get(i);101 O osm = toPurge.get(i); 93 102 if (makeIncompleteDataByPrimId.containsKey(osm)) { 94 103 // we could simply set the incomplete flag 95 104 // but that would not free memory in case the … … 124 133 return; 125 134 126 135 getAffectedDataSet().update(() -> { 127 for (O smPrimitiveosm : toPurge) {136 for (O osm : toPurge) { 128 137 PrimitiveData data = makeIncompleteDataByPrimId.get(osm); 129 138 if (data != null) { 130 139 if (getAffectedDataSet().getPrimitiveById(osm) != osm) … … 151 160 * @param sel collection of primitives to sort 152 161 * @return sorted list 153 162 */ 154 public static List<OsmPrimitive> topoSort(Collection<OsmPrimitive> sel) { 155 Set<OsmPrimitive> in = new HashSet<>(sel); 156 List<OsmPrimitive> out = new ArrayList<>(in.size()); 157 Set<Relation> inR = new HashSet<>(); 163 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> List<O> topoSort(Collection<O> sel) { 164 if (sel == null || sel.isEmpty()) return Collections.emptyList(); 165 OsmData<O, N, W, R> data = sel.iterator().next().getDataSet(); 166 Set<O> in = new HashSet<>(sel); 167 List<O> out = new ArrayList<>(in.size()); 168 Set<R> inR = new HashSet<>(); 158 169 159 170 // Nodes not deleted in the first pass 160 Set<O smPrimitive> remainingNodes = new HashSet<>(in.size());171 Set<O> remainingNodes = new HashSet<>(in.size()); 161 172 162 173 /** 163 174 * First add nodes that have no way referrer. 164 175 */ 165 176 outer: 166 for (Iterator<O smPrimitive> it = in.iterator(); it.hasNext();) {167 O smPrimitiveu = it.next();168 if (u instanceof Node) {169 N ode n = (Node) u;170 for ( OsmPrimitive ref : n.getReferrers()) {171 if (ref instanceof Way && in.contains(ref)) {177 for (Iterator<O> it = in.iterator(); it.hasNext();) { 178 O u = it.next(); 179 if (u instanceof INode) { 180 N n = (N) u; 181 for (IPrimitive ref : n.getReferrers()) { 182 if (ref instanceof IWay && in.contains(ref)) { 172 183 it.remove(); 173 remainingNodes.add( n);184 remainingNodes.add((O) n); 174 185 continue outer; 175 186 } 176 187 } 177 188 it.remove(); 178 out.add( n);189 out.add((O) n); 179 190 } 180 191 } 181 192 … … 182 193 /** 183 194 * Then add all ways, each preceded by its (remaining) nodes. 184 195 */ 185 for (Iterator<O smPrimitive> it = in.iterator(); it.hasNext();) {186 O smPrimitiveu = it.next();187 if (u instanceof Way) {188 W ay w = (Way) u;196 for (Iterator<O> it = in.iterator(); it.hasNext();) { 197 O u = it.next(); 198 if (u instanceof IWay) { 199 W w = (W) u; 189 200 it.remove(); 190 for (N oden : w.getNodes()) {201 for (N n : w.getNodes()) { 191 202 if (remainingNodes.contains(n)) { 192 203 remainingNodes.remove(n); 193 out.add( n);204 out.add((O) n); 194 205 } 195 206 } 196 out.add( w);207 out.add((O) w); 197 208 } else if (u instanceof Relation) { 198 inR.add((R elation) u);209 inR.add((R) u); 199 210 } 200 211 } 201 212 … … 205 216 // Do topological sorting on a DAG where each arrow points from child to parent. 206 217 // (Because it is faster to loop over getReferrers() than getMembers().) 207 218 208 Map<R elation, Integer> numChilds = new HashMap<>();219 Map<R, Integer> numChilds = new HashMap<>(); 209 220 210 221 // calculate initial number of childs 211 for (R elationr : inR) {222 for (R r : inR) { 212 223 numChilds.put(r, 0); 213 224 } 214 for (R elationr : inR) {215 for ( OsmPrimitive parent : r.getReferrers()) {216 if (!(parent instanceof Relation))225 for (R r : inR) { 226 for (IPrimitive parent : r.getReferrers()) { 227 if (!(parent instanceof IRelation)) 217 228 throw new AssertionError(); 218 229 Integer i = numChilds.get(parent); 219 230 if (i != null) { 220 numChilds.put((R elation) parent, i+1);231 numChilds.put((R) parent, i+1); 221 232 } 222 233 } 223 234 } 224 Set<R elation> childlessR = new HashSet<>();225 for (R elationr : inR) {235 Set<R> childlessR = new HashSet<>(); 236 for (R r : inR) { 226 237 if (numChilds.get(r).equals(0)) { 227 238 childlessR.add(r); 228 239 } 229 240 } 230 241 231 List<R elation> outR = new ArrayList<>(inR.size());242 List<R> outR = new ArrayList<>(inR.size()); 232 243 while (!childlessR.isEmpty()) { 233 244 // Identify one childless Relation and let it virtually die. This makes other relations childless. 234 Iterator<R elation> it = childlessR.iterator();235 R elationnext = it.next();245 Iterator<R> it = childlessR.iterator(); 246 R next = it.next(); 236 247 it.remove(); 237 248 outR.add(next); 238 249 239 for ( OsmPrimitive parentPrim : next.getReferrers()) {240 R elation parent = (Relation) parentPrim;250 for (IPrimitive parentPrim : next.getReferrers()) { 251 R parent = (R) parentPrim; 241 252 Integer i = numChilds.get(parent); 242 253 if (i != null) { 243 254 numChilds.put(parent, i-1); … … 251 262 if (outR.size() != inR.size()) 252 263 throw new AssertionError("topo sort algorithm failed"); 253 264 254 out .addAll(outR);265 outR.forEach(r -> out.add((O) r)); 255 266 256 267 return out; 257 268 } … … 267 278 } 268 279 269 280 @Override 270 public Collection< ? extends OsmPrimitive> getParticipatingPrimitives() {281 public Collection<O> getParticipatingPrimitives() { 271 282 return toPurge; 272 283 } 273 284 274 285 @Override 275 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {286 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 276 287 // Do nothing 277 288 } 278 289 … … 286 297 if (this == obj) return true; 287 298 if (obj == null || getClass() != obj.getClass()) return false; 288 299 if (!super.equals(obj)) return false; 289 PurgeCommand that = (PurgeCommand) obj;300 PurgeCommand<?, ?, ?, ?> that = (PurgeCommand<?, ?, ?, ?>) obj; 290 301 return Objects.equals(toPurge, that.toPurge) && 291 302 Objects.equals(makeIncompleteData, that.makeIncompleteData) && 292 303 Objects.equals(makeIncompleteDataByPrimId, that.makeIncompleteDataByPrimId) && -
src/org/openstreetmap/josm/command/RemoveNodesCommand.java
8 8 import org.openstreetmap.josm.data.osm.DataSet; 9 9 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 10 10 import org.openstreetmap.josm.data.osm.Node; 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 12 import org.openstreetmap.josm.data.osm.Relation; 11 13 import org.openstreetmap.josm.data.osm.Way; 12 14 13 15 /** … … 17 19 * 18 20 * @author Giuseppe Bilotta 19 21 */ 20 public class RemoveNodesCommand extends AbstractNodesCommand< Set<Node>> {22 public class RemoveNodesCommand extends AbstractNodesCommand<OsmPrimitive, Node, Way, Relation, Set<Node>> { 21 23 22 24 /** 23 25 * Constructs a new {@code RemoveNodesCommand}. -
src/org/openstreetmap/josm/command/RotateCommand.java
7 7 import java.util.Objects; 8 8 9 9 import org.openstreetmap.josm.data.coor.EastNorth; 10 import org.openstreetmap.josm.data.osm. Node;10 import org.openstreetmap.josm.data.osm.INode; 11 11 import org.openstreetmap.josm.data.osm.OsmPrimitive; 12 12 13 13 /** … … 84 84 protected void transformNodes() { 85 85 double cosPhi = Math.cos(rotationAngle); 86 86 double sinPhi = Math.sin(rotationAngle); 87 for ( Node n : nodes) {87 for (INode n : nodes) { 88 88 EastNorth oldEastNorth = oldStates.get(n).getEastNorth(); 89 89 double x = oldEastNorth.east() - pivot.east(); 90 90 double y = oldEastNorth.north() - pivot.north(); -
src/org/openstreetmap/josm/command/SelectCommand.java
9 9 import java.util.Objects; 10 10 11 11 import org.openstreetmap.josm.data.osm.DataSet; 12 import org.openstreetmap.josm.data.osm.Node; 12 13 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 import org.openstreetmap.josm.data.osm.Relation; 15 import org.openstreetmap.josm.data.osm.Way; 13 16 14 17 /** 15 18 * Command that selects OSM primitives … … 16 19 * 17 20 * @author Landwirt 18 21 */ 19 public class SelectCommand extends Command {22 public class SelectCommand extends Command<OsmPrimitive, Node, Way, Relation> { 20 23 21 24 /** the primitives to select when executing the command */ 22 25 private final Collection<OsmPrimitive> newSelection; -
src/org/openstreetmap/josm/command/SequenceCommand.java
10 10 11 11 import javax.swing.Icon; 12 12 13 import org.openstreetmap.josm.data.osm.DataSet; 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 13 import org.openstreetmap.josm.data.osm.INode; 14 import org.openstreetmap.josm.data.osm.IPrimitive; 15 import org.openstreetmap.josm.data.osm.IRelation; 16 import org.openstreetmap.josm.data.osm.IWay; 17 import org.openstreetmap.josm.data.osm.OsmData; 15 18 import org.openstreetmap.josm.tools.ImageProvider; 16 19 import org.openstreetmap.josm.tools.Utils; 17 20 … … 19 22 * A command consisting of a sequence of other commands. Executes the other commands 20 23 * and undo them in reverse order. 21 24 * @author imi 25 * @param <O> the base type of primitives 26 * @param <N> type representing nodes 27 * @param <W> type representing ways 28 * @param <R> type representing relations 22 29 * @since 31 23 30 */ 24 public class SequenceCommand extends Command{31 public class SequenceCommand<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends Command<O, N, W, R> { 25 32 26 33 /** The command sequence to be executed. */ 27 private Command [] sequence;34 private Command<O, N, W, R>[] sequence; 28 35 private boolean sequenceComplete; 29 36 private final String name; 30 37 /** Determines if the sequence execution should continue after one of its commands fails. */ … … 38 45 * @param continueOnError Determines if the sequence execution should continue after one of its commands fails 39 46 * @since 12726 40 47 */ 41 public SequenceCommand( DataSet ds, String name, Collection<Command> sequenz, boolean continueOnError) {48 public SequenceCommand(OsmData<O, N, W, R> ds, String name, Collection<Command<O, N, W, R>> sequenz, boolean continueOnError) { 42 49 super(ds); 43 50 this.name = name; 44 51 this.sequence = sequenz.toArray(new Command[0]); … … 52 59 * @param continueOnError Determines if the sequence execution should continue after one of its commands fails 53 60 * @since 11874 54 61 */ 55 public SequenceCommand(String name, Collection<Command > sequenz, boolean continueOnError) {62 public SequenceCommand(String name, Collection<Command<O, N, W, R>> sequenz, boolean continueOnError) { 56 63 this(sequenz.iterator().next().getAffectedDataSet(), name, sequenz, continueOnError); 57 64 } 58 65 … … 61 68 * @param name The description text 62 69 * @param sequenz The sequence that should be executed. 63 70 */ 64 public SequenceCommand(String name, Collection<Command > sequenz) {71 public SequenceCommand(String name, Collection<Command<O, N, W, R>> sequenz) { 65 72 this(name, sequenz, false); 66 73 } 67 74 … … 70 77 * @param name The description text 71 78 * @param sequenz The sequence that should be executed. 72 79 */ 73 public SequenceCommand(String name, Command ... sequenz) {80 public SequenceCommand(String name, Command<O, N, W, R>... sequenz) { 74 81 this(name, Arrays.asList(sequenz)); 75 82 } 76 83 84 /** 85 * Convenient constructor, if the commands are known at compile time. 86 * @param name The description text to be used for the sequence command, if one is created. 87 * @param sequenz The sequence that should be executed. 88 * @param <O> the base type of primitives 89 * @param <N> type representing nodes 90 * @param <W> type representing ways 91 * @param <R> type representing relations 92 * @return Either a SequenceCommand, or the only command in the potential sequence 93 * @since xxx 94 */ 95 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> createSimplifiedSequenceCommand(String name, Command<O, N, W, R>... sequenz) { 96 if (sequenz.length == 1) { 97 return sequenz[0]; 98 } 99 return new SequenceCommand<>(name, sequenz); 100 } 101 102 /** 103 * Convenient constructor, if the commands are known at compile time. 104 * @param name The description text to be used for the sequence command, if one is created. 105 * @param sequenz The sequence that should be executed. 106 * @param <O> the base type of primitives 107 * @param <N> type representing nodes 108 * @param <W> type representing ways 109 * @param <R> type representing relations 110 * @return Either a SequenceCommand, or the only command in the potential sequence 111 * @since xxx 112 */ 113 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Command<O, N, W, R> createSimplifiedSequenceCommand(String name, Collection<Command<O, N, W, R>> sequenz) { 114 if (sequenz.size() == 1) { 115 return sequenz.iterator().next(); 116 } 117 return new SequenceCommand<>(name, sequenz); 118 } 119 77 120 @Override public boolean executeCommand() { 78 121 for (int i = 0; i < sequence.length; i++) { 79 122 boolean result = sequence[i].executeCommand(); … … 90 133 * Returns the last command. 91 134 * @return The last command, or {@code null} if the sequence is empty. 92 135 */ 93 public Command getLastCommand() {136 public Command<O, N, W, R> getLastCommand() { 94 137 if (sequence.length == 0) 95 138 return null; 96 139 return sequence[sequence.length-1]; … … 112 155 } 113 156 114 157 @Override 115 public void fillModifiedData(Collection<O smPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {116 for (Command c : sequence) {158 public void fillModifiedData(Collection<O> modified, Collection<O> deleted, Collection<O> added) { 159 for (Command<O, N, W, R> c : sequence) { 117 160 c.fillModifiedData(modified, deleted, added); 118 161 } 119 162 } … … 143 186 } 144 187 145 188 @Override 146 public Collection< ? extends OsmPrimitive> getParticipatingPrimitives() {147 Collection<O smPrimitive> prims = new HashSet<>();148 for (Command c : sequence) {189 public Collection<O> getParticipatingPrimitives() { 190 Collection<O> prims = new HashSet<>(); 191 for (Command<O, N, W, R> c : sequence) { 149 192 prims.addAll(c.getParticipatingPrimitives()); 150 193 } 151 194 return prims; 152 195 } 153 196 154 protected final void setSequence(Command ... sequence) {197 protected final void setSequence(Command<O, N, W, R>... sequence) { 155 198 this.sequence = Utils.copyArray(sequence); 156 199 } 157 200 … … 169 212 if (this == obj) return true; 170 213 if (obj == null || getClass() != obj.getClass()) return false; 171 214 if (!super.equals(obj)) return false; 172 SequenceCommand that = (SequenceCommand) obj;215 SequenceCommand<?, ?, ?, ?> that = (SequenceCommand<?, ?, ?, ?>) obj; 173 216 return sequenceComplete == that.sequenceComplete && 174 217 continueOnError == that.continueOnError && 175 218 Arrays.equals(sequence, that.sequence) && -
src/org/openstreetmap/josm/command/TransformNodesCommand.java
8 8 import java.util.Map; 9 9 import java.util.NoSuchElementException; 10 10 import java.util.Objects; 11 import java.util.stream.Collectors; 11 12 12 13 import javax.swing.Icon; 13 14 14 15 import org.openstreetmap.josm.data.coor.EastNorth; 16 import org.openstreetmap.josm.data.osm.INode; 15 17 import org.openstreetmap.josm.data.osm.Node; 16 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Relation; 20 import org.openstreetmap.josm.data.osm.Way; 17 21 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 18 22 import org.openstreetmap.josm.tools.ImageProvider; 19 23 … … 22 26 * 23 27 * @author Olivier Croquette <ocroquette@free.fr> 24 28 */ 25 public abstract class TransformNodesCommand extends Command {29 public abstract class TransformNodesCommand extends Command<OsmPrimitive, Node, Way, Relation> { 26 30 27 31 /** 28 32 * The nodes to transform. 29 33 */ 30 protected final Collection< Node> nodes;34 protected final Collection<INode> nodes; 31 35 32 36 /** 33 37 * List of all old states of the nodes. 34 38 */ 35 protected final Map< Node, OldNodeState> oldStates = new HashMap<>();39 protected final Map<INode, OldNodeState> oldStates = new HashMap<>(); 36 40 37 41 /** 38 42 * Stores the state of the nodes before the command. 39 43 */ 40 44 protected final void storeOldState() { 41 for ( Node n : this.nodes) {45 for (INode n : this.nodes) { 42 46 oldStates.put(n, new OldNodeState(n)); 43 47 } 44 48 } … … 85 89 * Flag all nodes as modified. 86 90 */ 87 91 public void flagNodesAsModified() { 88 for ( Node n : nodes) {92 for (INode n : nodes) { 89 93 n.setModified(true); 90 94 } 91 95 } … … 95 99 */ 96 100 @Override 97 101 public void undoCommand() { 98 for ( Node n : nodes) {102 for (INode n : nodes) { 99 103 OldNodeState os = oldStates.get(n); 100 104 n.setCoor(os.getLatLon()); 101 105 n.setModified(os.isModified()); … … 108 112 109 113 @Override 110 114 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 111 return nodes;115 return getTransformedNodes(); 112 116 } 113 117 114 118 @Override … … 126 130 * @return nodes with the current transformation applied 127 131 */ 128 132 public Collection<Node> getTransformedNodes() { 129 return nodes ;133 return nodes.stream().filter(Node.class::isInstance).map(Node.class::cast).collect(Collectors.toList()); 130 134 } 131 135 132 136 /** … … 138 142 public EastNorth getNodesCenter() { 139 143 EastNorth sum = new EastNorth(0, 0); 140 144 141 for ( Node n : nodes) {145 for (INode n : nodes) { 142 146 EastNorth en = n.getEastNorth(); 143 147 sum = sum.add(en.east(), en.north()); 144 148 } -
src/org/openstreetmap/josm/command/conflict/ConflictAddCommand.java
13 13 import org.openstreetmap.josm.data.conflict.Conflict; 14 14 import org.openstreetmap.josm.data.osm.DataSet; 15 15 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 16 import org.openstreetmap.josm.data.osm.Node; 16 17 import org.openstreetmap.josm.data.osm.OsmDataManager; 17 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Relation; 20 import org.openstreetmap.josm.data.osm.Way; 18 21 import org.openstreetmap.josm.gui.MainApplication; 19 22 import org.openstreetmap.josm.tools.ImageProvider; 20 23 import org.openstreetmap.josm.tools.Logging; … … 24 27 * Command used to add a new conflict. 25 28 * @since 1857 26 29 */ 27 public class ConflictAddCommand extends Command {30 public class ConflictAddCommand extends Command<OsmPrimitive, Node, Way, Relation> { 28 31 private final Conflict<? extends OsmPrimitive> conflict; 29 32 30 33 /** … … 55 58 @Override 56 59 public boolean executeCommand() { 57 60 try { 58 getAffectedDataSet().getConflicts().add(conflict);61 ((DataSet) getAffectedDataSet()).getConflicts().add(conflict); 59 62 } catch (IllegalStateException e) { 60 63 Logging.error(e); 61 64 warnBecauseOfDoubleConflict(); … … 65 68 66 69 @Override 67 70 public void undoCommand() { 68 DataSet ds = getAffectedDataSet();71 DataSet ds = (DataSet) getAffectedDataSet(); 69 72 if (!OsmDataManager.getInstance().containsDataSet(ds)) { 70 73 Logging.warn(tr("Layer ''{0}'' does not exist any more. Cannot remove conflict for object ''{1}''.", 71 74 ds.getName(), -
src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java
9 9 import org.openstreetmap.josm.data.conflict.Conflict; 10 10 import org.openstreetmap.josm.data.conflict.ConflictCollection; 11 11 import org.openstreetmap.josm.data.osm.DataSet; 12 import org.openstreetmap.josm.data.osm.Node; 12 13 import org.openstreetmap.josm.data.osm.OsmDataManager; 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 15 import org.openstreetmap.josm.data.osm.Relation; 16 import org.openstreetmap.josm.data.osm.Way; 13 17 import org.openstreetmap.josm.tools.Logging; 14 18 15 19 /** … … 20 24 * it reconstitutes them. 21 25 * 22 26 */ 23 public abstract class ConflictResolveCommand extends Command {27 public abstract class ConflictResolveCommand extends Command<OsmPrimitive, Node, Way, Relation> { 24 28 /** the list of resolved conflicts */ 25 29 private final ConflictCollection resolvedConflicts = new ConflictCollection(); 26 30 … … 49 53 * 50 54 */ 51 55 protected void reconstituteConflicts() { 52 DataSet ds = getAffectedDataSet();56 DataSet ds = (DataSet) getAffectedDataSet(); 53 57 for (Conflict<?> c : resolvedConflicts) { 54 58 if (!ds.getConflicts().hasConflictForMy(c.getMy())) { 55 59 ds.getConflicts().add(c); … … 61 65 public void undoCommand() { 62 66 super.undoCommand(); 63 67 64 DataSet ds = getAffectedDataSet();68 DataSet ds = (DataSet) getAffectedDataSet(); 65 69 if (!OsmDataManager.getInstance().containsDataSet(ds)) { 66 70 Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more", 67 71 this.toString(), -
src/org/openstreetmap/josm/data/osm/DataSet.java
128 128 private final CopyOnWriteArrayList<DataSetListener> listeners = new CopyOnWriteArrayList<>(); 129 129 130 130 // provide means to highlight map elements that are not osm primitives 131 private Collection<WaySegment > highlightedVirtualNodes = new LinkedList<>();132 private Collection<WaySegment > highlightedWaySegments = new LinkedList<>();131 private Collection<WaySegment<Node, Way>> highlightedVirtualNodes = new LinkedList<>(); 132 private Collection<WaySegment<Node, Way>> highlightedWaySegments = new LinkedList<>(); 133 133 private final ListenerList<HighlightUpdateListener> highlightUpdateListeners = ListenerList.create(); 134 134 135 135 // Number of open calls to beginUpdate … … 539 539 primitive.setDataset(null); 540 540 } 541 541 542 void removePrimitive(OsmPrimitive primitive) { 542 @Override 543 public void removePrimitive(OsmPrimitive primitive) { 543 544 checkModifiable(); 544 545 update(() -> { 545 546 removePrimitiveImpl(primitive); … … 571 572 } 572 573 573 574 @Override 574 public Collection<WaySegment > getHighlightedVirtualNodes() {575 public Collection<WaySegment<Node, Way>> getHighlightedVirtualNodes() { 575 576 return Collections.unmodifiableCollection(highlightedVirtualNodes); 576 577 } 577 578 578 579 @Override 579 public Collection<WaySegment > getHighlightedWaySegments() {580 public Collection<WaySegment<Node, Way>> getHighlightedWaySegments() { 580 581 return Collections.unmodifiableCollection(highlightedWaySegments); 581 582 } 582 583 … … 630 631 } 631 632 632 633 @Override 633 public void setHighlightedVirtualNodes(Collection<WaySegment > waySegments) {634 public void setHighlightedVirtualNodes(Collection<WaySegment<Node, Way>> waySegments) { 634 635 if (highlightedVirtualNodes.isEmpty() && waySegments.isEmpty()) 635 636 return; 636 637 … … 639 640 } 640 641 641 642 @Override 642 public void setHighlightedWaySegments(Collection<WaySegment > waySegments) {643 public void setHighlightedWaySegments(Collection<WaySegment<Node, Way>> waySegments) { 643 644 if (highlightedWaySegments.isEmpty() && waySegments.isEmpty()) 644 645 return; 645 646 -
src/org/openstreetmap/josm/data/osm/DefaultNameFormatter.java
667 667 * @param maxElements the maximum number of elements to display 668 668 * @return HTML unordered list 669 669 */ 670 public String formatAsHtmlUnorderedList(Collection<? extends OsmPrimitive> primitives, int maxElements) {670 public String formatAsHtmlUnorderedList(Collection<? extends IPrimitive> primitives, int maxElements) { 671 671 Collection<String> displayNames = primitives.stream().map(x -> x.getDisplayName(this)).collect(Collectors.toList()); 672 672 return Utils.joinAsHtmlUnorderedList(Utils.limit(displayNames, maxElements, "...")); 673 673 } -
src/org/openstreetmap/josm/data/osm/INode.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import org.openstreetmap.josm.data.Bounds; 4 5 import org.openstreetmap.josm.data.coor.EastNorth; 5 6 import org.openstreetmap.josm.data.coor.ILatLon; 6 7 import org.openstreetmap.josm.data.coor.LatLon; … … 70 71 default String getDisplayName(NameFormatter formatter) { 71 72 return formatter.format(this); 72 73 } 74 75 76 /** 77 * Determines if this node is outside of the world. See also #13538. 78 * @return <code>true</code>, if the coordinate is outside the world, compared by using lat/lon and east/north 79 * @since 14960 (extracted to INode in xxx) 80 */ 81 default public boolean isOutSideWorld() { 82 LatLon ll = getCoor(); 83 if (ll != null) { 84 Bounds b = ProjectionRegistry.getProjection().getWorldBoundsLatLon(); 85 if (lat() < b.getMinLat() || lat() > b.getMaxLat() || lon() < b.getMinLon() || lon() > b.getMaxLon()) { 86 return true; 87 } 88 if (!ProjectionRegistry.getProjection().latlon2eastNorth(ll).equalsEpsilon(getEastNorth(), 1.0)) { 89 // we get here if a node was moved or created left from -180 or right from +180 90 return true; 91 } 92 } 93 return false; 94 } 73 95 } -
src/org/openstreetmap/josm/data/osm/IPrimitive.java
331 331 * Makes the given visitor visit this primitive. 332 332 * @param visitor visitor 333 333 */ 334 void accept(PrimitiveVisitor visitor);334 void accept(PrimitiveVisitor<?, ?, ?> visitor); 335 335 336 336 /** 337 337 * <p>Visits {@code visitor} for all referrers.</p> … … 339 339 * @param visitor the visitor. Ignored, if null. 340 340 * @since 13806 341 341 */ 342 void visitReferrers(PrimitiveVisitor visitor);342 void visitReferrers(PrimitiveVisitor<?, ?, ?> visitor); 343 343 344 344 /** 345 345 * Replies the name of this primitive. The default implementation replies the value … … 478 478 * @return OsmData this primitive is part of. 479 479 * @since 13807 480 480 */ 481 OsmData<?, ?, ?, ?> getDataSet();481 <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> OsmData<O, N, W, R> getDataSet(); 482 482 483 483 /** 484 484 * Returns {@link #getKeys()} for which {@code key} does not fulfill uninteresting criteria. -
src/org/openstreetmap/josm/data/osm/IRelation.java
14 14 * @param <M> Type of OSM relation member 15 15 * @since 4098 16 16 */ 17 public interface IRelation<M extends IRelationMember<? >> extends IPrimitive {17 public interface IRelation<M extends IRelationMember<?, ?, ?, ?>> extends IPrimitive { 18 18 19 19 /** 20 20 * Returns the number of members. -
src/org/openstreetmap/josm/data/osm/IRelationMember.java
5 5 6 6 /** 7 7 * IRelationMember captures the common functions of {@link RelationMember} and {@link RelationMemberData}. 8 * @param <P> the base type of OSM primitives 8 * @param <O> the base type of primitives 9 * @param <N> type representing nodes 10 * @param <W> type representing ways 11 * @param <R> type representing relations 9 12 * @since 13677 10 13 */ 11 public interface IRelationMember< P extends IPrimitive> extends PrimitiveId {14 public interface IRelationMember<O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> extends PrimitiveId { 12 15 13 16 /** 14 17 * Returns the role of this relation member. … … 40 43 boolean isNode(); 41 44 42 45 /** 46 * Returns the relation member as a node. 47 * @return Member as node 48 * @since 1937 (RelationMember), xxx (IRelationMember) 49 */ 50 N getNode(); 51 52 /** 43 53 * Determines if this relation member is a way. 44 54 * @return True if member is way 45 55 */ … … 46 56 boolean isWay(); 47 57 48 58 /** 59 * Returns the relation member as a way. 60 * @return Member as way 61 * @since 1937 (RelationMember), xxx (IRelationMember) 62 */ 63 W getWay(); 64 65 /** 49 66 * Determines if this relation member is a relation. 50 67 * @return True if member is relation 51 68 */ … … 52 69 boolean isRelation(); 53 70 54 71 /** 72 * Returns the relation member as a relation. 73 * @return Member as relation 74 * @since 1937 (RelationMember), xxx (IRelationMember) 75 */ 76 R getRelation(); 77 78 /** 55 79 * Returns type of member for icon display. 56 80 * @return type of member for icon display 57 81 * @since 13766 (IRelationMember) … … 65 89 * @return Member. Returned value is never null. 66 90 * @since 13766 (IRelationMember) 67 91 */ 68 PgetMember();92 O getMember(); 69 93 } -
src/org/openstreetmap/josm/data/osm/IWay.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import java.util.Collection; 4 5 import java.util.List; 5 6 7 import org.openstreetmap.josm.tools.Pair; 8 6 9 /** 7 10 * IWay captures the common functions of {@link Way} and {@link WayData}. 8 11 * @param <N> type of OSM node … … 132 135 * @since 13922 133 136 */ 134 137 boolean isInnerNode(INode n); 138 139 /** 140 * Removes the given {@link Node} from this way. Ignored, if n is null. 141 * @param n The node to remove. Ignored, if null 142 * @since 1463 Way, xxx IWay 143 */ 144 public void removeNode(N n); 145 146 /** 147 * Removes the given set of {@link Node nodes} from this way. Ignored, if selection is null. 148 * @param selection The selection of nodes to remove. Ignored, if null 149 * @since 5408 Way, xxx IWay 150 */ 151 public void removeNodes(Collection<N> selection); 152 153 /** 154 * Adds a node to the end of the list of nodes. Ignored, if n is null. 155 * 156 * @param n the node. Ignored, if null 157 * @throws IllegalStateException if this way is marked as incomplete. We can't add a node 158 * to an incomplete way 159 * @since 1313 Way, xxx IWay 160 */ 161 void addNode(N n); 162 163 /** 164 * Adds a node at position offs. 165 * 166 * @param offs the offset 167 * @param n the node. Ignored, if null. 168 * @throws IllegalStateException if this way is marked as incomplete. We can't add a node 169 * to an incomplete way 170 * @throws IndexOutOfBoundsException if offs is out of bounds 171 * @since 1313 Way, xxx IWay 172 */ 173 void addNode(int offs, N n); 174 175 /** 176 * Replies the ordered {@link List} of chunks of this way. Each chunk is replied as a {@link Pair} of {@link Node nodes}. 177 * @param sort If true, the nodes of each pair are sorted as defined by {@link Pair#sort}. 178 * If false, Pair.a and Pair.b are in the way order 179 * (i.e for a given Pair(n), Pair(n-1).b == Pair(n).a, Pair(n).b == Pair(n+1).a, etc.) 180 * @return The ordered list of chunks of this way. 181 * @since 3348 (Way), xxx (IWay) 182 */ 183 List<Pair<N, N>> getNodePairs(boolean sort); 135 184 } -
src/org/openstreetmap/josm/data/osm/Node.java
10 10 import java.util.function.Predicate; 11 11 import java.util.stream.Collectors; 12 12 13 import org.openstreetmap.josm.data.Bounds;14 13 import org.openstreetmap.josm.data.coor.EastNorth; 15 14 import org.openstreetmap.josm.data.coor.LatLon; 16 15 import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor; … … 405 404 return referrers(Way.class).collect(Collectors.toList()); 406 405 } 407 406 408 /**409 * Determines if this node is outside of the world. See also #13538.410 * @return <code>true</code>, if the coordinate is outside the world, compared by using lat/lon and east/north411 * @since 14960412 */413 public boolean isOutSideWorld() {414 LatLon ll = getCoor();415 if (ll != null) {416 Bounds b = ProjectionRegistry.getProjection().getWorldBoundsLatLon();417 if (lat() < b.getMinLat() || lat() > b.getMaxLat() || lon() < b.getMinLon() || lon() > b.getMaxLon()) {418 return true;419 }420 if (!ProjectionRegistry.getProjection().latlon2eastNorth(ll).equalsEpsilon(getEastNorth(), 1.0)) {421 // we get here if a node was moved or created left from -180 or right from +180422 return true;423 }424 }425 return false;426 }427 428 407 @Override 429 408 public UniqueIdGenerator getIdGenerator() { 430 409 return idGenerator; -
src/org/openstreetmap/josm/data/osm/NodePositionComparator.java
9 9 * 10 10 * @author viesturs 11 11 */ 12 public class NodePositionComparator implements Comparator<Node>, Serializable {12 public class NodePositionComparator<N extends INode> implements Comparator<N>, Serializable { 13 13 14 14 private static final long serialVersionUID = 1L; 15 15 16 16 @Override 17 public int compare(N ode n1, Noden2) {17 public int compare(N n1, N n2) { 18 18 19 19 if (n1.getCoor().equalsEpsilon(n2.getCoor())) 20 20 return 0; -
src/org/openstreetmap/josm/data/osm/OsmData.java
61 61 void addPrimitive(O primitive); 62 62 63 63 /** 64 * Removes a primitive 65 * @param primitive the primitive 66 */ 67 void removePrimitive(O primitive); 68 69 /** 64 70 * Removes all primitives. 65 71 */ 66 72 void clear(); … … 269 275 * 270 276 * @return unmodifiable collection of WaySegments 271 277 */ 272 Collection<WaySegment > getHighlightedVirtualNodes();278 Collection<WaySegment<N, W>> getHighlightedVirtualNodes(); 273 279 274 280 /** 275 281 * Returns an unmodifiable collection of WaySegments that should be highlighted. … … 276 282 * 277 283 * @return unmodifiable collection of WaySegments 278 284 */ 279 Collection<WaySegment > getHighlightedWaySegments();285 Collection<WaySegment<N, W>> getHighlightedWaySegments(); 280 286 281 287 /** 282 288 * clear all highlights of virtual nodes 283 289 */ 284 290 default void clearHighlightedVirtualNodes() { 285 setHighlightedVirtualNodes(new ArrayList<WaySegment >());291 setHighlightedVirtualNodes(new ArrayList<WaySegment<N, W>>()); 286 292 } 287 293 288 294 /** … … 289 295 * clear all highlights of way segments 290 296 */ 291 297 default void clearHighlightedWaySegments() { 292 setHighlightedWaySegments(new ArrayList<WaySegment >());298 setHighlightedWaySegments(new ArrayList<WaySegment<N, W>>()); 293 299 } 294 300 295 301 /** … … 297 303 * *WaySegments* to avoid a VirtualNode class that wouldn't have much use otherwise. 298 304 * @param waySegments Collection of way segments 299 305 */ 300 void setHighlightedVirtualNodes(Collection<WaySegment > waySegments);306 void setHighlightedVirtualNodes(Collection<WaySegment<N, W>> waySegments); 301 307 302 308 /** 303 309 * set what virtual ways should be highlighted. 304 310 * @param waySegments Collection of way segments 305 311 */ 306 void setHighlightedWaySegments(Collection<WaySegment > waySegments);312 void setHighlightedWaySegments(Collection<WaySegment<N, W>> waySegments); 307 313 308 314 /** 309 315 * Adds a listener that gets notified whenever way segment / virtual nodes highlights change. -
src/org/openstreetmap/josm/data/osm/PrimitiveData.java
168 168 } 169 169 170 170 @Override 171 public OsmData<?, ?, ?, ?> getDataSet() {171 public <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> OsmData<O, N, W, R> getDataSet() { 172 172 return null; 173 173 } 174 174 -
src/org/openstreetmap/josm/data/osm/RelationMember.java
11 11 * Since membership may be qualified by a "role", a simple list is not sufficient. 12 12 * @since 343 13 13 */ 14 public class RelationMember implements IRelationMember<OsmPrimitive > {14 public class RelationMember implements IRelationMember<OsmPrimitive, Node, Way, Relation> { 15 15 16 16 /** 17 17 * … … 66 66 * @return Member as node 67 67 * @since 1937 68 68 */ 69 @Override 69 70 public Node getNode() { 70 71 return (Node) member; 71 72 } -
src/org/openstreetmap/josm/data/osm/Way.java
5 5 6 6 import java.util.ArrayList; 7 7 import java.util.Arrays; 8 import java.util.Collection; 8 9 import java.util.HashSet; 9 10 import java.util.List; 10 11 import java.util.Map; … … 151 152 return neigh; 152 153 } 153 154 154 /** 155 * Replies the ordered {@link List} of chunks of this way. Each chunk is replied as a {@link Pair} of {@link Node nodes}. 156 * @param sort If true, the nodes of each pair are sorted as defined by {@link Pair#sort}. 157 * If false, Pair.a and Pair.b are in the way order 158 * (i.e for a given Pair(n), Pair(n-1).b == Pair(n).a, Pair(n).b == Pair(n+1).a, etc.) 159 * @return The ordered list of chunks of this way. 160 * @since 3348 161 */ 155 @Override 162 156 public List<Pair<Node, Node>> getNodePairs(boolean sort) { 163 157 List<Pair<Node, Node>> chunkSet = new ArrayList<>(); 164 158 if (isIncomplete()) return chunkSet; … … 182 176 visitor.visit(this); 183 177 } 184 178 185 @Override public void accept(PrimitiveVisitor visitor) {179 @Override public void accept(PrimitiveVisitor<?, ?, ?> visitor) { 186 180 visitor.visit(this); 187 181 } 188 182 … … 332 326 return true; 333 327 } 334 328 335 /** 336 * Removes the given {@link Node} from this way. Ignored, if n is null. 337 * @param n The node to remove. Ignored, if null 338 * @since 1463 339 */ 329 @Override 340 330 public void removeNode(Node n) { 341 331 checkDatasetNotReadOnly(); 342 332 if (n == null || isIncomplete()) return; … … 361 351 } 362 352 } 363 353 364 /** 365 * Removes the given set of {@link Node nodes} from this way. Ignored, if selection is null. 366 * @param selection The selection of nodes to remove. Ignored, if null 367 * @since 5408 368 */ 369 public void removeNodes(Set<? extends Node> selection) { 354 @Override 355 public void removeNodes(Collection<Node> selection) { 370 356 checkDatasetNotReadOnly(); 371 357 if (selection == null || isIncomplete()) return; 372 358 boolean locked = writeLock(); … … 395 381 } 396 382 } 397 383 398 /** 399 * Adds a node to the end of the list of nodes. Ignored, if n is null. 400 * 401 * @param n the node. Ignored, if null 402 * @throws IllegalStateException if this way is marked as incomplete. We can't add a node 403 * to an incomplete way 404 * @since 1313 405 */ 384 @Override 406 385 public void addNode(Node n) { 407 386 checkDatasetNotReadOnly(); 408 387 if (n == null) return; … … 421 400 } 422 401 } 423 402 424 /** 425 * Adds a node at position offs. 426 * 427 * @param offs the offset 428 * @param n the node. Ignored, if null. 429 * @throws IllegalStateException if this way is marked as incomplete. We can't add a node 430 * to an incomplete way 431 * @throws IndexOutOfBoundsException if offs is out of bounds 432 * @since 1313 433 */ 403 @Override 434 404 public void addNode(int offs, Node n) { 435 405 checkDatasetNotReadOnly(); 436 406 if (n == null) return; -
src/org/openstreetmap/josm/data/osm/WaySegment.java
2 2 package org.openstreetmap.josm.data.osm; 3 3 4 4 import java.awt.geom.Line2D; 5 import java.lang.reflect.InvocationTargetException; 5 6 import java.util.Objects; 6 7 8 import org.openstreetmap.josm.tools.Logging; 9 7 10 /** 8 11 * A segment consisting of 2 consecutive nodes out of a way. 9 12 */ 10 public final class WaySegment implements Comparable<WaySegment> {13 public final class WaySegment<N extends INode, W extends IWay<N>> implements Comparable<WaySegment<N, W>> { 11 14 12 15 /** 13 16 * The way. 14 17 */ 15 public final W ayway;18 public final W way; 16 19 17 20 /** 18 21 * The index of one of the 2 nodes in the way. The other node has the … … 26 29 * @param i The node lower index 27 30 * @throws IllegalArgumentException in case of invalid index 28 31 */ 29 public WaySegment(W ayw, int i) {32 public WaySegment(W w, int i) { 30 33 way = w; 31 34 lowerIndex = i; 32 35 if (i < 0 || i >= w.getNodesCount() - 1) { … … 38 41 * Returns the first node of the way segment. 39 42 * @return the first node 40 43 */ 41 public N odegetFirstNode() {44 public N getFirstNode() { 42 45 return way.getNode(lowerIndex); 43 46 } 44 47 … … 46 49 * Returns the second (last) node of the way segment. 47 50 * @return the second node 48 51 */ 49 public N odegetSecondNode() {52 public N getSecondNode() { 50 53 return way.getNode(lowerIndex + 1); 51 54 } 52 55 … … 58 61 * @return way segment 59 62 * @throws IllegalArgumentException if the node pair is not part of way 60 63 */ 61 public static WaySegment forNodePair(Way way, Node first, Nodesecond) {64 public static <N extends INode, W extends IWay<N>> WaySegment<N, W> forNodePair(W way, N first, N second) { 62 65 int endIndex = way.getNodesCount() - 1; 63 66 while (endIndex > 0) { 64 67 final int indexOfFirst = way.getNodes().subList(0, endIndex).lastIndexOf(first); 65 68 if (second.equals(way.getNode(indexOfFirst + 1))) { 66 return new WaySegment (way, indexOfFirst);69 return new WaySegment<>(way, indexOfFirst); 67 70 } 68 71 endIndex--; 69 72 } … … 72 75 73 76 /** 74 77 * Returns this way segment as complete way. 75 * @return the way segment as {@code W ay}78 * @return the way segment as {@code W} 76 79 */ 77 public Way toWay() { 78 Way w = new Way(); 79 w.addNode(getFirstNode()); 80 w.addNode(getSecondNode()); 81 return w; 80 public W toWay() { 81 try { 82 /** way is of type W, so it should always create a new W */ 83 @SuppressWarnings("unchecked") 84 W w = (W) way.getClass().getConstructor().newInstance(); 85 w.addNode(getFirstNode()); 86 w.addNode(getSecondNode()); 87 return w; 88 } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException 89 | NoSuchMethodException | SecurityException e) { 90 Logging.trace(e); 91 return null; 92 } 82 93 } 83 94 84 95 @Override … … 85 96 public boolean equals(Object o) { 86 97 if (this == o) return true; 87 98 if (o == null || getClass() != o.getClass()) return false; 88 WaySegment that = (WaySegment) o;99 WaySegment<?, ?> that = (WaySegment<?, ?>) o; 89 100 return lowerIndex == that.lowerIndex && 90 101 Objects.equals(way, that.way); 91 102 } … … 96 107 } 97 108 98 109 @Override 99 public int compareTo(WaySegment o) {110 public int compareTo(WaySegment<N, W> o) { 100 111 return o == null ? -1 : (equals(o) ? 0 : toWay().compareTo(o.toWay())); 101 112 } 102 113 -
src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java
4 4 import java.util.Collection; 5 5 import java.util.HashSet; 6 6 7 import org.openstreetmap.josm.data.osm. Node;8 import org.openstreetmap.josm.data.osm. OsmPrimitive;9 import org.openstreetmap.josm.data.osm. Relation;10 import org.openstreetmap.josm.data.osm. RelationMember;11 import org.openstreetmap.josm.data.osm. Way;7 import org.openstreetmap.josm.data.osm.INode; 8 import org.openstreetmap.josm.data.osm.IPrimitive; 9 import org.openstreetmap.josm.data.osm.IRelation; 10 import org.openstreetmap.josm.data.osm.IRelationMember; 11 import org.openstreetmap.josm.data.osm.IWay; 12 12 13 13 /** 14 14 * Collect all nodes a specific osm primitive has. … … 15 15 * 16 16 * @author imi 17 17 */ 18 public class AllNodesVisitor implements OsmPrimitiveVisitor{18 public class AllNodesVisitor<N extends INode, W extends IWay<N>, R extends IRelation<? extends IRelationMember<?, N, W, R>>> implements PrimitiveVisitor<N, W, R> { 19 19 20 20 /** 21 21 * The resulting nodes collected so far. 22 22 */ 23 public Collection<N ode> nodes = new HashSet<>();23 public Collection<N> nodes = new HashSet<>(); 24 24 25 25 /** 26 26 * Nodes have only itself as nodes. 27 27 */ 28 28 @Override 29 public void visit(N oden) {29 public void visit(N n) { 30 30 nodes.add(n); 31 31 } 32 32 … … 34 34 * Ways have their way nodes. 35 35 */ 36 36 @Override 37 public void visit(W ayw) {37 public void visit(W w) { 38 38 if (w.isIncomplete()) return; 39 for (N oden : w.getNodes()) {39 for (N n : w.getNodes()) { 40 40 visit(n); 41 41 } 42 42 } … … 47 47 * if so, use AutomatchVisitor! 48 48 */ 49 49 @Override 50 public void visit(R elatione) {51 for ( RelationMemberm : e.getMembers()) {50 public void visit(R e) { 51 for (IRelationMember<?, N, W, R> m : e.getMembers()) { 52 52 if (m.isNode()) visit(m.getNode()); 53 53 } 54 54 } … … 58 58 * @param osms The OSM primitives to inspect 59 59 * @return All nodes the given primitives have. 60 60 */ 61 public static Collection<Node> getAllNodes(Collection<? extends OsmPrimitive> osms) {62 AllNodesVisitor v = new AllNodesVisitor();63 for ( OsmPrimitive osm : osms) {61 public static <N extends INode, W extends IWay<N>, R extends IRelation<? extends IRelationMember<?, N, W, R>>> Collection<N> getAllNodes(Collection<? extends IPrimitive> osms) { 62 AllNodesVisitor<N, W, R> v = new AllNodesVisitor<>(); 63 for (IPrimitive osm : osms) { 64 64 osm.accept(v); 65 65 } 66 66 return v.nodes; -
src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
14 14 import org.openstreetmap.josm.data.osm.IRelation; 15 15 import org.openstreetmap.josm.data.osm.IRelationMember; 16 16 import org.openstreetmap.josm.data.osm.IWay; 17 import org.openstreetmap.josm.data.osm.Node;18 17 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 import org.openstreetmap.josm.data.osm.Relation;20 import org.openstreetmap.josm.data.osm.Way;21 18 import org.openstreetmap.josm.data.projection.ProjectionRegistry; 22 19 import org.openstreetmap.josm.spi.preferences.Config; 23 20 … … 26 23 * EastNorth values as reference. 27 24 * @author imi 28 25 */ 29 public class BoundingXYVisitor implements OsmPrimitiveVisitor, PrimitiveVisitor{26 public class BoundingXYVisitor implements PrimitiveVisitor<INode, IWay<INode>, IRelation<?>> { 30 27 /** default value for setting "edit.zoom-enlarge-bbox" */ 31 28 private static final double ENLARGE_DEFAULT = 0.0002; 32 29 … … 33 30 private ProjectionBounds bounds; 34 31 35 32 @Override 36 public void visit(Node n) {37 visit((ILatLon) n);38 }39 40 @Override41 public void visit(Way w) {42 visit((IWay<?>) w);43 }44 45 @Override46 public void visit(Relation r) {47 visit((IRelation<?>) r);48 }49 50 @Override51 33 public void visit(INode n) { 52 34 visit((ILatLon) n); 53 35 } 54 36 55 37 @Override 56 public void visit(IWay< ?> w) {38 public void visit(IWay<INode> w) { 57 39 if (w.isIncomplete()) return; 58 40 for (INode n : w.getNodes()) { 59 41 visit(n); … … 63 45 @Override 64 46 public void visit(IRelation<?> r) { 65 47 // only use direct members 66 for (IRelationMember<? > m : r.getMembers()) {48 for (IRelationMember<?, ?, ?, ?> m : r.getMembers()) { 67 49 if (!m.isRelation()) { 68 50 m.getMember().accept(this); 69 51 } -
src/org/openstreetmap/josm/data/osm/visitor/OsmPrimitiveVisitor.java
10 10 * types {@link Node}, {@link Way} and {@link Relation}. 11 11 * @since 12810 12 12 */ 13 public interface OsmPrimitiveVisitor {13 public interface OsmPrimitiveVisitor extends PrimitiveVisitor<Node, Way, Relation> { 14 14 /** 15 15 * Visiting call for points. 16 16 * @param n The node to inspect. 17 17 */ 18 @Override 18 19 void visit(Node n); 19 20 20 21 /** … … 22 23 * @param w The way to inspect. 23 24 * @since 64 24 25 */ 26 @Override 25 27 void visit(Way w); 26 28 27 29 /** … … 29 31 * @param r The relation to inspect. 30 32 * @since 343 31 33 */ 34 @Override 32 35 void visit(Relation r); 33 36 34 37 } -
src/org/openstreetmap/josm/data/osm/visitor/PrimitiveVisitor.java
7 7 8 8 /** 9 9 * OSM primitives interfaces visitor, following conventional <a href="https://en.wikipedia.org/wiki/Visitor_pattern">visitor design pattern</a>. 10 * @since 4100 10 * @since 4100, xxx for generics 11 11 */ 12 public interface PrimitiveVisitor {12 public interface PrimitiveVisitor<N extends INode, W extends IWay<N>, R extends IRelation<?>> { 13 13 14 14 /** 15 15 * Visiting call for nodes. 16 16 * @param n The node to inspect. 17 17 */ 18 void visit( INoden);18 void visit(N n); 19 19 20 20 /** 21 21 * Visiting call for ways. 22 22 * @param w The way to inspect. 23 23 */ 24 void visit( IWay<?>w);24 void visit(W w); 25 25 26 26 /** 27 27 * Visiting call for relations. 28 28 * @param r The relation to inspect. 29 29 */ 30 void visit( IRelation<?>r);30 void visit(R r); 31 31 } -
src/org/openstreetmap/josm/data/validation/Test.java
282 282 * @param testError error to fix 283 283 * @return The command to fix the error 284 284 */ 285 public Command fixError(TestError testError) {285 public Command<OsmPrimitive, Node, Way, Relation> fixError(TestError testError) { 286 286 return null; 287 287 } 288 288 … … 334 334 * @param primitives The primitives wanted for deletion 335 335 * @return a Delete command on all primitives that have not yet been deleted, or null otherwise 336 336 */ 337 protected final Command deletePrimitivesIfNeeded(Collection<? extends OsmPrimitive> primitives) {337 protected final Command<OsmPrimitive, Node, Way, Relation> deletePrimitivesIfNeeded(Collection<? extends OsmPrimitive> primitives) { 338 338 Collection<OsmPrimitive> primitivesToDelete = new ArrayList<>(); 339 339 for (OsmPrimitive p : primitives) { 340 340 if (!p.isDeleted()) { -
src/org/openstreetmap/josm/data/validation/TestError.java
51 51 /** If this error is selected */ 52 52 private boolean selected; 53 53 /** Supplying a command to fix the error */ 54 private final Supplier<Command > fixingCommand;54 private final Supplier<Command<OsmPrimitive, Node, Way, Relation>> fixingCommand; 55 55 56 56 /** 57 57 * A builder for a {@code TestError}. … … 66 66 private String descriptionEn; 67 67 private Collection<? extends OsmPrimitive> primitives; 68 68 private Collection<?> highlighted; 69 private Supplier<Command > fixingCommand;69 private Supplier<Command<OsmPrimitive, Node, Way, Relation>> fixingCommand; 70 70 71 71 Builder(Test tester, Severity severity, int code) { 72 72 this.tester = tester; … … 172 172 * @return {@code this} 173 173 * @see ValidatorVisitor#visit(WaySegment) 174 174 */ 175 public Builder highlightWaySegments(Collection<WaySegment > highlighted) {175 public Builder highlightWaySegments(Collection<WaySegment<Node, Way>> highlighted) { 176 176 CheckParameterUtil.ensureParameterNotNull(highlighted, "highlighted"); 177 177 this.highlighted = highlighted; 178 178 return this; … … 209 209 * @param fixingCommand the fix supplier. Can be null 210 210 * @return {@code this} 211 211 */ 212 public Builder fix(Supplier<Command > fixingCommand) {212 public Builder fix(Supplier<Command<OsmPrimitive, Node, Way, Relation>> fixingCommand) { 213 213 CheckParameterUtil.ensureThat(this.fixingCommand == null, "fixingCommand already set"); 214 214 this.fixingCommand = fixingCommand; 215 215 return this; … … 409 409 * 410 410 * @return The command to fix the error 411 411 */ 412 public Command getFix() {412 public Command<OsmPrimitive, Node, Way, Relation> getFix() { 413 413 // obtain fix from the error 414 final Command fix = fixingCommand != null ? fixingCommand.get() : null;414 final Command<OsmPrimitive, Node, Way, Relation> fix = fixingCommand != null ? fixingCommand.get() : null; 415 415 if (fix != null) { 416 416 return fix; 417 417 } … … 441 441 if (o instanceof OsmPrimitive) { 442 442 v.visit((OsmPrimitive) o); 443 443 } else if (o instanceof WaySegment) { 444 v.visit((WaySegment ) o);444 v.visit((WaySegment<Node, Way>) o); 445 445 } else if (o instanceof List<?>) { 446 446 v.visit((List<Node>) o); 447 447 } else if (o instanceof Area) { -
src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
14 14 import java.util.Set; 15 15 16 16 import org.openstreetmap.josm.data.coor.EastNorth; 17 import org.openstreetmap.josm.data.osm.Node; 17 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 18 19 import org.openstreetmap.josm.data.osm.OsmUtils; 19 20 import org.openstreetmap.josm.data.osm.Relation; … … 75 76 } 76 77 77 78 /** All way segments, grouped by cells */ 78 private final Map<Point2D, List<WaySegment >> cellSegments = new HashMap<>(1000);79 private final Map<Point2D, List<WaySegment<Node, Way>>> cellSegments = new HashMap<>(1000); 79 80 /** The already detected ways in error */ 80 private final Map<List<Way>, List<WaySegment >> seenWays = new HashMap<>(50);81 private final Map<List<Way>, List<WaySegment<Node, Way>>> seenWays = new HashMap<>(50); 81 82 82 83 protected final int code; 83 84 … … 364 365 365 366 int nodesSize = w.getNodesCount(); 366 367 for (int i = 0; i < nodesSize - 1; i++) { 367 final WaySegment es1 = new WaySegment(w, i);368 final WaySegment<Node, Way> es1 = new WaySegment<>(w, i); 368 369 final EastNorth en1 = es1.getFirstNode().getEastNorth(); 369 370 final EastNorth en2 = es1.getSecondNode().getEastNorth(); 370 371 if (en1 == null || en2 == null) { … … 371 372 Logging.warn("Crossing ways test skipped " + es1); 372 373 continue; 373 374 } 374 for (List<WaySegment > segments : getSegments(cellSegments, en1, en2)) {375 for (WaySegment es2 : segments) {375 for (List<WaySegment<Node, Way>> segments : getSegments(cellSegments, en1, en2)) { 376 for (WaySegment<Node, Way> es2 : segments) { 376 377 List<Way> prims; 377 List<WaySegment > highlight;378 List<WaySegment<Node, Way>> highlight; 378 379 379 380 if (!es1.intersects(es2) || ignoreWaySegmentCombination(es1.way, es2.way)) { 380 381 continue; … … 419 420 * @param n2 The second EastNorth 420 421 * @return A list with all the cells the segment crosses 421 422 */ 422 public static List<List<WaySegment >> getSegments(Map<Point2D, List<WaySegment>> cellSegments, EastNorth n1, EastNorth n2) {423 List<List<WaySegment >> cells = new ArrayList<>();423 public static List<List<WaySegment<Node, Way>>> getSegments(Map<Point2D, List<WaySegment<Node, Way>>> cellSegments, EastNorth n1, EastNorth n2) { 424 List<List<WaySegment<Node, Way>>> cells = new ArrayList<>(); 424 425 for (Point2D cell : ValUtil.getSegmentCells(n1, n2, OsmValidator.getGridDetail())) { 425 426 cells.add(cellSegments.computeIfAbsent(cell, k -> new ArrayList<>())); 426 427 } … … 434 435 * @param crossingWays map to collect crossing ways and related segments 435 436 * @param findSharedWaySegments true: find shared way segments instead of crossings 436 437 */ 437 public static void findIntersectingWay(Way w, Map<Point2D, List<WaySegment >> cellSegments,438 Map<List<Way>, List<WaySegment >> crossingWays, boolean findSharedWaySegments) {438 public static void findIntersectingWay(Way w, Map<Point2D, List<WaySegment<Node, Way>>> cellSegments, 439 Map<List<Way>, List<WaySegment<Node, Way>>> crossingWays, boolean findSharedWaySegments) { 439 440 int nodesSize = w.getNodesCount(); 440 441 for (int i = 0; i < nodesSize - 1; i++) { 441 final WaySegment es1 = new WaySegment(w, i);442 final WaySegment<Node, Way> es1 = new WaySegment<>(w, i); 442 443 final EastNorth en1 = es1.getFirstNode().getEastNorth(); 443 444 final EastNorth en2 = es1.getSecondNode().getEastNorth(); 444 445 if (en1 == null || en2 == null) { … … 445 446 Logging.warn("Crossing ways test skipped " + es1); 446 447 continue; 447 448 } 448 for (List<WaySegment > segments : CrossingWays.getSegments(cellSegments, en1, en2)) {449 for (WaySegment es2 : segments) {449 for (List<WaySegment<Node, Way>> segments : CrossingWays.getSegments(cellSegments, en1, en2)) { 450 for (WaySegment<Node, Way> es2 : segments) { 450 451 451 List<WaySegment > highlight;452 List<WaySegment<Node, Way>> highlight; 452 453 if (es2.way == w // reported by CrossingWays.SelfIntersection 453 454 || (findSharedWaySegments && !es1.isSimilar(es2)) 454 455 || (!findSharedWaySegments && !es1.intersects(es2))) -
src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
40 40 public class OverlappingWays extends Test { 41 41 42 42 /** Bag of all way segments */ 43 private MultiMap<Pair<Node, Node>, WaySegment > nodePairs;43 private MultiMap<Pair<Node, Node>, WaySegment<Node, Way>> nodePairs; 44 44 45 45 protected static final int OVERLAPPING_HIGHWAY = 101; 46 46 protected static final int OVERLAPPING_RAILWAY = 102; … … 77 77 78 78 @Override 79 79 public void endTest() { 80 Map<List<Way>, Set<WaySegment >> seenWays = new HashMap<>(500);80 Map<List<Way>, Set<WaySegment<Node, Way>>> seenWays = new HashMap<>(500); 81 81 82 82 Collection<TestError> preliminaryErrors = new ArrayList<>(); 83 for (Set<WaySegment > duplicated : nodePairs.values()) {83 for (Set<WaySegment<Node, Way>> duplicated : nodePairs.values()) { 84 84 int ways = duplicated.size(); 85 85 86 86 if (ways > 1) { 87 87 List<OsmPrimitive> prims = new ArrayList<>(); 88 88 List<Way> currentWays = new ArrayList<>(); 89 Collection<WaySegment > highlight;89 Collection<WaySegment<Node, Way>> highlight; 90 90 int highway = 0; 91 91 int railway = 0; 92 92 int area = 0; 93 93 94 for (WaySegment ws : duplicated) {94 for (WaySegment<Node, Way> ws : duplicated) { 95 95 if (ws.way.hasKey(HIGHWAY)) { 96 96 highway++; 97 97 } else if (ws.way.hasKey(RAILWAY)) { … … 166 166 nodePairs = null; 167 167 } 168 168 169 protected static Set<WaySegment > checkDuplicateWaySegment(Way w) {169 protected static Set<WaySegment<Node, Way>> checkDuplicateWaySegment(Way w) { 170 170 // test for ticket #4959 171 Set<WaySegment > segments = new TreeSet<>((o1, o2) -> {171 Set<WaySegment<Node, Way>> segments = new TreeSet<>((o1, o2) -> { 172 172 final List<Node> n1 = Arrays.asList(o1.getFirstNode(), o1.getSecondNode()); 173 173 final List<Node> n2 = Arrays.asList(o2.getFirstNode(), o2.getSecondNode()); 174 174 Collections.sort(n1); … … 177 177 final int second = n1.get(1).compareTo(n2.get(1)); 178 178 return first != 0 ? first : second; 179 179 }); 180 final Set<WaySegment > duplicateWaySegments = new HashSet<>();180 final Set<WaySegment<Node, Way>> duplicateWaySegments = new HashSet<>(); 181 181 182 182 for (int i = 0; i < w.getNodesCount() - 1; i++) { 183 final WaySegment segment = new WaySegment(w, i);183 final WaySegment<Node, Way> segment = new WaySegment<>(w, i); 184 184 final boolean wasInSet = !segments.add(segment); 185 185 if (wasInSet) { 186 186 duplicateWaySegments.add(segment); … … 192 192 @Override 193 193 public void visit(Way w) { 194 194 195 final Set<WaySegment > duplicateWaySegment = checkDuplicateWaySegment(w);195 final Set<WaySegment<Node, Way>> duplicateWaySegment = checkDuplicateWaySegment(w); 196 196 if (!duplicateWaySegment.isEmpty()) { 197 197 errors.add(TestError.builder(this, Severity.ERROR, DUPLICATE_WAY_SEGMENT) 198 198 .message(tr("Way contains segment twice")) … … 211 211 continue; 212 212 } 213 213 nodePairs.put(Pair.sort(new Pair<>(lastN, n)), 214 new WaySegment (w, i));214 new WaySegment<>(w, i)); 215 215 lastN = n; 216 216 } 217 217 } -
src/org/openstreetmap/josm/gui/NavigatableComponent.java
39 39 import org.openstreetmap.josm.data.coor.ILatLon; 40 40 import org.openstreetmap.josm.data.coor.LatLon; 41 41 import org.openstreetmap.josm.data.osm.BBox; 42 import org.openstreetmap.josm.data.osm.DataSet; 42 import org.openstreetmap.josm.data.osm.INode; 43 import org.openstreetmap.josm.data.osm.IPrimitive; 44 import org.openstreetmap.josm.data.osm.IRelation; 45 import org.openstreetmap.josm.data.osm.IWay; 43 46 import org.openstreetmap.josm.data.osm.Node; 44 import org.openstreetmap.josm.data.osm.OsmPrimitive; 45 import org.openstreetmap.josm.data.osm.Relation; 47 import org.openstreetmap.josm.data.osm.OsmData; 46 48 import org.openstreetmap.josm.data.osm.Way; 47 49 import org.openstreetmap.josm.data.osm.WaySegment; 48 50 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; … … 90 92 /** 91 93 * To determine if a primitive is currently selectable. 92 94 */ 93 public transient Predicate< OsmPrimitive> isSelectablePredicate = prim -> {95 public transient Predicate<IPrimitive> isSelectablePredicate = prim -> { 94 96 if (!prim.isSelectable()) return false; 95 97 // if it isn't displayed on screen, you cannot click on it 96 98 MapCSSStyleSource.STYLE_SOURCE_LOCK.readLock().lock(); … … 549 551 * @param n The node, where this geopoint would be drawn. 550 552 * @return The point on screen where "node" would be drawn, relative to the own top/left. 551 553 */ 552 public Point2D getPoint2D( Node n) {554 public Point2D getPoint2D(INode n) { 553 555 return getPoint2D(n.getEastNorth()); 554 556 } 555 557 … … 590 592 * looses precision, may overflow (depends on p and current scale) 591 593 * @param n node 592 594 * @return point 593 * @see #getPoint2D( Node)595 * @see #getPoint2D(INode) 594 596 */ 595 public Point getPoint( Node n) {597 public Point getPoint(INode n) { 596 598 Point2D d = getPoint2D(n); 597 599 return new Point((int) d.getX(), (int) d.getY()); 598 600 } … … 982 984 * 983 985 * @return a sorted map with the keys representing the distance of their associated nodes to point p. 984 986 */ 985 private Map<Double, List< Node>> getNearestNodesImpl(Point p, Predicate<OsmPrimitive> predicate) {986 Map<Double, List< Node>> nearestMap = new TreeMap<>();987 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();987 private Map<Double, List<INode>> getNearestNodesImpl(Point p, Predicate<IPrimitive> predicate) { 988 Map<Double, List<INode>> nearestMap = new TreeMap<>(); 989 OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData(); 988 990 989 991 if (ds != null) { 990 992 double dist, snapDistanceSq = PROP_SNAP_DISTANCE.get(); 991 993 snapDistanceSq *= snapDistanceSq; 992 994 993 for ( Node n : ds.searchNodes(getBBox(p, PROP_SNAP_DISTANCE.get()))) {995 for (INode n : ds.searchNodes(getBBox(p, PROP_SNAP_DISTANCE.get()))) { 994 996 if (predicate.test(n) 995 997 && (dist = getPoint2D(n).distanceSq(p)) < snapDistanceSq) { 996 998 nearestMap.computeIfAbsent(dist, k -> new LinkedList<>()).add(n); … … 1014 1016 * dist(nearest) to dist(nearest)+4px around p and 1015 1017 * that are not in ignore. 1016 1018 */ 1017 public final List< Node> getNearestNodes(Point p,1018 Collection< Node> ignore, Predicate<OsmPrimitive> predicate) {1019 List< Node> nearestList = Collections.emptyList();1019 public final List<INode> getNearestNodes(Point p, 1020 Collection<INode> ignore, Predicate<IPrimitive> predicate) { 1021 List<INode> nearestList = Collections.emptyList(); 1020 1022 1021 1023 if (ignore == null) { 1022 1024 ignore = Collections.emptySet(); 1023 1025 } 1024 1026 1025 Map<Double, List< Node>> nlists = getNearestNodesImpl(p, predicate);1027 Map<Double, List<INode>> nlists = getNearestNodesImpl(p, predicate); 1026 1028 if (!nlists.isEmpty()) { 1027 1029 Double minDistSq = null; 1028 for (Entry<Double, List< Node>> entry : nlists.entrySet()) {1030 for (Entry<Double, List<INode>> entry : nlists.entrySet()) { 1029 1031 Double distSq = entry.getKey(); 1030 List< Node> nlist = entry.getValue();1032 List<INode> nlist = entry.getValue(); 1031 1033 1032 1034 // filter nodes to be ignored before determining minDistSq.. 1033 1035 nlist.removeAll(ignore); … … 1060 1062 * dist(nearest) to dist(nearest)+4px around p. 1061 1063 * @see #getNearestNodes(Point, Collection, Predicate) 1062 1064 */ 1063 public final List< Node> getNearestNodes(Point p, Predicate<OsmPrimitive> predicate) {1065 public final List<INode> getNearestNodes(Point p, Predicate<IPrimitive> predicate) { 1064 1066 return getNearestNodes(p, null, predicate); 1065 1067 } 1066 1068 … … 1084 1086 * 1085 1087 * @return A node within snap-distance to point p, that is chosen by the algorithm described. 1086 1088 */ 1087 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate, boolean useSelected) {1089 public final INode getNearestNode(Point p, Predicate<IPrimitive> predicate, boolean useSelected) { 1088 1090 return getNearestNode(p, predicate, useSelected, null); 1089 1091 } 1090 1092 … … 1112 1114 * @return A node within snap-distance to point p, that is chosen by the algorithm described. 1113 1115 * @since 6065 1114 1116 */ 1115 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate,1116 boolean useSelected, Collection< OsmPrimitive> preferredRefs) {1117 public final INode getNearestNode(Point p, Predicate<IPrimitive> predicate, 1118 boolean useSelected, Collection<IPrimitive> preferredRefs) { 1117 1119 1118 Map<Double, List< Node>> nlists = getNearestNodesImpl(p, predicate);1120 Map<Double, List<INode>> nlists = getNearestNodesImpl(p, predicate); 1119 1121 if (nlists.isEmpty()) return null; 1120 1122 1121 1123 if (preferredRefs != null && preferredRefs.isEmpty()) preferredRefs = null; 1122 Node ntsel = null, ntnew = null, ntref = null;1124 INode ntsel = null, ntnew = null, ntref = null; 1123 1125 boolean useNtsel = useSelected; 1124 1126 double minDistSq = nlists.keySet().iterator().next(); 1125 1127 1126 for (Entry<Double, List< Node>> entry : nlists.entrySet()) {1128 for (Entry<Double, List<INode>> entry : nlists.entrySet()) { 1127 1129 Double distSq = entry.getKey(); 1128 for ( Node nd : entry.getValue()) {1130 for (INode nd : entry.getValue()) { 1129 1131 // find the nearest selected node 1130 1132 if (ntsel == null && nd.isSelected()) { 1131 1133 ntsel = nd; … … 1136 1138 useNtsel |= Utils.equalsEpsilon(distSq, minDistSq); 1137 1139 } 1138 1140 if (ntref == null && preferredRefs != null && Utils.equalsEpsilon(distSq, minDistSq)) { 1139 List< OsmPrimitive> ndRefs = nd.getReferrers();1140 for ( OsmPrimitive ref: preferredRefs) {1141 List<? extends IPrimitive> ndRefs = nd.getReferrers(); 1142 for (IPrimitive ref: preferredRefs) { 1141 1143 if (ndRefs.contains(ref)) { 1142 1144 ntref = nd; 1143 1145 break; … … 1170 1172 * 1171 1173 * @return The nearest node to point p. 1172 1174 */ 1173 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate) {1175 public final INode getNearestNode(Point p, Predicate<IPrimitive> predicate) { 1174 1176 return getNearestNode(p, predicate, true); 1175 1177 } 1176 1178 … … 1184 1186 * @return a sorted map with the keys representing the perpendicular 1185 1187 * distance of their associated way segments to point p. 1186 1188 */ 1187 private Map<Double, List<WaySegment>> getNearestWaySegmentsImpl(Point p, Predicate<OsmPrimitive> predicate) { 1188 Map<Double, List<WaySegment>> nearestMap = new TreeMap<>(); 1189 DataSet ds = MainApplication.getLayerManager().getActiveDataSet(); 1189 private <N extends INode, W extends IWay<N>> Map<Double, List<WaySegment<N, W>>> getNearestWaySegmentsImpl(Point p, Predicate<IPrimitive> predicate, OsmData<?, N, W, ?> ds) { 1190 Map<Double, List<WaySegment<N, W>>> nearestMap = new TreeMap<>(); 1190 1191 1191 1192 if (ds != null) { 1192 1193 double snapDistanceSq = Config.getPref().getInt("mappaint.segment.snap-distance", 10); 1193 1194 snapDistanceSq *= snapDistanceSq; 1194 1195 1195 for (W ayw : ds.searchWays(getBBox(p, Config.getPref().getInt("mappaint.segment.snap-distance", 10)))) {1196 for (W w : ds.searchWays(getBBox(p, Config.getPref().getInt("mappaint.segment.snap-distance", 10)))) { 1196 1197 if (!predicate.test(w)) { 1197 1198 continue; 1198 1199 } 1199 N odelastN = null;1200 N lastN = null; 1200 1201 int i = -2; 1201 for (N oden : w.getNodes()) {1202 for (N n : w.getNodes()) { 1202 1203 i++; 1203 1204 if (n.isDeleted() || n.isIncomplete()) { //FIXME: This shouldn't happen, raise exception? 1204 1205 continue; … … 1224 1225 >> 32 << 32); // resolution in numbers with large exponent not needed here.. 1225 1226 1226 1227 if (perDistSq < snapDistanceSq && a < c + snapDistanceSq && b < c + snapDistanceSq) { 1227 nearestMap.computeIfAbsent(perDistSq, k -> new LinkedList<>()).add(new WaySegment (w, i));1228 nearestMap.computeIfAbsent(perDistSq, k -> new LinkedList<>()).add(new WaySegment<>(w, i)); 1228 1229 } 1229 1230 1230 1231 lastN = n; … … 1247 1248 * @return all segments within 10px of p that are not in ignore, 1248 1249 * sorted by their perpendicular distance. 1249 1250 */ 1250 public final List<WaySegment> getNearestWaySegments(Point p, 1251 Collection<WaySegment> ignore, Predicate<OsmPrimitive> predicate) { 1252 List<WaySegment> nearestList = new ArrayList<>(); 1253 List<WaySegment> unselected = new LinkedList<>(); 1251 public final <N extends INode, W extends IWay<N>> List<WaySegment<N, W>> getNearestWaySegments(Point p, 1252 Collection<WaySegment<N, W>> ignore, Predicate<IPrimitive> predicate) { 1253 OsmData<?, N, W, ?> ds = MainApplication.getLayerManager().getActiveData(); 1254 List<WaySegment<N, W>> nearestList = new ArrayList<>(); 1255 List<WaySegment<N, W>> unselected = new LinkedList<>(); 1254 1256 1255 for (List<WaySegment > wss : getNearestWaySegmentsImpl(p, predicate).values()) {1257 for (List<WaySegment<N, W>> wss : getNearestWaySegmentsImpl(p, predicate, ds).values()) { 1256 1258 // put selected waysegs within each distance group first 1257 1259 // makes the order of nearestList dependent on current selection state 1258 for (WaySegment ws : wss) {1260 for (WaySegment<N, W> ws : wss) { 1259 1261 (ws.way.isSelected() ? nearestList : unselected).add(ws); 1260 1262 } 1261 1263 nearestList.addAll(unselected); … … 1277 1279 * @return all segments within 10px of p, sorted by their perpendicular distance. 1278 1280 * @see #getNearestWaySegments(Point, Collection, Predicate) 1279 1281 */ 1280 public final List<WaySegment > getNearestWaySegments(Point p, Predicate<OsmPrimitive> predicate) {1282 public final List<WaySegment<Node, Way>> getNearestWaySegments(Point p, Predicate<IPrimitive> predicate) { 1281 1283 return getNearestWaySegments(p, null, predicate); 1282 1284 } 1283 1285 … … 1292 1294 * and, depending on use_selected, prefers a selected way segment, if found. 1293 1295 * @see #getNearestWaySegments(Point, Collection, Predicate) 1294 1296 */ 1295 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate, boolean useSelected) { 1296 WaySegment wayseg = null; 1297 WaySegment ntsel = null; 1297 public final <N extends INode, W extends IWay<N>> WaySegment<N, W> getNearestWaySegment(Point p, Predicate<IPrimitive> predicate, boolean useSelected) { 1298 OsmData<?, N, W, ?> ds = MainApplication.getLayerManager().getActiveData(); 1299 WaySegment<N, W> wayseg = null; 1300 WaySegment<N, W> ntsel = null; 1298 1301 1299 for (List<WaySegment > wslist : getNearestWaySegmentsImpl(p, predicate).values()) {1302 for (List<WaySegment<N, W>> wslist : getNearestWaySegmentsImpl(p, predicate, ds).values()) { 1300 1303 if (wayseg != null && ntsel != null) { 1301 1304 break; 1302 1305 } 1303 for (WaySegment ws : wslist) {1306 for (WaySegment<N, W> ws : wslist) { 1304 1307 if (wayseg == null) { 1305 1308 wayseg = ws; 1306 1309 } … … 1328 1331 * @see #getNearestWaySegments(Point, Collection, Predicate) 1329 1332 * @since 6065 1330 1333 */ 1331 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate, 1332 boolean useSelected, Collection<OsmPrimitive> preferredRefs) { 1333 WaySegment wayseg = null; 1334 public final <N extends INode, W extends IWay<N>> WaySegment<N, W> getNearestWaySegment(Point p, Predicate<IPrimitive> predicate, 1335 boolean useSelected, Collection<IPrimitive> preferredRefs) { 1336 OsmData<?, N, W, ?> ds = MainApplication.getLayerManager().getActiveData(); 1337 WaySegment<N, W> wayseg = null; 1334 1338 if (preferredRefs != null && preferredRefs.isEmpty()) 1335 1339 preferredRefs = null; 1336 1340 1337 for (List<WaySegment > wslist : getNearestWaySegmentsImpl(p, predicate).values()) {1338 for (WaySegment ws : wslist) {1341 for (List<WaySegment<N, W>> wslist : getNearestWaySegmentsImpl(p, predicate, ds).values()) { 1342 for (WaySegment<N, W> ws : wslist) { 1339 1343 if (wayseg == null) { 1340 1344 wayseg = ws; 1341 1345 } … … 1347 1351 if (preferredRefs.contains(ws.getFirstNode()) || preferredRefs.contains(ws.getSecondNode())) { 1348 1352 return ws; 1349 1353 } 1350 Collection< OsmPrimitive> wayRefs = ws.way.getReferrers();1354 Collection<? extends IPrimitive> wayRefs = ws.way.getReferrers(); 1351 1355 // prefer member of the given relations 1352 for ( OsmPrimitive ref: preferredRefs) {1353 if (ref instanceof Relation && wayRefs.contains(ref)) {1356 for (IPrimitive ref: preferredRefs) { 1357 if (ref instanceof IRelation && wayRefs.contains(ref)) { 1354 1358 return ws; 1355 1359 } 1356 1360 } … … 1367 1371 * 1368 1372 * @return The nearest way segment to point p. 1369 1373 */ 1370 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate) {1374 public final <N extends INode, W extends IWay<N>> WaySegment<N, W> getNearestWaySegment(Point p, Predicate<IPrimitive> predicate) { 1371 1375 return getNearestWaySegment(p, predicate, true); 1372 1376 } 1373 1377 … … 1383 1387 * @return all nearest ways to the screen point given that are not in ignore. 1384 1388 * @see #getNearestWaySegments(Point, Collection, Predicate) 1385 1389 */ 1386 public final List<Way> getNearestWays(Point p, 1387 Collection<Way> ignore, Predicate<OsmPrimitive> predicate) { 1388 List<Way> nearestList = new ArrayList<>(); 1389 Set<Way> wset = new HashSet<>(); 1390 public final <N extends INode, W extends IWay<N>> List<W> getNearestWays(Point p, 1391 Collection<W> ignore, Predicate<IPrimitive> predicate) { 1392 OsmData<?, N, W, ?> ds = MainApplication.getLayerManager().getActiveData(); 1393 List<W> nearestList = new ArrayList<>(); 1394 Set<W> wset = new HashSet<>(); 1390 1395 1391 for (List<WaySegment > wss : getNearestWaySegmentsImpl(p, predicate).values()) {1392 for (WaySegment ws : wss) {1396 for (List<WaySegment<N, W>> wss : getNearestWaySegmentsImpl(p, predicate, ds).values()) { 1397 for (WaySegment<N, W> ws : wss) { 1393 1398 if (wset.add(ws.way)) { 1394 1399 nearestList.add(ws.way); 1395 1400 } … … 1413 1418 * @return all nearest ways to the screen point given. 1414 1419 * @see #getNearestWays(Point, Collection, Predicate) 1415 1420 */ 1416 public final List<Way> getNearestWays(Point p, Predicate<OsmPrimitive> predicate) {1421 public final <N extends INode, W extends IWay<N>> List<W> getNearestWays(Point p, Predicate<IPrimitive> predicate) { 1417 1422 return getNearestWays(p, null, predicate); 1418 1423 } 1419 1424 … … 1426 1431 * @return The nearest way to point p, prefer a selected way if there are multiple nearest. 1427 1432 * @see #getNearestWaySegment(Point, Predicate) 1428 1433 */ 1429 public final Way getNearestWay(Point p, Predicate<OsmPrimitive> predicate) {1430 WaySegment nearestWaySeg = getNearestWaySegment(p, predicate);1434 public final <N extends INode, W extends IWay<N>> W getNearestWay(Point p, Predicate<IPrimitive> predicate) { 1435 WaySegment<N, W> nearestWaySeg = getNearestWaySegment(p, predicate); 1431 1436 return (nearestWaySeg == null) ? null : nearestWaySeg.way; 1432 1437 } 1433 1438 … … 1452 1457 * @see #getNearestNodes(Point, Collection, Predicate) 1453 1458 * @see #getNearestWays(Point, Collection, Predicate) 1454 1459 */ 1455 public final List< OsmPrimitive> getNearestNodesOrWays(Point p,1456 Collection< OsmPrimitive> ignore, Predicate<OsmPrimitive> predicate) {1457 List< OsmPrimitive> nearestList = Collections.emptyList();1458 OsmPrimitive osm = getNearestNodeOrWay(p, predicate, false);1460 public final List<IPrimitive> getNearestNodesOrWays(Point p, 1461 Collection<IPrimitive> ignore, Predicate<IPrimitive> predicate) { 1462 List<IPrimitive> nearestList = Collections.emptyList(); 1463 IPrimitive osm = getNearestNodeOrWay(p, predicate, false); 1459 1464 1460 1465 if (osm != null) { 1461 if (osm instanceof Node) {1466 if (osm instanceof INode) { 1462 1467 nearestList = new ArrayList<>(getNearestNodes(p, predicate)); 1463 } else if (osm instanceof Way) {1468 } else if (osm instanceof IWay) { 1464 1469 nearestList = new ArrayList<>(getNearestWays(p, predicate)); 1465 1470 } 1466 1471 if (ignore != null) { … … 1481 1486 * @return Primitives nearest to the given screen point. 1482 1487 * @see #getNearestNodesOrWays(Point, Collection, Predicate) 1483 1488 */ 1484 public final List< OsmPrimitive> getNearestNodesOrWays(Point p, Predicate<OsmPrimitive> predicate) {1489 public final List<IPrimitive> getNearestNodesOrWays(Point p, Predicate<IPrimitive> predicate) { 1485 1490 return getNearestNodesOrWays(p, null, predicate); 1486 1491 } 1487 1492 … … 1494 1499 * @param useSelected whether to prefer selected nodes 1495 1500 * @return true, if the node fulfills the properties of the function body 1496 1501 */ 1497 private boolean isPrecedenceNode( Node osm, Point p, boolean useSelected) {1502 private boolean isPrecedenceNode(INode osm, Point p, boolean useSelected) { 1498 1503 if (osm != null) { 1499 1504 if (p.distanceSq(getPoint2D(osm)) <= (4*4)) return true; 1500 1505 if (osm.isTagged()) return true; … … 1527 1532 * @see #getNearestNode(Point, Predicate) 1528 1533 * @see #getNearestWay(Point, Predicate) 1529 1534 */ 1530 public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate, boolean useSelected) {1531 Collection< OsmPrimitive> sel;1532 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();1535 public final IPrimitive getNearestNodeOrWay(Point p, Predicate<IPrimitive> predicate, boolean useSelected) { 1536 Collection<IPrimitive> sel; 1537 OsmData<? extends IPrimitive, ? extends INode, ? extends IWay<?>, ? extends IRelation<?>> ds = MainApplication.getLayerManager().getActiveData(); 1533 1538 if (useSelected && ds != null) { 1534 sel = ds.getSelected();1539 sel = new ArrayList<>(ds.getSelected()); 1535 1540 } else { 1536 1541 sel = null; 1537 1542 } 1538 OsmPrimitive osm = getNearestNode(p, predicate, useSelected, sel);1543 IPrimitive osm = getNearestNode(p, predicate, useSelected, sel); 1539 1544 1540 if (isPrecedenceNode(( Node) osm, p, useSelected)) return osm;1541 WaySegment ws;1545 if (isPrecedenceNode((INode) osm, p, useSelected)) return osm; 1546 WaySegment<?, ?> ws; 1542 1547 if (useSelected) { 1543 1548 ws = getNearestWaySegment(p, predicate, useSelected, sel); 1544 1549 } else { … … 1559 1564 // is wayseg shorter than maxWaySegLenSq and 1560 1565 // is p closer to the middle of wayseg than to the nearest node? 1561 1566 if (wp1.distanceSq(wp2) < maxWaySegLenSq && 1562 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D(( Node) osm))) {1567 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D((INode) osm))) { 1563 1568 osm = ws.way; 1564 1569 } 1565 1570 } … … 1596 1601 * @return a list of all objects that are nearest to point p and 1597 1602 * not in ignore or an empty list if nothing was found. 1598 1603 */ 1599 public final List< OsmPrimitive> getAllNearest(Point p,1600 Collection< OsmPrimitive> ignore, Predicate<OsmPrimitive> predicate) {1601 List< OsmPrimitive> nearestList = new ArrayList<>();1602 Set< Way> wset = new HashSet<>();1604 public final List<IPrimitive> getAllNearest(Point p, 1605 Collection<IPrimitive> ignore, Predicate<IPrimitive> predicate) { 1606 List<IPrimitive> nearestList = new ArrayList<>(); 1607 Set<IWay<?>> wset = new HashSet<>(); 1603 1608 1604 1609 // add nearby ways 1605 for (List<WaySegment > wss : getNearestWaySegmentsImpl(p, predicate).values()) {1606 for (WaySegment ws : wss) {1610 for (List<WaySegment<INode, IWay<INode>>> wss : getNearestWaySegmentsImpl(p, predicate, MainApplication.getLayerManager().getActiveData()).values()) { 1611 for (WaySegment<?, ?> ws : wss) { 1607 1612 if (wset.add(ws.way)) { 1608 1613 nearestList.add(ws.way); 1609 1614 } … … 1611 1616 } 1612 1617 1613 1618 // add nearby nodes 1614 for (List< Node> nlist : getNearestNodesImpl(p, predicate).values()) {1619 for (List<INode> nlist : getNearestNodesImpl(p, predicate).values()) { 1615 1620 nearestList.addAll(nlist); 1616 1621 } 1617 1622 1618 1623 // add parent relations of nearby nodes and ways 1619 Set< OsmPrimitive> parentRelations = new HashSet<>();1620 for ( OsmPrimitive o : nearestList) {1621 for ( OsmPrimitive r : o.getReferrers()) {1622 if (r instanceof Relation && predicate.test(r)) {1624 Set<IPrimitive> parentRelations = new HashSet<>(); 1625 for (IPrimitive o : nearestList) { 1626 for (IPrimitive r : o.getReferrers()) { 1627 if (r instanceof IRelation && predicate.test(r)) { 1623 1628 parentRelations.add(r); 1624 1629 } 1625 1630 } … … 1644 1649 * or an empty list if nothing was found. 1645 1650 * @see #getAllNearest(Point, Collection, Predicate) 1646 1651 */ 1647 public final List< OsmPrimitive> getAllNearest(Point p, Predicate<OsmPrimitive> predicate) {1652 public final List<IPrimitive> getAllNearest(Point p, Predicate<IPrimitive> predicate) { 1648 1653 return getAllNearest(p, null, predicate); 1649 1654 } 1650 1655 -
src/org/openstreetmap/josm/gui/SelectionManager.java
19 19 20 20 import org.openstreetmap.josm.actions.SelectByInternalPointAction; 21 21 import org.openstreetmap.josm.data.Bounds; 22 import org.openstreetmap.josm.data.osm. DataSet;23 import org.openstreetmap.josm.data.osm. Node;24 import org.openstreetmap.josm.data.osm. OsmPrimitive;25 import org.openstreetmap.josm.data.osm. Way;22 import org.openstreetmap.josm.data.osm.INode; 23 import org.openstreetmap.josm.data.osm.IPrimitive; 24 import org.openstreetmap.josm.data.osm.IWay; 25 import org.openstreetmap.josm.data.osm.OsmData; 26 26 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 27 27 import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable; 28 28 import org.openstreetmap.josm.tools.ColorHelper; … … 363 363 * objects that are touched, instead those which are completely covered. 364 364 * @return The collection of selected objects. 365 365 */ 366 public Collection< OsmPrimitive> getSelectedObjects(boolean alt) {367 Collection< OsmPrimitive> selection = new LinkedList<>();366 public Collection<IPrimitive> getSelectedObjects(boolean alt) { 367 Collection<IPrimitive> selection = new LinkedList<>(); 368 368 369 369 // whether user only clicked, not dragged. 370 370 boolean clicked = false; … … 373 373 clicked = true; 374 374 } 375 375 376 DataSet ds = MainApplication.getLayerManager().getActiveDataSet();376 OsmData<?, ?, ?, ?> ds = MainApplication.getLayerManager().getActiveData(); 377 377 if (clicked) { 378 378 Point center = new Point(selectionResult.xpoints[0], selectionResult.ypoints[0]); 379 OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive::isSelectable, false);379 IPrimitive osm = nc.getNearestNodeOrWay(center, IPrimitive::isSelectable, false); 380 380 if (osm != null) { 381 381 selection.add(osm); 382 382 } 383 383 } else if (ds != null) { 384 384 // nodes 385 for ( Node n : ds.getNodes()) {385 for (INode n : ds.getNodes()) { 386 386 if (n.isSelectable() && selectionResult.contains(nc.getPoint2D(n))) { 387 387 selection.add(n); 388 388 } … … 389 389 } 390 390 391 391 // ways 392 for ( Wayw : ds.getWays()) {392 for (IWay<?> w : ds.getWays()) { 393 393 if (!w.isSelectable() || w.isEmpty()) { 394 394 continue; 395 395 } 396 396 if (alt) { 397 for ( Node n : w.getNodes()) {397 for (INode n : w.getNodes()) { 398 398 if (!n.isIncomplete() && selectionResult.contains(nc.getPoint2D(n))) { 399 399 selection.add(w); 400 400 break; … … 402 402 } 403 403 } else { 404 404 boolean allIn = true; 405 for ( Node n : w.getNodes()) {405 for (INode n : w.getNodes()) { 406 406 if (!n.isIncomplete() && !selectionResult.contains(nc.getPoint(n))) { 407 407 allIn = false; 408 408 break; -
src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDataText.java
183 183 184 184 void addRelationMembers(IRelation<?> r) { 185 185 add(trn("{0} Member: ", "{0} Members: ", r.getMembersCount(), r.getMembersCount())); 186 for (IRelationMember<? > m : r.getMembers()) {186 for (IRelationMember<?, ?, ?, ?> m : r.getMembers()) { 187 187 s.append(INDENT).append(INDENT); 188 188 addHeadline(m.getMember()); 189 189 s.append(tr(" as \"{0}\"", m.getRole())); -
src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java
40 40 import org.openstreetmap.josm.data.osm.DataSet; 41 41 import org.openstreetmap.josm.data.osm.Node; 42 42 import org.openstreetmap.josm.data.osm.OsmPrimitive; 43 import org.openstreetmap.josm.data.osm.Relation; 44 import org.openstreetmap.josm.data.osm.Way; 43 45 import org.openstreetmap.josm.data.osm.WaySegment; 44 46 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; 45 47 import org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter; … … 632 634 protected void fixError(TestError error) throws InterruptedException, InvocationTargetException { 633 635 if (error.isFixable()) { 634 636 if (error.getPrimitives().stream().noneMatch(p -> p.isDeleted() || p.getDataSet() == null)) { 635 final Command fixCommand = error.getFix();637 final Command<OsmPrimitive, Node, Way, Relation> fixCommand = error.getFix(); 636 638 if (fixCommand != null) { 637 639 SwingUtilities.invokeAndWait(fixCommand::executeCommand); 638 640 fixCommands.add(fixCommand); … … 712 714 } 713 715 714 716 private static class AutofixCommand extends SequenceCommand { 715 AutofixCommand(Collection<Command > sequenz) {717 AutofixCommand(Collection<Command<OsmPrimitive, Node, Way, Relation>> sequenz) { 716 718 super(tr("auto-fixed validator issues"), sequenz, true); 717 719 setSequenceComplete(true); 718 720 } … … 719 721 720 722 @Override 721 723 public void undoCommand() { 722 getAffectedDataSet().update(super::undoCommand);724 ((DataSet) getAffectedDataSet()).update(super::undoCommand); 723 725 } 724 726 725 727 @Override 726 728 public boolean executeCommand() { 727 return getAffectedDataSet().update(super::executeCommand);729 return ((DataSet) getAffectedDataSet()).update(super::executeCommand); 728 730 } 729 731 } 730 732 -
src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
546 546 OsmDataLayer layer = MainApplication.getLayerManager().getActiveDataLayer(); 547 547 if (!layer.isLocked()) { 548 548 List<RelationMember> members = new ArrayList<>(); 549 for (IRelationMember<? > rm : ((MemberInfo) membershipData.getValueAt(row, 1)).role) {549 for (IRelationMember<?, ?, ?, ?> rm : ((MemberInfo) membershipData.getValueAt(row, 1)).role) { 550 550 if (rm instanceof RelationMember) { 551 551 members.add((RelationMember) rm); 552 552 } … … 681 681 MemberInfo mi = Optional.ofNullable(roles.get(r)).orElseGet(() -> new MemberInfo(newSel)); 682 682 roles.put(r, mi); 683 683 int i = 1; 684 for (IRelationMember<? > m : r.getMembers()) {684 for (IRelationMember<?, ?, ?, ?> m : r.getMembers()) { 685 685 if (m.getMember() == primitive) { 686 686 mi.add(m, i); 687 687 } … … 942 942 static final class TaggingPresetCommandHandler implements TaggingPresetHandler { 943 943 @Override 944 944 public void updateTags(List<Tag> tags) { 945 Command command = TaggingPreset.createCommand(getSelection(), tags);945 Command<?, ?, ?, ?> command = TaggingPreset.createCommand(getSelection(), tags); 946 946 if (command != null) { 947 947 UndoRedoHandler.getInstance().add(command); 948 948 } … … 1000 1000 } 1001 1001 1002 1002 static class MemberInfo { 1003 private final List<IRelationMember<? >> role = new ArrayList<>();1003 private final List<IRelationMember<?, ?, ?, ?>> role = new ArrayList<>(); 1004 1004 private Set<IPrimitive> members = new HashSet<>(); 1005 1005 private List<Integer> position = new ArrayList<>(); 1006 1006 private Collection<? extends IPrimitive> selection; … … 1011 1011 this.selection = selection; 1012 1012 } 1013 1013 1014 void add(IRelationMember<? > r, Integer p) {1014 void add(IRelationMember<?, ?, ?, ?> r, Integer p) { 1015 1015 role.add(r); 1016 1016 members.add(r.getMember()); 1017 1017 position.add(p); … … 1033 1033 1034 1034 String getRoleString() { 1035 1035 if (roleString == null) { 1036 for (IRelationMember<? > r : role) {1036 for (IRelationMember<?, ?, ?, ?> r : role) { 1037 1037 if (roleString == null) { 1038 1038 roleString = r.getRole(); 1039 1039 } else if (!roleString.equals(r.getRole())) { … … 1142 1142 for (OsmPrimitive primitive: OsmDataManager.getInstance().getInProgressSelection()) { 1143 1143 rel.removeMembersFor(primitive); 1144 1144 } 1145 UndoRedoHandler.getInstance().add(new ChangeCommand (cur, rel));1145 UndoRedoHandler.getInstance().add(new ChangeCommand<>(cur, rel)); 1146 1146 1147 1147 tagTable.clearSelection(); 1148 1148 if (nextRelation != null) { -
src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
51 51 import org.openstreetmap.josm.command.ChangeCommand; 52 52 import org.openstreetmap.josm.command.Command; 53 53 import org.openstreetmap.josm.data.osm.DefaultNameFormatter; 54 import org.openstreetmap.josm.data.osm.Node; 54 55 import org.openstreetmap.josm.data.osm.OsmPrimitive; 55 56 import org.openstreetmap.josm.data.osm.Relation; 56 57 import org.openstreetmap.josm.data.osm.RelationMember; 57 58 import org.openstreetmap.josm.data.osm.Tag; 59 import org.openstreetmap.josm.data.osm.Way; 58 60 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 59 61 import org.openstreetmap.josm.gui.MainApplication; 60 62 import org.openstreetmap.josm.gui.MainMenu; … … 903 905 * @return The resulting command 904 906 * @throws IllegalArgumentException if orig is null 905 907 */ 906 public static Command addPrimitivesToRelation(final Relation orig, Collection<? extends OsmPrimitive> primitivesToAdd) {908 public static Command<OsmPrimitive, Node, Way, Relation> addPrimitivesToRelation(final Relation orig, Collection<? extends OsmPrimitive> primitivesToAdd) { 907 909 CheckParameterUtil.ensureParameterNotNull(orig, "orig"); 908 910 try { 909 911 final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets( … … 922 924 relation.addMember(new RelationMember(roles.size() == 1 ? roles.iterator().next() : "", p)); 923 925 modified = true; 924 926 } 925 return modified ? new ChangeCommand (orig, relation) : null;927 return modified ? new ChangeCommand<>(orig, relation) : null; 926 928 } catch (AddAbortException ign) { 927 929 Logging.trace(ign); 928 930 return null; -
src/org/openstreetmap/josm/gui/layer/AbstractOsmDataLayer.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.layer; 3 3 4 import org.openstreetmap.josm.data.osm.INode; 5 import org.openstreetmap.josm.data.osm.IPrimitive; 6 import org.openstreetmap.josm.data.osm.IRelation; 7 import org.openstreetmap.josm.data.osm.IWay; 4 8 import org.openstreetmap.josm.data.osm.OsmData; 5 9 6 10 /** … … 17 21 * Returns the {@link OsmData} behind this layer. 18 22 * @return the {@link OsmData} behind this layer. 19 23 */ 20 public abstract OsmData<?, ?, ?, ?> getDataSet();24 public abstract <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> OsmData<O, N, W, R> getDataSet(); 21 25 22 26 @Override 23 27 public void lock() { -
src/org/openstreetmap/josm/gui/layer/MainLayerManager.java
14 14 15 15 import org.openstreetmap.josm.data.gpx.GpxData; 16 16 import org.openstreetmap.josm.data.osm.DataSet; 17 import org.openstreetmap.josm.data.osm.INode; 18 import org.openstreetmap.josm.data.osm.IPrimitive; 19 import org.openstreetmap.josm.data.osm.IRelation; 20 import org.openstreetmap.josm.data.osm.IWay; 17 21 import org.openstreetmap.josm.data.osm.OsmData; 18 22 import org.openstreetmap.josm.gui.MainApplication; 19 23 import org.openstreetmap.josm.gui.io.AsynchronousUploadPrimitivesTask; … … 406 410 * @return That data set, <code>null</code> if there is no active data layer. 407 411 * @since 13926 408 412 */ 409 public synchronized OsmData<?, ?, ?, ?> getActiveData() {413 public synchronized <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> OsmData<O, N, W, R> getActiveData() { 410 414 if (dataLayer != null) { 411 415 return dataLayer.getDataSet(); 412 416 } else { -
src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
24 24 import org.openstreetmap.josm.data.osm.IRelation; 25 25 import org.openstreetmap.josm.data.osm.IRelationMember; 26 26 import org.openstreetmap.josm.data.osm.IWay; 27 import org.openstreetmap.josm.data.osm.Node; 27 28 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 28 29 import org.openstreetmap.josm.data.osm.OsmUtils; 29 30 import org.openstreetmap.josm.data.osm.Relation; … … 189 190 * referrer was found.</p> 190 191 * 191 192 */ 192 private class MatchingReferrerFinder implements PrimitiveVisitor {193 private class MatchingReferrerFinder implements PrimitiveVisitor<INode, IWay<INode>, IRelation<?>> { 193 194 private final Environment e; 194 195 195 196 /** … … 243 244 } 244 245 245 246 @Override 246 public void visit(IWay< ?> w) {247 public void visit(IWay<INode> w) { 247 248 doVisit(w, w::getNodesCount, w::getNode); 248 249 } 249 250 … … 253 254 } 254 255 } 255 256 256 private abstract static class AbstractFinder implements PrimitiveVisitor {257 private abstract static class AbstractFinder implements PrimitiveVisitor<INode, IWay<INode>, IRelation<?>> { 257 258 protected final Environment e; 258 259 259 260 protected AbstractFinder(Environment e) { … … 265 266 } 266 267 267 268 @Override 268 public void visit(IWay< ?> w) {269 public void visit(IWay<INode> w) { 269 270 } 270 271 271 272 @Override … … 298 299 private class MultipolygonOpenEndFinder extends AbstractFinder { 299 300 300 301 @Override 301 public void visit(IWay< ?> w) {302 public void visit(IWay<INode> w) { 302 303 w.visitReferrers(innerVisitor); 303 304 } 304 305 … … 306 307 super(e); 307 308 } 308 309 309 private final PrimitiveVisitor innerVisitor = new AbstractFinder(e) {310 private final PrimitiveVisitor<INode, IWay<INode>, IRelation<?>> innerVisitor = new AbstractFinder(e) { 310 311 @Override 311 312 public void visit(IRelation<?> r) { 312 313 if (r instanceof Relation && left.matches(e.withPrimitive(r))) { … … 327 328 private final String layer; 328 329 private Area area; 329 330 /** Will contain all way segments, grouped by cells */ 330 Map<Point2D, List<WaySegment >> cellSegments;331 Map<Point2D, List<WaySegment<Node, Way>>> cellSegments; 331 332 332 333 private CrossingFinder(Environment e) { 333 334 super(e); … … 347 348 return Geometry.getAreaEastNorth(p); 348 349 } 349 350 350 private Map<List<Way>, List<WaySegment >> findCrossings(IPrimitive area,351 Map<Point2D, List<WaySegment >> cellSegments) {351 private Map<List<Way>, List<WaySegment<Node, Way>>> findCrossings(IPrimitive area, 352 Map<Point2D, List<WaySegment<Node, Way>>> cellSegments) { 352 353 /** The detected crossing ways */ 353 Map<List<Way>, List<WaySegment >> crossingWays = new HashMap<>(50);354 Map<List<Way>, List<WaySegment<Node, Way>>> crossingWays = new HashMap<>(50); 354 355 if (area instanceof Way) { 355 356 CrossingWays.findIntersectingWay((Way) area, cellSegments, crossingWays, false); 356 357 } else if (area instanceof Relation && area.isMultipolygon()) { … … 413 414 findCrossings(e.osm, cellSegments); // ignore self intersections etc. here 414 415 } 415 416 // need a copy 416 final Map<Point2D, List<WaySegment >> tmpCellSegments = new HashMap<>(cellSegments);417 final Map<Point2D, List<WaySegment<Node, Way>>> tmpCellSegments = new HashMap<>(cellSegments); 417 418 // calculate all crossings between e.osm and p 418 Map<List<Way>, List<WaySegment >> crossingWays = findCrossings(p, tmpCellSegments);419 Map<List<Way>, List<WaySegment<Node, Way>>> crossingWays = findCrossings(p, tmpCellSegments); 419 420 if (!crossingWays.isEmpty()) { 420 421 addToChildren(e, p); 421 422 if (e.crossingWaysMap == null) { … … 469 470 } 470 471 471 472 @Override 472 public void visit(IWay< ?> w) {473 public void visit(IWay<INode> w) { 473 474 if (left.matches(new Environment(w).withParent(e.osm)) 474 475 && w.getBBox().bounds(e.osm.getBBox()) 475 476 && !Geometry.filterInsidePolygon(Collections.singletonList(e.osm), w).isEmpty()) { … … 601 602 } 602 603 } 603 604 } else if (e.osm instanceof IRelation) { 604 List<? extends IRelationMember<? >> members = ((IRelation<?>) e.osm).getMembers();605 List<? extends IRelationMember<?, ?, ?, ?>> members = ((IRelation<?>) e.osm).getMembers(); 605 606 for (int i = 0; i < members.size(); i++) { 606 607 IPrimitive member = members.get(i).getMember(); 607 608 if (left.matches(e.withPrimitive(member)) -
src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java
41 41 import org.openstreetmap.josm.data.UndoRedoHandler; 42 42 import org.openstreetmap.josm.data.osm.DataSet; 43 43 import org.openstreetmap.josm.data.osm.IPrimitive; 44 import org.openstreetmap.josm.data.osm.Node; 44 45 import org.openstreetmap.josm.data.osm.OsmData; 45 46 import org.openstreetmap.josm.data.osm.OsmDataManager; 46 47 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 47 48 import org.openstreetmap.josm.data.osm.Relation; 48 49 import org.openstreetmap.josm.data.osm.RelationMember; 49 50 import org.openstreetmap.josm.data.osm.Tag; 51 import org.openstreetmap.josm.data.osm.Way; 50 52 import org.openstreetmap.josm.data.osm.search.SearchCompiler; 51 53 import org.openstreetmap.josm.data.osm.search.SearchCompiler.Match; 52 54 import org.openstreetmap.josm.data.osm.search.SearchParseError; … … 412 414 } 413 415 414 416 if (!sel.isEmpty() && answer == DIALOG_ANSWER_APPLY) { 415 Command cmd = createCommand(sel, getChangedTags());417 Command<?, ?, ?, ?> cmd = createCommand(sel, getChangedTags()); 416 418 if (cmd != null) { 417 419 UndoRedoHandler.getInstance().add(cmd); 418 420 } … … 547 549 * @param changedTags The tags to change 548 550 * @return A command that changes the tags. 549 551 */ 550 public static Command createCommand(Collection<OsmPrimitive> sel, List<Tag> changedTags) {551 List<Command > cmds = new ArrayList<>();552 public static Command<?, ?, ?, ?> createCommand(Collection<OsmPrimitive> sel, List<Tag> changedTags) { 553 List<Command<OsmPrimitive, Node, Way, Relation>> cmds = new ArrayList<>(); 552 554 for (Tag tag: changedTags) { 553 555 ChangePropertyCommand cmd = new ChangePropertyCommand(sel, tag.getKey(), tag.getValue()); 554 556 if (cmd.getObjectsNumber() > 0) { -
src/org/openstreetmap/josm/tools/Geometry.java
26 26 import org.openstreetmap.josm.data.coor.EastNorth; 27 27 import org.openstreetmap.josm.data.coor.ILatLon; 28 28 import org.openstreetmap.josm.data.osm.BBox; 29 import org.openstreetmap.josm.data.osm.DataSet;30 29 import org.openstreetmap.josm.data.osm.INode; 31 30 import org.openstreetmap.josm.data.osm.IPrimitive; 31 import org.openstreetmap.josm.data.osm.IRelation; 32 32 import org.openstreetmap.josm.data.osm.IWay; 33 33 import org.openstreetmap.josm.data.osm.MultipolygonBuilder; 34 34 import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygon; 35 35 import org.openstreetmap.josm.data.osm.Node; 36 36 import org.openstreetmap.josm.data.osm.NodePositionComparator; 37 import org.openstreetmap.josm.data.osm.OsmData; 37 38 import org.openstreetmap.josm.data.osm.OsmPrimitive; 38 39 import org.openstreetmap.josm.data.osm.Relation; 39 40 import org.openstreetmap.josm.data.osm.Way; … … 95 96 * the ways. 96 97 * @return list of new nodes, if test is true the list might not contain all intersections 97 98 */ 98 public static Set<Node> addIntersections(List<Way> ways, boolean test, List<Command> cmds) {99 public static <O extends IPrimitive, N extends INode, W extends IWay<N>, R extends IRelation<?>> Set<N> addIntersections(List<W> ways, boolean test, List<Command<O, N, W, R>> cmds) { 99 100 100 101 int n = ways.size(); 101 102 @SuppressWarnings("unchecked") 102 List<N ode>[] newNodes = new ArrayList[n];103 List<N>[] newNodes = new ArrayList[n]; 103 104 BBox[] wayBounds = new BBox[n]; 104 105 boolean[] changedWays = new boolean[n]; 105 106 106 Set<N ode> intersectionNodes = new LinkedHashSet<>();107 Set<N> intersectionNodes = new LinkedHashSet<>(); 107 108 108 109 //copy node arrays for local usage. 109 110 for (int pos = 0; pos < n; pos++) { … … 112 113 changedWays[pos] = false; 113 114 } 114 115 115 DataSetdataset = ways.get(0).getDataSet();116 OsmData<O, N, W, R> dataset = ways.get(0).getDataSet(); 116 117 117 118 //iterate over all way pairs and introduce the intersections 118 Comparator<N ode> coordsComparator = new NodePositionComparator();119 Comparator<N> coordsComparator = new NodePositionComparator<>(); 119 120 for (int seg1Way = 0; seg1Way < n; seg1Way++) { 120 121 for (int seg2Way = seg1Way; seg2Way < n; seg2Way++) { 121 122 … … 124 125 continue; 125 126 } 126 127 127 List<N ode> way1Nodes = newNodes[seg1Way];128 List<N ode> way2Nodes = newNodes[seg2Way];128 List<N> way1Nodes = newNodes[seg1Way]; 129 List<N> way2Nodes = newNodes[seg2Way]; 129 130 130 131 //iterate over primary segmemt 131 132 for (int seg1Pos = 0; seg1Pos + 1 < way1Nodes.size(); seg1Pos++) { … … 136 137 for (int seg2Pos = seg2Start; seg2Pos + 1 < way2Nodes.size(); seg2Pos++) { 137 138 138 139 //need to get them again every time, because other segments may be changed 139 N odeseg1Node1 = way1Nodes.get(seg1Pos);140 N odeseg1Node2 = way1Nodes.get(seg1Pos + 1);141 N odeseg2Node1 = way2Nodes.get(seg2Pos);142 N odeseg2Node2 = way2Nodes.get(seg2Pos + 1);140 N seg1Node1 = way1Nodes.get(seg1Pos); 141 N seg1Node2 = way1Nodes.get(seg1Pos + 1); 142 N seg2Node1 = way2Nodes.get(seg2Pos); 143 N seg2Node2 = way2Nodes.get(seg2Pos + 1); 143 144 144 145 int commonCount = 0; 145 146 //test if we have common nodes to add. … … 168 169 seg2Node1.getEastNorth(), seg2Node2.getEastNorth()); 169 170 170 171 if (intersection != null) { 171 Node newNode = new Node(ProjectionRegistry.getProjection().eastNorth2latlon(intersection)); 172 Node intNode = newNode; 172 N newNode = Utils.clone(seg1Node1); 173 newNode.removeAll(); // Make certain we don't keep any keys from the original node 174 newNode.setCoor(ProjectionRegistry.getProjection().eastNorth2latlon(intersection)); 175 N intNode = newNode; 173 176 boolean insertInSeg1 = false; 174 177 boolean insertInSeg2 = false; 175 178 //find if the intersection point is at end point of one of the segments, if so use that point … … 218 221 intersectionNodes.add(intNode); 219 222 220 223 if (intNode == newNode) { 221 cmds.add(new AddCommand (dataset,intNode));224 cmds.add(new AddCommand<>(dataset, (O) intNode)); 222 225 } 223 226 } 224 227 } else if (test && !intersectionNodes.isEmpty()) … … 234 237 continue; 235 238 } 236 239 237 W ayway = ways.get(pos);238 W ay newWay = new Way(way);240 W way = ways.get(pos); 241 W newWay = Utils.clone(way); 239 242 newWay.setNodes(newNodes[pos]); 240 243 241 cmds.add(new ChangeCommand (dataset, way,newWay));244 cmds.add(new ChangeCommand<>(dataset, (O) way, (O) newWay)); 242 245 } 243 246 244 247 return intersectionNodes; … … 1540 1543 * May return {@link Double#NaN}. 1541 1544 * @since 15035 1542 1545 */ 1543 public static double getDistanceSegmentSegment(WaySegment ws1, WaySegmentws2) {1546 public static <N extends INode, W extends IWay<N>> double getDistanceSegmentSegment(WaySegment<N, W> ws1, WaySegment<N, W> ws2) { 1544 1547 return getDistanceSegmentSegment(ws1.getFirstNode(), ws1.getSecondNode(), ws2.getFirstNode(), ws2.getSecondNode()); 1545 1548 } 1546 1549 … … 1555 1558 * May return {@link Double#NaN}. 1556 1559 * @since 15035 1557 1560 */ 1558 public static double getDistanceSegmentSegment( Node ws1Node1, Node ws1Node2, Node ws2Node1,Node ws2Node2) {1561 public static double getDistanceSegmentSegment(INode ws1Node1, INode ws1Node2, INode ws2Node1, INode ws2Node2) { 1559 1562 EastNorth enWs1Node1 = ws1Node1.getEastNorth(); 1560 1563 EastNorth enWs1Node2 = ws1Node2.getEastNorth(); 1561 1564 EastNorth enWs2Node1 = ws2Node1.getEastNorth(); -
src/org/openstreetmap/josm/tools/Utils.java
15 15 import java.io.IOException; 16 16 import java.io.InputStream; 17 17 import java.io.UnsupportedEncodingException; 18 import java.lang.reflect.InvocationTargetException; 18 19 import java.net.MalformedURLException; 19 20 import java.net.URI; 20 21 import java.net.URISyntaxException; … … 68 69 import javax.script.ScriptEngine; 69 70 import javax.script.ScriptEngineManager; 70 71 71 import com.kitfox.svg.xml.XMLParseUtil;72 72 import org.openstreetmap.josm.spi.preferences.Config; 73 73 74 import com.kitfox.svg.xml.XMLParseUtil; 75 74 76 /** 75 77 * Basic utils, that can be useful in different parts of the program. 76 78 */ … … 1945 1947 // remove extra whitespaces 1946 1948 return rawString.trim(); 1947 1949 } 1950 1951 /** 1952 * Clone an object that has a cloning constructor 1953 * 1954 * @param <T> The object class to clone 1955 * @param object The object that is cloned 1956 * @return The cloned object, or {@code null} 1957 */ 1958 @SuppressWarnings("unchecked") 1959 public static <T> T clone(T object) { 1960 try { 1961 Object obj = object.getClass().getConstructor(object.getClass()).newInstance(object); 1962 if (object.getClass().isAssignableFrom(obj.getClass())) { 1963 return (T) obj; 1964 } else { 1965 return null; 1966 } 1967 } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 1968 Logging.error(e); 1969 return null; 1970 } 1971 } 1948 1972 } -
test/unit/org/openstreetmap/josm/TestUtils.java
389 389 * @param ds data set 390 390 * @return a new empty command 391 391 */ 392 public static Command newCommand(DataSet ds) {393 return new Command (ds) {392 public static Command<OsmPrimitive, Node, Way, Relation> newCommand(DataSet ds) { 393 return new Command<OsmPrimitive, Node, Way, Relation>(ds) { 394 394 @Override 395 395 public String getDescriptionText() { 396 396 return ""; -
test/unit/org/openstreetmap/josm/command/SequenceCommandTest.java
21 21 import org.openstreetmap.josm.data.osm.DataSet; 22 22 import org.openstreetmap.josm.data.osm.Node; 23 23 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 import org.openstreetmap.josm.data.osm.Relation; 24 25 import org.openstreetmap.josm.data.osm.User; 26 import org.openstreetmap.josm.data.osm.Way; 25 27 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 26 28 import org.openstreetmap.josm.testutils.JOSMTestRules; 27 29 … … 64 66 return super.executeCommand(); 65 67 } 66 68 }; 67 SequenceCommand command = new SequenceCommand("seq", Arrays.<Command>asList(command1, command2));69 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", Arrays.<Command<OsmPrimitive, Node, Way, Relation>>asList(command1, command2)); 68 70 69 71 command.executeCommand(); 70 72 … … 86 88 super.undoCommand(); 87 89 } 88 90 }; 89 SequenceCommand command = new SequenceCommand("seq", Arrays.<Command>asList(command1, command2));91 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", Arrays.<Command<OsmPrimitive, Node, Way, Relation>>asList(command1, command2)); 90 92 91 93 command.executeCommand(); 92 94 … … 110 112 TestCommand command1 = new TestCommand(ds, null); 111 113 FailingCommand command2 = new FailingCommand(ds); 112 114 TestCommand command3 = new TestCommand(ds, null); 113 SequenceCommand command = new SequenceCommand("seq", Arrays.<Command>asList(command1, command2, command3));115 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", Arrays.<Command<OsmPrimitive, Node, Way, Relation>>asList(command1, command2, command3)); 114 116 assertFalse(command.executeCommand()); 115 117 assertFalse(command1.executed); 116 118 // Don't check command2 executed state as it's possible but not necessary to undo failed commands … … 127 129 TestCommand command1 = new TestCommand(ds, null); 128 130 FailingCommand command2 = new FailingCommand(ds); 129 131 TestCommand command3 = new TestCommand(ds, null); 130 SequenceCommand command = new SequenceCommand("seq", Arrays.<Command>asList(command1, command2, command3), true);132 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", Arrays.<Command<OsmPrimitive, Node, Way, Relation>>asList(command1, command2, command3), true); 131 133 assertTrue(command.executeCommand()); 132 134 assertTrue(command1.executed); 133 135 assertTrue(command3.executed); … … 146 148 final TestCommand command1 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode)); 147 149 final TestCommand command2 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode2)); 148 150 149 assertEquals(command2, new SequenceCommand (ds, "seq", Arrays.asList(command1, command2), false).getLastCommand());150 assertNull(new SequenceCommand (ds, "seq", Collections.emptyList(), false).getLastCommand());151 assertEquals(command2, new SequenceCommand<>(ds, "seq", Arrays.asList(command1, command2), false).getLastCommand()); 152 assertNull(new SequenceCommand<>(ds, "seq", Collections.emptyList(), false).getLastCommand()); 151 153 } 152 154 153 155 /** … … 156 158 @Test 157 159 public void testFillModifiedData() { 158 160 DataSet ds = new DataSet(); 159 Command command1 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode));160 Command command2 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode2));161 Command command3 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingWay)) {161 Command<OsmPrimitive, Node, Way, Relation> command1 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode)); 162 Command<OsmPrimitive, Node, Way, Relation> command2 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode2)); 163 Command<OsmPrimitive, Node, Way, Relation> command3 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingWay)) { 162 164 @Override 163 165 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, 164 166 Collection<OsmPrimitive> added) { … … 165 167 deleted.addAll(primitives); 166 168 } 167 169 }; 168 Command command4 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingRelation)) {170 Command<OsmPrimitive, Node, Way, Relation> command4 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingRelation)) { 169 171 @Override 170 172 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, 171 173 Collection<OsmPrimitive> added) { … … 176 178 ArrayList<OsmPrimitive> modified = new ArrayList<>(); 177 179 ArrayList<OsmPrimitive> deleted = new ArrayList<>(); 178 180 ArrayList<OsmPrimitive> added = new ArrayList<>(); 179 SequenceCommand command = new SequenceCommand("seq", command1, command2, command3, command4);181 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", command1, command2, command3, command4); 180 182 command.fillModifiedData(modified, deleted, added); 181 183 assertArrayEquals(new Object[] {testData.existingNode, testData.existingNode2}, modified.toArray()); 182 184 assertArrayEquals(new Object[] {testData.existingWay}, deleted.toArray()); … … 189 191 @Test 190 192 public void testGetParticipatingPrimitives() { 191 193 DataSet ds = new DataSet(); 192 Command command1 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode));193 Command command2 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode2));194 Command<OsmPrimitive, Node, Way, Relation> command1 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode)); 195 Command<OsmPrimitive, Node, Way, Relation> command2 = new TestCommand(ds, Arrays.<OsmPrimitive>asList(testData.existingNode2)); 194 196 195 SequenceCommand command = new SequenceCommand("seq", command1, command2);197 SequenceCommand<OsmPrimitive, Node, Way, Relation> command = new SequenceCommand<>("seq", command1, command2); 196 198 command.executeCommand(); 197 199 Collection<? extends OsmPrimitive> primitives = command.getParticipatingPrimitives(); 198 200 assertEquals(2, primitives.size()); … … 205 207 */ 206 208 @Test 207 209 public void testDescription() { 208 assertTrue(new SequenceCommand (new DataSet(), "test", Collections.emptyList(), false).getDescriptionText().matches("Sequence: test"));210 assertTrue(new SequenceCommand<>(new DataSet(), "test", Collections.emptyList(), false).getDescriptionText().matches("Sequence: test")); 209 211 } 210 212 211 213 /** … … 217 219 TestUtils.assumeWorkingEqualsVerifier(); 218 220 EqualsVerifier.forClass(SequenceCommand.class).usingGetClass() 219 221 .withPrefabValues(Command.class, 220 new AddCommand (ds, new Node(1)), new AddCommand(ds, new Node(2)))222 new AddCommand<>(ds, new Node(1)), new AddCommand<>(ds, new Node(2))) 221 223 .withPrefabValues(DataSet.class, 222 224 new DataSet(), new DataSet()) 223 225 .withPrefabValues(User.class, … … 228 230 .verify(); 229 231 } 230 232 231 private static class TestCommand extends Command {233 private static class TestCommand extends Command<OsmPrimitive, Node, Way, Relation> { 232 234 protected final Collection<? extends OsmPrimitive> primitives; 233 235 protected boolean executed; 234 236
