| | 399 | |
| | 400 | /** |
| | 401 | * Check if an associatedStreet Relation is obsolete. This test marks only those relations which |
| | 402 | * are complete and don't contain any information which isn't also tagged on the members. |
| | 403 | * The strategy is to avoid any false positive. |
| | 404 | * @param r the relation |
| | 405 | */ |
| | 406 | private void checkIfObsolete(Relation r) { |
| | 407 | if (r.isIncomplete()) |
| | 408 | return; |
| | 409 | /** array of country codes for which the test should be performed. For now, only Germany */ |
| | 410 | String[] countryCodes = {"DE"}; |
| | 411 | TagMap neededtagsForHouse = new TagMap(); |
| | 412 | for (Entry<String, String> tag : r.getKeys().entrySet()) { |
| | 413 | String key = tag.getKey(); |
| | 414 | if (key.startsWith("name:")) { |
| | 415 | return; // maybe check if all members have corresponding tags? |
| | 416 | } else if (key.startsWith("addr:")) { |
| | 417 | neededtagsForHouse.put(key, tag.getValue()); |
| | 418 | } else { |
| | 419 | switch (key) { |
| | 420 | case "name": |
| | 421 | case "type": |
| | 422 | case "source": |
| | 423 | break; |
| | 424 | default: |
| | 425 | // unexpected tag in relation |
| | 426 | return; |
| | 427 | } |
| | 428 | } |
| | 429 | } |
| | 430 | |
| | 431 | for (RelationMember m : r.getMembers()) { |
| | 432 | if (m.getMember().isIncomplete() || m.isRelation() || !isInWarnCountry(m, countryCodes)) |
| | 433 | return; |
| | 434 | |
| | 435 | String role = m.getRole(); |
| | 436 | if ("".equals(role)) { |
| | 437 | if (m.isWay() && m.getMember().hasKey("highway")) { |
| | 438 | role = "street"; |
| | 439 | } else if (m.getMember().hasTag("building")) |
| | 440 | role = "house"; |
| | 441 | } |
| | 442 | switch (role) { |
| | 443 | case "house": |
| | 444 | case "addr:houselink": |
| | 445 | case "address": |
| | 446 | if (!m.getMember().hasTag(ADDR_STREET) || !m.getMember().hasTag(ADDR_HOUSE_NUMBER)) |
| | 447 | return; |
| | 448 | for (Entry<String, String> tag : neededtagsForHouse.entrySet()) { |
| | 449 | if (!m.getMember().hasTag(tag.getKey(), tag.getValue())) |
| | 450 | return; |
| | 451 | } |
| | 452 | break; |
| | 453 | case "street": |
| | 454 | if (!m.getMember().hasTag("name") && r.hasTag("name")) |
| | 455 | return; |
| | 456 | break; |
| | 457 | default: |
| | 458 | // unknown role: don't create auto-fix |
| | 459 | return; |
| | 460 | } |
| | 461 | } |
| | 462 | errors.add(TestError.builder(this, Severity.WARNING, OBSOLETE_RELATION) |
| | 463 | .message(tr("Relation is obsolete")) |
| | 464 | .primitives(r) |
| | 465 | .build()); |
| | 466 | } |
| | 467 | |
| | 468 | private static boolean isInWarnCountry(RelationMember m, String[] countryCodes) { |
| | 469 | if (countryCodes.length == 0) |
| | 470 | return true; |
| | 471 | LatLon center = null; |
| | 472 | |
| | 473 | if (m.isNode()) { |
| | 474 | center = m.getNode().getCoor(); |
| | 475 | } else if (m.isWay()) { |
| | 476 | center = m.getWay().getBBox().getCenter(); |
| | 477 | } |
| | 478 | if (center == null) |
| | 479 | return true; |
| | 480 | for (String country : countryCodes) { |
| | 481 | if (Territories.isIso3166Code(country, center)) |
| | 482 | return true; |
| | 483 | } |
| | 484 | return false; |
| | 485 | } |
| | 486 | |
| | 487 | /** |
| | 488 | * remove obsolete relation. |
| | 489 | */ |
| | 490 | @Override |
| | 491 | public Command fixError(TestError testError) { |
| | 492 | return new DeleteCommand(testError.getPrimitives()); |
| | 493 | } |
| | 494 | |
| | 495 | @Override |
| | 496 | public boolean isFixable(TestError testError) { |
| | 497 | if (!(testError.getTester() instanceof Addresses)) |
| | 498 | return false; |
| | 499 | return testError.getCode() == OBSOLETE_RELATION; |
| | 500 | } |
| | 501 | |