Ticket #5561: fix-unglue-ways-cleanup-code.patch
File fix-unglue-ways-cleanup-code.patch, 14.2 KB (added by , 13 years ago) |
---|
-
src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
340 340 private Collection<OsmPrimitive> cycleSetup(Collection<OsmPrimitive> single, MouseEvent e) { 341 341 OsmPrimitive osm = null; 342 342 343 if (single == null) { 344 single = MapView.asColl( 345 mv.getNearestNodeOrWay(e.getPoint(), OsmPrimitive.isSelectablePredicate, false)); 346 } 343 if (single != null && !single.isEmpty()) { 344 osm = single.iterator().next(); 347 345 348 if (!single.isEmpty()) {346 Point p = e.getPoint(); 349 347 boolean waitForMouseUp = Main.pref.getBoolean("mappaint.select.waits-for-mouse-up", false); 350 348 boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; 351 349 boolean alt = ((e.getModifiers() & (ActionEvent.ALT_MASK|InputEvent.ALT_GRAPH_MASK)) != 0 352 350 || Main.pref.getBoolean("selectaction.cycles.multiple.matches", false)); 353 351 354 Point p = e.getPoint();355 osm = single.iterator().next();356 357 352 if (!alt) { 358 353 cycleList = MapView.asColl(osm); 354 359 355 if (waitForMouseUp) { 360 // find a selected nearest node or way, not the true nearest..356 // prefer a selected nearest node or way, if possible 361 357 osm = mv.getNearestNodeOrWay(p, OsmPrimitive.isSelectablePredicate, true); 362 358 } 363 359 } else { … … 367 363 cycleList = new LinkedList<OsmPrimitive>(mv.getNearestWays(p, OsmPrimitive.isSelectablePredicate)); 368 364 } 369 365 370 if ( !waitForMouseUp &&cycleList.size()>1) {366 if (cycleList.size()>1) { 371 367 cyclePrims = false; 372 368 373 369 OsmPrimitive old = osm; … … 379 375 } 380 376 } 381 377 382 // for cycle groups of 2, we can toggle to the true nearest 383 // primitive on mouse presses, if it is not selected and if ctrl is not used 384 // else, if rotation is possible, defer sel change to mouse release 385 if (cycleList.size()==2) { 386 if (!(old.equals(osm) || ctrl)) { 378 // special case: for cycle groups of 2, we can toggle to the 379 // true nearest primitive on mousePressed right away 380 if (cycleList.size()==2 && !waitForMouseUp) { 381 if (!(osm.equals(old) || osm.isNew() || ctrl)) { 387 382 cyclePrims = false; 388 383 osm = old; 389 } 384 } // else defer toggling to mouseRelease time in those cases: 385 /* 386 * osm == old -- the true nearest node is the selected one 387 * osm is a new node -- do not break unglue ways in ALT mode 388 * ctrl is pressed -- ctrl generally works on mouseReleased 389 */ 390 390 } 391 391 } 392 392 } -
src/org/openstreetmap/josm/gui/SelectionManager.java
273 273 Point center = new Point(r.x+r.width/2, r.y+r.height/2); 274 274 275 275 if (clicked) { 276 OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate );276 OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate, false); 277 277 if (osm != null) { 278 278 selection.add(osm); 279 279 } -
src/org/openstreetmap/josm/gui/NavigatableComponent.java
559 559 } 560 560 561 561 /** 562 * The *result* depends on the current map selection state .562 * The *result* depends on the current map selection state IF use_selected is true. 563 563 * 564 564 * If more than one node within node.snap-distance pixels is found, 565 * the nearest node selected is returned .565 * the nearest node selected is returned IF use_selected is true. 566 566 * 567 * If no such node is found, the nearest new/id=0 node within568 * a bout the same distance as the true nearest node is returned.567 * Else the nearest new/id=0 node within about the same distance 568 * as the true nearest node is returned. 569 569 * 570 570 * If no such node is found either, the true nearest 571 571 * node to p is returned. 572 572 * 573 * Finally, if a node is not found at all, return null.573 * Finally, if a node is not found at all, null is returned. 574 574 * 575 575 * @return A node within snap-distance to point p, 576 576 * that is chosen by the algorithm described. … … 579 579 * @param predicate this parameter imposes a condition on the returned object, e.g. 580 580 * give the nearest node that is tagged. 581 581 */ 582 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate ) {582 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) { 583 583 Node n = null; 584 584 585 585 Map<Double, List<Node>> nlists = getNearestNodesImpl(p, predicate); … … 602 602 } 603 603 604 604 // take nearest selected, nearest new or true nearest node to p, in that order 605 n = (ntsel != null) ? ntsel : ((ntnew != null) ? ntnew 606 : nlists.values().iterator().next().get(0)); 605 n = (ntsel != null && use_selected) ? ntsel 606 : ((ntnew != null) ? ntnew 607 : nlists.values().iterator().next().get(0)); 607 608 } 608 609 609 610 return n; 610 611 } 611 612 613 /** 614 * Convenience method to {@link #getNearestNode(Point, Predicate, boolean)}. 615 * 616 * @return The nearest node to point p. 617 */ 618 public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate) { 619 return getNearestNode(p, predicate, true); 620 } 621 612 622 @Deprecated 613 623 public final Node getNearestNode(Point p) { 614 624 return getNearestNode(p, OsmPrimitive.isUsablePredicate); … … 730 740 } 731 741 732 742 /** 733 * The *result* depends on the current map selection state .743 * The *result* depends on the current map selection state IF use_selected is true. 734 744 * 735 745 * @return The nearest way segment to point p, 736 * prefer a nearest,selected way segment, if found.746 * and, depending on use_selected, prefers a selected way segment, if found. 737 747 * @see #getNearestWaySegments(Point, Collection, Predicate) 738 748 * 739 749 * @param p the point for which to search the nearest segment. 740 750 * @param predicate the returned object has to fulfill certain properties. 751 * @param use_selected whether selected way segments should be preferred. 741 752 */ 742 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate ) {753 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) { 743 754 WaySegment wayseg = null, ntsel = null; 744 755 745 756 for (List<WaySegment> wslist : getNearestWaySegmentsImpl(p, predicate).values()) { … … 756 767 } 757 768 } 758 769 759 return (ntsel != null) ? ntsel : wayseg; 770 return (ntsel != null && use_selected) ? ntsel : wayseg; 771 } 772 773 /** 774 * Convenience method to {@link #getNearestWaySegment(Point, Predicate, boolean)}. 775 * 776 * @return The nearest way segment to point p. 777 */ 778 public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate) { 779 return getNearestWaySegment(p, predicate, true); 760 780 } 761 781 762 782 /** … … 882 902 883 903 /** 884 904 * This is used as a helper routine to {@link #getNearestNodeOrWay(Point, Predicate, boolean)} 905 * It decides, whether to yield the node to be tested or look for further (way) candidates. 885 906 * 886 * @return true, if the node fulfills certain properties wrt p and use_sel907 * @return true, if the node fulfills the properties of the function body 887 908 * 888 909 * @param osm node to check 889 910 * @param p point clicked 890 * @param use_sel whether to prefer a selected node911 * @param use_selected whether to prefer selected nodes 891 912 */ 892 913 private boolean isPrecedenceNode(Node osm, Point p, boolean use_selected) { 893 914 boolean ret = false; … … 929 950 * @param use_selected whether to prefer primitives that are currently selected. 930 951 */ 931 952 public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) { 932 OsmPrimitive osm = null;953 OsmPrimitive osm = getNearestNode(p, predicate, use_selected); 933 954 WaySegment ws = null; 934 955 935 // find a nearest, selected primitive 936 if (use_selected) { 937 osm = getNearestNode(p, predicate); 938 use_selected = isPrecedenceNode((Node)osm, p, use_selected); 956 if (!isPrecedenceNode((Node)osm, p, use_selected)) { 957 ws = getNearestWaySegment(p, predicate, use_selected); 939 958 940 if (!use_selected) { 941 ws = getNearestWaySegment(p, predicate); 942 if (ws != null) { 943 if (ws.way.isSelected() || osm == null) { 944 // either no nearest nodes found or none were selected 945 use_selected = true; 946 osm = ws.way; 947 } // else { unselected node and wayseg found, do the stuff below } 959 if (ws != null) { 960 if ((ws.way.isSelected() && use_selected) || osm == null) { 961 // either (no _selected_ nearest node found, if desired) or no nearest node was found 962 osm = ws.way; 948 963 } else { 949 // no nearest wayseg found, osm is null or the nearest node 950 use_selected = true; 951 } 952 } 953 } 964 int maxWaySegLenSq = 3*PROP_SNAP_DISTANCE.get(); 965 maxWaySegLenSq *= maxWaySegLenSq; 954 966 955 // no nearest, selected primitive was found or caller does not care about current selection 956 if (!use_selected) { 957 if (osm == null) { 958 // get the true nearest node (if unselected found before, reuse it) 959 for (List<Node> nlist : getNearestNodesImpl(p, predicate).values()) { 960 osm = nlist.get(0); 961 break; 962 } 963 } 967 Point2D wp1 = getPoint2D(ws.way.getNode(ws.lowerIndex)); 968 Point2D wp2 = getPoint2D(ws.way.getNode(ws.lowerIndex+1)); 964 969 965 // there is no nearest node OR it does not fulfill criteria to simply be chosen 966 if (osm == null || !isPrecedenceNode((Node)osm, p, use_selected)) { 967 if (ws == null) { 968 // get the true nearest wayseg (if unselected found before, reuse it) 969 for (WaySegment wseg : getNearestWaySegments(p, predicate)) { 970 ws = wseg; 971 break; 972 } 973 } 974 if (ws != null) { 975 if (osm == null) { 976 // a nearest node was not found 970 // is wayseg shorter than maxWaySegLenSq and 971 // is p closer to the middle of wayseg than to the nearest node? 972 if (wp1.distanceSq(wp2) < maxWaySegLenSq && 973 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D((Node)osm))) { 977 974 osm = ws.way; 978 } else {979 int maxWaySegLenSq = 3*PROP_SNAP_DISTANCE.get();980 maxWaySegLenSq *= maxWaySegLenSq;981 982 Point2D wp1 = getPoint2D(ws.way.getNode(ws.lowerIndex));983 Point2D wp2 = getPoint2D(ws.way.getNode(ws.lowerIndex+1));984 985 // is wayseg shorter than maxWaySegLenSq and986 // is p closer to the middle of wayseg than to the nearest node?987 if (wp1.distanceSq(wp2) < maxWaySegLenSq &&988 p.distanceSq(project(0.5, wp1, wp2)) < p.distanceSq(getPoint2D((Node)osm))) {989 osm = ws.way;990 }991 975 } 992 976 } 993 977 } … … 996 980 return osm; 997 981 } 998 982 999 /**1000 * Convenience method to {@link #getNearestNodeOrWay(Point, Predicate, boolean)}.1001 *1002 * @return The nearest primitive to point p.1003 */1004 public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate) {1005 return getNearestNodeOrWay(p, predicate, false);1006 }1007 1008 983 @Deprecated 1009 984 public final OsmPrimitive getNearest(Point p, Predicate<OsmPrimitive> predicate) { 1010 985 return getNearestNodeOrWay(p, predicate, false); -
src/org/openstreetmap/josm/gui/MapStatus.java
299 299 * @param ms 300 300 */ 301 301 private final void statusBarElementUpdate(MouseState ms) { 302 final OsmPrimitive osmNearest = mv.getNearestNodeOrWay(ms.mousePos, OsmPrimitive.isUsablePredicate );302 final OsmPrimitive osmNearest = mv.getNearestNodeOrWay(ms.mousePos, OsmPrimitive.isUsablePredicate, false); 303 303 if (osmNearest != null) { 304 304 nameText.setText(osmNearest.getDisplayName(DefaultNameFormatter.getInstance())); 305 305 } else {