parent
96053e81b0
commit
2223d9918e
3 changed files with 98 additions and 97 deletions
|
@ -1,6 +1,24 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import net.osmand.NativeLibrary;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import gnu.trove.iterator.TIntIterator;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.set.hash.TIntHashSet;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||
|
@ -19,26 +37,6 @@ import net.osmand.util.Algorithms;
|
|||
import net.osmand.util.MapAlgorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import gnu.trove.iterator.TIntIterator;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.set.hash.TIntHashSet;
|
||||
|
||||
public class RouteResultPreparation {
|
||||
|
||||
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = false;
|
||||
|
@ -623,7 +621,7 @@ public class RouteResultPreparation {
|
|||
// calculateStatistics(result);
|
||||
}
|
||||
|
||||
private void calculateStatistics(List<RouteSegmentResult> result) {
|
||||
protected void calculateStatistics(List<RouteSegmentResult> result) {
|
||||
InputStream is = RenderingRulesStorage.class.getResourceAsStream("default.render.xml");
|
||||
final Map<String, String> renderingConstants = new LinkedHashMap<String, String>();
|
||||
try {
|
||||
|
@ -800,13 +798,22 @@ public class RouteResultPreparation {
|
|||
}
|
||||
if (dist < mergeDistance) {
|
||||
mergeTurnLanes(leftside, currentSegment, nextSegment);
|
||||
inferCommonActiveLane(currentSegment.getTurnType(), nextSegment.getTurnType());
|
||||
TurnType turnType = currentSegment.getTurnType();
|
||||
TIntHashSet possibleTurn = getPossibleTurnsFromActiveLanes(turnType.getLanes(), true);
|
||||
if (possibleTurn.size() == 1) {
|
||||
TurnType tt = TurnType.valueOf(possibleTurn.iterator().next(), currentSegment.getTurnType().isLeftSide());
|
||||
tt.setLanes(turnType.getLanes());
|
||||
tt.setSkipToSpeak(turnType.isSkipToSpeak());
|
||||
currentSegment.setTurnType(tt);
|
||||
turnType = tt;
|
||||
}
|
||||
inferCommonActiveLane(turnType, nextSegment.getTurnType());
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
if (!merged) {
|
||||
TurnType tt = currentSegment.getTurnType();
|
||||
inferActiveTurnLanesFromTurn(tt, TurnType.C);
|
||||
inferActiveTurnLanesFromTurn(tt, tt.getValue());
|
||||
}
|
||||
nextSegment = currentSegment;
|
||||
dist = 0;
|
||||
|
@ -984,11 +991,9 @@ public class RouteResultPreparation {
|
|||
if(turnSet.size() == 1) {
|
||||
singleTurn = turnSet.iterator().next();
|
||||
} else if(currentTurn.goAhead() && turnSet.contains(nextTurn.getValue())) {
|
||||
if(currentTurn.isPossibleLeftTurn() &&
|
||||
TurnType.isLeftTurn(nextTurn.getValue())) {
|
||||
singleTurn = nextTurn.getValue();
|
||||
} else if(currentTurn.isPossibleLeftTurn() &&
|
||||
TurnType.isLeftTurn(nextTurn.getActiveCommonLaneTurn())) {
|
||||
if (currentTurn.isPossibleLeftTurn() && TurnType.isLeftTurn(nextTurn.getValue())) {
|
||||
singleTurn = nextTurn.getValue();
|
||||
} else if (currentTurn.isPossibleLeftTurn() && TurnType.isLeftTurn(nextTurn.getActiveCommonLaneTurn())) {
|
||||
singleTurn = nextTurn.getActiveCommonLaneTurn();
|
||||
} else if(currentTurn.isPossibleRightTurn() &&
|
||||
TurnType.isRightTurn(nextTurn.getValue())) {
|
||||
|
@ -1054,7 +1059,7 @@ public class RouteResultPreparation {
|
|||
// add description about turn
|
||||
double mpi = MapUtils.degreesDiff(prev.getBearingEnd(), rr.getBearingBegin());
|
||||
if(noAttachedRoads){
|
||||
// TODO VICTOR : look at the comment inside direction route
|
||||
// VICTOR : look at the comment inside direction route
|
||||
// ? avoid small zigzags is covered at (search for "zigzags")
|
||||
// double begin = rr.getObject().directionRoute(rr.getStartPointIndex(), rr.getStartPointIndex() <
|
||||
// rr.getEndPointIndex(), 25);
|
||||
|
@ -1269,17 +1274,8 @@ public class RouteResultPreparation {
|
|||
String[] splitLaneOptions = turnLanes.split("\\|", -1);
|
||||
int activeBeginIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.leftLanes, true,
|
||||
rs.leftLanesInfo, rs.roadsOnLeft, rs.addRoadsOnLeft);
|
||||
|
||||
if(!rs.keepLeft && activeBeginIndex != -1 &&
|
||||
splitLaneOptions.length > 0 && !splitLaneOptions[splitLaneOptions.length - 1].contains(";")) {
|
||||
activeBeginIndex = Math.max(activeBeginIndex, 1);
|
||||
}
|
||||
int activeEndIndex = findActiveIndex(rawLanes, splitLaneOptions, rs.rightLanes, false,
|
||||
rs.rightLanesInfo, rs.roadsOnRight, rs.addRoadsOnRight);
|
||||
if(!rs.keepRight && activeEndIndex != -1 &&
|
||||
splitLaneOptions.length > 0 && !splitLaneOptions[0].contains(";") ) {
|
||||
activeEndIndex = Math.min(activeEndIndex, rawLanes.length - 1);
|
||||
}
|
||||
if (activeBeginIndex == -1 || activeEndIndex == -1 || activeBeginIndex > activeEndIndex) {
|
||||
// something went wrong
|
||||
return createSimpleKeepLeftRightTurn(leftSide, prevSegm, currentSegm, rs);
|
||||
|
@ -1292,6 +1288,12 @@ public class RouteResultPreparation {
|
|||
int tp = inferSlightTurnFromLanes(rawLanes, rs);
|
||||
if (tp != t.getValue() && tp != 0) {
|
||||
t = TurnType.valueOf(tp, leftSide);
|
||||
} else {
|
||||
if (rs.keepRight && TurnType.getSecondaryTurn(rawLanes[activeEndIndex]) == 0) {
|
||||
t = TurnType.valueOf(TurnType.getPrimaryTurn(rawLanes[activeEndIndex]), leftSide);
|
||||
} else if (rs.keepLeft && TurnType.getSecondaryTurn(rawLanes[activeBeginIndex]) == 0) {
|
||||
t = TurnType.valueOf(TurnType.getPrimaryTurn(rawLanes[activeBeginIndex]), leftSide);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < rawLanes.length; k++) {
|
||||
|
@ -1597,59 +1599,11 @@ public class RouteResultPreparation {
|
|||
}
|
||||
|
||||
private int inferSlightTurnFromLanes(int[] oLanes, RoadSplitStructure rs) {
|
||||
TIntHashSet possibleTurns = new TIntHashSet();
|
||||
for (int i = 0; i < oLanes.length; i++) {
|
||||
if ((oLanes[i] & 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (possibleTurns.isEmpty()) {
|
||||
// Nothing is in the list to compare to, so add the first elements
|
||||
possibleTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.add(TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
} else {
|
||||
TIntArrayList laneTurns = new TIntArrayList();
|
||||
laneTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
laneTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
laneTurns.add(TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
possibleTurns.retainAll(laneTurns);
|
||||
if (possibleTurns.isEmpty()) {
|
||||
// No common turns, so can't determine anything.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
TIntHashSet possibleTurns = getPossibleTurnsFromActiveLanes(oLanes, false);
|
||||
if (possibleTurns.isEmpty()) {
|
||||
// No common turns, so can't determine anything.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Remove all turns from lanes not selected...because those aren't it
|
||||
for (int i = 0; i < oLanes.length; i++) {
|
||||
if ((oLanes[i] & 1) == 0 && !possibleTurns.isEmpty()) {
|
||||
possibleTurns.remove((Integer) TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.remove((Integer) TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.remove((Integer) TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove all non-slight turns // TEST don't pass
|
||||
// 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();
|
||||
|
@ -1688,6 +1642,53 @@ public class RouteResultPreparation {
|
|||
return infer;
|
||||
}
|
||||
|
||||
private TIntHashSet getPossibleTurnsFromActiveLanes(int[] oLanes, boolean onlyPrimary) {
|
||||
TIntHashSet possibleTurns = new TIntHashSet();
|
||||
for (int i = 0; i < oLanes.length; i++) {
|
||||
if ((oLanes[i] & 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (possibleTurns.isEmpty()) {
|
||||
// Nothing is in the list to compare to, so add the first elements
|
||||
possibleTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (!onlyPrimary && TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (!onlyPrimary && TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.add(TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
} else {
|
||||
TIntArrayList laneTurns = new TIntArrayList();
|
||||
laneTurns.add(TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (!onlyPrimary && TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
laneTurns.add(TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (!onlyPrimary && TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
laneTurns.add(TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
possibleTurns.retainAll(laneTurns);
|
||||
if (possibleTurns.isEmpty()) {
|
||||
// No common turns, so can't determine anything.
|
||||
return possibleTurns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all turns from lanes not selected...because those aren't it
|
||||
for (int i = 0; i < oLanes.length; i++) {
|
||||
if ((oLanes[i] & 1) == 0 && !possibleTurns.isEmpty()) {
|
||||
possibleTurns.remove((Integer) TurnType.getPrimaryTurn(oLanes[i]));
|
||||
if (TurnType.getSecondaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.remove((Integer) TurnType.getSecondaryTurn(oLanes[i]));
|
||||
}
|
||||
if (TurnType.getTertiaryTurn(oLanes[i]) != 0) {
|
||||
possibleTurns.remove((Integer) TurnType.getTertiaryTurn(oLanes[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return possibleTurns;
|
||||
}
|
||||
|
||||
private boolean isMotorway(RouteSegmentResult s){
|
||||
String h = s.getObject().getHighway();
|
||||
return "motorway".equals(h) || "motorway_link".equals(h) ||
|
||||
|
|
|
@ -21,6 +21,8 @@ import gnu.trove.map.hash.TIntObjectHashMap;
|
|||
|
||||
|
||||
public class RouteSegmentResult implements StringExternalizable<RouteDataBundle> {
|
||||
// this should be bigger (50-80m) but tests need to be fixed first
|
||||
private static final float DIST_BEARING_DETECT = 5;
|
||||
private final RouteDataObject object;
|
||||
private int startPointIndex;
|
||||
private int endPointIndex;
|
||||
|
@ -444,11 +446,11 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
}
|
||||
|
||||
public float getBearingBegin() {
|
||||
return (float) (object.directionRoute(startPointIndex, startPointIndex < endPointIndex) / Math.PI * 180);
|
||||
return (float) (object.directionRoute(startPointIndex, startPointIndex < endPointIndex, DIST_BEARING_DETECT) / Math.PI * 180);
|
||||
}
|
||||
|
||||
public float getBearing(int point, boolean plus) {
|
||||
return (float) (object.directionRoute(point, plus) / Math.PI * 180);
|
||||
return (float) (object.directionRoute(point, plus, DIST_BEARING_DETECT) / Math.PI * 180);
|
||||
}
|
||||
|
||||
public float getDistance(int point, boolean plus) {
|
||||
|
@ -456,7 +458,7 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
}
|
||||
|
||||
public float getBearingEnd() {
|
||||
return (float) (MapUtils.alignAngleDifference(object.directionRoute(endPointIndex, startPointIndex > endPointIndex) - Math.PI) / Math.PI * 180);
|
||||
return (float) (MapUtils.alignAngleDifference(object.directionRoute(endPointIndex, startPointIndex > endPointIndex, DIST_BEARING_DETECT) - Math.PI) / Math.PI * 180);
|
||||
}
|
||||
|
||||
public void setSegmentTime(float segmentTime) {
|
||||
|
|
|
@ -38,15 +38,13 @@ public class RouteResultPreparationTest {
|
|||
private static RoutePlannerFrontEnd fe;
|
||||
private static RoutingContext ctx;
|
||||
|
||||
private String testName;
|
||||
private LatLon startPoint;
|
||||
private LatLon endPoint;
|
||||
private Map<Long, String> expectedResults;
|
||||
|
||||
private Log log = PlatformUtil.getLog(RouteResultPreparationTest.class);
|
||||
protected Log log = PlatformUtil.getLog(RouteResultPreparationTest.class);
|
||||
|
||||
public RouteResultPreparationTest(String testName, LatLon startPoint, LatLon endPoint, Map<Long, String> expectedResults) {
|
||||
this.testName = testName;
|
||||
this.startPoint = startPoint;
|
||||
this.endPoint = endPoint;
|
||||
this.expectedResults = expectedResults;
|
||||
|
|
Loading…
Reference in a new issue