Ticket #17898: 17898-download-areas.patch

File 17898-download-areas.patch, 8.3 KB (added by GerdP, 6 years ago)

patch implemets the download areas strategy, also contains 18863-detect-broken.2.patch

  • src/org/openstreetmap/josm/command/SplitWayCommand.java

     
    2626
    2727import javax.swing.JOptionPane;
    2828
     29import org.openstreetmap.josm.data.Bounds;
    2930import org.openstreetmap.josm.data.osm.DataSet;
    3031import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
    3132import org.openstreetmap.josm.data.osm.Node;
     
    3940import org.openstreetmap.josm.gui.MainApplication;
    4041import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    4142import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
     43import org.openstreetmap.josm.io.BoundingBoxDownloader;
    4244import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
    4345import org.openstreetmap.josm.io.OsmTransferException;
    4446import org.openstreetmap.josm.spi.preferences.Config;
     
    5658
    5759    private static volatile Consumer<String> warningNotifier = Logging::warn;
    5860    private static final String DOWNLOAD_MISSING_PREF_KEY = "split_way_download_missing_members";
     61    private static final String DOWNLOAD_MISSING_PARENT_PREF_KEY = "split_way_download_missing_parents";
    5962
    6063    private static final class RelationInformation {
    6164        boolean warnme;
     
    349352        final int indexOfWayToKeep = newWays.indexOf(wayToKeep);
    350353        newWays.remove(wayToKeep);
    351354
     355        if (!way.isNew() && (way.getDataSet().getDataSourceBounds().isEmpty()
     356                || way.getNodes().stream().allMatch(Node::isOutsideDownloadArea))) {
     357            MissingParentsStrategy missingParentsStrategy;
     358            if (ConditionalOptionPaneUtil.getDialogReturnValue(DOWNLOAD_MISSING_PARENT_PREF_KEY) == Integer.MAX_VALUE) {
     359                // User has previously told us downloading missing relations is fine.
     360                missingParentsStrategy = MissingParentsStrategy.GO_AHEAD_WITH_DOWNLOADS;
     361            } else {
     362                // Ask the user.
     363                missingParentsStrategy = offerToDownloadMissingParentsIfNeeded();
     364            }
     365            switch (missingParentsStrategy) {
     366            case GO_AHEAD_WITH_DOWNLOADS:
     367                try {
     368                    downloadParents(way);
     369                } catch (OsmTransferException e) {
     370                    ExceptionDialogUtil.explainException(e);
     371                    return Optional.empty();
     372                }
     373                break;
     374            case GO_AHEAD_WITHOUT_DOWNLOADS:
     375                // Proceed with the split with the information we have.
     376                // This can mean that we break relations.
     377                break;
     378            case USER_ABORTED:
     379            default:
     380                return Optional.empty();
     381            }
     382
     383        }
    352384        // Figure out the order of relation members (if any).
    353385        Analysis analysis = analyseSplit(way, wayToKeep, newWays, indexOfWayToKeep);
    354386
     
    472504            int ir = 0;
    473505            List<RelationMember> relationMembers = r.getMembers();
    474506            for (RelationMember rm : relationMembers) {
    475                 if (rm.isWay() && rm.getMember() == way) {
     507                if (rm.getMember() == way) {
    476508                    boolean insert = true;
    477509                    if (relationSpecialTypes.containsKey(type) && "restriction".equals(relationSpecialTypes.get(type))) {
    478510                        RelationInformation rValue = treatAsRestriction(r, rm, c, newWays, way, changedWay);
     
    541573                                    // won't help in any case.
    542574                                    direction = Direction.IRRELEVANT;
    543575                                }
     576                                if (direction == Direction.UNKNOWN && (!way.firstNode().isOutsideDownloadArea()
     577                                        || way.lastNode().isOutsideDownloadArea())) {
     578                                    // check if any other complete way in the relation is connected to the way
     579                                    // if so, the order of the relation is broken
     580                                    for (int i = 0; i < r.getMembersCount(); i++) {
     581                                        if (i >= ir - 1 && i <= ir + 1)
     582                                            continue;
     583                                        RelationMember rmTest = r.getMember(i);
     584                                        if (rmTest.isWay() && !rmTest.getMember().isIncomplete() &&
     585                                            (way.isFirstLastNode(rmTest.getWay().firstNode())
     586                                                    || way.isFirstLastNode(rm.getWay().lastNode()))) {
     587                                                direction = Direction.IRRELEVANT;
     588                                                break;
     589                                        }
     590                                    }
     591                                }
    544592                            }
    545593                        } else {
    546594                            int k = 1;
     
    708756        MainApplication.getLayerManager().getEditLayer().mergeFrom(ds);
    709757    }
    710758
     759    static MissingParentsStrategy offerToDownloadMissingParentsIfNeeded() {
     760        String[] options = {
     761                tr("Yes, download areas"),
     762                tr("No, abort the split operation"),
     763                tr("No, perform the split without downloading")
     764        };
     765
     766        JMultilineLabel msg = new JMultilineLabel(tr("This way may be part of a relation. <br>"
     767                + "None of the nodes of this way is in a download area. If the way is member of one or more relations "
     768                + "those relations might need to be updated.<br> Download area around end nodes to get needed information?"));
     769        msg.setMaxWidth(600);
     770
     771        int ret = JOptionPane.showOptionDialog(
     772                MainApplication.getMainFrame(),
     773                msg,
     774                tr("Download missing information about parent relations?"),
     775                JOptionPane.OK_CANCEL_OPTION,
     776                JOptionPane.QUESTION_MESSAGE,
     777                null,
     778                options,
     779                options[0]
     780                );
     781
     782        switch (ret) {
     783        case JOptionPane.OK_OPTION:
     784            // Ask the user if they want to do this automatically from now on. We only ask this for the download
     785            // action, because automatically cancelling is confusing (the user can't tell why this happened), and
     786            // automatically performing the split without downloading missing parent relations is
     787            // likely to break relations.
     788            ConditionalOptionPaneUtil.showMessageDialog(
     789                    DOWNLOAD_MISSING_PARENT_PREF_KEY,
     790                    MainApplication.getMainFrame(),
     791                    tr("Missing parent relations will be downloaded. Should this be done automatically from now on?"),
     792                    tr("Downloading missing parent relation"),
     793                    JOptionPane.INFORMATION_MESSAGE
     794                    );
     795            return MissingParentsStrategy.GO_AHEAD_WITH_DOWNLOADS;
     796        case JOptionPane.CANCEL_OPTION:
     797            return MissingParentsStrategy.GO_AHEAD_WITHOUT_DOWNLOADS;
     798        default:
     799            return MissingParentsStrategy.USER_ABORTED;
     800        }
     801    }
     802
     803
     804    private static void downloadParents(Way way) throws OsmTransferException {
     805        // Download possible parent relations
     806        Set<Node> endNodes = new HashSet<>(Arrays.asList(way.firstNode(), way.lastNode()));
     807        for (Node n : endNodes) {
     808            if (n.isOutsideDownloadArea() || n.getDataSet().getDataSourceBounds().isEmpty()) {
     809                BoundingBoxDownloader reader = new BoundingBoxDownloader(new Bounds(n.getCoor(), true));
     810                DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
     811                MainApplication.getLayerManager().getEditLayer().mergeFrom(ds);
     812            }
     813        }
     814    }
     815
    711816    static SplitWayCommand splitBasedOnAnalyses(Way way,
    712817                                                List<Way> newWays,
    713818                                                List<OsmPrimitive> newSelection,
     
    9641069        GO_AHEAD_WITHOUT_DOWNLOADS,
    9651070        USER_ABORTED
    9661071    }
     1072
     1073    enum MissingParentsStrategy {
     1074        GO_AHEAD_WITH_DOWNLOADS,
     1075        GO_AHEAD_WITHOUT_DOWNLOADS,
     1076        USER_ABORTED
     1077    }
    9671078}