Update routes
This commit is contained in:
parent
e0a8cc36f9
commit
1756e39616
3 changed files with 344 additions and 309 deletions
|
@ -60,8 +60,8 @@ public class BinaryInspector {
|
||||||
// test cases show info
|
// test cases show info
|
||||||
if(args.length == 1 && "test".equals(args[0])) {
|
if(args.length == 1 && "test".equals(args[0])) {
|
||||||
in.inspector(new String[]{
|
in.inspector(new String[]{
|
||||||
// "-vpoi",
|
"-vpoi",
|
||||||
"-vmap", "-vmapobjects",
|
// "-vmap", "-vmapobjects",
|
||||||
// "-vrouting",
|
// "-vrouting",
|
||||||
// "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings",
|
// "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings",
|
||||||
// "-zoom=16",
|
// "-zoom=16",
|
||||||
|
|
|
@ -40,15 +40,35 @@ public class RouteResultPreparation {
|
||||||
List<RouteSegmentResult> prepareResult(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
|
List<RouteSegmentResult> prepareResult(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
|
||||||
validateAllPointsConnected(result);
|
validateAllPointsConnected(result);
|
||||||
splitRoadsAndAttachRoadSegments(ctx, result);
|
splitRoadsAndAttachRoadSegments(ctx, result);
|
||||||
// calculate time
|
|
||||||
calculateTimeSpeed(ctx, result);
|
calculateTimeSpeed(ctx, result);
|
||||||
|
|
||||||
addTurnInfo(ctx.leftSideNavigation, result);
|
for (int i = 0; i < result.size(); i ++) {
|
||||||
|
TurnType turnType = getTurnInfo(result, i, ctx.leftSideNavigation);
|
||||||
|
result.get(i).setTurnType(turnType);
|
||||||
|
}
|
||||||
|
|
||||||
determineTurnsToMerge(ctx.leftSideNavigation, result);
|
determineTurnsToMerge(ctx.leftSideNavigation, result);
|
||||||
|
justifyUTurns(ctx.leftSideNavigation, result);
|
||||||
addTurnInfoDescriptions(result);
|
addTurnInfoDescriptions(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void justifyUTurns(boolean leftSide, List<RouteSegmentResult> result) {
|
||||||
|
int next;
|
||||||
|
for (int i = 0; i < result.size() - 1; i = next) {
|
||||||
|
next = i + 1;
|
||||||
|
TurnType t = result.get(i).getTurnType();
|
||||||
|
// justify turn
|
||||||
|
if (t != null) {
|
||||||
|
TurnType jt = justifyUTurn(leftSide, result, i, t);
|
||||||
|
if (jt != null) {
|
||||||
|
result.get(i).setTurnType(jt);
|
||||||
|
next = i + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void calculateTimeSpeed(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
|
private void calculateTimeSpeed(RoutingContext ctx, List<RouteSegmentResult> result) throws IOException {
|
||||||
for (int i = 0; i < result.size(); i++) {
|
for (int i = 0; i < result.size(); i++) {
|
||||||
RouteSegmentResult rr = result.get(i);
|
RouteSegmentResult rr = result.get(i);
|
||||||
|
@ -332,26 +352,6 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addTurnInfo(boolean leftside, List<RouteSegmentResult> result) {
|
|
||||||
int next = 1;
|
|
||||||
for (int i = 0; i <= result.size(); i = next) {
|
|
||||||
TurnType t = null;
|
|
||||||
next = i + 1;
|
|
||||||
if (i < result.size()) {
|
|
||||||
t = getTurnInfo(result, i, leftside);
|
|
||||||
// justify turn
|
|
||||||
if(t != null && i < result.size() - 1) {
|
|
||||||
TurnType jt = justifyUTurn(leftside, result, i, t);
|
|
||||||
if(jt != null) {
|
|
||||||
t = jt;
|
|
||||||
next = i + 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.get(i).setTurnType(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addTurnInfoDescriptions(List<RouteSegmentResult> result) {
|
protected void addTurnInfoDescriptions(List<RouteSegmentResult> result) {
|
||||||
int prevSegment = -1;
|
int prevSegment = -1;
|
||||||
float dist = 0;
|
float dist = 0;
|
||||||
|
@ -359,8 +359,29 @@ public class RouteResultPreparation {
|
||||||
if (i == result.size() || result.get(i).getTurnType() != null) {
|
if (i == result.size() || result.get(i).getTurnType() != null) {
|
||||||
if (prevSegment >= 0) {
|
if (prevSegment >= 0) {
|
||||||
String turn = result.get(prevSegment).getTurnType().toString();
|
String turn = result.get(prevSegment).getTurnType().toString();
|
||||||
if (result.get(prevSegment).getTurnType().getLanes() != null) {
|
final int[] lns = result.get(prevSegment).getTurnType().getLanes();
|
||||||
turn += Arrays.toString(result.get(prevSegment).getTurnType().getLanes());
|
if (lns != null) {
|
||||||
|
String s = "[ ";
|
||||||
|
for (int h = 0; h < lns.length; h++) {
|
||||||
|
if (h > 0) {
|
||||||
|
s += ", ";
|
||||||
|
}
|
||||||
|
if (lns[h] % 2 == 1) {
|
||||||
|
s += "+";
|
||||||
|
}
|
||||||
|
int pt = TurnType.getPrimaryTurn(lns[h]);
|
||||||
|
if (pt == 0) {
|
||||||
|
pt = 1;
|
||||||
|
}
|
||||||
|
s += TurnType.valueOf(pt, false).toXmlString();
|
||||||
|
int st = TurnType.getSecondaryTurn(lns[h]);
|
||||||
|
if (st != 0) {
|
||||||
|
s += ";" + TurnType.valueOf(st, false).toXmlString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
s += "]";
|
||||||
|
turn += s;
|
||||||
}
|
}
|
||||||
result.get(prevSegment).setDescription(
|
result.get(prevSegment).setDescription(
|
||||||
turn + MessageFormat.format(" and go {0,number,#.##} meters", dist));
|
turn + MessageFormat.format(" and go {0,number,#.##} meters", dist));
|
||||||
|
@ -381,7 +402,7 @@ public class RouteResultPreparation {
|
||||||
boolean tl = TurnType.TL == t.getValue();
|
boolean tl = TurnType.TL == t.getValue();
|
||||||
boolean tr = TurnType.TR == t.getValue();
|
boolean tr = TurnType.TR == t.getValue();
|
||||||
if(tl || tr) {
|
if(tl || tr) {
|
||||||
TurnType tnext = getTurnInfo(result, i + 1, leftside);
|
TurnType tnext = result.get(i + 1).getTurnType();
|
||||||
if (tnext != null && result.get(i).getDistance() < 35) { //
|
if (tnext != null && result.get(i).getDistance() < 35) { //
|
||||||
boolean ut = true;
|
boolean ut = true;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
@ -397,6 +418,7 @@ public class RouteResultPreparation {
|
||||||
ut = false;
|
ut = false;
|
||||||
}
|
}
|
||||||
if (ut) {
|
if (ut) {
|
||||||
|
tnext.setSkipToSpeak(true);
|
||||||
if (tl && TurnType.TL == tnext.getValue()) {
|
if (tl && TurnType.TL == tnext.getValue()) {
|
||||||
return TurnType.valueOf(TurnType.TU, false);
|
return TurnType.valueOf(TurnType.TU, false);
|
||||||
} else if (tr && TurnType.TR == tnext.getValue()) {
|
} else if (tr && TurnType.TR == tnext.getValue()) {
|
||||||
|
@ -409,108 +431,97 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void determineTurnsToMerge(boolean leftside, List<RouteSegmentResult> result) {
|
private void determineTurnsToMerge(boolean leftside, List<RouteSegmentResult> result) {
|
||||||
for (int i = result.size() - 2; i >= 0; i--) {
|
|
||||||
RouteSegmentResult currentSegment = result.get(i);
|
|
||||||
RouteSegmentResult nextSegment = null;
|
RouteSegmentResult nextSegment = null;
|
||||||
|
double dist = 0;
|
||||||
// We need to get the next segment that has a turn and lanes attached.
|
for (int i = result.size() - 1; i >= 0; i--) {
|
||||||
for (int j = i + 1; j < result.size(); j++) {
|
RouteSegmentResult currentSegment = result.get(i);
|
||||||
RouteSegmentResult possibleSegment = result.get(j);
|
|
||||||
if (possibleSegment.getTurnType() != null && possibleSegment.getTurnType().getLanes() != null) {
|
|
||||||
nextSegment = possibleSegment;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextSegment == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TurnType currentTurn = currentSegment.getTurnType();
|
TurnType currentTurn = currentSegment.getTurnType();
|
||||||
TurnType nextTurn = nextSegment.getTurnType();
|
dist += currentSegment.getDistance();
|
||||||
|
if (currentTurn == null || currentTurn.getLanes() == null) {
|
||||||
if (currentTurn == null || currentTurn.getLanes() == null || nextTurn == null || nextTurn.getLanes() == null) {
|
// skip
|
||||||
continue;
|
} else {
|
||||||
}
|
if (nextSegment != null) {
|
||||||
|
|
||||||
// Only allow slight turns that are nearby to be merged.
|
|
||||||
// [disabled cause it is valuable for two consequent sharp turns as well]
|
|
||||||
// the distance could be longer on highways and shorter in city
|
|
||||||
String hw = currentSegment.getObject().getHighway();
|
String hw = currentSegment.getObject().getHighway();
|
||||||
double mergeDistance = 200;
|
double mergeDistance = 200;
|
||||||
if (hw != null && (hw.startsWith("trunk") || hw.startsWith("motorway"))) {
|
if (hw != null && (hw.startsWith("trunk") || hw.startsWith("motorway"))) {
|
||||||
mergeDistance = 400;
|
mergeDistance = 400;
|
||||||
}
|
}
|
||||||
if (currentSegment.getDistance() < mergeDistance/*
|
if (dist < mergeDistance) {
|
||||||
&& TurnType.isSlightTurn(currentTurn.getValue())*/) {
|
|
||||||
mergeTurnLanes(leftside, currentSegment, nextSegment);
|
mergeTurnLanes(leftside, currentSegment, nextSegment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nextSegment = currentSegment;
|
||||||
|
dist = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergeTurnLanes(boolean leftSide, RouteSegmentResult currentSegment, RouteSegmentResult nextSegment) {
|
private class MergeTurnLaneTurn {
|
||||||
TurnType currentTurn = currentSegment.getTurnType();
|
TurnType turn;
|
||||||
TurnType nextTurn = nextSegment.getTurnType();
|
int[] originalLanes;
|
||||||
boolean isUsingTurnLanes = TurnType.getPrimaryTurn(currentTurn.getLanes()[0]) != 0
|
int[] disabledLanes;
|
||||||
&& TurnType.getPrimaryTurn(nextTurn.getLanes()[0]) != 0;
|
int activeStartIndex = -1;
|
||||||
if (isUsingTurnLanes) {
|
int activeEndIndex = -1;
|
||||||
int[] lanes = new int[currentTurn.getLanes().length];
|
|
||||||
int activeIndex = -1;
|
|
||||||
int activeLen = 0;
|
int activeLen = 0;
|
||||||
// define enabled lanes
|
|
||||||
for(int i = 0; i < lanes.length; i++) {
|
public MergeTurnLaneTurn(RouteSegmentResult segment) {
|
||||||
int ln = currentTurn.getLanes()[i];
|
this.turn = segment.getTurnType();
|
||||||
lanes[i] = ln & ~1;
|
if(turn != null) {
|
||||||
|
originalLanes = turn.getLanes();
|
||||||
|
}
|
||||||
|
if(originalLanes != null) {
|
||||||
|
disabledLanes = new int[originalLanes.length];
|
||||||
|
for (int i = 0; i < originalLanes.length; i++) {
|
||||||
|
int ln = originalLanes[i];
|
||||||
|
disabledLanes[i] = ln & ~1;
|
||||||
if ((ln & 1) > 0) {
|
if ((ln & 1) > 0) {
|
||||||
if(activeIndex == -1) {
|
if (activeStartIndex == -1) {
|
||||||
activeIndex = i;
|
activeStartIndex = i;
|
||||||
activeLen++;
|
}
|
||||||
} else {
|
activeEndIndex = i;
|
||||||
activeLen++;
|
activeLen++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(activeLen < 2) {
|
}
|
||||||
|
|
||||||
|
public boolean isActiveTurnMostLeft() {
|
||||||
|
return activeStartIndex == 0;
|
||||||
|
}
|
||||||
|
public boolean isActiveTurnMostRight() {
|
||||||
|
return activeEndIndex == originalLanes.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeTurnLanes(boolean leftSide, RouteSegmentResult currentSegment, RouteSegmentResult nextSegment) {
|
||||||
|
MergeTurnLaneTurn active = new MergeTurnLaneTurn(currentSegment);
|
||||||
|
MergeTurnLaneTurn target = new MergeTurnLaneTurn(nextSegment);
|
||||||
|
if (active.activeLen < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int targetActiveIndex = -1;
|
if (target.activeStartIndex == -1) {
|
||||||
int targetActiveLen = 0;
|
|
||||||
int[] nextLanes = nextTurn.getLanes();
|
|
||||||
for(int i = 0; i < nextLanes.length; i++) {
|
|
||||||
int ln = nextLanes[i];
|
|
||||||
if((ln & 1) > 0) {
|
|
||||||
if(targetActiveIndex == -1) {
|
|
||||||
targetActiveIndex = i;
|
|
||||||
targetActiveLen++;
|
|
||||||
} else {
|
|
||||||
targetActiveLen++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(targetActiveIndex == -1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
// next turn is left
|
if (target.isActiveTurnMostLeft()) {
|
||||||
if(targetActiveIndex == 0) {
|
|
||||||
// let only the most left lanes be enabled
|
// let only the most left lanes be enabled
|
||||||
if(targetActiveLen <= activeLen) {
|
if (target.activeLen <= active.activeLen) {
|
||||||
activeLen = targetActiveLen;
|
active.activeEndIndex -= (active.activeLen - target.activeLen);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} else if(targetActiveIndex + targetActiveLen == nextLanes.length) {
|
} else if (target.isActiveTurnMostRight()) {
|
||||||
// next turn is right
|
// next turn is right
|
||||||
// let only the most right lanes be enabled
|
// let only the most right lanes be enabled
|
||||||
if(targetActiveLen <= activeLen) {
|
if (target.activeLen < active.activeLen) {
|
||||||
activeIndex += (activeLen - targetActiveLen);
|
active.activeStartIndex += (active.activeLen - target.activeLen);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// next turn is get through (take out the left and the right turn)
|
// next turn is get through (take out the left and the right turn)
|
||||||
if(nextLanes.length >= activeLen) {
|
if (target.originalLanes.length >= active.activeLen) {
|
||||||
float ratio = (nextLanes.length / (float)activeLen);
|
float ratio = (target.originalLanes.length / (float) active.activeLen);
|
||||||
activeLen = (int) Math.ceil(targetActiveLen * ratio);
|
active.activeEndIndex = (int) Math.ceil(target.activeEndIndex * ratio);
|
||||||
activeIndex = (int) Math.floor(targetActiveIndex / ratio);
|
active.activeStartIndex = (int) Math.floor(target.activeStartIndex / ratio);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,23 +529,22 @@ public class RouteResultPreparation {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// set the allowed lane bit
|
// set the allowed lane bit
|
||||||
for (int i = 0; i < lanes.length; i++) {
|
for (int i = 0; i < active.disabledLanes.length; i++) {
|
||||||
if(i >= activeIndex && i < activeIndex + activeLen) {
|
if (i >= active.activeStartIndex && i <= active.activeEndIndex) {
|
||||||
lanes[i] |= 1;
|
active.disabledLanes[i] |= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentTurn.setLanes(lanes);
|
TurnType currentTurn = currentSegment.getTurnType();
|
||||||
int turn = inferTurnFromLanes(lanes);
|
currentTurn.setLanes(active.disabledLanes);
|
||||||
|
int turn = inferTurnFromLanes(active.disabledLanes);
|
||||||
if (turn != 0 && turn != currentTurn.getValue()) {
|
if (turn != 0 && turn != currentTurn.getValue()) {
|
||||||
TurnType newTurnType = TurnType.valueOf(turn, leftSide);
|
TurnType newTurnType = TurnType.valueOf(turn, leftSide);
|
||||||
newTurnType.setLanes(lanes);
|
newTurnType.setLanes(active.disabledLanes);
|
||||||
newTurnType.setSkipToSpeak(currentTurn.isSkipToSpeak());
|
newTurnType.setSkipToSpeak(currentTurn.isSkipToSpeak());
|
||||||
currentSegment.setTurnType(newTurnType);
|
currentSegment.setTurnType(newTurnType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static final int MAX_SPEAK_PRIORITY = 5;
|
private static final int MAX_SPEAK_PRIORITY = 5;
|
||||||
private int highwaySpeakPriority(String highway) {
|
private int highwaySpeakPriority(String highway) {
|
||||||
|
@ -585,10 +595,8 @@ public class RouteResultPreparation {
|
||||||
} else {
|
} else {
|
||||||
t = TurnType.valueOf(TurnType.TU, leftSide);
|
t = TurnType.valueOf(TurnType.TU, leftSide);
|
||||||
}
|
}
|
||||||
int[] lanes = getTurnLanesInfo(prev, t.getValue(), leftSide, true);
|
int[] lanes = getTurnLanesInfo(prev, t.getValue());
|
||||||
if(lanes != null) {
|
|
||||||
t.setLanes(lanes);
|
t.setLanes(lanes);
|
||||||
}
|
|
||||||
} else if (mpi < -TURN_DEGREE_MIN) {
|
} else if (mpi < -TURN_DEGREE_MIN) {
|
||||||
if (mpi > -60) {
|
if (mpi > -60) {
|
||||||
t = TurnType.valueOf(TurnType.TSLR, leftSide);
|
t = TurnType.valueOf(TurnType.TSLR, leftSide);
|
||||||
|
@ -597,14 +605,12 @@ public class RouteResultPreparation {
|
||||||
} else if (mpi > -135 || !leftSide) {
|
} else if (mpi > -135 || !leftSide) {
|
||||||
t = TurnType.valueOf(TurnType.TSHR, leftSide);
|
t = TurnType.valueOf(TurnType.TSHR, leftSide);
|
||||||
} else {
|
} else {
|
||||||
t = TurnType.valueOf(TurnType.TU, leftSide);
|
t = TurnType.valueOf(TurnType.TRU, leftSide);
|
||||||
}
|
}
|
||||||
int[] lanes = getTurnLanesInfo(prev, t.getValue(), leftSide, false);
|
int[] lanes = getTurnLanesInfo(prev, t.getValue());
|
||||||
if(lanes != null) {
|
|
||||||
t.setLanes(lanes);
|
t.setLanes(lanes);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr, t);
|
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr);
|
||||||
}
|
}
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
t.setTurnAngle((float) -mpi);
|
t.setTurnAngle((float) -mpi);
|
||||||
|
@ -613,39 +619,34 @@ public class RouteResultPreparation {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] getTurnLanesInfo(RouteSegmentResult prevSegm, int mainTurnType, boolean leftSide,
|
private int[] getTurnLanesInfo(RouteSegmentResult prevSegm, int mainTurnType) {
|
||||||
boolean leftTurn) {
|
|
||||||
String turnLanes = getTurnLanesString(prevSegm);
|
String turnLanes = getTurnLanesString(prevSegm);
|
||||||
if (turnLanes == null) {
|
if (turnLanes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
int[] lanesArray = calculateRawTurnLanes(turnLanes, mainTurnType);
|
||||||
if (splitLaneOptions.length != countLanesMinOne(prevSegm)) {
|
|
||||||
// Error in data or missing data
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int[] lanesArray = calculateRawTurnLanes(splitLaneOptions, mainTurnType);
|
|
||||||
// Manually set the allowed lanes.
|
// Manually set the allowed lanes.
|
||||||
boolean isSet = setAllowedLanes(mainTurnType, lanesArray);
|
boolean isSet = setAllowedLanes(mainTurnType, lanesArray);
|
||||||
if(!isSet && lanesArray.length > 0) {
|
if(!isSet && lanesArray.length > 0) {
|
||||||
// In some cases (at least in the US), the rightmost lane might not have a right turn indicated as per turn:lanes,
|
// In some cases (at least in the US), the rightmost lane might not have a right turn indicated as per turn:lanes,
|
||||||
// but is allowed and being used here. This section adds in that indicator. The same applies for where leftSide is true.
|
// but is allowed and being used here. This section adds in that indicator. The same applies for where leftSide is true.
|
||||||
|
boolean leftTurn = TurnType.isLeftTurn(mainTurnType);
|
||||||
int ind = leftTurn? 0 : lanesArray.length - 1;
|
int ind = leftTurn? 0 : lanesArray.length - 1;
|
||||||
final int tt = TurnType.getPrimaryTurn(lanesArray[ind]);
|
final int tt = TurnType.getPrimaryTurn(lanesArray[ind]);
|
||||||
if (leftTurn) {
|
if (leftTurn) {
|
||||||
if (!TurnType.isLeftTurn(tt)) {
|
if (!TurnType.isLeftTurn(tt)) {
|
||||||
// This was just to make sure that there's no bad data.
|
// This was just to make sure that there's no bad data.
|
||||||
|
TurnType.setPrimaryTurnAndReset(lanesArray, ind, TurnType.TL);
|
||||||
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
||||||
TurnType.setPrimaryTurn(lanesArray, ind, TurnType.TL);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!TurnType.isRightTurn(tt)) {
|
if (!TurnType.isRightTurn(tt)) {
|
||||||
// This was just to make sure that there's no bad data.
|
// This was just to make sure that there's no bad data.
|
||||||
|
TurnType.setPrimaryTurnAndReset(lanesArray, ind, TurnType.TR);
|
||||||
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
||||||
TurnType.setPrimaryTurn(lanesArray, ind, TurnType.TR);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setAllowedLanes(lanesArray[ind], lanesArray);
|
setAllowedLanes(tt, lanesArray);
|
||||||
}
|
}
|
||||||
return lanesArray;
|
return lanesArray;
|
||||||
}
|
}
|
||||||
|
@ -692,113 +693,189 @@ public class RouteResultPreparation {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RoadSplitStructure {
|
||||||
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm, TurnType t) {
|
boolean keepLeft = false;
|
||||||
// keep left/right
|
boolean keepRight = false;
|
||||||
boolean kl = false;
|
|
||||||
boolean kr = false;
|
|
||||||
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
|
|
||||||
int ls = prevSegm.getObject().getLanes();
|
|
||||||
if(ls >= 0 && prevSegm.getObject().getOneway() == 0) {
|
|
||||||
ls = (ls + 1) / 2;
|
|
||||||
}
|
|
||||||
int left = 0;
|
|
||||||
int right = 0;
|
|
||||||
boolean speak = false;
|
boolean speak = false;
|
||||||
|
int leftLanes = 0;
|
||||||
|
int rightLanes = 0;
|
||||||
|
int roadsOnLeft = 0;
|
||||||
|
int addRoadsOnLeft = 0;
|
||||||
|
int roadsOnRight = 0;
|
||||||
|
int addRoadsOnRight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm) {
|
||||||
|
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
|
||||||
|
if(attachedRoutes == null || attachedRoutes.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// keep left/right
|
||||||
|
RoadSplitStructure rs = calculateRoadSplitStructure(prevSegm, currentSegm, attachedRoutes);
|
||||||
|
if(rs.roadsOnLeft + rs.roadsOnRight == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn lanes exist
|
||||||
|
String turnLanes = getTurnLanesString(prevSegm);
|
||||||
|
if (turnLanes != null) {
|
||||||
|
return createKeepLeftRightTurnBasedOnTurnTypes(rs, prevSegm, currentSegm, turnLanes, leftSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn lanes don't exist
|
||||||
|
if (rs.keepLeft || rs.keepRight) {
|
||||||
|
return createSimpleKeepLeftRightTurn(leftSide, prevSegm, currentSegm, rs);
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TurnType createKeepLeftRightTurnBasedOnTurnTypes(RoadSplitStructure rs, RouteSegmentResult prevSegm,
|
||||||
|
RouteSegmentResult currentSegm, String turnLanes,boolean leftSide) {
|
||||||
|
// Maybe going straight at a 90-degree intersection
|
||||||
|
TurnType t = TurnType.valueOf(TurnType.C, leftSide);
|
||||||
|
int[] rawLanes = calculateRawTurnLanes(turnLanes, TurnType.C);
|
||||||
|
if (rs.keepLeft || rs.keepRight) {
|
||||||
|
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
||||||
|
int activeBeginIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.leftLanes, true,
|
||||||
|
rs.roadsOnLeft, rs.addRoadsOnLeft);
|
||||||
|
int activeEndIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.rightLanes, false,
|
||||||
|
rs.roadsOnRight, rs.addRoadsOnRight);
|
||||||
|
if (activeBeginIndex == -1 || activeEndIndex == -1 || activeBeginIndex > activeEndIndex) {
|
||||||
|
// something went wrong
|
||||||
|
return createSimpleKeepLeftRightTurn(leftSide, prevSegm, currentSegm, rs);
|
||||||
|
}
|
||||||
|
for (int k = 0; k < rawLanes.length; k++) {
|
||||||
|
if (k >= activeBeginIndex && k <= activeEndIndex) {
|
||||||
|
rawLanes[k] |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int tp = inferTurnFromLanes(rawLanes);
|
||||||
|
if (tp != t.getValue() && tp != 0) {
|
||||||
|
t = TurnType.valueOf(tp, leftSide);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int k = 0; k < rawLanes.length; k++) {
|
||||||
|
int turn = rawLanes[k];
|
||||||
|
boolean active = false;
|
||||||
|
if (TurnType.getPrimaryTurn(turn) == TurnType.C) {
|
||||||
|
active = true;
|
||||||
|
} else if (TurnType.isRightTurn(turn) && rs.roadsOnRight == 0) {
|
||||||
|
// some turns go through many segments (to turn right or left)
|
||||||
|
// 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;
|
||||||
|
} else if (TurnType.isLeftTurn(turn) && rs.roadsOnLeft == 0) {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
if (active) {
|
||||||
|
rawLanes[k] |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.setSkipToSpeak(!rs.speak);
|
||||||
|
t.setLanes(rawLanes);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int findActiveIndex(int[] rawLanes, String[] splitLaneOptions, int lanes, boolean left,
|
||||||
|
int roads, int addRoads) {
|
||||||
|
int activeStartIndex = -1;
|
||||||
|
boolean lookupSlightTurn = addRoads > 0;
|
||||||
|
for (int i = 0; i < rawLanes.length; i++) {
|
||||||
|
int ind = left ? i : (rawLanes.length - i - 1);
|
||||||
|
if (!lookupSlightTurn ||
|
||||||
|
TurnType.isSlightTurn(TurnType.getPrimaryTurn(rawLanes[ind]))
|
||||||
|
|| TurnType.isSlightTurn(TurnType.getSecondaryTurn(rawLanes[ind]))) {
|
||||||
|
int cnt = countOccurrences(splitLaneOptions[ind], ';') + 1;
|
||||||
|
if(cnt > 1) {
|
||||||
|
// sometimes slight right turn goes to the road with 2 lanes
|
||||||
|
// the better situation to group all the lanes and
|
||||||
|
// when ';' we know for sure the lane combines 2 group
|
||||||
|
roads -= 2;
|
||||||
|
}
|
||||||
|
lanes -= cnt;
|
||||||
|
// we already found slight turn others are turn in different direction
|
||||||
|
lookupSlightTurn = false;
|
||||||
|
}
|
||||||
|
if (lanes < 0 || roads < 0) {
|
||||||
|
activeStartIndex = ind;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeStartIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RoadSplitStructure calculateRoadSplitStructure(RouteSegmentResult prevSegm, RouteSegmentResult currentSegm,
|
||||||
|
List<RouteSegmentResult> attachedRoutes) {
|
||||||
|
RoadSplitStructure rs = new RoadSplitStructure();
|
||||||
int speakPriority = Math.max(highwaySpeakPriority(prevSegm.getObject().getHighway()), highwaySpeakPriority(currentSegm.getObject().getHighway()));
|
int speakPriority = Math.max(highwaySpeakPriority(prevSegm.getObject().getHighway()), highwaySpeakPriority(currentSegm.getObject().getHighway()));
|
||||||
boolean otherRoutesExist = false;
|
|
||||||
if (attachedRoutes != null) {
|
|
||||||
for (RouteSegmentResult attached : attachedRoutes) {
|
for (RouteSegmentResult attached : attachedRoutes) {
|
||||||
double ex = MapUtils.degreesDiff(attached.getBearingBegin(), currentSegm.getBearingBegin());
|
double ex = MapUtils.degreesDiff(attached.getBearingBegin(), currentSegm.getBearingBegin());
|
||||||
double mpi = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), attached.getBearingBegin()));
|
double mpi = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), attached.getBearingBegin()));
|
||||||
int rsSpeakPriority = highwaySpeakPriority(attached.getObject().getHighway());
|
int rsSpeakPriority = highwaySpeakPriority(attached.getObject().getHighway());
|
||||||
if (rsSpeakPriority != MAX_SPEAK_PRIORITY || speakPriority == MAX_SPEAK_PRIORITY) {
|
if (rsSpeakPriority != MAX_SPEAK_PRIORITY || speakPriority == MAX_SPEAK_PRIORITY) {
|
||||||
if ((ex < TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex >= 0) {
|
int lanes = countLanesMinOne(attached);
|
||||||
kl = true;
|
boolean smallStraightVariation = mpi < TURN_DEGREE_MIN;
|
||||||
right += countLanesMinOne(attached);
|
boolean smallTargetVariation = Math.abs(ex) < TURN_DEGREE_MIN;
|
||||||
speak = speak || rsSpeakPriority <= speakPriority;
|
boolean attachedOnTheRight = ex >= 0;
|
||||||
} else if ((ex > -TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex <= 0) {
|
if (attachedOnTheRight) {
|
||||||
kr = true;
|
rs.roadsOnRight++;
|
||||||
left += countLanesMinOne(attached);
|
} else {
|
||||||
speak = speak || rsSpeakPriority <= speakPriority;
|
rs.roadsOnLeft++;
|
||||||
} else if (mpi >= TURN_DEGREE_MIN) {
|
}
|
||||||
// Indicate that there are other turns at this intersection, and displaying the lanes may be helpful here.
|
if (smallTargetVariation || smallStraightVariation) {
|
||||||
otherRoutesExist = true;
|
if (attachedOnTheRight) {
|
||||||
|
rs.keepLeft = true;
|
||||||
|
rs.rightLanes += lanes;
|
||||||
|
} else {
|
||||||
|
rs.keepRight = true;
|
||||||
|
rs.leftLanes += lanes;
|
||||||
|
}
|
||||||
|
rs.speak = rs.speak || rsSpeakPriority <= speakPriority;
|
||||||
|
} else {
|
||||||
|
if (attachedOnTheRight) {
|
||||||
|
rs.addRoadsOnRight++;
|
||||||
|
} else {
|
||||||
|
rs.addRoadsOnLeft++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(kr && left == 0) {
|
return rs;
|
||||||
left = 1;
|
|
||||||
} else if(kl && right == 0) {
|
|
||||||
right = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TurnType createSimpleKeepLeftRightTurn(boolean leftSide, RouteSegmentResult prevSegm,
|
||||||
|
RouteSegmentResult currentSegm, RoadSplitStructure rs) {
|
||||||
int current = countLanesMinOne(currentSegm);
|
int current = countLanesMinOne(currentSegm);
|
||||||
int[] lanes = new int[current + left + right];
|
int ls = current + rs.leftLanes + rs.rightLanes;
|
||||||
ls = current + left + right;
|
int[] lanes = new int[ls];
|
||||||
for (int it = 0; it < ls; it++) {
|
for (int it = 0; it < ls; it++) {
|
||||||
if (it < left || it >= left + current) {
|
if (it < rs.leftLanes || it >= rs.leftLanes + current) {
|
||||||
lanes[it] = 0;
|
lanes[it] = 0;
|
||||||
} else {
|
} else {
|
||||||
lanes[it] = 1;
|
lanes[it] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sometimes links are
|
// sometimes links are
|
||||||
if ((current <= left + right) && (left > 1 || right > 1)) {
|
if ((current <= rs.leftLanes + rs.rightLanes) && (rs.leftLanes > 1 || rs.rightLanes > 1)) {
|
||||||
speak = true;
|
rs.speak = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double devation = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), currentSegm.getBearingBegin()));
|
double devation = Math.abs(MapUtils.degreesDiff(prevSegm.getBearingEnd(), currentSegm.getBearingBegin()));
|
||||||
boolean makeSlightTurn = devation > 5 && (!isMotorway(prevSegm) || !isMotorway(currentSegm));
|
boolean makeSlightTurn = devation > 5 && (!isMotorway(prevSegm) || !isMotorway(currentSegm));
|
||||||
if (kl && kr) {
|
TurnType t = null;
|
||||||
|
if (rs.keepLeft && rs.keepRight) {
|
||||||
t = TurnType.valueOf(TurnType.C, leftSide);
|
t = TurnType.valueOf(TurnType.C, leftSide);
|
||||||
t.setSkipToSpeak(!speak);
|
} else if (rs.keepLeft) {
|
||||||
} else if (kl) {
|
|
||||||
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLL : TurnType.KL, leftSide);
|
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLL : TurnType.KL, leftSide);
|
||||||
t.setSkipToSpeak(!speak);
|
} else if (rs.keepRight) {
|
||||||
} else if (kr) {
|
|
||||||
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLR : TurnType.KR, leftSide);
|
t = TurnType.valueOf(makeSlightTurn ? TurnType.TSLR : TurnType.KR, leftSide);
|
||||||
t.setSkipToSpeak(!speak);
|
} else {
|
||||||
} else if (otherRoutesExist && getTurnLanesString(prevSegm) != null) {
|
|
||||||
// Maybe going straight at a 90-degree intersection
|
|
||||||
t = TurnType.valueOf(TurnType.C, leftSide);
|
|
||||||
t.setSkipToSpeak(true);
|
|
||||||
|
|
||||||
// When going straight, the lanes have to be calculated from the previous segment, not the current/next segment.
|
|
||||||
int prevLanes = countLanesMinOne(prevSegm);
|
|
||||||
|
|
||||||
t.setLanes(attachTurnLanesData(prevSegm, new int[prevLanes]));
|
|
||||||
|
|
||||||
// Manually set the allowed lanes based on the turn type
|
|
||||||
for (int i = 0; i < t.getLanes().length; i++) {
|
|
||||||
if (TurnType.getPrimaryTurn(t.getLanes()[i]) == TurnType.C) {
|
|
||||||
t.getLanes()[i] |= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
if (t != null && lanes != null) {
|
t.setSkipToSpeak(!rs.speak);
|
||||||
int[] calcLanes = attachTurnLanesData(prevSegm, lanes);
|
t.setLanes(lanes);
|
||||||
if(calcLanes != lanes) {
|
|
||||||
int tp = inferTurnFromLanes(calcLanes);
|
|
||||||
if (tp != 0 && tp != t.getValue()) {
|
|
||||||
TurnType derivedTurnType = TurnType.valueOf(tp, leftSide);
|
|
||||||
derivedTurnType.setLanes(calcLanes);
|
|
||||||
derivedTurnType.setSkipToSpeak(t.isSkipToSpeak());
|
|
||||||
// Because only the primary turn is displayed, if the turn to be taken is currently set as the
|
|
||||||
// secondary turn, then that needs to be switched around.
|
|
||||||
for (int i = 0; i < calcLanes.length; i++) {
|
|
||||||
if (TurnType.getSecondaryTurn(calcLanes[i]) == tp) {
|
|
||||||
derivedTurnType.setSecondaryTurn(i, TurnType.getPrimaryTurn(calcLanes[i]));
|
|
||||||
derivedTurnType.setPrimaryTurn(i, tp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.setLanes(calcLanes);
|
|
||||||
|
|
||||||
}
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,45 +916,7 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] attachTurnLanesData(RouteSegmentResult prevSegm, int[] outgoingCalcLanes) {
|
|
||||||
String turnLanes = getTurnLanesString(prevSegm);
|
|
||||||
if (turnLanes == null) {
|
|
||||||
return outgoingCalcLanes;
|
|
||||||
}
|
|
||||||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
|
||||||
if (splitLaneOptions.length != countLanesMinOne(prevSegm)) {
|
|
||||||
// Error in data or missing data
|
|
||||||
return outgoingCalcLanes;
|
|
||||||
}
|
|
||||||
int[] usableLanes = mergeOutgoingLanesUsingTurnLanes(outgoingCalcLanes, splitLaneOptions);
|
|
||||||
int[] rawLanes = calculateRawTurnLanes(splitLaneOptions, 0);
|
|
||||||
for(int k = 0 ; k < splitLaneOptions.length; k++) {
|
|
||||||
if((usableLanes[k] & 1) != 0) {
|
|
||||||
rawLanes[k] |= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return rawLanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int[] mergeOutgoingLanesUsingTurnLanes(int[] outgoingCalcLanes, String[] splitLaneOptions) {
|
|
||||||
int[] usableLanes = outgoingCalcLanes;
|
|
||||||
if (outgoingCalcLanes.length != splitLaneOptions.length) {
|
|
||||||
usableLanes = new int[splitLaneOptions.length];
|
|
||||||
// The turn:lanes don't easily match up to the target road.
|
|
||||||
int outgoingLanesIndex = 0;
|
|
||||||
int sourceLanesIndex = 0;
|
|
||||||
while (outgoingLanesIndex < outgoingCalcLanes.length &&
|
|
||||||
sourceLanesIndex < splitLaneOptions.length) {
|
|
||||||
int options = countOccurrences(splitLaneOptions[sourceLanesIndex], ';');
|
|
||||||
for (int k = 0; k <= options && outgoingLanesIndex < outgoingCalcLanes.length; k++) {
|
|
||||||
usableLanes[sourceLanesIndex] |= outgoingCalcLanes[outgoingLanesIndex];
|
|
||||||
outgoingLanesIndex++;
|
|
||||||
}
|
|
||||||
sourceLanesIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return usableLanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int countOccurrences(String haystack, char needle) {
|
private int countOccurrences(String haystack, char needle) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -905,8 +944,7 @@ public class RouteResultPreparation {
|
||||||
if(turnLanes == null) {
|
if(turnLanes == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
return calculateRawTurnLanes(turnLanes, 0);
|
||||||
return calculateRawTurnLanes(splitLaneOptions, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] parseLanes(RouteDataObject ro, double dirToNorthEastPi) {
|
public static int[] parseLanes(RouteDataObject ro, double dirToNorthEastPi) {
|
||||||
|
@ -939,7 +977,8 @@ public class RouteResultPreparation {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] calculateRawTurnLanes(String[] splitLaneOptions, int calcTurnType) {
|
private static int[] calculateRawTurnLanes(String turnLanes, int calcTurnType) {
|
||||||
|
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
||||||
int[] lanes = new int[splitLaneOptions.length];
|
int[] lanes = new int[splitLaneOptions.length];
|
||||||
for (int i = 0; i < splitLaneOptions.length; i++) {
|
for (int i = 0; i < splitLaneOptions.length; i++) {
|
||||||
String[] laneOptions = splitLaneOptions[i].split(";");
|
String[] laneOptions = splitLaneOptions[i].split(";");
|
||||||
|
@ -967,12 +1006,16 @@ public class RouteResultPreparation {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TurnType.getPrimaryTurn(lanes[i]) == 0) {
|
final int primary = TurnType.getPrimaryTurn(lanes[i]);
|
||||||
TurnType.setPrimaryTurn(lanes, i, turn);
|
if (primary == 0) {
|
||||||
|
TurnType.setPrimaryTurnAndReset(lanes, i, turn);
|
||||||
} else {
|
} else {
|
||||||
if (turn == calcTurnType) {
|
if (turn == calcTurnType ||
|
||||||
TurnType.setSecondaryTurn(lanes, i, TurnType.getPrimaryTurn(lanes[i]));
|
(TurnType.isRightTurn(calcTurnType) && TurnType.isRightTurn(turn)) ||
|
||||||
TurnType.setPrimaryTurn(lanes, i, turn);
|
(TurnType.isLeftTurn(calcTurnType) && TurnType.isLeftTurn(turn))
|
||||||
|
) {
|
||||||
|
TurnType.setPrimaryTurnAndReset(lanes, i, turn);
|
||||||
|
TurnType.setSecondaryTurn(lanes, i, primary);
|
||||||
} else {
|
} else {
|
||||||
TurnType.setSecondaryTurn(lanes, i, turn);
|
TurnType.setSecondaryTurn(lanes, i, turn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,14 +163,10 @@ public class TurnType {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that the primary turn will be the one displayed on the map.
|
// Note that the primary turn will be the one displayed on the map.
|
||||||
public static void setPrimaryTurn(int[] lanes, int lane, int turnType) {
|
public static void setPrimaryTurnAndReset(int[] lanes, int lane, int turnType) {
|
||||||
lanes[lane] |= (turnType << 1);
|
lanes[lane] = (turnType << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrimaryTurn(int lane, int turnType) {
|
|
||||||
lanes[lane] &= ~(15 << 1);
|
|
||||||
lanes[lane] |= (turnType << 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getPrimaryTurn(int laneValue) {
|
public static int getPrimaryTurn(int laneValue) {
|
||||||
// Get the primary turn modifier for the lane
|
// Get the primary turn modifier for the lane
|
||||||
|
@ -182,10 +178,6 @@ public class TurnType {
|
||||||
lanes[lane] |= (turnType << 5);
|
lanes[lane] |= (turnType << 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSecondaryTurn(int lane, int turnType) {
|
|
||||||
lanes[lane] |= (turnType << 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getSecondaryTurn(int laneValue) {
|
public static int getSecondaryTurn(int laneValue) {
|
||||||
// Get the primary turn modifier for the lane
|
// Get the primary turn modifier for the lane
|
||||||
return (laneValue >> 5);
|
return (laneValue >> 5);
|
||||||
|
@ -249,11 +241,11 @@ public class TurnType {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLeftTurn(int type) {
|
public static boolean isLeftTurn(int type) {
|
||||||
return type == TL || type == TSHL || type == TSLL;
|
return type == TL || type == TSHL || type == TSLL || type == TRU;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isRightTurn(int type) {
|
public static boolean isRightTurn(int type) {
|
||||||
return type == TR || type == TSHR || type == TSLR;
|
return type == TR || type == TSHR || type == TSLR || type == TU;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSlightTurn(int type) {
|
public static boolean isSlightTurn(int type) {
|
||||||
|
|
Loading…
Reference in a new issue