Ticket #22799: josm22799_smart_distribute_v2.patch

File josm22799_smart_distribute_v2.patch, 5.0 KB (added by gaben, 21 months ago)

add HTML notification formatting

  • src/org/openstreetmap/josm/actions/DistributeAction.java

     
    66
    77import java.awt.event.ActionEvent;
    88import java.awt.event.KeyEvent;
     9import java.util.ArrayList;
    910import java.util.Collection;
    1011import java.util.HashSet;
    1112import java.util.Iterator;
     
    4950     * Select method according to user selection.
    5051     * Case 1: One Way (no self-crossing) and at most 2 nodes contains by this way:
    5152     *     Distribute nodes keeping order along the way
    52      * Case 2: Other
     53     * Case 2: One Node part of at least one way, not a start or end node
     54     *     Distribute the selected node relative to neighbors
     55     * Case 3: Other
    5356     *     Distribute nodes
    5457     */
    5558    @Override
     
    5962
    6063        // Collect user selected objects
    6164        Collection<OsmPrimitive> selected = getLayerManager().getEditDataSet().getSelected();
    62         Collection<Way> ways = new LinkedList<>();
    63         Collection<Node> nodes = new HashSet<>();
     65        Collection<Way> ways = new ArrayList<>();
     66        Collection<Node> nodes = new ArrayList<>();
    6467        for (OsmPrimitive osm : selected) {
    6568            if (osm instanceof Node) {
    6669                nodes.add((Node) osm);
     
    8184            cmds = distributeWay(ways, nodes);
    8285        } else if (checkDistributeNodes(ways, nodes)) {
    8386            cmds = distributeNodes(nodes);
     87        } else if (checkDistributeNode(nodes)){
     88            cmds = distributeNode(nodes);
    8489        } else {
    8590            new Notification(
    86                              tr("Please select :\n" +
    87                                 "* One no self-crossing way with at most two of its nodes;\n" +
    88                                 "* Three nodes."))
     91                             tr("Please select:<ul>" +
     92                                "<li>One no self-crossing way with at most two of its nodes;</li>" +
     93                                "<li>One node in the middle of a way;</li>" +
     94                                "<li>Three nodes.</li></ul>"))
    8995                .setIcon(JOptionPane.INFORMATION_MESSAGE)
    90                 .setDuration(Notification.TIME_SHORT)
    9196                .show();
    9297            return;
    9398        }
     
    185190    }
    186191
    187192    /**
     193     * Test if single node oriented algorithm applies to the selection.
     194     * @param nodes The selected node. Collection type and naming kept for compatibility with similar methods.
     195     * @return true in this case
     196     */
     197    private static boolean checkDistributeNode(Collection<Node> nodes) {
     198        if (nodes.size() == 1) {
     199            Node node = nodes.iterator().next();
     200            int goodWays = 0;
     201            for (Way way : node.getParentWays()) {
     202                // the algorithm is applicable only if there is one way which:
     203                //  - is open and the selected node is a middle node, or
     204                //  - is closed and has at least 4 nodes (as 3 doesn't make sense and error-prone)
     205                if (!way.isFirstLastNode(node) || (way.isClosed() && way.getRealNodesCount() > 3))
     206                    goodWays++;
     207            }
     208            return goodWays == 1;
     209        }
     210        return false;
     211    }
     212
     213    /**
     214     * Distribute a single node relative to way neighbours.
     215     * @see DistributeAction#distributeNodes(Collection)
     216     * @param nodes nodes to distribute
     217     * @return Commands to execute to perform action
     218     */
     219    private static Collection<Command> distributeNode(Collection<Node> nodes) {
     220        final Node node = nodes.iterator().next();
     221        Way parent = node.getParentWays().iterator().next();
     222
     223        // make the user selected node the middle in the output variable
     224        nodes.clear();
     225
     226        List<Node> neighbours = new ArrayList<>(parent.getNeighbours(node));
     227
     228        nodes.add(neighbours.get(0));
     229        nodes.add(node);
     230        nodes.add(neighbours.get(1));
     231
     232        // call the distribution method with 3 nodes
     233        return distributeNodes(nodes);
     234    }
     235
     236    /**
    188237     * Test if nodes oriented algorithm applies to the selection.
    189238     * @param ways Selected ways
    190239     * @param nodes Selected nodes
     
    197246    /**
    198247     * Distribute nodes when only nodes are selected.
    199248     * The general algorithm here is to find the two selected nodes
    200      * that are furthest apart, and then to distribute all other selected
     249     * that are the furthest apart, and then to distribute all other selected
    201250     * nodes along the straight line between these nodes.
    202251     * @param nodes nodes to distribute
    203252     * @return Commands to execute to perform action
     
    241290        // A list of commands to do
    242291        Collection<Command> cmds = new LinkedList<>();
    243292
    244         // Amount of nodes between A and B plus 1
     293        // Number of nodes between A and B plus 1
    245294        int num = nodes.size()+1;
    246295
    247296        // Current number of node