Ticket #5861: 5861_v2.patch
| File 5861_v2.patch, 9.5 KB (added by , 15 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/TurnrestrictionTest.java
4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.util.ArrayList; 7 import java.util.Arrays; 7 8 import java.util.Collections; 9 import java.util.List; 8 10 9 11 import org.openstreetmap.josm.data.osm.Node; 10 12 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 30 32 protected static final int TO_VIA_NODE = 1810; 31 33 protected static final int FROM_VIA_WAY = 1811; 32 34 protected static final int TO_VIA_WAY = 1812; 35 protected static final int MIX_VIA = 1813; 36 protected static final int UNCONNECTED_VIA = 1814; 33 37 34 38 public TurnrestrictionTest() { 35 39 super(tr("Turnrestriction"), tr("This test checks if turnrestrictions are valid")); … … 42 46 43 47 Way fromWay = null; 44 48 Way toWay = null; 45 OsmPrimitive via = null;49 List<OsmPrimitive> via = new ArrayList<OsmPrimitive>(); 46 50 47 51 boolean morefrom = false; 48 52 boolean moreto = false; 49 53 boolean morevia = false; 54 boolean mixvia = false; 50 55 51 56 /* find the "from", "via" and "to" elements */ 52 57 for (RelationMember m : r.getMembers()) { … … 75 80 toWay = w; 76 81 } 77 82 } else if ("via".equals(m.getRole())) { 78 if ( via != null) {79 m orevia = true;83 if (!via.isEmpty() && via.get(0) instanceof Node) { 84 mixvia = true; 80 85 } else { 81 via = w;86 via.add(w); 82 87 } 83 88 } else { 84 89 errors.add(new TestError(this, Severity.WARNING, tr("Unknown role"), UNKNOWN_ROLE, … … 87 92 } else if (m.isNode()) { 88 93 Node n = m.getNode(); 89 94 if ("via".equals(m.getRole())) { 90 if (via != null) { 91 morevia = true; 95 if (!via.isEmpty()) { 96 if (via.get(0) instanceof Node) { 97 morevia = true; 98 } else { 99 mixvia = true; 100 } 92 101 } else { 93 via = n;102 via.add(n); 94 103 } 95 104 } else { 96 105 errors.add(new TestError(this, Severity.WARNING, tr("Unknown role"), UNKNOWN_ROLE, … … 108 117 errors.add(new TestError(this, Severity.ERROR, tr("More than one \"to\" way found"), MORE_TO, r)); 109 118 } 110 119 if (morevia) { 111 errors.add(new TestError(this, Severity.ERROR, tr("More than one \"via\" wayfound"), MORE_VIA, r));120 errors.add(new TestError(this, Severity.ERROR, tr("More than one \"via\" node found"), MORE_VIA, r)); 112 121 } 122 if (mixvia) { 123 errors.add(new TestError(this, Severity.ERROR, tr("Cannot mix node and way for role \"via\""), MIX_VIA, r)); 124 } 113 125 114 126 if (fromWay == null) { 115 127 errors.add(new TestError(this, Severity.ERROR, tr("No \"from\" way found"), NO_FROM, r)); … … 119 131 errors.add(new TestError(this, Severity.ERROR, tr("No \"to\" way found"), NO_TO, r)); 120 132 return; 121 133 } 122 if (via == null) {134 if (via.isEmpty()) { 123 135 errors.add(new TestError(this, Severity.ERROR, tr("No \"via\" node or way found"), NO_VIA, r)); 124 136 return; 125 137 } 126 138 127 139 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; 134 } 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; 139 } 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); 140 148 } 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 } 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 158 } 159 159 } 160 checkIfConnected((Way) via.get(via.size() - 1), toWay, 161 tr("The last \"via\" and the \"to\" way are not connected."), TO_VIA_WAY); 160 162 161 if (fromWay.isFirstLastNode(firstNode)) { 162 viaNode = firstNode; 163 } else if (!onewayvia && fromWay.isFirstLastNode(lastNode)) { 164 viaNode = lastNode; 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; 165 196 } 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; 197 Boolean onewayvia = OsmUtils.getOsmBoolean(onewayviastr); 198 if (onewayvia != null && onewayvia) { 199 return 1; 200 } 169 201 } 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; 175 204 } 176 205 } -
data/defaultpresets.xml
4138 4138 </optional> 4139 4139 <roles> 4140 4140 <role key="from" text="from way" requisite="required" count="1" type="way" /> 4141 <role key="via" text="via node or way " requisite="required" count="1" type="way,node" />4141 <role key="via" text="via node or ways" requisite="required" type="way,node" /> 4142 4142 <role key="to" text="to way" requisite="required" count="1" type="way" /> 4143 4143 </roles> 4144 4144 </item>
