Ticket #11778: 11778-alpha.patch

File 11778-alpha.patch, 6.6 KB (added by GerdP, 6 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java

     
    3333import org.openstreetmap.josm.data.validation.TestError;
    3434import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3535import org.openstreetmap.josm.spi.preferences.Config;
     36import org.openstreetmap.josm.tools.Geometry;
    3637
    3738/**
    3839 * Checks if a way has an endpoint very near to another way.
     
    4950
    5051    protected abstract boolean isCandidate(OsmPrimitive p);
    5152
     53    /**
     54     * Check if unconnected end node should be ignored.
     55     * @param n the node
     56     * @return true if node should be ignored
     57     */
     58    protected boolean ignoreUnconnectedEndNode(Node n) {
     59        return false;
     60    }
     61
    5262    @Override
    5363    public boolean isPrimitiveUsable(OsmPrimitive p) {
    5464        return super.isPrimitiveUsable(p) && ((partialSelection && p instanceof Node) || isCandidate(p));
     
    7181        protected boolean isCandidate(OsmPrimitive p) {
    7282            return p.hasKey(HIGHWAY);
    7383        }
     84
     85        @Override
     86        protected boolean ignoreUnconnectedEndNode(Node n) {
     87            return n.hasTag(HIGHWAY, "turning_circle", "bus_stop")
     88                    || n.hasTag("amenity", "parking_entrance")
     89                    || n.isKeyTrue("noexit")
     90                    || n.hasKey("entrance", "barrier")
     91                    || n.getParentWays().stream().anyMatch(Test::isBuilding);
     92        }
    7493    }
    7594
    7695    /**
     
    87106
    88107        @Override
    89108        protected boolean isCandidate(OsmPrimitive p) {
    90             return p.hasKey(RAILWAY) && !p.hasTag(RAILWAY, "abandoned");
     109            return p.hasTagDifferent(RAILWAY, "abandoned");
    91110        }
     111
     112        @Override
     113        protected boolean ignoreUnconnectedEndNode(Node n) {
     114            return n.hasTag(RAILWAY, "buffer_stop");
     115        }
    92116    }
    93117
    94118    /**
     
    123147
    124148        @Override
    125149        protected boolean isCandidate(OsmPrimitive p) {
    126             return p.hasKey("natural", "landuse") && !p.hasTag("natural", "tree_row", "cliff");
     150            return p.hasKey("landuse") || p.hasTagDifferent("natural", "tree_row", "cliff");
    127151        }
    128152    }
    129153
     
    199223        dsArea = ds == null ? null : ds.getDataSourceArea();
    200224    }
    201225
     226    private boolean isMuchNearerToBuilding(Node node, double distToHighway) {
     227        double fudge = 0.33 * distToHighway * (360.0d / (Ellipsoid.WGS84.a * 2 * Math.PI));
     228        double x = node.getCoor().lon();
     229        double y = node.getCoor().lat();
     230        LatLon topLeft = new LatLon(y+fudge, x-fudge);
     231        LatLon botRight = new LatLon(y-fudge, x+fudge);
     232        BBox bbox = new BBox(topLeft, botRight);
     233        for (Node n : ds.searchNodes(bbox)) {
     234            if (isBuilding(n) && node.getCoor().greatCircleDistance(n.getCoor()) < distToHighway) return true;
     235        }
     236        for (Way w : ds.searchWays(bbox)) {
     237            if (isBuilding(w) && Geometry.getDistanceWayNode(w, node) < distToHighway) return true;
     238        }
     239        return false;
     240    }
     241
    202242    protected Map<Node, MyWaySegment> getWayEndNodesNearOtherHighway() {
    203243        Map<Node, MyWaySegment> map = new HashMap<>();
    204244        for (MyWaySegment s : waySegments) {
     
    207247                return map;
    208248            }
    209249            for (Node en : s.nearbyNodes(mindist)) {
    210                 if (en.hasTag(HIGHWAY, "turning_circle", "bus_stop")
    211                         || en.hasTag("amenity", "parking_entrance")
    212                         || en.hasTag(RAILWAY, "buffer_stop")
    213                         || en.isKeyTrue("noexit")
    214                         || en.hasKey("entrance", "barrier")) {
    215                     continue;
    216                 }
    217250                // to handle intersections of 't' shapes and similar
    218                 if (!en.isConnectedTo(s.w.getNodes(), 3 /* hops */, null)) {
     251                if (!en.isConnectedTo(s.w.getNodes(), 1 /* hops */, null)) {
     252                    if (isHighwayTest && s.w.hasTag(HIGHWAY, "service", "footway", "steps", "path")
     253                            && isMuchNearerToBuilding(en, s.getDist(en))) {
     254                        continue;
     255                    }
    219256                    addIfNewOrCloser(map, en, s);
    220257                }
    221258            }
     
    232269            }
    233270            if (!s.concernsArea) {
    234271                for (Node en : s.nearbyNodes(mindist)) {
    235                     if (!en.isConnectedTo(s.w.getNodes(), 3 /* hops */, null)) {
     272                    if (!en.isConnectedTo(s.w.getNodes(), 1 /* hops */, null)) {
    236273                        addIfNewOrCloser(map, en, s);
    237274                    }
    238275                }
     
    249286                return map;
    250287            }
    251288            for (Node en : s.nearbyNodes(minmiddledist)) {
    252                 if (!en.isConnectedTo(s.w.getNodes(), 3 /* hops */, null)) {
     289                if (!en.isConnectedTo(s.w.getNodes(), 1 /* hops */, null)) {
    253290                    addIfNewOrCloser(map, en, s);
    254291                }
    255292            }
     
    291328
    292329        for (Way w : ds.getWays()) {
    293330            if (w.isUsable() && isCandidate(w) && w.getRealNodesCount() > 1
    294                     // don't complain about highways ending near platforms
     331                    // don't complain about highways or railways ending near platforms
    295332                    && !w.hasTag(HIGHWAY, "platform") && !w.hasTag(RAILWAY, "platform", "platform_edge")
    296333                    ) {
    297334                waySegments.addAll(getWaySegments(w));
     
    299336                addNode(w.lastNode(), endnodes);
    300337            }
    301338        }
    302         searchNodes = new QuadBuckets<>();
    303         searchNodes.addAll(endnodes);
    304         if (isHighwayTest) {
    305             addErrors(Severity.WARNING, getWayEndNodesNearOtherHighway(), tr("Way end node near other highway"));
    306         } else {
    307             addErrors(Severity.WARNING, getWayEndNodesNearOtherWay(), tr("Way end node near other way"));
     339        endnodes.removeIf(this::ignoreUnconnectedEndNode);
     340        if (!endnodes.isEmpty()) {
     341            searchNodes = new QuadBuckets<>();
     342            searchNodes.addAll(endnodes);
     343            if (isHighwayTest) {
     344                addErrors(Severity.WARNING, getWayEndNodesNearOtherHighway(), tr("Way end node near other highway"));
     345            } else {
     346                addErrors(Severity.WARNING, getWayEndNodesNearOtherWay(), tr("Way end node near other way"));
     347            }
    308348        }
    309349
    310350        /* the following two use a shorter distance */