diff --git a/src/org/openstreetmap/josm/actions/search/SearchAction.java b/src/org/openstreetmap/josm/actions/search/SearchAction.java
index 4ba64b9..7b9ca85 100644
|
a
|
b
|
public class SearchAction extends JosmAction implements ParameterizedAction {
|
| 228 | 228 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>nodes:</b>... - objects with given number of nodes (<b>nodes:</b>count, <b>nodes:</b>min-max, <b>nodes:</b>min- or <b>nodes:</b>-max)")); |
| 229 | 229 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>tags:</b>... - objects with given number of tags (<b>tags:</b>count, <b>tags:</b>min-max, <b>tags:</b>min- or <b>tags:</b>-max)")); |
| 230 | 230 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>role:</b>... - objects with given role in a relation")); |
| 231 | | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>... - objects with this timestamp (2009-11-12T14:51:09Z, 2009-11-12 or T14:51 ...)")); |
| | 231 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>timestamp - objects with this last modification timestamp (2009-11-12T14:51:09Z, 2009-11-12 or T14:51 ...)")); |
| | 232 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>timestamp:</b>min/max - objects with last modification within range")); |
| 232 | 233 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>areasize:</b>... - closed ways with given area in m\u00b2 (<b>areasize:</b>min-max or <b>areasize:</b>max)")); |
| 233 | 234 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>modified</b> - all changed objects")); |
| 234 | 235 | /* I18n: don't translate the bold text keyword */ descriptionText.appendItem(tr("<b>selected</b> - all selected objects")); |
diff --git a/src/org/openstreetmap/josm/actions/search/SearchCompiler.java b/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
index 20294a6..d1087b9 100644
|
a
|
b
|
import java.io.PushbackReader;
|
| 8 | 8 | import java.io.StringReader; |
| 9 | 9 | import java.text.Normalizer; |
| 10 | 10 | import java.util.Collection; |
| | 11 | import java.util.Date; |
| 11 | 12 | import java.util.regex.Matcher; |
| 12 | 13 | import java.util.regex.Pattern; |
| 13 | 14 | import java.util.regex.PatternSyntaxException; |
| … |
… |
public class SearchCompiler {
|
| 549 | 550 | |
| 550 | 551 | private abstract static class CountRange extends Match { |
| 551 | 552 | |
| 552 | | private int minCount; |
| 553 | | private int maxCount; |
| | 553 | private long minCount; |
| | 554 | private long maxCount; |
| 554 | 555 | |
| 555 | | public CountRange(int minCount, int maxCount) { |
| | 556 | public CountRange(long minCount, long maxCount) { |
| 556 | 557 | this.minCount = Math.min(minCount, maxCount); |
| 557 | 558 | this.maxCount = Math.max(minCount, maxCount); |
| 558 | 559 | } |
| 559 | 560 | |
| 560 | | protected abstract Integer getCount(OsmPrimitive osm); |
| | 561 | protected abstract Long getCount(OsmPrimitive osm); |
| 561 | 562 | |
| 562 | 563 | protected abstract String getCountString(); |
| 563 | 564 | |
| 564 | 565 | @Override |
| 565 | 566 | public boolean match(OsmPrimitive osm) { |
| 566 | | Integer count = getCount(osm); |
| | 567 | Long count = getCount(osm); |
| 567 | 568 | if (count == null) |
| 568 | 569 | return false; |
| 569 | 570 | else |
| … |
… |
public class SearchCompiler {
|
| 580 | 581 | |
| 581 | 582 | private static class NodeCountRange extends CountRange { |
| 582 | 583 | |
| 583 | | public NodeCountRange(int minCount, int maxCount) { |
| | 584 | public NodeCountRange(long minCount, long maxCount) { |
| 584 | 585 | super(minCount, maxCount); |
| 585 | 586 | } |
| 586 | 587 | |
| 587 | 588 | @Override |
| 588 | | protected Integer getCount(OsmPrimitive osm) { |
| | 589 | protected Long getCount(OsmPrimitive osm) { |
| 589 | 590 | if (!(osm instanceof Way)) |
| 590 | 591 | return null; |
| 591 | 592 | else |
| 592 | | return ((Way) osm).getNodesCount(); |
| | 593 | return (long) ((Way) osm).getNodesCount(); |
| 593 | 594 | } |
| 594 | 595 | |
| 595 | 596 | @Override |
| … |
… |
public class SearchCompiler {
|
| 600 | 601 | |
| 601 | 602 | private static class TagCountRange extends CountRange { |
| 602 | 603 | |
| 603 | | public TagCountRange(int minCount, int maxCount) { |
| | 604 | public TagCountRange(long minCount, long maxCount) { |
| 604 | 605 | super(minCount, maxCount); |
| 605 | 606 | } |
| 606 | 607 | |
| 607 | 608 | @Override |
| 608 | | protected Integer getCount(OsmPrimitive osm) { |
| 609 | | return osm.getKeys().size(); |
| | 609 | protected Long getCount(OsmPrimitive osm) { |
| | 610 | return (long) osm.getKeys().size(); |
| 610 | 611 | } |
| 611 | 612 | |
| 612 | 613 | @Override |
| … |
… |
public class SearchCompiler {
|
| 615 | 616 | } |
| 616 | 617 | } |
| 617 | 618 | |
| | 619 | private static class TimestampRange extends CountRange { |
| | 620 | |
| | 621 | public TimestampRange(long minCount, long maxCount) { |
| | 622 | super(minCount, maxCount); |
| | 623 | } |
| | 624 | |
| | 625 | @Override |
| | 626 | protected Long getCount(OsmPrimitive osm) { |
| | 627 | return osm.getTimestamp().getTime(); |
| | 628 | } |
| | 629 | |
| | 630 | @Override |
| | 631 | protected String getCountString() { |
| | 632 | return "timestamp"; |
| | 633 | } |
| | 634 | |
| | 635 | } |
| | 636 | |
| 618 | 637 | private static class New extends Match { |
| 619 | 638 | @Override public boolean match(OsmPrimitive osm) { |
| 620 | 639 | return osm.isNew(); |
| … |
… |
public class SearchCompiler {
|
| 724 | 743 | */ |
| 725 | 744 | private static class Area extends CountRange { |
| 726 | 745 | |
| 727 | | public Area(int minCount, int maxCount) { |
| | 746 | public Area(long minCount, long maxCount) { |
| 728 | 747 | super(minCount, maxCount); |
| 729 | 748 | } |
| 730 | 749 | |
| 731 | 750 | @Override |
| 732 | | protected Integer getCount(OsmPrimitive osm) { |
| | 751 | protected Long getCount(OsmPrimitive osm) { |
| 733 | 752 | if (!(osm instanceof Way && ((Way) osm).isClosed())) |
| 734 | 753 | return null; |
| 735 | 754 | Way way = (Way) osm; |
| 736 | | return (int) Geometry.closedWayArea(way); |
| | 755 | return (long) Geometry.closedWayArea(way); |
| 737 | 756 | } |
| 738 | 757 | |
| 739 | 758 | @Override |
| … |
… |
public class SearchCompiler {
|
| 872 | 891 | return new Id(tokenizer.readNumber(tr("Primitive id expected"))); |
| 873 | 892 | else if ("tags".equals(key)) { |
| 874 | 893 | Range range = tokenizer.readRange(tr("Range of numbers expected")); |
| 875 | | return new TagCountRange((int)range.getStart(), (int)range.getEnd()); |
| | 894 | return new TagCountRange(range.getStart(), range.getEnd()); |
| 876 | 895 | } else if ("nodes".equals(key)) { |
| 877 | 896 | Range range = tokenizer.readRange(tr("Range of numbers expected")); |
| 878 | | return new NodeCountRange((int)range.getStart(), (int)range.getEnd()); |
| | 897 | return new NodeCountRange(range.getStart(), range.getEnd()); |
| 879 | 898 | } else if ("areasize".equals(key)) { |
| 880 | 899 | Range range = tokenizer.readRange(tr("Range of numbers expected")); |
| 881 | | return new Area((int)range.getStart(), (int)range.getEnd()); |
| | 900 | return new Area(range.getStart(), range.getEnd()); |
| | 901 | } else if ("timestamp".equals(key)) { |
| | 902 | String rangeS = " " + tokenizer.readTextOrNumber() + " "; // add leading/trailing space in order to get expected split (e.g. "a--" => {"a", ""}) |
| | 903 | String[] rangeA = rangeS.split("/"); |
| | 904 | if (rangeA.length == 1) { |
| | 905 | return new KeyValue(key, rangeS, regexSearch, caseSensitive); |
| | 906 | } else if (rangeA.length == 2) { |
| | 907 | String rangeA1 = rangeA[0].trim(); |
| | 908 | String rangeA2 = rangeA[1].trim(); |
| | 909 | long minDate = DateUtils.fromString(rangeA1.isEmpty() ? "1980" : rangeA1).getTime(); // if min timestap is empty: use lowest possible date |
| | 910 | long maxDate = rangeA2.isEmpty() ? new Date().getTime() : DateUtils.fromString(rangeA2).getTime(); // if max timestamp is empty: use "now" |
| | 911 | return new TimestampRange(minDate, maxDate); |
| | 912 | } else { |
| | 913 | throw new ParseError(tr("Expecting <i>min</i>/<i>max</i>'' after ''timestamp2''")); |
| | 914 | } |
| 882 | 915 | } else if ("changeset".equals(key)) |
| 883 | 916 | return new ChangesetId(tokenizer.readNumber(tr("Changeset id expected"))); |
| 884 | 917 | else if ("version".equals(key)) |