Changeset 3642 in josm


Ignore:
Timestamp:
2010-10-28T16:40:22+02:00 (9 years ago)
Author:
bastiK
Message:

fixed #5561 (patch by cmuelle8) - wrong node selected after "unglue way"

Location:
trunk/src/org/openstreetmap/josm
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java

    r3594 r3642  
    341341        OsmPrimitive osm = null;
    342342
    343         if (single == null) {
    344             single = MapView.asColl(
    345                     mv.getNearestNodeOrWay(e.getPoint(), OsmPrimitive.isSelectablePredicate, false));
    346         }
    347 
    348         if (!single.isEmpty()) {
     343        if (single != null && !single.isEmpty()) {
     344            osm = single.iterator().next();
     345
     346            Point p = e.getPoint();
    349347            boolean waitForMouseUp = Main.pref.getBoolean("mappaint.select.waits-for-mouse-up", false);
    350348            boolean ctrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0;
     
    352350                    || Main.pref.getBoolean("selectaction.cycles.multiple.matches", false));
    353351
    354             Point p = e.getPoint();
    355             osm = single.iterator().next();
    356 
    357352            if (!alt) {
    358353                cycleList = MapView.asColl(osm);
     354
    359355                if (waitForMouseUp) {
    360                     // find a selected nearest node or way, not the true nearest..
     356                    // prefer a selected nearest node or way, if possible
    361357                    osm = mv.getNearestNodeOrWay(p, OsmPrimitive.isSelectablePredicate, true);
    362358                }
     
    368364                }
    369365
    370                 if (!waitForMouseUp && cycleList.size()>1) {
     366                if (cycleList.size()>1) {
    371367                    cyclePrims = false;
    372368
     
    380376                    }
    381377
    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)) {
    387382                            cyclePrims = false;
    388383                            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                         */
    390390                    }
    391391                }
  • trunk/src/org/openstreetmap/josm/gui/MapStatus.java

    r3629 r3642  
    300300         */
    301301        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);
    303303            if (osmNearest != null) {
    304304                nameText.setText(osmNearest.getDisplayName(DefaultNameFormatter.getInstance()));
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r3600 r3642  
    560560
    561561    /**
    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.
    563563     *
    564564     * If more than one node within node.snap-distance pixels is found,
    565      * the nearest node selected is returned.
    566      *
    567      * If no such node is found, the nearest new/id=0 node within
    568      * about the same distance as the true nearest node is returned.
     565     * the nearest node selected is returned IF use_selected is true.
     566     *
     567     * Else the nearest new/id=0 node within about the same distance
     568     * as the true nearest node is returned.
    569569     *
    570570     * If no such node is found either, the true nearest
    571571     * node to p is returned.
    572572     *
    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.
    574574     *
    575575     * @return A node within snap-distance to point p,
     
    580580     *        give the nearest node that is tagged.
    581581     */
    582     public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate) {
     582    public final Node getNearestNode(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) {
    583583        Node n = null;
    584584
     
    603603
    604604            // 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));
    607608        }
    608609
    609610        return n;
     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);
    610620    }
    611621
     
    731741
    732742    /**
    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.
    734744     *
    735745     * @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.
    737747     * @see #getNearestWaySegments(Point, Collection, Predicate)
    738748     *
    739749     * @param p the point for which to search the nearest segment.
    740750     * @param predicate the returned object has to fulfill certain properties.
    741      */
    742     public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate) {
     751     * @param use_selected whether selected way segments should be preferred.
     752     */
     753    public final WaySegment getNearestWaySegment(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) {
    743754        WaySegment wayseg = null, ntsel = null;
    744755
     
    757768        }
    758769
    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);
    760780    }
    761781
     
    883903    /**
    884904     * This is used as a helper routine to {@link #getNearestNodeOrWay(Point, Predicate, boolean)}
    885      *
    886      * @return true, if the node fulfills certain properties wrt p and use_sel
     905     * It decides, whether to yield the node to be tested or look for further (way) candidates.
     906     *
     907     * @return true, if the node fulfills the properties of the function body
    887908     *
    888909     * @param osm node to check
    889910     * @param p point clicked
    890      * @param use_sel whether to prefer a selected node
     911     * @param use_selected whether to prefer selected nodes
    891912     */
    892913    private boolean isPrecedenceNode(Node osm, Point p, boolean use_selected) {
     
    930951     */
    931952    public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate, boolean use_selected) {
    932         OsmPrimitive osm = null;
     953        OsmPrimitive osm = getNearestNode(p, predicate, use_selected);
    933954        WaySegment ws = null;
    934955
    935         // find a nearest, selected primitive
    936         if (use_selected) {
    937             osm = getNearestNode(p, predicate);
    938             use_selected = isPrecedenceNode((Node)osm, p, use_selected);
    939 
    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;
     956        if (!isPrecedenceNode((Node)osm, p, use_selected)) {
     957            ws = getNearestWaySegment(p, predicate, use_selected);
     958
     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;
     963                } else {
     964                    int maxWaySegLenSq = 3*PROP_SNAP_DISTANCE.get();
     965                    maxWaySegLenSq *= maxWaySegLenSq;
     966
     967                    Point2D wp1 = getPoint2D(ws.way.getNode(ws.lowerIndex));
     968                    Point2D wp2 = getPoint2D(ws.way.getNode(ws.lowerIndex+1));
     969
     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))) {
    946974                        osm = ws.way;
    947                     } // else { unselected node and wayseg found, do the stuff below }
    948                 } else {
    949                     // no nearest wayseg found, osm is null or the nearest node
    950                     use_selected = true;
    951                 }
    952             }
    953         }
    954 
    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             }
    964 
    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;
    972975                    }
    973976                }
    974                 if (ws != null) {
    975                     if (osm == null) {
    976                         // a nearest node was not found
    977                         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 and
    986                         // 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                     }
    992                 }
    993977            }
    994978        }
    995979
    996980        return osm;
    997     }
    998 
    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);
    1006981    }
    1007982
  • trunk/src/org/openstreetmap/josm/gui/SelectionManager.java

    r3594 r3642  
    274274
    275275        if (clicked) {
    276             OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate);
     276            OsmPrimitive osm = nc.getNearestNodeOrWay(center, OsmPrimitive.isSelectablePredicate, false);
    277277            if (osm != null) {
    278278                selection.add(osm);
Note: See TracChangeset for help on using the changeset viewer.