Add gradient route line

This commit is contained in:
cepprice 2021-04-15 14:10:41 +05:00
parent 26f9e85f2a
commit ff7aa932a3
5 changed files with 269 additions and 54 deletions

View file

@ -186,7 +186,7 @@ public class RouteColorize {
public List<RouteColorizationPoint> getResult(boolean simplify) { public List<RouteColorizationPoint> getResult(boolean simplify) {
List<RouteColorizationPoint> result = new ArrayList<>(); List<RouteColorizationPoint> result = new ArrayList<>();
if (simplify) { if (simplify) {
result = simplify(); result = simplify(zoom);
} else { } else {
for (int i = 0; i < latitudes.length; i++) { for (int i = 0; i < latitudes.length; i++) {
result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i])); result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i]));
@ -242,7 +242,7 @@ public class RouteColorize {
return rgbaToDecimal(0, 0, 0, 0); return rgbaToDecimal(0, 0, 0, 0);
} }
private List<RouteColorizationPoint> simplify() { public List<RouteColorizationPoint> simplify(int zoom) {
if (dataList == null) { if (dataList == null) {
dataList = new ArrayList<>(); dataList = new ArrayList<>();
for (int i = 0; i < latitudes.length; i++) { for (int i = 0; i < latitudes.length; i++) {

View file

@ -4,6 +4,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Paint.Cap; import android.graphics.Paint.Cap;
@ -11,6 +12,7 @@ import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
@ -44,6 +46,7 @@ import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper; import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.layers.ContextMenuLayer.IContextMenuProvider; import net.osmand.plus.views.layers.ContextMenuLayer.IContextMenuProvider;
@ -54,6 +57,7 @@ import net.osmand.plus.views.layers.geometry.RouteGeometryWayContext;
import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleProperty;
import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RouteColorize;
import net.osmand.router.TransportRouteResult; import net.osmand.router.TransportRouteResult;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -109,6 +113,7 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
private int routeLineColor; private int routeLineColor;
private Integer directionArrowsColor; private Integer directionArrowsColor;
private GradientScaleType gradientScaleType = null;
public RouteLayer(RoutingHelper helper) { public RouteLayer(RoutingHelper helper) {
this.helper = helper; this.helper = helper;
@ -331,14 +336,22 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
DrawSettings settings, DrawSettings settings,
RouteLineDrawInfo drawInfo) { RouteLineDrawInfo drawInfo) {
updateAttrs(settings, tileBox); updateAttrs(settings, tileBox);
updateRouteColors(nightMode);
paintRouteLinePreview.setColor(getRouteLineColor());
paintRouteLinePreview.setStrokeWidth(getRouteLineWidth(tileBox)); paintRouteLinePreview.setStrokeWidth(getRouteLineWidth(tileBox));
int centerX = drawInfo.getCenterX(); int centerX = drawInfo.getCenterX();
int centerY = drawInfo.getCenterY(); int centerY = drawInfo.getCenterY();
int screenHeight = drawInfo.getScreenHeight(); int screenHeight = drawInfo.getScreenHeight();
if (gradientScaleType == GradientScaleType.ALTITUDE || gradientScaleType == GradientScaleType.SLOPE) {
int[] colors = new int[] {RouteColorize.RED, RouteColorize.YELLOW, RouteColorize.GREEN};
float[] positions = new float[] {0, 0.5f, 1};
LinearGradient gradient = new LinearGradient(centerX, 0, centerX, screenHeight, colors, positions, Shader.TileMode.CLAMP);
paintRouteLinePreview.setShader(gradient);
} else {
updateRouteColors(nightMode);
paintRouteLinePreview.setColor(getRouteLineColor());
}
canvas.drawLine(centerX, 0, centerX, screenHeight, paintRouteLinePreview); canvas.drawLine(centerX, 0, centerX, screenHeight, paintRouteLinePreview);
if (previewIcon == null) { if (previewIcon == null) {
@ -524,9 +537,9 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
boolean directTo = route.getRouteService() == RouteService.DIRECT_TO; boolean directTo = route.getRouteService() == RouteService.DIRECT_TO;
boolean straight = route.getRouteService() == RouteService.STRAIGHT; boolean straight = route.getRouteService() == RouteService.STRAIGHT;
publicTransportRouteGeometry.clearRoute(); publicTransportRouteGeometry.clearRoute();
routeGeometry.updateRoute(tb, route); routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor(), gradientScaleType);
routeGeometry.updateRoute(tb, route, view.getApplication());
updateRouteColors(nightMode); updateRouteColors(nightMode);
routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor());
if (directTo) { if (directTo) {
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude, routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude,
null, 0); null, 0);

View file

@ -126,7 +126,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
zooms.clear(); zooms.clear();
} }
private PathGeometryZoom getGeometryZoom(RotatedTileBox tb) { protected PathGeometryZoom getGeometryZoom(RotatedTileBox tb, Map<Integer, PathGeometryZoom> zooms) {
int zoom = tb.getZoom(); int zoom = tb.getZoom();
PathGeometryZoom zm = zooms.size() > zoom ? zooms.get(zoom) : null; PathGeometryZoom zm = zooms.size() > zoom ? zooms.get(zoom) : null;
if (zm == null) { if (zm == null) {
@ -148,7 +148,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
if (locationProvider == null || locationProvider.getSize() == 0) { if (locationProvider == null || locationProvider.getSize() == 0) {
return; return;
} }
PathGeometryZoom geometryZoom = getGeometryZoom(tb); PathGeometryZoom geometryZoom = getGeometryZoom(tb, zooms);
TByteArrayList simplification = geometryZoom.getSimplifyPoints(); TByteArrayList simplification = geometryZoom.getSimplifyPoints();
List<Double> odistances = geometryZoom.getDistances(); List<Double> odistances = geometryZoom.getDistances();
@ -171,29 +171,24 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
if (simplification.getQuick(i) == 0 && !styleMap.containsKey(i)) { if (simplification.getQuick(i) == 0 && !styleMap.containsKey(i)) {
continue; continue;
} }
double lat = locationProvider.getLatitude(i);
double lon = locationProvider.getLongitude(i);
if (shouldAddLocation(simplification, leftLongitude, rightLongitude, bottomLatitude, topLatitude, if (shouldAddLocation(simplification, leftLongitude, rightLongitude, bottomLatitude, topLatitude,
locationProvider, i)) { locationProvider, i)) {
double dist = previous == -1 ? 0 : odistances.get(i); double dist = previous == -1 ? 0 : odistances.get(i);
if (!previousVisible) { if (!previousVisible) {
double prevLat = Double.NaN;
double prevLon = Double.NaN;
if (previous != -1) { if (previous != -1) {
prevLat = locationProvider.getLatitude(previous); addLocation(tb, previous, style, tx, ty, angles, distances, dist, styles);
prevLon = locationProvider.getLongitude(previous);
} else if (lastProjection != null) { } else if (lastProjection != null) {
prevLat = lastProjection.getLatitude(); double prevLat = lastProjection.getLatitude();
prevLon = lastProjection.getLongitude(); double prevLon = lastProjection.getLongitude();
} if (!Double.isNaN(prevLat) && !Double.isNaN(prevLon)) {
if (!Double.isNaN(prevLat) && !Double.isNaN(prevLon)) { addLocation(tb, prevLat, prevLon, getStyle(i - 1, style), tx, ty, angles, distances, dist, styles); // first point
addLocation(tb, prevLat, prevLon, getStyle(i - 1, style), tx, ty, angles, distances, dist, styles); // first point }
} }
} }
addLocation(tb, lat, lon, style, tx, ty, angles, distances, dist, styles); addLocation(tb, i, style, tx, ty, angles, distances, dist, styles);
previousVisible = true; previousVisible = true;
} else if (previousVisible) { } else if (previousVisible) {
addLocation(tb, lat, lon, style, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), styles); addLocation(tb, i, style, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), styles);
double distToFinish = 0; double distToFinish = 0;
for (int ki = i + 1; ki < odistances.size(); ki++) { for (int ki = i + 1; ki < odistances.size(); ki++) {
distToFinish += odistances.get(ki); distToFinish += odistances.get(ki);
@ -214,7 +209,14 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
return leftLon <= lon && lon <= rightLon && bottomLat <= lat && lat <= topLat; return leftLon <= lon && lon <= rightLon && bottomLat <= lat && lat <= topLat;
} }
private void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style, protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle<?> style,
List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances,
double dist, List<GeometryWayStyle<?>> styles) {
addLocation(tb, locationProvider.getLatitude(locationIdx), locationProvider.getLongitude(locationIdx),
style, tx, ty, angles, distances, dist, styles);
}
protected void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style,
List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances, List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances,
double dist, List<GeometryWayStyle<?>> styles) { double dist, List<GeometryWayStyle<?>> styles) {
float x = tb.getPixXFromLatLon(latitude, longitude); float x = tb.getPixXFromLatLon(latitude, longitude);
@ -372,7 +374,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
} }
} }
private static class PathGeometryZoom { protected static class PathGeometryZoom {
private static final float EPSILON_IN_DPI = 2; private static final float EPSILON_IN_DPI = 2;
@ -390,12 +392,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
angles = new ArrayList<>(size); angles = new ArrayList<>(size);
if (simplify) { if (simplify) {
simplifyPoints.fill(0, size, (byte) 0); simplifyPoints.fill(0, size, (byte) 0);
if (size > 0) { simplify(tb, locationProvider, simplifyPoints);
simplifyPoints.set(0, (byte) 1);
}
double distInPix = (tb.getDistance(0, 0, tb.getPixWidth(), 0) / tb.getPixWidth());
double cullDistance = (distInPix * (EPSILON_IN_DPI * Math.max(1, tb.getDensity())));
cullRamerDouglasPeucker(simplifyPoints, locationProvider, 0, size - 1, cullDistance);
} else { } else {
simplifyPoints.fill(0, size, (byte) 1); simplifyPoints.fill(0, size, (byte) 1);
} }
@ -422,6 +419,16 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
} }
} }
protected void simplify(RotatedTileBox tb, GeometryWayProvider locationProvider, TByteArrayList simplifyPoints) {
int size = locationProvider.getSize();
if (size > 0) {
simplifyPoints.set(0, (byte) 1);
}
double distInPix = (tb.getDistance(0, 0, tb.getPixWidth(), 0) / tb.getPixWidth());
double cullDistance = (distInPix * (EPSILON_IN_DPI * Math.max(1, tb.getDensity())));
cullRamerDouglasPeucker(simplifyPoints, locationProvider, 0, size - 1, cullDistance);
}
public List<Double> getDistances() { public List<Double> getDistances() {
return distances; return distances;
} }

View file

@ -2,20 +2,30 @@ package net.osmand.plus.views.layers.geometry;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PointF;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.Location;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.router.RouteColorize;
import net.osmand.router.RouteColorize.RouteColorizationPoint;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import gnu.trove.list.array.TByteArrayList;
import net.osmand.Location; public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, RouteGeometryWayDrawer> {
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper;
import java.util.Collections;
import java.util.List;
public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, GeometryWayDrawer<RouteGeometryWayContext>> {
private RoutingHelper helper; private RoutingHelper helper;
private RouteCalculationResult route; private RouteCalculationResult route;
@ -23,34 +33,82 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Geome
private Integer customColor; private Integer customColor;
private Float customWidth; private Float customWidth;
private Integer customPointColor; private Integer customPointColor;
private GradientScaleType scaleType;
public RouteGeometryWay(RouteGeometryWayContext context) { public RouteGeometryWay(RouteGeometryWayContext context) {
super(context, new GeometryWayDrawer<>(context)); super(context, new RouteGeometryWayDrawer(context));
this.helper = context.getApp().getRoutingHelper(); this.helper = context.getApp().getRoutingHelper();
} }
public void setRouteStyleParams(@Nullable @ColorInt Integer color, public void setRouteStyleParams(@Nullable @ColorInt Integer color,
@Nullable Float width, @Nullable Float width,
@Nullable @ColorInt Integer pointColor) { @Nullable @ColorInt Integer pointColor,
@Nullable GradientScaleType scaleType) {
this.customColor = color; this.customColor = color;
this.customWidth = width; this.customWidth = width;
this.customPointColor = pointColor; this.customPointColor = pointColor;
this.scaleType = GradientScaleType.ALTITUDE;
} }
@NonNull public void updateRoute(RotatedTileBox tb, RouteCalculationResult route, OsmandApplication app) {
@Override if (tb.getMapDensity() == getMapDensity() && this.route == route) {
public GeometryWayStyle<RouteGeometryWayContext> getDefaultWayStyle() { return;
Paint paint = getContext().getAttrs().paint; }
int color = customColor != null ? customColor : paint.getColor();
float width = customWidth != null ? customWidth : paint.getStrokeWidth();
return new GeometrySolidWayStyle(getContext(), color, width, customPointColor);
}
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) { this.route = route;
if (tb.getMapDensity() != getMapDensity() || this.route != route) { List<Location> locations = route != null ? route.getImmutableAllLocations() : Collections.<Location>emptyList();
this.route = route;
List<Location> locations = route != null ? route.getImmutableAllLocations() : Collections.<Location>emptyList(); if (scaleType == null || locations.size() < 2) {
updateWay(locations, tb); updateWay(locations, tb);
return;
}
GPXFile gpxFile = GpxUiHelper.makeGpxFromRoute(route, app);
if (!gpxFile.hasAltitude) {
updateWay(locations, tb);
}
RouteColorize routeColorize = new RouteColorize(tb.getZoom(), gpxFile, null, scaleType.toColorizationType(), 0);
List<RouteColorizationPoint> points = routeColorize.getResult(false);
updateWay(new GradientGeometryWayProvider(routeColorize), createStyles(points), tb);
}
private Map<Integer, GeometryWayStyle<?>> createStyles(List<RouteColorizationPoint> points) {
Map<Integer, GeometryWayStyle<?>> styleMap = new TreeMap<>();
for (int i = 1; i < points.size(); i++) {
GeometryGradientWayStyle style = getGradientWayStyle();
style.startColor = points.get(i - 1).color;
style.endColor = points.get(i).color;
styleMap.put(i, style);
}
return styleMap;
}
@Override
protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle<?> style, List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances, double dist, List<GeometryWayStyle<?>> styles) {
super.addLocation(tb, getLocationProvider().getLatitude(locationIdx),
getLocationProvider().getLongitude(locationIdx), style, tx, ty, angles, distances, dist, styles);
if (scaleType != null && tx.size() - 1 > 0) {
int idx = tx.size() - 1;
((GeometryGradientWayStyle) style).startXY = new PointF(tx.get(idx - 1), ty.get(idx - 1));
((GeometryGradientWayStyle) style).endXY = new PointF(tx.get(idx), ty.get(idx));
}
}
@Override
protected void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style, List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances, double dist, List<GeometryWayStyle<?>> styles) {
super.addLocation(tb, latitude, longitude, style, tx, ty, angles, distances, dist, styles);
if (scaleType != null) {
int lastIdx = tx.size() - 1;
((GeometryGradientWayStyle) style).startXY = new PointF(tx.get(lastIdx), ty.get(lastIdx));
((GeometryGradientWayStyle) style).startColor = getGradientLocationProvider().getColor(0);
((GeometryGradientWayStyle) style).endColor = getGradientLocationProvider().getColor(0);
if (lastIdx != 0) {
((GeometryGradientWayStyle) styles.get(lastIdx - 1)).endXY = new PointF(tx.get(lastIdx - 1), ty.get(lastIdx - 1));
}
} }
} }
@ -61,17 +119,125 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Geome
} }
} }
@NonNull
@Override
public GeometryWayStyle<RouteGeometryWayContext> getDefaultWayStyle() {
Paint paint = getContext().getAttrs().paint;
int color = customColor != null ? customColor : paint.getColor();
float width = customWidth != null ? customWidth : paint.getStrokeWidth();
return scaleType == null ?
new GeometrySolidWayStyle(getContext(), color, width, customPointColor) :
new GeometryGradientWayStyle(getContext(), width);
}
private GeometryGradientWayStyle getGradientWayStyle() {
return (GeometryGradientWayStyle) getDefaultWayStyle();
}
@Override @Override
public Location getNextVisiblePoint() { public Location getNextVisiblePoint() {
return helper.getRoute().getCurrentStraightAnglePoint(); return helper.getRoute().getCurrentStraightAnglePoint();
} }
private GradientGeometryWayProvider getGradientLocationProvider() {
return (GradientGeometryWayProvider) getLocationProvider();
}
@Override
protected PathGeometryZoom getGeometryZoom(RotatedTileBox tb, Map<Integer, PathGeometryZoom> zooms) {
if (scaleType == null) {
return super.getGeometryZoom(tb, zooms);
}
int zoom = tb.getZoom();
PathGeometryZoom zm = zooms.get(zoom);
if (zm == null) {
zm = new GradientPathGeometryZoom(getLocationProvider(), tb, true);
zooms.put(zoom, zm);
}
return zm;
}
private static class GradientGeometryWayProvider implements GeometryWayProvider {
private final RouteColorize routeColorize;
private final List<RouteColorizationPoint> locations;
public GradientGeometryWayProvider(RouteColorize routeColorize) {
this.routeColorize = routeColorize;
locations = routeColorize.getResult(false);
}
public List<RouteColorizationPoint> simplify(int zoom) {
return routeColorize.simplify(zoom);
}
public int getColor(int index) {
return locations.get(index).color;
}
@Override
public double getLatitude(int index) {
return locations.get(index).lat;
}
@Override
public double getLongitude(int index) {
return locations.get(index).lon;
}
@Override
public int getSize() {
return locations.size();
}
}
private static class GradientPathGeometryZoom extends PathGeometryZoom {
public GradientPathGeometryZoom(GeometryWayProvider locationProvider, RotatedTileBox tb, boolean simplify) {
super(locationProvider, tb, simplify);
}
@Override
protected void simplify(RotatedTileBox tb, GeometryWayProvider locationProvider, TByteArrayList simplifyPoints) {
if (locationProvider instanceof GradientGeometryWayProvider) {
GradientGeometryWayProvider provider = (GradientGeometryWayProvider) locationProvider;
List<RouteColorizationPoint> simplified = provider.simplify(tb.getZoom());
for (RouteColorizationPoint location : simplified) {
simplifyPoints.set(location.id, (byte) 1);
}
}
}
}
public static class GeometryGradientWayStyle extends GeometryWayStyle<RouteGeometryWayContext> {
public int startColor;
public int endColor;
public PointF startXY;
public PointF endXY;
public GeometryGradientWayStyle(RouteGeometryWayContext context, Float width) {
super(context, 0xFFFFFFFF, width);
}
@Override
public Bitmap getPointBitmap() {
return getContext().getArrowBitmap();
}
@Override
public boolean equals(Object other) {
return this == other;
}
}
private static class GeometrySolidWayStyle extends GeometryWayStyle<RouteGeometryWayContext> { private static class GeometrySolidWayStyle extends GeometryWayStyle<RouteGeometryWayContext> {
private Integer pointColor; private Integer pointColor;
GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color, Float width, GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color, Float width,
Integer pointColor) { Integer pointColor) {
super(context, color, width); super(context, color, width);
this.pointColor = pointColor; this.pointColor = pointColor;
} }
@ -97,4 +263,4 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Geome
return other instanceof GeometrySolidWayStyle; return other instanceof GeometrySolidWayStyle;
} }
} }
} }

View file

@ -0,0 +1,29 @@
package net.osmand.plus.views.layers.geometry;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import net.osmand.plus.views.layers.geometry.RouteGeometryWay.GeometryGradientWayStyle;
public class RouteGeometryWayDrawer extends GeometryWayDrawer<RouteGeometryWayContext> {
public RouteGeometryWayDrawer(RouteGeometryWayContext context) {
super(context);
}
@Override
public void drawPath(Canvas canvas, Path path, GeometryWayStyle<?> s) {
if (s instanceof GeometryGradientWayStyle) {
GeometryGradientWayStyle style = (GeometryGradientWayStyle) s;
LinearGradient gradient = new LinearGradient(style.startXY.x, style.startXY.y, style.endXY.x, style.endXY.y,
style.startColor, style.endColor, Shader.TileMode.CLAMP);
getContext().getAttrs().customColorPaint.setShader(gradient);
getContext().getAttrs().customColorPaint.setStrokeCap(Paint.Cap.ROUND);
}
super.drawPath(canvas, path, s);
}
}