From ff7aa932a3385c4b444960188c95bc4376a6bee1 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 15 Apr 2021 14:10:41 +0500 Subject: [PATCH 01/15] Add gradient route line --- .../java/net/osmand/router/RouteColorize.java | 4 +- .../osmand/plus/views/layers/RouteLayer.java | 21 +- .../views/layers/geometry/GeometryWay.java | 53 +++-- .../layers/geometry/RouteGeometryWay.java | 216 ++++++++++++++++-- .../geometry/RouteGeometryWayDrawer.java | 29 +++ 5 files changed, 269 insertions(+), 54 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 6a0c5c5794..62186a8bb3 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -186,7 +186,7 @@ public class RouteColorize { public List getResult(boolean simplify) { List result = new ArrayList<>(); if (simplify) { - result = simplify(); + result = simplify(zoom); } else { for (int i = 0; i < latitudes.length; 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); } - private List simplify() { + public List simplify(int zoom) { if (dataList == null) { dataList = new ArrayList<>(); for (int i = 0; i < latitudes.length; i++) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java index 01e6765000..f2f1ba24b5 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java @@ -4,6 +4,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Cap; @@ -11,6 +12,7 @@ import android.graphics.Path; import android.graphics.PointF; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; +import android.graphics.Shader; import android.graphics.drawable.Drawable; 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.TransportRoutingHelper; import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; 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.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; +import net.osmand.router.RouteColorize; import net.osmand.router.TransportRouteResult; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -109,6 +113,7 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { private int routeLineColor; private Integer directionArrowsColor; + private GradientScaleType gradientScaleType = null; public RouteLayer(RoutingHelper helper) { this.helper = helper; @@ -331,14 +336,22 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { DrawSettings settings, RouteLineDrawInfo drawInfo) { updateAttrs(settings, tileBox); - updateRouteColors(nightMode); - paintRouteLinePreview.setColor(getRouteLineColor()); paintRouteLinePreview.setStrokeWidth(getRouteLineWidth(tileBox)); int centerX = drawInfo.getCenterX(); int centerY = drawInfo.getCenterY(); 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); if (previewIcon == null) { @@ -524,9 +537,9 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { boolean directTo = route.getRouteService() == RouteService.DIRECT_TO; boolean straight = route.getRouteService() == RouteService.STRAIGHT; publicTransportRouteGeometry.clearRoute(); - routeGeometry.updateRoute(tb, route); + routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor(), gradientScaleType); + routeGeometry.updateRoute(tb, route, view.getApplication()); updateRouteColors(nightMode); - routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor()); if (directTo) { routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude, null, 0); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java index aed7a2f315..7e9a511286 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -126,7 +126,7 @@ public abstract class GeometryWay zooms) { int zoom = tb.getZoom(); PathGeometryZoom zm = zooms.size() > zoom ? zooms.get(zoom) : null; if (zm == null) { @@ -148,7 +148,7 @@ public abstract class GeometryWay odistances = geometryZoom.getDistances(); @@ -171,29 +171,24 @@ public abstract class GeometryWay style, + protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle style, + List tx, List ty, List angles, List distances, + double dist, List> 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 tx, List ty, List angles, List distances, double dist, List> styles) { float x = tb.getPixXFromLatLon(latitude, longitude); @@ -372,7 +374,7 @@ public abstract class GeometryWay(size); if (simplify) { simplifyPoints.fill(0, size, (byte) 0); - 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); + simplify(tb, locationProvider, simplifyPoints); } else { simplifyPoints.fill(0, size, (byte) 1); } @@ -422,6 +419,16 @@ public abstract class GeometryWay 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 getDistances() { return distances; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index d46ca8cd68..bbac19c8fe 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -2,20 +2,30 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Bitmap; 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.NonNull; import androidx.annotation.Nullable; +import gnu.trove.list.array.TByteArrayList; -import net.osmand.Location; -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> { +public class RouteGeometryWay extends GeometryWay { private RoutingHelper helper; private RouteCalculationResult route; @@ -23,34 +33,82 @@ public class RouteGeometryWay extends GeometryWay(context)); + super(context, new RouteGeometryWayDrawer(context)); this.helper = context.getApp().getRoutingHelper(); } public void setRouteStyleParams(@Nullable @ColorInt Integer color, @Nullable Float width, - @Nullable @ColorInt Integer pointColor) { + @Nullable @ColorInt Integer pointColor, + @Nullable GradientScaleType scaleType) { this.customColor = color; this.customWidth = width; this.customPointColor = pointColor; + this.scaleType = GradientScaleType.ALTITUDE; } - @NonNull - @Override - public GeometryWayStyle getDefaultWayStyle() { - 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, OsmandApplication app) { + if (tb.getMapDensity() == getMapDensity() && this.route == route) { + return; + } - public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) { - if (tb.getMapDensity() != getMapDensity() || this.route != route) { - this.route = route; - List locations = route != null ? route.getImmutableAllLocations() : Collections.emptyList(); + this.route = route; + List locations = route != null ? route.getImmutableAllLocations() : Collections.emptyList(); + + if (scaleType == null || locations.size() < 2) { 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 points = routeColorize.getResult(false); + + updateWay(new GradientGeometryWayProvider(routeColorize), createStyles(points), tb); + } + + private Map> createStyles(List points) { + Map> 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 tx, List ty, List angles, List distances, double dist, List> 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 tx, List ty, List angles, List distances, double dist, List> 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 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 public Location getNextVisiblePoint() { return helper.getRoute().getCurrentStraightAnglePoint(); } + private GradientGeometryWayProvider getGradientLocationProvider() { + return (GradientGeometryWayProvider) getLocationProvider(); + } + + @Override + protected PathGeometryZoom getGeometryZoom(RotatedTileBox tb, Map 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 locations; + + public GradientGeometryWayProvider(RouteColorize routeColorize) { + this.routeColorize = routeColorize; + locations = routeColorize.getResult(false); + } + + public List 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 simplified = provider.simplify(tb.getZoom()); + for (RouteColorizationPoint location : simplified) { + simplifyPoints.set(location.id, (byte) 1); + } + } + } + } + + public static class GeometryGradientWayStyle extends GeometryWayStyle { + + 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 { private Integer pointColor; GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color, Float width, - Integer pointColor) { + Integer pointColor) { super(context, color, width); this.pointColor = pointColor; } @@ -97,4 +263,4 @@ public class RouteGeometryWay extends GeometryWay { + + + 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); + } +} \ No newline at end of file From 149b89090bc1253af7b3c802050b14d38c68a772 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 15 Apr 2021 17:28:48 +0500 Subject: [PATCH 02/15] Add configurable drawing of route line border --- .../osmand/plus/views/layers/RouteLayer.java | 2 ++ .../views/layers/geometry/GeometryWay.java | 19 ++++++++++-- .../layers/geometry/GeometryWayDrawer.java | 7 +++++ .../layers/geometry/RouteGeometryWay.java | 12 ++++++- .../geometry/RouteGeometryWayDrawer.java | 31 ++++++++++++++++++- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java index f2f1ba24b5..e74b0242ce 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java @@ -141,6 +141,8 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { attrs.defaultWidth = (int) (12 * density); attrs.defaultWidth3 = (int) (7 * density); attrs.defaultColor = view.getResources().getColor(R.color.nav_track); + attrs.shadowPaint.setColor(0x80000000); + attrs.shadowPaint.setStrokeCap(Cap.ROUND); attrs.paint3.setStrokeCap(Cap.BUTT); attrs.paint3.setColor(Color.WHITE); attrs.paint2.setStrokeCap(Cap.BUTT); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java index 7e9a511286..2cfb950200 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -168,7 +168,7 @@ public abstract class GeometryWay> styleMap, int locationIdx) { + return simplification.getQuick(locationIdx) == 0 && !styleMap.containsKey(locationIdx); + } + protected boolean shouldAddLocation(TByteArrayList simplification, double leftLon, double rightLon, double bottomLat, double topLat, GeometryWayProvider provider, int currLocationIdx) { double lat = provider.getLatitude(currLocationIdx); @@ -358,7 +362,18 @@ public abstract class GeometryWay>> paths = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); calculatePath(tb, tx, ty, styles, paths); - for (Pair> pc : paths) { + + drawer.drawFullBorder(canvas, tb.getZoom(), paths); + drawer.drawSegmentBorder(canvas, tb.getZoom(), paths.get(0).first, paths.get(0).second); + for (int i = 1; i <= paths.size(); i++) { + if (i != paths.size()) { + Pair> prev = paths.get(i); + if (prev.second.hasPathLine()) { + drawer.drawSegmentBorder(canvas, tb.getZoom(), prev.first, prev.second); + } + } + + Pair> pc = paths.get(i - 1); GeometryWayStyle style = pc.second; if (style.hasPathLine()) { drawer.drawPath(canvas, pc.first, style); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java index 494375d404..2b607563e5 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWayDrawer.java @@ -7,6 +7,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; +import android.util.Pair; import net.osmand.data.RotatedTileBox; @@ -89,6 +90,12 @@ public class GeometryWayDrawer { } } + protected void drawFullBorder(Canvas canvas, int zoom, List>> paths) { + } + + protected void drawSegmentBorder(Canvas canvas, int zoom, Path path, GeometryWayStyle style) { + } + protected PathPoint getArrowPathPoint(float iconx, float icony, GeometryWayStyle style, double angle) { return new PathPoint(iconx, icony, angle, style); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index bbac19c8fe..d78653b93a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -36,7 +36,7 @@ public class RouteGeometryWay extends GeometryWay> styleMap, int locationIdx) { + return scaleType == null ? + super.shouldSkipLocation(simplification, styleMap, locationIdx) : + simplification.getQuick(locationIdx) == 0; + } + @Override protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle style, List tx, List ty, List angles, List distances, double dist, List> styles) { super.addLocation(tb, getLocationProvider().getLatitude(locationIdx), diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java index 8c1d9a8868..060370e546 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java @@ -5,14 +5,36 @@ import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Shader; +import android.util.Pair; +import net.osmand.plus.views.MapTileLayer; import net.osmand.plus.views.layers.geometry.RouteGeometryWay.GeometryGradientWayStyle; +import java.util.List; + public class RouteGeometryWayDrawer extends GeometryWayDrawer { + private final int BORDER_TYPE_ZOOM_THRESHOLD = MapTileLayer.DEFAULT_MIN_ZOOM; - public RouteGeometryWayDrawer(RouteGeometryWayContext context) { + private final boolean drawBorder; + + public RouteGeometryWayDrawer(RouteGeometryWayContext context, boolean drawBorder) { super(context); + this.drawBorder = drawBorder; + } + + @Override + protected void drawFullBorder(Canvas canvas, int zoom, List>> paths) { + if (drawBorder && zoom > BORDER_TYPE_ZOOM_THRESHOLD) { + Paint borderPaint = getContext().getAttrs().shadowPaint; + Path fullPath = new Path(); + for (Pair> path : paths) { + if (path.second instanceof GeometryGradientWayStyle) { + fullPath.addPath(path.first); + } + } + canvas.drawPath(fullPath, borderPaint); + } } @Override @@ -26,4 +48,11 @@ public class RouteGeometryWayDrawer extends GeometryWayDrawer style) { + if (drawBorder && zoom < BORDER_TYPE_ZOOM_THRESHOLD) { + canvas.drawPath(path, getContext().getAttrs().shadowPaint); + } + } } \ No newline at end of file From aa6b04a924e56097823b3d87c4e5f6458c9df093 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 16 Apr 2021 11:02:27 +0500 Subject: [PATCH 03/15] Fix spoiled points --- .../src/net/osmand/plus/helpers/GpxUiHelper.java | 15 ++++++++++++++- .../views/layers/geometry/RouteGeometryWay.java | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index 87f9d4e579..9d6b019cc2 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -2139,16 +2139,29 @@ public class GpxUiHelper { float h = (float) l.getAltitude(); point.ele = h; if (lastHeight == HEIGHT_UNDEFINED && seg.points.size() > 0) { - for (GPXUtilities.WptPt pt : seg.points) { + for (int i = seg.points.size() - 1; i >= 0; i--) { + GPXUtilities.WptPt pt = seg.points.get(i); if (Double.isNaN(pt.ele)) { pt.ele = h; } } } lastHeight = h; + } else { + lastHeight = HEIGHT_UNDEFINED; } seg.points.add(point); } + if (lastHeight == HEIGHT_UNDEFINED && gpx.hasAltitude) { + int start = seg.points.size() - 1; + while (start > 0 && Double.isNaN(seg.points.get(start).ele)) { + start--; + } + double ele = seg.points.get(start).ele; + for (int i = start + 1; i < seg.points.size(); i++) { + seg.points.get(i).ele = ele; + } + } track.segments.add(seg); gpx.tracks.add(track); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index d78653b93a..314e299760 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -4,6 +4,7 @@ import android.graphics.Bitmap; import android.graphics.Paint; import android.graphics.PointF; +import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.Location; import net.osmand.data.RotatedTileBox; @@ -71,6 +72,13 @@ public class RouteGeometryWay extends GeometryWay pts = gpxFile.tracks.get(0).segments.get(0).points; + GPXUtilities.WptPt firstPt = pts.get(0); + if (firstPt.ele == 0) { + firstPt.ele = pts.get(1).ele; + } + RouteColorize routeColorize = new RouteColorize(tb.getZoom(), gpxFile, null, scaleType.toColorizationType(), 0); List points = routeColorize.getResult(false); From 0bdf2dfa8a2e15ac78fa6f74c084805619723253 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 16 Apr 2021 17:51:01 +0500 Subject: [PATCH 04/15] Add UI to configure route line --- OsmAnd/res/layout/gradient_card.xml | 9 ++- OsmAnd/res/values/strings.xml | 3 + .../plus/routing/RouteLineDrawInfo.java | 23 ++++++++ .../routing/cards/RouteLineColorCard.java | 57 ++++++++++++++++--- .../plus/settings/backend/OsmandSettings.java | 1 + .../fragments/ProfileAppearanceFragment.java | 5 +- .../net/osmand/plus/track/GradientCard.java | 38 ++++++++++--- .../osmand/plus/views/layers/RouteLayer.java | 23 ++++++-- .../layers/geometry/RouteGeometryWay.java | 9 ++- 9 files changed, 140 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/layout/gradient_card.xml b/OsmAnd/res/layout/gradient_card.xml index a4edba9be2..11b82f10ad 100644 --- a/OsmAnd/res/layout/gradient_card.xml +++ b/OsmAnd/res/layout/gradient_card.xml @@ -5,8 +5,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="@dimen/content_padding" android:paddingStart="@dimen/content_padding" + android:paddingLeft="@dimen/content_padding" + android:paddingTop="@dimen/content_padding" + android:paddingRight="@dimen/content_padding" android:paddingEnd="@dimen/content_padding"> + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 9959488bd2..0a6f64787d 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,9 @@ --> + Max. height + Min. height + Route line will be colorized depending on the elevation profile of the route. Output User points Announce when exceeded diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java b/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java index 88a033edae..2bb2eec155 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java @@ -6,12 +6,14 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import net.osmand.plus.track.GradientScaleType; import net.osmand.util.Algorithms; public class RouteLineDrawInfo { private static final String LINE_COLOR_DAY = "line_color_day"; private static final String LINE_COLOR_NIGHT = "line_color_night"; + private static final String LINE_COLOR_GRADIENT = "line_color_gradient"; private static final String LINE_WIDTH = "line_width"; private static final String NAVIGATION_ICON_ID = "navigation_icon_id"; private static final String NAVIGATION_ICON_COLOR = "navigation_icon_color"; @@ -24,6 +26,7 @@ public class RouteLineDrawInfo { @ColorInt private Integer colorDay; private Integer colorNight; + private GradientScaleType scaleType; private String width; // temporally parameters to show in preview @@ -37,9 +40,11 @@ public class RouteLineDrawInfo { public RouteLineDrawInfo(@Nullable @ColorInt Integer colorDay, @Nullable @ColorInt Integer colorNight, + @Nullable GradientScaleType gradientScaleType, @Nullable String width) { this.colorDay = colorDay; this.colorNight = colorNight; + this.scaleType = gradientScaleType; this.width = width; } @@ -50,6 +55,7 @@ public class RouteLineDrawInfo { public RouteLineDrawInfo(@NonNull RouteLineDrawInfo existed) { this.colorDay = existed.colorDay; this.colorNight = existed.colorNight; + this.scaleType = existed.scaleType; this.width = existed.width; this.iconId = existed.iconId; this.iconColor = existed.iconColor; @@ -71,6 +77,10 @@ public class RouteLineDrawInfo { this.useDefaultColor = useDefaultColor; } + public void setGradientScaleType(@Nullable GradientScaleType scaleType) { + this.scaleType = scaleType; + } + public void setWidth(@Nullable String width) { this.width = width; } @@ -108,6 +118,11 @@ public class RouteLineDrawInfo { return nightMode ? colorNight : colorDay; } + @Nullable + public GradientScaleType getGradientScaleType() { + return scaleType; + } + @Nullable public String getWidth() { return width; @@ -141,6 +156,9 @@ public class RouteLineDrawInfo { if (bundle.containsKey(LINE_COLOR_NIGHT)) { colorNight = bundle.getInt(LINE_COLOR_NIGHT); } + if (bundle.containsKey(LINE_COLOR_GRADIENT)) { + scaleType = GradientScaleType.getGradientTypeByName(bundle.getString(LINE_COLOR_GRADIENT)); + } width = bundle.getString(LINE_WIDTH); iconId = bundle.getInt(NAVIGATION_ICON_ID); iconColor = bundle.getInt(NAVIGATION_ICON_COLOR); @@ -157,6 +175,9 @@ public class RouteLineDrawInfo { if (colorNight != null) { bundle.putInt(LINE_COLOR_NIGHT, colorNight); } + if (scaleType != null) { + bundle.putString(LINE_COLOR_GRADIENT, scaleType.getTypeName()); + } if (width != null) { bundle.putString(LINE_WIDTH, width); } @@ -177,6 +198,7 @@ public class RouteLineDrawInfo { if (!Algorithms.objectEquals(getColor(false), that.getColor(false))) return false; if (!Algorithms.objectEquals(getColor(true), that.getColor(true))) return false; + if (!Algorithms.objectEquals(scaleType, that.scaleType)) return false; return Algorithms.objectEquals(width, that.width); } @@ -184,6 +206,7 @@ public class RouteLineDrawInfo { public int hashCode() { int result = colorDay != null ? colorDay.hashCode() : 0; result = 31 * result + (colorNight != null ? colorNight.hashCode() : 0); + result = 31 * result + (scaleType != null ? scaleType.getTypeName().hashCode() : 0); result = 31 * result + (width != null ? width.hashCode() : 0); return result; } diff --git a/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java b/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java index dc6b10f9cd..f73371d643 100644 --- a/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java +++ b/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineColorCard.java @@ -21,6 +21,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.ColorDialogs; import net.osmand.plus.helpers.enums.DayNightMode; import net.osmand.plus.routepreparationmenu.cards.BaseCard; @@ -32,6 +33,8 @@ import net.osmand.plus.settings.fragments.HeaderUiAdapter; import net.osmand.plus.track.AppearanceViewHolder; import net.osmand.plus.track.ColorsCard; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; +import net.osmand.plus.track.GradientCard; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.widgets.MultiStateToggleButton; import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener; import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem; @@ -50,6 +53,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP private HeaderUiAdapter headerUiAdapter; private ColorsCard colorsCard; + private GradientCard gradientCard; private ColorTypeAdapter colorAdapter; private RecyclerView groupRecyclerView; private TextView tvDescription; @@ -63,7 +67,9 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP private enum ColorMode { DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style), - CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings); + CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings), + ALTITUDE(R.string.altitude, R.drawable.ic_action_hillshade_dark), + SLOPE(R.string.shared_string_slope, R.drawable.ic_action_altitude_ascent); ColorMode(int titleId, int iconId) { this.titleId = titleId; @@ -107,28 +113,43 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP setupRadioGroup(radioGroup); cardsContainer = (ViewGroup) view.findViewById(R.id.colors_card_container); - createColorSelector(cardsContainer); + createCards(cardsContainer); initSelectedMode(); } private void initSelectedMode() { - selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM; + if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.ALTITUDE) { + selectedMode = ColorMode.ALTITUDE; + } else if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.SLOPE) { + selectedMode = ColorMode.SLOPE; + } else { + selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM; + } modeChanged(); } private void modeChanged() { if (selectedMode == ColorMode.DEFAULT) { themeToggleContainer.setVisibility(View.GONE); - cardsContainer.setVisibility(View.GONE); + AndroidUiHelper.updateVisibility(colorsCard.getView(), false); + AndroidUiHelper.updateVisibility(gradientCard.getView(), false); routeLineDrawInfo.setUseDefaultColor(true); changeMapTheme(initMapTheme); - } else { + } else if (selectedMode == ColorMode.CUSTOM) { themeToggleContainer.setVisibility(View.VISIBLE); - cardsContainer.setVisibility(View.VISIBLE); + AndroidUiHelper.updateVisibility(colorsCard.getView(), true); + AndroidUiHelper.updateVisibility(gradientCard.getView(), false); routeLineDrawInfo.setUseDefaultColor(false); changeMapTheme(isNightMap() ? DayNightMode.NIGHT : DayNightMode.DAY); + } else { + gradientCard.setSelectedScaleType(getGradientScaleTypeFromMode()); + AndroidUiHelper.updateVisibility(colorsCard.getView(), false); + AndroidUiHelper.updateVisibility(gradientCard.getView(), true); + themeToggleContainer.setVisibility(View.GONE); + routeLineDrawInfo.setUseDefaultColor(false); } + routeLineDrawInfo.setGradientScaleType(getGradientScaleTypeFromMode()); updateColorItems(); updateDescription(); } @@ -169,7 +190,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP } } - private void createColorSelector(ViewGroup container) { + private void createCards(ViewGroup container) { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { List colors = new ArrayList<>(); @@ -183,6 +204,9 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP colorsCard = new ColorsCard(mapActivity, selectedColor, targetFragment, colors, preference, null); colorsCard.setListener(this); container.addView(colorsCard.build(mapActivity)); + + gradientCard = new GradientCard(mapActivity, routeLineDrawInfo.getGradientScaleType()); + container.addView(gradientCard.build(mapActivity)); } } @@ -211,6 +235,17 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP return routeLineDrawInfo.getColor(isNightMap()); } + @Nullable + private GradientScaleType getGradientScaleTypeFromMode() { + if (selectedMode == ColorMode.ALTITUDE) { + return GradientScaleType.ALTITUDE; + } else if (selectedMode == ColorMode.SLOPE) { + return GradientScaleType.SLOPE; + } else { + return null; + } + } + private void updateSelectedColor() { int selectedColor = colorsCard.getSelectedColor(); routeLineDrawInfo.setColor(selectedColor, isNightMap()); @@ -234,6 +269,8 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP String colorName = ""; if (selectedMode == ColorMode.DEFAULT) { colorName = app.getString(R.string.map_widget_renderer); + } else if (selectedMode == ColorMode.ALTITUDE || selectedMode == ColorMode.SLOPE) { + colorName = app.getString(selectedMode.titleId); } else if (getRouteLineColor() != null) { int colorNameId = ColorDialogs.getColorName(getRouteLineColor()); colorName = app.getString(colorNameId); @@ -247,10 +284,12 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP String pattern = app.getString(R.string.route_line_use_map_style_appearance); String color = app.getString(R.string.shared_string_color).toLowerCase(); description = String.format(pattern, color, app.getRendererRegistry().getSelectedRendererName()); - } else { + } else if (selectedMode == ColorMode.CUSTOM) { String pattern = app.getString(R.string.specify_color_for_map_mode); String mapModeTitle = app.getString(isNightMap() ? NIGHT_TITLE_ID : DAY_TITLE_ID); description = String.format(pattern, mapModeTitle.toLowerCase()); + } else { + description = app.getString(R.string.route_line_use_gradient_coloring); } tvDescription.setText(description); } @@ -367,4 +406,4 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP void onMapThemeUpdated(@NonNull DayNightMode mapTheme); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 1a77de50fb..c186146d81 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -2705,6 +2705,7 @@ public class OsmandSettings { public final ListStringPreference CUSTOM_ROUTE_LINE_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_route_line_colors", null, ",").makeShared().makeGlobal(); public final CommonPreference ROUTE_LINE_COLOR_DAY = new IntPreference(this, "route_line_color", 0).cache().makeProfile(); public final CommonPreference ROUTE_LINE_COLOR_NIGHT = new IntPreference(this, "route_line_color_night", 0).cache().makeProfile(); + public final CommonPreference ROUTE_LINE_GRADIENT = new EnumStringPreference<>(this, "route_line_gradient", null, new GradientScaleType[] {GradientScaleType.ALTITUDE, GradientScaleType.SLOPE}).cache().makeProfile(); public final CommonPreference ROUTE_LINE_WIDTH = new StringPreference(this, "route_line_width", null).makeProfile(); public final OsmandPreference USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeProfile(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java index c8d600315c..9bae7b1088 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ProfileAppearanceFragment.java @@ -63,6 +63,7 @@ import net.osmand.plus.settings.backend.backup.SettingsHelper; import net.osmand.plus.settings.fragments.RouteLineAppearanceFragment.OnApplyRouteLineListener; import net.osmand.plus.track.ColorsCard; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.widgets.FlowLayout; import net.osmand.plus.widgets.OsmandTextFieldBoxes; import net.osmand.util.Algorithms; @@ -1021,8 +1022,9 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O private RouteLineDrawInfo createRouteLineDrawInfo(@NonNull ApplicationMode appMode) { Integer colorDay = getRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_DAY); Integer colorNight = getRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_NIGHT); + GradientScaleType scaleType = settings.ROUTE_LINE_GRADIENT.getModeValue(appMode); String widthKey = settings.ROUTE_LINE_WIDTH.getModeValue(appMode); - return new RouteLineDrawInfo(colorDay, colorNight, widthKey); + return new RouteLineDrawInfo(colorDay, colorNight, scaleType, widthKey); } private Integer getRouteLineColor(@NonNull ApplicationMode appMode, @@ -1035,6 +1037,7 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O @NonNull RouteLineDrawInfo drawInfo) { saveRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_DAY, drawInfo.getColor(false)); saveRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_NIGHT, drawInfo.getColor(true)); + settings.ROUTE_LINE_GRADIENT.setModeValue(appMode, drawInfo.getGradientScaleType()); settings.ROUTE_LINE_WIDTH.setModeValue(appMode, drawInfo.getWidth()); } diff --git a/OsmAnd/src/net/osmand/plus/track/GradientCard.java b/OsmAnd/src/net/osmand/plus/track/GradientCard.java index 3c34d9f68d..de2623decf 100644 --- a/OsmAnd/src/net/osmand/plus/track/GradientCard.java +++ b/OsmAnd/src/net/osmand/plus/track/GradientCard.java @@ -19,15 +19,24 @@ import androidx.annotation.Nullable; public class GradientCard extends BaseCard { - private GPXTrackAnalysis gpxTrackAnalysis; + private final GPXTrackAnalysis gpxTrackAnalysis; private GradientScaleType selectedScaleType; + private final int minSlope = 0; + private final int maxSlope = 60; + public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis, @Nullable GradientScaleType selectedScaleType) { super(mapActivity); this.gpxTrackAnalysis = gpxTrackAnalysis; this.selectedScaleType = selectedScaleType; } + public GradientCard(@NonNull MapActivity mapActivity, @Nullable GradientScaleType scaleType) { + super(mapActivity); + this.gpxTrackAnalysis = null; + this.selectedScaleType = scaleType; + } + @Override public int getCardLayoutId() { return R.layout.gradient_card; @@ -40,14 +49,27 @@ public class GradientCard extends BaseCard { return; } - AndroidUiHelper.updateVisibility(view, true); TextView minValue = view.findViewById(R.id.min_value); TextView maxValue = view.findViewById(R.id.max_value); - double min = RouteColorize.getMinValue(selectedScaleType.toColorizationType(), gpxTrackAnalysis); - double max = RouteColorize.getMaxValue(selectedScaleType.toColorizationType(), - gpxTrackAnalysis, min, app.getSettings().getApplicationMode().getMaxSpeed()); - minValue.setText(formatValue(min)); - maxValue.setText(formatValue(max)); + + if (gpxTrackAnalysis != null) { + AndroidUiHelper.updateVisibility(view, true); + double min = RouteColorize.getMinValue(selectedScaleType.toColorizationType(), gpxTrackAnalysis); + double max = RouteColorize.getMaxValue(selectedScaleType.toColorizationType(), + gpxTrackAnalysis, min, app.getSettings().getApplicationMode().getMaxSpeed()); + minValue.setText(formatValue(min)); + maxValue.setText(formatValue(max)); + AndroidUiHelper.updateVisibility(view.findViewById(R.id.space), true); + } else { + if (selectedScaleType == GradientScaleType.ALTITUDE) { + minValue.setText(R.string.shared_string_min_height); + maxValue.setText(R.string.shared_string_max_height); + } else if (selectedScaleType == GradientScaleType.SLOPE) { + minValue.setText(formatValue(minSlope)); + maxValue.setText(formatValue(maxSlope)); + } + AndroidUiHelper.updateVisibility(view.findViewById(R.id.space), false); + } } public void setSelectedScaleType(GradientScaleType type) { @@ -59,7 +81,7 @@ public class GradientCard extends BaseCard { if (selectedScaleType == GradientScaleType.ALTITUDE) { return OsmAndFormatter.getFormattedAlt(value, app); } else if (selectedScaleType == GradientScaleType.SLOPE) { - return (int) value + " %"; + return app.getString(R.string.ltr_or_rtl_combine_via_space, String.valueOf((int) value), "%"); } String speed = OsmAndFormatter.getFormattedSpeed((float) value, app); String speedUnit = app.getSettings().SPEED_SYSTEM.get().toShortString(app); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java index e74b0242ce..9ebf2eb093 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/RouteLayer.java @@ -344,15 +344,17 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { int centerY = drawInfo.getCenterY(); int screenHeight = drawInfo.getScreenHeight(); + updateRouteColors(nightMode); + updateRouteGradient(); + + LinearGradient gradient = null; 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()); + gradient = new LinearGradient(centerX, 0, centerX, screenHeight, colors, positions, Shader.TileMode.CLAMP); } + paintRouteLinePreview.setShader(gradient); + paintRouteLinePreview.setColor(getRouteLineColor()); canvas.drawLine(centerX, 0, centerX, screenHeight, paintRouteLinePreview); @@ -475,6 +477,14 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { routeLineColor = color; } + private void updateRouteGradient() { + if (routeLineDrawInfo != null) { + gradientScaleType = routeLineDrawInfo.getGradientScaleType(); + } else { + gradientScaleType = view.getSettings().ROUTE_LINE_GRADIENT.getModeValue(helper.getAppMode()); + } + } + private float getRouteLineWidth(@NonNull RotatedTileBox tileBox) { String widthKey; if (routeLineDrawInfo != null) { @@ -539,9 +549,10 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider { boolean directTo = route.getRouteService() == RouteService.DIRECT_TO; boolean straight = route.getRouteService() == RouteService.STRAIGHT; publicTransportRouteGeometry.clearRoute(); + updateRouteColors(nightMode); + updateRouteGradient(); routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor(), gradientScaleType); routeGeometry.updateRoute(tb, route, view.getApplication()); - updateRouteColors(nightMode); if (directTo) { routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude, null, 0); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index 314e299760..28eef91f07 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -35,6 +35,7 @@ public class RouteGeometryWay extends GeometryWay Date: Fri, 16 Apr 2021 19:23:54 +0500 Subject: [PATCH 05/15] Small fixes --- .../java/net/osmand/router/RouteColorize.java | 2 + .../views/layers/geometry/GeometryWay.java | 7 ++ .../layers/geometry/GeometryWayContext.java | 4 ++ .../layers/geometry/RouteGeometryWay.java | 66 ++++++++++--------- .../geometry/RouteGeometryWayDrawer.java | 1 - 5 files changed, 47 insertions(+), 33 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 62186a8bb3..0db39d0695 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -266,6 +266,8 @@ public class RouteColorize { List sublist = dataList.subList(prevId, currentId); simplified.addAll(getExtremums(sublist)); } + Node lastSurvivedPoint = result.get(result.size() - 1); + simplified.add(dataList.get((int) lastSurvivedPoint.getId())); return simplified; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java index 2cfb950200..9bb4bf9445 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -139,6 +139,11 @@ public abstract class GeometryWay getDefaultWayStyle(); + @NonNull + protected Map> getStyleMap() { + return styleMap; + } + public Location getNextVisiblePoint() { return null; } @@ -380,6 +385,8 @@ public abstract class GeometryWay style : getStyleMap().values()) { + style.width = width; + } + } this.customColor = color; this.customWidth = width; this.customPointColor = pointColor; @@ -54,50 +60,46 @@ public class RouteGeometryWay extends GeometryWay locations = route != null ? route.getImmutableAllLocations() : Collections.emptyList(); + + if (scaleType == null || locations.size() < 2) { + updateWay(locations, tb); + return; + } + GPXFile gpxFile = GpxUiHelper.makeGpxFromRoute(route, app); + if (!gpxFile.hasAltitude) { + updateWay(locations, tb); + return; + } + + // Start point can have wrong zero altitude + List pts = gpxFile.tracks.get(0).segments.get(0).points; + GPXUtilities.WptPt firstPt = pts.get(0); + if (firstPt.ele == 0) { + firstPt.ele = pts.get(1).ele; + } + + RouteColorize routeColorize = new RouteColorize(tb.getZoom(), gpxFile, null, scaleType.toColorizationType(), 0); + List points = routeColorize.getResult(false); + + updateWay(new GradientGeometryWayProvider(routeColorize, points), createStyles(points), tb); } - - this.route = route; - List locations = route != null ? route.getImmutableAllLocations() : Collections.emptyList(); - - if (scaleType == null || locations.size() < 2) { - updateWay(locations, tb); - return; - } - GPXFile gpxFile = GpxUiHelper.makeGpxFromRoute(route, app); - if (!gpxFile.hasAltitude) { - updateWay(locations, tb); - return; - } - - // Start point can have wrong zero altitude - List pts = gpxFile.tracks.get(0).segments.get(0).points; - GPXUtilities.WptPt firstPt = pts.get(0); - if (firstPt.ele == 0) { - firstPt.ele = pts.get(1).ele; - } - - RouteColorize routeColorize = new RouteColorize(tb.getZoom(), gpxFile, null, scaleType.toColorizationType(), 0); - List points = routeColorize.getResult(false); - - updateWay(new GradientGeometryWayProvider(routeColorize), createStyles(points), tb); } private Map> createStyles(List points) { Map> 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; } @@ -183,9 +185,9 @@ public class RouteGeometryWay extends GeometryWay locations; - public GradientGeometryWayProvider(RouteColorize routeColorize) { + public GradientGeometryWayProvider(RouteColorize routeColorize, List locations) { this.routeColorize = routeColorize; - locations = routeColorize.getResult(false); + this.locations = locations; } public List simplify(int zoom) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java index 060370e546..746283a180 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java @@ -44,7 +44,6 @@ public class RouteGeometryWayDrawer extends GeometryWayDrawer Date: Sun, 18 Apr 2021 14:43:07 +0500 Subject: [PATCH 06/15] Fix border type switching --- .../plus/views/layers/geometry/RouteGeometryWayDrawer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java index 746283a180..1f613aecd5 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWayDrawer.java @@ -14,7 +14,7 @@ import java.util.List; public class RouteGeometryWayDrawer extends GeometryWayDrawer { - private final int BORDER_TYPE_ZOOM_THRESHOLD = MapTileLayer.DEFAULT_MIN_ZOOM; + private static final int BORDER_TYPE_ZOOM_THRESHOLD = MapTileLayer.DEFAULT_MAX_ZOOM + MapTileLayer.OVERZOOM_IN; private final boolean drawBorder; @@ -25,7 +25,7 @@ public class RouteGeometryWayDrawer extends GeometryWayDrawer>> paths) { - if (drawBorder && zoom > BORDER_TYPE_ZOOM_THRESHOLD) { + if (drawBorder && zoom < BORDER_TYPE_ZOOM_THRESHOLD) { Paint borderPaint = getContext().getAttrs().shadowPaint; Path fullPath = new Path(); for (Pair> path : paths) { @@ -50,7 +50,7 @@ public class RouteGeometryWayDrawer extends GeometryWayDrawer style) { - if (drawBorder && zoom < BORDER_TYPE_ZOOM_THRESHOLD) { + if (drawBorder && zoom >= BORDER_TYPE_ZOOM_THRESHOLD) { canvas.drawPath(path, getContext().getAttrs().shadowPaint); } } From 4de1aa9193f8f646f360918f0b8dc149691af04e Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 21 Apr 2021 23:51:15 +0500 Subject: [PATCH 07/15] Fix crash and other fixes --- .../java/net/osmand/router/RouteColorize.java | 2 +- .../net/osmand/plus/helpers/GpxUiHelper.java | 18 +++++------------- .../layers/geometry/RouteGeometryWay.java | 12 +++++------- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java index 0db39d0695..ece3b01a38 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -200,7 +200,7 @@ public class RouteColorize { public int getColorByValue(double value) { if (Double.isNaN(value)) { - value = (minValue + maxValue) / 2; + value = colorizationType == ColorizationType.SLOPE ? minValue : (minValue + maxValue) / 2; } for (int i = 0; i < palette.length - 1; i++) { if (value == palette[i][VALUE_INDEX]) diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index 9d6b019cc2..75d62d6f0a 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -2124,9 +2124,12 @@ public class GpxUiHelper { public static GPXFile makeGpxFromRoute(RouteCalculationResult route, OsmandApplication app) { + return makeGpxFromLocations(route.getRouteLocations(), app); + } + + public static GPXFile makeGpxFromLocations(List locations, OsmandApplication app) { double lastHeight = HEIGHT_UNDEFINED; GPXFile gpx = new GPXUtilities.GPXFile(Version.getFullVersion(app)); - List locations = route.getRouteLocations(); if (locations != null) { GPXUtilities.Track track = new GPXUtilities.Track(); GPXUtilities.TrkSegment seg = new GPXUtilities.TrkSegment(); @@ -2139,8 +2142,7 @@ public class GpxUiHelper { float h = (float) l.getAltitude(); point.ele = h; if (lastHeight == HEIGHT_UNDEFINED && seg.points.size() > 0) { - for (int i = seg.points.size() - 1; i >= 0; i--) { - GPXUtilities.WptPt pt = seg.points.get(i); + for (GPXUtilities.WptPt pt : seg.points) { if (Double.isNaN(pt.ele)) { pt.ele = h; } @@ -2152,16 +2154,6 @@ public class GpxUiHelper { } seg.points.add(point); } - if (lastHeight == HEIGHT_UNDEFINED && gpx.hasAltitude) { - int start = seg.points.size() - 1; - while (start > 0 && Double.isNaN(seg.points.get(start).ele)) { - start--; - } - double ele = seg.points.get(start).ele; - for (int i = start + 1; i < seg.points.size(); i++) { - seg.points.get(i).ele = ele; - } - } track.segments.add(seg); gpx.tracks.add(track); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java index 8d3ff947e9..a21a6ad29a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/RouteGeometryWay.java @@ -72,7 +72,7 @@ public class RouteGeometryWay extends GeometryWay Date: Wed, 21 Apr 2021 22:39:40 +0000 Subject: [PATCH 08/15] Translated using Weblate (Portuguese) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-pt/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index 9665801ba0..b8a308ae35 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -2013,7 +2013,7 @@ Utilizar dados de elevação Mostrar pontos e contornos de profundidade. Contornos de profundidade náuticos - Mostra a transparência da barra de navegação + Mostrar barra deslizante de transparência Widgets Objetos subterrâneos Dividir automaticamente as gravações após quebras From 2437fb722a9bac134219b1fdafceec89f496f7b4 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Thu, 22 Apr 2021 12:08:50 +0000 Subject: [PATCH 09/15] Translated using Weblate (Japanese) Currently translated at 98.4% (3663 of 3721 strings) --- OsmAnd/res/values-ja/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index fdca4a0e3b..aa933b4c1b 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -3843,7 +3843,7 @@ POIの更新は利用できません OsmAndLiveサブスクリプションの有効期限が切れました OsmAndLiveサブスクリプションが一時停止されました OsmAndLiveサブスクリプションは保留中です - マーカーの履歴 + マーカー履歴 GPXファイルをOpenStreetMapに送信 タグはカンマで区切って入力してください。 \"公開 \"状態は、追跡機能にてユーザーのGPS追跡、公開GPS追跡リスト、および生データのタイムスタンプ付き公開追跡リストに公開されることを意味します。APIを介して提供されるデータはユーザーの追跡ページを参照しません。追跡ポイントのタイムスタンプはパブリックGPS APIでは利用できず、また追跡ポイントは時系列に並んでいません。 From 3754cf782287d41002bca1f99bbc82ca22ffc9de Mon Sep 17 00:00:00 2001 From: Evgenii Martynenko Date: Thu, 22 Apr 2021 05:38:50 +0000 Subject: [PATCH 10/15] Translated using Weblate (Russian) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-ru/strings.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 726ed7bd3d..c4eb644806 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -2872,7 +2872,7 @@ Посадка на остановке Включить общественный транспорт с учётом автообновлений OsmAnd Live. Общественный транспорт OsmAnd Live - %1$d пересадки + пересадки: %1$d Грунтовая Песок Трава @@ -3263,7 +3263,7 @@ Выбранный профиль Персональный Скачивание %s - Толсто + Толстая Используется для оценки времени прибытия для неизвестного типа дорог и ограничения скорости для всех дорог (может изменить маршрут) Разрешить промежуточные маршруты Разрешить расширенные маршруты @@ -3302,7 +3302,7 @@ Соединение Симулировать свою позицию используя записанный GPX трек. Начало маршрута - Вернуться + Сброс Эти карты необходимо использовать с плагином. Добавленные профили Профили, добавленные плагином @@ -4056,7 +4056,11 @@ Следующая дата оплаты: %1$s OsmAnd Live Годовая подписка - • Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления». + • Добавлена возможность скачать контурные линии в футах. +\n +\n• Планирование маршрута: добавлены вкладки для переключения между точками и графиками. +\n +\n• Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления». \n \n• Теперь треки можно раскрашивать по высоте, скорости или уклону. \n @@ -4087,4 +4091,8 @@ Вывод %1$s → … Номер съезда + Формат единиц на контурных линиях + Выберите необходимый формат. Для изменения формата потребуется повторно загрузить файл. + футы + OsmAnd предоставляет данные изолиний в метрах и футах. Вам нужно будет повторно загрузить файл, чтобы изменить формат. \ No newline at end of file From 22237493a6296ae125a902bfddae665faab1e5fd Mon Sep 17 00:00:00 2001 From: ace shadow Date: Thu, 22 Apr 2021 00:30:43 +0000 Subject: [PATCH 11/15] Translated using Weblate (Slovak) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-sk/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 77dc42838a..b549707aeb 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -4045,7 +4045,11 @@ Všetky neuložené údaje budú stratené. Zobraziť úvodné okno Ak je vypnuté, záznam začne hneď po stlačení nástroja alebo položky v menu a preskočí okno nastavenia. - • Aktualizácie OsmAnd Live presunuté do \"Sťahovania > Aktualizácie\" + • Pridaná možnosť stiahnutia Vrstevníc v stopách +\n +\n• Plánovať trasy: pridané prepínače medzi bodmi a grafmi +\n +\n• Aktualizácie OsmAnd Live presunuté do \"Sťahovania > Aktualizácie\" \n \n • Stopy je teraz možné vyfarbiť podľa nadmorskej výšky, rýchlosti alebo sklonu svahu. \n @@ -4081,4 +4085,8 @@ Body používateľa Výstup %1$s → … + stopy + Formát jednotiek vrstevníc + OsmAnd poskytuje údaje vrstevníc v metroch a stopách. Budete musieť znovu stiahnuť súbor pre zmenu formátu. + Prosím zvoľte požadovaný formát. Budete musieť znovu stiahnuť súbor pre zmenu formátu. \ No newline at end of file From d1fb9d5129ff5978810bfefe0fb50c2daecc66b0 Mon Sep 17 00:00:00 2001 From: Zmicer Turok Date: Thu, 22 Apr 2021 07:33:55 +0000 Subject: [PATCH 12/15] Translated using Weblate (Belarusian) Currently translated at 98.0% (3648 of 3721 strings) --- OsmAnd/res/values-be/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-be/strings.xml b/OsmAnd/res/values-be/strings.xml index 109b223e99..299e12eead 100644 --- a/OsmAnd/res/values-be/strings.xml +++ b/OsmAnd/res/values-be/strings.xml @@ -1088,7 +1088,7 @@ Японская Карэйская Латышская - Летувісская + Летувіская Маратхі Нарвежская (Bokmål) Польская From 92d59f6521a67add5af7cf69d1faf576815d73c6 Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Wed, 21 Apr 2021 21:13:07 +0000 Subject: [PATCH 13/15] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 18e838ce27..a6b0528e89 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4049,15 +4049,19 @@ Linha de rota A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s. Especifique a cor para o modo de mapa: %1$s. - • As atualizações do OsmAnd Live foram movidas para \"Downloads > Atualizações\" + "• Adicionada opção para baixar curvas de nível em pés \n -\n• As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação. +\n • Plano de paisagem da rota: guias adicionadas para alternar entre pontos ou gráficos \n -\n• Adicionada opção para alterar a aparência da linha da rota de navegação +\n • As atualizações do OsmAnd Live foram movidas para \"Downloads> Atualizações\" \n -\n• Caixa de diálogo \"Gravação de viagem\" atualizada +\n • As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação. \n -\n +\n • Adicionada opção para alterar a aparência da linha da rota de navegação +\n +\n • Caixa de diálogo \"Gravação de viagem\" atualizada +\n +\n" Você não tem nenhuma compra Novo dispositivo / nova conta Se você tiver alguma dúvida, entre em contato conosco em %1$s. @@ -4081,4 +4085,8 @@ Pontos do usuário Saída %1$s → … + pés + Formato da unidade de curvas de nível + OsmAnd fornece dados de linhas de contorno em metros e pés. Você precisará baixar novamente o arquivo para alterar o formato. + Selecione o formato necessário. Você precisará baixar novamente o arquivo para alterar o formato. \ No newline at end of file From 74efa9f2b8cfa611c598d500064c8b4ca6ade01d Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Wed, 21 Apr 2021 21:14:04 +0000 Subject: [PATCH 14/15] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3927 of 3927 strings) --- OsmAnd/res/values-pt-rBR/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml index 12ab9fa85f..97e8722e1c 100644 --- a/OsmAnd/res/values-pt-rBR/phrases.xml +++ b/OsmAnd/res/values-pt-rBR/phrases.xml @@ -3927,4 +3927,5 @@ Mergulho de falésia Zurkhaneh Tipo de baía + Ultimate \ No newline at end of file From aa2c111e881d32c683af192f1b50e0234d8942b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Morais?= Date: Wed, 21 Apr 2021 19:33:43 +0000 Subject: [PATCH 15/15] Translated using Weblate (Portuguese) Currently translated at 100.0% (3927 of 3927 strings) --- OsmAnd/res/values-pt/phrases.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-pt/phrases.xml b/OsmAnd/res/values-pt/phrases.xml index 5ae2a5c536..6b4e191f7e 100644 --- a/OsmAnd/res/values-pt/phrases.xml +++ b/OsmAnd/res/values-pt/phrases.xml @@ -193,7 +193,7 @@ Ponte pedonal em pedras separadas Passo de montanha Portão - Muralha de cidade + Muralha/cerca de cidade Cancela elevatória Cabine de portagem Controlo aduaneiro @@ -637,13 +637,13 @@ Futebol australiano Base jumping Beisebol - Basquete + Basquetebol Voleibol de praia BMX Bocha Lawn bowls Futebol canadiano - Canoa + Canoagem Xadrez Escalada Críquete @@ -694,7 +694,7 @@ Marco de fronteira Canhão histórico Castelo - Portão/arco de cidade + Portão/porta/arco de cidade Forte Chafariz Ruínas históricas @@ -707,7 +707,7 @@ Aquário Parque de diversões Atração turística - Objeto turístico + Elemento turístico Atracão de feira Animal (atração) Roda gigante @@ -2866,9 +2866,9 @@ Aquicultura: mexilhões Rede de distribuição principal (MDF) Idade mínima - Sim - Não - Unicamente + Produtos orgânicos: sim + Produtos orgânicos: não + Produtos orgânicos: unicamente Espelho de tráfego Consulado Consulado geral @@ -3746,7 +3746,7 @@ Sexo comunitário: masculino Sexo comunitário: misto Sepultura - Espaço de estacionamento + Lugar de estacionamento (1 veículo) URL Tipo Estado