Ignore:
Timestamp:
2011-09-24T18:48:53+02:00 (13 years ago)
Author:
sbrunner
Message:

fix tr, remove debug logs

Location:
applications/editors/josm/plugins/merge-overlap
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/merge-overlap/.classpath

    r26575 r26705  
    33        <classpathentry kind="src" path="src"/>
    44        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-6-openjdk"/>
    5         <classpathentry kind="lib" path="/usr/share/josm/josm.jar" sourcepath="/home2/brunner/workspace/josm-0.0.svn3094/src"/>
     5        <classpathentry kind="lib" path="/usr/share/josm/josm.jar" sourcepath="/JOSM"/>
    66        <classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
    77        <classpathentry kind="output" path="bin"/>
  • applications/editors/josm/plugins/merge-overlap/src/mergeoverlap/MergeOverlapAction.java

    r26575 r26705  
    88import java.awt.event.ActionEvent;
    99import java.awt.event.KeyEvent;
    10 import java.rmi.server.RMIClassLoader;
    1110import java.util.ArrayList;
    1211import java.util.Arrays;
     
    5251public class MergeOverlapAction extends JosmAction {
    5352
    54     public MergeOverlapAction() {
    55         super(tr("Merge overlap"), "merge_overlap",
    56                 tr("Merge overlap of ways."), Shortcut.registerShortcut(
    57                         "tools:mergeoverlap", tr("Tool: {0}",
    58                                 tr("Merge overlap")), KeyEvent.VK_O,
    59                         Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
    60     }
    61 
    62     Map<Way, List<Relation>> relations = new HashMap<Way, List<Relation>>();
    63     Map<Way, Way> oldWays = new HashMap<Way, Way>();
    64     Map<Relation, Relation> newRelations = new HashMap<Relation, Relation>();
    65     Set<Way> deletes = new HashSet<Way>();
    66 
    67     /**
    68      * The action button has been clicked
    69      *
    70      * @param e Action Event
    71      */
    72     public void actionPerformed(ActionEvent e) {
    73 
    74         // List of selected ways
    75         List<Way> ways = new ArrayList<Way>();
    76         relations.clear();
    77         newRelations.clear();
    78        
    79         // For every selected way
    80         for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
    81             if (osm instanceof Way && !osm.isDeleted()) {
    82                 Way way = (Way)osm;
    83                 ways.add(way);
    84                 List<Relation> rels = new ArrayList<Relation>();
    85                 for (Relation r: OsmPrimitive.getFilteredList(way.getReferrers(), Relation.class)) {
    86                         rels.add(r);
    87                 }
    88                 relations.put(way, rels);
    89             }
    90         }
    91        
    92         List<Way> sel = new ArrayList<Way>(ways);
    93         Collection<Command> cmds = new LinkedList<Command>();
    94 
    95         // *****
    96         // split
    97         // *****
    98         for (Way way : ways) {
    99             Set<Node> nodes = new HashSet<Node>();
    100             for (Way opositWay : ways) {
    101                     if (way != opositWay) {
    102                         List<NodePos> nodesPos = new LinkedList<NodePos>();
    103        
    104                         int pos = 0;
    105                     for (Node node : way.getNodes()) {
    106                         int opositPos = 0;
    107                         for (Node opositNode : opositWay.getNodes()) {
    108                             if (node == opositNode) {
    109                                 if (opositWay.isClosed()) {
    110                                         opositPos %= opositWay.getNodesCount() - 1;
    111                                 }
    112                                 nodesPos.add(new NodePos(node, pos, opositPos));
    113                                 break;
    114                             }
    115                             opositPos++;
    116                         }
    117                         pos++;
    118                     }
    119 
    120                         NodePos start = null;
    121                         NodePos end = null;
    122                         int increment = 0;
    123 
    124                         boolean hasFirst = false;
    125                         for (NodePos node : nodesPos) {
    126                                 if (start == null) {
    127                                         start = node;
    128                                 }
    129                                 else {
    130                                         if (end == null) {
    131                                                 if (follows(way, opositWay, start, node, 1)) {
    132                                                         end = node;
    133                                                         increment = +1;
    134                                                 }
    135                                                 else if (follows(way, opositWay, start, node, -1)) {
    136                                                         end = node;
    137                                                         increment = -1;
    138                                                 }
    139                                                 else {
    140                                                         start = node;
    141                                                         end = null;
    142                                                 }
    143                                         }
    144                                         else {
    145                                                 if (follows(way, opositWay, end, node, increment)) {
    146                                                         end = node;
    147                                                 }
    148                                                 else {
    149                                                         hasFirst = addNodes(start, end, way, nodes, hasFirst);
    150                                         start = node;
    151                                         end = null;
    152                                                 }
    153                                         }
    154                             }
    155                         }
    156                        
    157                         if (start != null && end != null) {
    158                                 hasFirst = addNodes(start, end, way, nodes, hasFirst);
    159                             start = null;
    160                             end = null;
    161                         }
    162                     }
    163             }
    164             if (!nodes.isEmpty() && !way.isClosed() || nodes.size() >= 2) {
    165                 List<List<Node>> wayChunks = SplitWayAction.buildSplitChunks(way, new ArrayList<Node>(nodes));
    166                 SplitWayResult result = splitWay(getEditLayer(), way, wayChunks);
    167                
    168                 cmds.add(result.getCommand());
    169                 sel.remove(way);
    170                 sel.add(result.getOriginalWay());
    171                 sel.addAll(result.getNewWays());
    172                 List<Relation> rels = relations.remove(way);
    173                 relations.put(result.getOriginalWay(), rels);
    174                 for (Way w: result.getNewWays()) {
    175                         relations.put(w, rels);
    176                 }
    177             }
    178         }
    179 
    180         // *****
    181         // merge
    182         // *****
    183         ways = new ArrayList<Way>(sel);
    184         while (!ways.isEmpty()) {
    185             Way way = ways.get(0);
    186             List<Way> combine = new ArrayList<Way>();
    187             combine.add(way);
    188             for (Way opositWay : ways) {
    189                 if (way != opositWay && way.getNodesCount() == opositWay.getNodesCount()) {
    190                     boolean equals1 = true;
    191                     for (int i = 0 ; i < way.getNodesCount() ; i++) {
    192                         if (way.getNode(i) != opositWay.getNode(i)) {
    193                             equals1 = false;
    194                             break;
    195                         }
    196                     }
    197                     boolean equals2 = true;
    198                     for (int i = 0 ; i < way.getNodesCount() ; i++) {
    199                         if (way.getNode(i) != opositWay.getNode(way.getNodesCount() - i -1)) {
    200                             equals2 = false;
    201                             break;
    202                         }
    203                     }
    204                     if (equals1 || equals2) {
    205                         combine.add(opositWay);
    206                     }
    207                 }
    208             }
    209             ways.removeAll(combine);
    210             if (combine.size() > 1) {
    211                 sel.removeAll(combine);
    212                 // combine
    213                 Pair<Way, List<Command>> combineResult;
    214                 try {
    215                     combineResult = combineWaysWorker(combine);
    216                 } catch (UserCancelException e1) {
    217                     return;
    218                 }
    219                 sel.add(combineResult.a);
    220                 cmds.addAll(combineResult.b);
    221             }
    222         }
    223 
    224         for (Relation old: newRelations.keySet()) {
    225                 System.out.println("+++++++++++++");
    226                 System.out.println("old");
    227                 System.out.println(old.getDataSet());
    228                 System.out.println("new");
    229                 System.out.println(newRelations.get(old).getDataSet());
    230 
    231 //              for (int i=0; i < old.getMembersCount(); i++) {
    232                 for (int i=0; i < newRelations.get(old).getMembersCount(); i++) {
    233                 RelationMember rm = newRelations.get(old).getMember(i);
    234 //                RelationMember rm = old.getMember(i);
    235                 System.out.println("***********");
    236                 System.out.println("old");
    237  //             System.out.println(rm.getMember());
    238                 System.out.println(rm.getWay().getId());
    239                 System.out.println(rm.getWay().getDataSet());
    240 /*              System.out.println("new");
    241                 Way w = newWays.get(rm.getWay());
    242 //              System.out.println(w);
    243                 if (w == null) {
    244                         System.out.println(w);
    245                 }
    246                 else {
    247                         System.out.println(w.getDataSet());                     
    248                 }*/
    249                 }
    250                 cmds.add(new ChangeCommand(old, newRelations.get(old)));
    251         }
    252        
    253         List<Way> del = new LinkedList<Way>();
    254         for (Way w: deletes) {
    255                 if (!w.isDeleted()) {
    256                         del.add(w);
    257                 }
    258         }
    259         if (!del.isEmpty()) {
    260                 cmds.add(new DeleteCommand(del));
    261         }
    262 
    263         // Commit
    264         Main.main.undoRedo.add(new SequenceCommand(tr("Merge Overlap (combine)"), cmds));
    265         getCurrentDataSet().setSelected(sel);
    266         Main.map.repaint();
    267        
    268         relations.clear();
    269         newRelations.clear();
    270         oldWays.clear();
    271     }
     53        public MergeOverlapAction() {
     54                super(tr("Merge overlap", null), "merge_overlap", tr(
     55                                "Merge overlap of ways.", null), Shortcut.registerShortcut(
     56                                "tools:mergeoverlap",
     57                                tr("Tool: {0}", tr("Merge overlap", null)), KeyEvent.VK_O,
     58                                Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
     59        }
     60
     61        Map<Way, List<Relation>> relations = new HashMap<Way, List<Relation>>();
     62        Map<Way, Way> oldWays = new HashMap<Way, Way>();
     63        Map<Relation, Relation> newRelations = new HashMap<Relation, Relation>();
     64        Set<Way> deletes = new HashSet<Way>();
     65
     66        /**
     67         * The action button has been clicked
     68         *
     69         * @param e
     70         *            Action Event
     71         */
     72        public void actionPerformed(ActionEvent e) {
     73
     74                // List of selected ways
     75                List<Way> ways = new ArrayList<Way>();
     76                relations.clear();
     77                newRelations.clear();
     78
     79                // For every selected way
     80                for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
     81                        if (osm instanceof Way && !osm.isDeleted()) {
     82                                Way way = (Way) osm;
     83                                ways.add(way);
     84                                List<Relation> rels = new ArrayList<Relation>();
     85                                for (Relation r : OsmPrimitive.getFilteredList(way
     86                                                .getReferrers(), Relation.class)) {
     87                                        rels.add(r);
     88                                }
     89                                relations.put(way, rels);
     90                        }
     91                }
     92
     93                List<Way> sel = new ArrayList<Way>(ways);
     94                Collection<Command> cmds = new LinkedList<Command>();
     95
     96                // *****
     97                // split
     98                // *****
     99                for (Way way : ways) {
     100                        Set<Node> nodes = new HashSet<Node>();
     101                        for (Way opositWay : ways) {
     102                                if (way != opositWay) {
     103                                        List<NodePos> nodesPos = new LinkedList<NodePos>();
     104
     105                                        int pos = 0;
     106                                        for (Node node : way.getNodes()) {
     107                                                int opositPos = 0;
     108                                                for (Node opositNode : opositWay.getNodes()) {
     109                                                        if (node == opositNode) {
     110                                                                if (opositWay.isClosed()) {
     111                                                                        opositPos %= opositWay.getNodesCount() - 1;
     112                                                                }
     113                                                                nodesPos.add(new NodePos(node, pos, opositPos));
     114                                                                break;
     115                                                        }
     116                                                        opositPos++;
     117                                                }
     118                                                pos++;
     119                                        }
     120
     121                                        NodePos start = null;
     122                                        NodePos end = null;
     123                                        int increment = 0;
     124
     125                                        boolean hasFirst = false;
     126                                        for (NodePos node : nodesPos) {
     127                                                if (start == null) {
     128                                                        start = node;
     129                                                } else {
     130                                                        if (end == null) {
     131                                                                if (follows(way, opositWay, start, node, 1)) {
     132                                                                        end = node;
     133                                                                        increment = +1;
     134                                                                } else if (follows(way, opositWay, start, node,
     135                                                                                -1)) {
     136                                                                        end = node;
     137                                                                        increment = -1;
     138                                                                } else {
     139                                                                        start = node;
     140                                                                        end = null;
     141                                                                }
     142                                                        } else {
     143                                                                if (follows(way, opositWay, end, node,
     144                                                                                increment)) {
     145                                                                        end = node;
     146                                                                } else {
     147                                                                        hasFirst = addNodes(start, end, way, nodes,
     148                                                                                        hasFirst);
     149                                                                        start = node;
     150                                                                        end = null;
     151                                                                }
     152                                                        }
     153                                                }
     154                                        }
     155
     156                                        if (start != null && end != null) {
     157                                                hasFirst = addNodes(start, end, way, nodes, hasFirst);
     158                                                start = null;
     159                                                end = null;
     160                                        }
     161                                }
     162                        }
     163                        if (!nodes.isEmpty() && !way.isClosed() || nodes.size() >= 2) {
     164                                List<List<Node>> wayChunks = SplitWayAction.buildSplitChunks(
     165                                                way, new ArrayList<Node>(nodes));
     166                                SplitWayResult result = splitWay(getEditLayer(), way, wayChunks);
     167
     168                                cmds.add(result.getCommand());
     169                                sel.remove(way);
     170                                sel.add(result.getOriginalWay());
     171                                sel.addAll(result.getNewWays());
     172                                List<Relation> rels = relations.remove(way);
     173                                relations.put(result.getOriginalWay(), rels);
     174                                for (Way w : result.getNewWays()) {
     175                                        relations.put(w, rels);
     176                                }
     177                        }
     178                }
     179
     180                // *****
     181                // merge
     182                // *****
     183                ways = new ArrayList<Way>(sel);
     184                while (!ways.isEmpty()) {
     185                        Way way = ways.get(0);
     186                        List<Way> combine = new ArrayList<Way>();
     187                        combine.add(way);
     188                        for (Way opositWay : ways) {
     189                                if (way != opositWay
     190                                                && way.getNodesCount() == opositWay.getNodesCount()) {
     191                                        boolean equals1 = true;
     192                                        for (int i = 0; i < way.getNodesCount(); i++) {
     193                                                if (way.getNode(i) != opositWay.getNode(i)) {
     194                                                        equals1 = false;
     195                                                        break;
     196                                                }
     197                                        }
     198                                        boolean equals2 = true;
     199                                        for (int i = 0; i < way.getNodesCount(); i++) {
     200                                                if (way.getNode(i) != opositWay.getNode(way
     201                                                                .getNodesCount()
     202                                                                - i - 1)) {
     203                                                        equals2 = false;
     204                                                        break;
     205                                                }
     206                                        }
     207                                        if (equals1 || equals2) {
     208                                                combine.add(opositWay);
     209                                        }
     210                                }
     211                        }
     212                        ways.removeAll(combine);
     213                        if (combine.size() > 1) {
     214                                sel.removeAll(combine);
     215                                // combine
     216                                Pair<Way, List<Command>> combineResult;
     217                                try {
     218                                        combineResult = combineWaysWorker(combine);
     219                                } catch (UserCancelException e1) {
     220                                        return;
     221                                }
     222                                sel.add(combineResult.a);
     223                                cmds.addAll(combineResult.b);
     224                        }
     225                }
     226
     227                for (Relation old : newRelations.keySet()) {
     228                        cmds.add(new ChangeCommand(old, newRelations.get(old)));
     229                }
     230
     231                List<Way> del = new LinkedList<Way>();
     232                for (Way w : deletes) {
     233                        if (!w.isDeleted()) {
     234                                del.add(w);
     235                        }
     236                }
     237                if (!del.isEmpty()) {
     238                        cmds.add(new DeleteCommand(del));
     239                }
     240
     241                // Commit
     242                Main.main.undoRedo.add(new SequenceCommand(
     243                                tr("Merge Overlap (combine)", null), cmds));
     244                getCurrentDataSet().setSelected(sel);
     245                Main.map.repaint();
     246
     247                relations.clear();
     248                newRelations.clear();
     249                oldWays.clear();
     250        }
    272251
    273252        private class NodePos {
     
    275254                int pos;
    276255                int opositPos;
    277                 NodePos (Node n, int p, int op) {
     256
     257                NodePos(Node n, int p, int op) {
    278258                        node = n;
    279259                        pos = p;
    280260                        opositPos = op;
    281261                }
     262
    282263                public String toString() {
    283264                        return "NodePos: " + pos + ", " + opositPos + ", " + node;
     
    285266        }
    286267
    287         private boolean addNodes(NodePos start, NodePos end, Way way, Set<Node> nodes,
    288                         boolean hasFirst) {
    289                 if (way.isClosed() || (start.node != way.getNode(0)
    290                         && start.node != way.getNode(way.getNodesCount() - 1))) {
     268        private boolean addNodes(NodePos start, NodePos end, Way way,
     269                        Set<Node> nodes, boolean hasFirst) {
     270                if (way.isClosed()
     271                                || (start.node != way.getNode(0) && start.node != way
     272                                                .getNode(way.getNodesCount() - 1))) {
    291273                        hasFirst = hasFirst || start.node == way.getNode(0);
    292                     nodes.add(start.node);
    293                 }
    294                 if (way.isClosed() || (end.node != way.getNode(0)
    295                         && end.node != way.getNode(way.getNodesCount() - 1))) {
    296                     if (hasFirst && (end.node == way.getNode(way.getNodesCount() - 1))) {
    297                         nodes.remove(way.getNode(0));
    298                     }
    299                     else {
    300                         nodes.add(end.node);
    301                     }
     274                        nodes.add(start.node);
     275                }
     276                if (way.isClosed()
     277                                || (end.node != way.getNode(0) && end.node != way.getNode(way
     278                                                .getNodesCount() - 1))) {
     279                        if (hasFirst && (end.node == way.getNode(way.getNodesCount() - 1))) {
     280                                nodes.remove(way.getNode(0));
     281                        } else {
     282                                nodes.add(end.node);
     283                        }
    302284                }
    303285                return hasFirst;
    304286        }
    305287
    306     private boolean follows(Way way1, Way way2, NodePos np1, NodePos np2, int incr) {
    307         if (way2.isClosed() && incr == 1 && np1.opositPos == way2.getNodesCount() - 2) {
    308                 return np2.pos == np1.pos + 1 && np2.opositPos == 0;           
    309         }
    310         else if (way2.isClosed() && incr == 1 && np1.opositPos == 0) {
    311                 return np2.pos == np1.pos && np2.opositPos == 0
    312                                 || np2.pos == np1.pos + 1 && np2.opositPos == 1;               
    313         }       
    314         else if (way2.isClosed() && incr == -1 && np1.opositPos == 0) {
    315                 return np2.pos == np1.pos && np2.opositPos == 0
    316                                 || np2.pos == np1.pos + 1 && np2.opositPos == way2.getNodesCount() - 2;         
    317         }
    318         else {
    319                 return np2.pos == np1.pos + 1 && np2.opositPos == np1.opositPos + incr;
    320         }
    321     }
    322 
    323     /**
    324      * Splits a way
    325      *
    326      * @param layer
    327      * @param way
    328      * @param wayChunks
    329      * @return
    330      */
    331     private SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks) {
    332         // build a list of commands, and also a new selection list
    333         Collection<Command> commandList = new ArrayList<Command>(wayChunks.size());
    334 
    335         Iterator<List<Node>> chunkIt = wayChunks.iterator();
    336         Collection<String> nowarnroles = Main.pref.getCollection(
    337                 "way.split.roles.nowarn", Arrays.asList(new String[] {
    338                                 "outer", "inner", "forward", "backward" }));
    339 
    340         // First, change the original way
    341         Way changedWay = new Way(way);
    342         oldWays.put(changedWay, way);
    343         changedWay.setNodes(chunkIt.next());
    344         commandList.add(new ChangeCommand(way, changedWay));
    345 
    346         List<Way> newWays = new ArrayList<Way>();
    347         // Second, create new ways
    348         while (chunkIt.hasNext()) {
    349             Way wayToAdd = new Way();
    350             wayToAdd.setKeys(way.getKeys());
    351             newWays.add(wayToAdd);
    352             wayToAdd.setNodes(chunkIt.next());
    353             commandList.add(new AddCommand(layer, wayToAdd));
    354         }
    355         boolean warnmerole = false;
    356         boolean warnme = false;
    357         // now copy all relations to new way also
    358 
    359         for (Relation r : getParentRelations(way)) {
    360             if (!r.isUsable()) {
    361                 continue;
    362             }
    363             Relation c = null;
    364             String type = r.get("type");
    365             if (type == null) {
    366                 type = "";
    367             }
    368 
    369             int i_c = 0, i_r = 0;
    370             List<RelationMember> relationMembers = r.getMembers();
    371             for (RelationMember rm : relationMembers) {
    372                 if (rm.isWay() && rm.getMember() == way) {
    373                     boolean insert = true;
    374                     if ("restriction".equals(type)) {
    375                         /*
    376                          * this code assumes the restriction is correct. No real
    377                          * error checking done
    378                          */
    379                         String role = rm.getRole();
    380                         if ("from".equals(role) || "to".equals(role)) {
    381                             OsmPrimitive via = null;
    382                             for (RelationMember rmv : r.getMembers()) {
    383                                 if ("via".equals(rmv.getRole())) {
    384                                     via = rmv.getMember();
    385                                 }
    386                             }
    387                             List<Node> nodes = new ArrayList<Node>();
    388                             if (via != null) {
    389                                 if (via instanceof Node) {
    390                                     nodes.add((Node) via);
    391                                 } else if (via instanceof Way) {
    392                                     nodes.add(((Way) via).lastNode());
    393                                     nodes.add(((Way) via).firstNode());
    394                                 }
    395                             }
    396                             Way res = null;
    397                             for (Node n : nodes) {
    398                                 if (changedWay.isFirstLastNode(n)) {
    399                                     res = way;
    400                                 }
    401                             }
    402                             if (res == null) {
    403                                 for (Way wayToAdd : newWays) {
    404                                     for (Node n : nodes) {
    405                                         if (wayToAdd.isFirstLastNode(n)) {
    406                                             res = wayToAdd;
    407                                         }
    408                                     }
    409                                 }
    410                                 if (res != null) {
    411                                     if (c == null) {
    412                                         c = getNew(r);
    413                                     }
    414                                     c.addMember(new RelationMember(role, res));
    415                                     c.removeMembersFor(way);
    416                                     insert = false;
    417                                 }
    418                             } else {
    419                                 insert = false;
    420                             }
    421                         } else if (!"via".equals(role)) {
    422                             warnme = true;
    423                         }
    424                     } else if (!("route".equals(type))
    425                             && !("multipolygon".equals(type))) {
    426                         warnme = true;
    427                     }
    428                     if (c == null) {
    429                         c = getNew(r);
    430                     }
    431 
    432                     if (insert) {
    433                         if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) {
    434                             warnmerole = true;
    435                         }
    436 
    437                         Boolean backwards = null;
    438                         int k = 1;
    439                         while (i_r - k >= 0 || i_r + k < relationMembers.size()) {
    440                             if ((i_r - k >= 0)
    441                                     && relationMembers.get(i_r - k).isWay()) {
    442                                 Way w = relationMembers.get(i_r - k).getWay();
    443                                 if ((w.lastNode() == way.firstNode())
    444                                         || w.firstNode() == way.firstNode()) {
    445                                     backwards = false;
    446                                 } else if ((w.firstNode() == way.lastNode())
    447                                         || w.lastNode() == way.lastNode()) {
    448                                     backwards = true;
    449                                 }
    450                                 break;
    451                             }
    452                             if ((i_r + k < relationMembers.size())
    453                                     && relationMembers.get(i_r + k).isWay()) {
    454                                 Way w = relationMembers.get(i_r + k).getWay();
    455                                 if ((w.lastNode() == way.firstNode())
    456                                         || w.firstNode() == way.firstNode()) {
    457                                     backwards = true;
    458                                 } else if ((w.firstNode() == way.lastNode())
    459                                         || w.lastNode() == way.lastNode()) {
    460                                     backwards = false;
    461                                 }
    462                                 break;
    463                             }
    464                             k++;
    465                         }
    466 
    467                         int j = i_c;
    468                         for (Way wayToAdd : newWays) {
    469                             RelationMember em = new RelationMember(
    470                                     rm.getRole(), wayToAdd);
    471                             j++;
    472                             if ((backwards != null) && backwards) {
    473                                 c.addMember(i_c, em);
    474                             } else {
    475                                 c.addMember(j, em);
    476                             }
    477                         }
    478                         i_c = j;
    479                     }
    480                 }
    481                 i_c++;
    482                 i_r++;
    483             }
    484 
    485             if (c != null) {
    486                 //commandList.add(new ChangeCommand(layer, r, c));
    487                 newRelations.put(r, c);
    488             }
    489         }
    490         if (warnmerole) {
    491             JOptionPane
    492                     .showMessageDialog(
    493                             Main.parent,
    494                             tr("<html>A role based relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.</html>"),
    495                             tr("Warning"), JOptionPane.WARNING_MESSAGE);
    496         } else if (warnme) {
    497             JOptionPane
    498                     .showMessageDialog(
    499                             Main.parent,
    500                             tr("<html>A relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.</html>"),
    501                             tr("Warning"), JOptionPane.WARNING_MESSAGE);
    502         }
    503 
    504         return new SplitWayResult(new SequenceCommand("Split way", commandList), null, changedWay, newWays);
    505     }
    506 
    507     /**
    508      * @param ways
    509      * @return null if ways cannot be combined. Otherwise returns the combined
    510      *              ways and the commands to combine
    511      * @throws UserCancelException
    512      */
    513     private Pair<Way, List<Command>> combineWaysWorker(Collection<Way> ways) throws UserCancelException {                       
    514        
    515         // prepare and clean the list of ways to combine
    516         if (ways == null || ways.isEmpty())
    517             return null;
    518         ways.remove(null); // just in case -  remove all null ways from the collection
    519 
    520         // remove duplicates, preserving order
    521         ways = new LinkedHashSet<Way>(ways);
    522 
    523         // try to build a new way which includes all the combined ways
    524         NodeGraph graph = NodeGraph.createUndirectedGraphFromNodeWays(ways);
    525         List<Node> path = graph.buildSpanningPath();
    526 
    527         // check whether any ways have been reversed in the process
    528         // and build the collection of tags used by the ways to combine
    529         TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
    530 
    531         List<Way> reversedWays = new LinkedList<Way>();
    532         List<Way> unreversedWays = new LinkedList<Way>();
    533         for (Way w: ways) {
    534             if ((path.indexOf(w.getNode(0)) + 1) == path.lastIndexOf(w.getNode(1))) {
    535                 unreversedWays.add(w);
    536             } else {
    537                 reversedWays.add(w);
    538             }
    539         }
    540         // reverse path if all ways have been reversed
    541         if (unreversedWays.isEmpty()) {
    542             Collections.reverse(path);
    543             unreversedWays = reversedWays;
    544             reversedWays = null;
    545         }
    546         if ((reversedWays != null) && !reversedWays.isEmpty()) {
    547             // filter out ways that have no direction-dependent tags
    548             unreversedWays = ReverseWayTagCorrector.irreversibleWays(unreversedWays);
    549             reversedWays = ReverseWayTagCorrector.irreversibleWays(reversedWays);
    550             // reverse path if there are more reversed than unreversed ways with direction-dependent tags
    551             if (reversedWays.size() > unreversedWays.size()) {
    552                 Collections.reverse(path);
    553                 List<Way> tempWays = unreversedWays;
    554                 unreversedWays = reversedWays;
    555                 reversedWays = tempWays;
    556             }
    557             // if there are still reversed ways with direction-dependent tags, reverse their tags
    558             if (!reversedWays.isEmpty()) {
    559                 List<Way> unreversedTagWays = new ArrayList<Way>(ways);
    560                 unreversedTagWays.removeAll(reversedWays);
    561                 ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
    562                 List<Way> reversedTagWays = new ArrayList<Way>();
    563                 Collection<Command> changePropertyCommands =  null;
    564                 for (Way w : reversedWays) {
    565                     Way wnew = new Way(w);
    566                     reversedTagWays.add(wnew);
    567                     changePropertyCommands = reverseWayTagCorrector.execute(w, wnew);
    568                 }
    569                 if ((changePropertyCommands != null) && !changePropertyCommands.isEmpty()) {
    570                     for (Command c : changePropertyCommands) {
    571                         c.executeCommand();
    572                     }
    573                 }
    574                 wayTags = TagCollection.unionOfAllPrimitives(reversedTagWays);
    575                 wayTags.add(TagCollection.unionOfAllPrimitives(unreversedTagWays));
    576             }
    577         }
    578 
    579         // create the new way and apply the new node list
    580         Way targetWay = getTargetWay(ways);
    581         Way modifiedTargetWay = new Way(targetWay);
    582         modifiedTargetWay.setNodes(path);
    583 
    584         TagCollection completeWayTags = new TagCollection(wayTags);
    585         combineTigerTags(completeWayTags);
    586         normalizeTagCollectionBeforeEditing(completeWayTags, ways);
    587         TagCollection tagsToEdit = new TagCollection(completeWayTags);
    588         completeTagCollectionForEditing(tagsToEdit);
    589 
    590         MyCombinePrimitiveResolverDialog dialog = MyCombinePrimitiveResolverDialog.getInstance();
    591         dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues());
    592         dialog.setTargetPrimitive(targetWay);
    593         Set<Relation> parentRelations = getParentRelations(ways);
    594         dialog.getRelationMemberConflictResolverModel().populate(parentRelations, ways, oldWays);
    595         dialog.prepareDefaultDecisions();
    596 
    597         // resolve tag conflicts if necessary
    598         if (askForMergeTag(ways) || duplicateParentRelations(ways)) {
    599             dialog.setVisible(true);
    600             if (dialog.isCancelled())
    601                 throw new UserCancelException();
    602         }
    603 
    604         LinkedList<Command> cmds = new LinkedList<Command>();
    605         deletes.addAll(ways);
    606         deletes.remove(targetWay);
    607 
    608         cmds.add(new ChangeCommand(targetWay, modifiedTargetWay));
    609         cmds.addAll(dialog.buildWayResolutionCommands());
    610         dialog.buildRelationCorrespondance(newRelations, oldWays);
    611 
    612         return new Pair<Way, List<Command>>(targetWay, cmds);
    613     }
    614 
    615     private static Way getTargetWay(Collection<Way> combinedWays) {
    616         // init with an arbitrary way
    617         Way targetWay = combinedWays.iterator().next();
    618 
    619         // look for the first way already existing on
    620         // the server
    621         for (Way w : combinedWays) {
    622             targetWay = w;
    623             if (!w.isNew()) {
    624                 break;
    625             }
    626         }
    627         return targetWay;
    628     }
    629 
    630     /**
    631      * @return has tag to be merged (=> ask)
    632      */
    633     private static boolean askForMergeTag(Collection<Way> ways) {
    634         for (Way way: ways) {
    635             for (Way oposite: ways) {
    636                 for (String key: way.getKeys().keySet()) {
    637                         if (!"source".equals(key) && oposite.hasKey(key)
    638                                         && !way.get(key).equals(oposite.get(key))) {
    639                                 return true;
    640                         }
    641                 }
    642             }
    643         }
    644         return false;
    645     }
    646    
    647     /**
    648      * @return has duplicate parent relation
    649      */
    650     private boolean duplicateParentRelations(Collection<Way> ways) {
    651         Set<Relation> relations = new HashSet<Relation>();
    652         for (Way w: ways) {
    653             List<Relation> rs = getParentRelations(w);
    654             for (Relation r: rs) {
    655                 if (relations.contains(r)) {
    656                     return true;
    657                 }
    658             }
    659             relations.addAll(rs);
    660         }
    661         return false;
    662     }
    663 
    664     /**
    665      * Replies the set of referring relations
    666      *
    667      * @return the set of referring relations
    668      */
    669     private List<Relation> getParentRelations(Way way) {
    670         List<Relation> rels = new ArrayList<Relation>();
    671         for (Relation r: relations.get(way)) {
    672                 if (newRelations.containsKey(r)) {
    673                         rels.add(newRelations.get(r));
    674                 }
    675                 else {
    676                         rels.add(r);
    677                 }
    678         }
    679         return rels;
    680     }
    681    
    682     private Relation getNew(Relation r) {
    683         return getNew(r, newRelations);
    684     }
    685 
    686     public static Relation getNew(Relation r, Map<Relation, Relation> newRelations) {
    687         if (newRelations.containsValue(r)) {
    688                 return r;
    689         }
    690         else {
    691                 Relation c = new Relation(r);
    692                 newRelations.put(r, c);
    693                 return c;
    694         }
    695     }
    696    
    697     private Way getOld(Way r) {
    698         return getOld(r, oldWays);
    699     }
    700 
    701     public static Way getOld(Way w, Map<Way, Way> oldWays) {
    702         if (oldWays.containsKey(w)) {
    703                 return oldWays.get(w);
    704         }
    705         else {
    706                 return w;
    707         }
    708     }
    709    
    710     /**
    711      * Replies the set of referring relations
    712      *
    713      * @return the set of referring relations
    714      */
    715     private Set<Relation> getParentRelations(Collection<Way> ways) {
    716         HashSet<Relation> ret = new HashSet<Relation>();
    717         for (Way w: ways) {
    718             ret.addAll(getParentRelations(w));
    719         }
    720         return ret;
    721     }
    722 
    723     /** Enable this action only if something is selected */
    724     @Override
    725     protected void updateEnabledState() {
    726         if (getCurrentDataSet() == null) {
    727             setEnabled(false);
    728         } else {
    729             updateEnabledState(getCurrentDataSet().getSelected());
    730         }
    731     }
    732 
    733     /** Enable this action only if something is selected */
    734     @Override
    735     protected void updateEnabledState(
    736             Collection<? extends OsmPrimitive> selection) {
    737         if (selection == null) {
    738             setEnabled(false);
    739             return;
    740         }
    741         for (OsmPrimitive primitive: selection) {
    742             if (!(primitive instanceof Way) || primitive.isDeleted()) {
    743                 setEnabled(false);
    744                 return;
    745             }
    746         }
    747         setEnabled(selection.size() >= 2);
    748     }
     288        private boolean follows(Way way1, Way way2, NodePos np1, NodePos np2,
     289                        int incr) {
     290                if (way2.isClosed() && incr == 1
     291                                && np1.opositPos == way2.getNodesCount() - 2) {
     292                        return np2.pos == np1.pos + 1 && np2.opositPos == 0;
     293                } else if (way2.isClosed() && incr == 1 && np1.opositPos == 0) {
     294                        return np2.pos == np1.pos && np2.opositPos == 0
     295                                        || np2.pos == np1.pos + 1 && np2.opositPos == 1;
     296                } else if (way2.isClosed() && incr == -1 && np1.opositPos == 0) {
     297                        return np2.pos == np1.pos && np2.opositPos == 0
     298                                        || np2.pos == np1.pos + 1
     299                                        && np2.opositPos == way2.getNodesCount() - 2;
     300                } else {
     301                        return np2.pos == np1.pos + 1
     302                                        && np2.opositPos == np1.opositPos + incr;
     303                }
     304        }
     305
     306        /**
     307         * Splits a way
     308         *
     309         * @param layer
     310         * @param way
     311         * @param wayChunks
     312         * @return
     313         */
     314        private SplitWayResult splitWay(OsmDataLayer layer, Way way,
     315                        List<List<Node>> wayChunks) {
     316                // build a list of commands, and also a new selection list
     317                Collection<Command> commandList = new ArrayList<Command>(wayChunks
     318                                .size());
     319
     320                Iterator<List<Node>> chunkIt = wayChunks.iterator();
     321                Collection<String> nowarnroles = Main.pref.getCollection(
     322                                "way.split.roles.nowarn", Arrays.asList(new String[] { "outer",
     323                                                "inner", "forward", "backward" }));
     324
     325                // First, change the original way
     326                Way changedWay = new Way(way);
     327                oldWays.put(changedWay, way);
     328                changedWay.setNodes(chunkIt.next());
     329                commandList.add(new ChangeCommand(way, changedWay));
     330
     331                List<Way> newWays = new ArrayList<Way>();
     332                // Second, create new ways
     333                while (chunkIt.hasNext()) {
     334                        Way wayToAdd = new Way();
     335                        wayToAdd.setKeys(way.getKeys());
     336                        newWays.add(wayToAdd);
     337                        wayToAdd.setNodes(chunkIt.next());
     338                        commandList.add(new AddCommand(layer, wayToAdd));
     339                }
     340                boolean warnmerole = false;
     341                boolean warnme = false;
     342                // now copy all relations to new way also
     343
     344                for (Relation r : getParentRelations(way)) {
     345                        if (!r.isUsable()) {
     346                                continue;
     347                        }
     348                        Relation c = null;
     349                        String type = r.get("type");
     350                        if (type == null) {
     351                                type = "";
     352                        }
     353
     354                        int i_c = 0, i_r = 0;
     355                        List<RelationMember> relationMembers = r.getMembers();
     356                        for (RelationMember rm : relationMembers) {
     357                                if (rm.isWay() && rm.getMember() == way) {
     358                                        boolean insert = true;
     359                                        if ("restriction".equals(type)) {
     360                                                /*
     361                                                 * this code assumes the restriction is correct. No real
     362                                                 * error checking done
     363                                                 */
     364                                                String role = rm.getRole();
     365                                                if ("from".equals(role) || "to".equals(role)) {
     366                                                        OsmPrimitive via = null;
     367                                                        for (RelationMember rmv : r.getMembers()) {
     368                                                                if ("via".equals(rmv.getRole())) {
     369                                                                        via = rmv.getMember();
     370                                                                }
     371                                                        }
     372                                                        List<Node> nodes = new ArrayList<Node>();
     373                                                        if (via != null) {
     374                                                                if (via instanceof Node) {
     375                                                                        nodes.add((Node) via);
     376                                                                } else if (via instanceof Way) {
     377                                                                        nodes.add(((Way) via).lastNode());
     378                                                                        nodes.add(((Way) via).firstNode());
     379                                                                }
     380                                                        }
     381                                                        Way res = null;
     382                                                        for (Node n : nodes) {
     383                                                                if (changedWay.isFirstLastNode(n)) {
     384                                                                        res = way;
     385                                                                }
     386                                                        }
     387                                                        if (res == null) {
     388                                                                for (Way wayToAdd : newWays) {
     389                                                                        for (Node n : nodes) {
     390                                                                                if (wayToAdd.isFirstLastNode(n)) {
     391                                                                                        res = wayToAdd;
     392                                                                                }
     393                                                                        }
     394                                                                }
     395                                                                if (res != null) {
     396                                                                        if (c == null) {
     397                                                                                c = getNew(r);
     398                                                                        }
     399                                                                        c.addMember(new RelationMember(role, res));
     400                                                                        c.removeMembersFor(way);
     401                                                                        insert = false;
     402                                                                }
     403                                                        } else {
     404                                                                insert = false;
     405                                                        }
     406                                                } else if (!"via".equals(role)) {
     407                                                        warnme = true;
     408                                                }
     409                                        } else if (!("route".equals(type))
     410                                                        && !("multipolygon".equals(type))) {
     411                                                warnme = true;
     412                                        }
     413                                        if (c == null) {
     414                                                c = getNew(r);
     415                                        }
     416
     417                                        if (insert) {
     418                                                if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) {
     419                                                        warnmerole = true;
     420                                                }
     421
     422                                                Boolean backwards = null;
     423                                                int k = 1;
     424                                                while (i_r - k >= 0 || i_r + k < relationMembers.size()) {
     425                                                        if ((i_r - k >= 0)
     426                                                                        && relationMembers.get(i_r - k).isWay()) {
     427                                                                Way w = relationMembers.get(i_r - k).getWay();
     428                                                                if ((w.lastNode() == way.firstNode())
     429                                                                                || w.firstNode() == way.firstNode()) {
     430                                                                        backwards = false;
     431                                                                } else if ((w.firstNode() == way.lastNode())
     432                                                                                || w.lastNode() == way.lastNode()) {
     433                                                                        backwards = true;
     434                                                                }
     435                                                                break;
     436                                                        }
     437                                                        if ((i_r + k < relationMembers.size())
     438                                                                        && relationMembers.get(i_r + k).isWay()) {
     439                                                                Way w = relationMembers.get(i_r + k).getWay();
     440                                                                if ((w.lastNode() == way.firstNode())
     441                                                                                || w.firstNode() == way.firstNode()) {
     442                                                                        backwards = true;
     443                                                                } else if ((w.firstNode() == way.lastNode())
     444                                                                                || w.lastNode() == way.lastNode()) {
     445                                                                        backwards = false;
     446                                                                }
     447                                                                break;
     448                                                        }
     449                                                        k++;
     450                                                }
     451
     452                                                int j = i_c;
     453                                                for (Way wayToAdd : newWays) {
     454                                                        RelationMember em = new RelationMember(
     455                                                                        rm.getRole(), wayToAdd);
     456                                                        j++;
     457                                                        if ((backwards != null) && backwards) {
     458                                                                c.addMember(i_c, em);
     459                                                        } else {
     460                                                                c.addMember(j, em);
     461                                                        }
     462                                                }
     463                                                i_c = j;
     464                                        }
     465                                }
     466                                i_c++;
     467                                i_r++;
     468                        }
     469
     470                        if (c != null) {
     471                                // commandList.add(new ChangeCommand(layer, r, c));
     472                                newRelations.put(r, c);
     473                        }
     474                }
     475                if (warnmerole) {
     476                        JOptionPane
     477                                        .showMessageDialog(
     478                                                        Main.parent,
     479                                                        tr("<html>A role based relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.</html>", null),
     480                                                        tr("Warning", null), JOptionPane.WARNING_MESSAGE);
     481                } else if (warnme) {
     482                        JOptionPane
     483                                        .showMessageDialog(
     484                                                        Main.parent,
     485                                                        tr("<html>A relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.</html>", null),
     486                                                        tr("Warning", null), JOptionPane.WARNING_MESSAGE);
     487                }
     488
     489                return new SplitWayResult(
     490                                new SequenceCommand("Split way", commandList), null,
     491                                changedWay, newWays);
     492        }
     493
     494        /**
     495         * @param ways
     496         * @return null if ways cannot be combined. Otherwise returns the combined
     497         *         ways and the commands to combine
     498         * @throws UserCancelException
     499         */
     500        private Pair<Way, List<Command>> combineWaysWorker(Collection<Way> ways)
     501                        throws UserCancelException {
     502
     503                // prepare and clean the list of ways to combine
     504                if (ways == null || ways.isEmpty())
     505                        return null;
     506                ways.remove(null); // just in case - remove all null ways from the
     507                                                        // collection
     508
     509                // remove duplicates, preserving order
     510                ways = new LinkedHashSet<Way>(ways);
     511
     512                // try to build a new way which includes all the combined ways
     513                NodeGraph graph = NodeGraph.createUndirectedGraphFromNodeWays(ways);
     514                List<Node> path = graph.buildSpanningPath();
     515
     516                // check whether any ways have been reversed in the process
     517                // and build the collection of tags used by the ways to combine
     518                TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
     519
     520                List<Way> reversedWays = new LinkedList<Way>();
     521                List<Way> unreversedWays = new LinkedList<Way>();
     522                for (Way w : ways) {
     523                        if ((path.indexOf(w.getNode(0)) + 1) == path.lastIndexOf(w
     524                                        .getNode(1))) {
     525                                unreversedWays.add(w);
     526                        } else {
     527                                reversedWays.add(w);
     528                        }
     529                }
     530                // reverse path if all ways have been reversed
     531                if (unreversedWays.isEmpty()) {
     532                        Collections.reverse(path);
     533                        unreversedWays = reversedWays;
     534                        reversedWays = null;
     535                }
     536                if ((reversedWays != null) && !reversedWays.isEmpty()) {
     537                        // filter out ways that have no direction-dependent tags
     538                        unreversedWays = ReverseWayTagCorrector
     539                                        .irreversibleWays(unreversedWays);
     540                        reversedWays = ReverseWayTagCorrector
     541                                        .irreversibleWays(reversedWays);
     542                        // reverse path if there are more reversed than unreversed ways with
     543                        // direction-dependent tags
     544                        if (reversedWays.size() > unreversedWays.size()) {
     545                                Collections.reverse(path);
     546                                List<Way> tempWays = unreversedWays;
     547                                unreversedWays = reversedWays;
     548                                reversedWays = tempWays;
     549                        }
     550                        // if there are still reversed ways with direction-dependent tags,
     551                        // reverse their tags
     552                        if (!reversedWays.isEmpty()) {
     553                                List<Way> unreversedTagWays = new ArrayList<Way>(ways);
     554                                unreversedTagWays.removeAll(reversedWays);
     555                                ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
     556                                List<Way> reversedTagWays = new ArrayList<Way>();
     557                                Collection<Command> changePropertyCommands = null;
     558                                for (Way w : reversedWays) {
     559                                        Way wnew = new Way(w);
     560                                        reversedTagWays.add(wnew);
     561                                        changePropertyCommands = reverseWayTagCorrector.execute(w,
     562                                                        wnew);
     563                                }
     564                                if ((changePropertyCommands != null)
     565                                                && !changePropertyCommands.isEmpty()) {
     566                                        for (Command c : changePropertyCommands) {
     567                                                c.executeCommand();
     568                                        }
     569                                }
     570                                wayTags = TagCollection.unionOfAllPrimitives(reversedTagWays);
     571                                wayTags.add(TagCollection
     572                                                .unionOfAllPrimitives(unreversedTagWays));
     573                        }
     574                }
     575
     576                // create the new way and apply the new node list
     577                Way targetWay = getTargetWay(ways);
     578                Way modifiedTargetWay = new Way(targetWay);
     579                modifiedTargetWay.setNodes(path);
     580
     581                TagCollection completeWayTags = new TagCollection(wayTags);
     582                combineTigerTags(completeWayTags);
     583                normalizeTagCollectionBeforeEditing(completeWayTags, ways);
     584                TagCollection tagsToEdit = new TagCollection(completeWayTags);
     585                completeTagCollectionForEditing(tagsToEdit);
     586
     587                MyCombinePrimitiveResolverDialog dialog = MyCombinePrimitiveResolverDialog
     588                                .getInstance();
     589                dialog.getTagConflictResolverModel().populate(tagsToEdit,
     590                                completeWayTags.getKeysWithMultipleValues());
     591                dialog.setTargetPrimitive(targetWay);
     592                Set<Relation> parentRelations = getParentRelations(ways);
     593                dialog.getRelationMemberConflictResolverModel().populate(
     594                                parentRelations, ways, oldWays);
     595                dialog.prepareDefaultDecisions();
     596
     597                // resolve tag conflicts if necessary
     598                if (askForMergeTag(ways) || duplicateParentRelations(ways)) {
     599                        dialog.setVisible(true);
     600                        if (dialog.isCancelled())
     601                                throw new UserCancelException();
     602                }
     603
     604                LinkedList<Command> cmds = new LinkedList<Command>();
     605                deletes.addAll(ways);
     606                deletes.remove(targetWay);
     607
     608                cmds.add(new ChangeCommand(targetWay, modifiedTargetWay));
     609                cmds.addAll(dialog.buildWayResolutionCommands());
     610                dialog.buildRelationCorrespondance(newRelations, oldWays);
     611
     612                return new Pair<Way, List<Command>>(targetWay, cmds);
     613        }
     614
     615        private static Way getTargetWay(Collection<Way> combinedWays) {
     616                // init with an arbitrary way
     617                Way targetWay = combinedWays.iterator().next();
     618
     619                // look for the first way already existing on
     620                // the server
     621                for (Way w : combinedWays) {
     622                        targetWay = w;
     623                        if (!w.isNew()) {
     624                                break;
     625                        }
     626                }
     627                return targetWay;
     628        }
     629
     630        /**
     631         * @return has tag to be merged (=> ask)
     632         */
     633        private static boolean askForMergeTag(Collection<Way> ways) {
     634                for (Way way : ways) {
     635                        for (Way oposite : ways) {
     636                                for (String key : way.getKeys().keySet()) {
     637                                        if (!"source".equals(key) && oposite.hasKey(key)
     638                                                        && !way.get(key).equals(oposite.get(key))) {
     639                                                return true;
     640                                        }
     641                                }
     642                        }
     643                }
     644                return false;
     645        }
     646
     647        /**
     648         * @return has duplicate parent relation
     649         */
     650        private boolean duplicateParentRelations(Collection<Way> ways) {
     651                Set<Relation> relations = new HashSet<Relation>();
     652                for (Way w : ways) {
     653                        List<Relation> rs = getParentRelations(w);
     654                        for (Relation r : rs) {
     655                                if (relations.contains(r)) {
     656                                        return true;
     657                                }
     658                        }
     659                        relations.addAll(rs);
     660                }
     661                return false;
     662        }
     663
     664        /**
     665         * Replies the set of referring relations
     666         *
     667         * @return the set of referring relations
     668         */
     669        private List<Relation> getParentRelations(Way way) {
     670                List<Relation> rels = new ArrayList<Relation>();
     671                for (Relation r : relations.get(way)) {
     672                        if (newRelations.containsKey(r)) {
     673                                rels.add(newRelations.get(r));
     674                        } else {
     675                                rels.add(r);
     676                        }
     677                }
     678                return rels;
     679        }
     680
     681        private Relation getNew(Relation r) {
     682                return getNew(r, newRelations);
     683        }
     684
     685        public static Relation getNew(Relation r,
     686                        Map<Relation, Relation> newRelations) {
     687                if (newRelations.containsValue(r)) {
     688                        return r;
     689                } else {
     690                        Relation c = new Relation(r);
     691                        newRelations.put(r, c);
     692                        return c;
     693                }
     694        }
     695
     696        private Way getOld(Way r) {
     697                return getOld(r, oldWays);
     698        }
     699
     700        public static Way getOld(Way w, Map<Way, Way> oldWays) {
     701                if (oldWays.containsKey(w)) {
     702                        return oldWays.get(w);
     703                } else {
     704                        return w;
     705                }
     706        }
     707
     708        /**
     709         * Replies the set of referring relations
     710         *
     711         * @return the set of referring relations
     712         */
     713        private Set<Relation> getParentRelations(Collection<Way> ways) {
     714                HashSet<Relation> ret = new HashSet<Relation>();
     715                for (Way w : ways) {
     716                        ret.addAll(getParentRelations(w));
     717                }
     718                return ret;
     719        }
     720
     721        /** Enable this action only if something is selected */
     722        @Override
     723        protected void updateEnabledState() {
     724                if (getCurrentDataSet() == null) {
     725                        setEnabled(false);
     726                } else {
     727                        updateEnabledState(getCurrentDataSet().getSelected());
     728                }
     729        }
     730
     731        /** Enable this action only if something is selected */
     732        @Override
     733        protected void updateEnabledState(
     734                        Collection<? extends OsmPrimitive> selection) {
     735                if (selection == null) {
     736                        setEnabled(false);
     737                        return;
     738                }
     739                for (OsmPrimitive primitive : selection) {
     740                        if (!(primitive instanceof Way) || primitive.isDeleted()) {
     741                                setEnabled(false);
     742                                return;
     743                        }
     744                }
     745                setEnabled(selection.size() >= 2);
     746        }
    749747}
  • applications/editors/josm/plugins/merge-overlap/src/mergeoverlap/MergeOverlapPlugin.java

    r26575 r26705  
    1919        public MergeOverlapPlugin(PluginInformation info) {
    2020        super(info);
    21         name = tr("Merge overlap");
     21        name = tr("Merge overlap", null);
    2222        JMenu toolsMenu = null;
    2323        for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
    2424            JMenu menu = Main.main.menu.getMenu(i);
    2525            String name = menu.getText();
    26             if (name != null && name.equals(tr("Tools"))) {
     26            if (name != null && name.equals(tr("Tools", null))) {
    2727                toolsMenu = menu;
    2828            }
  • applications/editors/josm/plugins/merge-overlap/src/mergeoverlap/MyCombinePrimitiveResolverDialog.java

    r26575 r26705  
    173173    protected void updateTitle() {
    174174        if (targetPrimitive == null) {
    175             setTitle(tr("Conflicts when combining primitives"));
     175            setTitle(tr("Conflicts when combining primitives", null));
    176176            return;
    177177        }
     
    324324        JPanel pnl = new JPanel();
    325325        pnl.setLayout(new BorderLayout());
    326         pnl.add(new JLabel(tr("No conflicts to resolve")));
     326        pnl.add(new JLabel(tr("No conflicts to resolve", null)));
    327327        return pnl;
    328328    }
     
    386386
    387387        public CancelAction() {
    388             putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution"));
    389             putValue(Action.NAME, tr("Cancel"));
     388            putValue(Action.SHORT_DESCRIPTION, tr("Cancel conflict resolution", null));
     389            putValue(Action.NAME, tr("Cancel", null));
    390390            putValue(Action.SMALL_ICON, ImageProvider.get("", "cancel"));
    391391            setEnabled(true);
     
    401401
    402402        public ApplyAction() {
    403             putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts"));
    404             putValue(Action.NAME, tr("Apply"));
     403            putValue(Action.SHORT_DESCRIPTION, tr("Apply resolved conflicts", null));
     404            putValue(Action.NAME, tr("Apply", null));
    405405            putValue(Action.SMALL_ICON, ImageProvider.get("ok"));
    406406            updateEnabledState();
     
    800800            JPanel pnl = new JPanel();
    801801            pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    802             pnl.add(new JLabel(tr("Role:")));
     802            pnl.add(new JLabel(tr("Role:", null)));
    803803            pnl.add(tfRole = new AutoCompletingTextField(10));
    804             tfRole.setToolTipText(tr("Enter a role for all relation memberships"));
     804            tfRole.setToolTipText(tr("Enter a role for all relation memberships", null));
    805805            pnl.add(new JButton(new ApplyRoleAction()));
    806806            tfRole.addActionListener(new ApplyRoleAction());
     
    819819            JPanel pnl = new JPanel();
    820820            pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    821             cbTagRelations = new JCheckBox(tr("Tag modified relations with "));
     821            cbTagRelations = new JCheckBox(tr("Tag modified relations with ", null));
    822822            cbTagRelations.addChangeListener(new ToggleTagRelationsAction());
    823823            cbTagRelations.setToolTipText(
    824824                    tr("<html>Select to enable entering a tag which will be applied<br>"
    825                             + "to all modified relations.</html>"));
     825                            + "to all modified relations.</html>", null));
    826826            pnl.add(cbTagRelations);
    827827            pnl.add(new JLabel(trc("tag", "Key:")));
    828828            pnl.add(tfKey = new AutoCompletingTextField(10));
    829             tfKey.setToolTipText(tr("<html>Enter a tag key, i.e. <strong><tt>fixme</tt></strong></html>"));
    830             pnl.add(new JLabel(tr("Value:")));
     829            tfKey.setToolTipText(tr("<html>Enter a tag key, i.e. <strong><tt>fixme</tt></strong></html>", null));
     830            pnl.add(new JLabel(tr("Value:", null)));
    831831            pnl.add(tfValue = new AutoCompletingTextField(10));
    832             tfValue.setToolTipText(tr("<html>Enter a tag value, i.e. <strong><tt>check members</tt></strong></html>"));
     832            tfValue.setToolTipText(tr("<html>Enter a tag value, i.e. <strong><tt>check members</tt></strong></html>", null));
    833833            cbTagRelations.setSelected(false);
    834834            tfKey.setEnabled(false);
     
    848848                    + "the other ways that are members of the same relation: the combined way will "
    849849                    + "take the place of the original way in the relation."
    850                     + "</html>"));
     850                    + "</html>", null));
    851851            invalidate();
    852852        }
     
    859859                    + "the other nodes that are members of the same relation: the target node will "
    860860                    + "take the place of the original node in the relation."
    861                     + "</html>"));
     861                    + "</html>", null));
    862862            invalidate();
    863863        }
     
    865865        class ApplyRoleAction extends AbstractAction {
    866866            public ApplyRoleAction() {
    867                 putValue(NAME, tr("Apply"));
     867                putValue(NAME, tr("Apply", null));
    868868                putValue(SMALL_ICON, ImageProvider.get("ok"));
    869                 putValue(SHORT_DESCRIPTION, tr("Apply this role to all members"));
     869                putValue(SHORT_DESCRIPTION, tr("Apply this role to all members", null));
    870870            }
    871871
     
    12701270            gc.weightx = 1.0;
    12711271            gc.anchor = GridBagConstraints.LINE_START;
    1272             pnl.add(new JLabel(tr("<html>Please select the values to keep for the following tags.</html>")), gc);
     1272            pnl.add(new JLabel(tr("<html>Please select the values to keep for the following tags.</html>", null)), gc);
    12731273
    12741274            gc.gridy = 1;
    12751275            gc.fill = GridBagConstraints.HORIZONTAL;
    12761276            gc.weighty = 0.0;
    1277             pnl.add(cbShowTagsWithConflictsOnly = new JCheckBox(tr("Show tags with conflicts only")), gc);
    1278             pnl.add(cbShowTagsWithMultiValuesOnly = new JCheckBox(tr("Show tags with multiple values only")), gc);
     1277            pnl.add(cbShowTagsWithConflictsOnly = new JCheckBox(tr("Show tags with conflicts only", null)), gc);
     1278            pnl.add(cbShowTagsWithMultiValuesOnly = new JCheckBox(tr("Show tags with multiple values only", null)), gc);
    12791279            cbShowTagsWithConflictsOnly.addChangeListener(
    12801280                    new ChangeListener() {
Note: See TracChangeset for help on using the changeset viewer.