Changeset 222 in josm for src/org


Ignore:
Timestamp:
2007-04-27T22:26:37+02:00 (17 years ago)
Author:
framm
Message:

Complete overhaul of "Reorder Way" command. Will now also flip segments if required to build a proper way. Work based on patch submitted by eai@….

Location:
src/org/openstreetmap/josm/actions
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/actions/ReorderAction.java

    r184 r222  
    22
    33import static org.openstreetmap.josm.tools.I18n.tr;
     4import static org.openstreetmap.josm.tools.I18n.trn;
    45
    56import java.awt.event.ActionEvent;
    67import java.awt.event.KeyEvent;
    78import java.util.Collection;
    8 import java.util.HashSet;
    99import java.util.Iterator;
    1010import java.util.LinkedList;
     
    1414import org.openstreetmap.josm.Main;
    1515import org.openstreetmap.josm.command.ChangeCommand;
     16import org.openstreetmap.josm.command.Command;
     17import org.openstreetmap.josm.command.SequenceCommand;
     18import org.openstreetmap.josm.data.osm.Node;
    1619import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1720import org.openstreetmap.josm.data.osm.Segment;
    1821import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
    1923
    2024public class ReorderAction extends JosmAction {
    2125
    2226        public ReorderAction() {
    23                 super(tr("Reorder segments"), "reorder", tr("Try to reorder segments of a way so that they are in a line. May try to flip segments around to match a line."), KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK, true);
     27                super(tr("Reorder Segments"), "reorder", tr("Try to reorder segments of a way so that they are in a line. May try to flip segments around to match a line."), KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK, true);
    2428    }
    2529       
     30        /**
     31         * This method first sorts all the segments in a way, then makes sure that all
     32         * the segments are facing the same direction as the first one.
     33         */
    2634        public void actionPerformed(ActionEvent e) {
    2735                Collection<Way> ways = new LinkedList<Way>();
     
    2937                        if (osm instanceof Way)
    3038                                ways.add((Way)osm);
     39               
    3140                if (ways.size() < 1) {
    3241                        JOptionPane.showMessageDialog(Main.parent, tr("Please select at least one way."));
    3342                        return;
    3443                }
     44               
    3545                if (ways.size() > 1) {
    36                         int answer = JOptionPane.showConfirmDialog(Main.parent, tr("You selected more than one way. Reorder the segments of {0} ways?"), tr("Reorder segments"), JOptionPane.OK_CANCEL_OPTION);
     46                        int answer = JOptionPane.showConfirmDialog(Main.parent,
     47                                trn(null, "You selected more than one way. Reorder the segments of {0} ways?", ways.size(), ways.size()),
     48                                tr("Reorder segments"), JOptionPane.OK_CANCEL_OPTION);
    3749                        if (answer != JOptionPane.OK_OPTION)
    3850                                return;
    3951                }
     52                boolean doneSomething = false;
    4053                for (Way way : ways) {
    41                         Way newWay = new Way(way);
    42                         newWay.segments.clear();
    43                         newWay.segments.addAll(sortSegments(new HashSet<Segment>(way.segments)));
    44                         Main.main.editLayer().add(new ChangeCommand(way, newWay));
    45                         Main.map.mapView.repaint();
     54                        if (!way.isIncomplete() && way.segments.size() > 1)
     55                        {                       
     56                                doneSomething = true;
     57                                final LinkedList<Segment> sel = new LinkedList<Segment>(sortSegments(new LinkedList<Segment>(way.segments)));           
     58       
     59                        Collection<Command> c = new LinkedList<Command>();
     60       
     61                        boolean direction = false;
     62                        // work out the "average" direction of the way, we use this to direct the rest of the segments
     63                        int dirCounter = 0;
     64                        for(int i = 0; i < sel.size() - 1; i++)
     65                        {
     66                                Segment firstSegment = sel.get(i);
     67                                Segment secondSegment = sel.get(i+1);
     68                                if ( firstSegment.to == secondSegment.from || firstSegment.to == secondSegment.to ) // direction = true when 'from' is the first node in the Way
     69                                        dirCounter++;
     70                                else
     71                                        dirCounter--;
     72                        }
     73                        if ( dirCounter <= 0 )
     74                                direction = false;
     75                        else
     76                                direction = true;
     77                       
     78                        Node lastNode = null;
     79
     80                        // we need to calculate what the first node in the way is, we work from there
     81                        Segment firstSegment = sel.getFirst();
     82                        Segment secondSegment = sel.get(1);
     83                        if (firstSegment.to == secondSegment.from || firstSegment.to == secondSegment.to)
     84                                lastNode = firstSegment.from;
     85                        else
     86                                lastNode = firstSegment.to;
     87                       
     88                        // go through each segment and flip them if required
     89                        for (Segment s : sel) {
     90                                Segment snew = new Segment(s);
     91                                boolean segDirection = s.from == lastNode;
     92                                // segDirection = true when the 'from' node occurs before the 'to' node in the Way
     93                                if (direction != segDirection)
     94                                {                       
     95                                        // reverse the segment's direction
     96                                        Node n = snew.from;
     97                                        snew.from = snew.to;
     98                                        snew.to = n;
     99                                        c.add(new ChangeCommand(s, snew));
     100                                }       
     101                               
     102                                if (direction) // if its facing forwards,
     103                                        lastNode = snew.to; // our next node is the 'to' one
     104                                else
     105                                        lastNode = snew.from; // otherwise its the 'from' one
     106                        }
     107
     108                        LinkedList<Segment> segments = new LinkedList<Segment>();
     109                       
     110                        // Now we recreate the segment list, in the correct order of the direction
     111                        for (Segment s : sel)
     112                                if (!direction)
     113                                        segments.addFirst(s);
     114                                else
     115                                        segments.addLast(s);
     116                               
     117                        // Check if the new segment list is actually different from the old one
     118                        // before we go and add a change command for it
     119                        for(int i = 0; i < segments.size(); i++)
     120                                if (way.segments.get(i) != segments.get(i))
     121                                {
     122                                        Way newWay = new Way(way);
     123                                        newWay.segments.clear();
     124                                                newWay.segments.addAll(segments);
     125                                                c.add(new ChangeCommand(way, newWay));
     126                                                break;
     127                                }
     128       
     129                        // Check we've got some change commands before we add a sequence command
     130                        if (c.size() != 0) {
     131                                NameVisitor v = new NameVisitor();
     132                                way.visit(v);
     133                                Main.main.editLayer().add(new SequenceCommand(tr("Reorder segments for way {0}",v.name), c));
     134                        }
     135                        }
    46136                }
     137                if (!doneSomething) {
     138                        JOptionPane.showMessageDialog(Main.parent,
     139                                        trn("The selected way is incomplete or has only one segment.",
     140                                                        "None of the selected ways are complete and have more than one segment.",
     141                                                        ways.size()));
     142                }
     143                Main.map.repaint();
    47144        }
    48145
    49146        /**
    50          * sort the segments in best possible order. This is done by:
    51          * 0  if no elements in list, quit
    52          * 1  taking the first ls as pivot, remove it from list
    53          * 2  searching for a connection at from or to of pivot
    54          * 3  if found, attach it, remove it from list, goto 2
    55          * 4  if not found, save the pivot-string and goto 0
     147         * This sort is based on the sort in the old ReorderAction, but it works
     148         * irresepective of the direction of the segments. This produces a sort
     149         * that can be useful even if the segments are facing the wrong direction.
    56150         */
    57         public static LinkedList<Segment> sortSegments(HashSet<Segment> segmentSet) {
     151        public static LinkedList<Segment> sortSegments(LinkedList<Segment> segments) {
     152               
    58153                LinkedList<Segment> sortedSegments = new LinkedList<Segment>();
    59                 LinkedList<Segment> segments = new LinkedList<Segment>(segmentSet);
     154               
    60155                while (!segments.isEmpty()) {
    61156                        LinkedList<Segment> pivotList = new LinkedList<Segment>();
    62157                        pivotList.add(segments.getFirst());
    63158                        segments.removeFirst();
    64                         for (boolean found = true; found;) {
     159                        boolean found;
     160                        do {
    65161                                found = false;
    66162                                for (Iterator<Segment> it = segments.iterator(); it.hasNext();) {
     
    68164                                        if (ls.incomplete)
    69165                                                continue; // incomplete segments are never added to a new way
    70                                         if (ls.from == pivotList.getLast().to) {
     166                                        if (ls.from == pivotList.getLast().to || ls.to == pivotList.getLast().to || ls.from == pivotList.getLast().from || ls.to == pivotList.getLast().from) {
    71167                                                pivotList.addLast(ls);
    72168                                                it.remove();
    73169                                                found = true;
    74                                         } else if (ls.to == pivotList.getFirst().from) {
     170                                        } else if (ls.to == pivotList.getFirst().from || ls.from == pivotList.getFirst().from || ls.to == pivotList.getFirst().to || ls.from == pivotList.getFirst().to) {
    75171                                                pivotList.addFirst(ls);
    76                                                 it.remove();
     172                                                it.remove(); 
    77173                                                found = true;
    78174                                        }
    79175                                }
    80                         }
     176                        } while (found);
    81177                        sortedSegments.addAll(pivotList);
    82178                }
    83179            return sortedSegments;
    84     }
     180        }
    85181}
  • src/org/openstreetmap/josm/actions/ReverseSegmentAction.java

    r184 r222  
    2626
    2727    public ReverseSegmentAction() {
    28         super(tr("Reverse Segments"), "segmentflip", tr("Revert the direction of all selected Segments."), KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
     28        super(tr("Reverse segments"), "segmentflip", tr("Reverse the direction of all selected Segments."), KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK, true);
    2929    }
    3030
  • src/org/openstreetmap/josm/actions/mapmode/AddWayAction.java

    r203 r222  
    9292                                for (Segment seg : way.segments) {
    9393                                        if (seg.incomplete) {
    94                                                 JOptionPane.showMessageDialog(Main.parent,tr("Warning: This way is incomplete. Try to download it, before adding segments."));
     94                                                JOptionPane.showMessageDialog(Main.parent,tr("Warning: This way is incomplete. Try to download it before adding segments."));
    9595                                                return;
    9696                                        }
     
    140140                        for (Segment seg : way.segments) {
    141141                                if (seg.incomplete) {
    142                                         JOptionPane.showMessageDialog(Main.parent, tr("Warning: This way is incomplete. Try to download it, before adding segments."));
     142                                        JOptionPane.showMessageDialog(Main.parent, tr("Warning: This way is incomplete. Try to download it before adding segments."));
    143143                                        break;
    144144                                }
     
    188188                        return null;
    189189
    190                 LinkedList<Segment> sortedSegments = ReorderAction.sortSegments(segmentSet);
     190                LinkedList<Segment> rawSegments = new LinkedList<Segment>(segmentSet);
     191                LinkedList<Segment> sortedSegments = ReorderAction.sortSegments(rawSegments);
    191192
    192193                if (wayToAdd != null) {
Note: See TracChangeset for help on using the changeset viewer.