Changeset 27936 in osm for applications/editors/josm


Ignore:
Timestamp:
2012-02-25T17:00:42+01:00 (13 years ago)
Author:
joshdoe
Message:

utilsplugin2: add inside, intersecting, and allintersecting search keywords (see #josm5905, #josm7178)

Location:
applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/UtilsPlugin2.java

    r27859 r27936  
    88import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
    99import java.awt.event.KeyEvent;
     10import java.util.Arrays;
     11import java.util.Collection;
     12import java.util.HashSet;
     13import java.util.Set;
    1014import javax.swing.JMenu;
    1115import javax.swing.JMenuItem;
     
    1519
    1620import org.openstreetmap.josm.Main;
     21import org.openstreetmap.josm.actions.search.PushbackTokenizer;
     22import org.openstreetmap.josm.actions.search.SearchCompiler;
     23import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
     24import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
     25import org.openstreetmap.josm.actions.search.SearchCompiler.UnaryMatch;
     26import org.openstreetmap.josm.actions.search.SearchCompiler.UnaryMatchFactory;
     27import org.openstreetmap.josm.data.osm.OsmPrimitive;
     28import org.openstreetmap.josm.data.osm.Relation;
     29import org.openstreetmap.josm.data.osm.Way;
    1730import org.openstreetmap.josm.gui.MainMenu;
    1831import org.openstreetmap.josm.gui.MapFrame;
     
    94107        drawArc = MainMenu.add(toolsMenu, new CurveAction());
    95108
     109        // register search operators
     110        SearchCompiler.addMatchFactory(new UtilsUnaryMatchFactory());
    96111    }
    97112
     
    133148        return new UtilsPluginPreferences();
    134149    }
    135 
     150   
     151    public static class UtilsUnaryMatchFactory implements UnaryMatchFactory {
     152        private static Collection<String> keywords = Arrays.asList("inside",
     153                "intersecting", "allintersecting");
     154       
     155        @Override
     156        public UnaryMatch get(String keyword, Match matchOperand, PushbackTokenizer tokenizer) throws ParseError {
     157            if ("inside".equals(keyword))
     158                return new InsideMatch(matchOperand);
     159            else if ("intersecting".equals(keyword))
     160                return new IntersectingMatch(matchOperand, false);
     161            else if ("allintersecting".equals(keyword))
     162                return new IntersectingMatch(matchOperand, true);
     163            return null;
     164        }
     165
     166        @Override
     167        public Collection<String> getKeywords() {
     168            return keywords;
     169        }
     170    }
     171
     172    /**
     173     * Matches all objects contained within the match expression.
     174     */
     175    public static class InsideMatch extends UnaryMatch {
     176        private Collection<OsmPrimitive> inside = null;
     177       
     178        public InsideMatch(Match match) {
     179            super(match);
     180            init();
     181        }
     182       
     183        /**
     184         * Find all objects inside areas which match the expression
     185         */
     186        private void init() {
     187            Collection<OsmPrimitive> matchedAreas = new HashSet<OsmPrimitive>();
     188
     189            // find all ways that match the expression
     190            Collection<Way> ways = Main.main.getCurrentDataSet().getWays();
     191            for (Way way : ways) {
     192                if (match.match(way))
     193                    matchedAreas.add(way);
     194            }
     195           
     196            // find all relations that match the expression
     197            Collection<Relation> rels = Main.main.getCurrentDataSet().getRelations();
     198            for (Relation rel : rels) {
     199                if (match.match(rel))
     200                    matchedAreas.add(rel);
     201            }
     202           
     203            inside = NodeWayUtils.selectAllInside(matchedAreas, Main.main.getCurrentDataSet());
     204        }
     205
     206        @Override
     207        public boolean match(OsmPrimitive osm) {
     208            return inside.contains(osm);
     209        }
     210    }
     211   
     212    public static class IntersectingMatch extends UnaryMatch {
     213        private Collection<Way> intersecting = null;
     214       
     215        public IntersectingMatch(Match match, boolean all) {
     216            super(match);
     217            init(all);
     218        }   
     219       
     220        /**
     221         * Find (all) ways intersecting ways which match the expression.
     222         */
     223        private void init(boolean all) {
     224            Collection<Way> matchedWays = new HashSet<Way>();
     225           
     226            // find all ways that match the expression
     227            Collection<Way> allWays = Main.main.getCurrentDataSet().getWays();
     228            for (Way way : allWays) {
     229                if (match.match(way))
     230                    matchedWays.add(way);
     231            }
     232           
     233            Set<Way> newWays = new HashSet<Way>();
     234            if (all)
     235                NodeWayUtils.addWaysIntersectingWaysRecursively(allWays, matchedWays, newWays);
     236            else
     237                NodeWayUtils.addWaysIntersectingWays(allWays, matchedWays, newWays);
     238            intersecting = newWays;
     239        }
     240       
     241        @Override
     242        public boolean match(OsmPrimitive osm) {
     243            if (osm instanceof Way)
     244                return intersecting.contains((Way)osm);
     245            return false;
     246        }
     247    }
    136248}
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/NodeWayUtils.java

    r27318 r27936  
    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){
     
    172172    }
    173173
    174     static void addWaysIntersectingWaysRecursively
     174    public static void addWaysIntersectingWaysRecursively
    175175            (Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays)
    176176    {
     
    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);
     464
     465        for (Iterator<Relation> it = selectedRels.iterator(); it.hasNext();) {
     466            Relation r = it.next();
     467            if (!r.isMultipolygon()) {
     468                it.remove();
     469            }
     470        }
     471
     472        Set<Way> newWays = new HashSet<Way>();
     473        Set<Node> newNodes = new HashSet<Node>();
     474        // select ways attached to already selected ways
     475        if (!selectedWays.isEmpty()) {
     476            for (Way w: selectedWays) {
     477                addAllInsideWay(dataset,w,newWays,newNodes);
     478            }
     479        }
     480        if (!selectedRels.isEmpty()) {
     481            for (Relation r: selectedRels) {
     482                addAllInsideMultipolygon(dataset,r,newWays,newNodes);
     483            }
     484        }
     485       
     486        Set<OsmPrimitive> insideSelection = new HashSet<OsmPrimitive>();
     487        if (!newWays.isEmpty() || !newNodes.isEmpty()) {
     488            insideSelection.addAll(newWays);
     489            insideSelection.addAll(newNodes);
     490        }
     491        return insideSelection;
     492    }
     493
    460494
    461495}
  • applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/selection/SelectAllInsideAction.java

    r27852 r27936  
    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
     
    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,
Note: See TracChangeset for help on using the changeset viewer.