Ticket #17898: 17898.3.patch

File 17898.3.patch, 30.3 KB (added by GerdP, 6 years ago)
  • src/org/openstreetmap/josm/actions/CombineWayAction.java

     
    88import java.awt.event.ActionEvent;
    99import java.awt.event.KeyEvent;
    1010import java.util.ArrayList;
     11import java.util.Arrays;
    1112import java.util.Collection;
    1213import java.util.Collections;
    13 import java.util.HashSet;
    1414import java.util.LinkedHashSet;
    1515import java.util.LinkedList;
    1616import java.util.List;
     
    2222import javax.swing.JOptionPane;
    2323
    2424import org.openstreetmap.josm.actions.corrector.ReverseWayTagCorrector;
     25import org.openstreetmap.josm.actions.downloadtasks.DownloadReferrersTask;
    2526import org.openstreetmap.josm.command.ChangeCommand;
    2627import org.openstreetmap.josm.command.Command;
    2728import org.openstreetmap.josm.command.DeleteCommand;
     29import org.openstreetmap.josm.command.MissingDataHelper;
     30import org.openstreetmap.josm.command.MissingDataHelper.MissingDataStrategy;
     31import org.openstreetmap.josm.command.MissingDataHelper.WhenRelationOrderUncertain;
    2832import org.openstreetmap.josm.command.SequenceCommand;
    2933import org.openstreetmap.josm.data.UndoRedoHandler;
    3034import org.openstreetmap.josm.data.osm.DataSet;
     
    279283                    .show();
    280284            return;
    281285        }
     286        List<Node> path = tryJoin(selectedWays);
     287        if (path.isEmpty()) {
     288            warnCombiningImpossible();
     289            return;
     290        }
    282291
    283292        // see #18083: check if we will combine ways at nodes outside of the download area
    284         Set<Node> endNodesOutside = new HashSet<>();
    285         for (Way w : selectedWays) {
    286             final Node[] endnodes = {w.firstNode(), w.lastNode()};
    287             for (Node n : endnodes) {
    288                 if (!n.isNew() && n.isOutsideDownloadArea() && !endNodesOutside.add(n)) {
    289                     new Notification(tr("Combine ways refused<br>" + "(A shared node is outside of the download area)"))
    290                             .setIcon(JOptionPane.INFORMATION_MESSAGE).show();
    291                     return;
     293        Set<Way> unsureParents = selectedWays.stream().filter(
     294                w -> (Command.checkOutlyingOrIncompleteOperation(Arrays.asList(w.firstNode(), w.lastNode()), null)
     295                        & Command.IS_OUTSIDE) != 0)
     296                .collect(Collectors.toSet());
     297        if (!unsureParents.isEmpty()) {
     298            final String msg = tr(
     299                    "Modified data is not inside a downloaded area. Relations might be corrupted by combining the ways."
     300                            + "<br>" + "Download missing information from Server?");
    292301
    293                 }
     302            MissingDataStrategy missingDataStrategy = MissingDataHelper
     303                    .getUserDecision(WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD, "combine_ways_download_missing_data", msg);
     304            switch (missingDataStrategy) {
     305            case GO_AHEAD_WITH_DOWNLOADS:
     306                MainApplication.worker.submit(new DownloadReferrersTask(getLayerManager().getEditLayer(), unsureParents));
     307                break;
     308            case GO_AHEAD_WITHOUT_DOWNLOADS:
     309                // Proceed with the split with the information we have.
     310                // This can mean that we break relations.
     311                break;
     312            case USER_ABORTED:
     313            default:
     314                return;
    294315            }
    295316        }
    296317
    297         // combine and update gui
    298         Pair<Way, Command> combineResult;
    299         try {
    300             combineResult = combineWaysWorker(selectedWays);
    301         } catch (UserCancelException ex) {
    302             Logging.trace(ex);
    303             return;
    304         }
     318        GuiHelper.executeByMainWorkerInEDT(() -> {
     319            // combine and update gui
     320            Pair<Way, Command> combineResult;
     321            try {
     322                combineResult = combineWaysWorker(selectedWays);
     323            } catch (UserCancelException ex) {
     324                Logging.trace(ex);
     325                return;
     326            }
    305327
    306         if (combineResult == null)
    307             return;
     328            if (combineResult == null)
     329                return;
    308330
    309         final Way selectedWay = combineResult.a;
    310         UndoRedoHandler.getInstance().add(combineResult.b);
    311         Test test = new OverlappingWays();
    312         test.startTest(null);
    313         test.visit(combineResult.a);
    314         test.endTest();
    315         if (test.getErrors().isEmpty()) {
    316             test = new SelfIntersectingWay();
     331            final Way selectedWay = combineResult.a;
     332            UndoRedoHandler.getInstance().add(combineResult.b);
     333            Test test = new OverlappingWays();
    317334            test.startTest(null);
    318335            test.visit(combineResult.a);
    319336            test.endTest();
    320         }
    321         if (!test.getErrors().isEmpty()) {
    322             new Notification(test.getErrors().get(0).getMessage())
    323             .setIcon(JOptionPane.WARNING_MESSAGE)
    324             .setDuration(Notification.TIME_SHORT)
    325             .show();
    326         }
    327         if (selectedWay != null) {
    328             GuiHelper.runInEDT(() -> ds.setSelected(selectedWay));
    329         }
     337            if (test.getErrors().isEmpty()) {
     338                test = new SelfIntersectingWay();
     339                test.startTest(null);
     340                test.visit(combineResult.a);
     341                test.endTest();
     342            }
     343            if (!test.getErrors().isEmpty()) {
     344                new Notification(test.getErrors().get(0).getMessage())
     345                .setIcon(JOptionPane.WARNING_MESSAGE)
     346                .setDuration(Notification.TIME_SHORT)
     347                .show();
     348            }
     349            if (selectedWay != null) {
     350                ds.setSelected(selectedWay);
     351            }
     352        });
    330353    }
    331354
    332355    @Override
  • src/org/openstreetmap/josm/actions/SplitWayAction.java

     
    2525import javax.swing.JPanel;
    2626import javax.swing.ListSelectionModel;
    2727
     28import org.openstreetmap.josm.command.MissingDataHelper;
    2829import org.openstreetmap.josm.command.SplitWayCommand;
    2930import org.openstreetmap.josm.data.UndoRedoHandler;
    3031import org.openstreetmap.josm.data.osm.DataSet;
     
    293294                wayToKeep,
    294295                newWays,
    295296                !isMapModeDraw ? newSelection : null,
    296                 SplitWayCommand.WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD
     297                MissingDataHelper.WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD
    297298        );
    298299
    299300        splitWayCommand.ifPresent(result -> {
  • src/org/openstreetmap/josm/command/MissingDataHelper.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.command;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import javax.swing.JOptionPane;
     7
     8import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
     9import org.openstreetmap.josm.gui.MainApplication;
     10import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
     11
     12/**
     13 * Methods for actions which may corrupt relations. They should make sure that possible membership in relations is known
     14 * and that relations are not corrupted by the modification of the member.
     15 * @since xxx
     16 */
     17public class MissingDataHelper {
     18
     19    private MissingDataHelper() {
     20        // Hide default constructor for utils classes
     21    }
     22
     23    /**
     24     * What to do when the action might modify a member of a relation and either the parents
     25     * of the object are not known for certain or the action might need to add members in a specific order and that
     26     * order cannot be determined with the available information.
     27     * This can be used for unit tests.
     28     */
     29    public enum WhenRelationOrderUncertain {
     30        /**
     31         * Ask the user to consent to downloading the missing information. The user can abort the operation or choose to
     32         * proceed without downloading anything.
     33         */
     34        ASK_USER_FOR_CONSENT_TO_DOWNLOAD,
     35        /**
     36         * If needed information is missing, abort the action.
     37         */
     38        ABORT,
     39        /**
     40         * Perform the action even when needed information is missing, without downloading anything and risk to corrupt relations.
     41         */
     42        PERFORM_ANYWAY,
     43        /**
     44         * If needed information is missing, automatically download these without prompting the user.
     45         */
     46        DOWNLOAD_MISSING
     47    }
     48
     49    /**
     50     * What to do if needed data is missing.
     51     */
     52    public enum MissingDataStrategy {
     53        /** continue, download needed data */
     54        GO_AHEAD_WITH_DOWNLOADS,
     55        /** continue, don't download needed data and risk to break relations */
     56        GO_AHEAD_WITHOUT_DOWNLOADS,
     57        /** aboort action */
     58        USER_ABORTED
     59    }
     60
     61    /**
     62     * Check given preference key and optionally show dialog to ask user for confirmation regarding the download of missing data.
     63     * @param whenRelationOrderUncertain What to do when the action might corrupt relations and additional data is needed
     64     * @param prefKey the preference key which is used to store the user decision in case the answer is "Yes, download missing data"
     65     * @param msgText Text for the dialog
     66     * @return the strategy to use
     67     */
     68    public static MissingDataStrategy getUserDecision(WhenRelationOrderUncertain whenRelationOrderUncertain,
     69            String prefKey, String msgText) {
     70        switch (whenRelationOrderUncertain) {
     71        case ASK_USER_FOR_CONSENT_TO_DOWNLOAD:
     72            // Only ask the user about downloading missing data when they haven't consented to this before.
     73            if (ConditionalOptionPaneUtil.getDialogReturnValue(prefKey) == Integer.MAX_VALUE) {
     74                // User has previously told us downloading missing relation members is fine.
     75                return MissingDataStrategy.GO_AHEAD_WITH_DOWNLOADS;
     76            }
     77            // Ask the user.
     78            return offerToDownloadMissingDataIfNeeded(prefKey, msgText);
     79        case PERFORM_ANYWAY:
     80            return MissingDataStrategy.GO_AHEAD_WITHOUT_DOWNLOADS;
     81        case DOWNLOAD_MISSING:
     82            return MissingDataStrategy.GO_AHEAD_WITH_DOWNLOADS;
     83        case ABORT:
     84        default:
     85            return MissingDataStrategy.USER_ABORTED;
     86        }
     87    }
     88
     89    static MissingDataStrategy offerToDownloadMissingDataIfNeeded(String preferenceKey, String msgText) {
     90
     91        JMultilineLabel msg = new JMultilineLabel(msgText != null ? msgText :
     92                tr("Relations might be corrupted by this operation. Download missing information from Server?"));
     93
     94        String[] options = {
     95                tr("Yes, download"),
     96                tr("No, abort the operation"),
     97                tr("No, perform the operation without downloading")
     98        };
     99
     100        msg.setMaxWidth(600);
     101
     102        int ret = JOptionPane.showOptionDialog(
     103                MainApplication.getMainFrame(),
     104                msg,
     105                tr("Download missing information about relations?"),
     106                JOptionPane.OK_CANCEL_OPTION,
     107                JOptionPane.QUESTION_MESSAGE,
     108                null,
     109                options,
     110                options[0]
     111                );
     112
     113        switch (ret) {
     114        case JOptionPane.OK_OPTION:
     115            // Ask the user if they want to do this automatically from now on. We only ask this for the download
     116            // action, because automatically cancelling is confusing (the user can't tell why this happened), and
     117            // automatically performing the split without downloading missing parent relations is
     118            // likely to break relations.
     119            ConditionalOptionPaneUtil.showMessageDialog(
     120                    preferenceKey,
     121                    MainApplication.getMainFrame(),
     122                    tr("Missing information about relations will be downloaded. "
     123                            + "Should this be done automatically from now on?"),
     124                    tr("Download missing information about relations"),
     125                    JOptionPane.INFORMATION_MESSAGE
     126                    );
     127            return MissingDataStrategy.GO_AHEAD_WITH_DOWNLOADS;
     128        case JOptionPane.CANCEL_OPTION:
     129            return MissingDataStrategy.GO_AHEAD_WITHOUT_DOWNLOADS;
     130        default:
     131            return MissingDataStrategy.USER_ABORTED;
     132        }
     133    }
     134
     135}
  • src/org/openstreetmap/josm/command/SplitWayCommand.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.command;
    33
    4 import static org.openstreetmap.josm.command.SplitWayCommand.MissingMemberStrategy.GO_AHEAD_WITHOUT_DOWNLOADS;
    5 import static org.openstreetmap.josm.command.SplitWayCommand.MissingMemberStrategy.GO_AHEAD_WITH_DOWNLOADS;
    6 import static org.openstreetmap.josm.command.SplitWayCommand.MissingMemberStrategy.USER_ABORTED;
    7 import static org.openstreetmap.josm.command.SplitWayCommand.WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD;
    84import static org.openstreetmap.josm.tools.I18n.tr;
    95import static org.openstreetmap.josm.tools.I18n.trn;
    106
     
    2420import java.util.Set;
    2521import java.util.function.Consumer;
    2622
    27 import javax.swing.JOptionPane;
    28 
     23import org.openstreetmap.josm.command.MissingDataHelper.MissingDataStrategy;
     24import org.openstreetmap.josm.command.MissingDataHelper.WhenRelationOrderUncertain;
    2925import org.openstreetmap.josm.data.osm.DataSet;
    3026import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
    3127import org.openstreetmap.josm.data.osm.Node;
     
    3430import org.openstreetmap.josm.data.osm.Relation;
    3531import org.openstreetmap.josm.data.osm.RelationMember;
    3632import org.openstreetmap.josm.data.osm.Way;
    37 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    3833import org.openstreetmap.josm.gui.ExceptionDialogUtil;
    3934import org.openstreetmap.josm.gui.MainApplication;
    4035import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    41 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
    4236import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
     37import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
    4338import org.openstreetmap.josm.io.OsmTransferException;
    4439import org.openstreetmap.josm.spi.preferences.Config;
    4540import org.openstreetmap.josm.tools.CheckParameterUtil;
     
    5550public class SplitWayCommand extends SequenceCommand {
    5651
    5752    private static volatile Consumer<String> warningNotifier = Logging::warn;
    58     private static final String DOWNLOAD_MISSING_PREF_KEY = "split_way_download_missing_members";
     53    private static final String DOWNLOAD_MISSING_PREF_KEY = "split_way_download_missing_data";
    5954
    6055    private static final class RelationInformation {
    6156        boolean warnme;
     
    285280
    286281        // This method could be refactored to use an Optional in the future, but would need to be deprecated first
    287282        // to phase out use by plugins.
    288         return splitWay(way, wayChunks, selection, splitStrategy, ASK_USER_FOR_CONSENT_TO_DOWNLOAD).orElse(null);
     283        return splitWay(way, wayChunks, selection, splitStrategy,
     284                WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD).orElse(null);
    289285    }
    290286
    291287    /**
     
    344340                                                       List<Way> newWays,
    345341                                                       List<OsmPrimitive> newSelection,
    346342                                                       WhenRelationOrderUncertain whenRelationOrderUncertain) {
    347         if (whenRelationOrderUncertain == null) whenRelationOrderUncertain = ASK_USER_FOR_CONSENT_TO_DOWNLOAD;
     343        if (whenRelationOrderUncertain == null) whenRelationOrderUncertain = WhenRelationOrderUncertain.ASK_USER_FOR_CONSENT_TO_DOWNLOAD;
    348344
    349345        final int indexOfWayToKeep = newWays.indexOf(wayToKeep);
    350346        newWays.remove(wayToKeep);
    351347
     348        final String msg = tr("Relations might be corrupted by splitting the way. Download missing information from Server?");
     349
     350        MissingDataStrategy missingDataStrategy = null;
     351        if (!way.isNew() && (way.getDataSet().getDataSourceBounds().isEmpty()
     352                || way.getNodes().stream().allMatch(Node::isOutsideDownloadArea))) {
     353            missingDataStrategy = MissingDataHelper.getUserDecision(whenRelationOrderUncertain, DOWNLOAD_MISSING_PREF_KEY, msg);
     354            switch (missingDataStrategy) {
     355            case GO_AHEAD_WITH_DOWNLOADS:
     356                try {
     357                    downloadParents(way);
     358                } catch (OsmTransferException e) {
     359                    ExceptionDialogUtil.explainException(e);
     360                    return Optional.empty();
     361                }
     362                break;
     363            case GO_AHEAD_WITHOUT_DOWNLOADS:
     364                // Proceed with the split with the information we have.
     365                // This can mean that we break relations.
     366                break;
     367            case USER_ABORTED:
     368            default:
     369                return Optional.empty();
     370            }
     371        }
     372
    352373        // Figure out the order of relation members (if any).
    353374        Analysis analysis = analyseSplit(way, wayToKeep, newWays, indexOfWayToKeep);
    354375
     
    380401            }
    381402        }
    382403
    383         MissingMemberStrategy missingMemberStrategy;
    384404        if (relationsNeedingMoreMembers.isEmpty()) {
    385405            // The split can be performed without any extra downloads.
    386             missingMemberStrategy = GO_AHEAD_WITHOUT_DOWNLOADS;
     406            missingDataStrategy = MissingDataStrategy.GO_AHEAD_WITHOUT_DOWNLOADS;
    387407        } else {
    388             switch (whenRelationOrderUncertain) {
    389                 case ASK_USER_FOR_CONSENT_TO_DOWNLOAD:
    390                     // If the analysis shows that for some relations missing members should be downloaded, offer the user the
    391                     // chance to consent to this.
    392 
    393                     // Only ask the user about downloading missing members when they haven't consented to this before.
    394                     if (ConditionalOptionPaneUtil.getDialogReturnValue(DOWNLOAD_MISSING_PREF_KEY) == Integer.MAX_VALUE) {
    395                         // User has previously told us downloading missing relation members is fine.
    396                         missingMemberStrategy = GO_AHEAD_WITH_DOWNLOADS;
    397                     } else {
    398                         // Ask the user.
    399                         missingMemberStrategy = offerToDownloadMissingMembersIfNeeded(analysis, relationsNeedingMoreMembers);
    400                     }
    401                     break;
    402                 case SPLIT_ANYWAY:
    403                     missingMemberStrategy = GO_AHEAD_WITHOUT_DOWNLOADS;
    404                     break;
    405                 case DOWNLOAD_MISSING_MEMBERS:
    406                     missingMemberStrategy = GO_AHEAD_WITH_DOWNLOADS;
    407                     break;
    408                 case ABORT:
    409                 default:
    410                     missingMemberStrategy = USER_ABORTED;
    411                     break;
     408            if (missingDataStrategy == null) {
     409                missingDataStrategy = MissingDataHelper.getUserDecision(whenRelationOrderUncertain, DOWNLOAD_MISSING_PREF_KEY, msg);
    412410            }
    413411        }
    414 
    415         switch (missingMemberStrategy) {
    416             case GO_AHEAD_WITH_DOWNLOADS:
    417                 try {
    418                     downloadMissingMembers(incompleteMembers);
    419                 } catch (OsmTransferException e) {
    420                     ExceptionDialogUtil.explainException(e);
    421                     return Optional.empty();
    422                 }
    423                 // If missing relation members were downloaded, perform the analysis again to find the relation
    424                 // member order for all relations.
    425                 analysis = analyseSplit(way, wayToKeep, newWays, indexOfWayToKeep);
    426                 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
    427             case GO_AHEAD_WITHOUT_DOWNLOADS:
    428                 // Proceed with the split with the information we have.
    429                 // This can mean that there are no missing members we want, or that the user chooses to continue
    430                 // the split without downloading them.
    431                 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
    432             case USER_ABORTED:
    433             default:
     412        if (missingDataStrategy == MissingDataStrategy.USER_ABORTED)
     413            return Optional.empty();
     414        if (missingDataStrategy == MissingDataStrategy.GO_AHEAD_WITH_DOWNLOADS) {
     415            try {
     416                downloadMissingMembers(incompleteMembers);
     417            } catch (OsmTransferException e) {
     418                ExceptionDialogUtil.explainException(e);
    434419                return Optional.empty();
     420            }
     421            // If missing relation members were downloaded, perform the analysis again to find the relation
     422            // member order for all relations.
     423            analysis = analyseSplit(way, wayToKeep, newWays, indexOfWayToKeep);
    435424        }
     425        return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));
    436426    }
    437427
    438428    static Analysis analyseSplit(Way way,
     
    633623        }
    634624    }
    635625
    636     static MissingMemberStrategy offerToDownloadMissingMembersIfNeeded(Analysis analysis,
    637                                                                        List<Relation> relationsNeedingMoreMembers) {
    638         String[] options = {
    639                 tr("Yes, download the missing members"),
    640                 tr("No, abort the split operation"),
    641                 tr("No, perform the split without downloading")
    642         };
    643 
    644         String msgMemberOfRelations = trn(
    645                 "This way is part of a relation.",
    646                 "This way is part of {0} relations.",
    647                 analysis.getNumberOfRelations(),
    648                 analysis.getNumberOfRelations()
    649         );
    650 
    651         String msgReferToRelations;
    652         if (analysis.getNumberOfRelations() == 1) {
    653             msgReferToRelations = tr("this relation");
    654         } else if (analysis.getNumberOfRelations() == relationsNeedingMoreMembers.size()) {
    655             msgReferToRelations = tr("these relations");
    656         } else {
    657             msgReferToRelations = trn(
    658                     "one relation",
    659                     "{0} relations",
    660                     relationsNeedingMoreMembers.size(),
    661                     relationsNeedingMoreMembers.size()
    662             );
    663         }
    664 
    665         String msgRelationsMissingData = tr(
    666                 "For {0} the correct order of the new way parts could not be determined. " +
    667                         "To fix this, some missing relation members should be downloaded first.",
    668                 msgReferToRelations
    669         );
    670 
    671         JMultilineLabel msg = new JMultilineLabel(msgMemberOfRelations + " " + msgRelationsMissingData);
    672         msg.setMaxWidth(600);
    673 
    674         int ret = JOptionPane.showOptionDialog(
    675                 MainApplication.getMainFrame(),
    676                 msg,
    677                 tr("Download missing relation members?"),
    678                 JOptionPane.OK_CANCEL_OPTION,
    679                 JOptionPane.QUESTION_MESSAGE,
    680                 null,
    681                 options,
    682                 options[0]
    683         );
    684 
    685         switch (ret) {
    686             case JOptionPane.OK_OPTION:
    687                 // Ask the user if they want to do this automatically from now on. We only ask this for the download
    688                 // action, because automatically cancelling is confusing (the user can't tell why this happened), and
    689                 // automatically performing the split without downloading missing members despite needing them is
    690                 // likely to break a lot of routes. The user also can't tell the difference between a split that needs
    691                 // no downloads at all, and this special case where downloading missing relation members will prevent
    692                 // broken relations.
    693                 ConditionalOptionPaneUtil.showMessageDialog(
    694                         DOWNLOAD_MISSING_PREF_KEY,
    695                         MainApplication.getMainFrame(),
    696                         tr("Missing relation members will be downloaded. Should this be done automatically from now on?"),
    697                         tr("Downloading missing relation members"),
    698                         JOptionPane.INFORMATION_MESSAGE
    699                 );
    700                 return GO_AHEAD_WITH_DOWNLOADS;
    701             case JOptionPane.CANCEL_OPTION:
    702                 return GO_AHEAD_WITHOUT_DOWNLOADS;
    703             default:
    704                 return USER_ABORTED;
    705         }
    706     }
    707 
    708626    static void downloadMissingMembers(Set<OsmPrimitive> incompleteMembers) throws OsmTransferException {
    709627        // Download the missing members.
    710628        MultiFetchServerObjectReader reader = MultiFetchServerObjectReader.create();
     
    714632        MainApplication.getLayerManager().getEditLayer().mergeFrom(ds);
    715633    }
    716634
     635    private static void downloadParents(Way way) throws OsmTransferException {
     636        // Download possible parent relations
     637        OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(way);
     638        DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
     639        MainApplication.getLayerManager().getEditLayer().mergeFrom(ds);
     640    }
     641
    717642    static SplitWayCommand splitBasedOnAnalyses(Way way,
    718643                                                List<Way> newWays,
    719644                                                List<OsmPrimitive> newSelection,
     
    885810        return relationSpecialTypes;
    886811    }
    887812
    888     /**
    889      * What to do when the split way is part of relations, and the order of the new parts in the relation cannot be
    890      * determined without downloading missing relation members.
    891      */
    892     public enum WhenRelationOrderUncertain {
    893         /**
    894          * Ask the user to consent to downloading the missing members. The user can abort the operation or choose to
    895          * proceed without downloading anything.
    896          */
    897         ASK_USER_FOR_CONSENT_TO_DOWNLOAD,
    898         /**
    899          * If there are relation members missing, and these are needed to determine the order of the new parts in
    900          * that relation, abort the split operation.
    901          */
    902         ABORT,
    903         /**
    904          * If there are relation members missing, and these are needed to determine the order of the new parts in
    905          * that relation, continue with the split operation anyway, without downloading anything. Caution: use this
    906          * option with care.
    907          */
    908         SPLIT_ANYWAY,
    909         /**
    910          * If there are relation members missing, and these are needed to determine the order of the new parts in
    911          * that relation, automatically download these without prompting the user.
    912          */
    913         DOWNLOAD_MISSING_MEMBERS
    914     }
    915 
    916813    static class RelationAnalysis {
    917814        private final Relation relation;
    918815        private final RelationMember relationMember;
     
    965862        ROLE
    966863    }
    967864
    968     enum MissingMemberStrategy {
    969         GO_AHEAD_WITH_DOWNLOADS,
    970         GO_AHEAD_WITHOUT_DOWNLOADS,
    971         USER_ABORTED
    972     }
    973865}
  • test/data/regress/18596/data.osm

     
    11<?xml version='1.0' encoding='UTF-8'?>
    22<osm version='0.6' generator='JOSM' upload='never' download='never'>
     3  <bounds minlat='53.1855593' minlon='5.786497' maxlat='53.1912994' maxlon='5.799107' origin='fake bounds' />
    34  <node id='1001' version='1' visible='true' lat='53.18916486972' lon='5.79536381868' />
    45  <node id='1002' version='1' visible='true' lat='53.19109032103' lon='5.79066925796' />
    56  <node id='1003' version='1' visible='true' lat='53.18576597652' lon='5.79492806044' />
  • test/unit/org/openstreetmap/josm/command/SplitWayCommandTest.java

     
    1717import org.junit.Test;
    1818import org.openstreetmap.josm.TestUtils;
    1919import org.openstreetmap.josm.command.SplitWayCommand.Strategy;
     20import org.openstreetmap.josm.data.Bounds;
     21import org.openstreetmap.josm.data.DataSource;
    2022import org.openstreetmap.josm.data.UndoRedoHandler;
    2123import org.openstreetmap.josm.data.coor.LatLon;
    2224import org.openstreetmap.josm.data.osm.DataSet;
     
    150152    @Test
    151153    public void testOneMemberOrderedRelationShowsWarningTest() {
    152154        final DataSet dataSet = new DataSet();
     155        dataSet.addDataSource(new DataSource(new Bounds(-180, -90, 180, 90), "Test"));
    153156
    154157        // Positive IDs to mark that these ways are incomplete (i.e., no nodes loaded).
    155158        final Way w1 = new Way(1);
     
    180183                SplitWayCommand.buildSplitChunks(w2, Collections.singletonList(n2)),
    181184                new ArrayList<>(),
    182185                Strategy.keepLongestChunk(),
    183                 SplitWayCommand.WhenRelationOrderUncertain.ABORT
     186                MissingDataHelper.WhenRelationOrderUncertain.ABORT
    184187        );
    185188
    186189        assertFalse(result.isPresent());
     
    311314                    new ArrayList<>(),
    312315                    Strategy.keepLongestChunk(),
    313316                    // This split requires no additional downloads.
    314                     SplitWayCommand.WhenRelationOrderUncertain.ABORT
     317                    MissingDataHelper.WhenRelationOrderUncertain.ABORT
    315318            );
    316319
    317320            assertTrue(result.isPresent());
     
    359362                    new ArrayList<>(),
    360363                    Strategy.keepLongestChunk(),
    361364                    // This split requires no additional downloads. If any are needed, this command will fail.
    362                     SplitWayCommand.WhenRelationOrderUncertain.ABORT
     365                    MissingDataHelper.WhenRelationOrderUncertain.ABORT
    363366            );
    364367
    365368            // Should not result in aborting the split.