Ticket #19956: 19956.patch

File 19956.patch, 7.3 KB (added by GerdP, 5 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/DuplicateRelation.java

     
    2828import org.openstreetmap.josm.data.validation.Severity;
    2929import org.openstreetmap.josm.data.validation.Test;
    3030import org.openstreetmap.josm.data.validation.TestError;
     31import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3132import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3233import org.openstreetmap.josm.tools.MultiMap;
    3334
     
    201202
    202203    @Override
    203204    public void endTest() {
    204         super.endTest();
    205205        for (Set<OsmPrimitive> duplicated : relations.values()) {
    206206            if (duplicated.size() > 1) {
    207207                TestError testError = TestError.builder(this, Severity.ERROR, DUPLICATE_RELATION)
     
    222222            }
    223223        }
    224224        relationsNoKeys = null;
     225        super.endTest();
    225226    }
    226227
    227228    @Override
     
    245246     */
    246247    @Override
    247248    public Command fixError(TestError testError) {
    248         if (testError.getCode() == SAME_RELATION) return null;
    249         Set<Relation> relFix = testError.primitives(Relation.class)
    250                 .filter(r -> !r.isDeleted())
     249        if (!isFixable(testError))
     250            return null;
     251        Set<Relation> toFix = testError.primitives(Relation.class)
     252                .filter(this::isPrimitiveUsable)
    251253                .collect(Collectors.toSet());
    252254
    253         if (relFix.size() < 2)
     255        if (toFix.size() < 2)
    254256            return null;
    255257
     258        // see #19956 check again
     259        Test test2 = new DuplicateRelation();
     260        test2.startTest(NullProgressMonitor.INSTANCE);
     261        toFix.forEach(test2::visit);
     262        test2.endTest();
     263        boolean errorStillExists = false;
     264        for (TestError e : test2.getErrors()) {
     265            if (e.getCode() == testError.getCode() && e.getPrimitives().size() >= 2) {
     266                // refresh primitives, might be fewer than before
     267                toFix = e.primitives(Relation.class).collect(Collectors.toSet());
     268                errorStillExists = true;
     269                break;
     270            }
     271        }
     272        if (!errorStillExists)
     273            return null;
     274
    256275        long idToKeep = 0;
    257         Relation relationToKeep = relFix.iterator().next();
     276        Relation relationToKeep = toFix.iterator().next();
    258277        // Find the relation that is member of one or more relations. (If any)
    259278        Relation relationWithRelations = null;
    260279        Collection<Relation> relRef = null;
    261         for (Relation w : relFix) {
    262             Collection<Relation> rel = w.referrers(Relation.class).collect(Collectors.toList());
     280        for (Relation r : toFix) {
     281            Collection<Relation> rel = r.referrers(Relation.class).collect(Collectors.toList());
    263282            if (!rel.isEmpty()) {
    264283                if (relationWithRelations != null)
    265284                    throw new AssertionError("Cannot fix duplicate relations: More than one relation is member of another relation.");
    266                 relationWithRelations = w;
     285                relationWithRelations = r;
    267286                relRef = rel;
    268287            }
    269288            // Only one relation will be kept - the one with lowest positive ID, if such exist
    270289            // or one "at random" if no such exists. Rest of the relations will be deleted
    271             if (!w.isNew() && (idToKeep == 0 || w.getId() < idToKeep)) {
    272                 idToKeep = w.getId();
    273                 relationToKeep = w;
     290            if (!r.isNew() && (idToKeep == 0 || r.getId() < idToKeep)) {
     291                idToKeep = r.getId();
     292                relationToKeep = r;
    274293            }
    275294        }
    276295
     
    291310        }
    292311
    293312        // Delete all relations in the list
    294         relFix.remove(relationToKeep);
    295         commands.add(new DeleteCommand(relFix));
     313        toFix.remove(relationToKeep);
     314        commands.add(new DeleteCommand(toFix));
    296315        return new SequenceCommand(tr("Delete duplicate relations"), commands);
    297316    }
    298317
  • src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java

     
    2929import org.openstreetmap.josm.data.validation.Severity;
    3030import org.openstreetmap.josm.data.validation.Test;
    3131import org.openstreetmap.josm.data.validation.TestError;
     32import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3233import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3334import org.openstreetmap.josm.tools.MultiMap;
    3435
     
    122123
    123124    @Override
    124125    public void endTest() {
    125         super.endTest();
    126126        for (Set<OsmPrimitive> duplicated : ways.values()) {
    127127            if (duplicated.size() > 1) {
    128128                TestError testError = TestError.builder(this, Severity.ERROR, DUPLICATE_WAY)
     
    165165        ways = null;
    166166        waysNoTags = null;
    167167        knownHashCodes = null;
     168        super.endTest();
    168169    }
    169170
    170171    /**
     
    249250     */
    250251    @Override
    251252    public Command fixError(TestError testError) {
    252         Set<Way> wayz = testError.primitives(Way.class)
    253                 .filter(w -> !w.isDeleted())
     253        if (!isFixable(testError))
     254            return null;
     255
     256        Set<Way> toFix = testError.primitives(Way.class)
     257                .filter(this::isPrimitiveUsable)
    254258                .collect(Collectors.toSet());
    255259
    256         if (wayz.size() < 2)
     260        if (toFix.size() < 2)
    257261            return null;
    258262
     263        // see #19956 check again
     264        Test test2 = new DuplicateWay();
     265        test2.startTest(NullProgressMonitor.INSTANCE);
     266        toFix.forEach(test2::visit);
     267        test2.endTest();
     268        boolean errorStillExists = false;
     269        for (TestError e : test2.getErrors()) {
     270            if (e.getCode() == testError.getCode() && e.getPrimitives().size() >= 2) {
     271                // refresh primitives, might be fewer than before
     272                toFix = e.primitives(Way.class).collect(Collectors.toSet());
     273                errorStillExists = true;
     274                break;
     275            }
     276        }
     277        if (!errorStillExists)
     278            return null;
     279
    259280        long idToKeep = 0;
    260         Way wayToKeep = wayz.iterator().next();
     281        Way wayToKeep = toFix.iterator().next();
    261282        // Find the way that is member of one or more relations. (If any)
    262283        Way wayWithRelations = null;
    263284        List<Relation> relations = null;
    264         for (Way w : wayz) {
     285        for (Way w : toFix) {
    265286            List<Relation> rel = w.referrers(Relation.class).collect(Collectors.toList());
    266287            if (!rel.isEmpty()) {
    267288                if (wayWithRelations != null)
     
    295316
    296317        // Delete all ways in the list
    297318        // Note: nodes are not deleted, these can be detected and deleted at next pass
    298         wayz.remove(wayToKeep);
    299         commands.add(new DeleteCommand(wayz));
     319        toFix.remove(wayToKeep);
     320        commands.add(new DeleteCommand(toFix));
    300321        return new SequenceCommand(tr("Delete duplicate ways"), commands);
    301322    }
    302323