Changeset 359 in josm


Ignore:
Timestamp:
2007-10-11T14:02:42+02:00 (17 years ago)
Author:
gebner
Message:

Insert a node into multiple ways.

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

Legend:

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

    r358 r359  
    1111import java.util.Collections;
    1212import java.util.HashMap;
     13import java.util.HashSet;
     14import java.util.Map;
    1315import java.util.LinkedList;
     16import java.util.List;
    1417
    1518import javax.swing.JOptionPane;
     
    8083                Collection<Command> cmds = new LinkedList<Command>();
    8184
    82                 Way reuseWay = null, replacedWay = null;
     85                ArrayList<Way> reuseWays = new ArrayList<Way>(),
     86                        replacedWays = new ArrayList<Way>();
    8387                boolean newNode = false;
    8488                Node n = Main.map.mapView.getNearestNode(e.getPoint());
     
    9498                        cmds.add(new AddCommand(n));
    9599
    96                         WaySegment ws = Main.map.mapView.getNearestWaySegment(e.getPoint());
    97                         if (ws != null) {
    98                                 replacedWay = ws.way;
    99                                 reuseWay = splitWaySegmentAtNode(ws, n, cmds);
     100                        // Insert the node into all the nearby way segments
     101                        List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(e.getPoint());
     102                        Map<Way, List<Integer>> insertPoints = new HashMap<Way, List<Integer>>();
     103                        for (WaySegment ws : wss) {
     104                                List<Integer> is;
     105                                if (insertPoints.containsKey(ws.way)) {
     106                                        is = insertPoints.get(ws.way);
     107                                } else {
     108                                        is = new ArrayList<Integer>();
     109                                        insertPoints.put(ws.way, is);
     110                                }
     111
     112                                is.add(ws.lowerIndex);
     113                        }
     114                        for (Map.Entry<Way, List<Integer>> insertPoint : insertPoints.entrySet()) {
     115                                Way w = insertPoint.getKey();
     116                                List<Integer> is = insertPoint.getValue();
     117
     118                                Way wnew = new Way(w);
     119
     120                                pruneSuccsAndReverse(is);
     121                                for (int i : is) wnew.nodes.add(i + 1, n);
     122
     123                                cmds.add(new ChangeCommand(insertPoint.getKey(), wnew));
     124                                replacedWays.add(insertPoint.getKey());
     125                                reuseWays.add(wnew);
    100126                        }
    101127                }
     
    111137                                cmds.add(new AddCommand(way));
    112138                        } else {
    113                                 if (way == replacedWay) {
    114                                         way = reuseWay;
     139                                int i;
     140                                if ((i = replacedWays.indexOf(way)) != -1) {
     141                                        way = reuseWays.get(i);
    115142                                } else {
    116143                                        Way wnew = new Way(way);
     
    133160                        return; // We didn't do anything.
    134161                } else if (!extendedWay) {
    135                         if (reuseWay == null) {
     162                        if (reuseWays.isEmpty()) {
    136163                                title = tr("Add node");
    137164                        } else {
     
    140167                } else if (!newNode) {
    141168                        title = tr("Connect existing way to node");
    142                 } else if (reuseWay == null) {
     169                } else if (reuseWays.isEmpty()) {
    143170                        title = tr("Add a new node to an existing way");
    144171                } else {
     
    171198                return way;
    172199        }
    173        
    174         private Way splitWaySegmentAtNode(WaySegment ws, Node n, Collection<Command> cmds) {
    175                 Way wnew = new Way(ws.way);
    176                 wnew.nodes.add(ws.lowerIndex + 1, n);
    177                 cmds.add(new ChangeCommand(ws.way, wnew));
    178                 return wnew;
     200
     201        private static void pruneSuccsAndReverse(List<Integer> is) {
     202                //if (is.size() < 2) return;
     203
     204                HashSet<Integer> is2 = new HashSet<Integer>();
     205                for (int i : is) {
     206                        if (!is2.contains(i - 1) && !is2.contains(i + 1)) {
     207                                is2.add(i);
     208                        }
     209                }
     210                is.clear();
     211                is.addAll(is2);
     212                Collections.sort(is);
     213                Collections.reverse(is);
    179214        }
    180215}
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r357 r359  
    55import java.util.Collection;
    66import java.util.HashSet;
     7import java.util.TreeMap;
     8import java.util.List;
     9import java.util.ArrayList;
    710
    811import javax.swing.JComponent;
     
    145148
    146149        /**
    147          * @return the nearest way segment to the screen point given that is not
    148          * in ignore.
     150         * @return all way segments within 10px of p, sorted by their
     151         * perpendicular distance.
    149152         *
    150153         * @param p the point for which to search the nearest segment.
    151          * @param ignore a collection of segments which are not to be returned.
    152          * May be null.
    153          */
    154         public final WaySegment getNearestWaySegment(Point p, Collection<WaySegment> ignore) {
    155                 Way minPrimitive = null;
    156                 int minI = 0;
    157                 double minDistanceSq = Double.MAX_VALUE;
     154         */
     155        public final List<WaySegment> getNearestWaySegments(Point p) {
     156                TreeMap<Double, WaySegment> nearest = new TreeMap<Double, WaySegment>();
    158157                for (Way w : Main.ds.ways) {
    159158                        if (w.deleted)
     
    168167                                        continue;
    169168                                }
    170                                 if (ignore == null || !ignore.contains(new WaySegment(w, i))) {
    171                                         Point A = getPoint(lastN.eastNorth);
    172                                         Point B = getPoint(n.eastNorth);
    173                                         double c = A.distanceSq(B);
    174                                         double a = p.distanceSq(B);
    175                                         double b = p.distanceSq(A);
    176                                         double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
    177                                         if (perDist < 100 && minDistanceSq > perDist && a < c+100 && b < c+100) {
    178                                                 minDistanceSq = perDist;
    179                                                 minPrimitive = w;
    180                                                 minI = i;
    181                                         }
    182                                 }
     169
     170                                Point A = getPoint(lastN.eastNorth);
     171                                Point B = getPoint(n.eastNorth);
     172                                double c = A.distanceSq(B);
     173                                double a = p.distanceSq(B);
     174                                double b = p.distanceSq(A);
     175                                double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
     176                                if (perDist < 100 && a < c+100 && b < c+100) {
     177                                        nearest.put(perDist, new WaySegment(w, i));
     178                                }
     179
    183180                                lastN = n;
    184181                        }
    185182                }
    186                 return minPrimitive == null ? null : new WaySegment(minPrimitive, minI);
     183                return new ArrayList<WaySegment>(nearest.values());
     184        }
     185
     186        /**
     187         * @return the nearest way segment to the screen point given that is not
     188         * in ignore.
     189         *
     190         * @param p the point for which to search the nearest segment.
     191         * @param ignore a collection of segments which are not to be returned.
     192         * May be null.
     193         */
     194        public final WaySegment getNearestWaySegment(Point p, Collection<WaySegment> ignore) {
     195                List<WaySegment> nearest = getNearestWaySegments(p);
     196                if (ignore != null) nearest.removeAll(ignore);
     197                return nearest.isEmpty() ? null : nearest.get(0);
    187198        }
    188199
Note: See TracChangeset for help on using the changeset viewer.