This uses the new reverse lookup code and some of the new commands to greatly simplify the CombineWayAction code.
--- core-dave/src/org/openstreetmap/josm/actions/CombineWayAction.java | 89 ++++------ 1 file changed, 39 insertions(+), 50 deletions(-) diff -puN src/org/openstreetmap/josm/actions/CombineWayAction.java~combine-way-action-mods src/org/openstreetmap/josm/actions/CombineWayAction.java --- core/src/org/openstreetmap/josm/actions/CombineWayAction.java~combine-way-action-mods 2008-04-28 18:59:27.000000000 -0700 +++ core-dave/src/org/openstreetmap/josm/actions/CombineWayAction.java 2008-04-28 18:59:27.000000000 -0700 @@ -1,4 +1,3 @@ -// License: GPL. Copyright 2007 by Immanuel Scholz and others package org.openstreetmap.josm.actions; import static org.openstreetmap.josm.tools.I18n.tr; @@ -25,10 +24,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import org.openstreetmap.josm.Main; -import org.openstreetmap.josm.command.ChangeCommand; -import org.openstreetmap.josm.command.Command; -import org.openstreetmap.josm.command.DeleteCommand; -import org.openstreetmap.josm.command.SequenceCommand; +import org.openstreetmap.josm.command.*; import org.openstreetmap.josm.data.SelectionChangedListener; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; @@ -38,6 +34,7 @@ import org.openstreetmap.josm.data.osm.R import org.openstreetmap.josm.data.osm.TigerUtils; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.tools.GBC; +import org.openstreetmap.josm.tools.ReverseLookup; import org.openstreetmap.josm.tools.Pair; /** @@ -52,7 +49,7 @@ public class CombineWayAction extends Jo DataSet.selListeners.add(this); } - public void actionPerformed(ActionEvent event) { + @SuppressWarnings("unchecked") public void actionPerformed(ActionEvent event) { Collection<OsmPrimitive> selection = Main.ds.getSelected(); LinkedList<Way> selectedWays = new LinkedList<Way>(); @@ -75,45 +72,24 @@ public class CombineWayAction extends Jo // Step 1, iterate over all relations and figure out which of our // selected ways are members of a relation. - HashMap<Pair<Relation,String>, HashSet<Way>> backlinks = - new HashMap<Pair<Relation,String>, HashSet<Way>>(); - HashSet<Relation> relationsUsingWays = new HashSet<Relation>(); - for (Relation r : Main.ds.relations) { - if (r.deleted || r.incomplete) continue; - for (RelationMember rm : r.members) { - if (rm.member instanceof Way) { - for(Way w : selectedWays) { - if (rm.member == w) { - Pair<Relation,String> pair = new Pair<Relation,String>(r, rm.role); - HashSet<Way> waylinks = new HashSet<Way>(); - if (backlinks.containsKey(pair)) { - waylinks = backlinks.get(pair); - } else { - waylinks = new HashSet<Way>(); - backlinks.put(pair, waylinks); - } - waylinks.add(w); - - // this is just a cache for later use - relationsUsingWays.add(r); - } - } - } - } - } + HashSet<Relation> relationsUsingWays = ReverseLookup.relationsUsingWays(selectedWays); // Complain to the user if the ways don't have equal memberships. - for (HashSet<Way> waylinks : backlinks.values()) { - if (!waylinks.containsAll(selectedWays)) { - int option = JOptionPane.showConfirmDialog(Main.parent, - tr("The selected ways have differing relation memberships. " - + "Do you still want to combine them?"), - tr("Combine ways with different memberships?"), - JOptionPane.YES_NO_OPTION); + int option = JOptionPane.DEFAULT_OPTION; + for (Relation r : relationsUsingWays) { + for (Way w : selectedWays) { + if (r.members.contains(w)) + continue; + option = JOptionPane.showConfirmDialog(Main.parent, + tr("The selected ways have differing relation memberships. " + + "Do you still want to combine them?"), + tr("Combine ways with different memberships?"), + JOptionPane.YES_NO_OPTION); if (option == JOptionPane.YES_OPTION) break; - return; } + if (option == JOptionPane.YES_OPTION) + break; } // collect properties for later conflict resolving @@ -133,7 +109,7 @@ public class CombineWayAction extends Jo } else { Object secondTry = actuallyCombineWays(selectedWays, true); if (secondTry instanceof List) { - int option = JOptionPane.showConfirmDialog(Main.parent, + option = JOptionPane.showConfirmDialog(Main.parent, tr("The ways can not be combined in their current directions. " + "Do you want to reverse some of them?"), tr("Change directions?"), JOptionPane.YES_NO_OPTION); @@ -147,15 +123,30 @@ public class CombineWayAction extends Jo } } - Way newWay = new Way(selectedWays.get(0)); - newWay.nodes.clear(); - newWay.nodes.addAll(nodeList); + LinkedList<Command> cmds = new LinkedList<Command>(); + Way newWay = selectedWays.get(0); + for (int i = 0; i < nodeList.size(); i++) { + Node newn = nodeList.get(i); + Node old = null; + if (i < newWay.nodes.size()) + old = newWay.nodes.get(i); + if (old == newn) + continue; + if (old == null) { + cmds.add(new AddNodeToWayCommand(newWay, newn, i)); + continue; + } + cmds.add(new ReplaceNodeInWayCommand(newWay, old, newn, i)); + } // display conflict dialog Map<String, JComboBox> components = new HashMap<String, JComboBox>(); JPanel p = new JPanel(new GridBagLayout()); for (Entry<String, Set<String>> e : props.entrySet()) { - if (TigerUtils.isTigerTag(e.getKey())) { + if (e.getKey().equals("source")) { + // just punt on source for now, it's not important enough to keep + newWay.put(e.getKey(), e.getValue().iterator().next()); + } else if (TigerUtils.isTigerTag(e.getKey())) { String combined = TigerUtils.combineTags(e.getKey(), e.getValue()); newWay.put(e.getKey(), combined); } else if (e.getValue().size() > 1) { @@ -177,9 +168,7 @@ public class CombineWayAction extends Jo newWay.put(e.getKey(), e.getValue().getEditor().getItem().toString()); } - LinkedList<Command> cmds = new LinkedList<Command>(); cmds.add(new DeleteCommand(selectedWays.subList(1, selectedWays.size()))); - cmds.add(new ChangeCommand(selectedWays.peek(), newWay)); // modify all relations containing the now-deleted ways for (Relation r : relationsUsingWays) { @@ -192,13 +181,13 @@ public class CombineWayAction extends Jo if (selectedWays.contains(rm.member)) { rolesToReAdd.add(rm.role); } else { - newRel.members.add(rm); + cmds.add(new AddRelationMemberCommand(r, rm)); } } for (String role : rolesToReAdd) { - newRel.members.add(new RelationMember(role, selectedWays.peek())); + RelationMember rm = new RelationMember(role, selectedWays.peek()); + cmds.add(new AddRelationMemberCommand(r, rm)); } - cmds.add(new ChangeCommand(r, newRel)); } Main.main.undoRedo.add(new SequenceCommand(tr("Combine {0} ways", selectedWays.size()), cmds)); Main.ds.setSelected(selectedWays.peek()); _ _______________________________________________ josm-dev mailing list josm-dev@openstreetmap.org http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev