Ticket #21163: josm_21163.patch
| File josm_21163.patch, 6.0 KB (added by , 5 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/ConditionalKeys.java
11 11 import java.util.Set; 12 12 import java.util.regex.Matcher; 13 13 import java.util.regex.Pattern; 14 import java.util.stream.Collectors; 14 15 15 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 17 import org.openstreetmap.josm.data.validation.Severity; … … 75 76 } 76 77 77 78 /** 79 * Check if the value is a valid restriction value 80 * @param part The value 81 * @param hasLanes key has :lanes included 82 * @return <code>true</code> for allowed restriction values 83 */ 84 public static boolean isRestrictionValueLanes(String part, Boolean hasLanes) { 85 if (hasLanes) { 86 final Set<Boolean> check = 87 Arrays.stream(part.split(tr("\\|"))) 88 .map(restrictionValue -> isRestrictionValue(restrictionValue)) 89 .collect(Collectors.toSet()); 90 return check.contains(false) ? false : true; 91 } 92 else { 93 return isRestrictionValue(part); 94 } 95 } 96 97 /** 78 98 * Checks if the key denotes a 79 99 * <a href="http://wiki.openstreetmap.org/wiki/Key:access#Transport_mode_restrictions">transport access mode restriction</a> 80 100 * @param part The key (or the restriction part of it, e.g. for lanes) … … 105 125 return false; 106 126 } 107 127 final String[] parts = key.replace(":conditional", "").split(":", -1); 108 return isKeyValid3Parts(parts) || isKeyValid1Part(parts) || isKeyValid2Parts(parts); 128 129 /* 130 * Treat cases where "lanes" is used in keys. Simply remove them. 131 */ 132 final String[] partsNoLanes = dealWithLanes(parts); 133 134 return isKeyValid3Parts(partsNoLanes) || isKeyValid1Part(partsNoLanes) || isKeyValid2Parts(partsNoLanes); 109 135 } 110 136 137 /* 138 * This is not explicitly specified at <a href="https://wiki.openstreetmap.org/wiki/Conditional_restrictions#Tagging">conditional restrictions tagging</a>, but 139 * it's saying below "A conditional Lanes restriction, evaluated per-lane, overrules a non-conditional lanes restriction" 140 * Remove from "parts" using ArrayList. This approach has the advantage that the rest of the checks do not have to be altered. 141 */ 142 private static String[] dealWithLanes(String... parts) { 143 List<String> checkLanes = new ArrayList<>(); 144 checkLanes.addAll(Arrays.asList(parts)); 145 /* lanes may only be present/removed if other keys are used, too. Additionally, they may only be used within the first two positions */ 146 if(checkLanes.size() > 1 && checkLanes.indexOf("lanes") <= 1 ){ 147 checkLanes.remove("lanes"); 148 } 149 return checkLanes.toArray(new String[checkLanes.size()]); 150 } 151 111 152 private static boolean isKeyValid3Parts(String... parts) { 112 153 return parts.length == 3 && isRestrictionType(parts[0]) && isTransportationMode(parts[1]) && isDirection(parts[2]); 113 154 } … … 195 236 try { 196 237 for (final ConditionalValue conditional : ConditionalValue.parse(value)) { 197 238 // validate restriction value 198 if (isTransportationMode(key.split(":", -1)[0]) && !isRestrictionValue (conditional.restrictionValue)) {239 if (isTransportationMode(key.split(":", -1)[0]) && !isRestrictionValueLanes(conditional.restrictionValue, key.contains(tr(":lanes")))) { 199 240 return tr("{0} is not a valid restriction value", conditional.restrictionValue); 200 241 } 201 242 // validate opening hour if the value contains an hour (heuristic) -
src/org/openstreetmap/josm/data/validation/tests/Lanes.java
40 40 return value.isEmpty() ? 0 : value.replaceAll("[^|]", "").length() + 1; 41 41 } 42 42 43 private int getLanesCountConditional(String value, Boolean isConditional, OsmPrimitive p) { 44 if (isConditional) { 45 // Also respect values like "yes|no|no @ (Mo-Fr 06:30-9:00); yes|no|no @ (Mo-Fr 17:30-19:00)" 46 final Set<Integer> allLanesCounts = 47 Arrays.stream(value.split(";")) 48 .map(removeConditional -> {return removeConditional.replaceAll("\\s*@\\s*\\(.*?\\)\\s*", "");}) 49 .map(singleValue -> getLanesCount(singleValue)) 50 .collect(Collectors.toSet()); 51 if (allLanesCounts.size() > 1) { 52 // if not all numbers are the same 53 errors.add(TestError.builder(this, Severity.WARNING, 3100) 54 .message(tr("Different lanes counts {0} within conditional value '{1}'", allLanesCounts.toString(), value)) 55 .primitives(p) 56 .build()); 57 } 58 return allLanesCounts.iterator().next(); 59 } 60 else { 61 return getLanesCount(value); 62 } 63 } 64 43 65 protected void checkNumberOfLanesByKey(final OsmPrimitive p, String lanesKey, String message) { 44 66 final Set<Integer> lanesCount = 45 67 p.keys() 46 .filter(x -> x.endsWith(":" + lanesKey) )68 .filter(x -> x.endsWith(":" + lanesKey) || x.endsWith(":" + lanesKey + ":conditional")) 47 69 .filter(x -> !Arrays.asList(BLACKLIST).contains(x)) 48 .map(key -> getLanesCount (p.get(key)))70 .map(key -> getLanesCountConditional(p.get(key), key.endsWith(":conditional"), p)) 49 71 .collect(Collectors.toSet()); 50 72 51 73 if (lanesCount.size() > 1) {
