Changeset 15745 in josm for trunk/src


Ignore:
Timestamp:
2020-01-22T00:30:33+01:00 (5 years ago)
Author:
Don-vip
Message:

fix #18590 - AddressesTest should split addresses on common delimiters (, and ;) (patch by taylor.smock, modified)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java

    r15043 r15745  
    141141    private void collectAddress(OsmPrimitive p) {
    142142        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                }
    146147            }
    147148        }
     
    157158                        // ignore addresses of buildings that are connected to addr:unit nodes
    158159                        // 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                            }
    164166                        }
    165167                    }
     
    185187        if (!isPOI(p) && hasAddress(p)) {
    186188            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
    202225                                severityLevel = Severity.WARNING;
    203226                            } 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                                }
    214234                            }
    215235                        }
    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                }
    236242            }
    237243            errors.addAll(result);
     
    241247    }
    242248
    243     static String getSimplifiedAddress(OsmPrimitive p) {
     249    static List<String> getSimplifiedAddresses(OsmPrimitive p) {
    244250        String simplifiedStreetName = p.hasKey(ADDR_STREET) ? p.get(ADDR_STREET) : p.get(ADDR_PLACE);
    245251        // 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(
    247253                simplifiedStreetName.replaceAll("[ -]", ""),
    248                 p.get(ADDR_HOUSE_NUMBER),
     254                addrHouseNumber,
    249255                p.get(ADDR_HOUSE_NAME),
    250256                p.get(ADDR_UNIT),
     
    252258            .filter(Objects::nonNull)
    253259            .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(",|;"));
    255271    }
    256272
Note: See TracChangeset for help on using the changeset viewer.