Fix issue with turn type
This commit is contained in:
parent
ddf6d63704
commit
a9b1031ce9
2 changed files with 165 additions and 184 deletions
|
@ -1,16 +1,16 @@
|
||||||
package net.osmand.router;
|
package net.osmand.router;
|
||||||
|
|
||||||
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
|
import gnu.trove.set.hash.TIntHashSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
|
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||||
|
@ -21,6 +21,8 @@ import net.osmand.router.BinaryRoutePlanner.RouteSegment;
|
||||||
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
|
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
public class RouteResultPreparation {
|
public class RouteResultPreparation {
|
||||||
|
|
||||||
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = false;
|
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = false;
|
||||||
|
@ -440,7 +442,10 @@ public class RouteResultPreparation {
|
||||||
} else {
|
} else {
|
||||||
t = TurnType.valueOf(TurnType.TU, leftSide);
|
t = TurnType.valueOf(TurnType.TU, leftSide);
|
||||||
}
|
}
|
||||||
assignLanesInfo(prev, t, leftSide);
|
int[] lanes = getTurnLanesInfo(prev, t.getValue(), leftSide, true);
|
||||||
|
if(lanes != null) {
|
||||||
|
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);
|
||||||
|
@ -451,7 +456,10 @@ public class RouteResultPreparation {
|
||||||
} else {
|
} else {
|
||||||
t = TurnType.valueOf(TurnType.TU, leftSide);
|
t = TurnType.valueOf(TurnType.TU, leftSide);
|
||||||
}
|
}
|
||||||
assignLanesInfo(prev, t, leftSide);
|
int[] lanes = getTurnLanesInfo(prev, t.getValue(), leftSide, false);
|
||||||
|
if(lanes != null) {
|
||||||
|
t.setLanes(lanes);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr, t);
|
t = attachKeepLeftInfoAndLanes(leftSide, prev, rr, t);
|
||||||
}
|
}
|
||||||
|
@ -462,62 +470,52 @@ public class RouteResultPreparation {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignLanesInfo(RouteSegmentResult prevSegm, TurnType t, boolean leftSide) {
|
private int[] getTurnLanesInfo(RouteSegmentResult prevSegm, int mainTurnType, boolean leftSide,
|
||||||
int lanes = prevSegm.getObject().getLanes();
|
boolean leftTurn) {
|
||||||
if (prevSegm.getObject().getOneway() == 0) {
|
|
||||||
lanes = countLanes(prevSegm, lanes);
|
|
||||||
}
|
|
||||||
if (lanes <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String turnLanes = getTurnLanesString(prevSegm);
|
String turnLanes = getTurnLanesString(prevSegm);
|
||||||
if (turnLanes == null) {
|
if (turnLanes == null) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
||||||
if (splitLaneOptions.length != lanes) {
|
if (splitLaneOptions.length != countLanesMinOne(prevSegm)) {
|
||||||
// Error in data or missing data
|
// Error in data or missing data
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
int[] lanesArray = calculateRawTurnLanes(splitLaneOptions, mainTurnType);
|
||||||
int[] lanesArray = new int[lanes];
|
// Manually set the allowed lanes.
|
||||||
t.setLanes(lanesArray);
|
boolean isSet = setAllowedLanes(mainTurnType, lanesArray);
|
||||||
assignTurns(splitLaneOptions, t);
|
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.
|
||||||
if (leftSide) {
|
int ind = leftTurn? 0 : lanesArray.length - 1;
|
||||||
if (t.getValue() == TurnType.TL
|
final int tt = TurnType.getPrimaryTurn(lanesArray[ind]);
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TL
|
if (leftTurn) {
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TSLL
|
if (!TurnType.isLeftTurn(tt)) {
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[0]) != TurnType.TSHL) {
|
|
||||||
if (TurnType.getPrimaryTurn(lanesArray[0]) != 0) {
|
|
||||||
// This was just to make sure that there's no bad data.
|
// This was just to make sure that there's no bad data.
|
||||||
t.setSecondaryTurn(0, TurnType.getPrimaryTurn(lanesArray[0]));
|
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
||||||
t.setPrimaryTurn(0, TurnType.TL);
|
TurnType.setPrimaryTurn(lanesArray, ind, TurnType.TL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int lastIndex = lanesArray.length - 1;
|
if (!TurnType.isRightTurn(tt)) {
|
||||||
if (t.getValue() == TurnType.TR
|
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TR
|
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TSLR
|
|
||||||
&& TurnType.getPrimaryTurn(lanesArray[lastIndex]) != TurnType.TSHR) {
|
|
||||||
if (TurnType.getPrimaryTurn(lanesArray[lastIndex]) != 0) {
|
|
||||||
// This was just to make sure that there's no bad data.
|
// This was just to make sure that there's no bad data.
|
||||||
t.setSecondaryTurn(lastIndex, TurnType.getPrimaryTurn(lanesArray[lastIndex]));
|
TurnType.setSecondaryTurn(lanesArray, ind, tt);
|
||||||
t.setPrimaryTurn(lastIndex, TurnType.TR);
|
TurnType.setPrimaryTurn(lanesArray, ind, TurnType.TR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setAllowedLanes(lanesArray[ind], lanesArray);
|
||||||
|
}
|
||||||
|
return lanesArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manually set the allowed lanes.
|
protected boolean setAllowedLanes(int mainTurnType, int[] lanesArray) {
|
||||||
|
boolean turnSet = false;
|
||||||
for (int i = 0; i < lanesArray.length; i++) {
|
for (int i = 0; i < lanesArray.length; i++) {
|
||||||
if (TurnType.getPrimaryTurn(lanesArray[i]) == t.getValue()) {
|
if (TurnType.getPrimaryTurn(lanesArray[i]) == mainTurnType) {
|
||||||
lanesArray[i] |= 1;
|
lanesArray[i] |= 1;
|
||||||
|
turnSet = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return turnSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TurnType processRoundaboutTurn(List<RouteSegmentResult> result, int i, boolean leftSide, RouteSegmentResult prev,
|
private TurnType processRoundaboutTurn(List<RouteSegmentResult> result, int i, boolean leftSide, RouteSegmentResult prev,
|
||||||
|
@ -554,7 +552,6 @@ public class RouteResultPreparation {
|
||||||
|
|
||||||
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm, TurnType t) {
|
private TurnType attachKeepLeftInfoAndLanes(boolean leftSide, RouteSegmentResult prevSegm, RouteSegmentResult currentSegm, TurnType t) {
|
||||||
// keep left/right
|
// keep left/right
|
||||||
int[] lanes = null;
|
|
||||||
boolean kl = false;
|
boolean kl = false;
|
||||||
boolean kr = false;
|
boolean kr = false;
|
||||||
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
|
List<RouteSegmentResult> attachedRoutes = currentSegm.getAttachedRoutes(currentSegm.getStartPointIndex());
|
||||||
|
@ -574,27 +571,11 @@ public class RouteResultPreparation {
|
||||||
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) {
|
if ((ex < TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex >= 0) {
|
||||||
kl = true;
|
kl = true;
|
||||||
int lns = attached.getObject().getLanes();
|
right += countLanesMinOne(attached);
|
||||||
if(attached.getObject().getOneway() == 0) {
|
|
||||||
lns = countLanes(attached, lns);
|
|
||||||
}
|
|
||||||
if (lns <= 0) {
|
|
||||||
right += 1;
|
|
||||||
} else {
|
|
||||||
right += lns;
|
|
||||||
}
|
|
||||||
speak = speak || rsSpeakPriority <= speakPriority;
|
speak = speak || rsSpeakPriority <= speakPriority;
|
||||||
} else if ((ex > -TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex <= 0) {
|
} else if ((ex > -TURN_DEGREE_MIN || mpi < TURN_DEGREE_MIN) && ex <= 0) {
|
||||||
kr = true;
|
kr = true;
|
||||||
int lns = attached.getObject().getLanes();
|
left += countLanesMinOne(attached);
|
||||||
if(attached.getObject().getOneway() == 0) {
|
|
||||||
lns = countLanes(attached, lns);
|
|
||||||
}
|
|
||||||
if (lns <= 0) {
|
|
||||||
left += 1;
|
|
||||||
} else {
|
|
||||||
left += lns;
|
|
||||||
}
|
|
||||||
speak = speak || rsSpeakPriority <= speakPriority;
|
speak = speak || rsSpeakPriority <= speakPriority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,16 +586,8 @@ public class RouteResultPreparation {
|
||||||
} else if(kl && right == 0) {
|
} else if(kl && right == 0) {
|
||||||
right = 1;
|
right = 1;
|
||||||
}
|
}
|
||||||
int current = currentSegm.getObject().getLanes();
|
int current = countLanesMinOne(currentSegm);
|
||||||
// attachedRoutes covers all allowed outbound routes at that point except currentSegm.
|
int[] lanes = new int[current + left + right];
|
||||||
if (currentSegm.getObject().getOneway() == 0) {
|
|
||||||
current = countLanes(currentSegm, current);
|
|
||||||
}
|
|
||||||
if (current <= 0) {
|
|
||||||
current = 1;
|
|
||||||
}
|
|
||||||
// if(ls >= 0 /*&& current + left + right >= ls*/){
|
|
||||||
lanes = new int[current + left + right];
|
|
||||||
ls = current + left + right;
|
ls = current + left + right;
|
||||||
for (int it = 0; it < ls; it++) {
|
for (int it = 0; it < ls; it++) {
|
||||||
if (it < left || it >= left + current) {
|
if (it < left || it >= left + current) {
|
||||||
|
@ -627,7 +600,6 @@ public class RouteResultPreparation {
|
||||||
if ((current <= left + right) && (left > 1 || right > 1)) {
|
if ((current <= left + right) && (left > 1 || right > 1)) {
|
||||||
speak = true;
|
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));
|
||||||
|
@ -640,14 +612,42 @@ public class RouteResultPreparation {
|
||||||
t.setSkipToSpeak(!speak);
|
t.setSkipToSpeak(!speak);
|
||||||
}
|
}
|
||||||
if (t != null && lanes != null) {
|
if (t != null && lanes != null) {
|
||||||
t.setLanes(lanes);
|
int[] calcLanes = attachTurnLanesData(prevSegm, 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);
|
||||||
|
|
||||||
t = attachTurnLanesData(leftSide, prevSegm, t);
|
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int countLanes(RouteSegmentResult attached, int lns) {
|
|
||||||
|
protected int countLanesMinOne(RouteSegmentResult attached) {
|
||||||
|
final boolean oneway = attached.getObject().getOneway() != 0;
|
||||||
|
int lns = attached.getObject().getLanes();
|
||||||
|
if(lns == 0) {
|
||||||
|
String tls = getTurnLanesString(attached);
|
||||||
|
if(tls != null) {
|
||||||
|
lns = countOccurrences(tls, '|');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oneway) {
|
||||||
|
return Math.max(1, lns);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (attached.isForwardDirection() && attached.getObject().getValue("lanes:forward") != null) {
|
if (attached.isForwardDirection() && attached.getObject().getValue("lanes:forward") != null) {
|
||||||
return Integer.parseInt(attached.getObject().getValue("lanes:forward"));
|
return Integer.parseInt(attached.getObject().getValue("lanes:forward"));
|
||||||
|
@ -657,7 +657,7 @@ public class RouteResultPreparation {
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return (lns + 1) / 2;
|
return Math.max(1, (lns + 1) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getTurnLanesString(RouteSegmentResult segment) {
|
protected String getTurnLanesString(RouteSegmentResult segment) {
|
||||||
|
@ -672,64 +672,44 @@ public class RouteResultPreparation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TurnType attachTurnLanesData(boolean leftSide, RouteSegmentResult prevSegm, TurnType t) {
|
private int[] attachTurnLanesData(RouteSegmentResult prevSegm, int[] outgoingCalcLanes) {
|
||||||
int lanes = prevSegm.getObject().getLanes();
|
|
||||||
String turnLanes = getTurnLanesString(prevSegm);
|
String turnLanes = getTurnLanesString(prevSegm);
|
||||||
|
|
||||||
if (turnLanes == null) {
|
if (turnLanes == null) {
|
||||||
return t;
|
return outgoingCalcLanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
||||||
if (splitLaneOptions.length != lanes) {
|
if (splitLaneOptions.length != countLanesMinOne(prevSegm)) {
|
||||||
// Error in data or missing data
|
// Error in data or missing data
|
||||||
return t;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.getLanes().length != lanes) {
|
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.
|
// The turn:lanes don't easily match up to the target road.
|
||||||
List<Integer> sourceLanes = new ArrayList<Integer>();
|
|
||||||
|
|
||||||
int outgoingLanesIndex = 0;
|
int outgoingLanesIndex = 0;
|
||||||
int sourceLanesIndex = 0;
|
int sourceLanesIndex = 0;
|
||||||
|
while (outgoingLanesIndex < outgoingCalcLanes.length &&
|
||||||
while (outgoingLanesIndex < t.getLanes().length && sourceLanesIndex < lanes) {
|
sourceLanesIndex < splitLaneOptions.length) {
|
||||||
if (splitLaneOptions[sourceLanesIndex].contains(";")) {
|
|
||||||
// Two or more allowed turns for this lane
|
|
||||||
int options = countOccurrences(splitLaneOptions[sourceLanesIndex], ';');
|
int options = countOccurrences(splitLaneOptions[sourceLanesIndex], ';');
|
||||||
if (options == 1) {
|
for (int k = 0; k <= options && outgoingLanesIndex < outgoingCalcLanes.length; k++) {
|
||||||
if (outgoingLanesIndex + 1 >= t.getLanes().length) {
|
usableLanes[sourceLanesIndex] |= outgoingCalcLanes[outgoingLanesIndex];
|
||||||
// Likely an error in data
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
int usability = t.getLanes()[outgoingLanesIndex] | t.getLanes()[outgoingLanesIndex + 1];
|
|
||||||
sourceLanes.add(usability);
|
|
||||||
outgoingLanesIndex += 2;
|
|
||||||
sourceLanesIndex++;
|
|
||||||
} else {
|
|
||||||
// Not supported
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Only one allowed turn; behave normally
|
|
||||||
sourceLanes.add(t.getLanes()[outgoingLanesIndex]);
|
|
||||||
outgoingLanesIndex++;
|
outgoingLanesIndex++;
|
||||||
|
}
|
||||||
sourceLanesIndex++;
|
sourceLanesIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return usableLanes;
|
||||||
int[] newLanes = new int[sourceLanes.size()];
|
|
||||||
|
|
||||||
for (int i = 0; i < sourceLanes.size(); i++) {
|
|
||||||
newLanes[i] = sourceLanes.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
t.setLanes(newLanes);
|
|
||||||
}
|
|
||||||
|
|
||||||
assignTurns(splitLaneOptions, t);
|
|
||||||
t = inferTurnFromLanes(t, leftSide);
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int countOccurrences(String haystack, char needle) {
|
private int countOccurrences(String haystack, char needle) {
|
||||||
|
@ -742,7 +722,8 @@ public class RouteResultPreparation {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignTurns(String[] splitLaneOptions, TurnType t) {
|
private int[] calculateRawTurnLanes(String[] splitLaneOptions, int calcTurnType) {
|
||||||
|
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(";");
|
||||||
|
|
||||||
|
@ -769,80 +750,64 @@ public class RouteResultPreparation {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TurnType.getPrimaryTurn(t.getLanes()[i]) == 0) {
|
if (TurnType.getPrimaryTurn(lanes[i]) == 0) {
|
||||||
t.setPrimaryTurn(i, turn);
|
TurnType.setPrimaryTurn(lanes, i, turn);
|
||||||
} else {
|
} else {
|
||||||
if (turn == t.getValue()) {
|
if (turn == calcTurnType) {
|
||||||
t.setSecondaryTurn(i, TurnType.getPrimaryTurn(t.getLanes()[i]));
|
TurnType.setSecondaryTurn(lanes, i, TurnType.getPrimaryTurn(lanes[i]));
|
||||||
t.setPrimaryTurn(i, turn);
|
TurnType.setPrimaryTurn(lanes, i, turn);
|
||||||
} else {
|
} else {
|
||||||
t.setSecondaryTurn(i, turn);
|
TurnType.setSecondaryTurn(lanes, i, turn);
|
||||||
}
|
}
|
||||||
|
|
||||||
break; // Move on to the next lane
|
break; // Move on to the next lane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return lanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TurnType inferTurnFromLanes(TurnType t, boolean leftSide) {
|
private int inferTurnFromLanes(int[] oLanes) {
|
||||||
List<Integer> possibleTurns = new ArrayList<Integer>();
|
TIntHashSet possibleTurns = new TIntHashSet();
|
||||||
for (int i = 0; i < t.getLanes().length; i++) {
|
for (int i = 0; i < oLanes.length; i++) {
|
||||||
if ((t.getLanes()[i] & 1) == 0) {
|
if ((oLanes[i] & 1) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (possibleTurns.isEmpty()) {
|
if (possibleTurns.isEmpty()) {
|
||||||
// Nothing is in the list to compare to, so add the first elements
|
// Nothing is in the list to compare to, so add the first elements
|
||||||
possibleTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
|
possibleTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||||
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
|
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||||
possibleTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
|
possibleTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<Integer> laneTurns = new ArrayList<Integer>();
|
TIntArrayList laneTurns = new TIntArrayList();
|
||||||
laneTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
|
laneTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||||
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
|
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||||
laneTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
|
laneTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||||
}
|
}
|
||||||
possibleTurns.retainAll(laneTurns);
|
possibleTurns.retainAll(laneTurns);
|
||||||
|
|
||||||
if (possibleTurns.isEmpty()) {
|
if (possibleTurns.isEmpty()) {
|
||||||
// No common turns, so can't determine anything.
|
// No common turns, so can't determine anything.
|
||||||
return t;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all turns from lanes not selected...because those aren't it
|
// Remove all turns from lanes not selected...because those aren't it
|
||||||
for (int i = 0; i < t.getLanes().length; i++) {
|
for (int i = 0; i < oLanes.length; i++) {
|
||||||
if ((t.getLanes()[i] & 1) == 0 && !possibleTurns.isEmpty()) {
|
if ((oLanes[i] & 1) == 0 && !possibleTurns.isEmpty()) {
|
||||||
List<Integer> notLaneTurns = new ArrayList<Integer>();
|
possibleTurns.remove((Integer) TurnType.getPrimaryTurn(oLanes[i]));
|
||||||
notLaneTurns.add(TurnType.getPrimaryTurn(t.getLanes()[i]));
|
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||||
if (TurnType.getSecondaryTurn(t.getLanes()[i]) != 0) {
|
possibleTurns.remove((Integer) TurnType.getSecondaryTurn(oLanes[i]));
|
||||||
notLaneTurns.add(TurnType.getSecondaryTurn(t.getLanes()[i]));
|
|
||||||
}
|
}
|
||||||
possibleTurns.removeAll(notLaneTurns);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking to see that there is only one unique turn
|
// Checking to see that there is only one unique turn
|
||||||
if (new HashSet<Integer>(possibleTurns).size() == 1) {
|
if (possibleTurns.size() == 1) {
|
||||||
TurnType derivedTurnType = TurnType.valueOf(possibleTurns.get(0), leftSide);
|
return possibleTurns.iterator().next();
|
||||||
derivedTurnType.setLanes(t.getLanes());
|
|
||||||
derivedTurnType.setSkipToSpeak(t.isSkipToSpeak());
|
|
||||||
t = derivedTurnType;
|
|
||||||
|
|
||||||
// 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 < t.getLanes().length; i++) {
|
|
||||||
if (TurnType.getSecondaryTurn(t.getLanes()[i]) == t.getValue()) {
|
|
||||||
int temp = TurnType.getSecondaryTurn(t.getLanes()[i]);
|
|
||||||
t.setSecondaryTurn(i, TurnType.getPrimaryTurn(t.getLanes()[i]));
|
|
||||||
t.setPrimaryTurn(i, temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMotorway(RouteSegmentResult s){
|
private boolean isMotorway(RouteSegmentResult s){
|
||||||
|
|
|
@ -163,6 +163,10 @@ public class TurnType {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that there is no "weight" or ordering between the primary and secondary turns.
|
// Note that there is no "weight" or ordering between the primary and secondary turns.
|
||||||
|
public static void setPrimaryTurn(int[] lanes, int lane, int turnType) {
|
||||||
|
lanes[lane] |= (turnType << 1);
|
||||||
|
}
|
||||||
|
|
||||||
public void setPrimaryTurn(int lane, int turnType) {
|
public void setPrimaryTurn(int lane, int turnType) {
|
||||||
lanes[lane] |= (turnType << 1);
|
lanes[lane] |= (turnType << 1);
|
||||||
}
|
}
|
||||||
|
@ -172,6 +176,10 @@ public class TurnType {
|
||||||
return (laneValue >> 1) & ((1 << 4) - 1);
|
return (laneValue >> 1) & ((1 << 4) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setSecondaryTurn(int[] lanes, int lane, int turnType) {
|
||||||
|
lanes[lane] |= (turnType << 5);
|
||||||
|
}
|
||||||
|
|
||||||
public void setSecondaryTurn(int lane, int turnType) {
|
public void setSecondaryTurn(int lane, int turnType) {
|
||||||
lanes[lane] |= (turnType << 5);
|
lanes[lane] |= (turnType << 5);
|
||||||
}
|
}
|
||||||
|
@ -237,4 +245,12 @@ public class TurnType {
|
||||||
}
|
}
|
||||||
return super.toString();
|
return super.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLeftTurn(int type) {
|
||||||
|
return type == TL || type == TSHL || type == TSLL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRightTurn(int type) {
|
||||||
|
return type == TR || type == TSHR || type == TSLR;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue