Ticket #7178: inside_intersecting_operators.patch

File inside_intersecting_operators.patch, 10.1 KB (added by joshdoe, 9 years ago)

inside, intersecting, and allintersecting operators using newer MatchFactory

  • utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java

     
    147147     * @param initWays ways to check intersections
    148148     * @param newWays set to place the ways we found
    149149     */
    150     static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
     150    public static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) {
    151151        int count=0;
    152152        for (Way w : initWays){
    153153            count+=addWaysIntersectingWay(allWays, w, newWays);
     
    171171        return newNodes.size()-s;
    172172    }
    173173
    174     static void addWaysIntersectingWaysRecursively
     174    public static void addWaysIntersectingWaysRecursively
    175175            (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays)
    176176    {
    177177            Set<Way> foundWays = new HashSet<Way>();
     
    457457       // System.out.printf("Intersected intercount %d %s\n",interCount, point.toString());
    458458        if (interCount%2 == 1) return 1; else return 0;
    459459    }
     460   
     461    public static Collection<OsmPrimitive> selectAllInside(Collection<OsmPrimitive> selected, DataSet dataset) {
     462        Set<Way> selectedWays = OsmPrimitive.getFilteredSet(selected, Way.class);
     463        Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(selected, Relation.class);
    460464
     465        for (Relation r: selectedRels) {
     466            if (!r.isMultipolygon()) selectedRels.remove(r);
     467        }
     468
     469        Set<Way> newWays = new HashSet<Way>();
     470        Set<Node> newNodes = new HashSet<Node>();
     471        // select ways attached to already selected ways
     472        if (!selectedWays.isEmpty()) {
     473            for (Way w: selectedWays) {
     474                addAllInsideWay(dataset,w,newWays,newNodes);
     475            }
     476        }
     477        if (!selectedRels.isEmpty()) {
     478            for (Relation r: selectedRels) {
     479                addAllInsideMultipolygon(dataset,r,newWays,newNodes);
     480            }
     481        }
     482       
     483        Set<OsmPrimitive> insideSelection = new HashSet<OsmPrimitive>();
     484        if (!newWays.isEmpty() || !newNodes.isEmpty()) {
     485            insideSelection.addAll(newWays);
     486            insideSelection.addAll(newNodes);
     487        }
     488        return insideSelection;
     489    }
     490
     491
    461492}
  • utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java

     
    1414
    1515import org.openstreetmap.josm.Main;
    1616import org.openstreetmap.josm.actions.JosmAction;
    17 import org.openstreetmap.josm.data.osm.Node;
    18 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    19 import org.openstreetmap.josm.data.osm.Relation;
    20 import org.openstreetmap.josm.data.osm.Way;
     17import org.openstreetmap.josm.data.osm.*;
    2118import org.openstreetmap.josm.tools.Shortcut;
    2219
    2320/**
     
    3128                KeyEvent.VK_I, Shortcut.GROUP_EDIT ,KeyEvent.ALT_DOWN_MASK|KeyEvent.SHIFT_DOWN_MASK), true);
    3229        putValue("help", ht("/Action/SelectAllInside"));
    3330    }
    34 
     31   
     32    @Override
    3533    public void actionPerformed(ActionEvent e) {
    3634        long t=System.currentTimeMillis();
    37         Set<Way> selectedWays = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Way.class);
    38         Set<Relation> selectedRels = OsmPrimitive.getFilteredSet(getCurrentDataSet().getSelected(), Relation.class);
    39 
    40         for (Relation r: selectedRels) {
    41             if (!r.isMultipolygon()) selectedRels.remove(r);
    42         }
    43 
    44         Set<Way> newWays = new HashSet<Way>();
    45         Set<Node> newNodes = new HashSet<Node>();
    46         // select ways attached to already selected ways
    47         if (!selectedWays.isEmpty()) {
    48             for (Way w: selectedWays) {
    49                 NodeWayUtils.addAllInsideWay(getCurrentDataSet(),w,newWays,newNodes);
    50             }
    51         }
    52         if (!selectedRels.isEmpty()) {
    53             for (Relation r: selectedRels) {
    54                 NodeWayUtils.addAllInsideMultipolygon(getCurrentDataSet(),r,newWays,newNodes);
    55             }
    56         }
    57         if (!newWays.isEmpty() || !newNodes.isEmpty()) {
    58             getCurrentDataSet().addSelected(newWays);
    59             getCurrentDataSet().addSelected(newNodes);
     35        Collection<OsmPrimitive> insideSelected = NodeWayUtils.selectAllInside(getCurrentDataSet().getSelected(), getCurrentDataSet());
     36       
     37        if (!insideSelected.isEmpty()) {
     38            getCurrentDataSet().addSelected(insideSelected);
    6039        } else{
    6140        JOptionPane.showMessageDialog(Main.parent,
    6241               tr("Nothing found. Please select some closed ways or multipolygons to find all primitives inside them!"),
  • utilsplugin2/src/utilsplugin2/UtilsPlugin2.java

     
    11// License: GPL v2 or later. See LICENSE file for details.
    22package utilsplugin2;
    33
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
    46import utilsplugin2.customurl.ChooseURLAction;
    57import utilsplugin2.customurl.OpenPageAction;
    68import utilsplugin2.customurl.UtilsPluginPreferences;
    79
    810import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
    911import java.awt.event.KeyEvent;
     12import java.util.Arrays;
     13import java.util.Collection;
     14import java.util.HashSet;
     15import java.util.Set;
    1016import javax.swing.JMenu;
    1117import javax.swing.JMenuItem;
    1218import utilsplugin2.selection.*;
    1319import utilsplugin2.dumbutils.*;
    1420
    1521import org.openstreetmap.josm.Main;
     22import org.openstreetmap.josm.actions.search.PushbackTokenizer;
     23import org.openstreetmap.josm.actions.search.SearchCompiler;
     24import org.openstreetmap.josm.actions.search.SearchCompiler.*;
     25import org.openstreetmap.josm.data.osm.OsmPrimitive;
     26import org.openstreetmap.josm.data.osm.Relation;
     27import org.openstreetmap.josm.data.osm.Way;
    1628import org.openstreetmap.josm.gui.MainMenu;
    1729import org.openstreetmap.josm.gui.MapFrame;
    1830import org.openstreetmap.josm.plugins.Plugin;
     
    8799       
    88100        selectURL = MainMenu.add(toolsMenu, new ChooseURLAction());
    89101       
    90 
     102        // register search operators
     103        SearchCompiler.addMatchFactory(new UtilsUnaryMatchFactory());
    91104    }
    92105
    93106    @Override
     
    124137    public PreferenceSetting getPreferenceSetting() {
    125138        return new UtilsPluginPreferences();
    126139    }
     140   
     141    public static class UtilsUnaryMatchFactory implements UnaryMatchFactory {
     142        private static Collection<String> keywords = Arrays.asList("inside",
     143                "intersecting", "allintersecting");
     144       
     145        @Override
     146        public UnaryMatch get(String keyword, Match matchOperand, PushbackTokenizer tokenizer) throws ParseError {
     147            if ("inside".equals(keyword))
     148                return new InsideMatch(matchOperand);
     149            else if ("intersecting".equals(keyword))
     150                return new IntersectingMatch(matchOperand, false);
     151            else if ("allintersecting".equals(keyword))
     152                return new IntersectingMatch(matchOperand, true);
     153            return null;
     154        }
    127155
     156        @Override
     157        public Collection<String> getKeywords() {
     158            return keywords;
     159        }
     160    }
     161
     162    /**
     163     * Matches all objects contained within the match expression.
     164     */
     165    public static class InsideMatch extends UnaryMatch {
     166        private Collection<OsmPrimitive> inside = null;
     167       
     168        public InsideMatch(Match match) {
     169            super(match);
     170            init();
     171        }
     172       
     173        /**
     174         * Find all objects inside areas which match the expression
     175         */
     176        private void init() {
     177            Collection<OsmPrimitive> matchedAreas = new HashSet<OsmPrimitive>();
     178
     179            // find all ways that match the expression
     180            Collection<Way> ways = Main.main.getCurrentDataSet().getWays();
     181            for (Way way : ways) {
     182                if (match.match(way))
     183                    matchedAreas.add(way);
     184            }
     185           
     186            // find all relations that match the expression
     187            Collection<Relation> rels = Main.main.getCurrentDataSet().getRelations();
     188            for (Relation rel : rels) {
     189                if (match.match(rel))
     190                    matchedAreas.add(rel);
     191            }
     192           
     193            inside = NodeWayUtils.selectAllInside(matchedAreas, Main.main.getCurrentDataSet());
     194        }
     195
     196        @Override
     197        public boolean match(OsmPrimitive osm) {
     198            return inside.contains(osm);
     199        }
     200    }
     201   
     202    public static class IntersectingMatch extends UnaryMatch {
     203        private Collection<Way> intersecting = null;
     204       
     205        public IntersectingMatch(Match match, boolean all) {
     206            super(match);
     207            init(all);
     208        }   
     209       
     210        /**
     211         * Find (all) ways intersecting ways which match the expression.
     212         */
     213        private void init(boolean all) {
     214            Collection<Way> matchedWays = new HashSet<Way>();
     215           
     216            // find all ways that match the expression
     217            Collection<Way> allWays = Main.main.getCurrentDataSet().getWays();
     218            for (Way way : allWays) {
     219                if (match.match(way))
     220                    matchedWays.add(way);
     221            }
     222           
     223            Set<Way> newWays = new HashSet<Way>();
     224            if (all)
     225                NodeWayUtils.addWaysIntersectingWaysRecursively(allWays, matchedWays, newWays);
     226            else
     227                NodeWayUtils.addWaysIntersectingWays(allWays, matchedWays, newWays);
     228            intersecting = newWays;
     229        }
     230       
     231        @Override
     232        public boolean match(OsmPrimitive osm) {
     233            return intersecting.contains(osm);
     234        }
     235    }
    128236}