Fix issue with roundabouts

This commit is contained in:
Victor Shcherb 2015-06-20 22:09:40 +02:00
parent 0d4e7982ab
commit c45b9e6615

View file

@ -197,6 +197,7 @@ public class RouteLayer extends OsmandMapLayer {
for (int i = 0; i < actionPoints.size(); i++) { for (int i = 0; i < actionPoints.size(); i++) {
Location o = actionPoints.get(i); Location o = actionPoints.get(i);
if (o == null) { if (o == null) {
first = true;
canvas.drawPath(pth, actionPaint); canvas.drawPath(pth, actionPaint);
double angleRad = Math.atan2(y - py, x - px); double angleRad = Math.atan2(y - py, x - px);
double angle = (angleRad * 180 / Math.PI) + 90f; double angle = (angleRad * 180 / Math.PI) + 90f;
@ -212,7 +213,6 @@ public class RouteLayer extends OsmandMapLayer {
matrix.postRotate((float) angle, actionArrow.getWidth() / 2, 0); matrix.postRotate((float) angle, actionArrow.getWidth() / 2, 0);
matrix.postTranslate(px + pdx - actionArrow.getWidth() / 2, py + pdy); matrix.postTranslate(px + pdx - actionArrow.getWidth() / 2, py + pdy);
canvas.drawBitmap(actionArrow, matrix, paintIconAction); canvas.drawBitmap(actionArrow, matrix, paintIconAction);
first = true;
} else { } else {
px = x; px = x;
py = y; py = y;
@ -375,87 +375,94 @@ public class RouteLayer extends OsmandMapLayer {
double actionDist = 0; double actionDist = 0;
Location previousAction = null; Location previousAction = null;
actionPoints.clear(); actionPoints.clear();
int prevFinishPoint = -2; int prevFinishPoint = -1;
for (int i = 0; i < routeNodes.size(); i++) { for (int routePoint = 0; routePoint < routeNodes.size(); routePoint++) {
Location ls = routeNodes.get(i); Location loc = routeNodes.get(routePoint);
if(nf != null) { if(nf != null) {
int pnt = nf.routeEndPointOffset == 0 ? nf.routePointOffset : nf.routeEndPointOffset; int pnt = nf.routeEndPointOffset == 0 ? nf.routePointOffset : nf.routeEndPointOffset;
if(pnt < i + cd ) { if(pnt < routePoint + cd ) {
nf = null; nf = null;
} }
} }
while (nf == null && it.hasNext()) { while (nf == null && it.hasNext()) {
nf = it.next(); nf = it.next();
int pnt = nf.routeEndPointOffset == 0 ? nf.routePointOffset : nf.routeEndPointOffset; int pnt = nf.routeEndPointOffset == 0 ? nf.routePointOffset : nf.routeEndPointOffset;
if (pnt < i + cd) { if (pnt < routePoint + cd) {
nf = null; nf = null;
} }
} }
boolean action = nf != null && (nf.routePointOffset == i + cd || boolean action = nf != null && (nf.routePointOffset == routePoint + cd ||
(nf.routePointOffset <= i + cd && i + cd <= nf.routeEndPointOffset)); (nf.routePointOffset <= routePoint + cd && routePoint + cd <= nf.routeEndPointOffset));
if(!action && previousAction == null) { if(!action && previousAction == null) {
// no need to check
continue; continue;
} }
boolean visible = leftLongitude <= ls.getLongitude() && ls.getLongitude() <= rightLongitude && bottomLatitude <= ls.getLatitude() boolean visible = leftLongitude <= loc.getLongitude() && loc.getLongitude() <= rightLongitude && bottomLatitude <= loc.getLatitude()
&& ls.getLatitude() <= topLatitude; && loc.getLatitude() <= topLatitude;
if(!action) { if(action && !visible && previousAction == null) {
if(previousAction != null) { continue;
float dist = ls.distanceTo(previousAction); }
actionDist += dist; if (!action) {
if(actionDist >= DISTANCE_ACTION) { // previousAction != null
actionPoints.add(calculateProjection(1 - (actionDist - DISTANCE_ACTION) / dist, previousAction, ls)); float dist = loc.distanceTo(previousAction);
actionPoints.add(null); actionDist += dist;
prevFinishPoint = i; if (actionDist >= DISTANCE_ACTION) {
previousAction = null; actionPoints.add(calculateProjection(1 - (actionDist - DISTANCE_ACTION) / dist, previousAction, loc));
actionDist = 0; actionPoints.add(null);
} else { prevFinishPoint = routePoint;
actionPoints.add(ls); previousAction = null;
previousAction = ls; actionDist = 0;
} } else {
actionPoints.add(loc);
previousAction = loc;
} }
} else { } else {
// action point // action point
if(visible) { if (previousAction == null) {
// visible action point addPreviousToActionPoints(lastProjection, routeNodes, DISTANCE_ACTION,
if (previousAction == null) { prevFinishPoint, routePoint, loc);
// put some points in front
int ind = actionPoints.size();
Location lprevious = ls;
double dist = 0;
for (int k = i - 1; k >= -1; k--) {
Location l = k == -1 ? lastProjection : routeNodes.get(k);
float loc = lprevious.distanceTo(l);
if(prevFinishPoint == k) {
if(ind >= 2) {
actionPoints.remove(ind - 2);
actionPoints.remove(ind - 2);
}
prevFinishPoint = -2;
break;
}
dist += loc;
if (dist >= DISTANCE_ACTION) {
if(loc > 1) {
actionPoints.add(ind, calculateProjection(1 - (dist - DISTANCE_ACTION) / loc, lprevious, l));
}
break;
} else {
actionPoints.add(ind, l);
lprevious = l;
}
}
}
actionPoints.add(ls);
previousAction = ls;
actionDist = 0;
} }
actionPoints.add(loc);
previousAction = loc;
prevFinishPoint = -1;
actionDist = 0;
} }
} }
if(previousAction != null) { if(previousAction != null) {
actionPoints.add(null); actionPoints.add(null);
} }
} }
private void addPreviousToActionPoints(Location lastProjection, List<Location> routeNodes, double DISTANCE_ACTION,
int prevFinishPoint, int routePoint, Location loc) {
// put some points in front
int ind = actionPoints.size();
Location lprevious = loc;
double dist = 0;
for (int k = routePoint - 1; k >= -1; k--) {
Location l = k == -1 ? lastProjection : routeNodes.get(k);
float locDist = lprevious.distanceTo(l);
dist += locDist;
if (dist >= DISTANCE_ACTION) {
if (locDist > 1) {
actionPoints.add(ind,
calculateProjection(1 - (dist - DISTANCE_ACTION) / locDist, lprevious, l));
}
break;
} else {
actionPoints.add(ind, l);
lprevious = l;
}
if (prevFinishPoint == k) {
if (ind >= 2) {
actionPoints.remove(ind - 2);
actionPoints.remove(ind - 2);
}
break;
}
}
}
private Location calculateProjection(double part, Location lp, Location l) { private Location calculateProjection(double part, Location lp, Location l) {
Location p = new Location(l); Location p = new Location(l);