Changeset 11061 in josm


Ignore:
Timestamp:
2016-09-27T20:47:19+02:00 (15 months ago)
Author:
simon04
Message:

fix #10260 - Warning on reversing ways with direction-dependent nodes

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java

    r10125 r11061  
    55
    66import java.util.ArrayList;
     7import java.util.Arrays;
    78import java.util.Collection;
    89import java.util.HashMap;
     
    1011import java.util.Locale;
    1112import java.util.Map;
     13import java.util.function.Function;
    1214import java.util.regex.Matcher;
    1315import java.util.regex.Pattern;
     
    1618import org.openstreetmap.josm.data.correction.RoleCorrection;
    1719import org.openstreetmap.josm.data.correction.TagCorrection;
     20import org.openstreetmap.josm.data.osm.Node;
    1821import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1922import org.openstreetmap.josm.data.osm.OsmUtils;
     
    6467    }
    6568
    66     private static class StringSwitcher {
     69    private interface IStringSwitcher extends Function<String, String> {
     70
     71        static IStringSwitcher combined(IStringSwitcher... switchers) {
     72            return key -> {
     73                for (IStringSwitcher switcher : switchers) {
     74                    final String newKey = switcher.apply(key);
     75                    if (!key.equals(newKey)) {
     76                        return newKey;
     77                    }
     78                }
     79                return key;
     80            };
     81        }
     82
     83        static IStringSwitcher compassCardinal() {
     84            final List<String> cardinal = Arrays.asList(
     85                    "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
     86                    "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW");
     87            return key -> {
     88                final int index = cardinal.indexOf(key);
     89                if (index >= 0) {
     90                    return cardinal.get((index + cardinal.size() / 2) % cardinal.size());
     91                }
     92                return key;
     93            };
     94        }
     95
     96        static IStringSwitcher compassDegrees() {
     97            return key -> {
     98                if (!key.matches("\\d+")) {
     99                    return key;
     100                }
     101                final int i = Integer.parseInt(key);
     102                if (i < 0 || i > 360) {
     103                    return key;
     104                }
     105                return Integer.toString((i + 180) % 360);
     106            };
     107        }
     108
     109        static IStringSwitcher compass() {
     110            return combined(
     111                    IStringSwitcher.compassCardinal(),
     112                    IStringSwitcher.compassDegrees()
     113            );
     114        }
     115    }
     116
     117    private static class StringSwitcher implements IStringSwitcher {
    67118
    68119        private final String a;
     
    76127        }
    77128
     129        @Override
    78130        public String apply(String text) {
    79131            Matcher m = pattern.matcher(text);
     
    128180                    newValue = OsmUtils.reverseval;
    129181                }
    130                 for (StringSwitcher prefixSuffixSwitcher : stringSwitchers) {
    131                     newKey = prefixSuffixSwitcher.apply(key);
    132                     if (!key.equals(newKey)) {
    133                         break;
    134                     }
    135                 }
    136             } else if (key.startsWith("incline") || key.endsWith("incline")
    137                     || key.startsWith("direction") || key.endsWith("direction")) {
     182                newKey = COMBINED_SWITCHERS.apply(key);
     183            } else if (key.startsWith("incline") || key.endsWith("incline")) {
    138184                newValue = UP_DOWN.apply(value);
    139185                if (newValue.equals(value)) {
    140186                    newValue = invertNumber(value);
     187                }
     188            } else if (key.startsWith("direction") || key.endsWith("direction")) {
     189                newValue = COMBINED_SWITCHERS.apply(value);
     190                if (newValue.equals(value)) {
     191                    newValue = IStringSwitcher.compass().apply(value);
    141192                }
    142193            } else if (key.endsWith(":forward") || key.endsWith(":backward")) {
     
    144195                newKey = FORWARD_BACKWARD.apply(key);
    145196            } else if (!ignoreKeyForCorrection(key)) {
    146                 for (StringSwitcher prefixSuffixSwitcher : stringSwitchers) {
    147                     newKey = prefixSuffixSwitcher.apply(key);
    148                     if (!key.equals(newKey)) {
    149                         break;
    150                     }
    151                     newValue = prefixSuffixSwitcher.apply(value);
    152                     if (!value.equals(newValue)) {
    153                         break;
    154                     }
    155                 }
     197                newKey = COMBINED_SWITCHERS.apply(key);
     198                newValue = COMBINED_SWITCHERS.apply(value);
    156199            }
    157200            return new Tag(newKey, newValue);
     
    161204    private static final StringSwitcher FORWARD_BACKWARD = new StringSwitcher("forward", "backward");
    162205    private static final StringSwitcher UP_DOWN = new StringSwitcher("up", "down");
    163 
    164     private static final StringSwitcher[] stringSwitchers = new StringSwitcher[] {
     206    private static final IStringSwitcher COMBINED_SWITCHERS = IStringSwitcher.combined(
    165207        new StringSwitcher("left", "right"),
    166208        new StringSwitcher("forwards", "backwards"),
     
    168210        new StringSwitcher("north", "south"),
    169211        FORWARD_BACKWARD, UP_DOWN
    170     };
     212    );
    171213
    172214    /**
     
    207249    static List<TagCorrection> getTagCorrections(Tagged way) {
    208250        List<TagCorrection> tagCorrections = new ArrayList<>();
    209         for (String key : way.keySet()) {
    210             String value = way.get(key);
     251        for (Map.Entry<String, String> entry : way.getKeys().entrySet()) {
     252            final String key = entry.getKey();
     253            final String value = entry.getValue();
    211254            Tag newTag = TagSwitcher.apply(key, value);
    212255            String newKey = newTag.getKey();
     
    245288                }
    246289
    247                 boolean found = false;
    248                 String newRole = null;
    249                 for (StringSwitcher prefixSuffixSwitcher : stringSwitchers) {
    250                     newRole = prefixSuffixSwitcher.apply(member.getRole());
    251                     if (!newRole.equals(member.getRole())) {
    252                         found = true;
    253                         break;
    254                     }
    255                 }
    256 
    257                 if (found) {
     290                final String newRole = COMBINED_SWITCHERS.apply(member.getRole());
     291                if (!member.getRole().equals(newRole)) {
    258292                    roleCorrections.add(new RoleCorrection(relation, position, member, newRole));
    259293                }
     
    263297        }
    264298        return roleCorrections;
     299    }
     300
     301    static Map<OsmPrimitive, List<TagCorrection>> getTagCorrectionsMap(Way way) {
     302        Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = new HashMap<>();
     303        List<TagCorrection> tagCorrections = getTagCorrections((Tagged) way);
     304        if (!tagCorrections.isEmpty()) {
     305            tagCorrectionsMap.put(way, tagCorrections);
     306        }
     307        for (Node node : way.getNodes()) {
     308            final List<TagCorrection> corrections = getTagCorrections(node);
     309            if (!corrections.isEmpty()) {
     310                tagCorrectionsMap.put(node, corrections);
     311            }
     312        }
     313        return tagCorrectionsMap;
    265314    }
    266315
    267316    @Override
    268317    public Collection<Command> execute(Way oldway, Way way) throws UserCancelException {
    269         Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = new HashMap<>();
    270         List<TagCorrection> tagCorrections = getTagCorrections(way);
    271         if (!tagCorrections.isEmpty()) {
    272             tagCorrectionsMap.put(way, tagCorrections);
    273         }
     318        Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = getTagCorrectionsMap(way);
    274319
    275320        Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap = new HashMap<>();
  • trunk/src/org/openstreetmap/josm/data/correction/TagCorrection.java

    r10125 r11061  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.data.correction;
     3
     4import java.util.Objects;
    35
    46/**
     
    4749        return !newValue.equals(oldValue);
    4850    }
     51
     52    @Override
     53    public boolean equals(Object o) {
     54        if (this == o) return true;
     55        if (!(o instanceof TagCorrection)) return false;
     56        TagCorrection that = (TagCorrection) o;
     57        return Objects.equals(oldKey, that.oldKey) &&
     58                Objects.equals(newKey, that.newKey) &&
     59                Objects.equals(oldValue, that.oldValue) &&
     60                Objects.equals(newValue, that.newValue);
     61    }
     62
     63    @Override
     64    public int hashCode() {
     65        return Objects.hash(oldKey, newKey, oldValue, newValue);
     66    }
    4967}
  • trunk/test/unit/org/openstreetmap/josm/corrector/ReverseWayTagCorrectorTest.java

    r10945 r11061  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.corrector;
     3
     4import java.util.Collections;
     5import java.util.List;
     6import java.util.Map;
     7import java.util.stream.Stream;
    38
    49import org.junit.Assert;
    510import org.junit.Rule;
    611import org.junit.Test;
     12import org.openstreetmap.josm.data.correction.TagCorrection;
     13import org.openstreetmap.josm.data.osm.Node;
     14import org.openstreetmap.josm.data.osm.OsmPrimitive;
     15import org.openstreetmap.josm.data.osm.OsmUtils;
    716import org.openstreetmap.josm.data.osm.Tag;
     17import org.openstreetmap.josm.data.osm.Way;
    818import org.openstreetmap.josm.testutils.JOSMTestRules;
    919
     
    3949            assertSwitch(new Tag(k, "something"), new Tag(k, "something"));
    4050        }
     51        // direction=forward/backward/...
     52        assertSwitch(new Tag("direction", "forward"), new Tag("direction", "backward"));
     53        assertSwitch(new Tag("direction", "backward"), new Tag("direction", "forward"));
     54        assertSwitch(new Tag("direction", "north"), new Tag("direction", "south"));
     55        assertSwitch(new Tag("direction", "NNE"), new Tag("direction", "SSW"));
     56        assertSwitch(new Tag("direction", "270"), new Tag("direction", "90"));
     57        assertSwitch(new Tag("direction", "135"), new Tag("direction", "315"));
     58        assertSwitch(new Tag("direction", "337"), new Tag("direction", "157"));
    4159        // :left/:right with oneway (see #10977)
    4260        assertSwitch(new Tag("cycleway:left:oneway", "-1"), new Tag("cycleway:right:oneway", "yes"));
     
    99117        Assert.assertEquals(ReverseWayTagCorrector.TagSwitcher.apply(oldTag), newTag);
    100118    }
     119
     120    /**
     121     * Test tag correction on way nodes
     122     */
     123    @Test
     124    public void testSwitchingWayNodes() {
     125        final OsmPrimitive n1 = OsmUtils.createPrimitive("node");
     126        final OsmPrimitive n2 = OsmUtils.createPrimitive("node direction=SSW");
     127        final OsmPrimitive n3 = OsmUtils.createPrimitive("node");
     128        final Way w = new Way();
     129        Stream.of(n1, n2, n3).map(Node.class::cast).forEach(w::addNode);
     130        final Map<OsmPrimitive, List<TagCorrection>> tagCorrections = ReverseWayTagCorrector.getTagCorrectionsMap(w);
     131        Assert.assertEquals(1, tagCorrections.size());
     132        Assert.assertEquals(Collections.singleton(n2),
     133                tagCorrections.keySet());
     134        Assert.assertEquals(Collections.singletonList(new TagCorrection("direction", "SSW", "direction", "NNE")),
     135                tagCorrections.values().iterator().next());
     136    }
    101137}
Note: See TracChangeset for help on using the changeset viewer.