Changeset 34844 in osm


Ignore:
Timestamp:
2019-01-21T08:02:06+01:00 (5 years ago)
Author:
gerdp
Message:

see #10225: Improve case when two new ways are selected

Also improves javadoc and simplifies exception handling

Location:
applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java

    r34812 r34844  
    5959
    6060            UndoRedoHandler.getInstance().add(replaceCommand);
    61         } catch (IllegalArgumentException ex) {
    62             new Notification(
    63                     ex.getMessage()
    64                     ).setIcon(JOptionPane.WARNING_MESSAGE).show();
    65         } catch (ReplaceGeometryException ex) {
     61        } catch (IllegalArgumentException | ReplaceGeometryException ex) {
    6662            new Notification(
    6763                    ex.getMessage()
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java

    r34816 r34844  
    1515import java.util.List;
    1616import java.util.Map;
     17import java.util.Set;
    1718
    1819import javax.swing.JOptionPane;
     
    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) {
     
    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) {
     
    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) {
     
    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;
    219                 }
    220             }
    221             idxNew = areNewNodes ? 0 : 1;
    222             overrideNewCheck = true;
    223             for (Node n : selection.get(1 - idxNew).getNodes()) {
    224                 if (n.isNew()) {
    225                     overrideNewCheck = false;
     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;
    226231                }
    227232            }
     
    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
     
    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) {
     
    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}
Note: See TracChangeset for help on using the changeset viewer.