Ticket #16247: 16247.patch

File 16247.patch, 5.3 KB (added by GerdP, 5 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/PowerLines.java

     
    66import java.util.ArrayList;
    77import java.util.Arrays;
    88import java.util.Collection;
     9import java.util.LinkedHashSet;
    910import java.util.List;
     11import java.util.Set;
    1012
    1113import org.openstreetmap.josm.data.osm.Node;
    1214import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1315import org.openstreetmap.josm.data.osm.Relation;
     16import org.openstreetmap.josm.data.osm.RelationMember;
    1417import org.openstreetmap.josm.data.osm.Way;
    1518import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
    1619import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay;
     
    2932
    3033    /** Test identifier */
    3134    protected static final int POWER_LINES = 2501;
     35    protected static final int POWER_CONNECTION = 2502;
    3236
    3337    /** Values for {@code power} key interpreted as power lines */
    3438    static final Collection<String> POWER_LINE_TAGS = Arrays.asList("line", "minor_line");
     
    4246    static final Collection<String> POWER_ALLOWED_TAGS = Arrays.asList("switch", "transformer", "busbar", "generator", "switchgear",
    4347            "portal", "terminal", "insulator");
    4448
    45     private final List<TestError> potentialErrors = new ArrayList<>();
     49    private final Set<Node> badConnections = new LinkedHashSet<>();
     50    private final Set<Node> missingTowerOrPole = new LinkedHashSet<>();
    4651
    4752    private final List<OsmPrimitive> powerStations = new ArrayList<>();
    4853
     
    6065                for (Node n : w.getNodes()) {
    6166                    if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)
    6267                        && (!w.isFirstLastNode(n) || !isPowerStation(n))) {
    63                         potentialErrors.add(TestError.builder(this, Severity.WARNING, POWER_LINES)
    64                                 .message(tr("Missing power tower/pole within power line"))
    65                                 .primitives(n)
    66                                 .build());
     68                        missingTowerOrPole.add(n);
    6769                    }
    6870                }
    6971            } else if (w.isClosed() && isPowerStation(w)) {
     
    7375    }
    7476
    7577    @Override
     78    public void visit(Node n) {
     79        boolean nodeInLineOrCable = false;
     80        boolean connectedToUnrelated = false;
     81        for (Way parent : n.getParentWays()) {
     82            if (parent.hasTag("power", "line", "minor_line", "cable"))
     83                nodeInLineOrCable = true;
     84            else if (!isRelatedToPower(parent)) {
     85                connectedToUnrelated = true;
     86            }
     87        }
     88        if (nodeInLineOrCable && connectedToUnrelated)
     89            badConnections.add(n);
     90    }
     91
     92    private static boolean isRelatedToPower(Way way) {
     93        if (way.hasTag("power") || way.hasTag("building"))
     94            return true;
     95        for (OsmPrimitive ref : way.getReferrers()) {
     96            if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) {
     97                for (RelationMember rm : ((Relation) ref).getMembers()) {
     98                    if (way == rm.getMember() && !"inner".equals(rm.getRole()))
     99                        return true;
     100                }
     101            }
     102        }
     103        return false;
     104    }
     105
     106    @Override
    76107    public void visit(Relation r) {
    77108        if (r.isMultipolygon() && isPowerStation(r)) {
    78109            powerStations.add(r);
     
    82113    @Override
    83114    public void startTest(ProgressMonitor progressMonitor) {
    84115        super.startTest(progressMonitor);
    85         powerStations.clear();
    86         potentialErrors.clear();
     116        clearCollections();
    87117    }
    88118
    89119    @Override
    90120    public void endTest() {
    91         for (TestError e : potentialErrors) {
    92             e.primitives(Node.class)
    93                     .filter(n -> !isInPowerStation(n))
    94                     .findAny()
    95                     .ifPresent(ignore -> errors.add(e));
     121        for (Node n : missingTowerOrPole) {
     122            if (!isInPowerStation(n)) {
     123                errors.add(TestError.builder(this, Severity.WARNING, POWER_LINES)
     124                        .message(tr("Missing power tower/pole within power line"))
     125                        .primitives(n)
     126                        .build());
     127            }
    96128        }
    97         potentialErrors.clear();
    98         powerStations.clear();
     129
     130        for (Node n : badConnections) {
     131            errors.add(TestError.builder(this, Severity.WARNING, POWER_CONNECTION)
     132                    .message(tr("Node connects a power line or cable with an object "
     133                            + "which is not related to the power infrastructure (java)."))
     134                    .primitives(n).build());
     135        }
     136        clearCollections();
    99137        super.endTest();
    100138    }
    101139
     
    176214    private static boolean isBuildingIn(OsmPrimitive p, Collection<String> values) {
    177215        return p.hasTag("building", values);
    178216    }
     217
     218    private void clearCollections() {
     219        powerStations.clear();
     220        badConnections.clear();
     221        missingTowerOrPole.clear();
     222    }
    179223}