protected void checkDistance(OsmPrimitive house, Collection<Way> street) { EastNorth centroid; if (house instanceof Node) { centroid = ((Node) house).getEastNorth(); } else if (house instanceof Way) { List<Node> nodes = ((Way) house).getNodes(); if (house.hasKey(ADDR_INTERPOLATION)) { for (Node n : nodes) { if (n.hasKey(ADDR_HOUSE_NUMBER)) { checkDistance(n, street); } } return; } centroid = Geometry.getCentroid(nodes); } else { return; // TODO handle multipolygon houses ? } if (centroid == null) return; // fix #8305 double maxDistance = Main.pref.getDouble("validator.addresses.max_street_distance", 200.0); boolean hasIncompleteWays = false; for (Way streetPart : street) { for (Pair<Node, Node> chunk : streetPart.getNodePairs(false)) { EastNorth closest = Geometry.closestPointToSegment( chunk.a.getEastNorth(), chunk.b.getEastNorth(), centroid); if (closest.distance(centroid) <= maxDistance) { return; } } if (!hasIncompleteWays && streetPart.isIncomplete()) { hasIncompleteWays = true; } } // No street segment found near this house, report error on if the relation does not contain // incomplete street ways (fix #8314) if (hasIncompleteWays) return; List<OsmPrimitive> errorList = new ArrayList<OsmPrimitive>(street); errorList.add(0, house); errors.add( new AddressError(HOUSE_NUMBER_TOO_FAR, errorList, tr("House number too far from street"))); }