diff --git a/OsmAnd/res/layout-land/map_hud_top.xml b/OsmAnd/res/layout-land/map_hud_top.xml
index 10f5000b98..dcb81661ae 100644
--- a/OsmAnd/res/layout-land/map_hud_top.xml
+++ b/OsmAnd/res/layout-land/map_hud_top.xml
@@ -563,7 +563,11 @@
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/widget_turn_lane_border"
+ android:layout_marginRight="@dimen/widget_turn_lane_border"
+ android:layout_marginTop="@dimen/widget_turn_lane_border"/>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/widget_turn_lane_border"
+ android:layout_marginRight="@dimen/widget_turn_lane_border"
+ android:layout_marginTop="@dimen/widget_turn_lane_border"/>
+ 36dp
+ 3dp
+ 2dp
+ 16dp
+
48dp
36dp
diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml
index 1d152d6a89..fc0f61819f 100644
--- a/OsmAnd/res/values/strings.xml
+++ b/OsmAnd/res/values/strings.xml
@@ -140,13 +140,13 @@
Reload
Reload tiles to see up to date data.
Tile cache
- Wrong user name!
+ Wrong username!
To
From
- View images added in a certain period.
- Dates
- Type user name
- View images added by a certain user.
+ View only images added
+ Date
+ Type username
+ View only images added by
Username
You can filter images by submitter or by date. Filters apply only for closeup zoom.
Radius ruler
@@ -1985,7 +1985,7 @@
Visibility
Tags
Description
- Please specify OSM user name and password to upload GPX files.
+ Please specify OSM username and password to upload GPX files.
Support
Support new features
Donate to see new features implemented in the application.
@@ -2096,7 +2096,7 @@
General
Configure display and common settings for the application.
Global app settings
- Your OSM user name
+ Your OSM username
Needed for openstreetmap.org submissions.
Your OSM password
Background mode
diff --git a/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java b/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java
index 2cca347210..b9df08a3ba 100644
--- a/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java
+++ b/OsmAnd/src/net/osmand/plus/views/TurnPathHelper.java
@@ -1,12 +1,6 @@
package net.osmand.plus.views;
-import java.util.Map;
-
-import net.osmand.plus.R;
-import net.osmand.router.TurnType;
import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -18,6 +12,12 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+
+import net.osmand.plus.R;
+import net.osmand.router.TurnType;
+
+import java.util.Map;
public class TurnPathHelper {
@@ -134,8 +134,9 @@ public class TurnPathHelper {
}
// 72x72
- public static void calcTurnPath(Path pathForTurn, Path outlay, TurnType turnType,
- Matrix transform, PointF center, boolean mini) {
+ public static void calcTurnPath(Path pathForTurn, Path outlay, TurnType turnType,
+ Matrix transform, PointF center, boolean mini,
+ boolean shortArrow, boolean noOverlap, boolean smallArrow) {
if(turnType == null){
return;
}
@@ -146,13 +147,16 @@ public class TurnPathHelper {
int ha = 72;
int wa = 72;
int lowMargin = 6;
- if (TurnType.C == turnType.getValue()) {
- TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
+ float scaleTriangle = smallArrow ? 1.f : 1.5f;
+ int turnTypeId = turnType.getValue();
+
+ if (TurnType.C == turnTypeId) {
+ TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, scaleTriangle);
pathForTurn.moveTo(wa / 2 + tv.widthStepIn / 2, ha - lowMargin);
tv.drawTriangle(pathForTurn);
pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2, ha - lowMargin);
- } else if (TurnType.OFFR == turnType.getValue()){
- TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
+ } else if (TurnType.OFFR == turnTypeId){
+ TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, scaleTriangle);
float rightX = wa / 2 + tv.widthStepIn / 2;
float leftX = wa / 2 - tv.widthStepIn / 2;
int step = 7;
@@ -178,14 +182,15 @@ public class TurnPathHelper {
pathForTurn.moveTo(rightX, ha - 4 * lowMargin - 3 * step);
tv.drawTriangle(pathForTurn);
pathForTurn.lineTo(leftX, ha - 4 * lowMargin - 3 * step);
- } else if (TurnType.TR == turnType.getValue()|| TurnType.TL == turnType.getValue()) {
- int b = TurnType.TR == turnType.getValue()? 1 : -1;
- TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 90 : -90, 0, wa, ha / 2, 1.5f);
- float centerCurveX = wa / 2 + b * 4;
- float centerCurveY = ha / 2;
+ } else if (TurnType.TR == turnTypeId|| TurnType.TL == turnTypeId) {
+ int b = TurnType.TR == turnTypeId? 1 : -1;
+ TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 90 : -90, 0, wa, (shortArrow ? ha : ha / 2), scaleTriangle);
// calculated
- float h = centerCurveY - lowMargin;
- float r = tv.cy - tv.widthStepIn / 2;
+ float rDiv = (shortArrow ? 4 : noOverlap ? 1 : 2);
+ float r = (tv.cy - tv.widthStepIn / 2) / rDiv;
+ float centerCurveX = wa / 2 + b * (noOverlap ? 4 : r + tv.widthStepIn / 2);
+ float centerCurveY = ha / 2 + (shortArrow ? r + tv.widthStepIn / 2 : !noOverlap ? -r : 0);
+ float h = ha - centerCurveY - lowMargin;
float centerLineX = centerCurveX - b * (r + tv.widthStepIn / 2);
RectF innerOval = new RectF(centerCurveX - r, centerCurveY - r, centerCurveX + r, centerCurveY + r);
RectF outerOval = new RectF(innerOval);
@@ -197,13 +202,15 @@ public class TurnPathHelper {
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90, - b *90);
pathForTurn.rLineTo(0, h);
- } else if (TurnType.TSLR == turnType.getValue() || TurnType.TSLL == turnType.getValue()) {
- int b = TurnType.TSLR == turnType.getValue() ? 1 : -1;
- TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 45 : -45, 0, wa, ha, 1.5f);
- tv.cx -= b * 7;
- float centerBottomX = wa / 2 - b * 6;
- float centerCurveY = ha / 2 + 8;
- float centerCurveX = centerBottomX + b * (wa / 2);
+ } else if (TurnType.TSLR == turnTypeId || TurnType.TSLL == turnTypeId) {
+ int b = TurnType.TSLR == turnTypeId ? 1 : -1;
+ float angle = shortArrow ? 65 : 45;
+ TurnVariables tv = new TurnVariables(b != 1, b == 1 ? angle : -angle, 0, wa, ha, scaleTriangle);
+ tv.cx -= b * (shortArrow ? 0 : 7);
+ tv.cy += shortArrow ? 12 : 0;
+ float centerBottomX = wa / 2 - (noOverlap ? b * 6 : 0);
+ float centerCurveY = shortArrow ? ha - 6 : ha / 2 + 8;
+ float centerCurveX = centerBottomX + b * (wa / 2 - (shortArrow && noOverlap ? 6 : 0));
// calculated
float rx1 = Math.abs(centerCurveX - centerBottomX) - tv.widthStepIn / 2;
float rx2 = Math.abs(centerCurveX - centerBottomX) + tv.widthStepIn / 2;
@@ -222,16 +229,20 @@ public class TurnPathHelper {
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90 - b * (90 - (ellipseAngle2)), -b * (ellipseAngle2));
pathForTurn.lineTo(centerBottomX - b * tv.widthStepIn / 2, ha - lowMargin);
- } else if (TurnType.TSHR == turnType.getValue() || TurnType.TSHL == turnType.getValue()) {
- int b = TurnType.TSHR == turnType.getValue() ? 1 : -1;
- float centerCircleY = ha / 4;
- float centerCircleX = wa / 2 - b * (wa / 5);
- TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 135 : -135, 0, wa, ha, 1.5f);
+ } else if (TurnType.TSHR == turnTypeId || TurnType.TSHL == turnTypeId) {
+ int b = TurnType.TSHR == turnTypeId ? 1 : -1;
+ float centerCircleY = shortArrow ? ha / 2 : ha / 4;
+ float centerCircleX = wa / 2 - (noOverlap ? b * (wa / 5) : 0);
+ TurnVariables tv = new TurnVariables(b != 1, b == 1 ? 135 : -135, 0, wa, ha, scaleTriangle);
// calculated
float angle = 45;
- float r = tv.widthStepIn / 2;
+ float r = tv.widthStepIn / 2;
tv.cx = centerCircleX;
tv.cy = centerCircleY;
+ if (shortArrow) {
+ tv.cx -= b * 2;
+ tv.cy -= 2;
+ }
RectF innerOval = new RectF(centerCircleX - r, centerCircleY - r, centerCircleX + r, centerCircleY + r);
pathForTurn.moveTo(centerCircleX + b * tv.widthStepIn / 2, ha - lowMargin);
pathForTurn.lineTo(centerCircleX + b * tv.widthStepIn / 2, (float) (centerCircleY +
@@ -241,16 +252,16 @@ public class TurnPathHelper {
// pathForTurn.lineTo(centerCircleX - b * tv.widthStepIn / 2, (float) (centerCircleY - 2 *r));
pathForTurn.arcTo(innerOval, -90 + b * angle, - b * (90 + angle));
pathForTurn.lineTo(centerCircleX - b * tv.widthStepIn / 2, ha - lowMargin);
- } else if(TurnType.TU == turnType.getValue() || TurnType.TRU == turnType.getValue()) {
- int b = TurnType.TU == turnType.getValue() ? -1 : 1;
- float radius = 16;
- float centerRadiusY = ha / 2 - 10;
- float extraMarginBottom = 5;
- TurnVariables tv = new TurnVariables(b != 1, 180, 0, wa, ha, 1.5f);
+ } else if(TurnType.TU == turnTypeId || TurnType.TRU == turnTypeId) {
+ int b = TurnType.TU == turnTypeId ? -1 : 1;
+ float radius = shortArrow ? 10 : 16;
+ float centerRadiusY = ha / 2 + (shortArrow ? 10 : -10);
+ float extraMarginBottom = shortArrow ? 0 : 5;
+ TurnVariables tv = new TurnVariables(b != 1, 180, 0, wa, ha, scaleTriangle);
// calculated
- float centerRadiusX = wa / 2;
+ float centerRadiusX = wa / 2 + (shortArrow ? b * radius : 0);
tv.cx = centerRadiusX + b * radius;
- tv.cy = centerRadiusY - extraMarginBottom;
+ tv.cy = shortArrow ? ha - centerRadiusY : centerRadiusY - extraMarginBottom;
lowMargin += extraMarginBottom;
tv.rot = 0;
@@ -265,29 +276,31 @@ public class TurnPathHelper {
tv.drawTriangle(pathForTurn);
pathForTurn.arcTo(outerOval, -90 + b * 90, -b * 180);
pathForTurn.lineTo(centerRadiusX - b * (radius + tv.widthStepIn / 2), ha - lowMargin);
- } else if (TurnType.KL == turnType.getValue() || TurnType.KR == turnType.getValue()) {
- int b = TurnType.KR == turnType.getValue()? 1 : -1;
- float shiftX = 8;
+ } else if (TurnType.KL == turnTypeId || TurnType.KR == turnTypeId) {
+ int b = TurnType.KR == turnTypeId ? 1 : -1;
+ float shiftX = shortArrow ? 12 : 8;
float firstH = 18;
float secondH = 20;
- TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, 1.5f);
+ TurnVariables tv = new TurnVariables(false, 0, 0, wa, ha, scaleTriangle);
// calculated
- tv.cx += b * shiftX;
- pathForTurn.moveTo(wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin);
- pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH);
- // pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
+ tv.cx += b * shiftX * (noOverlap ? 1 : 2);
+ float dx = b * shiftX * (noOverlap ? 1 : 2);
+ float mdx = -b * shiftX * (noOverlap ? 1 : 0);
+ pathForTurn.moveTo(wa / 2 + tv.widthStepIn / 2 + mdx, ha - lowMargin);
+ pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 + mdx, ha - lowMargin - firstH);
+ // pathForTurn.lineTo(wa / 2 + tv.widthStepIn / 2 + dx, ha - lowMargin - firstH - secondH);
pathForTurn.cubicTo(
- wa / 2 + tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH - secondH / 2 + b * 3,
- wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH / 2 + b * 3,
- wa / 2 + tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
+ wa / 2 + tv.widthStepIn / 2 + mdx, ha - lowMargin - firstH - secondH / 2 + b * 3,
+ wa / 2 + tv.widthStepIn / 2 + dx, ha - lowMargin - firstH - secondH / 2 + b * 3,
+ wa / 2 + tv.widthStepIn / 2 + dx, ha - lowMargin - firstH - secondH);
tv.drawTriangle(pathForTurn);
- pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH);
+ pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 + dx, ha - lowMargin - firstH - secondH);
pathForTurn.cubicTo(
- wa / 2 - tv.widthStepIn / 2 + b * shiftX, ha - lowMargin - firstH - secondH / 2 - b * 2,
- wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH - secondH / 2 - b * 2,
- wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH );
-// pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin - firstH);
- pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 - b * shiftX, ha - lowMargin);
+ wa / 2 - tv.widthStepIn / 2 + dx, ha - lowMargin - firstH - secondH / 2 - b * 2,
+ wa / 2 - tv.widthStepIn / 2 + mdx, ha - lowMargin - firstH - secondH / 2 - b * 2,
+ wa / 2 - tv.widthStepIn / 2 + mdx, ha - lowMargin - firstH );
+// pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 + mdx, ha - lowMargin - firstH);
+ pathForTurn.lineTo(wa / 2 - tv.widthStepIn / 2 + mdx, ha - lowMargin);
} else if(turnType != null && turnType.isRoundAbout() ) {
int out = turnType.getExitOut();
boolean leftSide = turnType.isLeftSide();
@@ -477,7 +490,8 @@ public class TurnPathHelper {
paintRouteDirectionOutlay.setStyle(Style.STROKE);
paintRouteDirectionOutlay.setColor(Color.BLACK);
paintRouteDirectionOutlay.setAntiAlias(true);
- TurnPathHelper.calcTurnPath(dp, dpOutlay, TurnType.straight(), null, null, mini);
+ TurnPathHelper.calcTurnPath(dp, dpOutlay, TurnType.straight(), null, null, mini,
+ false, true, false);
}
@Override
@@ -489,12 +503,13 @@ public class TurnPathHelper {
}
public void setRouteType(TurnType t){
- TurnPathHelper.calcTurnPath(p, pOutlay, t, null, null, mini);
+ TurnPathHelper.calcTurnPath(p, pOutlay, t, null, null, mini,
+ false, true, false);
onBoundsChange(getBounds());
}
@Override
- public void draw(Canvas canvas) {
+ public void draw(@NonNull Canvas canvas) {
canvas.drawPath(dpOutlay, paintRouteDirectionOutlay);
canvas.drawPath(dp, paintRouteDirection);
}
@@ -519,113 +534,42 @@ public class TurnPathHelper {
public static class TurnResource {
- boolean flip;
- int resourceId;
- public TurnResource(){}
+ int turnType;
+ boolean shortArrow;
+ boolean noOverlap;
+ boolean leftSide;
- public TurnResource(int resourceId, boolean value) {
- this.resourceId = resourceId;
- this.flip = value;
+ TurnResource() {}
+
+ TurnResource(int turnType, boolean shortArrow, boolean noOverlap, boolean leftSide) {
+ this.turnType = turnType == 0 ? 1 : turnType;
+ this.shortArrow = shortArrow;
+ this.noOverlap = noOverlap;
+ this.leftSide = leftSide;
}
@Override
- public boolean equals(Object o) {
- return super.equals(o);
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ TurnResource other = (TurnResource) obj;
+ return other.turnType == turnType && other.shortArrow == shortArrow
+ && other.noOverlap == noOverlap && other.leftSide == leftSide;
}
@Override
public int hashCode() {
- return resourceId * (flip ? -1 : 1);
+ return (turnType + (noOverlap ? 100 : 1) + (shortArrow ? 1000 : 1)) * (leftSide ? -1 : 1);
}
}
- private static TurnResource getTallArrow(int tt, boolean nooverlap){
-
- TurnResource result = new TurnResource();
-
- switch (tt){
- case TurnType.C:
- result.resourceId = R.drawable.map_turn_forward_small;
- break;
- case TurnType.TR:
- case TurnType.TL:
- result.resourceId = nooverlap ? R.drawable.map_turn_right_small : R.drawable.map_turn_right2_small;
- break;
- case TurnType.KR:
- case TurnType.KL:
- result.resourceId = R.drawable.map_turn_keep_right_small;
- break;
- case TurnType.TSLR:
- case TurnType.TSLL:
- result.resourceId = R.drawable.map_turn_slight_right_small;
- break;
- case TurnType.TSHR:
- case TurnType.TSHL:
- result.resourceId = R.drawable.map_turn_sharp_right_small;
- break;
- case TurnType.TRU:
- case TurnType.TU:
- result.resourceId = R.drawable.map_turn_uturn_right_small;
- break;
- default:
- result.resourceId = R.drawable.map_turn_forward_small;
- break;
- }
-
- if(tt == TurnType.TL || tt == TurnType.KL || tt == TurnType.TSLL
- || tt == TurnType.TSHL || tt == TurnType.TU){
- result.flip = true;
- }
-
- return result;
-
- }
-
- private static TurnResource getShortArrow(int tt){
-
- TurnResource result = new TurnResource();
-
- switch (tt) {
- case TurnType.C:
- result.resourceId = R.drawable.map_turn_forward_small;
- break;
- case TurnType.TR:
- case TurnType.TL:
- result.resourceId = R.drawable.map_turn_forward_right_turn_small;
- break;
- case TurnType.KR:
- case TurnType.KL:
- result.resourceId = R.drawable.map_turn_forward_keep_right_small;
- break;
- case TurnType.TSLR:
- case TurnType.TSLL:
- result.resourceId = R.drawable.map_turn_forward_slight_right_turn_small;
- break;
- case TurnType.TSHR:
- case TurnType.TSHL:
- result.resourceId = R.drawable.map_turn_forward_turn_sharp_small;
- break;
- case TurnType.TRU:
- case TurnType.TU:
- result.resourceId = R.drawable.map_turn_forward_uturn_right_small;
- break;
- default:
- result.resourceId = R.drawable.map_turn_forward_small;
- break;
- }
-
- if(tt == TurnType.TL || tt == TurnType.KL || tt == TurnType.TSLL
- || tt == TurnType.TSHL || tt == TurnType.TU){
- result.flip = true;
- }
-
- return result;
-
- }
-
- public static Bitmap getBitmapFromTurnType(Resources res, Map cache, int firstTurn,
- int secondTurn, int thirdTurn, int turnIndex, float coef, boolean leftSide) {
+ public static Path getPathFromTurnType(Resources res, Map cache, int firstTurn,
+ int secondTurn, int thirdTurn, int turnIndex, float coef, boolean leftSide, boolean smallArrow) {
int firstTurnType = TurnType.valueOf(firstTurn, leftSide).getValue();
int secondTurnType = TurnType.valueOf(secondTurn, leftSide).getValue();
@@ -635,14 +579,14 @@ public class TurnPathHelper {
if (turnIndex == FIRST_TURN) {
if (secondTurnType == 0) {
- turnResource = getTallArrow(firstTurnType, true);
+ turnResource = new TurnResource(firstTurnType, false, false, leftSide);
} else if (secondTurnType == TurnType.C || thirdTurnType == TurnType.C) {
- turnResource = getShortArrow(firstTurnType);
+ turnResource = new TurnResource(firstTurnType, true, false, leftSide);
} else {
if (firstTurnType == TurnType.TU || firstTurnType == TurnType.TRU) {
- turnResource = getShortArrow(firstTurnType);
+ turnResource = new TurnResource(firstTurnType, true, false, leftSide);
} else {
- turnResource = getTallArrow(firstTurnType, false);
+ turnResource = new TurnResource(firstTurnType, false, false, leftSide);
}
}
} else if (turnIndex == SECOND_TURN) {
@@ -652,9 +596,9 @@ public class TurnPathHelper {
turnResource = null;
} else if (firstTurnType == TurnType.C || thirdTurnType == TurnType.C) {
// get the small one
- turnResource = getShortArrow(secondTurnType);
+ turnResource = new TurnResource(secondTurnType, true, false, leftSide);
} else {
- turnResource = getTallArrow(secondTurnType, false);
+ turnResource = new TurnResource(secondTurnType, false, false, leftSide);
}
} else if (turnIndex == THIRD_TURN) {
if ((TurnType.isLeftTurn(firstTurnType) || TurnType.isLeftTurn(secondTurnType)) && TurnType.isLeftTurn(thirdTurnType)) {
@@ -662,18 +606,18 @@ public class TurnPathHelper {
} else if ((TurnType.isRightTurn(firstTurnType) || TurnType.isRightTurn(secondTurnType)) && TurnType.isRightTurn(thirdTurnType)) {
turnResource = null;
} else {
- turnResource = getShortArrow(thirdTurnType);
+ turnResource = new TurnResource(thirdTurnType, true, false, leftSide);
}
}
if (turnResource == null) {
return null;
}
- Bitmap b = cache.get(turnResource);
- if (b == null) {
- b = turnResource.flip ? getFlippedBitmap(res, turnResource.resourceId) : BitmapFactory.decodeResource(res,
- turnResource.resourceId);
- cache.put(turnResource, b);
+ Path p = cache.get(turnResource);
+ if (p == null) {
+ int size = res.getDimensionPixelSize(R.dimen.widget_turn_lane_size);
+ p = getPathFromTurnResource(turnResource, size, smallArrow);
+ cache.put(turnResource, p);
}
// Maybe redundant scaling
@@ -682,27 +626,17 @@ public class TurnPathHelper {
* bRatio); int hq = Math.round(s); b = Bitmap.createScaledBitmap(b, wq, hq, false);
*/
- return b;
+ return p;
}
- public static Bitmap getFlippedBitmap(Resources res, int resId){
-
- BitmapFactory.Options opt = new BitmapFactory.Options();
- opt.inJustDecodeBounds = true;
- //Below line is necessary to fill in opt.outWidth, opt.outHeight
- Bitmap b = BitmapFactory.decodeResource(res, resId, opt);
-
- b = Bitmap.createBitmap(opt.outWidth, opt.outHeight, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(b);
-
- Matrix flipHorizontalMatrix = new Matrix();
- flipHorizontalMatrix.setScale(-1, 1);
- flipHorizontalMatrix.postTranslate(b.getWidth(), 0);
-
- Bitmap bb = BitmapFactory.decodeResource(res, resId);
- canvas.drawBitmap(bb, flipHorizontalMatrix, null);
-
- return b;
+ private static Path getPathFromTurnResource(TurnResource turnResource, int size, boolean smallArrow) {
+ float coef = size / 72.f;
+ Path p = new Path();
+ Matrix matrix = new Matrix();
+ matrix.postScale(coef, coef);
+ calcTurnPath(p, null, TurnType.valueOf(turnResource.turnType, turnResource.leftSide),
+ matrix, null, false, turnResource.shortArrow, turnResource.noOverlap, smallArrow);
+ return p;
}
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java
index e18ed456e1..20b4fb69c3 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/NextTurnInfoWidget.java
@@ -1,13 +1,5 @@
package net.osmand.plus.views.mapwidgets;
-import net.osmand.plus.OsmAndFormatter;
-import net.osmand.plus.OsmandApplication;
-import net.osmand.plus.R;
-import net.osmand.plus.routing.RoutingHelper;
-import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
-import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopTextView;
-import net.osmand.plus.views.TurnPathHelper;
-import net.osmand.router.TurnType;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
@@ -22,8 +14,17 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorRes;
+import android.support.annotation.NonNull;
import android.text.TextPaint;
+import net.osmand.plus.OsmAndFormatter;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+import net.osmand.plus.routing.RoutingHelper;
+import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
+import net.osmand.plus.views.TurnPathHelper;
+import net.osmand.router.TurnType;
+
public class NextTurnInfoWidget extends TextInfoWidget {
@@ -185,7 +186,7 @@ public class NextTurnInfoWidget extends TextInfoWidget {
}
@Override
- public void draw(Canvas canvas) {
+ public void draw(@NonNull Canvas canvas) {
/// small indent
// canvas.translate(0, 3 * scaleCoefficient);
canvas.drawPath(pathForTurnOutlay, paintBlack);
@@ -222,7 +223,8 @@ public class NextTurnInfoWidget extends TextInfoWidget {
public boolean setTurnType(TurnType turnType) {
if(turnType != this.turnType) {
this.turnType = turnType;
- TurnPathHelper.calcTurnPath(pathForTurn, pathForTurnOutlay, turnType, null, centerText, mini);
+ TurnPathHelper.calcTurnPath(pathForTurn, pathForTurnOutlay, turnType, null,
+ centerText, mini, false, true, false);
onBoundsChange(getBounds());
return true;
}
diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java
index f8e5c1214e..d4a02fac67 100644
--- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java
+++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/RouteInfoWidgetsFactory.java
@@ -5,28 +5,25 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.BlurMaskFilter.Blur;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
-import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.hardware.GeomagneticField;
import android.os.BatteryManager;
+import android.support.annotation.NonNull;
import android.text.format.DateFormat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
@@ -54,12 +51,12 @@ import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.TurnPathHelper;
+import net.osmand.plus.views.TurnPathHelper.TurnResource;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.WidgetState;
import net.osmand.router.RouteResultPreparation;
import net.osmand.router.TurnType;
import net.osmand.util.Algorithms;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -726,26 +723,6 @@ public class RouteInfoWidgetsFactory {
!showRelativeBearing.get() ? bearingNightResId : relativeBearingNightResId);
return bearingControl;
}
-
- private static Path getPathFromTurnType(List paths, int laneType, Path defaultType, float coef, boolean mini) {
- if(laneType == 0) {
- return defaultType;
- }
- while (paths.size() <= laneType) {
- paths.add(null);
- }
- Path p = paths.get(laneType);
- if (p != null) {
- return p;
- }
- p = new Path();
- Matrix pathTransform = new Matrix();
- pathTransform.postScale(coef, coef );
- TurnType tp = TurnType.valueOf(laneType, false);
- TurnPathHelper.calcTurnPath(p, null, tp, pathTransform, null, mini);
- paths.set(laneType, p);
- return p;
- }
public static class LanesControl {
@@ -865,11 +842,8 @@ public class RouteInfoWidgetsFactory {
int[] lanes = null;
boolean imminent = false;
private Context ctx;
- private ArrayList paths = new ArrayList();
- private Map bitmapCache = new HashMap();
+ private Map pathsCache = new HashMap<>();
private Paint paintBlack;
- private Path laneStraight;
- private final Bitmap laneStraightBitmap;
private Paint paintRouteDirection;
private Paint paintSecondTurn;
private float scaleCoefficient;
@@ -877,59 +851,107 @@ public class RouteInfoWidgetsFactory {
private int width;
private static final float miniCoeff = 2f;
private final boolean leftSide;
+ private int imgMinWidth;
+ private int imgMargin;
- public LanesDrawable(MapActivity ctx, float scaleCoefficent) {
+ LanesDrawable(MapActivity ctx, float scaleCoefficent) {
this.ctx = ctx;
OsmandSettings settings = ctx.getMyApplication().getSettings();
leftSide = settings.DRIVING_REGION.get().leftHandDriving;
+ imgMinWidth = ctx.getResources().getDimensionPixelSize(R.dimen.widget_turn_lane_min_width);
+ imgMargin = ctx.getResources().getDimensionPixelSize(R.dimen.widget_turn_lane_margin);
this.scaleCoefficient = scaleCoefficent;
- laneStraight = getPathFromTurnType(paths, TurnType.C, null, scaleCoefficient / miniCoeff, true);
- laneStraightBitmap = TurnPathHelper.getBitmapFromTurnType(ctx.getResources(), bitmapCache, TurnType.C, 0, 0, TurnPathHelper.FIRST_TURN, scaleCoefficient / miniCoeff, leftSide);
- paintBlack = new Paint();
+
+ paintBlack = new Paint(Paint.ANTI_ALIAS_FLAG);
paintBlack.setStyle(Style.STROKE);
paintBlack.setColor(Color.BLACK);
- paintBlack.setAntiAlias(true);
- paintBlack.setStrokeWidth(2.5f);
-
+ paintBlack.setStrokeWidth(1.5f);
+
paintRouteDirection = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintRouteDirection.setStyle(Style.FILL_AND_STROKE);
+ paintRouteDirection.setStyle(Style.FILL);
paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow));
paintSecondTurn = new Paint(Paint.ANTI_ALIAS_FLAG);
- paintSecondTurn.setStyle(Style.FILL_AND_STROKE);
+ paintSecondTurn.setStyle(Style.FILL);
paintSecondTurn.setColor(ctx.getResources().getColor(R.color.nav_arrow_distant));
-
}
- public void updateBounds() {
+ void updateBounds() {
float w = 0;
- int h = 0;
+ float h = 0;
float coef = scaleCoefficient / miniCoeff;
if (lanes != null) {
for (int i = 0; i < lanes.length; i++) {
int turnType = TurnType.getPrimaryTurn(lanes[i]);
int secondTurnType = TurnType.getSecondaryTurn(lanes[i]);
int thirdTurnType = TurnType.getTertiaryTurn(lanes[i]);
- Bitmap b = TurnPathHelper.getBitmapFromTurnType(ctx.getResources(), bitmapCache, turnType,
- secondTurnType, thirdTurnType, TurnPathHelper.FIRST_TURN, coef, leftSide);
- if (b != null) {
- if (secondTurnType == 0 && thirdTurnType == 0) {
- int arrowWidth = AndroidUtils.dpToPx(ctx, getArrowWidthInDp(turnType));
- int emptyWidth = b.getWidth() - arrowWidth;
- w += emptyWidth / 2 + arrowWidth;
- } else {
- w += b.getWidth();
- }
- int bitmapHeight = b.getHeight();
- if (bitmapHeight > h) {
- h = bitmapHeight;
+
+ RectF imgBounds = new RectF();
+ if (thirdTurnType > 0) {
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.THIRD_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ }
}
}
+ if (secondTurnType > 0) {
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.SECOND_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ }
+ }
+ }
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.FIRST_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ }
+ }
+ if (imgBounds.right > 0)
+ {
+ if (imgBounds.width() < imgMinWidth) {
+ imgBounds.inset(-(imgMinWidth - imgBounds.width()) / 2.f, 0);
+ }
+ w += imgBounds.width() + (i < lanes.length - 1 ? imgMargin * 2 : 0);
+
+ float imageHeight = imgBounds.bottom;
+ if (imageHeight > h)
+ h = imageHeight;
+ }
+ }
+ if (w > 0) {
+ w += 4;
+ }
+ if (h > 0) {
+ h += 4;
}
}
width = (int) w;
- height = h;
+ height = (int) h;
}
@Override
@@ -944,16 +966,13 @@ public class RouteInfoWidgetsFactory {
@Override
- public void draw(Canvas canvas) {
- Bitmap src = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
- // setup canvas for painting
- Canvas srcCanvas = new Canvas(src);
+ public void draw(@NonNull Canvas canvas) {
// setup default color
- srcCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ //canvas.drawColor(0, PorterDuff.Mode.CLEAR);
//to change color immediately when needed
if (lanes != null && lanes.length > 0) {
- srcCanvas.save();
+ canvas.save();
// canvas.translate((int) (16 * scaleCoefficient), 0);
for (int i = 0; i < lanes.length; i++) {
if ((lanes[i] & 1) == 1) {
@@ -966,127 +985,89 @@ public class RouteInfoWidgetsFactory {
int secondTurnType = TurnType.getSecondaryTurn(lanes[i]);
int thirdTurnType = TurnType.getTertiaryTurn(lanes[i]);
+ RectF imgBounds = new RectF();
+ Path thirdTurnPath = null;
+ Path secondTurnPath = null;
+ Path firstTurnPath = null;
+
float coef = scaleCoefficient / miniCoeff;
- if(thirdTurnType > 0){
- Bitmap bSecond = null;
- bSecond = TurnPathHelper.getBitmapFromTurnType(ctx.getResources(), bitmapCache, turnType,
- secondTurnType, thirdTurnType, TurnPathHelper.THIRD_TURN, coef, leftSide);
- if (bSecond != null){
- paintSecondTurn.setColorFilter(new PorterDuffColorFilter(paintSecondTurn.getColor(), PorterDuff.Mode.SRC_ATOP));
- srcCanvas.drawBitmap(bSecond, 0f, 0f, paintSecondTurn);
+ if (thirdTurnType > 0) {
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.THIRD_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ thirdTurnPath = p;
+ }
}
}
- if(secondTurnType > 0){
- Bitmap bSecond = null;
- bSecond = TurnPathHelper.getBitmapFromTurnType(ctx.getResources(), bitmapCache, turnType,
- secondTurnType, thirdTurnType, TurnPathHelper.SECOND_TURN, coef, leftSide);
- if (bSecond != null){
- paintSecondTurn.setColorFilter(new PorterDuffColorFilter(paintSecondTurn.getColor(), PorterDuff.Mode.SRC_ATOP));
- srcCanvas.drawBitmap(bSecond, 0f, 0f, paintSecondTurn);
+ if (secondTurnType > 0) {
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.SECOND_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ secondTurnPath = p;
+ }
}
}
- Bitmap b = TurnPathHelper.getBitmapFromTurnType(ctx.getResources(), bitmapCache, turnType,
- secondTurnType, thirdTurnType, TurnPathHelper.FIRST_TURN, coef, leftSide);
- if(b != null) {
- paintRouteDirection.setColorFilter(new PorterDuffColorFilter(paintRouteDirection.getColor(), PorterDuff.Mode.SRC_ATOP));
- Bitmap bitmap;
- if (secondTurnType == 0 && thirdTurnType == 0) {
- bitmap = applyCrop(b, turnType);
+ Path p = TurnPathHelper.getPathFromTurnType(ctx.getResources(), pathsCache, turnType,
+ secondTurnType, thirdTurnType, TurnPathHelper.FIRST_TURN, coef, leftSide, true);
+ if (p != null) {
+ RectF b = new RectF();
+ p.computeBounds(b, true);
+ if (!b.isEmpty()) {
+ if (imgBounds.isEmpty()) {
+ imgBounds.set(b);
+ } else {
+ imgBounds.union(b);
+ }
+ firstTurnPath = p;
+ }
+ }
+
+ if (firstTurnPath != null || secondTurnPath != null || thirdTurnPath != null) {
+ if (imgBounds.width() < imgMinWidth) {
+ imgBounds.inset(-(imgMinWidth - imgBounds.width()) / 2.f, 0);
+ }
+ if (i == 0) {
+ imgBounds.set(imgBounds.left - 2, imgBounds.top, imgBounds.right + imgMargin, imgBounds.bottom);
} else {
- bitmap = b;
+ imgBounds.inset(-imgMargin, 0);
}
- srcCanvas.drawBitmap(bitmap, 0f, 0f, paintRouteDirection);
- srcCanvas.translate(bitmap.getWidth(), 0);
+
+ canvas.translate(-imgBounds.left, 0);
+
+ if (thirdTurnPath != null) {
+ canvas.drawPath(thirdTurnPath, paintSecondTurn);
+ canvas.drawPath(thirdTurnPath, paintBlack);
+ }
+ if (secondTurnPath != null) {
+ canvas.drawPath(secondTurnPath, paintSecondTurn);
+ canvas.drawPath(secondTurnPath, paintBlack);
+ }
+ if (firstTurnPath != null) {
+ canvas.drawPath(firstTurnPath, paintRouteDirection);
+ canvas.drawPath(firstTurnPath, paintBlack);
+ }
+
+ canvas.translate(imgBounds.right, 0);
}
}
- srcCanvas.restore();
- }
-
- // create a blur paint for capturing alpha
- Paint ptBlur = new Paint();
- float density = ctx.getResources().getDisplayMetrics().density;
- ptBlur.setMaskFilter(new BlurMaskFilter(1.66f * density, Blur.OUTER));
- int[] offsetXY = new int[2];
- // capture alpha into a bitmap
- Bitmap bmAlpha = src.extractAlpha(ptBlur, offsetXY);
- // create a color paint
- Paint ptAlphaColor = new Paint();
- ptAlphaColor.setColor(0xFF000000);
- // paint color for captured alpha region (bitmap)
- canvas.drawBitmap(bmAlpha, offsetXY[0], offsetXY[1], ptAlphaColor);
- // free memory
- bmAlpha.recycle();
-
- // paint the image source
- canvas.drawBitmap(src, 0, 0, null);
- }
-
- private Bitmap applyCrop(Bitmap bitmap, int turnType) {
- int arrowWidth = AndroidUtils.dpToPx(ctx, getArrowWidthInDp(turnType));
- int emptyWidth = bitmap.getWidth() - arrowWidth;
- int widthToCrop = emptyWidth / 4;
- return Bitmap.createBitmap(bitmap, widthToCrop, 0, bitmap.getWidth() - 2 * widthToCrop, bitmap.getHeight());
- }
-
- private int getArrowWidthInDp(int tt) {
- int result;
-
- switch (tt){
- case TurnType.C:
- result = 12;
- break;
- case TurnType.TR:
- case TurnType.TL:
- result = 20;
- break;
- case TurnType.KR:
- case TurnType.KL:
- result = 13;
- break;
- case TurnType.TSLR:
- case TurnType.TSLL:
- result = 13;
- break;
- case TurnType.TSHR:
- case TurnType.TSHL:
- result = 19;
- break;
- case TurnType.TRU:
- case TurnType.TU:
- result = 24;
- break;
- default:
- result = 12;
- break;
- }
-
- return result;
- }
-
- //@Override
- public void drawOld(Canvas canvas) {
- float w = 72 * scaleCoefficient / miniCoeff;
- //to change color immediately when needed
- if (lanes != null && lanes.length > 0) {
- canvas.save();
- // canvas.translate((int) (16 * scaleCoefficient), 0);
- for (int i = 0; i < lanes.length; i++) {
- int turnType;
- if ((lanes[i] & 1) == 1) {
- paintRouteDirection.setColor(imminent ? ctx.getResources().getColor(R.color.nav_arrow_imminent) :
- ctx.getResources().getColor(R.color.nav_arrow));
- turnType = TurnType.getPrimaryTurn(lanes[i]);
- } else {
- paintRouteDirection.setColor(ctx.getResources().getColor(R.color.nav_arrow_distant));
- turnType = TurnType.getPrimaryTurn(lanes[i]);
- }
- Path p = getPathFromTurnType(paths, turnType, laneStraight, scaleCoefficient / miniCoeff, true);
- canvas.drawPath(p, paintBlack);
- canvas.drawPath(p, paintRouteDirection);
- canvas.translate(w, 0);
- }
canvas.restore();
- }
+ }
}
@Override