Ticket #10225: 10225-v2.patch

File 10225-v2.patch, 6.5 KB (added by GerdP, 7 years ago)
  • src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java

     
    5858                return;
    5959
    6060            UndoRedoHandler.getInstance().add(replaceCommand);
    61         } catch (IllegalArgumentException ex) {
     61        } catch (IllegalArgumentException | ReplaceGeometryException ex) {
    6262            new Notification(
    6363                    ex.getMessage()
    6464                    ).setIcon(JOptionPane.WARNING_MESSAGE).show();
    65         } catch (ReplaceGeometryException ex) {
    66             new Notification(
    67                     ex.getMessage()
    68                     ).setIcon(JOptionPane.WARNING_MESSAGE).show();
    6965        }
    7066    }
    7167
  • src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java

     
    1414import java.util.LinkedList;
    1515import java.util.List;
    1616import java.util.Map;
     17import java.util.Set;
    1718
    1819import javax.swing.JOptionPane;
    1920
     
    5253
    5354    /**
    5455     * Replace new or uploaded object with new object
     56     * @return (in case of success) a command to update the geometry of one primitive and remove the other
    5557     */
    5658    public static ReplaceGeometryCommand buildReplaceWithNewCommand(OsmPrimitive firstObject, OsmPrimitive secondObject) {
    5759        if (firstObject instanceof Node && secondObject instanceof Node) {
     
    7173    /**
    7274     * Replace subjectObject geometry with referenceObject geometry and merge tags
    7375     * and relation memberships.
     76     * @param subjectObject object to modify
     77     * @param referenceSubject object that gives new geometry and is removed
     78     * @return (in case of success) a command to update the geometry of fist object and remove the other
    7479     */
    7580    public static ReplaceGeometryCommand buildReplaceCommand(OsmPrimitive subjectObject, OsmPrimitive referenceSubject) {
    7681        if (subjectObject instanceof Node && referenceSubject instanceof Node) {
     
    9095
    9196    /**
    9297     * Replace a new or uploaded node with a new node
     98     * @return (in case of success) a command to update the geometry of one primitive and remove the other
    9399     */
    94100    public static ReplaceGeometryCommand buildReplaceNodeWithNewCommand(Node firstNode, Node secondNode) {
    95101        if (firstNode.isNew() && !secondNode.isNew())
     
    206212                commands);
    207213    }
    208214
    209     public static ReplaceGeometryCommand buildReplaceWayWithNewCommand(List<Way> selection) {
     215    private static ReplaceGeometryCommand buildReplaceWayWithNewCommand(List<Way> selection) {
    210216        // determine which way will be replaced and which will provide the geometry
    211217        boolean overrideNewCheck = false;
    212218        int idxNew = selection.get(0).isNew() ? 0 : 1;
    213219        if (selection.get(1-idxNew).isNew()) {
    214             // if both are new, select the one with all the DB nodes
    215             boolean areNewNodes = false;
    216             for (Node n : selection.get(0).getNodes()) {
    217                 if (n.isNew()) {
    218                     areNewNodes = true;
     220            // compute the nodes which are not shared by both ways
     221            Set<Node> s0OnlyNodes = getDistinctNodes(selection.get(0), selection.get(1));
     222            Set<Node> s1OnlyNodes = getDistinctNodes(selection.get(1), selection.get(0));
     223
     224            boolean hasNewS0 = s0OnlyNodes.stream().anyMatch(Node::isNew);
     225            boolean hasNewS1 = s1OnlyNodes.stream().anyMatch(Node::isNew);
     226            if (hasNewS0 != hasNewS1) {
     227                // OK: one way doesn't have new nodes which don't appear in both ways
     228                overrideNewCheck = true;
     229                if (hasNewS1) {
     230                    idxNew = 1;
    219231                }
    220232            }
    221             idxNew = areNewNodes ? 0 : 1;
    222             overrideNewCheck = true;
    223             for (Node n : selection.get(1 - idxNew).getNodes()) {
    224                 if (n.isNew()) {
    225                     overrideNewCheck = false;
    226                 }
    227             }
    228233        }
    229234        Way referenceWay = selection.get(idxNew);
    230235        Way subjectWay = selection.get(1 - idxNew);
     
    231236
    232237        if (!overrideNewCheck && (subjectWay.isNew() || !referenceWay.isNew())) {
    233238            throw new ReplaceGeometryException(
    234                     tr("Please select one way that exists in the database and one new way with correct geometry."));
     239                    tr("Both ways are new and have new nodes, cannot decide which one has the correct geometry."));
    235240        }
    236241        return buildReplaceWayCommand(subjectWay, referenceWay);
    237242    }
    238243
     244    /**
     245     * Replace geometry of subjectWay by that of referenceWay. Tries to keep the history of nodes.
     246     * @param subjectWay way to modify
     247     * @param referenceWay way to remove
     248     * @return
     249     */
    239250    public static ReplaceGeometryCommand buildReplaceWayCommand(Way subjectWay, Way referenceWay) {
    240251
    241252        Area a = MainApplication.getLayerManager().getEditDataSet().getDataSourceArea();
     
    373384    }
    374385
    375386    /**
    376      * Create a list of nodes that are not used anywhere except in the way.
     387     * Create a list of distinct nodes that are not tagged and not used anywhere except in the way.
     388     * @param way the way
     389     * @return list of distinct nodes that are not tagged and not used anywhere except in the way
    377390     */
    378391    protected static List<Node> getUnimportantNodes(Way way) {
    379392        List<Node> nodePool = new LinkedList<>();
     
    479492        }
    480493        return nearest;
    481494    }
     495
     496    /**
     497     * Return the nodes that appear only in 1st way , not in 2nd way.
     498     * @param way1 1st way
     499     * @param way2 2nd way
     500     * @return set of distinct nodes which appear only in first way
     501     */
     502    private static Set<Node> getDistinctNodes(Way way1, Way way2) {
     503        Set<Node> distincNodes = new HashSet<>(way1.getNodes());
     504        distincNodes.removeAll(way2.getNodes());
     505        return distincNodes;
     506    }
    482507}