Ticket #6168: correct_extend.patch

File correct_extend.patch, 15.5 KB (added by akks, 13 years ago)

correct patch

  • src/utilsplugin2/UtilsPlugin2.java

     
    1414    JMenuItem addIntersections;
    1515    JMenuItem splitObject;
    1616    JMenuItem selectWayNodes;
     17    JMenuItem extendSelection;
     18    JMenuItem extendSelectionR;
    1719
    1820    public UtilsPlugin2(PluginInformation info) {
    1921        super(info);
     
    2224        addIntersections = MainMenu.add(Main.main.menu.toolsMenu, new AddIntersectionsAction());
    2325        splitObject = MainMenu.add(Main.main.menu.toolsMenu, new SplitObjectAction());
    2426        selectWayNodes = MainMenu.add(Main.main.menu.toolsMenu, new SelectWayNodesAction());
     27        extendSelection = MainMenu.add(Main.main.menu.toolsMenu, new ExtendSelectionAction());
     28        extendSelectionR = MainMenu.add(Main.main.menu.toolsMenu, new RecursiveExtendSelectionAction());
    2529    }
    2630
    2731    @Override
     
    3135        addIntersections.setEnabled(enabled);
    3236        splitObject.setEnabled(enabled);
    3337        selectWayNodes.setEnabled(enabled);
     38        extendSelection.setEnabled(enabled);
     39        extendSelectionR.setEnabled(enabled);
    3440    }
    3541}
  • src/utilsplugin2/RecursiveExtendSelectionAction.java

     
     1package utilsplugin2;
     2
     3import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.event.ActionEvent;
     7import java.awt.event.KeyEvent;
     8import java.util.Collection;
     9import java.util.HashSet;
     10import java.util.LinkedHashSet;
     11import java.util.LinkedList;
     12import java.util.List;
     13import java.util.Set;
     14import javax.swing.JOptionPane;
     15import org.openstreetmap.josm.Main;
     16import org.openstreetmap.josm.actions.JosmAction;
     17import org.openstreetmap.josm.data.SelectionChangedListener;
     18import org.openstreetmap.josm.data.osm.*;
     19
     20import org.openstreetmap.josm.tools.Shortcut;
     21
     22/**
     23 *    Extends current selection by selecting nodes on all touched ways
     24 */
     25class RecursiveExtendSelectionAction extends JosmAction {
     26
     27    public RecursiveExtendSelectionAction() {
     28        super(tr("Extends selection recursively"), "rextendselection", tr("Extends current selection recursively."),
     29                Shortcut.registerShortcut("tools:rextendselection", tr("Tool: {0}","Extends selection recursively"),
     30                KeyEvent.VK_E, Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
     31        putValue("help", ht("/Action/RExtendSelection"));
     32    }
     33
     34    public void actionPerformed(ActionEvent e) {
     35        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
     36        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
     37        Set<Way> activeWays = new LinkedHashSet<Way>();
     38
     39        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
     40
     41        if (selectedNodes.isEmpty() && selectedWays.isEmpty()) return;
     42
     43        // if no nodes are selected,
     44        // select ways attached to already selected ways
     45        if (selectedNodes.isEmpty() && !selectedWays.isEmpty()) {
     46            Set<Way> newWays = new LinkedHashSet<Way>();
     47
     48            NodeWayUtils.addWaysIntersectingWays(getCurrentDataSet().getWays(), selectedWays, newWays);
     49           
     50            newWays.removeAll(selectedWays);
     51            System.out.printf("%d ways added to selection\n",newWays.size());
     52            getCurrentDataSet().addSelected(newWays);
     53            return;
     54        }
     55
     56
     57        if (! selectedWays.isEmpty()) activeWays = selectedWays;
     58       
     59        Set<Node> newNodes = new HashSet <Node>();
     60
     61
     62        if ( activeWays.isEmpty()) {
     63            NodeWayUtils.addWaysConnectedToNodes(selectedNodes, activeWays);
     64        }
     65
     66        for (Node node: selectedNodes) {
     67            NodeWayUtils.addNodesConnectedToWays(activeWays,newNodes);
     68        }
     69       
     70        // select only newly found nodes
     71         newNodes.removeAll(selectedNodes);
     72         System.out.printf("Found %d new nodes\n",newNodes.size());
     73         
     74         getCurrentDataSet().addSelected(newNodes);
     75
     76         newNodes = null;
     77
     78    }
     79
     80    @Override
     81    protected void updateEnabledState() {
     82        if (getCurrentDataSet() == null) {
     83            setEnabled(false);
     84        } else {
     85            updateEnabledState(getCurrentDataSet().getSelected());
     86        }
     87    }
     88
     89    @Override
     90    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
     91        if (selection == null) {
     92            setEnabled(false);
     93            return;
     94        }
     95        setEnabled(!selection.isEmpty());
     96    }
     97
     98
     99}
  • src/utilsplugin2/NodeWayUtils.java

     
     1// License: GPL. Copyright 2011 by Alexei Kasatkin
     2package utilsplugin2;
     3
     4import java.util.Collection;
     5import java.util.List;
     6import java.util.Set;
     7import org.openstreetmap.josm.data.osm.Node;
     8import org.openstreetmap.josm.data.osm.OsmPrimitive;
     9import org.openstreetmap.josm.data.osm.Way;
     10import org.openstreetmap.josm.tools.Geometry;
     11import org.openstreetmap.josm.tools.Pair;
     12
     13/**
     14 * Class with some useful functions that are reused in extend selection actions
     15 *
     16 */
     17public final class NodeWayUtils {
     18
     19    /**
     20     * Find the neighbours of node n on the way w and put them in given collection
     21     * @param w way on which the search goes
     22     * @param n node to find its neighbours
     23     * @param nodes collection to place the nodes we found
     24     */
     25    static void addNeighbours(Way w, Node n, Collection<Node> nodes) {
     26        List<Node> nodeList = w.getNodes();
     27       
     28        int idx = nodeList.indexOf(n);
     29        if (idx == -1) return;
     30
     31        // add previous element
     32        if (idx > 0) {
     33            nodes.add(nodeList.get(idx - 1));
     34        }
     35        // add next element
     36        if (idx < nodeList.size() - 1) {
     37            nodes.add(nodeList.get(idx + 1));
     38        }
     39        if (w.isClosed()) {
     40            // cyclic neighbours detection
     41            if (idx == 0) {
     42                nodes.add(nodeList.get(nodeList.size() - 2));
     43            }
     44            if (idx == nodeList.size() - 1) {
     45                nodes.add(nodeList.get(1));
     46            }
     47        }
     48     }
     49
     50    /**
     51     * Adds all ways attached to way to specified collection
     52     * @param w way to find attached ways
     53     * @param ways  collection to place the ways we found
     54     */
     55    static void addWaysConnectedToWay(Way w, Collection<Way> ways) {
     56        List<Node> nodes = w.getNodes();
     57        for (Node n: nodes) {
     58            ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
     59        }
     60    }
     61
     62    /**
     63     * Adds all ways attached to node to specified collection
     64     * @param n Node to find attached ways
     65     * @param ways  collection to place the ways we found
     66     */
     67    static void addWaysConnectedToNode(Node n, Collection<Way> ways) {
     68        ways.addAll(OsmPrimitive.getFilteredList(n.getReferrers(), Way.class));
     69    }
     70
     71
     72
     73    /**
     74     * Adds all ways intersecting one way to specified set
     75     * @param ways collection of ways to search
     76     * @param w way to check intersections
     77     * @param newWays set to place the ways we found
     78     */
     79    static void addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays) {
     80        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
     81            for (Way anyway: ways) {
     82            List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false);
     83            loop: for (Pair<Node,Node> p1 : nodePairs) {
     84                for (Pair<Node,Node> p2 : nodePairs2) {
     85                    if (null!=Geometry.getSegmentSegmentIntersection(
     86                            p1.a.getEastNorth(),p1.b.getEastNorth(),
     87                            p2.a.getEastNorth(),p2.b.getEastNorth())) {
     88                        newWays.add(anyway);
     89                        break loop;
     90                    }
     91                }
     92            }
     93        }
     94    }
     95
     96    /**
     97     * Adds all ways from allWays intersecting initWays way to specified set newWays
     98     * @param allWays collection of ways to search
     99     * @param initWays ways to check intersections
     100     * @param newWays set to place the ways we found
     101     */
     102    static void addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
     103        for (Way w : initWays){
     104            addWaysIntersectingWay(allWays, w, newWays);
     105        }
     106    }
     107
     108    static void addWaysConnectedToNodes(Set<Node> selectedNodes, Set<Way> newWays) {
     109        for (Node node: selectedNodes) {
     110            addWaysConnectedToNode(node, newWays);
     111        }
     112    }
     113
     114    static void addNodesConnectedToWays(Set<Way> initWays, Set<Node> newNodes) {
     115        for (Way w: initWays) {
     116                newNodes.addAll(w.getNodes());
     117        }
     118    }
     119
     120
     121
     122}
  • src/utilsplugin2/ExtendSelectionAction.java

     
     1package utilsplugin2;
     2
     3import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.event.ActionEvent;
     7import java.awt.event.KeyEvent;
     8import java.util.Collection;
     9import java.util.HashSet;
     10import java.util.LinkedHashSet;
     11import java.util.LinkedList;
     12import java.util.List;
     13import java.util.Set;
     14import javax.swing.JOptionPane;
     15import org.openstreetmap.josm.Main;
     16import org.openstreetmap.josm.actions.JosmAction;
     17import org.openstreetmap.josm.data.SelectionChangedListener;
     18import org.openstreetmap.josm.data.osm.*;
     19
     20import org.openstreetmap.josm.tools.Shortcut;
     21
     22/**
     23 *    Extends current selection
     24 */
     25class ExtendSelectionAction extends JosmAction {
     26
     27    public static final boolean treeMode = false;
     28
     29    public ExtendSelectionAction() {
     30        super(tr("Extends selection"), "extendselection", tr("Extends current selections."),
     31                Shortcut.registerShortcut("tools:extendselection", tr("Tool: {0}","Extends selection"),
     32                KeyEvent.VK_E, Shortcut.GROUP_EDIT), true);
     33        putValue("help", ht("/Action/ExtendSelection"));
     34    }
     35
     36    private  Set<Way> activeWays = new LinkedHashSet<Way>();
     37
     38    public void actionPerformed(ActionEvent e) {
     39        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
     40        Set<Node> selectedNodes = OsmPrimitive.getFilteredSet(selection, Node.class);
     41
     42
     43        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
     44       
     45       
     46        // if no nodes and no ways are selected, do nothing
     47        if (selectedNodes.isEmpty() && selectedWays.isEmpty()) return;
     48
     49        // if no nodes are selected,
     50        // select ways attached to already selected ways
     51        if (selectedNodes.isEmpty() && !selectedWays.isEmpty()) {
     52            Set<Way> newWays = new LinkedHashSet<Way>();
     53
     54
     55            for (Way w : selectedWays){
     56                NodeWayUtils.addWaysConnectedToWay(w, newWays);
     57            }
     58            newWays.removeAll(selectedWays);
     59            System.out.printf("%d ways added to selection\n",newWays.size());
     60            getCurrentDataSet().addSelected(newWays);
     61            return;
     62        }
     63
     64
     65
     66        if (selectedWays.isEmpty()) {
     67            // if one node is selected, used ways connected to it to extend selecteons
     68            // activeWays are remembered for next extend action (!!!)
     69
     70            // FIXME: some strange behaviour is possible if user delete some of these way
     71            // how to clear activeWays during such user actions? Do not know
     72            if (selectedNodes.size() == 1) {
     73                activeWays.clear();
     74                System.out.println("Cleared active ways");
     75            }
     76        } else {
     77            // use only ways that were selected for adding nodes
     78            activeWays = selectedWays;
     79        }
     80
     81        Set<Node> newNodes = new HashSet <Node>();
     82
     83        if (treeMode || activeWays.isEmpty()) {
     84                NodeWayUtils.addWaysConnectedToNodes(selectedNodes, activeWays);
     85            }
     86
     87        for (Node node: selectedNodes) {
     88            for (Way w: activeWays) {
     89                NodeWayUtils.addNeighbours(w, node, newNodes);
     90            }
     91        }
     92       
     93        // select only newly found nodes
     94         newNodes.removeAll(selectedNodes);
     95
     96         System.out.printf("Found %d new nodes\n",newNodes.size());
     97         
     98         // enable branching on next call of this function
     99         // if no new nodes were found, next search will include all touched ways
     100         if (newNodes.isEmpty()) {
     101             activeWays.clear();
     102             System.out.println("No more points found, activeways cleared");
     103         }
     104
     105         getCurrentDataSet().addSelected(newNodes);
     106         newNodes = null;
     107
     108    }
     109
     110    @Override
     111    protected void updateEnabledState() {
     112        if (getCurrentDataSet() == null) {
     113            setEnabled(false);
     114        } else {
     115            updateEnabledState(getCurrentDataSet().getSelected());
     116        }
     117    }
     118
     119    @Override
     120    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
     121        if (selection == null) {
     122            setEnabled(false);
     123            return;
     124        }
     125        setEnabled(!selection.isEmpty());
     126    }
     127
     128
     129
     130}
  • build.xml

     
    3030<project name="utilsplugin2" default="dist" basedir=".">
    3131
    3232    <!-- enter the SVN commit message -->
    33     <property name="commit.message" value="fix" />
     33    <property name="commit.message" value="extend selection" />
    3434    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    3535    <property name="plugin.main.version" value="3835" />
    3636
     
    3939      ************************************************
    4040      ** should not be necessary to change the following properties
    4141     -->
    42     <property name="josm"                   location="../../core/dist/josm-custom.jar"/>
     42    <property name="josm"                   location="../../dist/josm-custom.jar"/>
    4343    <property name="plugin.build.dir"       value="build"/>
    4444    <property name="plugin.src.dir"         value="src"/>
    4545    <!-- this is the directory where the plugin jar is copied to -->
     
    168168            <env key="LANG" value="C"/>
    169169            <arg value="info"/>
    170170            <arg value="--xml"/>
    171             <arg value="../../core"/>
     171            <arg value="../../"/>
    172172        </exec>
    173173        <xmlproperty file="core.info.xml" prefix="coreversion" keepRoot="true" collapseAttributes="true"/>
    174174        <echo>Building against core revision ${coreversion.info.entry.revision}.</echo>
     
    253253
    254254    <target name="publish" depends="ensure-svn-present,core-info,commit-current,update-current,clean,dist,commit-dist">
    255255    </target>
     256    <target name="runjosm" depends="install">
     257        <java jar="${josm}" >
     258            <arg line="../../data_nodist/neubrandenburg.osm"/>
     259        </java>
     260    </target>
    256261</project>