Changeset 5787 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
r5777 r5787 5 5 6 6 import java.util.ArrayList; 7 import java.util.Arrays;8 7 import java.util.Collection; 9 8 import java.util.HashMap; … … 18 17 import org.openstreetmap.josm.data.osm.Relation; 19 18 import org.openstreetmap.josm.data.osm.RelationMember; 19 import org.openstreetmap.josm.data.osm.Tag; 20 import org.openstreetmap.josm.data.osm.TagCollection; 20 21 import org.openstreetmap.josm.data.osm.Way; 21 22 … … 28 29 * for the user to confirm. 29 30 */ 30 31 31 public class ReverseWayTagCorrector extends TagCorrector<Way> { 32 32 33 private static class PrefixSuffixSwitcher { 34 35 private static final String SEPARATOR = "[:_]"; 33 private static final String SEPARATOR = "[:_]"; 34 35 private static final Pattern getPatternFor(String s) { 36 return getPatternFor(s, false); 37 } 38 39 private static final Pattern getPatternFor(String s, boolean exactMatch) { 40 if (exactMatch) { 41 return Pattern.compile("(^)(" + s + ")($)"); 42 } else { 43 return Pattern.compile("(^|.*" + SEPARATOR + ")(" + s + ")(" + SEPARATOR + ".*|$)", 44 Pattern.CASE_INSENSITIVE); 45 } 46 } 47 48 private static final Collection<Pattern> ignoredKeys = new ArrayList<Pattern>(); 49 static { 50 for (String s : OsmPrimitive.getUninterestingKeys()) { 51 ignoredKeys.add(getPatternFor(s)); 52 } 53 for (String s : new String[]{"name", "ref", "tiger:county"}) { 54 ignoredKeys.add(getPatternFor(s, false)); 55 } 56 for (String s : new String[]{"tiger:county", "turn:lanes", "change:lanes", "placement"}) { 57 ignoredKeys.add(getPatternFor(s, true)); 58 } 59 } 60 61 private static class StringSwitcher { 36 62 37 63 private final String a; … … 39 65 private final Pattern pattern; 40 66 41 public PrefixSuffixSwitcher(String a, String b) {67 public StringSwitcher(String a, String b) { 42 68 this.a = a; 43 69 this.b = b; 44 this.pattern = Pattern.compile( 45 "(^|.*" + SEPARATOR + ")(" + a + "|" + b + ")(" + SEPARATOR + ".*|$)", 46 Pattern.CASE_INSENSITIVE); 70 this.pattern = getPatternFor(a + "|" + b); 47 71 } 48 72 … … 64 88 } 65 89 66 private static final PrefixSuffixSwitcher[] prefixSuffixSwitchers =67 new PrefixSuffixSwitcher[] {68 new PrefixSuffixSwitcher("left", "right"),69 new PrefixSuffixSwitcher("forward", "backward"),70 new PrefixSuffixSwitcher("forwards", "backwards"),71 new PrefixSuffixSwitcher("up", "down"),72 new PrefixSuffixSwitcher("east", "west"),73 new PrefixSuffixSwitcher("north", "south"),74 };75 76 90 /** 77 * Tests whether way can be reversed without semantic change, i.e., whether tags have to be changed. 78 * Looks for keys like oneway, oneway:bicycle, cycleway:right:oneway, left/right. 79 * @param way 80 * @return false if tags should be changed to keep semantic, true otherwise. 91 * Reverses a given tag. 92 * @since 5787 81 93 */ 82 public static boolean isReversible(Way way) { 83 for (String key : way.keySet()) { 84 for (String k : Arrays.asList("oneway", "incline", "direction")) { 85 if (key.startsWith(k) || key.endsWith(k)) { 86 return false; 87 } 88 } 89 String value = way.get(key); 90 for (PrefixSuffixSwitcher prefixSuffixSwitcher : prefixSuffixSwitchers) { 91 if (!key.equals(prefixSuffixSwitcher.apply(key)) || !value.equals(prefixSuffixSwitcher.apply(value))) { 92 return false; 93 } 94 } 95 } 96 return true; 97 } 98 99 public static List<Way> irreversibleWays(List<Way> ways) { 100 List<Way> newWays = new ArrayList<Way>(ways); 101 for (Way way : ways) { 102 if (isReversible(way)) { 103 newWays.remove(way); 104 } 105 } 106 return newWays; 107 } 108 109 public String invertNumber(String value) { 110 Pattern pattern = Pattern.compile("^([+-]?)(\\d.*)$", Pattern.CASE_INSENSITIVE); 111 Matcher matcher = pattern.matcher(value); 112 if (!matcher.matches()) return value; 113 String sign = matcher.group(1); 114 String rest = matcher.group(2); 115 sign = sign.equals("-") ? "" : "-"; 116 return sign + rest; 117 } 118 119 @Override 120 public Collection<Command> execute(Way oldway, Way way) throws UserCancelException { 121 Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = 122 new HashMap<OsmPrimitive, List<TagCorrection>>(); 123 124 ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>(); 125 for (String key : way.keySet()) { 94 public static class TagSwitcher { 95 96 /** 97 * Reverses a given tag. 98 * @param tag The tag to reverse 99 * @return The reversed tag (is equal to <code>tag</code> if no change is needed) 100 */ 101 public static final Tag apply(final Tag tag) { 102 return apply(tag.getKey(), tag.getValue()); 103 } 104 105 /** 106 * Reverses a given tag (key=value). 107 * @param key The tag key 108 * @param value The tag value 109 * @return The reversed tag (is equal to <code>key=value</code> if no change is needed) 110 */ 111 public static final Tag apply(final String key, final String value) { 126 112 String newKey = key; 127 String value = way.get(key);128 113 String newValue = value; 129 114 … … 136 121 } else if (key.startsWith("incline") || key.endsWith("incline") 137 122 || key.startsWith("direction") || key.endsWith("direction")) { 138 PrefixSuffixSwitcher switcher = new PrefixSuffixSwitcher("up", "down"); 139 newValue = switcher.apply(value); 123 newValue = UP_DOWN.apply(value); 140 124 if (newValue.equals(value)) { 141 125 newValue = invertNumber(value); 142 126 } 143 } else if (!ignoreKeyForPrefixSuffixCorrection(key)) { 144 for (PrefixSuffixSwitcher prefixSuffixSwitcher : prefixSuffixSwitchers) { 127 } else if (key.endsWith(":forward") || key.endsWith(":backward")) { 128 // Change key but not left/right value (fix #8518) 129 newKey = FORWARD_BACKWARD.apply(key); 130 131 } else if (!ignoreKeyForCorrection(key)) { 132 for (StringSwitcher prefixSuffixSwitcher : stringSwitchers) { 145 133 newKey = prefixSuffixSwitcher.apply(key); 146 134 if (!key.equals(newKey)) { … … 153 141 } 154 142 } 143 return new Tag(newKey, newValue); 144 } 145 } 146 147 private static final StringSwitcher FORWARD_BACKWARD = new StringSwitcher("forward", "backward"); 148 private static final StringSwitcher UP_DOWN = new StringSwitcher("up", "down"); 149 150 private static final StringSwitcher[] stringSwitchers = new StringSwitcher[] { 151 new StringSwitcher("left", "right"), 152 new StringSwitcher("forwards", "backwards"), 153 new StringSwitcher("east", "west"), 154 new StringSwitcher("north", "south"), 155 FORWARD_BACKWARD, UP_DOWN 156 }; 157 158 /** 159 * Tests whether way can be reversed without semantic change, i.e., whether tags have to be changed. 160 * Looks for keys like oneway, oneway:bicycle, cycleway:right:oneway, left/right. 161 * @param way 162 * @return false if tags should be changed to keep semantic, true otherwise. 163 */ 164 public static boolean isReversible(Way way) { 165 for (Tag tag : TagCollection.from(way)) { 166 if (!tag.equals(TagSwitcher.apply(tag))) { 167 return false; 168 } 169 } 170 return true; 171 } 172 173 public static List<Way> irreversibleWays(List<Way> ways) { 174 List<Way> newWays = new ArrayList<Way>(ways); 175 for (Way way : ways) { 176 if (isReversible(way)) { 177 newWays.remove(way); 178 } 179 } 180 return newWays; 181 } 182 183 public static String invertNumber(String value) { 184 Pattern pattern = Pattern.compile("^([+-]?)(\\d.*)$", Pattern.CASE_INSENSITIVE); 185 Matcher matcher = pattern.matcher(value); 186 if (!matcher.matches()) return value; 187 String sign = matcher.group(1); 188 String rest = matcher.group(2); 189 sign = sign.equals("-") ? "" : "-"; 190 return sign + rest; 191 } 192 193 @Override 194 public Collection<Command> execute(Way oldway, Way way) throws UserCancelException { 195 Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap = 196 new HashMap<OsmPrimitive, List<TagCorrection>>(); 197 198 ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>(); 199 for (String key : way.keySet()) { 200 String value = way.get(key); 201 Tag newTag = TagSwitcher.apply(key, value); 202 String newKey = newTag.getKey(); 203 String newValue = newTag.getValue(); 155 204 156 205 boolean needsCorrection = !key.equals(newKey); … … 190 239 boolean found = false; 191 240 String newRole = null; 192 for ( PrefixSuffixSwitcher prefixSuffixSwitcher : prefixSuffixSwitchers) {241 for (StringSwitcher prefixSuffixSwitcher : stringSwitchers) { 193 242 newRole = prefixSuffixSwitcher.apply(member.getRole()); 194 243 if (!newRole.equals(member.getRole())) { … … 215 264 } 216 265 217 private static boolean ignoreKeyForPrefixSuffixCorrection(String key) { 218 return key.contains("name") || key.equals("tiger:county") 219 || key.equalsIgnoreCase("fixme") || key.startsWith("note"); 266 private static boolean ignoreKeyForCorrection(String key) { 267 for (Pattern ignoredKey : ignoredKeys) { 268 if (ignoredKey.matcher(key).matches()) { 269 return true; 270 } 271 } 272 return false; 220 273 } 221 274 }
Note:
See TracChangeset
for help on using the changeset viewer.