From 1ce5313dfd570174f023c2be3fdbd299c9d61f4d Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 30 Mar 2021 23:53:18 +0300 Subject: [PATCH 01/32] Data storage folder show second slash "/" for path goes to the second line. --- .../datastorage/DataStorageFragment.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java index 41c58ebd7f..57da72c4cc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java @@ -234,7 +234,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto ivIcon.setImageDrawable(icon); if (currentKey.equals(MANUALLY_SPECIFIED)) { - tvSummary.setText(item.getDirectory()); + setFormattedPath(item, tvSummary); secondPart.setVisibility(View.GONE); tvAdditionalDescription.setVisibility(View.GONE); divider.setVisibility(View.GONE); @@ -252,15 +252,8 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } if (currentKey.equals(INTERNAL_STORAGE)) { tvAdditionalDescription.setText(item.getDescription()); - } else if (currentKey.equals(SHARED_STORAGE)) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - BidiFormatter rtlFormatter = BidiFormatter.getInstance(); - tvAdditionalDescription.setText(rtlFormatter.unicodeWrap(item.getDirectory())); - } else { - tvAdditionalDescription.setText(String.format("\u200E%s", item.getDirectory())); - } } else { - tvAdditionalDescription.setText(item.getDirectory()); + setFormattedPath(item, tvAdditionalDescription); } } } @@ -310,6 +303,15 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } } + private void setFormattedPath(StorageItem item, TextView tvAdditionalDescription) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + BidiFormatter pathRtlFormatter = BidiFormatter.getInstance(); + tvAdditionalDescription.setText(pathRtlFormatter.unicodeWrap(item.getDirectory())); + } else { + tvAdditionalDescription.setText(String.format("\u200E%s", item.getDirectory())); + } + } + @Override public void onDestroy() { if (!activity.isChangingConfigurations()) { From 8f8d4366d48fa1e544b56573744e0f367d802d9a Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 31 Mar 2021 13:01:16 +0300 Subject: [PATCH 02/32] Please re-check the "Terrain" menu empty state, it looks strange, why URL is on the first line? Other rtl languages work fine: Persian, Hebrew. Arabic may have its own characteristics , so its hardcoded in commit. --- .../plus/srtmplugin/TerrainFragment.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java index 1475a0a7fd..6583dea040 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java @@ -21,7 +21,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; -import androidx.core.content.ContextCompat; import com.github.ksoichiro.android.observablescrollview.ObservableListView; import com.google.android.material.slider.RangeSlider; @@ -50,14 +49,16 @@ import org.apache.commons.logging.Log; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.List; +import java.util.Locale; -import static net.osmand.plus.UiUtilities.CustomRadioButtonType.*; +import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END; +import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START; import static net.osmand.plus.download.DownloadActivityType.HILLSHADE_FILE; import static net.osmand.plus.download.DownloadActivityType.SLOPE_FILE; -import static net.osmand.plus.srtmplugin.TerrainMode.HILLSHADE; -import static net.osmand.plus.srtmplugin.TerrainMode.SLOPE; import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MAX_ZOOM; import static net.osmand.plus.srtmplugin.SRTMPlugin.TERRAIN_MIN_ZOOM; +import static net.osmand.plus.srtmplugin.TerrainMode.HILLSHADE; +import static net.osmand.plus.srtmplugin.TerrainMode.SLOPE; public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickListener, @@ -102,7 +103,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL private ArrayAdapter listAdapter; - private Slider.OnChangeListener transparencySliderChangeListener = new Slider.OnChangeListener() { + private final Slider.OnChangeListener transparencySliderChangeListener = new Slider.OnChangeListener() { @Override public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) { if (fromUser) { @@ -114,7 +115,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL } }; - private RangeSlider.OnChangeListener zoomSliderChangeListener = new RangeSlider.OnChangeListener() { + private final RangeSlider.OnChangeListener zoomSliderChangeListener = new RangeSlider.OnChangeListener() { @Override public void onValueChange(@NonNull RangeSlider slider, float value, boolean fromUser) { List values = slider.getValues(); @@ -186,11 +187,13 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL getString(R.string.slope_read_more), wikiString ); - String emptyStateText = String.format( - getString(R.string.ltr_or_rtl_combine_via_space), - getString(R.string.terrain_empty_state_text), - PLUGIN_URL - ); + boolean isArabicLocale = Locale.getDefault().getLanguage().equals("ar"); + String emptyStateText; + if (isArabicLocale) { + emptyStateText = getString(R.string.terrain_empty_state_text) + "\n" + PLUGIN_URL; + } else { + emptyStateText = String.format(getString(R.string.ltr_or_rtl_combine_via_space), getString(R.string.terrain_empty_state_text), PLUGIN_URL); + } setupClickableText(slopeReadMoreTv, readMoreText, wikiString, SLOPES_WIKI_URL, false); setupClickableText(emptyStateDescriptionTv, emptyStateText, PLUGIN_URL, PLUGIN_URL, true); @@ -269,7 +272,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL } private void adjustGlobalVisibility() { - emptyState.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE); + emptyState.setVisibility(View.VISIBLE); titleBottomDivider.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE); contentContainer.setVisibility(terrainEnabled ? View.VISIBLE : View.GONE); } @@ -290,10 +293,10 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL } private void setupClickableText(TextView textView, - String text, - String clickableText, - final String url, - final boolean medium) { + String text, + String clickableText, + final String url, + final boolean medium) { SpannableString spannableString = new SpannableString(text); ClickableSpan clickableSpan = new ClickableSpan() { @Override From 762e574bf0f5e5f7a8b90d3a3d5ee4cd0aa5cb8c Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 31 Mar 2021 22:51:30 +0500 Subject: [PATCH 03/32] Use profile color for plan route lines --- .../MeasurementEditingContext.java | 6 +- .../measurementtool/MeasurementToolLayer.java | 55 +++- .../views/layers/geometry/GeometryWay.java | 15 +- .../layers/geometry/GeometryWayContext.java | 3 +- .../geometry/MultiProfileGeometryWay.java | 252 ++++++++++++++++++ .../MultiProfileGeometryWayContext.java | 85 ++++++ .../MultiProfileGeometryWayDrawer.java | 32 +++ 7 files changed, 432 insertions(+), 16 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java create mode 100644 OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java create mode 100644 OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index 3512de68bc..bda7c5404b 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -1111,8 +1111,12 @@ public class MeasurementEditingContext implements IRouteSettingsListener { return res; } + public boolean isInMultiProfileMode() { + return lastCalculationMode == CalculationMode.NEXT_SEGMENT; + } + @Override public void onRouteSettingsChanged(@Nullable ApplicationMode mode) { recalculateRouteSegments(mode); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 3c6bcf6c89..7ab66f44b2 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -23,6 +23,8 @@ import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.Renderable; import net.osmand.plus.views.layers.ContextMenuLayer; import net.osmand.plus.views.layers.geometry.GeometryWay; +import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay; +import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWayContext; import net.osmand.util.MapUtils; import java.util.ArrayList; @@ -33,20 +35,28 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL private OsmandMapTileView view; private boolean inMeasurementMode; + private Bitmap centerIconDay; private Bitmap centerIconNight; private Bitmap pointIcon; private Bitmap applyingPointIcon; private Paint bitmapPaint; private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine"); + private final RenderingLineAttributes multiProfileLineAttrs = new RenderingLineAttributes("multiProfileMeasureDistanceLine"); + + private MultiProfileGeometryWay multiProfileGeometry; + private MultiProfileGeometryWayContext multiProfileGeometryWayContext; + private int marginPointIconX; private int marginPointIconY; private int marginApplyingPointIconX; private int marginApplyingPointIconY; private final Path path = new Path(); + private final List tx = new ArrayList<>(); private final List ty = new ArrayList<>(); private OnMeasureDistanceToCenter measureDistanceToCenterListener; + private OnSingleTapListener singleTapListener; private OnEnterMovePointModeListener enterMovePointModeListener; private LatLon pressedPointLatLon; @@ -63,6 +73,18 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL pointIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_measure_point_day); applyingPointIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_measure_point_move_day); + float density = view.getDensity(); + multiProfileLineAttrs.isPaint_1 = false; + multiProfileLineAttrs.paint_1.setColor(0xFFFFFFFF); + multiProfileLineAttrs.paint_1.setStyle(Paint.Style.FILL); + multiProfileLineAttrs.paint.setStrokeWidth(density * 14); + multiProfileLineAttrs.paint2.setStrokeWidth(density * 10); + multiProfileLineAttrs.isPaint3 = false; + multiProfileLineAttrs.paint3.setStrokeWidth(density * 2); + + multiProfileGeometryWayContext = new MultiProfileGeometryWayContext(view.getContext(), density); + multiProfileGeometry = new MultiProfileGeometryWay(multiProfileGeometryWayContext); + bitmapPaint = new Paint(); bitmapPaint.setAntiAlias(true); bitmapPaint.setDither(true); @@ -194,15 +216,28 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL } } - List before = editingCtx.getBeforeTrkSegmentLine(); - for (TrkSegment segment : before) { - new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2). - drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb); - } - List after = editingCtx.getAfterTrkSegmentLine(); - for (TrkSegment segment : after) { - new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2). - drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb); + if (editingCtx.isInMultiProfileMode()) { + multiProfileGeometryWayContext.updatePaints(settings.isNightMode(), multiProfileLineAttrs); + for (int i = 0; i < editingCtx.getBeforeSegments().size(); i++) { + multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), true, editingCtx.getBeforeSegments(), i); + multiProfileGeometry.drawSegments(canvas, tb); + } + for (int i = 0; i < editingCtx.getAfterSegments().size(); i++) { + multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), false, editingCtx.getAfterSegments(), i); + multiProfileGeometry.drawSegments(canvas, tb); + } + } else { + List before = editingCtx.getBeforeTrkSegmentLine(); + for (TrkSegment segment : before) { + new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2). + drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb); + } + + List after = editingCtx.getAfterTrkSegmentLine(); + for (TrkSegment segment : after) { + new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2). + drawSegment(view.getZoom(), lineAttrs.paint, canvas, tb); + } } drawPoints(canvas, tb); @@ -509,4 +544,4 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL interface OnMeasureDistanceToCenter { void onMeasure(float distance, float bearing); } -} +} \ No newline at end of file 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 9c7fd1c782..cc1633839e 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -174,8 +174,8 @@ public abstract class GeometryWay style, List tx, List ty, List angles, List distances, double dist, List> styles) { @@ -333,7 +340,7 @@ public abstract class GeometryWay tx, List ty, + protected void drawRouteSegment(RotatedTileBox tb, Canvas canvas, List tx, List ty, List angles, List distances, double distToFinish, List> styles) { if (tx.size() < 2) { return; @@ -449,4 +456,4 @@ public abstract class GeometryWay { + + private static final String DEFAULT_PROFILE_KEY = ApplicationMode.DEFAULT.getStringKey(); + + private Map, RoadSegmentData> segmentData; + private List beforeSegments; + private List afterSegments; + + public MultiProfileGeometryWay(MultiProfileGeometryWayContext context) { + super(context, new MultiProfileGeometryWayDrawer(context)); + } + + public void drawSegments(Canvas canvas, RotatedTileBox tileBox) { + QuadRect bounds = tileBox.getLatLonBounds(); + drawSegments(tileBox, canvas, bounds.top, bounds.left, bounds.bottom, bounds.right, null, 0); + } + + @Override + protected void drawRouteSegment(RotatedTileBox tb, Canvas canvas, List tx, List ty, List angles, List distances, double distToFinish, List> styles) { + if (tx.size() < 2) { + return; + } + try { + List>> pathStyles = new ArrayList<>(); + canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); + calculatePath(tb, tx, ty, styles, pathStyles); + + for (int i = 0; i < pathStyles.size(); i++) { + Pair> currPathStyle = pathStyles.get(i); + getDrawer().drawPathBorder(canvas, currPathStyle.first, currPathStyle.second); + getDrawer().drawPath(canvas, currPathStyle.first, currPathStyle.second); + } +// drawer.drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles); + } finally { + canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); + } + } + + public void updateRoute(RotatedTileBox tileBox, Map, RoadSegmentData> segmentData, + boolean before, List segments, int segmentIdx) { + boolean shouldUpdateRoute = tileBox.getMapDensity() != getMapDensity() || segmentDataChanged(segmentData) + || getSegments(before) != segments || true; + if (shouldUpdateRoute && segments.get(segmentIdx).points.size() >= 2) { + this.segmentData = segmentData; + setSegments(before, segments); + List userPoints = segments.get(segmentIdx).points; + List locations; + Map> styleMap; + + List ways = new ArrayList<>(); + List> styles = new ArrayList<>(); + setStyles(userPoints, ways, styles); + locations = new ArrayList<>(); + + styleMap = new TreeMap<>(); + int i = 0; + int k = 0; + if (ways.size() > 0) { + for (Way w : ways) { + styleMap.put(k, styles.get(i++)); + for (Node n : w.getNodes()) { + Location ln = new Location(""); + ln.setLatitude(n.getLatitude()); + ln.setLongitude(n.getLongitude()); + locations.add(ln); + k++; + } + } + } + + updateWay(locations, styleMap, tileBox); + } + } + + private void setStyles(List userPoints, List ways, List> styles) { + String prevProfileKey = ""; + Way way = new Way(-2); + + for (int i = 0; i < userPoints.size() - 1; i++) { + WptPt leftPt = userPoints.get(i); + Pair userLine = new Pair<>(leftPt, userPoints.get(i + 1)); + RoadSegmentData routeBetweenPoints = segmentData.get(userLine); + + if (!prevProfileKey.equals(getProfileKey(leftPt)) && !leftPt.isGap()) { + way = new Way(-2); + String currProfileKey = getProfileKey(leftPt); + Pair profileData = getProfileData(currProfileKey); + styles.add(new GeometryMultiProfileWayStyle(getContext(), profileData.first, profileData.second)); + ways.add(way); + prevProfileKey = currProfileKey; + } + + boolean isSecondToLast = i + 2 == userPoints.size(); + if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { + way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); + if (isSecondToLast) { + way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); + } + } else { + for (WptPt pt : routeBetweenPoints.getPoints()) { + if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { + way.addNode(new Node(pt.lat, pt.lon, -1)); + } + } + } + } + } + + @Override + protected boolean shouldAddLocation(double leftLon, double rightLon, double bottomLat, double topLat, GeometryWayProvider provider, int currLocationIdx) { + return super.shouldAddLocation(leftLon, rightLon, bottomLat, topLat, provider, currLocationIdx) + || currLocationIdx + 1 < provider.getSize() + && super.shouldAddLocation(leftLon, rightLon, bottomLat, topLat, provider, currLocationIdx + 1); + } + + private boolean segmentDataChanged(Map, RoadSegmentData> other) { + if (other.size() != segmentData.size()) { + return true; + } + for (Pair data : other.keySet()) { + if (other.get(data) != segmentData.get(data)) { + return true; + } + } + return false; + } + + private void setSegments(boolean before, List segments) { + if (before) { + this.beforeSegments = segments; + } else { + this.afterSegments = segments; + } + } + + private List getSegments(boolean before) { + return before ? this.beforeSegments : this.afterSegments; + } + + @NonNull + private String getProfileKey(WptPt pt) { + String key = pt.getProfileType(); + return key == null ? DEFAULT_PROFILE_KEY : key; + } + + private Pair getProfileData(String profileKey) { + boolean night = getContext().isNightMode(); + ApplicationMode mode = ApplicationMode.valueOfStringKey(profileKey, ApplicationMode.DEFAULT); + return ApplicationMode.DEFAULT.getStringKey().equals(mode.getStringKey()) ? + new Pair<>(ContextCompat.getColor(getContext().getCtx(), ProfileIconColors.DARK_YELLOW.getColor(night)), R.drawable.ic_action_split_interval) : + new Pair<>(mode.getProfileColor(night), mode.getIconRes()); + } + + @NonNull + @Override + public GeometryWayStyle getDefaultWayStyle() { + return null; + } + + public static class GeometryMultiProfileWayStyle extends GeometryWayStyle { + + @ColorInt + private final int lineColor; + @ColorInt + private final int borderColor; + @DrawableRes + private final int profileIconRes; + + public GeometryMultiProfileWayStyle(MultiProfileGeometryWayContext context, + @ColorInt int profileColor, @DrawableRes int profileIconRes) { + super(context); + this.lineColor = profileColor; + this.borderColor = ColorUtils.blendARGB(profileColor, Color.BLACK, 0.2f); + this.profileIconRes = profileIconRes; + } + + @ColorInt + public int getBorderColor() { + return borderColor; + } + + @ColorInt + public int getLineColor() { + return lineColor; + } + + @DrawableRes + public int getProfileIconRes() { + return profileIconRes; + } + + @Override + public Bitmap getPointBitmap() { +// return getContext().getProfileIconBitmap(); + return null; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + if (!super.equals(other)) { + return false; + } + GeometryMultiProfileWayStyle that = (GeometryMultiProfileWayStyle) other; + return lineColor == that.lineColor && + borderColor == that.borderColor && + profileIconRes == that.profileIconRes; + } + + @Override + public boolean hasPathLine() { + return true; + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java new file mode 100644 index 0000000000..6d4a92a70b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java @@ -0,0 +1,85 @@ +package net.osmand.plus.views.layers.geometry; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; + +import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; +import net.osmand.util.Algorithms; + +import java.util.HashMap; +import java.util.Map; + +import androidx.annotation.NonNull; + +public class MultiProfileGeometryWayContext extends GeometryWayContext { + + private RenderingLineAttributes multiProfileAttrs; + + private Bitmap pointIcon; + + private final Map profileIconsBitmapCache; + + public MultiProfileGeometryWayContext(Context ctx, float density) { + super(ctx, density); + profileIconsBitmapCache = new HashMap<>(); + } + + public void updatePaints(boolean nightMode, @NonNull RenderingLineAttributes multiProfileAttrs) { + this.multiProfileAttrs = multiProfileAttrs; + super.updatePaints(nightMode, multiProfileAttrs); + } + + @Override + protected void recreateBitmaps() { + float density = getDensity(); + float size = density * 12.5f; + float outerRadius = density * 6.25f; + float centerRadius = density * 6; + float innerRadius = density * 4; + float centerXY = size / 2; + + pointIcon = Bitmap.createBitmap((int) size, (int) size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(pointIcon); + Paint paint = new Paint(); + paint.setStyle(Paint.Style.FILL); + + paint.setColor(Color.BLACK); + canvas.drawCircle(centerXY, centerXY, outerRadius, paint); + + paint.setColor(Color.WHITE); + canvas.drawCircle(centerXY, centerXY, centerRadius, paint); + + paint.setColor(Algorithms.parseColor("#637EFB")); + canvas.drawCircle(centerXY, centerXY, innerRadius, paint); + } + + @Override + protected int getArrowBitmapResId() { + return 0; + } + + @NonNull + public Bitmap getProfileIconBitmap(@NonNull String profileKey, int profileColor) { + String key = profileKey + "_" + profileColor; + Bitmap bitmap = profileIconsBitmapCache.get(key); + if (bitmap == null) { + float density = getDensity(); + float diameter = density * 18; + bitmap = Bitmap.createBitmap((int) diameter, (int) diameter, Bitmap.Config.ARGB_8888); + + Canvas canvas = new Canvas(bitmap); + canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, multiProfileAttrs.paint_1); + multiProfileAttrs.paint3.setColor(profileColor); + canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, multiProfileAttrs.paint3); + } + return bitmap; + } + + @NonNull + public Bitmap getPointIcon() { + return pointIcon; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java new file mode 100644 index 0000000000..5d8120f1c2 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -0,0 +1,32 @@ +package net.osmand.plus.views.layers.geometry; + +import android.graphics.Canvas; +import android.graphics.Path; + +import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle; + +import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; + +public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer { + + public MultiProfileGeometryWayDrawer(MultiProfileGeometryWayContext context) { + super(context); + } + + @Override + public void drawPath(Canvas canvas, Path path, GeometryWayStyle style) { + if (style instanceof GeometryMultiProfileWayStyle) { + RenderingLineAttributes attrs = getContext().getAttrs(); + attrs.paint2.setColor(((GeometryMultiProfileWayStyle) style).getLineColor()); + canvas.drawPath(path, attrs.paint2); + } + } + + public void drawPathBorder(Canvas canvas, Path path, GeometryWayStyle style) { + if (style instanceof GeometryMultiProfileWayStyle) { + RenderingLineAttributes attrs = getContext().getAttrs(); + attrs.paint.setColor(((GeometryMultiProfileWayStyle) style).getBorderColor()); + canvas.drawPath(path, attrs.paint); + } + } +} \ No newline at end of file From 169d734f47e792c7749d8bd63e84f30697e6c9ba Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 1 Apr 2021 10:51:00 +0300 Subject: [PATCH 04/32] Quick action map: suggestion to display current map name --- OsmAnd/res/values/strings.xml | 1 + .../plus/quickaction/actions/MapStyleAction.java | 9 +++++++++ .../osmand/plus/rastermaps/MapOverlayAction.java | 13 +++++++++++-- .../net/osmand/plus/rastermaps/MapSourceAction.java | 13 ++++++++++++- .../osmand/plus/rastermaps/MapUnderlayAction.java | 9 +++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index a716c8b4f7..5cb21e97eb 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + %1$s + %2$d Update all maps added to %1$s? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java index 1bcac88a36..1e2a8e097e 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java @@ -245,4 +245,13 @@ public class MapStyleAction extends SwitchableAction { ? filters.get(0) + " +" + (filters.size() - 1) : filters.get(0); } + + @Override + public String getActionText(OsmandApplication application) { + List mapStyles = getFilteredStyles(); + int mapCount = mapStyles.size() - 1; + String name = application.getSettings().RENDERER.get(); + + return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java index 7972b264aa..15ae55cfae 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java @@ -104,8 +104,8 @@ public class MapOverlayAction extends SwitchableAction> { } int index = -1; - final String currentSource = settings.MAP_OVERLAY.get() == null ? KEY_NO_OVERLAY - : settings.MAP_OVERLAY.get(); + String currentSource = settings.MAP_OVERLAY.get() == null ? KEY_NO_OVERLAY + : settings.MAP_OVERLAY.get(); for (int idx = 0; idx < sources.size(); idx++) { if (sources.get(idx).first.equals(currentSource)) { @@ -224,4 +224,13 @@ public class MapOverlayAction extends SwitchableAction> { getParams().put(KEY_DIALOG, Boolean.toString(((SwitchCompat) root.findViewById(R.id.saveButton)).isChecked())); return super.fillParams(root, activity); } + + @Override + public String getActionText(OsmandApplication application) { + List> sources = loadListFromParams(); + int mapCount = sources.size() - 1; + String name = application.getSettings().MAP_OVERLAY.get(); + + return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java index b11a8ec812..556f8bbd61 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java @@ -91,7 +91,7 @@ public class MapSourceAction extends SwitchableAction> { OsmandSettings settings = activity.getMyApplication().getSettings(); List> sources = loadListFromParams(); if (sources.size() > 0) { - boolean showBottomSheetStyles = Boolean.valueOf(getParams().get(KEY_DIALOG)); + boolean showBottomSheetStyles = Boolean.parseBoolean(getParams().get(KEY_DIALOG)); if (showBottomSheetStyles) { showChooseDialog(activity.getSupportFragmentManager()); return; @@ -214,4 +214,15 @@ public class MapSourceAction extends SwitchableAction> { getParams().put(KEY_DIALOG, Boolean.toString(((SwitchCompat) root.findViewById(R.id.saveButton)).isChecked())); return super.fillParams(root, activity); } + + @Override + public String getActionText(OsmandApplication application) { + Pair currentSource = application.getSettings().MAP_ONLINE_DATA.get() + ? new Pair<>(application.getSettings().MAP_TILE_SOURCES.get(), application.getSettings().MAP_TILE_SOURCES.get()) + : new Pair<>(LAYER_OSM_VECTOR, application.getString(R.string.vector_data)); + final LinkedHashMap entriesMap = new LinkedHashMap<>(); + int mapCount = entriesMap.size() - 1; + + return application.getString(R.string.ltr_or_rtl_combine_via_plus, currentSource, mapCount); + } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java index ed598a344b..0bb2838b36 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java @@ -226,4 +226,13 @@ public class MapUnderlayAction extends SwitchableAction> { getParams().put(KEY_DIALOG, Boolean.toString(((SwitchCompat) root.findViewById(R.id.saveButton)).isChecked())); return super.fillParams(root, activity); } + + @Override + public String getActionText(OsmandApplication application) { + List> sources = loadListFromParams(); + int mapCount = sources.size() - 1; + String name = application.getSettings().MAP_UNDERLAY.get(); + + return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + } } From bf6d5f0b838bcbccf8d869753f82fe1d6217ce9f Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 1 Apr 2021 12:30:38 +0300 Subject: [PATCH 05/32] Change map quick widget naming style using arrow and three dots --- OsmAnd/res/values/strings.xml | 2 +- .../plus/quickaction/actions/MapStyleAction.java | 6 ++---- .../net/osmand/plus/rastermaps/MapOverlayAction.java | 7 +++---- .../net/osmand/plus/rastermaps/MapSourceAction.java | 10 ++++------ .../net/osmand/plus/rastermaps/MapUnderlayAction.java | 7 +++---- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5cb21e97eb..b4e3e4fdc2 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,7 +12,7 @@ --> - %1$s + %2$d + %1$s → … Update all maps added to %1$s? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java index 1e2a8e097e..0938e4d121 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java @@ -248,10 +248,8 @@ public class MapStyleAction extends SwitchableAction { @Override public String getActionText(OsmandApplication application) { - List mapStyles = getFilteredStyles(); - int mapCount = mapStyles.size() - 1; - String name = application.getSettings().RENDERER.get(); + String currentSource = application.getSettings().RENDERER.get(); - return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + return application.getString(R.string.map_quick_action_pattern, currentSource); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java index 15ae55cfae..41ae2b709b 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java @@ -227,10 +227,9 @@ public class MapOverlayAction extends SwitchableAction> { @Override public String getActionText(OsmandApplication application) { - List> sources = loadListFromParams(); - int mapCount = sources.size() - 1; - String name = application.getSettings().MAP_OVERLAY.get(); + String currentSource = application.getSettings().MAP_OVERLAY.get() == null ? KEY_NO_OVERLAY + : application.getSettings().MAP_OVERLAY.get(); - return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + return application.getString(R.string.map_quick_action_pattern, currentSource); } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java index 556f8bbd61..86043763ea 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java @@ -217,12 +217,10 @@ public class MapSourceAction extends SwitchableAction> { @Override public String getActionText(OsmandApplication application) { - Pair currentSource = application.getSettings().MAP_ONLINE_DATA.get() - ? new Pair<>(application.getSettings().MAP_TILE_SOURCES.get(), application.getSettings().MAP_TILE_SOURCES.get()) - : new Pair<>(LAYER_OSM_VECTOR, application.getString(R.string.vector_data)); - final LinkedHashMap entriesMap = new LinkedHashMap<>(); - int mapCount = entriesMap.size() - 1; + String currentSource = application.getSettings().MAP_ONLINE_DATA.get() + ? application.getSettings().MAP_TILE_SOURCES.get() + : application.getString(R.string.vector_data); - return application.getString(R.string.ltr_or_rtl_combine_via_plus, currentSource, mapCount); + return application.getString(R.string.map_quick_action_pattern, currentSource); } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java index 0bb2838b36..bb3708ba03 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java @@ -229,10 +229,9 @@ public class MapUnderlayAction extends SwitchableAction> { @Override public String getActionText(OsmandApplication application) { - List> sources = loadListFromParams(); - int mapCount = sources.size() - 1; - String name = application.getSettings().MAP_UNDERLAY.get(); + String currentSource = application.getSettings().MAP_UNDERLAY.get() == null ? KEY_NO_UNDERLAY + : application.getSettings().MAP_UNDERLAY.get(); - return application.getString(R.string.ltr_or_rtl_combine_via_plus, name, mapCount); + return application.getString(R.string.map_quick_action_pattern, currentSource); } } From a5fce381d5f15d40272cb9594797d676d22618cc Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 1 Apr 2021 16:22:28 +0300 Subject: [PATCH 06/32] Misprint fix --- OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java index 6583dea040..149d118124 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java @@ -272,7 +272,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL } private void adjustGlobalVisibility() { - emptyState.setVisibility(View.VISIBLE); + emptyState.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE); titleBottomDivider.setVisibility(terrainEnabled ? View.GONE : View.VISIBLE); contentContainer.setVisibility(terrainEnabled ? View.VISIBLE : View.GONE); } From b42a69e53f27d54955b82d959f83a5ef9708d609 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Thu, 1 Apr 2021 19:34:03 +0300 Subject: [PATCH 07/32] Fix #11184 --- .../activities/MapActivityKeyListener.java | 2 ++ .../plus/base/MapViewTrackingUtilities.java | 20 ++++++++++++++++++- .../plus/views/layers/MapControlsLayer.java | 18 +---------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java index 46ce19e3c2..08004ec9ab 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java @@ -92,6 +92,8 @@ public class MapActivityKeyListener implements KeyEvent.Callback { return true; } else if (keyCode == KeyEvent.KEYCODE_C) { mapActivity.getMapViewTrackingUtilities().backToLocationImpl(); + } else if (keyCode == KeyEvent.KEYCODE_D) { + mapActivity.getMapViewTrackingUtilities().switchRotateMapMode(); } else if (settings.EXTERNAL_INPUT_DEVICE.get() == PARROT_EXTERNAL_DEVICE) { // Parrot device has only dpad left and right if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java index 14a6623eae..d220b8bec1 100644 --- a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -39,6 +39,8 @@ import java.util.Map; public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLocationListener, OsmAndCompassListener, MapMarkerChangedListener { + + private static final int COMPASS_REQUEST_TIME_INTERVAL_MS = 5000; private static final int AUTO_FOLLOW_MSG_ID = OsmAndConstants.UI_HANDLER_LOCATION_SERVICE + 4; private long lastTimeAutoZooming = 0; @@ -59,6 +61,7 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc private Float heading; private boolean drivingRegionUpdated = false; private boolean movingToMyLocation = false; + private long compassRequest; public MapViewTrackingUtilities(OsmandApplication app){ this.app = app; @@ -424,7 +427,22 @@ public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLoc setMapLinkedToLocation(false); } - public void switchRotateMapMode(){ + public void switchRotateMapMode() { + if (app.getRoutingHelper().isFollowingMode()) { + if (compassRequest + COMPASS_REQUEST_TIME_INTERVAL_MS > System.currentTimeMillis()) { + compassRequest = 0; + switchRotateMapModeImpl(); + } else { + compassRequest = System.currentTimeMillis(); + app.showShortToastMessage(app.getString(R.string.press_again_to_change_the_map_orientation)); + } + } else { + compassRequest = 0; + switchRotateMapModeImpl(); + } + } + + private void switchRotateMapModeImpl(){ if (mapView != null) { String rotMode = app.getString(R.string.rotate_map_none_opt); if (settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_NONE && mapView.getRotate() != 0) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 22c077f02d..a4158feced 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -97,8 +97,6 @@ public class MapControlsLayer extends OsmandMapLayer { private static final int REQUEST_LOCATION_FOR_NAVIGATION_FAB_PERMISSION = 201; private static final int REQUEST_LOCATION_FOR_ADD_DESTINATION_PERMISSION = 202; - private static final int COMPASS_PRESSED_TIME_INTERVAL_MS = 5000; - public MapHudButton createHudButton(View iv, int resId, String id) { MapHudButton mc = new MapHudButton(); mc.iv = iv; @@ -139,7 +137,6 @@ public class MapControlsLayer extends OsmandMapLayer { private MapQuickActionLayer mapQuickActionLayer; private boolean forceShowCompass; private LatLon requestedLatLon; - private long compassPressed; private Set themeInfoProviderTags = new HashSet<>(); public MapControlsLayer(MapActivity activity) { @@ -292,20 +289,7 @@ public class MapControlsLayer extends OsmandMapLayer { compass.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - boolean followingMode = app.getRoutingHelper().isFollowingMode(); - - if (followingMode) { - if (compassPressed + COMPASS_PRESSED_TIME_INTERVAL_MS > System.currentTimeMillis()) { - compassPressed = 0; - mapActivity.getMapViewTrackingUtilities().switchRotateMapMode(); - } else { - compassPressed = System.currentTimeMillis(); - app.showShortToastMessage(app.getString(R.string.press_again_to_change_the_map_orientation)); - } - } else { - compassPressed = 0; - mapActivity.getMapViewTrackingUtilities().switchRotateMapMode(); - } + mapActivity.getMapViewTrackingUtilities().switchRotateMapMode(); } }); From bf55e86a7e7e4f75b0a29ef3a77201a6e369d0a5 Mon Sep 17 00:00:00 2001 From: cepprice Date: Thu, 1 Apr 2021 22:39:33 +0500 Subject: [PATCH 08/32] Draw profile icon on line center --- OsmAnd/src/net/osmand/AndroidUtils.java | 4 + .../measurementtool/MeasurementToolLayer.java | 4 +- .../views/layers/geometry/GeometryWay.java | 22 ++-- .../geometry/MultiProfileGeometryWay.java | 117 ++++++++++++------ .../MultiProfileGeometryWayContext.java | 39 ++++-- .../MultiProfileGeometryWayDrawer.java | 21 +++- 6 files changed, 144 insertions(+), 63 deletions(-) diff --git a/OsmAnd/src/net/osmand/AndroidUtils.java b/OsmAnd/src/net/osmand/AndroidUtils.java index 42b4a60919..4f0729d355 100644 --- a/OsmAnd/src/net/osmand/AndroidUtils.java +++ b/OsmAnd/src/net/osmand/AndroidUtils.java @@ -151,6 +151,10 @@ public class AndroidUtils { return resizedBitmap; } + public static Bitmap createScaledBitmap(Drawable drawable, int width, int height) { + return scaleBitmap(drawableToBitmap(drawable), width, height, false); + } + public static ColorStateList createBottomNavColorStateList(Context ctx, boolean nightMode) { return AndroidUtils.createCheckedColorStateList(ctx, nightMode, R.color.icon_color_default_light, R.color.wikivoyage_active_light, diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 7ab66f44b2..4ed8aa719a 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -82,7 +82,8 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL multiProfileLineAttrs.isPaint3 = false; multiProfileLineAttrs.paint3.setStrokeWidth(density * 2); - multiProfileGeometryWayContext = new MultiProfileGeometryWayContext(view.getContext(), density); + multiProfileGeometryWayContext = new MultiProfileGeometryWayContext( + view.getContext(), view.getApplication().getUIUtilities(), density); multiProfileGeometry = new MultiProfileGeometryWay(multiProfileGeometryWayContext); bitmapPaint = new Paint(); @@ -227,6 +228,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL multiProfileGeometry.drawSegments(canvas, tb); } } else { + multiProfileGeometry.clearWay(); List before = editingCtx.getBeforeTrkSegmentLine(); for (TrkSegment segment : before) { new Renderable.StandardTrack(new ArrayList<>(segment.points), 17.2). 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 cc1633839e..9489cd9620 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -174,7 +174,7 @@ public abstract class GeometryWay= lx && x <= rx && y >= ty && y <= by; } + public static boolean isIn(float x, float y, int lx, int ty, int rx, int by, float outMargin) { + return x >= lx - outMargin && x <= rx + outMargin && y >= ty - outMargin && y <= by + outMargin; + } + public static int calculatePath(RotatedTileBox tb, List xs, List ys, Path path) { List>> paths = new ArrayList<>(); - int res = calculatePath(tb, xs, ys, null, paths); + int res = calculatePath(tb, xs, ys, 0, null, paths); if (paths.size() > 0) { path.addPath(paths.get(0).first); } return res; } - public static int calculatePath(RotatedTileBox tb, List xs, List ys, List> styles, List>> paths) { + public static int calculatePath(RotatedTileBox tb, List xs, List ys, float outMargin, List> styles, List>> paths) { boolean segmentStarted = false; float prevX = xs.get(0); float prevY = ys.get(0); @@ -280,11 +284,11 @@ public abstract class GeometryWay style = hasStyles ? styles.get(0) : null; Path path = new Path(); - boolean prevIn = isIn(prevX, prevY, 0, 0, width, height); + boolean prevIn = isIn(prevX, prevY, 0, 0, width, height, outMargin); for (int i = 1; i < xs.size(); i++) { float currX = xs.get(i); float currY = ys.get(i); - boolean currIn = isIn(currX, currY, 0, 0, width, height); + boolean currIn = isIn(currX, currY, 0, 0, width, height, outMargin); boolean draw = false; if (prevIn && currIn) { draw = true; @@ -356,7 +360,7 @@ public abstract class GeometryWay>> paths = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, styles, paths); + calculatePath(tb, tx, ty, 0, styles, paths); for (Pair> pc : paths) { GeometryWayStyle style = pc.second; if (style.hasPathLine()) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java index e378c4edbd..865e56e60b 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java @@ -4,6 +4,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Path; +import android.graphics.PathMeasure; import android.util.Pair; import net.osmand.GPXUtilities.TrkSegment; @@ -55,14 +56,14 @@ public class MultiProfileGeometryWay extends GeometryWay>> pathStyles = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, styles, pathStyles); + calculatePath(tb, tx, ty, getContext().circleSize, styles, pathStyles); for (int i = 0; i < pathStyles.size(); i++) { Pair> currPathStyle = pathStyles.get(i); getDrawer().drawPathBorder(canvas, currPathStyle.first, currPathStyle.second); getDrawer().drawPath(canvas, currPathStyle.first, currPathStyle.second); } -// drawer.drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles); + getDrawer().drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles); } finally { canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); } @@ -71,8 +72,8 @@ public class MultiProfileGeometryWay extends GeometryWay, RoadSegmentData> segmentData, boolean before, List segments, int segmentIdx) { boolean shouldUpdateRoute = tileBox.getMapDensity() != getMapDensity() || segmentDataChanged(segmentData) - || getSegments(before) != segments || true; - if (shouldUpdateRoute && segments.get(segmentIdx).points.size() >= 2) { + || getSegments(before) != segments || getLocationProvider() == null; + if (shouldUpdateRoute) { this.segmentData = segmentData; setSegments(before, segments); List userPoints = segments.get(segmentIdx).points; @@ -81,7 +82,7 @@ public class MultiProfileGeometryWay extends GeometryWay ways = new ArrayList<>(); List> styles = new ArrayList<>(); - setStyles(userPoints, ways, styles); + setStyles(tileBox, userPoints, ways, styles); locations = new ArrayList<>(); styleMap = new TreeMap<>(); @@ -104,45 +105,68 @@ public class MultiProfileGeometryWay extends GeometryWay userPoints, List ways, List> styles) { - String prevProfileKey = ""; - Way way = new Way(-2); + private void setStyles(RotatedTileBox tileBox, List userPoints, List ways, List> styles) { + MultiProfileGeometryWayContext context = getContext(); + Path path = new Path(); + PathMeasure pathMeasure = new PathMeasure(); for (int i = 0; i < userPoints.size() - 1; i++) { WptPt leftPt = userPoints.get(i); Pair userLine = new Pair<>(leftPt, userPoints.get(i + 1)); RoadSegmentData routeBetweenPoints = segmentData.get(userLine); - if (!prevProfileKey.equals(getProfileKey(leftPt)) && !leftPt.isGap()) { - way = new Way(-2); - String currProfileKey = getProfileKey(leftPt); - Pair profileData = getProfileData(currProfileKey); - styles.add(new GeometryMultiProfileWayStyle(getContext(), profileData.first, profileData.second)); - ways.add(way); - prevProfileKey = currProfileKey; - } + Way way = new Way(-1); + String currProfileKey = getProfileKey(leftPt); + Pair profileData = getProfileData(currProfileKey); + GeometryMultiProfileWayStyle style = new GeometryMultiProfileWayStyle( + getContext(), currProfileKey, profileData.first, profileData.second); + styles.add(style); + ways.add(way); + path.reset(); boolean isSecondToLast = i + 2 == userPoints.size(); if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); if (isSecondToLast) { way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); } + movePathToWpt(path, tileBox, userLine.first); + pathLineToWpt(path, tileBox, userLine.second); } else { + movePathToWpt(path, tileBox, routeBetweenPoints.getPoints().get(0)); for (WptPt pt : routeBetweenPoints.getPoints()) { if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { way.addNode(new Node(pt.lat, pt.lon, -1)); } + pathLineToWpt(path, tileBox, pt); } } + + float[] xy = new float[2]; + pathMeasure.setPath(path, false); + float routeLength = pathMeasure.getLength(); + if ((routeLength - context.circleSize) / 2 >= context.minIconMargin) { + pathMeasure.getPosTan(pathMeasure.getLength() * 0.5f, xy, null); + style.setIconLat(tileBox.getLatFromPixel(xy[0], xy[1])); + style.setIconLon(tileBox.getLonFromPixel(xy[0], xy[1])); + } } } @Override - protected boolean shouldAddLocation(double leftLon, double rightLon, double bottomLat, double topLat, GeometryWayProvider provider, int currLocationIdx) { - return super.shouldAddLocation(leftLon, rightLon, bottomLat, topLat, provider, currLocationIdx) - || currLocationIdx + 1 < provider.getSize() - && super.shouldAddLocation(leftLon, rightLon, bottomLat, topLat, provider, currLocationIdx + 1); + protected boolean shouldAddLocation(RotatedTileBox tileBox, double leftLon, double rightLon, + double bottomLat, double topLat, GeometryWayProvider provider, + int currLocationIdx) { + float currX = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx), provider.getLongitude(currLocationIdx)); + float currY = tileBox.getPixYFromLatLon(provider.getLatitude(currLocationIdx), provider.getLongitude(currLocationIdx)); + if (tileBox.containsPoint(currX, currY, getContext().circleSize)) { + return true; + } else if (currLocationIdx + 1 >= provider.getSize()) { + return false; + } + float nextX = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx + 1), provider.getLongitude(currLocationIdx + 1)); + float nextY = tileBox.getPixXFromLatLon(provider.getLatitude(currLocationIdx + 1), provider.getLongitude(currLocationIdx + 1)); + return tileBox.containsPoint(nextX, nextY, getContext().circleSize); } private boolean segmentDataChanged(Map, RoadSegmentData> other) { @@ -169,6 +193,14 @@ public class MultiProfileGeometryWay extends GeometryWay { + private final String profileKey; @ColorInt private final int lineColor; @ColorInt @@ -198,9 +231,13 @@ public class MultiProfileGeometryWay extends GeometryWay profileIconsBitmapCache; - public MultiProfileGeometryWayContext(Context ctx, float density) { + public MultiProfileGeometryWayContext(Context ctx, UiUtilities iconsCache, float density) { super(ctx, density); + this.iconsCache = iconsCache; profileIconsBitmapCache = new HashMap<>(); + minIconMargin = density * 30; + circleSize = density * 70; } public void updatePaints(boolean nightMode, @NonNull RenderingLineAttributes multiProfileAttrs) { @@ -62,18 +73,24 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { } @NonNull - public Bitmap getProfileIconBitmap(@NonNull String profileKey, int profileColor) { - String key = profileKey + "_" + profileColor; + public Bitmap getProfileIconBitmap(String profileKey, @DrawableRes int iconRes, @ColorInt int color) { + String key = profileKey + "_" + iconRes + "_" + color; Bitmap bitmap = profileIconsBitmapCache.get(key); if (bitmap == null) { - float density = getDensity(); - float diameter = density * 18; - bitmap = Bitmap.createBitmap((int) diameter, (int) diameter, Bitmap.Config.ARGB_8888); - + bitmap = Bitmap.createBitmap((int) circleSize, (int) circleSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); - canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, multiProfileAttrs.paint_1); - multiProfileAttrs.paint3.setColor(profileColor); - canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, multiProfileAttrs.paint3); + float center = bitmap.getWidth() / 2f; + + canvas.drawCircle(center, center, center / 2, multiProfileAttrs.paint_1); + multiProfileAttrs.paint3.setColor(color); + canvas.drawCircle(center, center, center / 2, multiProfileAttrs.paint3); + + float iconSize = center - getDensity() * 10; + Bitmap profileIconBitmap = AndroidUtils.createScaledBitmap( + iconsCache.getPaintedIcon(iconRes, color), (int) iconSize, (int) iconSize); + canvas.drawBitmap(profileIconBitmap, center - iconSize / 2, center - iconSize / 2, multiProfileAttrs.paint3); + + profileIconsBitmapCache.put(key, bitmap); } return bitmap; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java index 5d8120f1c2..6e947a26a3 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -3,9 +3,11 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Canvas; import android.graphics.Path; +import net.osmand.data.RotatedTileBox; +import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle; -import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; +import java.util.List; public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer { @@ -22,6 +24,23 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer tx, List ty, List angles, List distances, double distPixToFinish, List> styles) { + MultiProfileGeometryWayContext context = getContext(); + GeometryMultiProfileWayStyle style = null; + + for (int i = 0; i < styles.size(); i++) { + if (styles.get(i) != null && !styles.get(i).equals(style)) { + style = (GeometryMultiProfileWayStyle) styles.get(i); + double lat = style.getIconLat(); + double lon = style.getIconLon(); + float x = tb.getPixXFromLatLon(lat, lon) - context.circleSize / 2; + float y = tb.getPixYFromLatLon(lat, lon) - context.circleSize / 2; + canvas.drawBitmap(style.getPointBitmap(), x, y, null); + } + } + } + public void drawPathBorder(Canvas canvas, Path path, GeometryWayStyle style) { if (style instanceof GeometryMultiProfileWayStyle) { RenderingLineAttributes attrs = getContext().getAttrs(); From 4f35297d73a367825b1e320afc1e8c1b314bdbc5 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 1 Apr 2021 21:16:28 +0300 Subject: [PATCH 09/32] First iteration: 3 items done Rearrange items in the "Voice prompts" menu. Divide it into groups: "Announce", "User points", "Speed limit", 'Options", "Output". Rename current "Sped limit" switch to "Announce when exceeded" --- ...profile_preference_toolbar_with_switch.xml | 1 + OsmAnd/res/values/strings.xml | 6 +- OsmAnd/res/xml/voice_announces.xml | 102 ++++++++++++------ .../net/osmand/plus/routing/VoiceRouter.java | 33 +++--- .../plus/settings/backend/OsmandSettings.java | 1 + .../fragments/VoiceAnnouncesFragment.java | 73 +++++++++---- 6 files changed, 150 insertions(+), 66 deletions(-) diff --git a/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml b/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml index 33a93fc70e..14672b52df 100644 --- a/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml +++ b/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml @@ -71,6 +71,7 @@ + Output + User points + Announce when exceeded + Exit number Update all maps added to %1$s? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n @@ -2476,7 +2480,7 @@ Traffic calming Speed camera Traffic warning - Favorites nearby + Nearby favorites Nearby POI Traffic warnings OsmAnd background service still running. Stop it, too? diff --git a/OsmAnd/res/xml/voice_announces.xml b/OsmAnd/res/xml/voice_announces.xml index a7dfad299b..51ce54c40b 100644 --- a/OsmAnd/res/xml/voice_announces.xml +++ b/OsmAnd/res/xml/voice_announces.xml @@ -11,11 +11,41 @@ android:title="@string/voice_announces_info" tools:icon="@drawable/ic_action_info_dark" /> + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + - - + android:title="@string/output" /> diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index b9032e26e4..70c8443701 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -27,6 +27,8 @@ import net.osmand.router.TurnType; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import org.apache.commons.lang3.StringUtils; + import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -663,24 +665,29 @@ public class VoiceRouter { } private String getSpeakableExitRef(String exit) { - StringBuilder sb = new StringBuilder(); - if (exit != null) { - exit = exit.replace('-', ' '); - exit = exit.replace(':', ' '); - // Add spaces between digits and letters for better pronunciation - int length = exit.length(); - for (int i = 0; i < length; i++) { - if (i + 1 < length && Character.isDigit(exit.charAt(i)) && Character.isLetter(exit.charAt(i + 1))) { - sb.append(exit.charAt(i)); - sb.append(' '); - } else { - sb.append(exit.charAt(i)); + boolean showStartDialog = settings.EXIT_NUMBER_NAMES_SHOWED.get(); + if (showStartDialog) { + StringBuilder sb = new StringBuilder(); + if (exit != null) { + exit = exit.replace('-', ' '); + exit = exit.replace(':', ' '); + // Add spaces between digits and letters for better pronunciation + int length = exit.length(); + for (int i = 0; i < length; i++) { + if (i + 1 < length && Character.isDigit(exit.charAt(i)) && Character.isLetter(exit.charAt(i + 1))) { + sb.append(exit.charAt(i)); + sb.append(' '); + } else { + sb.append(exit.charAt(i)); + } } } + return sb.toString(); } - return sb.toString(); + return StringUtils.EMPTY; } + private int getIntRef(String stringRef) { int intRef = Algorithms.findFirstNumberEndIndex(stringRef); if (intRef > 0) { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 39f3cf3d92..72a692a8cc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1358,6 +1358,7 @@ public class OsmandSettings { public final OsmandPreference SPEED_CAMERAS_UNINSTALLED = new BooleanPreference(this, "speed_cameras_uninstalled", false).makeGlobal().makeShared(); public final OsmandPreference SPEED_CAMERAS_ALERT_SHOWED = new BooleanPreference(this, "speed_cameras_alert_showed", false).makeGlobal().makeShared(); + public final OsmandPreference EXIT_NUMBER_NAMES_SHOWED = new BooleanPreference(this, "exit_number_names", false).makeGlobal().makeShared(); public Set getForbiddenTypes() { Set typeNames = new HashSet<>(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java index fb617ab01f..ada65814b5 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java @@ -5,22 +5,26 @@ import android.content.Intent; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.AudioManager; +import android.net.Uri; import android.view.LayoutInflater; import android.view.View; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreferenceCompat; +import com.google.android.material.appbar.AppBarLayout; + import net.osmand.AndroidUtils; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; -import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.dialogs.SpeedCamerasBottomSheet; import net.osmand.plus.download.DownloadActivity; @@ -31,6 +35,8 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.bottomsheets.AnnouncementTimeBottomSheet; import net.osmand.plus.settings.preferences.ListPreferenceEx; +import net.osmand.plus.settings.preferences.SwitchPreferenceEx; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; import java.util.Set; @@ -43,11 +49,35 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr private static final String MORE_VALUE = "MORE_VALUE"; + private static final String OSMAND_VOICE_NAVIGATION_URL = "https://docs.osmand.net/en/main@latest/osmand/troubleshooting/navigation#voice-navigation"; + @Override protected void createToolbar(LayoutInflater inflater, View view) { - super.createToolbar(inflater, view); + AppBarLayout appbar = view.findViewById(R.id.appbar); + View toolbar = UiUtilities.getInflater(getContext(), isNightMode()).inflate(R.layout.profile_preference_toolbar_with_switch, appbar, false); - view.findViewById(R.id.toolbar_switch_container).setOnClickListener(new View.OnClickListener() { + View iconToolbarContainer = toolbar.findViewById(R.id.toolbar_icon); + ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); + icon.setImageResource(R.drawable.ic_action_help_online); + icon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getContext() != null) { + WikipediaDialogFragment.showFullArticle(getContext(), Uri.parse(OSMAND_VOICE_NAVIGATION_URL), true); + } + } + }); + ImageButton backButton = toolbar.findViewById(R.id.close_button); + backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity fragmentActivity = getActivity(); + if (fragmentActivity != null) { + fragmentActivity.onBackPressed(); + } + } + }); + toolbar.findViewById(R.id.toolbar_switch_container).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ApplicationMode selectedMode = getSelectedAppMode(); @@ -59,6 +89,9 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr updateMenu(); } }); + TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); + toolbarTitle.setText(getString(R.string.voice_announces)); + appbar.addView(toolbar); } @Override @@ -78,7 +111,7 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr View switchContainer = view.findViewById(R.id.toolbar_switch_container); AndroidUtils.setBackground(switchContainer, new ColorDrawable(color)); - SwitchCompat switchView = (SwitchCompat) switchContainer.findViewById(R.id.switchWidget); + SwitchCompat switchView = switchContainer.findViewById(R.id.switchWidget); switchView.setChecked(checked); UiUtilities.setupCompoundButton(switchView, isNightMode(), TOOLBAR); @@ -102,13 +135,13 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr enableDisablePreferences(!settings.VOICE_MUTE.getModeValue(getSelectedAppMode())); setupSpeakCamerasPref(); - setupSpeedCamerasAlert(); + setupTurnScreenOnNavigationInstructionsPref(); } private void setupSpeedLimitExceedPref() { //array size must be equal! - Float[] valuesKmh = new Float[] {-10f, -7f, -5f, 0f, 5f, 7f, 10f, 15f, 20f}; - Float[] valuesMph = new Float[] {-7f, -5f, -3f, 0f, 3f, 5f, 7f, 10f, 15f}; + Float[] valuesKmh = new Float[]{-10f, -7f, -5f, 0f, 5f, 7f, 10f, 15f, 20f}; + Float[] valuesMph = new Float[]{-7f, -5f, -3f, 0f, 3f, 5f, 7f, 10f, 15f}; String[] names; if (settings.METRIC_SYSTEM.getModeValue(getSelectedAppMode()) == MetricsConstants.KILOMETERS_AND_METERS) { names = new String[valuesKmh.length]; @@ -121,34 +154,34 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr names[i] = valuesMph[i].intValue() + " " + getString(R.string.mile_per_hour); } } - ListPreferenceEx voiceProvider = (ListPreferenceEx) findPreference(settings.SPEED_LIMIT_EXCEED_KMH.getId()); + ListPreferenceEx voiceProvider = findPreference(settings.SPEED_LIMIT_EXCEED_KMH.getId()); voiceProvider.setEntries(names); voiceProvider.setEntryValues(valuesKmh); } private void setupKeepInformingPref() { - Integer[] keepInformingValues = new Integer[] {0, 1, 2, 3, 5, 7, 10, 15, 20, 25, 30}; + Integer[] keepInformingValues = new Integer[]{0, 1, 2, 3, 5, 7, 10, 15, 20, 25, 30}; String[] keepInformingNames = new String[keepInformingValues.length]; keepInformingNames[0] = getString(R.string.keep_informing_never); for (int i = 1; i < keepInformingValues.length; i++) { keepInformingNames[i] = keepInformingValues[i] + " " + getString(R.string.int_min); } - ListPreferenceEx keepInforming = (ListPreferenceEx) findPreference(settings.KEEP_INFORMING.getId()); + ListPreferenceEx keepInforming = findPreference(settings.KEEP_INFORMING.getId()); keepInforming.setEntries(keepInformingNames); keepInforming.setEntryValues(keepInformingValues); } private void setupArrivalAnnouncementPref() { - Float[] arrivalValues = new Float[] {1.5f, 1f, 0.5f, 0.25f}; - String[] arrivalNames = new String[] { + Float[] arrivalValues = new Float[]{1.5f, 1f, 0.5f, 0.25f}; + String[] arrivalNames = new String[]{ getString(R.string.arrival_distance_factor_early), getString(R.string.arrival_distance_factor_normally), getString(R.string.arrival_distance_factor_late), getString(R.string.arrival_distance_factor_at_last) }; - ListPreferenceEx arrivalDistanceFactor = (ListPreferenceEx) findPreference(settings.ARRIVAL_DISTANCE_FACTOR.getId()); + ListPreferenceEx arrivalDistanceFactor = findPreference(settings.ARRIVAL_DISTANCE_FACTOR.getId()); arrivalDistanceFactor.setEntries(arrivalNames); arrivalDistanceFactor.setEntryValues(arrivalValues); } @@ -178,21 +211,21 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr Drawable enabled = getActiveIcon(R.drawable.ic_action_volume_up); Drawable icon = getPersistentPrefIcon(enabled, disabled); - ListPreferenceEx voiceProvider = (ListPreferenceEx) findPreference(settings.VOICE_PROVIDER.getId()); + ListPreferenceEx voiceProvider = findPreference(settings.VOICE_PROVIDER.getId()); voiceProvider.setEntries(entries); voiceProvider.setEntryValues(entryValues); voiceProvider.setIcon(icon); } private void setupAudioStreamGuidancePref() { - String[] streamTypes = new String[] { + String[] streamTypes = new String[]{ getString(R.string.voice_stream_music), getString(R.string.voice_stream_notification), getString(R.string.voice_stream_voice_call) }; //getString(R.string.shared_string_default)}; - Integer[] streamIntTypes = new Integer[] { + Integer[] streamIntTypes = new Integer[]{ AudioManager.STREAM_MUSIC, AudioManager.STREAM_NOTIFICATION, AudioManager.STREAM_VOICE_CALL @@ -208,6 +241,11 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr getPreferenceScreen().addPreference(interruptMusicPref); } + private void setupTurnScreenOnNavigationInstructionsPref() { + SwitchPreferenceEx turnScreenOnNavigationInstructions = findPreference(settings.TURN_SCREEN_ON_NAVIGATION_INSTRUCTIONS.getId()); + turnScreenOnNavigationInstructions.setDescription(R.string.turn_screen_on_navigation_instructions_descr); + } + private void updateMenu() { MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { @@ -319,12 +357,11 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr public void onPreferenceChanged(String prefId) { if (prefId.equals(settings.SPEED_CAMERAS_UNINSTALLED.getId())) { setupSpeakCamerasPref(); - setupSpeedCamerasAlert(); } } private void setupSpeakCamerasPref() { - SwitchPreferenceCompat showCameras = (SwitchPreferenceCompat) findPreference(settings.SPEAK_SPEED_CAMERA.getId()); + SwitchPreferenceCompat showCameras = findPreference(settings.SPEAK_SPEED_CAMERA.getId()); showCameras.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get()); } } \ No newline at end of file From b9e886ef64461282210937c7145b93e81066fa50 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 1 Apr 2021 22:00:04 +0300 Subject: [PATCH 10/32] Underlay, overlay naming fix --- OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java | 2 +- OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java index 41ae2b709b..8190b6c995 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapOverlayAction.java @@ -230,6 +230,6 @@ public class MapOverlayAction extends SwitchableAction> { String currentSource = application.getSettings().MAP_OVERLAY.get() == null ? KEY_NO_OVERLAY : application.getSettings().MAP_OVERLAY.get(); - return application.getString(R.string.map_quick_action_pattern, currentSource); + return application.getString(R.string.map_quick_action_pattern, getTranslatedItemName(application, currentSource)); } } diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java index bb3708ba03..ddb941e10b 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapUnderlayAction.java @@ -232,6 +232,6 @@ public class MapUnderlayAction extends SwitchableAction> { String currentSource = application.getSettings().MAP_UNDERLAY.get() == null ? KEY_NO_UNDERLAY : application.getSettings().MAP_UNDERLAY.get(); - return application.getString(R.string.map_quick_action_pattern, currentSource); + return application.getString(R.string.map_quick_action_pattern, getTranslatedItemName(application, currentSource)); } } From 14209dbd015e67d4efabccfe751f84ca9d18c393 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 2 Apr 2021 01:26:38 +0500 Subject: [PATCH 11/32] Support multiple segments --- .../measurementtool/MeasurementToolLayer.java | 13 +- .../geometry/MultiProfileGeometryWay.java | 150 ++++++++++-------- .../MultiProfileGeometryWayContext.java | 4 +- .../MultiProfileGeometryWayDrawer.java | 8 +- 4 files changed, 95 insertions(+), 80 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 4ed8aa719a..b630233137 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -219,14 +219,11 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL if (editingCtx.isInMultiProfileMode()) { multiProfileGeometryWayContext.updatePaints(settings.isNightMode(), multiProfileLineAttrs); - for (int i = 0; i < editingCtx.getBeforeSegments().size(); i++) { - multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), true, editingCtx.getBeforeSegments(), i); - multiProfileGeometry.drawSegments(canvas, tb); - } - for (int i = 0; i < editingCtx.getAfterSegments().size(); i++) { - multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), false, editingCtx.getAfterSegments(), i); - multiProfileGeometry.drawSegments(canvas, tb); - } + List allSegments = new ArrayList<>(); + allSegments.addAll(editingCtx.getBeforeSegments()); + allSegments.addAll(editingCtx.getAfterSegments()); + multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), allSegments); + multiProfileGeometry.drawSegments(canvas, tb); } else { multiProfileGeometry.clearWay(); List before = editingCtx.getBeforeTrkSegmentLine(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java index 865e56e60b..5096cfa59f 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java @@ -36,8 +36,7 @@ public class MultiProfileGeometryWay extends GeometryWay, RoadSegmentData> segmentData; - private List beforeSegments; - private List afterSegments; + private List segments; public MultiProfileGeometryWay(MultiProfileGeometryWayContext context) { super(context, new MultiProfileGeometryWayDrawer(context)); @@ -60,8 +59,10 @@ public class MultiProfileGeometryWay extends GeometryWay> currPathStyle = pathStyles.get(i); - getDrawer().drawPathBorder(canvas, currPathStyle.first, currPathStyle.second); - getDrawer().drawPath(canvas, currPathStyle.first, currPathStyle.second); + if (!((GeometryMultiProfileWayStyle) currPathStyle.second).isGap) { + getDrawer().drawPathBorder(canvas, currPathStyle.first, currPathStyle.second); + getDrawer().drawPath(canvas, currPathStyle.first, currPathStyle.second); + } } getDrawer().drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles); } finally { @@ -69,20 +70,18 @@ public class MultiProfileGeometryWay extends GeometryWay, RoadSegmentData> segmentData, - boolean before, List segments, int segmentIdx) { + public void updateRoute(RotatedTileBox tileBox, Map, RoadSegmentData> segmentData, List segments) { boolean shouldUpdateRoute = tileBox.getMapDensity() != getMapDensity() || segmentDataChanged(segmentData) - || getSegments(before) != segments || getLocationProvider() == null; + || this.segments != segments || getLocationProvider() == null; if (shouldUpdateRoute) { this.segmentData = segmentData; - setSegments(before, segments); - List userPoints = segments.get(segmentIdx).points; + this.segments = segments; List locations; Map> styleMap; List ways = new ArrayList<>(); List> styles = new ArrayList<>(); - setStyles(tileBox, userPoints, ways, styles); + setStyles(tileBox, segments, ways, styles); locations = new ArrayList<>(); styleMap = new TreeMap<>(); @@ -105,51 +104,72 @@ public class MultiProfileGeometryWay extends GeometryWay userPoints, List ways, List> styles) { - MultiProfileGeometryWayContext context = getContext(); + @Override + public void clearWay() { + super.clearWay(); + if (segmentData != null) { + segmentData.clear(); + } + } + + private void setStyles(RotatedTileBox tileBox, List segments, List ways, List> styles) { Path path = new Path(); PathMeasure pathMeasure = new PathMeasure(); - for (int i = 0; i < userPoints.size() - 1; i++) { - WptPt leftPt = userPoints.get(i); - Pair userLine = new Pair<>(leftPt, userPoints.get(i + 1)); - RoadSegmentData routeBetweenPoints = segmentData.get(userLine); - + for (TrkSegment segment : segments) { + List points = segment.points; + for (int i = 0; i < points.size() - 1; i++) { + setStylesInternal(tileBox, points, i, ways, styles, path, pathMeasure); + } + styles.add(new GeometryMultiProfileWayStyle(getContext(), 0, 0, true)); Way way = new Way(-1); - String currProfileKey = getProfileKey(leftPt); - Pair profileData = getProfileData(currProfileKey); - GeometryMultiProfileWayStyle style = new GeometryMultiProfileWayStyle( - getContext(), currProfileKey, profileData.first, profileData.second); - styles.add(style); + WptPt last = points.get(points.size() - 1); + way.addNode(new Node(last.lat, last.lon, -1)); ways.add(way); + } + } - path.reset(); - boolean isSecondToLast = i + 2 == userPoints.size(); - if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { - way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); - if (isSecondToLast) { - way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); - } - movePathToWpt(path, tileBox, userLine.first); - pathLineToWpt(path, tileBox, userLine.second); - } else { - movePathToWpt(path, tileBox, routeBetweenPoints.getPoints().get(0)); - for (WptPt pt : routeBetweenPoints.getPoints()) { - if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { - way.addNode(new Node(pt.lat, pt.lon, -1)); - } - pathLineToWpt(path, tileBox, pt); - } - } + private void setStylesInternal(RotatedTileBox tileBox, List points, int idx, List ways, + List> styles, Path path, PathMeasure pathMeasure) { + MultiProfileGeometryWayContext context = getContext(); + WptPt leftPt = points.get(idx); + Pair userLine = new Pair<>(leftPt, points.get(idx + 1)); + RoadSegmentData routeBetweenPoints = segmentData.get(userLine); + boolean isSecondToLast = idx + 2 == points.size(); - float[] xy = new float[2]; - pathMeasure.setPath(path, false); - float routeLength = pathMeasure.getLength(); - if ((routeLength - context.circleSize) / 2 >= context.minIconMargin) { - pathMeasure.getPosTan(pathMeasure.getLength() * 0.5f, xy, null); - style.setIconLat(tileBox.getLatFromPixel(xy[0], xy[1])); - style.setIconLon(tileBox.getLonFromPixel(xy[0], xy[1])); + Way way = new Way(-1); + String currProfileKey = getProfileKey(leftPt); + Pair profileData = getProfileData(currProfileKey); + GeometryMultiProfileWayStyle style = new GeometryMultiProfileWayStyle( + getContext(), profileData.first, profileData.second); + styles.add(style); + ways.add(way); + + path.reset(); + if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { + way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); + if (isSecondToLast) { + way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); } + movePathToWpt(path, tileBox, userLine.first); + pathLineToWpt(path, tileBox, userLine.second); + } else { + movePathToWpt(path, tileBox, routeBetweenPoints.getPoints().get(0)); + for (WptPt pt : routeBetweenPoints.getPoints()) { + if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { + way.addNode(new Node(pt.lat, pt.lon, -1)); + } + pathLineToWpt(path, tileBox, pt); + } + } + + float[] xy = new float[2]; + pathMeasure.setPath(path, false); + float routeLength = pathMeasure.getLength(); + if ((routeLength - context.circleSize) / 2 >= context.minIconMargin) { + pathMeasure.getPosTan(pathMeasure.getLength() * 0.5f, xy, null); + style.setIconLat(tileBox.getLatFromPixel(xy[0], xy[1])); + style.setIconLon(tileBox.getLonFromPixel(xy[0], xy[1])); } } @@ -181,18 +201,6 @@ public class MultiProfileGeometryWay extends GeometryWay segments) { - if (before) { - this.beforeSegments = segments; - } else { - this.afterSegments = segments; - } - } - - private List getSegments(boolean before) { - return before ? this.beforeSegments : this.afterSegments; - } - private void movePathToWpt(Path path, RotatedTileBox tileBox, WptPt pt) { path.moveTo(tileBox.getPixXFromLatLon(pt.lat, pt.lon), tileBox.getPixYFromLatLon(pt.lat, pt.lon)); } @@ -221,9 +229,8 @@ public class MultiProfileGeometryWay extends GeometryWay { + public static class GeometryMultiProfileWayStyle extends GeometryWayStyle { - private final String profileKey; @ColorInt private final int lineColor; @ColorInt @@ -231,16 +238,25 @@ public class MultiProfileGeometryWay extends GeometryWay Date: Fri, 2 Apr 2021 01:51:28 +0500 Subject: [PATCH 12/32] Change user point icons for multi profile mode --- .../measurementtool/MeasurementToolLayer.java | 41 +++++++++---------- .../MultiProfileGeometryWayContext.java | 13 +++--- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index b630233137..90ebcfda36 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -271,10 +271,10 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL List beforePoints = editingCtx.getBeforePoints(); List afterPoints = editingCtx.getAfterPoints(); if (beforePoints.size() > 0) { - drawPointIcon(canvas, tb, beforePoints.get(beforePoints.size() - 1)); + drawPointIcon(canvas, tb, beforePoints.get(beforePoints.size() - 1), true); } if (afterPoints.size() > 0) { - drawPointIcon(canvas, tb, afterPoints.get(0)); + drawPointIcon(canvas, tb, afterPoints.get(0), true); } if (editingCtx.getSelectedPointPosition() != -1) { @@ -321,25 +321,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL } if (overlapped) { WptPt pt = points.get(0); - if (pt != lastBeforePoint && pt != firstAfterPoint && isInTileBox(tb, pt)) { - float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); - float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); - canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint); - } + drawPointIcon(canvas, tb, pt, false); pt = points.get(points.size() - 1); - if (pt != lastBeforePoint && pt != firstAfterPoint && isInTileBox(tb, pt)) { - float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); - float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); - canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint); - } + drawPointIcon(canvas, tb, pt, false); } else { for (int i = 0; i < points.size(); i++) { WptPt pt = points.get(i); - if (pt != lastBeforePoint && pt != firstAfterPoint && isInTileBox(tb, pt)) { - float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); - float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); - canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint); - } + drawPointIcon(canvas, tb, pt, false); } } @@ -404,14 +392,23 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); } - private void drawPointIcon(Canvas canvas, RotatedTileBox tb, WptPt pt) { - canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); + private void drawPointIcon(Canvas canvas, RotatedTileBox tb, WptPt pt, boolean rotate) { + if (rotate) { + canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); + } float locX = tb.getPixXFromLatLon(pt.lat, pt.lon); float locY = tb.getPixYFromLatLon(pt.lat, pt.lon); - if (tb.containsPoint(locX, locY, 0)) { - canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint); + if (editingCtx.isInMultiProfileMode()) { + canvas.drawBitmap(multiProfileGeometryWayContext.getPointIcon(), locX - multiProfileGeometryWayContext.pointIconSize / 2, + locY - multiProfileGeometryWayContext.pointIconSize / 2, bitmapPaint); + } else { + if (tb.containsPoint(locX, locY, 0)) { + canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint); + } + } + if (rotate) { + canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); } - canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); } public WptPt addCenterPoint(boolean addPointBefore) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java index 3866611c92..555194ba87 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java @@ -24,6 +24,7 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { public final float minIconMargin; public final float circleSize; + public final float pointIconSize; private RenderingLineAttributes multiProfileAttrs; @@ -36,6 +37,7 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { profileIconsBitmapCache = new HashMap<>(); minIconMargin = density * 30; circleSize = density * 70; + pointIconSize = density * 22f; } public void updatePaints(boolean nightMode, @NonNull RenderingLineAttributes multiProfileAttrs) { @@ -46,13 +48,12 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { @Override protected void recreateBitmaps() { float density = getDensity(); - float size = density * 12.5f; - float outerRadius = density * 6.25f; - float centerRadius = density * 6; - float innerRadius = density * 4; - float centerXY = size / 2; + float outerRadius = density * 11f; + float centerRadius = density * 10.5f; + float innerRadius = density * 6.5f; + float centerXY = pointIconSize / 2; - pointIcon = Bitmap.createBitmap((int) size, (int) size, Bitmap.Config.ARGB_8888); + pointIcon = Bitmap.createBitmap((int) pointIconSize, (int) pointIconSize, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(pointIcon); Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); From 98887aba71a56349487d5fc55adeb41a960970a7 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Fri, 2 Apr 2021 16:24:58 +0300 Subject: [PATCH 13/32] Remove phrase --- OsmAnd/res/values/phrases.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index bfe9be1e13..fe727f7ad7 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -284,7 +284,6 @@ Ship chandler Sporting goods Stationery store - Tableware store Ticket sales Tobacco store Toyshop From 1a18eb5b58a332103c70c0cedae9fa10e4bcd99c Mon Sep 17 00:00:00 2001 From: xmd5a Date: Fri, 2 Apr 2021 17:24:17 +0300 Subject: [PATCH 14/32] Add missing phrase (fix https://github.com/osmandapp/OsmAnd/issues/11322) --- OsmAnd/res/values/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index fe727f7ad7..10ea9f7ae6 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4378,4 +4378,6 @@ Horseshoes Kickboxing + Diplomatic office + From 9f40195d76d1cb53d83d40a7a71bfb3ae21c0d04 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Fri, 2 Apr 2021 22:59:20 +0300 Subject: [PATCH 15/32] Remove unnecessary code from toolbar, boolean exit number setting --- ...profile_preference_toolbar_with_switch.xml | 26 +++++----- .../fragments/VoiceAnnouncesFragment.java | 47 +++++++------------ 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml b/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml index 14672b52df..c9ddd04254 100644 --- a/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml +++ b/OsmAnd/res/layout/profile_preference_toolbar_with_switch.xml @@ -5,10 +5,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="0dp" - osmand:contentInsetLeft="0dp" - osmand:contentInsetStart="0dp" - osmand:contentInsetRight="0dp" osmand:contentInsetEnd="0dp" + osmand:contentInsetLeft="0dp" + osmand:contentInsetRight="0dp" + osmand:contentInsetStart="0dp" osmand:theme="@style/ThemeOverlay.AppCompat.ActionBar"> + android:tint="?attr/default_icon_color" + osmand:srcCompat="@drawable/ic_arrow_back" /> + android:orientation="vertical" + android:paddingTop="@dimen/content_padding_half" + android:paddingBottom="@dimen/content_padding_half"> Date: Sat, 3 Apr 2021 21:32:33 +0300 Subject: [PATCH 16/32] Add phrase --- OsmAnd/res/values/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 10ea9f7ae6..2089642add 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -144,6 +144,7 @@ Non-immigrant visas Immigrant visas Citizen services + Bay type Store From 241a2387b12cfc12c46399dc3821e4b169467bf1 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sat, 3 Apr 2021 01:26:33 +0500 Subject: [PATCH 17/32] Fix colorization when speed was derived from timestamps --- .../java/net/osmand/router/RouteColorize.java | 43 ++++++++++++++----- .../net/osmand/plus/track/GradientCard.java | 24 +++-------- .../osmand/plus/views/layers/GPXLayer.java | 9 +++- 3 files changed, 45 insertions(+), 31 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 8fb0046bb4..e224e9c679 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -4,6 +4,7 @@ import net.osmand.GPXUtilities; import net.osmand.PlatformUtil; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -30,6 +31,8 @@ public class RouteColorize { public static final int RED = rgbaToDecimal(243, 55, 77, 255); public static final int[] colors = new int[] {GREEN, YELLOW, RED}; + private static final int MAX_SLOPE_VALUE = 25; + public enum ColorizationType { ELEVATION, SPEED, @@ -75,7 +78,7 @@ public class RouteColorize { /** * @param type ELEVATION, SPEED, SLOPE */ - public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ColorizationType type) { + public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ColorizationType type, float maxProfileSpeed) { if (!gpxFile.hasTrkPt()) { LOG.warn("GPX file is not consist of track points"); @@ -85,21 +88,27 @@ public class RouteColorize { List latList = new ArrayList<>(); List lonList = new ArrayList<>(); List valList = new ArrayList<>(); + + GPXUtilities.GPXTrackAnalysis analysis = Algorithms.isEmpty(gpxFile.path) ? + gpxFile.getAnalysis(System.currentTimeMillis()) : gpxFile.getAnalysis(gpxFile.modifiedTime); + int wptIdx = 0; for (GPXUtilities.Track t : gpxFile.tracks) { for (GPXUtilities.TrkSegment ts : t.segments) { for (GPXUtilities.WptPt p : ts.points) { latList.add(p.lat); lonList.add(p.lon); if (type == ColorizationType.SPEED) { - valList.add(p.speed); + valList.add((double) analysis.speedData.get(wptIdx).speed); } else { - valList.add(p.ele); + valList.add((double) analysis.elevationData.get(wptIdx).elevation); } + wptIdx++; } } } this.zoom = zoom; + colorizationType = type; latitudes = listToArray(latList); longitudes = listToArray(lonList); @@ -108,9 +117,8 @@ public class RouteColorize { } else { values = listToArray(valList); } - calculateMinMaxValue(); - colorizationType = type; + maxValue = getMaxValue(colorizationType, analysis, minValue, maxProfileSpeed); checkPalette(); sortPalette(); } @@ -194,7 +202,7 @@ public class RouteColorize { return rgbaToDecimal((int) resultRed, (int) resultGreen, (int) resultBlue, (int) resultAlpha); } } - return getDefaultColor(); + return getTransparentColor(); } public void setPalette(double[][] palette) { @@ -209,12 +217,12 @@ public class RouteColorize { } setPalette(new double[][] { {minValue, gradientPalette[0]}, - {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, gradientPalette[1]}, + {(minValue + maxValue) / 2, gradientPalette[1]}, {maxValue, gradientPalette[2]} }); } - private int getDefaultColor() { + private int getTransparentColor() { return rgbaToDecimal(0, 0, 0, 0); } @@ -295,7 +303,7 @@ public class RouteColorize { double[][] defaultPalette = { {minValue, GREEN}, - {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW}, + {(minValue + maxValue) / 2, YELLOW}, {maxValue, RED} }; palette = defaultPalette; @@ -397,6 +405,20 @@ public class RouteColorize { return result; } + public static double getMinValue(ColorizationType type, GPXUtilities.GPXTrackAnalysis analysis) { + return type == ColorizationType.ELEVATION ? analysis.minElevation : 0.0; + } + + public static double getMaxValue(ColorizationType type, GPXUtilities.GPXTrackAnalysis analysis, double minValue, double maxProfileSpeed) { + if (type == ColorizationType.SPEED) { + return Math.max(analysis.maxSpeed, maxProfileSpeed); + } else if (type == ColorizationType.ELEVATION) { + return Math.max(analysis.maxElevation, minValue + 50); + } else { + return MAX_SLOPE_VALUE; + } + } + private void calculateMinMaxValue() { if (values.length == 0) return; @@ -457,5 +479,4 @@ public class RouteColorize { this.val = val; } } - -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/GradientCard.java b/OsmAnd/src/net/osmand/plus/track/GradientCard.java index 217ad2a8f1..3c34d9f68d 100644 --- a/OsmAnd/src/net/osmand/plus/track/GradientCard.java +++ b/OsmAnd/src/net/osmand/plus/track/GradientCard.java @@ -12,6 +12,7 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.router.RouteColorize; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -42,8 +43,9 @@ public class GradientCard extends BaseCard { AndroidUiHelper.updateVisibility(view, true); TextView minValue = view.findViewById(R.id.min_value); TextView maxValue = view.findViewById(R.id.max_value); - float min = getMinValue(); - float max = getMaxValue(min); + 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)); } @@ -53,27 +55,13 @@ public class GradientCard extends BaseCard { updateContent(); } - private float getMinValue() { - return (float) (selectedScaleType == GradientScaleType.ALTITUDE ? gpxTrackAnalysis.minElevation : 0.0); - } - - private float getMaxValue(float minValue) { - if (selectedScaleType == GradientScaleType.SPEED) { - return (Math.max(gpxTrackAnalysis.maxSpeed, app.getSettings().getApplicationMode().getMaxSpeed())); - } else if (selectedScaleType == GradientScaleType.ALTITUDE) { - return (float) Math.max(gpxTrackAnalysis.maxElevation, minValue + 50); - } else { - return 25; - } - } - - private CharSequence formatValue(float value) { + private CharSequence formatValue(double value) { if (selectedScaleType == GradientScaleType.ALTITUDE) { return OsmAndFormatter.getFormattedAlt(value, app); } else if (selectedScaleType == GradientScaleType.SLOPE) { return (int) value + " %"; } - String speed = OsmAndFormatter.getFormattedSpeed(value, app); + String speed = OsmAndFormatter.getFormattedSpeed((float) value, app); String speedUnit = app.getSettings().SPEED_SYSTEM.get().toShortString(app); Spannable formattedSpeed = new SpannableString(speed); formattedSpeed.setSpan( diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index c16d687614..5c757285ef 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -684,11 +684,16 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM List segments = selectedGpxFile.getPointsToDisplay(); GradientScaleType scaleType = getGradientScaleType(gpxFile); List colorsOfPoints = null; - if (scaleType != null) { - RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, scaleType.toColorizationType()); + boolean needCalculateColors = scaleType != null && segments.get(0).points.get(0) + .getColor(scaleType.toColorizationType()) == 0; + + if (scaleType != null && currentTrack || needCalculateColors) { + RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, + scaleType.toColorizationType(), view.getApplication().getSettings().getApplicationMode().getMaxSpeed()); colorize.setPalette(getColorizationPalette(gpxFile, scaleType)); colorsOfPoints = colorize.getResult(false); } + int startIdx = 0; for (TrkSegment ts : segments) { String width = getTrackWidthName(gpxFile, defaultTrackWidthPref.get()); From 6cfc02979f1c5946bd26760ce8c50ad95c6707fb Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 4 Apr 2021 03:22:09 +0500 Subject: [PATCH 18/32] Remove border overlapping when zooming gradient track --- .../src/net/osmand/plus/views/Renderable.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index 27d741d964..657cf3856a 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -61,6 +61,7 @@ public class Renderable { public List points = null; // Original list of points protected List culled = new ArrayList<>(); // Reduced/resampled list of points + protected List oldCulled = new ArrayList<>(); protected int pointSize; protected double segmentSize; @@ -116,7 +117,7 @@ public class Renderable { updateLocalPaint(p); canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); if (scaleType != null) { - drawGradient(getPointsForDrawing(), p, canvas, tileBox); + drawGradient(getPointsForDrawingWithBorder(), p, canvas, tileBox); } else { drawSolid(getPointsForDrawing(), p, canvas, tileBox); } @@ -126,6 +127,9 @@ public class Renderable { public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { if (QuadRect.trivialOverlap(tileBox.getLatLonBounds(), trackBounds)) { // is visible? + if (tileBox.getZoomAnimation() > 0 && !Algorithms.isEmpty(culled) && scaleType != null) { + oldCulled = new ArrayList<>(culled); + } startCuller(zoom); drawSingleSegment(zoom, p, canvas, tileBox); } @@ -139,6 +143,16 @@ public class Renderable { return culled.isEmpty() ? points : culled; } + public List getPointsForDrawingWithBorder() { + if (!culled.isEmpty()) { + return culled; + } else if (!oldCulled.isEmpty()) { + return oldCulled; + } else { + return points; + } + } + public void drawGeometry(Canvas canvas, RotatedTileBox tileBox, QuadRect quadRect, int arrowColor, int trackColor, float trackWidth) { if (geometryWay != null) { List points = getPointsForDrawing(); @@ -290,7 +304,8 @@ public class Renderable { super(pt, 0); } - @Override public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { + @Override + public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { if (points.size() != pointSize) { int prevSize = pointSize; pointSize = points.size(); From 9e46f46a6b98cced1b7a10200685df549e841c46 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 4 Apr 2021 10:13:42 +0300 Subject: [PATCH 19/32] Custom width: increase max. number to 36 --- .../src/net/osmand/plus/routing/cards/RouteLineWidthCard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java b/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java index 72055da936..d9843f72ea 100644 --- a/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java +++ b/OsmAnd/src/net/osmand/plus/routing/cards/RouteLineWidthCard.java @@ -36,7 +36,7 @@ import java.util.List; public class RouteLineWidthCard extends BaseCard { private final static int CUSTOM_WIDTH_MIN = 1; - private final static int CUSTOM_WIDTH_MAX = 24; + private final static int CUSTOM_WIDTH_MAX = 36; private RouteLineDrawInfo routeLineDrawInfo; private OnNeedScrollListener onNeedScrollListener; From 4aa78747502aea4987c6d7417dfb75cd98b9a6e8 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Sun, 4 Apr 2021 10:15:23 +0300 Subject: [PATCH 20/32] Fix dark theme --- OsmAnd/res/layout/route_line_appearance.xml | 1 - .../settings/fragments/RouteLineAppearanceFragment.java | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/route_line_appearance.xml b/OsmAnd/res/layout/route_line_appearance.xml index ca822afb37..e5410cdd2f 100644 --- a/OsmAnd/res/layout/route_line_appearance.xml +++ b/OsmAnd/res/layout/route_line_appearance.xml @@ -88,7 +88,6 @@ android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/card_and_list_background_basic" android:minHeight="@dimen/toolbar_height" android:padding="0dp" osmand:contentInsetEnd="0dp" diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteLineAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteLineAppearanceFragment.java index 2975815bb4..254e1e3d3d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/RouteLineAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/RouteLineAppearanceFragment.java @@ -15,6 +15,7 @@ import android.widget.ScrollView; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; @@ -32,7 +33,6 @@ import net.osmand.plus.routing.cards.RouteLineColorCard; import net.osmand.plus.routing.cards.RouteLineColorCard.OnMapThemeUpdateListener; import net.osmand.plus.routing.cards.RouteLineColorCard.OnSelectedColorChangeListener; import net.osmand.plus.routing.cards.RouteLineWidthCard; -import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener; import net.osmand.plus.track.TrackAppearanceFragment.OnNeedScrollListener; @@ -203,6 +203,8 @@ public class RouteLineAppearanceFragment extends ContextMenuScrollFragment imple } }); closeButton.setImageResource(AndroidUtils.getNavigationIconResId(toolbarContainer.getContext())); + int bgColorId = isNightMode() ? R.color.app_bar_color_dark : R.color.list_background_color_light; + toolbarContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), bgColorId)); updateToolbarVisibility(toolbarContainer); } @@ -212,7 +214,7 @@ public class RouteLineAppearanceFragment extends ContextMenuScrollFragment imple if (Build.VERSION.SDK_INT >= 23 && !isNightMode() && view != null) { view.setSystemUiVisibility(view.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); } - return isNightMode() ? R.color.divider_color_dark : R.color.divider_color_light; + return isNightMode() ? R.color.status_bar_color_dark : R.color.divider_color_light; } @Override From d8ddb717427df979d339412e36c0d694f325d4c5 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 4 Apr 2021 18:03:09 +0500 Subject: [PATCH 21/32] Fixes after review --- .../java/net/osmand/router/RouteColorize.java | 21 +++++++------- .../osmand/plus/views/layers/GPXLayer.java | 28 +++++++++++++++---- 2 files changed, 34 insertions(+), 15 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 e224e9c679..a4d5e8a597 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -1,10 +1,13 @@ package net.osmand.router; -import net.osmand.GPXUtilities; +import net.osmand.GPXUtilities.GPXFile; +import net.osmand.GPXUtilities.GPXTrackAnalysis; +import net.osmand.GPXUtilities.Track; +import net.osmand.GPXUtilities.TrkSegment; +import net.osmand.GPXUtilities.WptPt; import net.osmand.PlatformUtil; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; -import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -78,7 +81,7 @@ public class RouteColorize { /** * @param type ELEVATION, SPEED, SLOPE */ - public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ColorizationType type, float maxProfileSpeed) { + public RouteColorize(int zoom, GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, float maxProfileSpeed) { if (!gpxFile.hasTrkPt()) { LOG.warn("GPX file is not consist of track points"); @@ -89,12 +92,10 @@ public class RouteColorize { List lonList = new ArrayList<>(); List valList = new ArrayList<>(); - GPXUtilities.GPXTrackAnalysis analysis = Algorithms.isEmpty(gpxFile.path) ? - gpxFile.getAnalysis(System.currentTimeMillis()) : gpxFile.getAnalysis(gpxFile.modifiedTime); int wptIdx = 0; - for (GPXUtilities.Track t : gpxFile.tracks) { - for (GPXUtilities.TrkSegment ts : t.segments) { - for (GPXUtilities.WptPt p : ts.points) { + for (Track t : gpxFile.tracks) { + for (TrkSegment ts : t.segments) { + for (WptPt p : ts.points) { latList.add(p.lat); lonList.add(p.lon); if (type == ColorizationType.SPEED) { @@ -405,11 +406,11 @@ public class RouteColorize { return result; } - public static double getMinValue(ColorizationType type, GPXUtilities.GPXTrackAnalysis analysis) { + public static double getMinValue(ColorizationType type, GPXTrackAnalysis analysis) { return type == ColorizationType.ELEVATION ? analysis.minElevation : 0.0; } - public static double getMaxValue(ColorizationType type, GPXUtilities.GPXTrackAnalysis analysis, double minValue, double maxProfileSpeed) { + public static double getMaxValue(ColorizationType type, GPXTrackAnalysis analysis, double minValue, double maxProfileSpeed) { if (type == ColorizationType.SPEED) { return Math.max(analysis.maxSpeed, maxProfileSpeed); } else if (type == ColorizationType.ELEVATION) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 5c757285ef..69266746a9 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -680,16 +680,15 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private void drawSelectedFileSegments(SelectedGpxFile selectedGpxFile, boolean currentTrack, Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { + OsmandApplication app = view.getApplication(); GPXFile gpxFile = selectedGpxFile.getGpxFile(); List segments = selectedGpxFile.getPointsToDisplay(); GradientScaleType scaleType = getGradientScaleType(gpxFile); List colorsOfPoints = null; - boolean needCalculateColors = scaleType != null && segments.get(0).points.get(0) - .getColor(scaleType.toColorizationType()) == 0; - if (scaleType != null && currentTrack || needCalculateColors) { - RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, - scaleType.toColorizationType(), view.getApplication().getSettings().getApplicationMode().getMaxSpeed()); + if (needCalculatePointsColors(segments, scaleType)) { + RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, selectedGpxFile.getTrackAnalysis(app), + scaleType.toColorizationType(), app.getSettings().getApplicationMode().getMaxSpeed()); colorize.setPalette(getColorizationPalette(gpxFile, scaleType)); colorsOfPoints = colorize.getResult(false); } @@ -721,6 +720,25 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } } + private boolean needCalculatePointsColors(List segments, GradientScaleType scaleType) { + if (scaleType == null) { + return false; + } + RouteColorize.ColorizationType colorizationType = scaleType.toColorizationType(); + for (int segIdx = segments.size() - 1; segIdx >= 0; segIdx--) { + List pts = segments.get(segIdx).points; + if (!Algorithms.isEmpty(pts)) { + for (int wptIdx = pts.size() - 1; wptIdx >= 0; wptIdx--) { + WptPt pt = pts.get(wptIdx); + if (pt.getColor(colorizationType) == 0) { + return true; + } + } + } + } + return false; + } + private int setColorsToPoints(TrkSegment segment, List colors, GradientScaleType scaleType, int startIdx) { int pointsSize = segment.points.size(); RouteColorize.RouteColorizationPoint startColor = colors.get(startIdx); From 4d9d1fd18fe5d1bcabaa8cc9ba339ff142d50eac Mon Sep 17 00:00:00 2001 From: cepprice Date: Sun, 4 Apr 2021 18:25:53 +0500 Subject: [PATCH 22/32] Fix route saving --- .../measurementtool/MeasurementToolLayer.java | 5 +---- .../geometry/MultiProfileGeometryWay.java | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java index 90ebcfda36..9d3f8812c4 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolLayer.java @@ -219,10 +219,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL if (editingCtx.isInMultiProfileMode()) { multiProfileGeometryWayContext.updatePaints(settings.isNightMode(), multiProfileLineAttrs); - List allSegments = new ArrayList<>(); - allSegments.addAll(editingCtx.getBeforeSegments()); - allSegments.addAll(editingCtx.getAfterSegments()); - multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), allSegments); + multiProfileGeometry.updateRoute(tb, editingCtx.getRoadSegmentData(), editingCtx.getBeforeSegments(), editingCtx.getAfterSegments()); multiProfileGeometry.drawSegments(canvas, tb); } else { multiProfileGeometry.clearWay(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java index 5096cfa59f..c2d98d7a54 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java @@ -5,6 +5,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Path; import android.graphics.PathMeasure; +import android.util.Log; import android.util.Pair; import net.osmand.GPXUtilities.TrkSegment; @@ -36,7 +37,8 @@ public class MultiProfileGeometryWay extends GeometryWay, RoadSegmentData> segmentData; - private List segments; + private List beforeSegments; + private List afterSegments; public MultiProfileGeometryWay(MultiProfileGeometryWayContext context) { super(context, new MultiProfileGeometryWayDrawer(context)); @@ -70,20 +72,26 @@ public class MultiProfileGeometryWay extends GeometryWay, RoadSegmentData> segmentData, List segments) { + public void updateRoute(RotatedTileBox tileBox, Map, RoadSegmentData> segmentData, + List beforeSegments, List afterSegments) { boolean shouldUpdateRoute = tileBox.getMapDensity() != getMapDensity() || segmentDataChanged(segmentData) - || this.segments != segments || getLocationProvider() == null; + || this.beforeSegments != beforeSegments || this.afterSegments != afterSegments || getLocationProvider() == null; if (shouldUpdateRoute) { this.segmentData = segmentData; - this.segments = segments; + this.beforeSegments = beforeSegments; + this.afterSegments = afterSegments; + List locations; Map> styleMap; - List ways = new ArrayList<>(); List> styles = new ArrayList<>(); - setStyles(tileBox, segments, ways, styles); locations = new ArrayList<>(); + List allSegments = new ArrayList<>(); + allSegments.addAll(beforeSegments); + allSegments.addAll(afterSegments); + setStyles(tileBox, allSegments, ways, styles); + styleMap = new TreeMap<>(); int i = 0; int k = 0; From 516881f8a5fd7fde473f65ed245d8919328f9cd6 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 5 Apr 2021 09:25:07 +0300 Subject: [PATCH 23/32] Add getTranslatedItemName() to other class --- .../src/net/osmand/plus/quickaction/actions/MapStyleAction.java | 2 +- OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java index 0938e4d121..5838bfc1a2 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/actions/MapStyleAction.java @@ -250,6 +250,6 @@ public class MapStyleAction extends SwitchableAction { public String getActionText(OsmandApplication application) { String currentSource = application.getSettings().RENDERER.get(); - return application.getString(R.string.map_quick_action_pattern, currentSource); + return application.getString(R.string.map_quick_action_pattern, getTranslatedItemName(application, currentSource)); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java index 86043763ea..d81b1f12ed 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/MapSourceAction.java @@ -221,6 +221,6 @@ public class MapSourceAction extends SwitchableAction> { ? application.getSettings().MAP_TILE_SOURCES.get() : application.getString(R.string.vector_data); - return application.getString(R.string.map_quick_action_pattern, currentSource); + return application.getString(R.string.map_quick_action_pattern, getTranslatedItemName(application, currentSource)); } } From f8cd5510855c3278c55f7633531ffb6e4d2b0ee6 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 5 Apr 2021 09:29:16 +0300 Subject: [PATCH 24/32] Remove else block with rtl and ltr combine --- .../src/net/osmand/plus/srtmplugin/TerrainFragment.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java index 149d118124..ae15dfbf6e 100644 --- a/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java +++ b/OsmAnd/src/net/osmand/plus/srtmplugin/TerrainFragment.java @@ -187,13 +187,7 @@ public class TerrainFragment extends BaseOsmAndFragment implements View.OnClickL getString(R.string.slope_read_more), wikiString ); - boolean isArabicLocale = Locale.getDefault().getLanguage().equals("ar"); - String emptyStateText; - if (isArabicLocale) { - emptyStateText = getString(R.string.terrain_empty_state_text) + "\n" + PLUGIN_URL; - } else { - emptyStateText = String.format(getString(R.string.ltr_or_rtl_combine_via_space), getString(R.string.terrain_empty_state_text), PLUGIN_URL); - } + String emptyStateText = getString(R.string.terrain_empty_state_text) + "\n" + PLUGIN_URL; setupClickableText(slopeReadMoreTv, readMoreText, wikiString, SLOPES_WIKI_URL, false); setupClickableText(emptyStateDescriptionTv, emptyStateText, PLUGIN_URL, PLUGIN_URL, true); From eb4a1108f8a346448d1bdf636a54981fff40a9ab Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 5 Apr 2021 11:44:55 +0500 Subject: [PATCH 25/32] Review fixes --- .../MeasurementEditingContext.java | 29 ++++++++++++++++--- .../views/layers/geometry/GeometryWay.java | 12 ++++++-- .../layers/geometry/GeometryWayContext.java | 3 +- .../geometry/MultiProfileGeometryWay.java | 28 ++++-------------- .../MultiProfileGeometryWayContext.java | 15 ++++++---- .../MultiProfileGeometryWayDrawer.java | 12 +++----- 6 files changed, 54 insertions(+), 45 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index bda7c5404b..ba28e9402a 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -2,9 +2,6 @@ package net.osmand.plus.measurementtool; import android.util.Pair; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; @@ -38,12 +35,18 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.NEXT_SEGMENT; import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode.WHOLE_TRACK; import static net.osmand.plus.measurementtool.command.MeasurementModeCommand.MeasurementCommandType.APPROXIMATE_POINTS; @@ -1112,7 +1115,25 @@ public class MeasurementEditingContext implements IRouteSettingsListener { } public boolean isInMultiProfileMode() { - return lastCalculationMode == CalculationMode.NEXT_SEGMENT; + if (lastCalculationMode == CalculationMode.NEXT_SEGMENT) { + return true; + } + Set profiles = new HashSet<>(); + List segments = new ArrayList<>(); + segments.addAll(beforeSegments); + segments.addAll(afterSegments); + for (TrkSegment segment : segments) { + if (Algorithms.isEmpty(segment.points)) { + continue; + } + for (WptPt pt : segment.points) { + if (!pt.isGap()) { + profiles.add(pt.getProfileType()); + } + } + } + lastCalculationMode = profiles.size() >= 2 ? NEXT_SEGMENT : WHOLE_TRACK; + return profiles.size() >= 2; } @Override 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 9489cd9620..d5f206ec90 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -11,6 +11,8 @@ import net.osmand.Location; import net.osmand.data.RotatedTileBox; import net.osmand.util.MapAlgorithms; import net.osmand.util.MapUtils; +import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle; + import java.util.ArrayList; import java.util.Collections; @@ -188,7 +190,9 @@ public abstract class GeometryWay prevStyle = style instanceof GeometryMultiProfileWayStyle ? + getStyle(i - 1, style) : style; + addLocation(tb, prevLat, prevLon, prevStyle, tx, ty, angles, distances, dist, styles); // first point } } addLocation(tb, lat, lon, style, tx, ty, angles, distances, dist, styles); @@ -360,7 +364,7 @@ public abstract class GeometryWay>> paths = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, 0, styles, paths); + calculatePath(tb, tx, ty, getOutMargin(), styles, paths); for (Pair> pc : paths) { GeometryWayStyle style = pc.second; if (style.hasPathLine()) { @@ -377,6 +381,10 @@ public abstract class GeometryWay tx, List ty, List angles, List distances, double distToFinish, List> styles) { - if (tx.size() < 2) { - return; - } - try { - List>> pathStyles = new ArrayList<>(); - canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, getContext().circleSize, styles, pathStyles); - - for (int i = 0; i < pathStyles.size(); i++) { - Pair> currPathStyle = pathStyles.get(i); - if (!((GeometryMultiProfileWayStyle) currPathStyle.second).isGap) { - getDrawer().drawPathBorder(canvas, currPathStyle.first, currPathStyle.second); - getDrawer().drawPath(canvas, currPathStyle.first, currPathStyle.second); - } - } - getDrawer().drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles); - } finally { - canvas.rotate(tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - } - } - public void updateRoute(RotatedTileBox tileBox, Map, RoadSegmentData> segmentData, List beforeSegments, List afterSegments) { boolean shouldUpdateRoute = tileBox.getMapDensity() != getMapDensity() || segmentDataChanged(segmentData) @@ -231,6 +208,11 @@ public class MultiProfileGeometryWay extends GeometryWay(mode.getProfileColor(night), mode.getIconRes()); } + @Override + protected float getOutMargin() { + return getContext().getAttrs().paint.getStrokeWidth() * 2; + } + @NonNull @Override public GeometryWayStyle getDefaultWayStyle() { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java index 555194ba87..d6ef3cfa72 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayContext.java @@ -7,6 +7,7 @@ import android.graphics.Color; import android.graphics.Paint; import net.osmand.AndroidUtils; +import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; import net.osmand.util.Algorithms; @@ -26,6 +27,8 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { public final float circleSize; public final float pointIconSize; + private static final String pointColorHex = "#637EFB"; + private RenderingLineAttributes multiProfileAttrs; private Bitmap pointIcon; @@ -64,15 +67,10 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { paint.setColor(Color.WHITE); canvas.drawCircle(centerXY, centerXY, centerRadius, paint); - paint.setColor(Algorithms.parseColor("#637EFB")); + paint.setColor(Algorithms.parseColor(pointColorHex)); canvas.drawCircle(centerXY, centerXY, innerRadius, paint); } - @Override - protected int getArrowBitmapResId() { - return 0; - } - @NonNull public Bitmap getProfileIconBitmap(@DrawableRes int iconRes, @ColorInt int color) { String key = iconRes + "_" + color; @@ -100,4 +98,9 @@ public class MultiProfileGeometryWayContext extends GeometryWayContext { public Bitmap getPointIcon() { return pointIcon; } + + @Override + protected int getArrowBitmapResId() { + return R.drawable.ic_action_split_interval; + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java index 7bc5620d18..52fed039ac 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -19,6 +19,10 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer style) { if (style instanceof GeometryMultiProfileWayStyle) { RenderingLineAttributes attrs = getContext().getAttrs(); + + attrs.paint.setColor(((GeometryMultiProfileWayStyle) style).getBorderColor()); + canvas.drawPath(path, attrs.paint); + attrs.paint2.setColor(((GeometryMultiProfileWayStyle) style).getLineColor()); canvas.drawPath(path, attrs.paint2); } @@ -42,12 +46,4 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer style) { - if (style instanceof GeometryMultiProfileWayStyle) { - RenderingLineAttributes attrs = getContext().getAttrs(); - attrs.paint.setColor(((GeometryMultiProfileWayStyle) style).getBorderColor()); - canvas.drawPath(path, attrs.paint); - } - } } \ No newline at end of file From 96d6aff02110a60e0ee35edc02812d29bcad9437 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 5 Apr 2021 09:58:00 +0300 Subject: [PATCH 26/32] Review --- .../net/osmand/plus/routing/VoiceRouter.java | 37 ++++++++----------- .../plus/settings/backend/OsmandSettings.java | 2 +- .../fragments/VoiceAnnouncesFragment.java | 9 ++--- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index 70c8443701..3d6318ca48 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -27,8 +27,6 @@ import net.osmand.router.TurnType; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; -import org.apache.commons.lang3.StringUtils; - import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -665,29 +663,26 @@ public class VoiceRouter { } private String getSpeakableExitRef(String exit) { - boolean showStartDialog = settings.EXIT_NUMBER_NAMES_SHOWED.get(); - if (showStartDialog) { - StringBuilder sb = new StringBuilder(); - if (exit != null) { - exit = exit.replace('-', ' '); - exit = exit.replace(':', ' '); - // Add spaces between digits and letters for better pronunciation - int length = exit.length(); - for (int i = 0; i < length; i++) { - if (i + 1 < length && Character.isDigit(exit.charAt(i)) && Character.isLetter(exit.charAt(i + 1))) { - sb.append(exit.charAt(i)); - sb.append(' '); - } else { - sb.append(exit.charAt(i)); - } + StringBuilder sb = new StringBuilder(); + if (exit != null) { + exit = exit.replace('-', ' '); + exit = exit.replace(':', ' '); + // Add spaces between digits and letters for better pronunciation + int length = exit.length(); + for (int i = 0; i < length; i++) { + if (i + 1 < length && Character.isDigit(exit.charAt(i)) && Character.isLetter(exit.charAt(i + 1))) { + sb.append(exit.charAt(i)); + sb.append(' '); + } else { + sb.append(exit.charAt(i)); } } - return sb.toString(); } - return StringUtils.EMPTY; + return sb.toString(); } + private int getIntRef(String stringRef) { int intRef = Algorithms.findFirstNumberEndIndex(stringRef); if (intRef > 0) { @@ -707,7 +702,7 @@ public class VoiceRouter { boolean isPlay = true; ExitInfo exitInfo = next.getExitInfo(); if (tParam != null) { - if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef())) { + if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && !settings.SPEAK_EXIT_NUMBER_NAMES.get()) { String stringRef = getSpeakableExitRef(exitInfo.getRef()); p.takeExit(tParam, dist, stringRef, getIntRef(exitInfo.getRef()), getSpeakableExitName(next, exitInfo, true)); } else { @@ -782,7 +777,7 @@ public class VoiceRouter { ExitInfo exitInfo = next.getExitInfo(); boolean isplay = true; if (tParam != null) { - if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef())) { + if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && !settings.SPEAK_EXIT_NUMBER_NAMES.get()) { String stringRef = getSpeakableExitRef(exitInfo.getRef()); p.takeExit(tParam, stringRef, getIntRef(exitInfo.getRef()), getSpeakableExitName(next, exitInfo, !suppressDest)); } else { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 72a692a8cc..e9339ccda4 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1355,10 +1355,10 @@ public class OsmandSettings { public final OsmandPreference SPEAK_SPEED_LIMIT = new BooleanPreference(this, "speak_speed_limit", false).makeProfile().cache(); public final OsmandPreference SPEAK_SPEED_CAMERA = new BooleanPreference(this, "speak_cameras", false).makeProfile().cache(); public final OsmandPreference SPEAK_TUNNELS = new BooleanPreference(this, "speak_tunnels", false).makeProfile().cache(); + public final OsmandPreference SPEAK_EXIT_NUMBER_NAMES = new BooleanPreference(this, "exit_number_names", true).makeProfile().cache(); public final OsmandPreference SPEED_CAMERAS_UNINSTALLED = new BooleanPreference(this, "speed_cameras_uninstalled", false).makeGlobal().makeShared(); public final OsmandPreference SPEED_CAMERAS_ALERT_SHOWED = new BooleanPreference(this, "speed_cameras_alert_showed", false).makeGlobal().makeShared(); - public final OsmandPreference EXIT_NUMBER_NAMES_SHOWED = new BooleanPreference(this, "exit_number_names", false).makeGlobal().makeShared(); public Set getForbiddenTypes() { Set typeNames = new HashSet<>(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java index edce5b859c..f041572b91 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/VoiceAnnouncesFragment.java @@ -69,16 +69,13 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPr protected void updateToolbar() { super.updateToolbar(); View view = getView(); - final boolean nightMode = !settings.isLightContentForMode(getSelectedAppMode()); - int iconColor = getResources().getColor(nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light); - ImageView profileIcon = (ImageView) view.findViewById(R.id.profile_icon); - profileIcon.setImageResource(R.drawable.ic_action_help_online); - profileIcon.setColorFilter(iconColor); + ImageView profileIcon = view.findViewById(R.id.profile_icon); + profileIcon.setImageDrawable(app.getUIUtilities().getIcon(R.drawable.ic_action_help_online, isNightMode() ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); profileIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (getContext() != null) { - WikipediaDialogFragment.showFullArticle(getContext(), Uri.parse(OSMAND_VOICE_NAVIGATION_URL), nightMode); + WikipediaDialogFragment.showFullArticle(getContext(), Uri.parse(OSMAND_VOICE_NAVIGATION_URL), isNightMode()); } } }); From 34f3474f1293b54a2511a77750d09e355ebc7798 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 5 Apr 2021 13:59:22 +0500 Subject: [PATCH 27/32] Fix profile icons placing --- .../geometry/MultiProfileGeometryWay.java | 103 +++++++----------- .../MultiProfileGeometryWayDrawer.java | 47 +++++++- 2 files changed, 79 insertions(+), 71 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java index eda20443e8..fa5f648217 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWay.java @@ -3,14 +3,12 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.Path; -import android.graphics.PathMeasure; -import android.util.Log; import android.util.Pair; import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; import net.osmand.Location; +import net.osmand.data.LatLon; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.osm.edit.Node; @@ -67,7 +65,7 @@ public class MultiProfileGeometryWay extends GeometryWay allSegments = new ArrayList<>(); allSegments.addAll(beforeSegments); allSegments.addAll(afterSegments); - setStyles(tileBox, allSegments, ways, styles); + setStyles(allSegments, ways, styles); styleMap = new TreeMap<>(); int i = 0; @@ -97,16 +95,13 @@ public class MultiProfileGeometryWay extends GeometryWay segments, List ways, List> styles) { - Path path = new Path(); - PathMeasure pathMeasure = new PathMeasure(); - + private void setStyles(List segments, List ways, List> styles) { for (TrkSegment segment : segments) { List points = segment.points; for (int i = 0; i < points.size() - 1; i++) { - setStylesInternal(tileBox, points, i, ways, styles, path, pathMeasure); + setStylesInternal(points, i, ways, styles); } - styles.add(new GeometryMultiProfileWayStyle(getContext(), 0, 0, true)); + styles.add(new GeometryMultiProfileWayStyle(getContext(), new ArrayList(), 0, 0, true)); Way way = new Way(-1); WptPt last = points.get(points.size() - 1); way.addNode(new Node(last.lat, last.lon, -1)); @@ -114,48 +109,42 @@ public class MultiProfileGeometryWay extends GeometryWay points, int idx, List ways, - List> styles, Path path, PathMeasure pathMeasure) { - MultiProfileGeometryWayContext context = getContext(); - WptPt leftPt = points.get(idx); - Pair userLine = new Pair<>(leftPt, points.get(idx + 1)); - RoadSegmentData routeBetweenPoints = segmentData.get(userLine); + private void setStylesInternal(List points, int idx, List ways, List> styles) { + WptPt startPt = points.get(idx); + WptPt endPt = points.get(idx + 1); + List routePoints = getRoutePoints(startPt, endPt); boolean isSecondToLast = idx + 2 == points.size(); Way way = new Way(-1); - String currProfileKey = getProfileKey(leftPt); + String currProfileKey = getProfileKey(startPt); Pair profileData = getProfileData(currProfileKey); GeometryMultiProfileWayStyle style = new GeometryMultiProfileWayStyle( - getContext(), profileData.first, profileData.second); + getContext(), routePoints, profileData.first, profileData.second); styles.add(style); ways.add(way); - path.reset(); - if (routeBetweenPoints == null || Algorithms.isEmpty(routeBetweenPoints.getPoints())) { - way.addNode(new Node(userLine.first.lat, userLine.first.lon, -1)); - if (isSecondToLast) { - way.addNode(new Node(userLine.second.lat, userLine.second.lon, -1)); - } - movePathToWpt(path, tileBox, userLine.first); - pathLineToWpt(path, tileBox, userLine.second); - } else { - movePathToWpt(path, tileBox, routeBetweenPoints.getPoints().get(0)); - for (WptPt pt : routeBetweenPoints.getPoints()) { - if (pt.lat != userLine.second.lat && pt.lon != userLine.second.lon || isSecondToLast) { - way.addNode(new Node(pt.lat, pt.lon, -1)); - } - pathLineToWpt(path, tileBox, pt); + for (LatLon routePt : routePoints) { + if (isSecondToLast || routePt.getLatitude() != endPt.getLatitude() + && routePt.getLongitude() != endPt.getLongitude()) { + way.addNode(new Node(routePt.getLatitude(), routePt.getLongitude(), -1)); } } + } - float[] xy = new float[2]; - pathMeasure.setPath(path, false); - float routeLength = pathMeasure.getLength(); - if ((routeLength - context.circleSize) / 2 >= context.minIconMargin) { - pathMeasure.getPosTan(pathMeasure.getLength() * 0.5f, xy, null); - style.setIconLat(tileBox.getLatFromPixel(xy[0], xy[1])); - style.setIconLon(tileBox.getLonFromPixel(xy[0], xy[1])); + private List getRoutePoints(WptPt start, WptPt end) { + Pair userLine = new Pair<>(start, end); + RoadSegmentData roadSegmentData = segmentData.get(userLine); + List routePoints = new ArrayList<>(); + + if (roadSegmentData == null || Algorithms.isEmpty(roadSegmentData.getPoints())) { + routePoints.add(new LatLon(start.lat, start.lon)); + routePoints.add(new LatLon(end.lat, end.lon)); + } else { + for (WptPt routePt : roadSegmentData.getPoints()) { + routePoints.add(new LatLon(routePt.lat, routePt.lon)); + } } + return routePoints; } @Override @@ -186,14 +175,6 @@ public class MultiProfileGeometryWay extends GeometryWay routePoints; - public GeometryMultiProfileWayStyle(MultiProfileGeometryWayContext context, + public GeometryMultiProfileWayStyle(MultiProfileGeometryWayContext context, List routePoints, @ColorInt int profileColor, @DrawableRes int profileIconRes, boolean isGap) { super(context); + this.routePoints = routePoints; this.lineColor = profileColor; this.borderColor = ColorUtils.blendARGB(profileColor, Color.BLACK, 0.2f); this.profileIconRes = profileIconRes; @@ -244,9 +225,9 @@ public class MultiProfileGeometryWay extends GeometryWay routePoints, @ColorInt int profileColor, @DrawableRes int profileIconRes) { - this(context, profileColor, profileIconRes, false); + this(context, routePoints, profileColor, profileIconRes, false); } @ColorInt @@ -264,20 +245,12 @@ public class MultiProfileGeometryWay extends GeometryWay getRoutePoints() { + return routePoints; } - public void setIconLon(double lon) { - iconLon = lon; - } - - public double getIconLat() { - return iconLat; - } - - public double getIconLon() { - return iconLon; + public boolean isGap() { + return isGap; } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java index 52fed039ac..b0c7e7c369 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -2,10 +2,14 @@ package net.osmand.plus.views.layers.geometry; import android.graphics.Canvas; import android.graphics.Path; +import android.graphics.PathMeasure; +import android.graphics.PointF; +import net.osmand.data.LatLon; import net.osmand.data.RotatedTileBox; import net.osmand.plus.views.OsmandMapLayer.RenderingLineAttributes; import net.osmand.plus.views.layers.geometry.MultiProfileGeometryWay.GeometryMultiProfileWayStyle; +import net.osmand.util.Algorithms; import java.util.List; @@ -30,20 +34,51 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer tx, List ty, List angles, List distances, double distPixToFinish, List> styles) { + Path path = new Path(); + PathMeasure pathMeasure = new PathMeasure(); MultiProfileGeometryWayContext context = getContext(); GeometryMultiProfileWayStyle style = null; for (int i = 0; i < styles.size(); i++) { - if (styles.get(i) != null && !styles.get(i).equals(style)) { + GeometryWayStyle s = styles.get(i); + if (s != null && !s.equals(style) || !((GeometryMultiProfileWayStyle) s).isGap()) { style = (GeometryMultiProfileWayStyle) styles.get(i); - double lat = style.getIconLat(); - double lon = style.getIconLon(); - if (!Double.isNaN(lat) && !Double.isNaN(lon)) { - float x = tb.getPixXFromLatLon(lat, lon) - context.circleSize / 2; - float y = tb.getPixYFromLatLon(lat, lon) - context.circleSize / 2; + PointF center = getIconCenter(tb, style.getRoutePoints(), path, pathMeasure); + if (center != null && tb.containsPoint(center.x, center.y, context.circleSize)) { + float x = center.x - context.circleSize / 2; + float y = center.y - context.circleSize / 2; canvas.drawBitmap(style.getPointBitmap(), x, y, null); } } } } + + private PointF getIconCenter(RotatedTileBox tileBox, List routePoints, Path path, PathMeasure pathMeasure) { + if (Algorithms.isEmpty(routePoints)) { + return null; + } + + path.reset(); + PointF first = getPoint(tileBox, routePoints.get(0)); + path.moveTo(first.x, first.y); + for (int i = 1; i < routePoints.size(); i++) { + PointF pt = getPoint(tileBox, routePoints.get(i)); + path.lineTo(pt.x, pt.y); + } + + pathMeasure.setPath(path, false); + float routeLength = pathMeasure.getLength(); + if ((routeLength - getContext().circleSize) / 2 < getContext().minIconMargin) { + return null; + } + + float[] xy = new float[2]; + pathMeasure.getPosTan(routeLength * 0.5f, xy, null); + return new PointF(xy[0], xy[1]); + } + + private PointF getPoint(RotatedTileBox tileBox, LatLon latLon) { + return new PointF(tileBox.getPixXFromLatLon(latLon.getLatitude(), latLon.getLongitude()), + tileBox.getPixYFromLatLon(latLon.getLatitude(), latLon.getLongitude())); + } } \ No newline at end of file From 0604374475cfa396da680cb60bc601eb55910c92 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 5 Apr 2021 14:21:00 +0500 Subject: [PATCH 28/32] Remove out margin --- .../views/layers/geometry/GeometryWay.java | 18 +++++------------- .../geometry/MultiProfileGeometryWay.java | 5 ----- 2 files changed, 5 insertions(+), 18 deletions(-) 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 d5f206ec90..2538103ec0 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -265,20 +265,16 @@ public abstract class GeometryWay= lx && x <= rx && y >= ty && y <= by; } - public static boolean isIn(float x, float y, int lx, int ty, int rx, int by, float outMargin) { - return x >= lx - outMargin && x <= rx + outMargin && y >= ty - outMargin && y <= by + outMargin; - } - public static int calculatePath(RotatedTileBox tb, List xs, List ys, Path path) { List>> paths = new ArrayList<>(); - int res = calculatePath(tb, xs, ys, 0, null, paths); + int res = calculatePath(tb, xs, ys, null, paths); if (paths.size() > 0) { path.addPath(paths.get(0).first); } return res; } - public static int calculatePath(RotatedTileBox tb, List xs, List ys, float outMargin, List> styles, List>> paths) { + public static int calculatePath(RotatedTileBox tb, List xs, List ys, List> styles, List>> paths) { boolean segmentStarted = false; float prevX = xs.get(0); float prevY = ys.get(0); @@ -288,11 +284,11 @@ public abstract class GeometryWay style = hasStyles ? styles.get(0) : null; Path path = new Path(); - boolean prevIn = isIn(prevX, prevY, 0, 0, width, height, outMargin); + boolean prevIn = isIn(prevX, prevY, 0, 0, width, height); for (int i = 1; i < xs.size(); i++) { float currX = xs.get(i); float currY = ys.get(i); - boolean currIn = isIn(currX, currY, 0, 0, width, height, outMargin); + boolean currIn = isIn(currX, currY, 0, 0, width, height); boolean draw = false; if (prevIn && currIn) { draw = true; @@ -364,7 +360,7 @@ public abstract class GeometryWay>> paths = new ArrayList<>(); canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY()); - calculatePath(tb, tx, ty, getOutMargin(), styles, paths); + calculatePath(tb, tx, ty, styles, paths); for (Pair> pc : paths) { GeometryWayStyle style = pc.second; if (style.hasPathLine()) { @@ -381,10 +377,6 @@ public abstract class GeometryWay(mode.getProfileColor(night), mode.getIconRes()); } - @Override - protected float getOutMargin() { - return getContext().getAttrs().paint.getStrokeWidth() * 2; - } - @NonNull @Override public GeometryWayStyle getDefaultWayStyle() { From 8c37068918dab38f526d65c2785ecb44ea2ec19c Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 5 Apr 2021 13:00:16 +0300 Subject: [PATCH 29/32] Undo inverting setting, remove method from BaseSettingsFragment --- OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java | 4 ++-- .../plus/settings/fragments/BaseSettingsFragment.java | 6 ------ .../plus/settings/fragments/ScreenAlertsFragment.java | 6 ++++++ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index 3d6318ca48..e4f34943d9 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -702,7 +702,7 @@ public class VoiceRouter { boolean isPlay = true; ExitInfo exitInfo = next.getExitInfo(); if (tParam != null) { - if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && !settings.SPEAK_EXIT_NUMBER_NAMES.get()) { + if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && settings.SPEAK_EXIT_NUMBER_NAMES.get()) { String stringRef = getSpeakableExitRef(exitInfo.getRef()); p.takeExit(tParam, dist, stringRef, getIntRef(exitInfo.getRef()), getSpeakableExitName(next, exitInfo, true)); } else { @@ -777,7 +777,7 @@ public class VoiceRouter { ExitInfo exitInfo = next.getExitInfo(); boolean isplay = true; if (tParam != null) { - if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && !settings.SPEAK_EXIT_NUMBER_NAMES.get()) { + if (exitInfo != null && !Algorithms.isEmpty(exitInfo.getRef()) && settings.SPEAK_EXIT_NUMBER_NAMES.get()) { String stringRef = getSpeakableExitRef(exitInfo.getRef()); p.takeExit(tParam, stringRef, getIntRef(exitInfo.getRef()), getSpeakableExitName(next, exitInfo, !suppressDest)); } else { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java index 6eeea74426..05c4c7e323 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/BaseSettingsFragment.java @@ -924,12 +924,6 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl } } - public void setupSpeedCamerasAlert() { - Preference speedCamerasAlert = findPreference(settings.SPEED_CAMERAS_UNINSTALLED.getId()); - speedCamerasAlert.setIcon(getContentIcon(R.drawable.ic_action_alert)); - speedCamerasAlert.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get()); - } - public void setupPrefRoundedBg(PreferenceViewHolder holder) { View selectableView = holder.itemView.findViewById(R.id.selectable_list_item); if (selectableView != null) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ScreenAlertsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ScreenAlertsFragment.java index a312253aee..b10d149342 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ScreenAlertsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ScreenAlertsFragment.java @@ -164,4 +164,10 @@ public class ScreenAlertsFragment extends BaseSettingsFragment implements OnPref showCameras.setIcon(getIcon(R.drawable.list_warnings_speed_camera)); showCameras.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get()); } + + public void setupSpeedCamerasAlert() { + Preference speedCamerasAlert = findPreference(settings.SPEED_CAMERAS_UNINSTALLED.getId()); + speedCamerasAlert.setIcon(getContentIcon(R.drawable.ic_action_alert)); + speedCamerasAlert.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get()); + } } \ No newline at end of file From 38d05b1f452bcb5735b32300d2dbbf50e07a1d8e Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 5 Apr 2021 13:17:58 +0300 Subject: [PATCH 30/32] Update VoiceRouter.java --- OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java index e4f34943d9..290ff960c8 100644 --- a/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java +++ b/OsmAnd/src/net/osmand/plus/routing/VoiceRouter.java @@ -681,8 +681,6 @@ public class VoiceRouter { return sb.toString(); } - - private int getIntRef(String stringRef) { int intRef = Algorithms.findFirstNumberEndIndex(stringRef); if (intRef > 0) { From b0b5a4cdb265568bf5d1af702cff0c211b3cf654 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Mon, 5 Apr 2021 14:12:03 +0300 Subject: [PATCH 31/32] Fix RouteColorize constructor for MapCreator --- .../main/java/net/osmand/router/RouteColorize.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 a4d5e8a597..0a39d57e25 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -8,6 +8,7 @@ import net.osmand.GPXUtilities.WptPt; import net.osmand.PlatformUtil; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; +import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; import org.apache.commons.logging.Log; @@ -81,6 +82,10 @@ public class RouteColorize { /** * @param type ELEVATION, SPEED, SLOPE */ + public RouteColorize(int zoom, GPXFile gpxFile, ColorizationType type) { + this(zoom, gpxFile, null, type, 0); + } + public RouteColorize(int zoom, GPXFile gpxFile, GPXTrackAnalysis analysis, ColorizationType type, float maxProfileSpeed) { if (!gpxFile.hasTrkPt()) { @@ -91,8 +96,13 @@ public class RouteColorize { List latList = new ArrayList<>(); List lonList = new ArrayList<>(); List valList = new ArrayList<>(); - int wptIdx = 0; + + if (analysis == null) { + analysis = Algorithms.isEmpty(gpxFile.path) + ? gpxFile.getAnalysis(System.currentTimeMillis()) + : gpxFile.getAnalysis(gpxFile.modifiedTime); + } for (Track t : gpxFile.tracks) { for (TrkSegment ts : t.segments) { for (WptPt p : ts.points) { From 7fd107c97aab309845e256faf0d36d62b4003400 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 5 Apr 2021 19:56:03 +0500 Subject: [PATCH 32/32] Review fixes --- .../MeasurementEditingContext.java | 20 ++++++++----------- .../views/layers/geometry/GeometryWay.java | 4 +--- .../MultiProfileGeometryWayDrawer.java | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java index ba28e9402a..af4d599afa 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementEditingContext.java @@ -1119,21 +1119,17 @@ public class MeasurementEditingContext implements IRouteSettingsListener { return true; } Set profiles = new HashSet<>(); - List segments = new ArrayList<>(); - segments.addAll(beforeSegments); - segments.addAll(afterSegments); - for (TrkSegment segment : segments) { - if (Algorithms.isEmpty(segment.points)) { - continue; - } - for (WptPt pt : segment.points) { - if (!pt.isGap()) { - profiles.add(pt.getProfileType()); + for (RoadSegmentData segmentData : roadSegmentData.values()) { + String profile = segmentData.getAppMode().getStringKey(); + if (!DEFAULT_APP_MODE.getStringKey().equals(profile)) { + profiles.add(profile); + if (profiles.size() >= 2) { + lastCalculationMode = NEXT_SEGMENT; + return true; } } } - lastCalculationMode = profiles.size() >= 2 ? NEXT_SEGMENT : WHOLE_TRACK; - return profiles.size() >= 2; + return false; } @Override 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 2538103ec0..ab98990d36 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/GeometryWay.java @@ -190,9 +190,7 @@ public abstract class GeometryWay prevStyle = style instanceof GeometryMultiProfileWayStyle ? - getStyle(i - 1, style) : style; - addLocation(tb, prevLat, prevLon, prevStyle, 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); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java index b0c7e7c369..c9e5f8101f 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/geometry/MultiProfileGeometryWayDrawer.java @@ -21,7 +21,7 @@ public class MultiProfileGeometryWayDrawer extends GeometryWayDrawer style) { - if (style instanceof GeometryMultiProfileWayStyle) { + if (style instanceof GeometryMultiProfileWayStyle && !((GeometryMultiProfileWayStyle) style).isGap()) { RenderingLineAttributes attrs = getContext().getAttrs(); attrs.paint.setColor(((GeometryMultiProfileWayStyle) style).getBorderColor());