use of net.osmand.router.TurnType in project Osmand by osmandapp.
the class RouteCalculationResult method addMissingTurnsToRoute.
protected static void addMissingTurnsToRoute(List<Location> locations, List<RouteDirectionInfo> originalDirections, Location start, LatLon end, ApplicationMode mode, Context ctx, boolean leftSide) {
if (locations.isEmpty()) {
return;
}
// speed m/s
float speed = mode.getDefaultSpeed();
int minDistanceForTurn = mode.getMinDistanceForTurn();
List<RouteDirectionInfo> computeDirections = new ArrayList<RouteDirectionInfo>();
int[] listDistance = new int[locations.size()];
listDistance[locations.size() - 1] = 0;
for (int i = locations.size() - 1; i > 0; i--) {
listDistance[i - 1] = (int) Math.round(locations.get(i - 1).distanceTo(locations.get(i)));
listDistance[i - 1] += listDistance[i];
}
int previousLocation = 0;
int prevBearingLocation = 0;
RouteDirectionInfo previousInfo = new RouteDirectionInfo(speed, TurnType.straight());
previousInfo.routePointOffset = 0;
previousInfo.setDescriptionRoute(ctx.getString(R.string.route_head));
computeDirections.add(previousInfo);
int distForTurn = 0;
float previousBearing = 0;
int startTurnPoint = 0;
for (int i = 1; i < locations.size() - 1; i++) {
Location next = locations.get(i + 1);
Location current = locations.get(i);
float bearing = current.bearingTo(next);
// try to get close to current location if possible
while (prevBearingLocation < i - 1) {
if (locations.get(prevBearingLocation + 1).distanceTo(current) > 70) {
prevBearingLocation++;
} else {
break;
}
}
if (distForTurn == 0) {
// measure only after turn
previousBearing = locations.get(prevBearingLocation).bearingTo(current);
startTurnPoint = i;
}
TurnType type = null;
String description = null;
float delta = previousBearing - bearing;
while (delta < 0) {
delta += 360;
}
while (delta > 360) {
delta -= 360;
}
distForTurn += locations.get(i).distanceTo(locations.get(i + 1));
if (i < locations.size() - 1 && distForTurn < minDistanceForTurn) {
// 2) if there is a small gap between roads (turn right and after 4m next turn left) - so the direction head
continue;
}
if (delta > 45 && delta < 315) {
if (delta < 60) {
type = TurnType.valueOf(TurnType.TSLL, leftSide);
description = ctx.getString(R.string.route_tsll);
} else if (delta < 120) {
type = TurnType.valueOf(TurnType.TL, leftSide);
description = ctx.getString(R.string.route_tl);
} else if (delta < 150) {
type = TurnType.valueOf(TurnType.TSHL, leftSide);
description = ctx.getString(R.string.route_tshl);
} else if (delta < 210) {
type = TurnType.valueOf(TurnType.TU, leftSide);
description = ctx.getString(R.string.route_tu);
} else if (delta < 240) {
description = ctx.getString(R.string.route_tshr);
type = TurnType.valueOf(TurnType.TSHR, leftSide);
} else if (delta < 300) {
description = ctx.getString(R.string.route_tr);
type = TurnType.valueOf(TurnType.TR, leftSide);
} else {
description = ctx.getString(R.string.route_tslr);
type = TurnType.valueOf(TurnType.TSLR, leftSide);
}
// calculate for previousRoute
previousInfo.distance = listDistance[previousLocation] - listDistance[i];
type.setTurnAngle(360 - delta);
previousInfo = new RouteDirectionInfo(speed, type);
previousInfo.setDescriptionRoute(description);
previousInfo.routePointOffset = startTurnPoint;
computeDirections.add(previousInfo);
previousLocation = startTurnPoint;
// for bearing using current location
prevBearingLocation = i;
}
// clear dist for turn
distForTurn = 0;
}
previousInfo.distance = listDistance[previousLocation];
if (originalDirections.isEmpty()) {
originalDirections.addAll(computeDirections);
} else {
int currentDirection = 0;
// one more
for (int i = 0; i <= originalDirections.size() && currentDirection < computeDirections.size(); i++) {
while (currentDirection < computeDirections.size()) {
int distanceAfter = 0;
if (i < originalDirections.size()) {
RouteDirectionInfo resInfo = originalDirections.get(i);
int r1 = computeDirections.get(currentDirection).routePointOffset;
int r2 = resInfo.routePointOffset;
distanceAfter = listDistance[resInfo.routePointOffset];
float dist = locations.get(r1).distanceTo(locations.get(r2));
// take into account that move roundabout is special turn that could be very lengthy
if (dist < 100) {
// the same turn duplicate
currentDirection++;
// while cycle
continue;
} else if (computeDirections.get(currentDirection).routePointOffset > resInfo.routePointOffset) {
// check it at the next point
break;
}
}
// add turn because it was missed
RouteDirectionInfo toAdd = computeDirections.get(currentDirection);
if (i > 0) {
// update previous
RouteDirectionInfo previous = originalDirections.get(i - 1);
toAdd.setAverageSpeed(previous.getAverageSpeed());
}
toAdd.distance = listDistance[toAdd.routePointOffset] - distanceAfter;
if (i < originalDirections.size()) {
originalDirections.add(i, toAdd);
} else {
originalDirections.add(toAdd);
}
i++;
currentDirection++;
}
}
}
int sum = 0;
for (int i = originalDirections.size() - 1; i >= 0; i--) {
originalDirections.get(i).afterLeftTime = sum;
sum += originalDirections.get(i).getExpectedTime();
}
}
use of net.osmand.router.TurnType in project Osmand by osmandapp.
the class RouteProvider method parseOsmAndGPXRoute.
private static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> res, GPXFile gpxFile, boolean osmandRouter, boolean leftSide, float defSpeed) {
List<RouteDirectionInfo> directions = null;
if (!osmandRouter) {
for (WptPt pt : gpxFile.getPoints()) {
res.add(createLocation(pt));
}
} else {
for (Track tr : gpxFile.tracks) {
for (TrkSegment ts : tr.segments) {
for (WptPt p : ts.points) {
res.add(createLocation(p));
}
}
}
}
float[] distanceToEnd = new float[res.size()];
for (int i = res.size() - 2; i >= 0; i--) {
distanceToEnd[i] = distanceToEnd[i + 1] + res.get(i).distanceTo(res.get(i + 1));
}
Route route = null;
if (gpxFile.routes.size() > 0) {
route = gpxFile.routes.get(0);
}
RouteDirectionInfo previous = null;
if (route != null && route.points.size() > 0) {
directions = new ArrayList<RouteDirectionInfo>();
Iterator<WptPt> iterator = route.points.iterator();
while (iterator.hasNext()) {
WptPt item = iterator.next();
try {
String stime = item.getExtensionsToRead().get("time");
int time = 0;
if (stime != null) {
time = Integer.parseInt(stime);
}
// $NON-NLS-1$
int offset = Integer.parseInt(item.getExtensionsToRead().get("offset"));
if (directions.size() > 0) {
RouteDirectionInfo last = directions.get(directions.size() - 1);
// update speed using time and idstance
last.setAverageSpeed((distanceToEnd[last.routePointOffset] - distanceToEnd[offset]) / last.getAverageSpeed());
last.distance = (int) Math.round(distanceToEnd[last.routePointOffset] - distanceToEnd[offset]);
}
// save time as a speed because we don't know distance of the route segment
float avgSpeed = time;
if (!iterator.hasNext() && time > 0) {
avgSpeed = distanceToEnd[offset] / time;
}
// $NON-NLS-1$
String stype = item.getExtensionsToRead().get("turn");
TurnType turnType;
if (stype != null) {
turnType = TurnType.fromString(stype.toUpperCase(), leftSide);
} else {
turnType = TurnType.straight();
}
// $NON-NLS-1$
String sturn = item.getExtensionsToRead().get("turn-angle");
if (sturn != null) {
turnType.setTurnAngle((float) Double.parseDouble(sturn));
}
RouteDirectionInfo dirInfo = new RouteDirectionInfo(avgSpeed, turnType);
// $NON-NLS-1$
dirInfo.setDescriptionRoute(item.desc);
dirInfo.routePointOffset = offset;
// Issue #2894
// $NON-NLS-1$
String sref = item.getExtensionsToRead().get("ref");
if (sref != null && !"null".equals(sref)) {
// $NON-NLS-1$
dirInfo.setRef(sref);
}
// $NON-NLS-1$
String sstreetname = item.getExtensionsToRead().get("street-name");
if (sstreetname != null && !"null".equals(sstreetname)) {
// $NON-NLS-1$
dirInfo.setStreetName(sstreetname);
}
// $NON-NLS-1$
String sdest = item.getExtensionsToRead().get("dest");
if (sdest != null && !"null".equals(sdest)) {
// $NON-NLS-1$
dirInfo.setDestinationName(sdest);
}
if (previous != null && TurnType.C != previous.getTurnType().getValue() && !osmandRouter) {
// calculate angle
if (previous.routePointOffset > 0) {
float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
float caz;
if (previous.getTurnType().isRoundAbout() && dirInfo.routePointOffset < res.size() - 1) {
caz = res.get(dirInfo.routePointOffset).bearingTo(res.get(dirInfo.routePointOffset + 1));
} else {
caz = res.get(dirInfo.routePointOffset - 1).bearingTo(res.get(dirInfo.routePointOffset));
}
float angle = caz - paz;
if (angle < 0) {
angle += 360;
} else if (angle > 360) {
angle -= 360;
}
// that magic number helps to fix some errors for turn
angle += 75;
if (previous.getTurnType().getTurnAngle() < 0.5f) {
previous.getTurnType().setTurnAngle(angle);
}
}
}
directions.add(dirInfo);
previous = dirInfo;
} catch (NumberFormatException e) {
// $NON-NLS-1$
log.info("Exception", e);
} catch (IllegalArgumentException e) {
// $NON-NLS-1$
log.info("Exception", e);
}
}
}
if (previous != null && TurnType.C != previous.getTurnType().getValue()) {
// calculate angle
if (previous.routePointOffset > 0 && previous.routePointOffset < res.size() - 1) {
float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset));
float caz = res.get(previous.routePointOffset).bearingTo(res.get(res.size() - 1));
float angle = caz - paz;
if (angle < 0) {
angle += 360;
}
if (previous.getTurnType().getTurnAngle() < 0.5f) {
previous.getTurnType().setTurnAngle(angle);
}
}
}
return directions;
}
use of net.osmand.router.TurnType in project Osmand by osmandapp.
the class NextTurnInfoWidget method updateDistance.
private void updateDistance() {
int deviatePath = turnDrawable.deviatedFromRoute ? deviatedPath : nextTurnDistance;
String ds = OsmAndFormatter.getFormattedDistance(deviatePath, app);
if (ds != null) {
TurnType turnType = getTurnType();
RoutingHelper routingHelper = app.getRoutingHelper();
if ((turnType != null) && (routingHelper != null)) {
setContentDescription(ds + " " + routingHelper.getRoute().toString(turnType, app, false));
} else {
setContentDescription(ds);
}
}
int ls = ds.lastIndexOf(' ');
if (ls == -1) {
setTextNoUpdateVisibility(ds, null);
} else {
setTextNoUpdateVisibility(ds.substring(0, ls), ds.substring(ls + 1));
}
}
use of net.osmand.router.TurnType in project Osmand by osmandapp.
the class RouteInfoWidgetsFactory method createNextNextInfoControl.
public NextTurnInfoWidget createNextNextInfoControl(final Activity activity, final OsmandApplication app, boolean horisontalMini) {
final RoutingHelper routingHelper = app.getRoutingHelper();
final NextTurnInfoWidget nextTurnInfo = new NextTurnInfoWidget(activity, app, horisontalMini) {
NextDirectionInfo calc1 = new NextDirectionInfo();
@Override
public boolean updateInfo(DrawSettings drawSettings) {
boolean followingMode = routingHelper.isFollowingMode() || app.getLocationProvider().getLocationSimulation().isRouteAnimating();
TurnType turnType = null;
boolean deviatedFromRoute = false;
int turnImminent = 0;
int nextTurnDistance = 0;
if (routingHelper != null && routingHelper.isRouteCalculated() && followingMode) {
deviatedFromRoute = routingHelper.isDeviatedFromRoute();
NextDirectionInfo r = routingHelper.getNextRouteDirectionInfo(calc1, true);
if (!deviatedFromRoute) {
if (r != null) {
r = routingHelper.getNextRouteDirectionInfoAfter(r, calc1, true);
}
}
if (r != null && r.distanceTo > 0 && r.directionInfo != null) {
turnType = r.directionInfo.getTurnType();
turnImminent = r.imminent;
nextTurnDistance = r.distanceTo;
}
}
setTurnType(turnType);
setTurnImminent(turnImminent, deviatedFromRoute);
setTurnDistance(nextTurnDistance);
return true;
}
};
nextTurnInfo.setOnClickListener(new View.OnClickListener() {
// int i = 0;
@Override
public void onClick(View v) {
// uncomment to test turn info rendering
// final int l = TurnType.predefinedTypes.length;
// final int exits = 5;
// i++;
// if (i % (l + exits) >= l ) {
// nextTurnInfo.turnType = TurnType.valueOf("EXIT" + (i % (l + exits) - l + 1), true);
// nextTurnInfo.exitOut = (i % (l + exits) - l + 1)+"";
// float a = 180 - (i % (l + exits) - l + 1) * 50;
// nextTurnInfo.turnType.setTurnAngle(a < 0 ? a + 360 : a);
// } else {
// nextTurnInfo.turnType = TurnType.valueOf(TurnType.predefinedTypes[i % (TurnType.predefinedTypes.length + exits)], true);
// nextTurnInfo.exitOut = "";
// }
// nextTurnInfo.turnImminent = (nextTurnInfo.turnImminent + 1) % 3;
// nextTurnInfo.nextTurnDirection = 580;
// TurnPathHelper.calcTurnPath(nextTurnInfo.pathForTurn, nexsweepAngletTurnInfo.turnType,nextTurnInfo.pathTransform);
// showMiniMap = true;
}
});
// initial state
return nextTurnInfo;
}
Aggregations