Ticket #6308: area-size-filter-search.patch

File area-size-filter-search.patch, 6.7 KB (added by olejorgenb, 15 years ago)

patch v0.1

  • src/org/openstreetmap/josm/actions/search/SearchAction.java

    diff --git a/src/org/openstreetmap/josm/actions/search/SearchAction.java b/src/org/openstreetmap/josm/actions/search/SearchAction.java
    index ea65058..bcc01d7 100644
    a b  
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm.actions.search;
    33
    4 import java.awt.Dimension;
    54import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    65import static org.openstreetmap.josm.tools.I18n.tr;
    76import static org.openstreetmap.josm.tools.I18n.trc;
    87
     8import java.awt.Dimension;
    99import java.awt.Font;
    1010import java.awt.GridBagLayout;
    1111import java.awt.event.ActionEvent;
    import javax.swing.JRadioButton;  
    2727
    2828import org.openstreetmap.josm.Main;
    2929import org.openstreetmap.josm.actions.ActionParameter;
     30import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;
    3031import org.openstreetmap.josm.actions.JosmAction;
    3132import org.openstreetmap.josm.actions.ParameterizedAction;
    32 import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;
    3333import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError;
    3434import org.openstreetmap.josm.data.osm.DataSet;
    3535import org.openstreetmap.josm.data.osm.Filter;
    public class SearchAction extends JosmAction implements ParameterizedAction {  
    198198                    + "<li>"+tr("<b>tags:</b>... - object with given number of tags (tags:count or tags:min-max)")+"</li>"
    199199                    + "<li>"+tr("<b>role:</b>... - object with given role in a relation")+"</li>"
    200200                    + "<li>"+tr("<b>timestamp:</b>... -  objects with this timestamp (<b>2009-11-12T14:51:09Z</b>, <b>2009-11-12</b> or <b>T14:51</b> ...)")+"</li>"
     201                    + "<li>"+tr("<b>areaSize:</b>... - closed ways with area between MIN and MAX sqm. (areaSize:MIN-MAX or areaSize:MAX")+"</li>"
    201202                    + "<li>"+tr("<b>modified</b> - all changed objects")+"</li>"
    202203                    + "<li>"+tr("<b>selected</b> - all selected objects")+"</li>"
    203204                    + "<li>"+tr("<b>incomplete</b> - all incomplete objects")+"</li>"
    204205                    + "<li>"+tr("<b>untagged</b> - all untagged objects")+"</li>"
     206                    + "<li>"+tr("<b>closed</b> - all closed ways (a node is not considered closed")+"</li>"
    205207                    + "<li>"+tr("<b>child <i>expr</i></b> - all children of objects matching the expression")+"</li>"
    206208                    + "<li>"+tr("<b>parent <i>expr</i></b> - all parents of objects matching the expression")+"</li>"
    207209                    + "<li>"+tr("Use <b>|</b> or <b>OR</b> to combine with logical or")+"</li>"
  • src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    diff --git a/src/org/openstreetmap/josm/actions/search/SearchCompiler.java b/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
    index bfb9415..ff923fc 100644
    a b public class SearchCompiler {  
    629629        }
    630630        @Override public String toString() {return "child(" + parent + ")";}
    631631    }
     632    /**
     633     * Matches on the area of a closed way. (approximate(?), but should be OK for small areas)
     634     *
     635     * Doesn't behave completely nice with not since it will match all nodes and non-closed ways too.
     636     * (not sure if there is a good way to fix this, and it's "easy enough" to work around with '& closed')
     637     *
     638     * @author Ole Jørgen Brønner
     639     */
     640    private static class Area extends Match {
     641        private int min, max;
     642
     643        public Area(int min, int max) {
     644            this.min = min;
     645            this.max = max;
     646            if (min == max) {
     647                this.min = 0;
     648            }
     649        }
     650        // taken from the measurement plugin
     651        public static double calcX(Node p1){
     652            double lat1, lon1, lat2, lon2;
     653            double dlon, dlat;
     654
     655            lat1 = p1.getCoor().lat() * Math.PI / 180.0;
     656            lon1 = p1.getCoor().lon() * Math.PI / 180.0;
     657            lat2 = lat1;
     658            lon2 = 0;
     659
     660            dlon = lon2 - lon1;
     661            dlat = lat2 - lat1;
     662
     663            double a = (Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2));
     664            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
     665            return 6367000 * c;
     666        }
     667        // taken from the measurement plugin
     668        public static double calcY(Node p1){
     669            double lat1, lon1, lat2, lon2;
     670            double dlon, dlat;
     671
     672            lat1 = p1.getCoor().lat() * Math.PI / 180.0;
     673            lon1 = p1.getCoor().lon() * Math.PI / 180.0;
     674            lat2 = 0;
     675            lon2 = lon1;
     676
     677            dlon = lon2 - lon1;
     678            dlat = lat2 - lat1;
     679
     680            double a = (Math.pow(Math.sin(dlat/2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2), 2));
     681            double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
     682            return 6367000 * c;
     683        }
     684
     685        private static double calcClosedWayArea(Way way) {
     686            //assert(way.isClosed());
     687
     688            //http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/
     689            double area = 0;
     690            Node lastN = null;
     691            for (Node n : way.getNodes()) {
     692                if (lastN != null) {
     693                    n.getEastNorth().getX();
     694
     695                    area += (calcX(n) * calcY(lastN)) - (calcY(n) * calcX(lastN));
     696                }
     697                lastN = n;
     698            }
     699            return Math.abs(area/2);
     700        }
     701        @Override
     702        public boolean match(OsmPrimitive osm) {
     703            if(!(osm instanceof Way && ((Way) osm).isClosed()))
     704                return false;
     705            Way way = (Way)osm;
     706            double area = calcClosedWayArea(way);
     707            return (min <= area && area <= max);
     708        }
     709    }
    632710
    633711    public static class ParseError extends Exception {
    634712        public ParseError(String msg) {
    public class SearchCompiler {  
    700778                } else if ("nodes".equals(key)) {
    701779                    Range range = tokenizer.readRange(tr("Range of numbers expected"));
    702780                    return new NodeCountRange((int)range.getStart(), (int)range.getEnd());
     781                } else if ("areaSize".equals(key)) {
     782                    Range range = tokenizer.readRange(tr("Range of numbers expected"));
     783                    return new Area((int)range.getStart(), (int)range.getEnd());
    703784                } else if ("changeset".equals(key))
    704785                    return new ChangesetId(tokenizer.readNumber(tr("Changeset id expected")));
    705786                else if ("version".equals(key))