Changeset 335 in josm for branch/0.5/src


Ignore:
Timestamp:
2007-09-30T01:44:08+02:00 (17 years ago)
Author:
gebner
Message:

CombineWayAction: Reorder ways if that makes it possible to combine them.

Location:
branch/0.5/src/org/openstreetmap/josm
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branch/0.5/src/org/openstreetmap/josm/actions/CombineWayAction.java

    r329 r335  
    7373                        }
    7474                }
    75                
    76                 // Battle plan:
    77                 //  1. Split the ways into small chunks of 2 nodes and weed out
    78                 //         duplicates.
    79                 //  2. Take a chunk and see if others could be appended or prepended,
    80                 //         if so, do it and remove it from the list of remaining chunks.
    81                 //         Rather, rinse, repeat.
    82                 //  3. If this algorithm does not produce a single way,
    83                 //     complain to the user.
    84                 //  4. Profit!
    85                
    86                 HashSet<NodePair> chunkSet = new HashSet<NodePair>();
    87                 for (Way w : selectedWays) {
    88                         if (w.nodes.size() == 0) continue;
    89                         Node lastN = null;
    90                         for (Node n : w.nodes) {
    91                                 if (lastN == null) {
    92                                         lastN = n;
    93                                         continue;
    94                                 }
    95                                 chunkSet.add(new NodePair(lastN, n));
    96                                 lastN = n;
    97                         }
    98                 }
    99                 LinkedList<NodePair> chunks = new LinkedList<NodePair>(chunkSet);
    100 
    101                 if (chunks.isEmpty()) {
    102                         JOptionPane.showMessageDialog(Main.parent, tr("All the ways were empty"));
    103                         return;
    104                 }
    105 
    106                 List<Node> nodeList = chunks.poll().toArrayList();
    107                 while (!chunks.isEmpty()) {
    108                         ListIterator<NodePair> it = chunks.listIterator();
    109                         boolean foundChunk = false;
    110                         while (it.hasNext()) {
    111                                 NodePair curChunk = it.next();
    112                                 if (curChunk.a == nodeList.get(nodeList.size() - 1)) { // append
    113                                         nodeList.add(curChunk.b);
    114                                         foundChunk = true;
    115                                 } else if (curChunk.b == nodeList.get(0)) { // prepend
    116                                         nodeList.add(0, curChunk.a);
    117                                         foundChunk = true;
    118                                 }
    119                                 if (foundChunk) {
    120                                         it.remove();
    121                                         break;
    122                                 }
    123                         }
    124                         if (!foundChunk) break;
    125                 }
    126 
    127                 if (!chunks.isEmpty()) {
    128                         JOptionPane.showMessageDialog(Main.parent,
    129                                 tr("Could not combine ways (Hint: ways have to point into the same direction)"));
    130                         return;
     75
     76                List<Node> nodeList = null;
     77                Object firstTry = actuallyCombineWays(selectedWays, false);
     78                if (firstTry instanceof List) {
     79                        nodeList = (List<Node>) firstTry;
     80                } else {
     81                        Object secondTry = actuallyCombineWays(selectedWays, true);
     82                        if (secondTry instanceof List) {
     83                                int option = JOptionPane.showConfirmDialog(Main.parent,
     84                                        tr("The ways can not be combined in their current directions.  "
     85                                        + "Do you want to reverse some of them?"), tr("Change directions?"),
     86                                        JOptionPane.YES_NO_OPTION);
     87                                if (option != JOptionPane.YES_OPTION) {
     88                                        return;
     89                                }
     90                                nodeList = (List<Node>) secondTry;
     91                        } else {
     92                                JOptionPane.showMessageDialog(Main.parent, (String) secondTry);
     93                                return;
     94                        }
    13195                }
    13296
     
    165129
    166130        /**
     131         * @return a message if combining failed, else a list of nodes.
     132         */
     133        private Object actuallyCombineWays(List<Way> ways, boolean ignoreDirection) {
     134                // Battle plan:
     135                //  1. Split the ways into small chunks of 2 nodes and weed out
     136                //         duplicates.
     137                //  2. Take a chunk and see if others could be appended or prepended,
     138                //         if so, do it and remove it from the list of remaining chunks.
     139                //         Rather, rinse, repeat.
     140                //  3. If this algorithm does not produce a single way,
     141                //     complain to the user.
     142                //  4. Profit!
     143               
     144                HashSet<NodePair> chunkSet = new HashSet<NodePair>();
     145                for (Way w : ways) {
     146                        if (w.nodes.size() == 0) continue;
     147                        Node lastN = null;
     148                        for (Node n : w.nodes) {
     149                                if (lastN == null) {
     150                                        lastN = n;
     151                                        continue;
     152                                }
     153
     154                                NodePair np = new NodePair(lastN, n);
     155                                if (ignoreDirection) {
     156                                        np.sort();
     157                                }
     158                                chunkSet.add(np);
     159
     160                                lastN = n;
     161                        }
     162                }
     163                LinkedList<NodePair> chunks = new LinkedList<NodePair>(chunkSet);
     164
     165                if (chunks.isEmpty()) {
     166                        return tr("All the ways were empty");
     167                }
     168
     169                List<Node> nodeList = chunks.poll().toArrayList();
     170                while (!chunks.isEmpty()) {
     171                        ListIterator<NodePair> it = chunks.listIterator();
     172                        boolean foundChunk = false;
     173                        while (it.hasNext()) {
     174                                NodePair curChunk = it.next();
     175                                if (curChunk.a == nodeList.get(nodeList.size() - 1)) { // append
     176                                        nodeList.add(curChunk.b);
     177                                } else if (curChunk.b == nodeList.get(0)) { // prepend
     178                                        nodeList.add(0, curChunk.a);
     179                                } else if (ignoreDirection && curChunk.b == nodeList.get(nodeList.size() - 1)) { // append
     180                                        nodeList.add(curChunk.a);
     181                                } else if (ignoreDirection && curChunk.a == nodeList.get(0)) { // prepend
     182                                        nodeList.add(0, curChunk.b);
     183                                } else {
     184                                        continue;
     185                                }
     186
     187                                foundChunk = true;
     188                                it.remove();
     189                                break;
     190                        }
     191                        if (!foundChunk) break;
     192                }
     193
     194                if (!chunks.isEmpty()) {
     195                        return tr("Could not combine ways "
     196                                + "(They could not be merged into a single string of nodes)");
     197                } else {
     198                        return nodeList;
     199                }
     200        }
     201
     202        /**
    167203         * Enable the "Combine way" menu option if more then one way is selected
    168204         */
  • branch/0.5/src/org/openstreetmap/josm/data/osm/NodePair.java

    r330 r335  
    3030                return l;
    3131        }
     32
     33        public void sort() {
     34                if (b.hashCode() < a.hashCode()) {
     35                        Node tmp = a;
     36                        a = b;
     37                        b = tmp;
     38                }
     39        }
    3240}
Note: See TracChangeset for help on using the changeset viewer.