Ignore:
Timestamp:
2011-08-28T13:26:45+02:00 (13 years ago)
Author:
stoecker
Message:

fix #5861 - patch by simon04 - validator warnings for multiple via ways

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/TurnrestrictionTest.java

    r3673 r4370  
    55
    66import java.util.ArrayList;
     7import java.util.Arrays;
    78import java.util.Collections;
     9import java.util.List;
    810
    911import org.openstreetmap.josm.data.osm.Node;
     
    3133    protected static final int FROM_VIA_WAY = 1811;
    3234    protected static final int TO_VIA_WAY = 1812;
     35    protected static final int MIX_VIA = 1813;
     36    protected static final int UNCONNECTED_VIA = 1814;
    3337
    3438    public TurnrestrictionTest() {
     
    4347        Way fromWay = null;
    4448        Way toWay = null;
    45         OsmPrimitive via = null;
     49        List<OsmPrimitive> via = new ArrayList<OsmPrimitive>();
    4650
    4751        boolean morefrom = false;
    4852        boolean moreto = false;
    4953        boolean morevia = false;
     54        boolean mixvia = false;
    5055
    5156        /* find the "from", "via" and "to" elements */
     
    7681                    }
    7782                } else if ("via".equals(m.getRole())) {
    78                     if (via != null) {
    79                         morevia = true;
    80                     } else {
    81                         via = w;
     83                    if (!via.isEmpty() && via.get(0) instanceof Node) {
     84                        mixvia = true;
     85                    } else {
     86                        via.add(w);
    8287                    }
    8388                } else {
     
    8893                Node n = m.getNode();
    8994                if ("via".equals(m.getRole())) {
    90                     if (via != null) {
    91                         morevia = true;
    92                     } else {
    93                         via = n;
     95                    if (!via.isEmpty()) {
     96                        if (via.get(0) instanceof Node) {
     97                            morevia = true;
     98                        } else {
     99                            mixvia = true;
     100                        }
     101                    } else {
     102                        via.add(n);
    94103                    }
    95104                } else {
     
    109118        }
    110119        if (morevia) {
    111             errors.add(new TestError(this, Severity.ERROR, tr("More than one \"via\" way found"), MORE_VIA, r));
     120            errors.add(new TestError(this, Severity.ERROR, tr("More than one \"via\" node found"), MORE_VIA, r));
     121        }
     122        if (mixvia) {
     123            errors.add(new TestError(this, Severity.ERROR, tr("Cannot mix node and way for role \"via\""), MIX_VIA, r));
    112124        }
    113125
     
    120132            return;
    121133        }
    122         if (via == null) {
     134        if (via.isEmpty()) {
    123135            errors.add(new TestError(this, Severity.ERROR, tr("No \"via\" node or way found"), NO_VIA, r));
    124136            return;
     
    126138
    127139        Node viaNode;
    128         if (via instanceof Node) {
    129             viaNode = (Node) via;
    130             if (!fromWay.isFirstLastNode(viaNode)) {
    131                 errors.add(new TestError(this, Severity.ERROR,
    132                         tr("The \"from\" way does not start or end at a \"via\" node"), FROM_VIA_NODE, r));
    133                 return;
     140        if (via.get(0) instanceof Node) {
     141            viaNode = (Node) via.get(0);
     142            Way viaPseudoWay = new Way();
     143            viaPseudoWay.addNode(viaNode);
     144            checkIfConnected(fromWay, viaPseudoWay,
     145                    tr("The \"from\" way does not start or end at a \"via\" node"), FROM_VIA_NODE);
     146            checkIfConnected(viaPseudoWay, toWay,
     147                    tr("The \"to\" way does not start or end at a \"via\" node"), TO_VIA_NODE);
     148        } else {
     149            // check if consecutive ways are connected: from/via[0], via[i-1]/via[i], via[last]/to
     150            checkIfConnected(fromWay, (Way) via.get(0),
     151                    tr("The \"from\" and the first \"via\" way are not connected."), FROM_VIA_WAY);
     152            if (via.size() > 1) {
     153                for (int i = 1; i < via.size(); i++) {
     154                    Way previous = (Way) via.get(i - 1);
     155                    Way current = (Way) via.get(i);
     156                    checkIfConnected(previous, current,
     157                            tr("The \"via\" ways are not connected."), UNCONNECTED_VIA);
     158                }
    134159            }
    135             if (!toWay.isFirstLastNode(viaNode)) {
    136                 errors.add(new TestError(this, Severity.ERROR,
    137                         tr("The \"to\" way does not start or end at a \"via\" node"), TO_VIA_NODE, r));
    138                 return;
     160            checkIfConnected((Way) via.get(via.size() - 1), toWay,
     161                    tr("The last \"via\" and the \"to\" way are not connected."), TO_VIA_WAY);
     162
     163        }
     164    }
     165
     166    private void checkIfConnected(Way previous, Way current, String msg, int code) {
     167        int onewayPrevious = isOneway(previous);
     168        int onewayCurrent = isOneway(current);
     169        Node endPrevious = onewayPrevious != -1 ? previous.lastNode() : previous.firstNode();
     170        Node startCurrent = onewayCurrent != -1 ? current.firstNode() : current.lastNode();
     171        //System.out.println(previous.getUniqueId() + " -- " + current.getUniqueId() + ": " + onewayPrevious + "/" + onewayCurrent + " " + endPrevious.getUniqueId() + "/" + startCurrent.getUniqueId());
     172        boolean c;
     173        if (onewayPrevious != 0 && onewayCurrent != 0) {
     174            // both oneways: end/start node must be equal
     175            c = endPrevious.equals(startCurrent);
     176        } else if (onewayPrevious != 0) {
     177            // previous way is oneway: end of previous must be start/end of current
     178            c = current.isFirstLastNode(endPrevious);
     179        } else if (onewayCurrent != 0) {
     180            // current way is oneway: start of current must be start/end of previous
     181            c = previous.isFirstLastNode(startCurrent);
     182        } else {
     183            // otherwise: start/end of previous must be start/end of current
     184            c = current.isFirstLastNode(previous.firstNode()) || current.isFirstLastNode(previous.lastNode());
     185        }
     186        if (!c) {
     187            errors.add(new TestError(this, Severity.ERROR, msg, code, Arrays.asList(previous, current)));
     188        }
     189    }
     190
     191    private static int isOneway(Way w) {
     192        String onewayviastr = w.get("oneway");
     193        if (onewayviastr != null) {
     194            if ("-1".equals(onewayviastr)) {
     195                return -1;
     196            } else {
     197                Boolean onewayvia = OsmUtils.getOsmBoolean(onewayviastr);
     198                if (onewayvia != null && onewayvia) {
     199                    return 1;
     200                }
    139201            }
    140         } else {
    141             Way viaWay = (Way) via;
    142             Node firstNode = viaWay.firstNode();
    143             Node lastNode = viaWay.lastNode();
    144             Boolean onewayvia = false;
    145 
    146             String onewayviastr = viaWay.get("oneway");
    147             if (onewayviastr != null) {
    148                 if ("-1".equals(onewayviastr)) {
    149                     onewayvia = true;
    150                     Node tmp = firstNode;
    151                     firstNode = lastNode;
    152                     lastNode = tmp;
    153                 } else {
    154                     onewayvia = OsmUtils.getOsmBoolean(onewayviastr);
    155                     if (onewayvia == null) {
    156                         onewayvia = false;
    157                     }
    158                 }
    159             }
    160 
    161             if (fromWay.isFirstLastNode(firstNode)) {
    162                 viaNode = firstNode;
    163             } else if (!onewayvia && fromWay.isFirstLastNode(lastNode)) {
    164                 viaNode = lastNode;
    165             } else {
    166                 errors.add(new TestError(this, Severity.ERROR,
    167                         tr("The \"from\" way does not start or end at a \"via\" way."), FROM_VIA_WAY, r));
    168                 return;
    169             }
    170             if (!toWay.isFirstLastNode(viaNode == firstNode ? lastNode : firstNode)) {
    171                 errors.add(new TestError(this, Severity.ERROR,
    172                         tr("The \"to\" way does not start or end at a \"via\" way."), TO_VIA_WAY, r));
    173             }
    174         }
     202        }
     203        return 0;
    175204    }
    176205}
Note: See TracChangeset for help on using the changeset viewer.