Ticket #22799: josm22799_smart_distribute_v2.patch
File josm22799_smart_distribute_v2.patch, 5.0 KB (added by , 21 months 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" + 87 "* One no self-crossing way with at most two of its nodes;\n" + 88 "* Three nodes.")) 91 tr("Please select:<ul>" + 92 "<li>One no self-crossing way with at most two of its nodes;</li>" + 93 "<li>One node in the middle of a way;</li>" + 94 "<li>Three nodes.</li></ul>")) 89 95 .setIcon(JOptionPane.INFORMATION_MESSAGE) 90 .setDuration(Notification.TIME_SHORT)91 96 .show(); 92 97 return; 93 98 } … … 185 190 } 186 191 187 192 /** 193 * Test if single node oriented algorithm applies to the selection. 194 * @param nodes The selected node. Collection type and naming kept for compatibility with similar methods. 195 * @return true in this case 196 */ 197 private static boolean checkDistributeNode(Collection<Node> nodes) { 198 if (nodes.size() == 1) { 199 Node node = nodes.iterator().next(); 200 int goodWays = 0; 201 for (Way way : node.getParentWays()) { 202 // the algorithm is applicable only if there is one way which: 203 // - is open and the selected node is a middle node, or 204 // - is closed and has at least 4 nodes (as 3 doesn't make sense and error-prone) 205 if (!way.isFirstLastNode(node) || (way.isClosed() && way.getRealNodesCount() > 3)) 206 goodWays++; 207 } 208 return goodWays == 1; 209 } 210 return false; 211 } 212 213 /** 214 * Distribute a single node relative to way neighbours. 215 * @see DistributeAction#distributeNodes(Collection) 216 * @param nodes nodes to distribute 217 * @return Commands to execute to perform action 218 */ 219 private static Collection<Command> distributeNode(Collection<Node> nodes) { 220 final Node node = nodes.iterator().next(); 221 Way parent = node.getParentWays().iterator().next(); 222 223 // make the user selected node the middle in the output variable 224 nodes.clear(); 225 226 List<Node> neighbours = new ArrayList<>(parent.getNeighbours(node)); 227 228 nodes.add(neighbours.get(0)); 229 nodes.add(node); 230 nodes.add(neighbours.get(1)); 231 232 // call the distribution method with 3 nodes 233 return distributeNodes(nodes); 234 } 235 236 /** 188 237 * Test if nodes oriented algorithm applies to the selection. 189 238 * @param ways Selected ways 190 239 * @param nodes Selected nodes … … 197 246 /** 198 247 * Distribute nodes when only nodes are selected. 199 248 * The general algorithm here is to find the two selected nodes 200 * that are furthest apart, and then to distribute all other selected249 * that are the furthest apart, and then to distribute all other selected 201 250 * nodes along the straight line between these nodes. 202 251 * @param nodes nodes to distribute 203 252 * @return Commands to execute to perform action … … 241 290 // A list of commands to do 242 291 Collection<Command> cmds = new LinkedList<>(); 243 292 244 // Amountof nodes between A and B plus 1293 // Number of nodes between A and B plus 1 245 294 int num = nodes.size()+1; 246 295 247 296 // Current number of node