Ignore:
Timestamp:
2020-09-29T16:37:29+02:00 (4 years ago)
Author:
GerdP
Message:

fix #19864: DataIntegrityProblemException: Deleted member referenced

  • create only one change command for each parent relation
  • delete all merged nodes in a final command
File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/MergeAddrPointsAction.java

    r35474 r35563  
    77import java.awt.event.ActionEvent;
    88import java.awt.event.KeyEvent;
     9import java.util.ArrayList;
    910import java.util.Collection;
    1011import java.util.Collections;
     
    1516import java.util.Map;
    1617import java.util.Map.Entry;
     18import java.util.stream.Collectors;
    1719import java.util.Set;
    1820
     
    3436import org.openstreetmap.josm.gui.Notification;
    3537import org.openstreetmap.josm.tools.Geometry;
     38import org.openstreetmap.josm.tools.Pair;
    3639import org.openstreetmap.josm.tools.Shortcut;
    3740
     
    109112        int multi = 0;
    110113        int conflicts = 0;
    111 
     114        List<Pair<Node, Way>> replaced = new ArrayList<>();
     115        Set<Relation> modifiedRelations = new HashSet<>();
    112116        for (Way w : buildings) {
    113117            Node mergeNode = null;
     
    147151                    cmds.add(new ChangePropertyCommand(Collections.singleton(w), tags));
    148152                if (!hasConflicts) {
    149                     for (OsmPrimitive p : mergeNode.getReferrers()) {
    150                         Relation r = (Relation) p;
    151                         Relation rnew = new Relation(r);
    152                         for (int i = 0; i < r.getMembersCount(); i++) {
    153                             RelationMember member = r.getMember(i);
    154                             if (mergeNode.equals(member.getMember())) {
    155                                 rnew.removeMember(i);
    156                                 rnew.addMember(i, new RelationMember(member.getRole(), w));
    157                             }
    158                         }
    159                         cmds.add(new ChangeCommand(r, rnew));
    160                     }
    161                     cmds.add(new DeleteCommand(mergeNode));
    162                 }
    163             }
    164         }
     153                    replaced.add(Pair.create(mergeNode, w));
     154                    modifiedRelations.addAll(mergeNode.referrers(Relation.class).collect(Collectors.toList()));
     155                }
     156            }
     157        }
     158
     159        for (Relation r : modifiedRelations) {
     160            Relation rnew = new Relation(r);
     161            boolean modified = false;
     162            for (Pair<Node, Way> repl : replaced) {
     163                for (int i = 0; i < rnew.getMembersCount(); i++) {
     164                    RelationMember member = rnew.getMember(i);
     165                    if (repl.a.equals(member.getMember())) {
     166                        rnew.removeMember(i);
     167                        rnew.addMember(i, new RelationMember(member.getRole(), repl.b));
     168                        modified = true;
     169                    }
     170                }
     171            }
     172            if (modified) {
     173                cmds.add(new ChangeCommand(r, rnew));
     174            }
     175        }
     176        cmds.add(new DeleteCommand(replaced.stream().map(p -> p.a).collect(Collectors.toList())));
     177
    165178        if (multi != 0)
    166179            new Notification(trn("There is {0} building with multiple address nodes inside",
Note: See TracChangeset for help on using the changeset viewer.