Changeset 8496 in josm


Ignore:
Timestamp:
2015-06-19T20:23:18+02:00 (9 years ago)
Author:
simon04
Message:

fix #11505 - Download objects: load a range of OSM objects (modified patch by windu.2b)

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/SimplePrimitiveId.java

    r8338 r8496  
    55import java.util.ArrayList;
    66import java.util.List;
     7import java.util.regex.MatchResult;
    78import java.util.regex.Matcher;
    89import java.util.regex.Pattern;
     
    1516    private final OsmPrimitiveType type;
    1617
    17     public static final Pattern ID_PATTERN = Pattern.compile("((n(ode)?|w(ay)?|r(el(ation)?)?)[ /]?)(\\d+)");
     18    public static final Pattern ID_PATTERN = Pattern.compile("(n|node|w|way|r|rel|relation)[ /]?(\\d+)");
     19
     20    public static final Pattern MULTIPLE_IDS_PATTERN = Pattern.compile(ID_PATTERN.pattern() + "(-(\\d+))?");
    1821
    1922    public SimplePrimitiveId(long id, OsmPrimitiveType type) {
     
    8083        final Matcher m = ID_PATTERN.matcher(s);
    8184        if (m.matches()) {
    82             return new SimplePrimitiveId(Long.parseLong(m.group(m.groupCount())),
    83                     s.charAt(0) == 'n'
    84                             ? OsmPrimitiveType.NODE
    85                             : s.charAt(0) == 'w'
    86                             ? OsmPrimitiveType.WAY
    87                             : OsmPrimitiveType.RELATION);
     85            return new SimplePrimitiveId(Long.parseLong(m.group(m.groupCount())), getOsmPrimitiveType(s.charAt(0)));
    8886        } else {
    8987            throw new IllegalArgumentException("The string " + s + " does not match the pattern " + ID_PATTERN);
     
    9290
    9391    /**
     92     * Parses a range {@code SimplePrimitiveId} from the string {@code s}.
     93     * @param s the string to be parsed, e.g., {@code node1}, {@code node1-7}, {@code node70-7}.
     94     * @return the parsed {@code SimplePrimitiveId}s
     95     * @throws IllegalArgumentException if the string does not match the pattern
     96     */
     97    public static List<SimplePrimitiveId> multipleFromString(String s) {
     98        final Matcher m = MULTIPLE_IDS_PATTERN.matcher(s);
     99        if (m.matches()) {
     100            return extractIdsInto(m, new ArrayList<SimplePrimitiveId>());
     101        } else {
     102            throw new IllegalArgumentException("The string " + s + " does not match the pattern " + MULTIPLE_IDS_PATTERN);
     103        }
     104    }
     105
     106    /**
    94107     * Attempts to parse extract any primitive id from the string {@code s}.
    95      * @param s the string to be parsed, e.g., {@code n1, w1}, {@code node1 and rel2}.
     108     * @param s the string to be parsed, e.g., {@code "n1, w1"}, {@code "node1 and rel2"}, {@code "node 123-29"}.
    96109     * @return the parsed list of {@code OsmPrimitiveType}s.
    97110     */
    98111    public static List<SimplePrimitiveId> fuzzyParse(String s) {
    99112        final List<SimplePrimitiveId> ids = new ArrayList<>();
    100         final Matcher m = ID_PATTERN.matcher(s);
     113        final Matcher m = MULTIPLE_IDS_PATTERN.matcher(s);
    101114        while (m.find()) {
    102             final char firstChar = s.charAt(m.start());
    103             ids.add(new SimplePrimitiveId(Long.parseLong(m.group(m.groupCount())),
    104                     firstChar == 'n'
    105                             ? OsmPrimitiveType.NODE
    106                             : firstChar == 'w'
    107                             ? OsmPrimitiveType.WAY
    108                             : OsmPrimitiveType.RELATION));
     115            extractIdsInto(m, ids);
    109116        }
    110117        return ids;
    111118    }
     119
     120    private static List<SimplePrimitiveId> extractIdsInto(MatchResult m, List<SimplePrimitiveId> ids) {
     121        final OsmPrimitiveType type = getOsmPrimitiveType(m.group(1).charAt(0));
     122        final String firstId = m.group(2);
     123        final String lastId = m.group(4);
     124        if (lastId != null) {
     125            final long lastIdParsed;
     126            if (lastId.length() < firstId.length()) {
     127                // parse ranges such as 123-25 or 123-5
     128                lastIdParsed = Long.parseLong(firstId.substring(0, firstId.length() - lastId.length()) + lastId);
     129            } else {
     130                // parse ranges such as 123-125 or 998-1001
     131                lastIdParsed = Long.parseLong(lastId);
     132            }
     133            for (long i = Long.parseLong(firstId); i <= lastIdParsed; i++) {
     134                ids.add(new SimplePrimitiveId(i, type));
     135            }
     136        } else {
     137            ids.add(new SimplePrimitiveId(Long.parseLong(firstId), type));
     138        }
     139        return ids;
     140    }
     141
     142    private static OsmPrimitiveType getOsmPrimitiveType(char firstChar) {
     143        return firstChar == 'n' ? OsmPrimitiveType.NODE : firstChar == 'w' ? OsmPrimitiveType.WAY : OsmPrimitiveType.RELATION;
     144    }
    112145}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/OsmIdSelectionDialog.java

    r8426 r8496  
    9191        tfId.setPreferredSize(new Dimension(400, tfId.getPreferredSize().height));
    9292
    93         HtmlPanel help = new HtmlPanel(/* I18n: {0} and {1} contains example strings not meant for translation. {2}=n, {3}=w, {4}=r. */
    94                 tr("Object IDs can be separated by comma or space.<br/>"
    95                         + "Examples: {0}<br/>"
    96                         + "In mixed mode, specify objects like this: {1}<br/>"
    97                         + "({2} stands for <i>node</i>, {3} for <i>way</i>, and {4} for <i>relation</i>)",
    98                         "<b>" + Utils.joinAsHtmlUnorderedList(Arrays.asList("1 2 5", "1,2,5")) + "</b>",
    99                         "<b>w123, n110, w12, r15</b>",
    100                         "<b>n</b>", "<b>w</b>", "<b>r</b>"
    101                 ));
     93        final String help1 = /* I18n: {0} and contains example strings not meant for translation. */
     94                tr("Object IDs can be separated by comma or space, for instance: {0}",
     95                        "<b>" + Utils.joinAsHtmlUnorderedList(Arrays.asList("1 2 5", "1,2,5")) + "</b>");
     96        final String help2 = /* I18n: {0} and contains example strings not meant for translation. {1}=n, {2}=w, {3}=r. */
     97                tr("In mixed mode, specify objects like this: {0}<br/>"
     98                                + "({1} stands for <i>node</i>, {2} for <i>way</i>, and {3} for <i>relation</i>)",
     99                        "<b>w123, n110, w12, r15</b>", "<b>n</b>", "<b>w</b>", "<b>r</b>");
     100        final String help3 = /* I18n: {0} and contains example strings not meant for translation. */
     101                tr("Ranges of object IDs are specified with a hyphen, for instance: {0}",
     102                        "<b>" + Utils.joinAsHtmlUnorderedList(Arrays.asList("w1-5", "n30-37", "r501-5")) + "</b>");
     103        HtmlPanel help = new HtmlPanel(help1 + "<br/>" + help2 + "<br/><br/>" + help3);
    102104        help.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
    103105
  • trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java

    r7005 r8496  
    107107                } else {
    108108                    try {
    109                         ids.add(SimplePrimitiveId.fromString(s));
     109                        ids.addAll(SimplePrimitiveId.multipleFromString(s));
    110110                    } catch (IllegalArgumentException ex) {
    111111                        try {
  • trunk/test/unit/org/openstreetmap/josm/data/osm/SimplePrimitiveIdTest.groovy

    r8194 r8496  
    2424    }
    2525
     26    void testBad() {
     27        shouldFail { SimplePrimitiveId.fromString("foobar") }
     28    }
     29
    2630    void testFuzzy() {
    2731        assert SimplePrimitiveId.fuzzyParse("foo relation/123 bar").toString() == "[relation 123]"
    2832        assert SimplePrimitiveId.fuzzyParse("foo relation/123 and way/345 but also node/789").toString() == "[relation 123, way 345, node 789]"
     33        assert SimplePrimitiveId.fuzzyParse("foo relation/123-24 and way/345-346 but also node/789").toString() == "[relation 123, relation 124, way 345, way 346, node 789]"
    2934    }
    3035
     
    3439        assert SimplePrimitiveId.fromString("relation 123") == new SimplePrimitiveId(123, OsmPrimitiveType.RELATION)
    3540    }
     41
     42    void testMultipleIDs() {
     43        assert SimplePrimitiveId.multipleFromString("node/234").toString() == "[node 234]"
     44        assert SimplePrimitiveId.multipleFromString("node/234-234").toString() == "[node 234]"
     45        assert SimplePrimitiveId.multipleFromString("node/2-1").toString() == "[]"
     46        assert SimplePrimitiveId.multipleFromString("node/123-124").toString() == "[node 123, node 124]"
     47        assert SimplePrimitiveId.multipleFromString("n/123-124").toString() == "[node 123, node 124]"
     48        assert SimplePrimitiveId.multipleFromString("node123-126").toString() == "[node 123, node 124, node 125, node 126]"
     49        assert SimplePrimitiveId.multipleFromString("way/123-123").toString() == "[way 123]"
     50        assert SimplePrimitiveId.multipleFromString("w/123-127").toString() == "[way 123, way 124, way 125, way 126, way 127]"
     51        assert SimplePrimitiveId.multipleFromString("way123-125").toString() == "[way 123, way 124, way 125]"
     52        assert SimplePrimitiveId.multipleFromString("relation/123-125").toString() == "[relation 123, relation 124, relation 125]"
     53        assert SimplePrimitiveId.multipleFromString("r/123-125").toString() == "[relation 123, relation 124, relation 125]"
     54        assert SimplePrimitiveId.multipleFromString("relation123-125").toString() == "[relation 123, relation 124, relation 125]"
     55        assert SimplePrimitiveId.multipleFromString("node/234-5").toString() == "[node 234, node 235]"
     56        assert SimplePrimitiveId.multipleFromString("node/234-35").toString() == "[node 234, node 235]"
     57        assert SimplePrimitiveId.multipleFromString("node/234-235").toString() == "[node 234, node 235]"
     58        assert SimplePrimitiveId.multipleFromString("node/998-1001").toString() == "[node 998, node 999, node 1000, node 1001]"
     59        shouldFail { SimplePrimitiveId.multipleFromString("foo node123 bar") }
     60    }
    3661}
Note: See TracChangeset for help on using the changeset viewer.