Ticket #20716: josm_20716_power_v1.patch

File josm_20716_power_v1.patch, 9.9 KB (added by gaben, 5 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java b/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java
    a b  
    4747    /** Bag of all way segments */
    4848    private MultiMap<Pair<Node, Node>, WaySegment> nodePairs;
    4949
    50     private boolean onlyKnwonLinear;
     50    private boolean onlyKnownLinear;
    5151    private boolean includeOther;
    5252    private boolean ignoreLayer;
    5353
     
    8383        super.startTest(monitor);
    8484        nodePairs = new MultiMap<>(1000);
    8585        includeOther = isBeforeUpload ? ValidatorPrefHelper.PREF_OTHER_UPLOAD.get() : ValidatorPrefHelper.PREF_OTHER.get();
    86         onlyKnwonLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true);
     86        onlyKnownLinear = Config.getPref().getBoolean("overlapping-ways.only-known-linear", true);
    8787        ignoreLayer = Config.getPref().getBoolean("overlapping-ways.ignore-layer", false);
    8888    }
    8989
     
    192192                errortype = tr("Waterway shares segment with linear way");
    193193                type = OVERLAPPING_WATERWAY_LINEAR_WAY;
    194194                severity = Severity.WARNING;
    195             } else if (!includeOther || onlyKnwonLinear) {
     195            } else if (!includeOther || onlyKnownLinear) {
    196196                return;
    197197            } else if (countHighway > 0) {
    198198                errortype = tr("Highway shares segment with other way");
     
    269269        if (IGNORED.test(w))
    270270            return;
    271271
    272         if (onlyKnwonLinear && (w.concernsArea() || w.getInterestingTags().isEmpty()))
     272        if (onlyKnownLinear && (w.concernsArea() || w.getInterestingTags().isEmpty()))
    273273            return;
    274274
    275275        Node lastN = null;
  • src/org/openstreetmap/josm/data/validation/tests/PowerLines.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java b/src/org/openstreetmap/josm/data/validation/tests/PowerLines.java
    a b  
    1111import java.util.Set;
    1212
    1313import org.openstreetmap.josm.data.osm.Node;
     14import org.openstreetmap.josm.data.osm.NodePair;
    1415import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1516import org.openstreetmap.josm.data.osm.Relation;
    1617import org.openstreetmap.josm.data.osm.RelationMember;
     
    2526import org.openstreetmap.josm.tools.Geometry;
    2627
    2728/**
    28  * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole tag.<br>
    29  * See #7812 for discussions about this test.
     29 * Checks for nodes in power lines/minor_lines that do not have a power=tower/pole/portal tag and also for ways where
     30 * are unusually long segments without line support feature.<br>
     31 * See #7812 and #{FIXME number} for discussions about this test.
    3032 */
    3133public class PowerLines extends Test {
    3234
    3335    /** Test identifier */
    3436    protected static final int POWER_LINES = 2501;
    3537    protected static final int POWER_CONNECTION = 2502;
     38    protected static final int POWER_SEGMENT_LENGTH = 2503;
    3639
    3740    /** Values for {@code power} key interpreted as power lines */
    3841    static final Collection<String> POWER_LINE_TAGS = Arrays.asList("line", "minor_line");
    3942    /** Values for {@code power} key interpreted as power towers */
    40     static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole");
     43    static final Collection<String> POWER_TOWER_TAGS = Arrays.asList("tower", "pole", "portal");
    4144    /** Values for {@code power} key interpreted as power stations */
    4245    static final Collection<String> POWER_STATION_TAGS = Arrays.asList("station", "sub_station", "substation", "plant", "generator");
    4346    /** Values for {@code building} key interpreted as power stations */
     
    4750            "portal", "terminal", "insulator");
    4851
    4952    private final Set<Node> badConnections = new LinkedHashSet<>();
    50     private final Set<Node> missingTowerOrPole = new LinkedHashSet<>();
     53    private final Set<Node> missingTag = new LinkedHashSet<>();
     54    private final Set<NodePair> missingNode = new LinkedHashSet<>();
    5155
    5256    private final List<OsmPrimitive> powerStations = new ArrayList<>();
    5357
     
    5862        super(tr("Power lines"), tr("Checks for nodes in power lines that do not have a power=tower/pole tag."));
    5963    }
    6064
    61     @Override
    62     public void visit(Way w) {
    63         if (w.isUsable()) {
    64             if (isPowerLine(w) && !w.hasTag("location", "underground")) {
    65                 for (Node n : w.getNodes()) {
    66                     if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)
    67                         && (!w.isFirstLastNode(n) || !isPowerStation(n))) {
    68                         missingTowerOrPole.add(n);
    69                     }
    70                 }
    71             } else if (w.isClosed() && isPowerStation(w)) {
    72                 powerStations.add(w);
    73             }
    74         }
    75     }
    76 
    7765    @Override
    7866    public void visit(Node n) {
    7967        boolean nodeInLineOrCable = false;
     
    8977            badConnections.add(n);
    9078    }
    9179
    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())
    99                         return true;
     80    @Override
     81    public void visit(Way w) {
     82        if (w.isUsable()) {
     83            if (isPowerLine(w) && !w.hasTag("location", "underground")) {
     84                float avgWayLength = (float) (w.getLength() / w.getRealNodesCount());
     85                Node prevNode = w.firstNode();
     86
     87                for (Node n : w.getNodes()) {
     88                    if (!isPowerTower(n) && !isPowerAllowed(n) && IN_DOWNLOADED_AREA.test(n)
     89                            && (!w.isFirstLastNode(n) || !isPowerStation(n))) {
     90                        missingTag.add(n);
     91                    }
     92
     93                    double distance = n.getCoor().greatCircleDistance(prevNode.getCoor());
     94                    if (w.getRealNodesCount() > 4 && distance > avgWayLength * 2.0f && !isPowerAllowed(n)) {
     95                        missingNode.add(new NodePair(prevNode, n));
     96                    }
     97                    prevNode = n;
    10098                }
     99            } else if (w.isClosed() && isPowerStation(w)) {
     100                powerStations.add(w);
    101101            }
    102102        }
    103         return false;
    104103    }
    105104
    106105    @Override
     
    118117
    119118    @Override
    120119    public void endTest() {
    121         for (Node n : missingTowerOrPole) {
     120        for (Node n : missingTag) {
    122121            if (!isInPowerStation(n)) {
    123122                errors.add(TestError.builder(this, Severity.WARNING, POWER_LINES)
    124                         .message(tr("Missing power tower/pole within power line"))
     123                        .message(tr("Missing power line support tag from node"))
    125124                        .primitives(n)
    126125                        .build());
    127126            }
     
    130129        for (Node n : badConnections) {
    131130            errors.add(TestError.builder(this, Severity.WARNING, POWER_CONNECTION)
    132131                    .message(tr("Node connects a power line or cable with an object "
    133                             + "which is not related to the power infrastructure."))
    134                     .primitives(n).build());
     132                            + "which is not related to the power infrastructure"))
     133                    .primitives(n)
     134                    .build());
    135135        }
     136
     137        for (NodePair pair : missingNode) {
     138            errors.add(TestError.builder(this, Severity.WARNING, POWER_SEGMENT_LENGTH)
     139                    .message(tr("Missing line support node within power line"))
     140                    .primitives(pair.getA(), pair.getB())
     141                    .build());
     142        }
     143
    136144        clearCollections();
    137145        super.endTest();
    138146    }
    139147
     148    private static boolean isRelatedToPower(Way way) {
     149        if (way.hasTag("power") || way.hasTag("building"))
     150            return true;
     151        for (OsmPrimitive ref : way.getReferrers()) {
     152            if (ref instanceof Relation && ref.isMultipolygon() && (ref.hasTag("power") || ref.hasTag("building"))) {
     153                for (RelationMember rm : ((Relation) ref).getMembers()) {
     154                    if (way == rm.getMember())
     155                        return true;
     156                }
     157            }
     158        }
     159        return false;
     160    }
     161
    140162    protected final boolean isInPowerStation(Node n) {
    141163        for (OsmPrimitive station : powerStations) {
    142164            List<List<Node>> nodesLists = new ArrayList<>();
     
    189211    /**
    190212     * Determines if the specified node denotes a power infrastructure allowed on a power line.
    191213     * @param n The node to be tested
    192      * @return True if power key is set and equal to switch/tranformer/busbar/generator
     214     * @return True if power key is set and equal to switch/transformer/busbar/generator
    193215     */
    194216    protected static final boolean isPowerAllowed(Node n) {
    195217        return isPowerIn(n, POWER_ALLOWED_TAGS);
     
    218240    private void clearCollections() {
    219241        powerStations.clear();
    220242        badConnections.clear();
    221         missingTowerOrPole.clear();
     243        missingTag.clear();
     244        missingNode.clear();
    222245    }
    223246}