Ticket #22799: josm22799_smart_distribute.patch
| File josm22799_smart_distribute.patch, 4.9 KB (added by , 3 years ago) |
|---|
-
src/org/openstreetmap/josm/actions/DistributeAction.java
6 6 7 7 import java.awt.event.ActionEvent; 8 8 import java.awt.event.KeyEvent; 9 import java.util.ArrayList; 9 10 import java.util.Collection; 10 11 import java.util.HashSet; 11 12 import java.util.Iterator; … … 49 50 * Select method according to user selection. 50 51 * Case 1: One Way (no self-crossing) and at most 2 nodes contains by this way: 51 52 * Distribute nodes keeping order along the way 52 * Case 2: Other 53 * Case 2: One Node part of at least one way, not a start or end node 54 * Distribute the selected node relative to neighbors 55 * Case 3: Other 53 56 * Distribute nodes 54 57 */ 55 58 @Override … … 59 62 60 63 // Collect user selected objects 61 64 Collection<OsmPrimitive> selected = getLayerManager().getEditDataSet().getSelected(); 62 Collection<Way> ways = new LinkedList<>();63 Collection<Node> nodes = new HashSet<>();65 Collection<Way> ways = new ArrayList<>(); 66 Collection<Node> nodes = new ArrayList<>(); 64 67 for (OsmPrimitive osm : selected) { 65 68 if (osm instanceof Node) { 66 69 nodes.add((Node) osm); … … 81 84 cmds = distributeWay(ways, nodes); 82 85 } else if (checkDistributeNodes(ways, nodes)) { 83 86 cmds = distributeNodes(nodes); 87 } else if (checkDistributeNode(nodes)){ 88 cmds = distributeNode(nodes); 84 89 } else { 85 90 new Notification( 86 tr("Please select :\n" +91 tr("Please select:\n" + 87 92 "* One no self-crossing way with at most two of its nodes;\n" + 88 "* Three nodes.")) 93 "* One node in the middle of a way;\n" + 94 "* A way with at least three nodes;\n" + 95 "* Three nodes")) 89 96 .setIcon(JOptionPane.INFORMATION_MESSAGE) 90 97 .setDuration(Notification.TIME_SHORT) 91 98 .show(); … … 185 192 } 186 193 187 194 /** 195 * Test if single node oriented algorithm applies to the selection. 196 * @param nodes The selected node. Collection type and naming kept for compatibility with similar methods. 197 * @return true in this case 198 */ 199 private static boolean checkDistributeNode(Collection<Node> nodes) { 200 if (nodes.size() == 1) { 201 Node node = nodes.iterator().next(); 202 int goodWays = 0; 203 for (Way way : node.getParentWays()) { 204 // the algorithm is applicable only if there is one way which: 205 // - is open and the selected node is a middle node, or 206 // - is closed (and has at least 4 nodes as 3 doesn't make sense and error-prone) 207 if (!way.isFirstLastNode(node) || (way.isClosed() && way.getRealNodesCount() > 3)) 208 goodWays++; 209 } 210 return goodWays == 1; 211 } 212 return false; 213 } 214 215 /** 216 * Distribute a single node relative to way neighbours. 217 * @see DistributeAction#distributeNodes(Collection) 218 * @param nodes nodes to distribute 219 * @return Commands to execute to perform action 220 */ 221 private static Collection<Command> distributeNode(Collection<Node> nodes) { 222 final Node node = nodes.iterator().next(); 223 Way parent = node.getParentWays().iterator().next(); 224 225 // make the user selected node the middle in the output variable 226 nodes.clear(); 227 List<Node> neighbours = new ArrayList<>(4); 228 neighbours.addAll(parent.getNeighbours(node)); 229 230 nodes.add(neighbours.get(0)); 231 nodes.add(node); 232 nodes.add(neighbours.get(1)); 233 234 // call the distribution method with 3 nodes 235 return distributeNodes(nodes); 236 } 237 238 /** 188 239 * Test if nodes oriented algorithm applies to the selection. 189 240 * @param ways Selected ways 190 241 * @param nodes Selected nodes … … 197 248 /** 198 249 * Distribute nodes when only nodes are selected. 199 250 * The general algorithm here is to find the two selected nodes 200 * that are furthest apart, and then to distribute all other selected251 * that are the furthest apart, and then to distribute all other selected 201 252 * nodes along the straight line between these nodes. 202 253 * @param nodes nodes to distribute 203 254 * @return Commands to execute to perform action … … 241 292 // A list of commands to do 242 293 Collection<Command> cmds = new LinkedList<>(); 243 294 244 // Amountof nodes between A and B plus 1295 // Number of nodes between A and B plus 1 245 296 int num = nodes.size()+1; 246 297 247 298 // Current number of node
