diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 9c058b6cff..f9026c75a5 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -18,17 +18,11 @@ public class ToDoConstants { // 42. Revise UI (icons/layouts). Support different devices. Add inactive/focus(!) icon versions. // Some icons are not fine (as back menu from map - it is blured). - // TODO: draw EXIT!!!, YOURS (calc turn/angle/time). [other done] - // 56. Add usage of CloudMade API for calculating route (show next turn & distance to it instead of mini map). - // 57. Implement routing information about expected time arriving - // 58. Implement difference about show route/follow route (show travel time/arrival time, show mini map/next turn, etc) - // 59. Show route information (directions/time, ....). Could be shown in context menu route. - // 46. Implement downloading strategy for tiles : select max zoom to download [16,15,14,...] // That means you can save internet because from [16 -> zoom -> 18], [14 -> zoom -> 16 - suitable for speed > 40], ... - - + // 61. Provide route information for YOURS (calclate turns/angle/expected time) + // 60. Audio guidance for routing // 58. Upload/Download zip-index from site & unzip them on phone // 50. Invent opening hours editor in order to edit POI hours better on device // 53. Add progress bars : to internet communication activities [editing/commiting/deleting poi], do not hide edit poi dialog if operation failed @@ -60,6 +54,10 @@ public class ToDoConstants { // BUGS Swing // DONE ANDROID : + // 56. Add usage of CloudMade API for calculating route (show next turn & distance to it instead of mini map). + // 57. Implement routing information about expected time arriving + // 58. Implement difference about show route/follow route (show travel time/arrival time, show mini map/next turn, etc) + // 59. Show route information (directions/time, ....). Now is shown in context menu route (about route) // DONE SWING diff --git a/OsmAnd/src/com/osmand/activities/RouteProvider.java b/OsmAnd/src/com/osmand/activities/RouteProvider.java index 1b59f91453..c3b53387a9 100644 --- a/OsmAnd/src/com/osmand/activities/RouteProvider.java +++ b/OsmAnd/src/com/osmand/activities/RouteProvider.java @@ -250,20 +250,21 @@ public class RouteProvider { if(stime != null){ dirInfo.expectedTime = Integer.parseInt(stime); } - String sturn = getContentFromNode(item, "turn-angle"); //$NON-NLS-1$ - if(sturn != null){ - dirInfo.turnAngle = (float) Double.parseDouble(sturn); - } String stype = getContentFromNode(item, "turn"); //$NON-NLS-1$ if(stype != null){ dirInfo.turnType = TurnType.valueOf(stype.toUpperCase()); } else { - dirInfo.turnType = TurnType.C; + dirInfo.turnType = TurnType.valueOf(TurnType.C); } + String sturn = getContentFromNode(item, "turn-angle"); //$NON-NLS-1$ + if(sturn != null){ + dirInfo.turnType.setTurnAngle((float) Double.parseDouble(sturn)); + } + int offset = Integer.parseInt(getContentFromNode(item, "offset")); //$NON-NLS-1$ dirInfo.routePointOffset = offset; - if(previous != null && previous.turnType != TurnType.C && previous.turnType != null){ + if(previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())){ // calculate angle if(previous.routePointOffset > 0){ float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset)); @@ -273,12 +274,15 @@ public class RouteProvider { } else { caz = res.get(dirInfo.routePointOffset - 1).bearingTo(res.get(dirInfo.routePointOffset)); } - float angle = caz - paz; + float angle = caz - paz + 60f; // that magic number helps to fix some errors if(angle < 0){ angle += 360; + } else if(angle > 360){ + angle -= 360; } - if(previous.turnAngle == 0f){ - previous.turnAngle = angle; + + if(previous.turnType.getTurnAngle() < 0.5f){ + previous.turnType.setTurnAngle(angle); } } } @@ -292,7 +296,7 @@ public class RouteProvider { log.info("Exception", e); //$NON-NLS-1$ } } - if(previous != null && previous.turnType != TurnType.C && previous.turnType != null){ + if(previous != null && previous.turnType != null && !TurnType.C.equals(previous.turnType.getValue())){ // calculate angle if(previous.routePointOffset > 0 && previous.routePointOffset < res.size() - 1){ float paz = res.get(previous.routePointOffset - 1).bearingTo(res.get(previous.routePointOffset)); @@ -301,8 +305,8 @@ public class RouteProvider { if(angle < 0){ angle += 360; } - if(previous.turnAngle == 0f){ - previous.turnAngle = angle; + if(previous.turnType.getTurnAngle() < 0.5f){ + previous.turnType.setTurnAngle(angle); } } } diff --git a/OsmAnd/src/com/osmand/activities/RoutingHelper.java b/OsmAnd/src/com/osmand/activities/RoutingHelper.java index fa5142b6ab..8c90cedb93 100644 --- a/OsmAnd/src/com/osmand/activities/RoutingHelper.java +++ b/OsmAnd/src/com/osmand/activities/RoutingHelper.java @@ -413,39 +413,53 @@ public class RoutingHelper { public static class TurnType { - public static final TurnType C = new TurnType("C"); // continue (go straight) //$NON-NLS-1$ - public static final TurnType TL = new TurnType("TL"); // turn left //$NON-NLS-1$ - public static final TurnType TSLL = new TurnType("TSLL"); // turn slight left //$NON-NLS-1$ - public static final TurnType TSHL = new TurnType("TSHL"); // turn sharp left //$NON-NLS-1$ - public static final TurnType TR = new TurnType("TR"); // turn right //$NON-NLS-1$ - public static final TurnType TSLR = new TurnType("TSLR"); // turn slight right //$NON-NLS-1$ - public static final TurnType TSHR = new TurnType("TSHR"); // turn sharp right //$NON-NLS-1$ - public static final TurnType TU = new TurnType("TU"); // U-turn //$NON-NLS-1$ - public static TurnType[] vals = new TurnType[] {C, TL, TSLL, TSHL, TR, TSLR, TSHR, TU}; + public static final String C = "C"; // continue (go straight) //$NON-NLS-1$ + public static final String TL = "TL"; // turn left //$NON-NLS-1$ + public static final String TSLL = "TSLL"; // turn slight left //$NON-NLS-1$ + public static final String TSHL = "TSHL"; // turn sharp left //$NON-NLS-1$ + public static final String TR = "TR"; // turn right //$NON-NLS-1$ + public static final String TSLR = "TSLR"; // turn slight right //$NON-NLS-1$ + public static final String TSHR = "TSHR"; // turn sharp right //$NON-NLS-1$ + public static final String TU = "TU"; // U-turn //$NON-NLS-1$ + public static String[] predefinedTypes = new String[] {C, TL, TSLL, TSHL, TR, TSLR, TSHR, TU}; public static TurnType valueOf(String s){ - for(TurnType v : vals){ - if(v.getValue().equals(s)){ - return v; + for(String v : predefinedTypes){ + if(v.equals(s)){ + return new TurnType(v); } } if(s!= null && s.startsWith("EXIT")){ //$NON-NLS-1$ - return getExitTurn(Integer.parseInt(s.substring(4))); + return getExitTurn(Integer.parseInt(s.substring(4)), 0); } return null; } private final String value; private int exitOut; + // calculated CW head rotation if previous direction to NORTH + private float turnAngle; - public static TurnType getExitTurn(int out){ - return new TurnType("EXIT", out); //$NON-NLS-1$ + public static TurnType getExitTurn(int out, float angle){ + TurnType r = new TurnType("EXIT", out); //$NON-NLS-1$ + r.setTurnAngle(angle); + return r; } private TurnType(String value, int exitOut){ this.value = value; this.exitOut = exitOut; } + + public float getTurnAngle() { + return turnAngle; + } + + public void setTurnAngle(float turnAngle) { + this.turnAngle = turnAngle; + } + + private TurnType(String value){ this.value = value; } @@ -463,7 +477,6 @@ public class RoutingHelper { public static class RouteDirectionInfo { public String descriptionRoute = ""; //$NON-NLS-1$ public int expectedTime; - public float turnAngle; // calculated CW head rotation if previous direction to NORTH public TurnType turnType; public int routePointOffset; // calculated vars diff --git a/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java b/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java index 8540a84736..4bfe9d9f32 100644 --- a/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java +++ b/OsmAnd/src/com/osmand/activities/ShowRouteInfoActivity.java @@ -60,7 +60,7 @@ public class ShowRouteInfoActivity extends ListActivity { } public void onListItemClick(ListView parent, View v, int position, long id) { - RouteDirectionInfo item = ((RouteInfoAdapter)getListAdapter()).getItem(position); + RouteDirectionInfo item = ((RouteInfoAdapter)getListAdapter()).getItem(position - 1); RoutingHelper inst = RoutingHelper.getInstance(this); Location loc = inst.getLocationFromRouteDirection(item); if(loc != null){ diff --git a/OsmAnd/src/com/osmand/views/MapInfoLayer.java b/OsmAnd/src/com/osmand/views/MapInfoLayer.java index ab86bbdb0b..335fc80210 100644 --- a/OsmAnd/src/com/osmand/views/MapInfoLayer.java +++ b/OsmAnd/src/com/osmand/views/MapInfoLayer.java @@ -10,6 +10,7 @@ import android.graphics.RectF; import android.graphics.Paint.Style; import android.location.Location; import android.text.format.DateFormat; +import android.util.FloatMath; import com.osmand.Algoritms; import com.osmand.Messages; @@ -61,7 +62,8 @@ public class MapInfoLayer implements OsmandMapLayer { private int centerMiniRouteX; private float scaleMiniRoute; private Matrix pathTransform; - private TurnType cachedTurnType; + private TurnType cachedTurnType = null; + private String cachedExitOut = null; public MapInfoLayer(MapActivity map, RouteLayer layer){ @@ -217,7 +219,7 @@ public class MapInfoLayer implements OsmandMapLayer { private void drawRouteInfo(Canvas canvas) { - if(routeLayer != null && routeLayer.getHelper().isRouterEnabled() && !routeLayer.getHelper().isFollowingMode() ){ + if(routeLayer != null && routeLayer.getHelper().isRouterEnabled() && routeLayer.getHelper().isFollowingMode() ){ int d = routeLayer.getHelper().getDistanceToNextRouteDirection(); if (showMiniMap || d == 0) { if (!routeLayer.getPath().isEmpty()) { @@ -240,9 +242,17 @@ public class MapInfoLayer implements OsmandMapLayer { if (!Algoritms.objectEquals(cachedTurnType, next.turnType)) { cachedTurnType = next.turnType; calcTurnPath(pathForTurn, cachedTurnType, pathTransform); + if(cachedTurnType.getExitOut() > 0){ + cachedExitOut = cachedTurnType.getExitOut()+""; //$NON-NLS-1$ + } else { + cachedExitOut = null; + } } canvas.drawPath(pathForTurn, paintRouteDirection); canvas.drawPath(pathForTurn, paintBlack); + if(cachedExitOut != null){ + canvas.drawText(cachedExitOut, boundsForMiniRoute.centerX() - 6, boundsForMiniRoute.centerY() - 9, paintBlack); + } canvas.drawText(MapUtils.getFormattedDistance(d), boundsForMiniRoute.left + 10, boundsForMiniRoute.bottom - 9, paintBlack); } @@ -272,19 +282,13 @@ public class MapInfoLayer implements OsmandMapLayer { canvas.drawText(cachedLeftTimeString, boundsForLeftTime.left + 5, boundsForLeftTime.bottom - 9, paintBlack); } - } else { - // TEST - // TODO remove -// canvas.drawRoundRect(boundsForMiniRoute, 3, 3, paintAlphaGray); -// canvas.drawRoundRect(boundsForMiniRoute, 3, 3, paintBlack); -// canvas.drawPath(pathForTurn, paintRouteDirection); -// canvas.drawPath(pathForTurn, paintBlack); -// canvas.drawText(MapUtils.getFormattedDistance(300), -// boundsForMiniRoute.left + 15, boundsForMiniRoute.bottom - 9, paintBlack); } } public static void calcTurnPath(Path pathForTurn, TurnType turnType, Matrix transform) { + if(turnType == null){ + return; + } pathForTurn.reset(); // draw path 96x96 int c = 48; @@ -295,7 +299,7 @@ public class MapInfoLayer implements OsmandMapLayer { float spartArrowL = (float) ((sarrowL - w / Math.sqrt(2)) / 2); float hpartArrowL = (float) (harrowL - w) / 2; - if (turnType == TurnType.C) { + if (TurnType.C.equals(turnType.getValue())) { int h = 65; pathForTurn.rMoveTo(w / 2, 0); @@ -305,8 +309,8 @@ public class MapInfoLayer implements OsmandMapLayer { pathForTurn.rLineTo(-harrowL / 2, harrowL / 2); pathForTurn.rLineTo(hpartArrowL, 0); pathForTurn.rLineTo(0, h); - } else if (turnType == TurnType.TR || turnType == TurnType.TL) { - int b = turnType == TurnType.TR ? 1 : -1; + } else if (TurnType.TR.equals(turnType.getValue())|| TurnType.TL.equals(turnType.getValue())) { + int b = TurnType.TR.equals(turnType.getValue())? 1 : -1; int h = 36; float quadShiftX = 22; float quadShiftY = 22; @@ -320,8 +324,8 @@ public class MapInfoLayer implements OsmandMapLayer { pathForTurn.rLineTo(0, hpartArrowL); pathForTurn.rQuadTo(-b * (quadShiftX + w), 0, -b * (quadShiftX + w), quadShiftY + w); pathForTurn.rLineTo(0, h); - } else if (turnType == TurnType.TSLR || turnType == TurnType.TSLL) { - int b = turnType == TurnType.TSLR ? 1 : -1; + } else if (TurnType.TSLR.equals(turnType.getValue()) || TurnType.TSLL.equals(turnType.getValue())) { + int b = TurnType.TSLR.equals(turnType.getValue()) ? 1 : -1; int h = 40; int quadShiftY = 22; float quadShiftX = (float) (quadShiftY / (1 + Math.sqrt(2))); @@ -337,8 +341,8 @@ public class MapInfoLayer implements OsmandMapLayer { pathForTurn.rLineTo(b * spartArrowL, spartArrowL); pathForTurn.rQuadTo(b * nQuadShiftX, -nQuadShiftX, b * nQuadShiftX, nQuadShifty); pathForTurn.rLineTo(0, h); - } else if (turnType == TurnType.TSHR || turnType == TurnType.TSHL) { - int b = turnType == TurnType.TSHR ? 1 : -1; + } else if (TurnType.TSHR.equals(turnType.getValue()) || TurnType.TSHL.equals(turnType.getValue())) { + int b = TurnType.TSHR.equals(turnType.getValue()) ? 1 : -1; int h = 45; float quadShiftX = 22; float quadShiftY = -(float) (quadShiftX / (1 + Math.sqrt(2))); @@ -354,7 +358,7 @@ public class MapInfoLayer implements OsmandMapLayer { pathForTurn.rLineTo(-b * spartArrowL, spartArrowL); pathForTurn.rCubicTo(b * nQuadShiftX / 2, nQuadShiftX / 2, b * nQuadShiftX, nQuadShiftX / 2, b * nQuadShiftX, nQuadShiftY); pathForTurn.rLineTo(0, h); - } else if(turnType == TurnType.TU){ + } else if(TurnType.TU.equals(turnType.getValue())) { int h = 54; float quadShiftX = 13; float quadShiftY = 13; @@ -370,8 +374,39 @@ public class MapInfoLayer implements OsmandMapLayer { pathForTurn.rQuadTo(0, -quadShiftX, quadShiftX, -quadShiftY); pathForTurn.rQuadTo(quadShiftX, 0, quadShiftX, quadShiftY); pathForTurn.rLineTo(0, h); - } else if(turnType != null && turnType.isExit()){ - // TODO !!! & check how it works + } else if (turnType != null && turnType.isExit()) { + float t = turnType.getTurnAngle(); + if (t >= 170 && t < 220) { + t = 220; + } else if (t > 160 && t < 170) { + t = 160; + } + float sweepAngle = (t - 360) - 180; + if (sweepAngle < -360) { + sweepAngle += 360; + } + float r1 = 32f; + float r2 = 24f; + float angleToRot = 0.3f; + + pathForTurn.moveTo(48, 48 + r1 + 8); + pathForTurn.lineTo(48, 48 + r1); + RectF r = new RectF(48 - r1, 48 - r1, 48 + r1, 48 + r1); + pathForTurn.arcTo(r, 90, sweepAngle); + float angleRad = (float) ((180 + sweepAngle)*Math.PI/180f); + + pathForTurn.lineTo(48 + (r1 + 4) * FloatMath.sin(angleRad), 48 - (r1 + 4) * FloatMath.cos(angleRad)); + pathForTurn.lineTo(48 + (r1 + 6) * FloatMath.sin(angleRad + angleToRot/2), 48 - (r1 + 6) * FloatMath.cos(angleRad + angleToRot/2)); + pathForTurn.lineTo(48 + (r1 + 12) * FloatMath.sin(angleRad - angleToRot/2), 48 - (r1 + 12) * FloatMath.cos(angleRad - angleToRot/2)); + pathForTurn.lineTo(48 + (r1 + 6) * FloatMath.sin(angleRad - 3*angleToRot/2), 48 - (r1 + 6) * FloatMath.cos(angleRad - 3*angleToRot/2)); + pathForTurn.lineTo(48 + (r1 + 4) * FloatMath.sin(angleRad - angleToRot), 48 - (r1 + 4) * FloatMath.cos(angleRad - angleToRot)); + pathForTurn.lineTo(48 + r2 * FloatMath.sin(angleRad - angleToRot), 48 - r2 * FloatMath.cos(angleRad - angleToRot)); + + r.set(48 - r2, 48 - r2, 48 + r2, 48 + r2); + pathForTurn.arcTo(r, 360 + sweepAngle + 90, -sweepAngle); + pathForTurn.lineTo(40, 48 + r2); + pathForTurn.lineTo(40, 48 + r1 + 8); + pathForTurn.close(); } pathForTurn.close(); pathForTurn.transform(transform);