Ignore:
Timestamp:
2008-09-18T15:19:00+02:00 (16 years ago)
Author:
stoecker
Message:

make advanced object deletion available for outside, so validator can use it

File:
1 edited

Legend:

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

    r850 r988  
    77import java.awt.event.KeyEvent;
    88import java.awt.event.MouseEvent;
    9 import java.util.ArrayList;
    10 import java.util.Collection;
    119import java.util.Collections;
    12 import java.util.HashSet;
    13 import java.util.HashMap;
    14 import java.util.Iterator;
    15 import java.util.LinkedList;
    16 import java.util.List;
    17 
    18 import javax.swing.JOptionPane;
    1910
    2011import org.openstreetmap.josm.Main;
    21 import org.openstreetmap.josm.command.*;
    22 import org.openstreetmap.josm.data.osm.Node;
     12import org.openstreetmap.josm.command.Command;
     13import org.openstreetmap.josm.command.DeleteCommand;
    2314import org.openstreetmap.josm.data.osm.OsmPrimitive;
    24 import org.openstreetmap.josm.data.osm.Way;
    2515import org.openstreetmap.josm.data.osm.WaySegment;
    26 import org.openstreetmap.josm.data.osm.Relation;
    27 import org.openstreetmap.josm.data.osm.RelationMember;
    28 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
    29 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
    3016import org.openstreetmap.josm.gui.MapFrame;
    31 import org.openstreetmap.josm.tools.*;
     17import org.openstreetmap.josm.tools.ImageProvider;
    3218
    3319/**
     
    8874                Command c;
    8975                if (ctrl) {
    90                         c = deleteWithReferences(Main.ds.getSelected());
     76                        c = DeleteCommand.deleteWithReferences(Main.ds.getSelected());
    9177                } else {
    92                         c = delete(Main.ds.getSelected(), !alt);
     78                        c = DeleteCommand.delete(Main.ds.getSelected(), !alt);
    9379                }
    9480                if (c != null) {
     
    9783
    9884                Main.map.repaint();
    99     }
     85        }
    10086
    10187        /**
     
    118104                        if (ws != null) {
    119105                                if (shift) {
    120                                         c = deleteWaySegment(ws);
     106                                        c = DeleteCommand.deleteWaySegment(ws);
    121107                                } else if (ctrl) {
    122                                         c = deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
     108                                        c = DeleteCommand.deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));
    123109                                } else {
    124                                         c = delete(Collections.singleton((OsmPrimitive)ws.way), !alt);
     110                                        c = DeleteCommand.delete(Collections.singleton((OsmPrimitive)ws.way), !alt);
    125111                                }
    126112                        }
    127113                } else if (ctrl) {
    128                         c = deleteWithReferences(Collections.singleton(sel));
     114                        c = DeleteCommand.deleteWithReferences(Collections.singleton(sel));
    129115                } else {
    130                         c = delete(Collections.singleton(sel), !alt);
     116                        c = DeleteCommand.delete(Collections.singleton(sel), !alt);
    131117                }
    132118                if (c != null) {
     
    136122                Main.map.mapView.repaint();
    137123        }
    138 
    139         /**
    140          * Delete the primitives and everything they reference.
    141          *
    142          * If a node is deleted, the node and all ways and relations
    143          * the node is part of are deleted as well.
    144          *
    145          * If a way is deleted, all relations the way is member of are also deleted.
    146          *
    147          * If a way is deleted, only the way and no nodes are deleted.
    148          *
    149          * @param selection The list of all object to be deleted.
    150          * @return command A command to perform the deletions, or null of there is
    151          * nothing to delete.
    152          */
    153         private Command deleteWithReferences(Collection<OsmPrimitive> selection) {
    154                 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);
    155                 for (OsmPrimitive osm : selection)
    156                         osm.visit(v);
    157                 v.data.addAll(selection);
    158                 if (v.data.isEmpty())
    159                         return null;
    160                 return new DeleteCommand(v.data);
    161         }
    162 
    163         /**
    164          * Try to delete all given primitives.
    165          *
    166          * If a node is used by a way, it's removed from that way.  If a node or a
    167          * way is used by a relation, inform the user and do not delete.
    168          *
    169          * If this would cause ways with less than 2 nodes to be created, delete
    170          * these ways instead.  If they are part of a relation, inform the user
    171          * and do not delete.
    172          *
    173          * @param selection The objects to delete.
    174          * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well
    175          * @return command A command to perform the deletions, or null of there is
    176          * nothing to delete.
    177          */
    178         private int testRelation(Relation ref, OsmPrimitive osm)
    179         {
    180                 NameVisitor n = new NameVisitor();
    181                 ref.visit(n);
    182                 NameVisitor s = new NameVisitor();
    183                 osm.visit(s);
    184                 String role = new String();
    185                 for (RelationMember m : ref.members)
    186                 {
    187                         if (m.member == osm)
    188                         {
    189                                 role = m.role;
    190                                 break;
    191                         }
    192                 }
    193                 if (role.length() > 0)
    194                 {
    195                         return JOptionPane.showConfirmDialog(Main.parent,
    196                         tr("Selection \"{0}\" is used by relation \"{1}\" with role {2}.\nDelete from relation?", s.name, n.name, role),
    197                         tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
    198                 }
    199                 else
    200                 {
    201                         return JOptionPane.showConfirmDialog(Main.parent,
    202                         tr("Selection \"{0}\" is used by relation \"{1}\".\nDelete from relation?", s.name, n.name),
    203                         tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);
    204                 }
    205         }
    206 
    207         private Command delete(Collection<OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {
    208                 if (selection.isEmpty()) return null;
    209 
    210                 Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);
    211                 Collection<Way> waysToBeChanged = new HashSet<Way>();
    212                 HashMap<OsmPrimitive, Collection<OsmPrimitive>> relationsToBeChanged = new HashMap<OsmPrimitive, Collection<OsmPrimitive>>();
    213 
    214                 if (alsoDeleteNodesInWay) {
    215                         // Delete untagged nodes that are to be unreferenced.
    216                         Collection<OsmPrimitive> delNodes = new HashSet<OsmPrimitive>();
    217                         for (OsmPrimitive osm : del) {
    218                                 if (osm instanceof Way) {
    219                                         for (Node n : ((Way)osm).nodes) {
    220                                                 if (!n.tagged) {
    221                                                         CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
    222                                                         n.visit(v);
    223                                                         v.data.removeAll(del);
    224                                                         if (v.data.isEmpty()) {
    225                                                                 delNodes.add(n);
    226                                                         }
    227                                                 }
    228                                         }
    229                                 }
    230                         }
    231                         del.addAll(delNodes);
    232                 }
    233                
    234                 for (OsmPrimitive osm : del) {
    235                         CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
    236                         osm.visit(v);
    237                         for (OsmPrimitive ref : v.data) {
    238                                 if (del.contains(ref)) continue;
    239                                 if (ref instanceof Way) {
    240                                         waysToBeChanged.add((Way) ref);
    241                                 } else if (ref instanceof Relation) {
    242                                         if (testRelation((Relation)ref, osm) == JOptionPane.YES_OPTION)
    243                                         {
    244                                                 Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
    245                                                 if(relset == null) relset = new HashSet<OsmPrimitive>();
    246                                                 relset.add(osm);
    247                                                 relationsToBeChanged.put(ref, relset);
    248                                         }
    249                                         else
    250                                                 return null;
    251                                 } else {
    252                                         return null;
    253                                 }
    254                         }
    255                 }
    256 
    257                 Collection<Command> cmds = new LinkedList<Command>();
    258                 for (Way w : waysToBeChanged) {
    259                         Way wnew = new Way(w);
    260                         wnew.nodes.removeAll(del);
    261                         if (wnew.nodes.size() < 2) {
    262                                 del.add(w);
    263 
    264                                 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);
    265                                 w.visit(v);
    266                                 for (OsmPrimitive ref : v.data) {
    267                                         if (del.contains(ref)) continue;
    268                                         if (ref instanceof Relation) {
    269                                                 Boolean found = false;
    270                                                 Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);
    271                                                 if (relset == null)
    272                                                         relset = new HashSet<OsmPrimitive>();
    273                                                 else
    274                                                 {
    275                                                         for (OsmPrimitive m : relset) {
    276                                                                 if(m == w)
    277                                                                 {
    278                                                                         found = true;
    279                                                                         break;
    280                                                                 }
    281                                                         }
    282                                                 }
    283                                                 if (!found)
    284                                                 {
    285                                                         if (testRelation((Relation)ref, w) == JOptionPane.YES_OPTION)
    286                                                         {
    287                                                                 relset.add(w);
    288                                                                 relationsToBeChanged.put(ref, relset);
    289                                                         }
    290                                                         else
    291                                                                 return null;
    292                                                 }
    293                                         } else {
    294                                                 return null;
    295                                         }
    296                                 }
    297                         } else {
    298                                 cmds.add(new ChangeCommand(w, wnew));
    299                         }
    300                 }
    301 
    302                 Iterator<OsmPrimitive> iterator = relationsToBeChanged.keySet().iterator();
    303                 while(iterator.hasNext())
    304                 {
    305                         Relation cur = (Relation)iterator.next();
    306                         Relation rel = new Relation(cur);
    307                         for(OsmPrimitive osm : relationsToBeChanged.get(cur))
    308                         {
    309                                 for (RelationMember rm : rel.members) {
    310                                         if (rm.member == osm)
    311                                         {
    312                                                 RelationMember mem = new RelationMember();
    313                                                 mem.role = rm.role;
    314                                                 mem.member = rm.member;
    315                                                 rel.members.remove(mem);
    316                                                 break;
    317                                         }
    318                                 }
    319                         }
    320                         cmds.add(new ChangeCommand(cur, rel));
    321                 }
    322 
    323                 if (!del.isEmpty()) cmds.add(new DeleteCommand(del));
    324 
    325                 return new SequenceCommand(tr("Delete"), cmds);
    326         }
    327 
    328         private Command deleteWaySegment(WaySegment ws) {
    329                 List<Node> n1 = new ArrayList<Node>(),
    330                         n2 = new ArrayList<Node>();
    331 
    332                 n1.addAll(ws.way.nodes.subList(0, ws.lowerIndex + 1));
    333                 n2.addAll(ws.way.nodes.subList(ws.lowerIndex + 1, ws.way.nodes.size()));
    334 
    335                 if (n1.size() < 2 && n2.size() < 2) {
    336                         return new DeleteCommand(Collections.singleton(ws.way));
    337                 }
    338                
    339                 Way wnew = new Way(ws.way);
    340                 wnew.nodes.clear();
    341 
    342                 if (n1.size() < 2) {
    343                         wnew.nodes.addAll(n2);
    344                         return new ChangeCommand(ws.way, wnew);
    345                 } else if (n2.size() < 2) {
    346                         wnew.nodes.addAll(n1);
    347                         return new ChangeCommand(ws.way, wnew);
    348                 } else {
    349                         Collection<Command> cmds = new LinkedList<Command>();
    350 
    351                         wnew.nodes.addAll(n1);
    352                         cmds.add(new ChangeCommand(ws.way, wnew));
    353 
    354                         Way wnew2 = new Way();
    355                         if (wnew.keys != null) {
    356                                 wnew2.keys = new HashMap<String, String>(wnew.keys);
    357                                 wnew2.checkTagged();
    358                                 wnew2.checkDirectionTagged();
    359                         }
    360                         wnew2.nodes.addAll(n2);
    361                         cmds.add(new AddCommand(wnew2));
    362 
    363                         return new SequenceCommand(tr("Split way segment"), cmds);
    364                 }
    365         }
    366124       
    367125        @Override public String getModeHelpText() {
Note: See TracChangeset for help on using the changeset viewer.