Fix turn lanes #2935
This commit is contained in:
parent
71fb0f8df5
commit
4112681f00
3 changed files with 78 additions and 20 deletions
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.router;
|
package net.osmand.router;
|
||||||
|
|
||||||
|
import gnu.trove.iterator.TIntIterator;
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
import gnu.trove.set.hash.TIntHashSet;
|
import gnu.trove.set.hash.TIntHashSet;
|
||||||
|
|
||||||
|
@ -947,28 +948,29 @@ public class RouteResultPreparation {
|
||||||
rawLanes[k] |= 1;
|
rawLanes[k] |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int tp = inferTurnFromLanes(rawLanes);
|
int tp = inferSlightTurnFromLanes(rawLanes, rs);
|
||||||
if (tp != t.getValue() && tp != 0) {
|
if (tp != t.getValue() && tp != 0) {
|
||||||
t = TurnType.valueOf(tp, leftSide);
|
t = TurnType.valueOf(tp, leftSide);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
boolean possiblyLeftTurn = rs.roadsOnLeft == 0;
|
||||||
|
boolean possiblyRightTurn = rs.roadsOnRight == 0;
|
||||||
for (int k = 0; k < rawLanes.length; k++) {
|
for (int k = 0; k < rawLanes.length; k++) {
|
||||||
int turn = TurnType.getPrimaryTurn(rawLanes[k]);
|
int turn = TurnType.getPrimaryTurn(rawLanes[k]);
|
||||||
int sturn = TurnType.getSecondaryTurn(rawLanes[k]);
|
int sturn = TurnType.getSecondaryTurn(rawLanes[k]);
|
||||||
boolean active = false;
|
boolean active = false;
|
||||||
if (turn == TurnType.C) {
|
// some turns go through many segments (to turn right or left)
|
||||||
if ((TurnType.isRightTurn(sturn) && rs.roadsOnRight == 0)
|
// so on one first segment the lane could be available and may be only 1 possible
|
||||||
|| (TurnType.isLeftTurn(sturn) && rs.roadsOnLeft == 0)) {
|
// all undesired lanes will be disabled through the 2nd pass
|
||||||
TurnType.setPrimaryTurn(rawLanes, k, sturn);
|
if((TurnType.isRightTurn(sturn) && possiblyRightTurn) ||
|
||||||
TurnType.setSecondaryTurn(rawLanes, k, turn);
|
(TurnType.isLeftTurn(sturn) && possiblyLeftTurn)) {
|
||||||
}
|
TurnType.setPrimaryTurn(rawLanes, k, sturn);
|
||||||
|
TurnType.setSecondaryTurn(rawLanes, k, turn);
|
||||||
active = true;
|
active = true;
|
||||||
} else if (TurnType.isRightTurn(turn) && rs.roadsOnRight == 0) {
|
} else if((TurnType.isRightTurn(turn) && possiblyRightTurn) ||
|
||||||
// some turns go through many segments (to turn right or left)
|
(TurnType.isLeftTurn(turn) && possiblyLeftTurn)) {
|
||||||
// so on one first segment the lane could be available and may be only 1 possible
|
|
||||||
// all undesired lanes will be disabled through the 2nd pass
|
|
||||||
active = true;
|
active = true;
|
||||||
} else if (TurnType.isLeftTurn(turn) && rs.roadsOnLeft == 0) {
|
} else if (turn == TurnType.C) {
|
||||||
active = true;
|
active = true;
|
||||||
}
|
}
|
||||||
if (active) {
|
if (active) {
|
||||||
|
@ -1266,7 +1268,7 @@ public class RouteResultPreparation {
|
||||||
return lanes;
|
return lanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int inferTurnFromLanes(int[] oLanes) {
|
private int inferSlightTurnFromLanes(int[] oLanes, RoadSplitStructure rs) {
|
||||||
TIntHashSet possibleTurns = new TIntHashSet();
|
TIntHashSet possibleTurns = new TIntHashSet();
|
||||||
for (int i = 0; i < oLanes.length; i++) {
|
for (int i = 0; i < oLanes.length; i++) {
|
||||||
if ((oLanes[i] & 1) == 0) {
|
if ((oLanes[i] & 1) == 0) {
|
||||||
|
@ -1310,10 +1312,40 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// remove all non-slight turns
|
||||||
|
if(possibleTurns.size() > 1) {
|
||||||
|
TIntIterator it = possibleTurns.iterator();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
int nxt = it.next();
|
||||||
|
if(!TurnType.isSlightTurn(nxt)) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int infer = 0;
|
||||||
|
if (possibleTurns.size() == 1) {
|
||||||
|
infer = possibleTurns.iterator().next();
|
||||||
|
} else if (possibleTurns.size() > 1) {
|
||||||
|
if (rs.keepLeft && rs.keepRight && possibleTurns.contains(TurnType.C)) {
|
||||||
|
infer = TurnType.C;
|
||||||
|
} else if (rs.keepLeft || rs.keepRight) {
|
||||||
|
TIntIterator it = possibleTurns.iterator();
|
||||||
|
infer = it.next();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
int next = it.next();
|
||||||
|
int orderInfer = TurnType.orderFromLeftToRight(infer);
|
||||||
|
int orderNext = TurnType.orderFromLeftToRight(next) ;
|
||||||
|
if(rs.keepLeft && orderNext < orderInfer) {
|
||||||
|
infer = next;
|
||||||
|
} else if(rs.keepRight && orderNext > orderInfer) {
|
||||||
|
infer = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Checking to see that there is only one unique turn
|
// Checking to see that there is only one unique turn
|
||||||
if (possibleTurns.size() == 1) {
|
if (infer != 0) {
|
||||||
int infer = possibleTurns.iterator().next();
|
|
||||||
for(int i = 0; i < oLanes.length; i++) {
|
for(int i = 0; i < oLanes.length; i++) {
|
||||||
if(TurnType.getSecondaryTurn(oLanes[i]) == infer) {
|
if(TurnType.getSecondaryTurn(oLanes[i]) == infer) {
|
||||||
int pt = TurnType.getPrimaryTurn(oLanes[i]);
|
int pt = TurnType.getPrimaryTurn(oLanes[i]);
|
||||||
|
@ -1324,10 +1356,8 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return infer;
|
|
||||||
}
|
}
|
||||||
|
return infer;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMotorway(RouteSegmentResult s){
|
private boolean isMotorway(RouteSegmentResult s){
|
||||||
|
|
|
@ -334,6 +334,34 @@ public class TurnType {
|
||||||
set.add(pt);
|
set.add(pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int orderFromLeftToRight(int type) {
|
||||||
|
switch(type) {
|
||||||
|
case TU:
|
||||||
|
return -5;
|
||||||
|
case TSHL:
|
||||||
|
return -4;
|
||||||
|
case TL:
|
||||||
|
return -3;
|
||||||
|
case TSLL:
|
||||||
|
return -2;
|
||||||
|
case KL:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case TRU:
|
||||||
|
return 5;
|
||||||
|
case TSHR:
|
||||||
|
return 4;
|
||||||
|
case TR:
|
||||||
|
return 3;
|
||||||
|
case TSLR:
|
||||||
|
return 2;
|
||||||
|
case KR:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,7 +508,7 @@
|
||||||
"longitude": 35.54365276535992
|
"longitude": 35.54365276535992
|
||||||
},
|
},
|
||||||
"expectedResults": {
|
"expectedResults": {
|
||||||
"118669516": "+TSLL, С"
|
"118669516": "TSLL:+TSLL,С"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -522,7 +522,7 @@
|
||||||
"longitude": 35.53820788105969
|
"longitude": 35.53820788105969
|
||||||
},
|
},
|
||||||
"expectedResults": {
|
"expectedResults": {
|
||||||
"118669511": "+TSLR, С"
|
"118669511": "TSLR:+TSLR,С"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue