Make track arrows more visible when track line is thin

This commit is contained in:
cepprice 2021-03-21 14:44:37 +05:00
parent 130a2889c3
commit f16b46295d
3 changed files with 71 additions and 6 deletions

View file

@ -2,13 +2,14 @@ package net.osmand.plus.views.layers.geometry;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.data.RotatedTileBox;
import java.util.List;
import androidx.annotation.NonNull;
public class GpxGeometryWay extends GeometryWay<GpxGeometryWayContext, GeometryWayDrawer<GpxGeometryWayContext>> {
private List<WptPt> points;
@ -76,7 +77,9 @@ public class GpxGeometryWay extends GeometryWay<GpxGeometryWayContext, GeometryW
public static class GeometryArrowsStyle extends GeometryWayStyle<GpxGeometryWayContext> {
private static final double DIRECTION_ARROW_DISTANCE_MULTIPLIER = 10.0;
private static final float TRACK_WIDTH_THRESHOLD = 8f;
private static final float ARROW_DISTANCE_MULTIPLIER = 1.5f;
private static final float SPECIAL_ARROW_DISTANCE_MULTIPLIER = 10f;
private Bitmap arrowBitmap;
@ -114,6 +117,9 @@ public class GpxGeometryWay extends GeometryWay<GpxGeometryWayContext, GeometryW
@Override
public Bitmap getPointBitmap() {
if (useSpecialArrow()) {
return getContext().getSpecialArrowBitmap();
}
return arrowBitmap != null ? arrowBitmap : getContext().getArrowBitmap();
}
@ -130,9 +136,15 @@ public class GpxGeometryWay extends GeometryWay<GpxGeometryWayContext, GeometryW
return trackWidth;
}
public boolean useSpecialArrow() {
return trackWidth <= AndroidUtils.dpToPx(getCtx(), TRACK_WIDTH_THRESHOLD);
}
@Override
public double getPointStepPx(double zoomCoef) {
return getPointBitmap().getHeight() + trackWidth * 1.5f;
return useSpecialArrow() ?
getPointBitmap().getHeight() * SPECIAL_ARROW_DISTANCE_MULTIPLIER :
getPointBitmap().getHeight() + trackWidth * ARROW_DISTANCE_MULTIPLIER;
}
}
}

View file

@ -1,20 +1,31 @@
package net.osmand.plus.views.layers.geometry;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import androidx.core.content.ContextCompat;
public class GpxGeometryWayContext extends GeometryWayContext {
private final Bitmap specialArrowBitmap;
public GpxGeometryWayContext(Context ctx, float density) {
super(ctx, density);
Paint paint = getPaintIcon();
paint.setStrokeCap(Paint.Cap.ROUND);
specialArrowBitmap = AndroidUtils.drawableToBitmap(ContextCompat.getDrawable(ctx, R.drawable.mm_special_arrow_up));
}
@Override
protected int getArrowBitmapResId() {
return R.drawable.ic_action_direction_arrow;
}
public Bitmap getSpecialArrowBitmap() {
return specialArrowBitmap;
}
}

View file

@ -1,12 +1,15 @@
package net.osmand.plus.views.layers.geometry;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import net.osmand.AndroidUtils;
import net.osmand.plus.views.layers.geometry.GpxGeometryWay.GeometryArrowsStyle;
public class GpxGeometryWayDrawer extends GeometryWayDrawer<GpxGeometryWayContext> {
@ -22,31 +25,70 @@ public class GpxGeometryWayDrawer extends GeometryWayDrawer<GpxGeometryWayContex
private static class ArrowPathPoint extends PathPoint {
private Bitmap circleBitmap;
ArrowPathPoint(float x, float y, double angle, GeometryWayStyle<?> style) {
super(x, y, angle, style);
createCircleBitmap((GeometryArrowsStyle) style);
}
@Override
void draw(Canvas canvas, GeometryWayContext context) {
if (style instanceof GeometryArrowsStyle) {
Context ctx = style.getCtx();
GeometryArrowsStyle arrowsWayStyle = (GeometryArrowsStyle) style;
Bitmap bitmap = style.getPointBitmap();
boolean useSpecialArrow = arrowsWayStyle.useSpecialArrow();
float newWidth = arrowsWayStyle.getTrackWidth() / 2f;
float newWidth = useSpecialArrow ? AndroidUtils.dpToPx(ctx, 12) : arrowsWayStyle.getTrackWidth() / 2f;
float paintH2 = bitmap.getHeight() / 2f;
float paintW2 = newWidth / 2f;
Matrix matrix = getMatrix();
matrix.reset();
matrix.postScale(newWidth / bitmap.getWidth(), 1);
float sy = useSpecialArrow ? newWidth / bitmap.getHeight() : 1;
matrix.postScale(newWidth / bitmap.getWidth(), sy);
matrix.postRotate((float) angle, paintW2, paintH2);
matrix.postTranslate(x - paintW2, y - paintH2);
if (useSpecialArrow) {
drawCircle(canvas, arrowsWayStyle);
}
Paint paint = context.getPaintIconCustom();
Integer pointColor = style.getPointColor();
paint.setColorFilter(new PorterDuffColorFilter(pointColor, PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, matrix, paint);
}
}
private void drawCircle(Canvas canvas, GeometryArrowsStyle style) {
float offset = circleBitmap.getWidth() / 2f;
float angleOffset = AndroidUtils.dpToPx(style.getCtx(), 1);
double rad = Math.toRadians(angle + 90);
float x = (float) (this.x - offset - angleOffset * Math.cos(rad));
float y = (float) (this.y - offset - angleOffset * Math.sin(rad));
canvas.drawBitmap(circleBitmap, x, y, null);
}
private void createCircleBitmap(GeometryArrowsStyle style) {
Context ctx = style.getCtx();
int size = AndroidUtils.dpToPx(ctx, 16);
circleBitmap = Bitmap.createBitmap(size, size, style.getPointBitmap().getConfig());
Paint paint = new Paint(Paint.DITHER_FLAG | Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
Canvas c = new Canvas(circleBitmap);
paint.setColor(0x33000000);
Path path = new Path();
path.addCircle(size / 2f, size / 2f, AndroidUtils.dpToPx(ctx, 8), Path.Direction.CW);
c.drawPath(path, paint);
paint.setColor(style.getTrackColor());
path.reset();
path.addCircle(size / 2f, size / 2f, AndroidUtils.dpToPx(ctx, 7), Path.Direction.CW);
c.drawPath(path, paint);
}
}
}