Merge pull request #11247 from osmandapp/add_stroke_to_gradient_track_line
Add border to gradient track line
This commit is contained in:
commit
3cfb56c443
2 changed files with 74 additions and 17 deletions
|
@ -4,6 +4,7 @@ import android.graphics.Canvas;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.LinearGradient;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.graphics.PointF;
|
||||||
import android.graphics.Shader;
|
import android.graphics.Shader;
|
||||||
|
|
||||||
import net.osmand.GPXUtilities;
|
import net.osmand.GPXUtilities;
|
||||||
|
@ -67,6 +68,7 @@ public class Renderable {
|
||||||
protected double zoom = -1;
|
protected double zoom = -1;
|
||||||
protected AsynchronousResampler culler = null; // The currently active resampler
|
protected AsynchronousResampler culler = null; // The currently active resampler
|
||||||
protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use
|
protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use
|
||||||
|
protected Paint borderPaint;
|
||||||
protected GradientScaleType scaleType = null;
|
protected GradientScaleType scaleType = null;
|
||||||
|
|
||||||
protected GpxGeometryWay geometryWay;
|
protected GpxGeometryWay geometryWay;
|
||||||
|
@ -88,6 +90,10 @@ public class Renderable {
|
||||||
paint.setStrokeWidth(p.getStrokeWidth());
|
paint.setStrokeWidth(p.getStrokeWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBorderPaint(@NonNull Paint paint) {
|
||||||
|
borderPaint = paint;
|
||||||
|
}
|
||||||
|
|
||||||
public void setGradientScaleType(GradientScaleType type) {
|
public void setGradientScaleType(GradientScaleType type) {
|
||||||
this.scaleType = type;
|
this.scaleType = type;
|
||||||
}
|
}
|
||||||
|
@ -177,33 +183,74 @@ public class Renderable {
|
||||||
|
|
||||||
protected void drawGradient(List<WptPt> pts, Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
protected void drawGradient(List<WptPt> pts, Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
||||||
QuadRect tileBounds = tileBox.getLatLonBounds();
|
QuadRect tileBounds = tileBox.getLatLonBounds();
|
||||||
Path path = new Path();
|
Path currentPath = new Path();
|
||||||
|
Path nextPath = new Path();
|
||||||
Paint paint = new Paint(this.paint);
|
Paint paint = new Paint(this.paint);
|
||||||
WptPt prevPt = pts.get(0);
|
|
||||||
for (int i = 1; i < pts.size(); i++) {
|
WptPt prevWpt = pts.get(0);
|
||||||
WptPt currentPt = pts.get(i);
|
WptPt currWpt = pts.get(1);
|
||||||
if (arePointsInsideTile(currentPt, prevPt, tileBounds)) {
|
|
||||||
float startX = tileBox.getPixXFromLatLon(prevPt.lat, prevPt.lon);
|
PointF prevXY = new PointF();
|
||||||
float startY = tileBox.getPixYFromLatLon(prevPt.lat, prevPt.lon);
|
PointF currXY = new PointF();
|
||||||
float endX = tileBox.getPixXFromLatLon(currentPt.lat, currentPt.lon);
|
PointF nextXY = new PointF();
|
||||||
float endY = tileBox.getPixYFromLatLon(currentPt.lat, currentPt.lon);
|
|
||||||
int prevColor = prevPt.getColor(scaleType.toColorizationType());
|
boolean currLineVisible = arePointsInsideTile(prevWpt, currWpt, tileBounds);
|
||||||
int currentColor = currentPt.getColor(scaleType.toColorizationType());
|
boolean nextLineVisible;
|
||||||
LinearGradient gradient = new LinearGradient(startX, startY, endX, endY, prevColor, currentColor, Shader.TileMode.CLAMP);
|
|
||||||
paint.setShader(gradient);
|
if (currLineVisible) {
|
||||||
path.reset();
|
pixXYFromWptPt(tileBox, prevXY, prevWpt);
|
||||||
path.moveTo(startX, startY);
|
pixXYFromWptPt(tileBox, currXY, currWpt);
|
||||||
path.lineTo(endX, endY);
|
canvas.drawPath(pathFromStartEnd(currentPath, prevXY, currXY), borderPaint);
|
||||||
canvas.drawPath(path, paint);
|
|
||||||
}
|
}
|
||||||
prevPt = currentPt;
|
|
||||||
|
for (int i = 1; i < pts.size(); i++) {
|
||||||
|
currWpt = pts.get(i);
|
||||||
|
WptPt nextWpt = i + 1 == pts.size() ? null : pts.get(i + 1);
|
||||||
|
|
||||||
|
nextLineVisible = arePointsInsideTile(currWpt, nextWpt, tileBounds);
|
||||||
|
if (nextWpt != null && nextLineVisible) {
|
||||||
|
pixXYFromWptPt(tileBox, currXY, currWpt);
|
||||||
|
pixXYFromWptPt(tileBox, nextXY, nextWpt);
|
||||||
|
canvas.drawPath(pathFromStartEnd(nextPath, currXY, nextXY), borderPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currLineVisible) {
|
||||||
|
int prevColor = prevWpt.getColor(scaleType.toColorizationType());
|
||||||
|
int currentColor = currWpt.getColor(scaleType.toColorizationType());
|
||||||
|
LinearGradient gradient = new LinearGradient(prevXY.x, prevXY.y, currXY.x, currXY.y,
|
||||||
|
prevColor, currentColor, Shader.TileMode.CLAMP);
|
||||||
|
paint.setShader(gradient);
|
||||||
|
canvas.drawPath(currentPath, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevWpt = currWpt;
|
||||||
|
currentPath.set(nextPath);
|
||||||
|
prevXY.set(currXY);
|
||||||
|
currXY.set(nextXY);
|
||||||
|
currLineVisible = nextLineVisible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean arePointsInsideTile(WptPt first, WptPt second, QuadRect tileBounds) {
|
protected boolean arePointsInsideTile(WptPt first, WptPt second, QuadRect tileBounds) {
|
||||||
|
if (first == null || second == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return Math.min(first.lon, second.lon) < tileBounds.right && Math.max(first.lon, second.lon) > tileBounds.left
|
return Math.min(first.lon, second.lon) < tileBounds.right && Math.max(first.lon, second.lon) > tileBounds.left
|
||||||
&& Math.min(first.lat, second.lat) < tileBounds.top && Math.max(first.lat, second.lat) > tileBounds.bottom;
|
&& Math.min(first.lat, second.lat) < tileBounds.top && Math.max(first.lat, second.lat) > tileBounds.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected PointF pixXYFromWptPt(RotatedTileBox tileBox, PointF pointF, WptPt wptPt) {
|
||||||
|
pointF.x = tileBox.getPixXFromLatLon(wptPt.lat, wptPt.lon);
|
||||||
|
pointF.y = tileBox.getPixYFromLatLon(wptPt.lat, wptPt.lon);
|
||||||
|
return pointF;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Path pathFromStartEnd(Path path, PointF start, PointF end) {
|
||||||
|
path.reset();
|
||||||
|
path.moveTo(start.x, start.y);
|
||||||
|
path.lineTo(end.x, end.y);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StandardTrack extends RenderableSegment {
|
public static class StandardTrack extends RenderableSegment {
|
||||||
|
|
|
@ -95,6 +95,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
private OsmandMapTileView view;
|
private OsmandMapTileView view;
|
||||||
|
|
||||||
private Paint paint;
|
private Paint paint;
|
||||||
|
private Paint borderPaint;
|
||||||
private Paint shadowPaint;
|
private Paint shadowPaint;
|
||||||
private Paint paintIcon;
|
private Paint paintIcon;
|
||||||
|
|
||||||
|
@ -190,6 +191,13 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
paint = new Paint();
|
paint = new Paint();
|
||||||
paint.setStyle(Style.STROKE);
|
paint.setStyle(Style.STROKE);
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
|
|
||||||
|
borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
borderPaint.setStyle(Style.STROKE);
|
||||||
|
borderPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
borderPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
borderPaint.setColor(0x80000000);
|
||||||
|
|
||||||
shadowPaint = new Paint();
|
shadowPaint = new Paint();
|
||||||
shadowPaint.setStyle(Style.STROKE);
|
shadowPaint.setStyle(Style.STROKE);
|
||||||
shadowPaint.setAntiAlias(true);
|
shadowPaint.setAntiAlias(true);
|
||||||
|
@ -341,6 +349,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
}
|
}
|
||||||
paint.setColor(color == 0 ? cachedColor : color);
|
paint.setColor(color == 0 ? cachedColor : color);
|
||||||
paint.setStrokeWidth(getTrackWidth(width, defaultTrackWidth));
|
paint.setStrokeWidth(getTrackWidth(width, defaultTrackWidth));
|
||||||
|
borderPaint.setStrokeWidth(paint.getStrokeWidth() + AndroidUtils.dpToPx(view.getContext(), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void acquireTrackWidth(String widthKey, RenderingRulesStorage rrs, RenderingRuleSearchRequest req, RenderingContext rc) {
|
private void acquireTrackWidth(String widthKey, RenderingRulesStorage rrs, RenderingRuleSearchRequest req, RenderingContext rc) {
|
||||||
|
@ -700,6 +709,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox);
|
updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox);
|
||||||
if (ts.renderer instanceof Renderable.RenderableSegment) {
|
if (ts.renderer instanceof Renderable.RenderableSegment) {
|
||||||
Renderable.RenderableSegment renderableSegment = (Renderable.RenderableSegment) ts.renderer;
|
Renderable.RenderableSegment renderableSegment = (Renderable.RenderableSegment) ts.renderer;
|
||||||
|
renderableSegment.setBorderPaint(borderPaint);
|
||||||
renderableSegment.setGradientScaleType(scaleType);
|
renderableSegment.setGradientScaleType(scaleType);
|
||||||
renderableSegment.drawSegment(view.getZoom(), paint, canvas, tileBox);
|
renderableSegment.drawSegment(view.getZoom(), paint, canvas, tileBox);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue