Changeset 12312 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2017-06-04T18:39:14+02:00 (7 years ago)
Author:
Don-vip
Message:

fix #14891 - improve roundabout/links validator test

File:
1 edited

Legend:

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

    r12031 r12312  
    1313import java.util.Map;
    1414import java.util.Set;
     15import java.util.stream.Collectors;
    1516
    1617import org.openstreetmap.josm.command.ChangePropertyCommand;
     
    108109    private void testWrongRoundabout(Way w) {
    109110        Map<String, List<Way>> map = new HashMap<>();
    110         // Count all highways (per type) connected to this roundabout, except links
     111        // Count all highways (per type) connected to this roundabout, except correct links
    111112        // As roundabouts are closed ways, take care of not processing the first/last node twice
    112113        for (Node n : new HashSet<>(w.getNodes())) {
    113114            for (Way h : Utils.filteredCollection(n.getReferrers(), Way.class)) {
    114115                String value = h.get(HIGHWAY);
    115                 if (h != w && value != null && !value.endsWith("_link")) {
    116                     List<Way> list = map.get(value);
    117                     if (list == null) {
    118                         list = new ArrayList<>();
    119                         map.put(value, list);
    120                     }
    121                     list.add(h);
     116                if (h != w && value != null) {
     117                    boolean link = value.endsWith("_link");
     118                    boolean linkOk = isHighwayLinkOkay(h);
     119                    if (link && !linkOk) {
     120                        // "Autofix" bad link value to avoid false positive in roundabout check
     121                        value = value.replaceAll("_link$", "");
     122                    }
     123                    if (!link || !linkOk) {
     124                        List<Way> list = map.get(value);
     125                        if (list == null) {
     126                            list = new ArrayList<>();
     127                            map.put(value, list);
     128                        }
     129                        list.add(h);
     130                    }
    122131                }
    123132            }
     
    146155    }
    147156
     157    /**
     158     * Determines if the given link road is correct, see https://wiki.openstreetmap.org/wiki/Highway_link.
     159     * @param way link road
     160     * @return {@code true} if the link road is correct or if the check cannot be performed due to missing data
     161     */
    148162    public static boolean isHighwayLinkOkay(final Way way) {
    149163        final String highway = way.get(HIGHWAY);
     
    165179        }
    166180
    167         return Utils.filteredCollection(referrers, Way.class).stream().anyMatch(
    168                 otherWay -> !way.equals(otherWay) && otherWay.hasTag(HIGHWAY, highway, highway.replaceAll("_link$", "")));
     181        // Find ways of same class (exact class of class_link)
     182        List<Way> sameClass = Utils.filteredCollection(referrers, Way.class).stream().filter(
     183                otherWay -> !way.equals(otherWay) && otherWay.hasTag(HIGHWAY, highway, highway.replaceAll("_link$", "")))
     184                .collect(Collectors.toList());
     185        if (sameClass.size() > 1) {
     186            // It is possible to have a class_link between 2 segments of same class
     187            // in roundabout designs that physically separate a specific turn from the main roundabout
     188            // But if we have more than a single adjacent class, and one of them is a roundabout, that's an error
     189            for (Way w : sameClass) {
     190                if (w.hasTag("junction", "roundabout")) {
     191                    return false;
     192                }
     193            }
     194        }
     195        // Link roads should always at least one adjacent segment of same class
     196        return !sameClass.isEmpty();
    169197    }
    170198
Note: See TracChangeset for help on using the changeset viewer.