Ticket #6308: area-size-filter-search.patch
| File area-size-filter-search.patch, 6.7 KB (added by , 15 years ago) |
|---|
-
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 1 1 // License: GPL. Copyright 2007 by Immanuel Scholz and others 2 2 package org.openstreetmap.josm.actions.search; 3 3 4 import java.awt.Dimension;5 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 6 5 import static org.openstreetmap.josm.tools.I18n.tr; 7 6 import static org.openstreetmap.josm.tools.I18n.trc; 8 7 8 import java.awt.Dimension; 9 9 import java.awt.Font; 10 10 import java.awt.GridBagLayout; 11 11 import java.awt.event.ActionEvent; … … import javax.swing.JRadioButton; 27 27 28 28 import org.openstreetmap.josm.Main; 29 29 import org.openstreetmap.josm.actions.ActionParameter; 30 import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter; 30 31 import org.openstreetmap.josm.actions.JosmAction; 31 32 import org.openstreetmap.josm.actions.ParameterizedAction; 32 import org.openstreetmap.josm.actions.ActionParameter.SearchSettingsActionParameter;33 33 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 34 34 import org.openstreetmap.josm.data.osm.DataSet; 35 35 import org.openstreetmap.josm.data.osm.Filter; … … public class SearchAction extends JosmAction implements ParameterizedAction { 198 198 + "<li>"+tr("<b>tags:</b>... - object with given number of tags (tags:count or tags:min-max)")+"</li>" 199 199 + "<li>"+tr("<b>role:</b>... - object with given role in a relation")+"</li>" 200 200 + "<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>" 201 202 + "<li>"+tr("<b>modified</b> - all changed objects")+"</li>" 202 203 + "<li>"+tr("<b>selected</b> - all selected objects")+"</li>" 203 204 + "<li>"+tr("<b>incomplete</b> - all incomplete objects")+"</li>" 204 205 + "<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>" 205 207 + "<li>"+tr("<b>child <i>expr</i></b> - all children of objects matching the expression")+"</li>" 206 208 + "<li>"+tr("<b>parent <i>expr</i></b> - all parents of objects matching the expression")+"</li>" 207 209 + "<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 { 629 629 } 630 630 @Override public String toString() {return "child(" + parent + ")";} 631 631 } 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 } 632 710 633 711 public static class ParseError extends Exception { 634 712 public ParseError(String msg) { … … public class SearchCompiler { 700 778 } else if ("nodes".equals(key)) { 701 779 Range range = tokenizer.readRange(tr("Range of numbers expected")); 702 780 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()); 703 784 } else if ("changeset".equals(key)) 704 785 return new ChangesetId(tokenizer.readNumber(tr("Changeset id expected"))); 705 786 else if ("version".equals(key))
