- Timestamp:
- 2020-01-22T00:30:33+01:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java
r15043 r15745 141 141 private void collectAddress(OsmPrimitive p) { 142 142 if (!isPOI(p)) { 143 String simplifiedAddress = getSimplifiedAddress(p); 144 if (!ignoredAddresses.contains(simplifiedAddress)) { 145 knownAddresses.computeIfAbsent(simplifiedAddress, x -> new ArrayList<>()).add(p); 143 for (String simplifiedAddress : getSimplifiedAddresses(p)) { 144 if (!ignoredAddresses.contains(simplifiedAddress)) { 145 knownAddresses.computeIfAbsent(simplifiedAddress, x -> new ArrayList<>()).add(p); 146 } 146 147 } 147 148 } … … 157 158 // ignore addresses of buildings that are connected to addr:unit nodes 158 159 // it's quite reasonable that there are more buildings with this address 159 String simplifiedAddress = getSimplifiedAddress(r); 160 if (!ignoredAddresses.contains(simplifiedAddress)) { 161 ignoredAddresses.add(simplifiedAddress); 162 } else if (knownAddresses.containsKey(simplifiedAddress)) { 163 knownAddresses.remove(simplifiedAddress); 160 for (String simplifiedAddress : getSimplifiedAddresses(r)) { 161 if (!ignoredAddresses.contains(simplifiedAddress)) { 162 ignoredAddresses.add(simplifiedAddress); 163 } else if (knownAddresses.containsKey(simplifiedAddress)) { 164 knownAddresses.remove(simplifiedAddress); 165 } 164 166 } 165 167 } … … 185 187 if (!isPOI(p) && hasAddress(p)) { 186 188 List<TestError> result = new ArrayList<>(); 187 String simplifiedAddress = getSimplifiedAddress(p); 188 if (!ignoredAddresses.contains(simplifiedAddress) && knownAddresses.containsKey(simplifiedAddress)) { 189 double maxDistance = MAX_DUPLICATE_DISTANCE.get(); 190 for (OsmPrimitive p2 : knownAddresses.get(simplifiedAddress)) { 191 if (p == p2) { 192 continue; 193 } 194 Severity severityLevel; 195 String city1 = p.get(ADDR_CITY); 196 String city2 = p2.get(ADDR_CITY); 197 double distance = getDistance(p, p2); 198 if (city1 != null && city2 != null) { 199 if (city1.equals(city2)) { 200 if ((!p.hasKey(ADDR_POSTCODE) || !p2.hasKey(ADDR_POSTCODE) || p.get(ADDR_POSTCODE).equals(p2.get(ADDR_POSTCODE))) 201 && (!p.hasKey(ADDR_SUBURB) || !p2.hasKey(ADDR_SUBURB) || p.get(ADDR_SUBURB).equals(p2.get(ADDR_SUBURB)))) { 189 for (String simplifiedAddress : getSimplifiedAddresses(p)) { 190 if (!ignoredAddresses.contains(simplifiedAddress) && knownAddresses.containsKey(simplifiedAddress)) { 191 double maxDistance = MAX_DUPLICATE_DISTANCE.get(); 192 for (OsmPrimitive p2 : knownAddresses.get(simplifiedAddress)) { 193 if (p == p2) { 194 continue; 195 } 196 Severity severityLevel; 197 String city1 = p.get(ADDR_CITY); 198 String city2 = p2.get(ADDR_CITY); 199 double distance = getDistance(p, p2); 200 if (city1 != null && city2 != null) { 201 if (city1.equals(city2)) { 202 if ((!p.hasKey(ADDR_POSTCODE) || !p2.hasKey(ADDR_POSTCODE) 203 || p.get(ADDR_POSTCODE).equals(p2.get(ADDR_POSTCODE))) 204 && (!p.hasKey(ADDR_SUBURB) || !p2.hasKey(ADDR_SUBURB) 205 || p.get(ADDR_SUBURB).equals(p2.get(ADDR_SUBURB)))) { 206 severityLevel = Severity.WARNING; 207 } else { 208 // address including city identical but postcode or suburb differs 209 // most likely perfectly fine 210 severityLevel = Severity.OTHER; 211 } 212 } else { 213 // address differs only by city - notify if very close, otherwise ignore 214 if (distance < maxDistance) { 215 severityLevel = Severity.OTHER; 216 } else { 217 continue; 218 } 219 } 220 } else { 221 // at least one address has no city specified 222 if (p.hasKey(ADDR_POSTCODE) && p2.hasKey(ADDR_POSTCODE) 223 && p.get(ADDR_POSTCODE).equals(p2.get(ADDR_POSTCODE))) { 224 // address including postcode identical 202 225 severityLevel = Severity.WARNING; 203 226 } else { 204 // address including city identical but postcode or suburb differs 205 // most likely perfectly fine 206 severityLevel = Severity.OTHER; 207 } 208 } else { 209 // address differs only by city - notify if very close, otherwise ignore 210 if (distance < maxDistance) { 211 severityLevel = Severity.OTHER; 212 } else { 213 continue; 227 // city/postcode unclear - warn if very close, otherwise only notify 228 // TODO: get city from surrounding boundaries? 229 if (distance < maxDistance) { 230 severityLevel = Severity.WARNING; 231 } else { 232 severityLevel = Severity.OTHER; 233 } 214 234 } 215 235 } 216 } else { 217 // at least one address has no city specified 218 if (p.hasKey(ADDR_POSTCODE) && p2.hasKey(ADDR_POSTCODE) && p.get(ADDR_POSTCODE).equals(p2.get(ADDR_POSTCODE))) { 219 // address including postcode identical 220 severityLevel = Severity.WARNING; 221 } else { 222 // city/postcode unclear - warn if very close, otherwise only notify 223 // TODO: get city from surrounding boundaries? 224 if (distance < maxDistance) { 225 severityLevel = Severity.WARNING; 226 } else { 227 severityLevel = Severity.OTHER; 228 } 229 } 230 } 231 result.add(TestError.builder(this, severityLevel, DUPLICATE_HOUSE_NUMBER) 232 .message(tr("Duplicate house numbers"), marktr("''{0}'' ({1}m)"), simplifiedAddress, (int) distance) 233 .primitives(Arrays.asList(p, p2)).build()); 234 } 235 knownAddresses.get(simplifiedAddress).remove(p); // otherwise we would get every warning two times 236 result.add(TestError.builder(this, severityLevel, DUPLICATE_HOUSE_NUMBER) 237 .message(tr("Duplicate house numbers"), marktr("''{0}'' ({1}m)"), simplifiedAddress, (int) distance) 238 .primitives(Arrays.asList(p, p2)).build()); 239 } 240 knownAddresses.get(simplifiedAddress).remove(p); // otherwise we would get every warning two times 241 } 236 242 } 237 243 errors.addAll(result); … … 241 247 } 242 248 243 static String getSimplifiedAddress(OsmPrimitive p) {249 static List<String> getSimplifiedAddresses(OsmPrimitive p) { 244 250 String simplifiedStreetName = p.hasKey(ADDR_STREET) ? p.get(ADDR_STREET) : p.get(ADDR_PLACE); 245 251 // ignore whitespaces and dashes in street name, so that "Mozart-Gasse", "Mozart Gasse" and "Mozartgasse" are all seen as equal 246 return Utils.strip(Stream.of(252 return expandHouseNumber(p.get(ADDR_HOUSE_NUMBER)).stream().map(addrHouseNumber -> Utils.strip(Stream.of( 247 253 simplifiedStreetName.replaceAll("[ -]", ""), 248 p.get(ADDR_HOUSE_NUMBER),254 addrHouseNumber, 249 255 p.get(ADDR_HOUSE_NAME), 250 256 p.get(ADDR_UNIT), … … 252 258 .filter(Objects::nonNull) 253 259 .collect(Collectors.joining(" "))) 254 .toUpperCase(Locale.ENGLISH); 260 .toUpperCase(Locale.ENGLISH)).collect(Collectors.toList()); 261 } 262 263 /** 264 * Split addr:housenumber on , and ; (common separators) 265 * 266 * @param houseNumber The housenumber to be split 267 * @return A list of addr:housenumber equivalents 268 */ 269 static List<String> expandHouseNumber(String houseNumber) { 270 return Arrays.asList(houseNumber.split(",|;")); 255 271 } 256 272
Note:
See TracChangeset
for help on using the changeset viewer.