Ticket #18138: 18138.patch

File 18138.patch, 6.2 KB (added by Traaker_L, 6 years ago)
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

     
    4242import org.openstreetmap.josm.data.validation.tests.BarriersEntrances;
    4343import org.openstreetmap.josm.data.validation.tests.Coastlines;
    4444import org.openstreetmap.josm.data.validation.tests.ConditionalKeys;
     45import org.openstreetmap.josm.data.validation.tests.ConnectivityRelationCheck;
    4546import org.openstreetmap.josm.data.validation.tests.CrossingWays;
    4647import org.openstreetmap.josm.data.validation.tests.DuplicateNode;
    4748import org.openstreetmap.josm.data.validation.tests.DuplicateRelation;
     
    148149        LongSegment.class, // 3500 .. 3599
    149150        PublicTransportRouteTest.class, // 3600 .. 3699
    150151        RightAngleBuildingTest.class, // 3700 .. 3799
     152        ConnectivityRelationCheck.class, // 3800 .. 3899
     153
    151154    };
    152155
    153156    /**
  • src/org/openstreetmap/josm/data/validation/tests/ConnectivityRelationCheck.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.HashMap;
     7import java.util.Map;
     8
     9import org.openstreetmap.josm.data.osm.OsmPrimitive;
     10import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     11import org.openstreetmap.josm.data.osm.Relation;
     12import org.openstreetmap.josm.data.osm.RelationMember;
     13import org.openstreetmap.josm.data.validation.Severity;
     14import org.openstreetmap.josm.data.validation.Test;
     15import org.openstreetmap.josm.data.validation.TestError;
     16
     17/**
     18 * Check for inconsistencies in lane information between relation and members.
     19 */
     20public class ConnectivityRelationCheck extends Test {
     21
     22    protected static final int INCONSISTENT_LANE_COUNT = 3800;
     23
     24    protected static final int UNKNOWN_CONNECTIVITY_ROLE = 3801;
     25
     26    protected static final int NO_CONNECTIVITY_TAG = 3802;
     27
     28    /**
     29    * Constructor
     30    */
     31    public ConnectivityRelationCheck() {
     32        super(tr("Connectivity Relation Check"), tr("Checks that lane count of relation matches with lanes of members"));
     33    }
     34
     35    //Get lane count of members from the 'connectivity' tag
     36    private Map<String, Integer> countLanesFromConnTag(Relation r) {
     37        Map<String, Integer> laneInfo = new HashMap<String, Integer>();
     38        if (r.hasKey("connectivity")) {
     39            String connectivityString = r.get("connectivity");
     40            laneInfo.put("from", 0);
     41            laneInfo.put("to", 0);
     42            String roleString = "from";
     43            for (char ch : connectivityString.toCharArray()) {
     44                if (Character.isDigit(ch)) {
     45                    int laneNum = Character.getNumericValue(ch);
     46                    if (laneNum > laneInfo.get(roleString)) {
     47                        laneInfo.put(roleString, laneNum);
     48                    }
     49                } else if (ch == ':') {
     50                    roleString = "to";
     51                } else if (ch == '|') {
     52                    roleString = "from";
     53                }
     54            }
     55        }
     56        return laneInfo;
     57    }
     58
     59    @Override
     60    public void visit(Relation r) {
     61        if (r.hasTag("type", "connectivity")) {
     62            //No Connectivity, member outside
     63            boolean incompleteMember = false, badRole = false;
     64            boolean noConnectivityTag = !r.hasKey("connectivity");
     65            //Lane count from connectivity tag
     66            Map<String, Integer> connTagLanes = countLanesFromConnTag(r);
     67            //Lane count from member tags
     68            Map<String, Integer> roleLanes = new HashMap<String, Integer>();
     69            for (RelationMember rM : r.getMembers()) {
     70                if (!incompleteMember) {
     71                    incompleteMember = rM.toString().contains("incomplete");
     72                }
     73                //Check role names
     74                String role = rM.getRole();
     75                if (!badRole) {
     76                    badRole = (!role.equals("from") && !role.equals("to") && !role.equals("via"));
     77                }
     78                //Check lanes
     79                if (rM.getType() == OsmPrimitiveType.WAY) {
     80                    OsmPrimitive prim = rM.getMember();
     81                    if (prim.hasKey("lanes")) {
     82                        if (!rM.getRole().equals("via")) {
     83                            roleLanes.put(rM.getRole(), Integer.parseInt(prim.get("lanes")));
     84                        }
     85                    }
     86                }
     87            }
     88            if (!incompleteMember) {
     89                if (noConnectivityTag) {
     90                    errors.add(TestError
     91                            .builder(this, Severity.WARNING, NO_CONNECTIVITY_TAG)
     92                            .message(tr("kaart"), tr("No connectivity tag in connectivity relation"))
     93                            .primitives(r)
     94                            .build());
     95                } else {
     96                    boolean fromCheck = roleLanes.get("from") < connTagLanes.get("from");
     97                    boolean toCheck = roleLanes.get("to") < connTagLanes.get("to");
     98                    if (fromCheck || toCheck) {
     99                        errors.add(TestError
     100                                .builder(this, Severity.WARNING, INCONSISTENT_LANE_COUNT)
     101                                .message(tr("kaart"), tr("Inconsistent lane numbering between relation and members"))
     102                                .primitives(r)
     103                                .build());
     104                    }
     105                }
     106                if (badRole) {
     107                    errors.add(TestError
     108                            .builder(this, Severity.WARNING, UNKNOWN_CONNECTIVITY_ROLE)
     109                            .message(tr("kaart"), tr("Unkown role in connectivity relation"))
     110                            .primitives(r)
     111                            .build());
     112                }
     113            }
     114        }
     115    }
     116}