From 908033e0a924b6cafef83a23b00834c50ae64092 Mon Sep 17 00:00:00 2001 From: cepprice Date: Sat, 6 Mar 2021 15:03:26 +0500 Subject: [PATCH 1/7] Finish UI of Track appearance context menu --- OsmAnd/res/drawable/bg_track_gradient.xml | 13 ++ OsmAnd/res/layout/gradient_card.xml | 46 +++++ OsmAnd/res/layout/track_coloring_card.xml | 13 +- OsmAnd/res/layout/track_width_card.xml | 3 +- OsmAnd/res/values/colors.xml | 4 + OsmAnd/res/values/strings.xml | 3 + .../net/osmand/plus/track/GradientCard.java | 81 ++++++++ .../plus/track/TrackAppearanceFragment.java | 34 +++- .../osmand/plus/track/TrackColoringCard.java | 186 ++++++++++++------ 9 files changed, 301 insertions(+), 82 deletions(-) create mode 100644 OsmAnd/res/drawable/bg_track_gradient.xml create mode 100644 OsmAnd/res/layout/gradient_card.xml create mode 100644 OsmAnd/src/net/osmand/plus/track/GradientCard.java diff --git a/OsmAnd/res/drawable/bg_track_gradient.xml b/OsmAnd/res/drawable/bg_track_gradient.xml new file mode 100644 index 0000000000..c72829a45e --- /dev/null +++ b/OsmAnd/res/drawable/bg_track_gradient.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/gradient_card.xml b/OsmAnd/res/layout/gradient_card.xml new file mode 100644 index 0000000000..ff0834bee0 --- /dev/null +++ b/OsmAnd/res/layout/gradient_card.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/track_coloring_card.xml b/OsmAnd/res/layout/track_coloring_card.xml index 2c7721f61d..0b1738293b 100644 --- a/OsmAnd/res/layout/track_coloring_card.xml +++ b/OsmAnd/res/layout/track_coloring_card.xml @@ -20,9 +20,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingTop="@dimen/context_menu_padding_margin_tiny" - android:visibility="gone" - android:paddingBottom="@dimen/content_padding"> + android:paddingTop="@dimen/context_menu_buttons_padding_bottom"> - - \ No newline at end of file diff --git a/OsmAnd/res/layout/track_width_card.xml b/OsmAnd/res/layout/track_width_card.xml index 3710ad43b4..744c90d137 100644 --- a/OsmAnd/res/layout/track_width_card.xml +++ b/OsmAnd/res/layout/track_width_card.xml @@ -45,14 +45,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingBottom="@dimen/content_padding"> + android:paddingBottom="@dimen/favorites_select_group_button_height"> #1AFFFFFF #67727272 + #5ADC5F + #D4EF32 + #F3374D + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index ed1259ed1f..98c8410b5e 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,9 @@ --> + Please select another type of colorization. + The track does not contain speed data. + The track does not contain altitude data. The recording will be continued. Distance by tap A toggle to show or hide the Coordinates widget on the map. diff --git a/OsmAnd/src/net/osmand/plus/track/GradientCard.java b/OsmAnd/src/net/osmand/plus/track/GradientCard.java new file mode 100644 index 0000000000..77d881574e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/track/GradientCard.java @@ -0,0 +1,81 @@ +package net.osmand.plus.track; + +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; +import android.widget.TextView; + +import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities.GPXTrackAnalysis; +import net.osmand.plus.OsmAndFormatter; +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 androidx.annotation.NonNull; + +public class GradientCard extends BaseCard { + + private GPXTrackAnalysis gpxTrackAnalysis; + private GradientScaleType selectedScaleType = null; + + public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis) { + super(mapActivity); + this.gpxTrackAnalysis = gpxTrackAnalysis; + } + + @Override + public int getCardLayoutId() { + return R.layout.gradient_card; + } + + @Override + protected void updateContent() { + if (selectedScaleType == null) { + AndroidUiHelper.updateVisibility(view, false); + return; + } + + 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); + minValue.setText(formatValue(min)); + maxValue.setText(formatValue(max)); + } + + public void setSelectedScaleType(GradientScaleType type) { + this.selectedScaleType = type; + 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) { + if (selectedScaleType == GradientScaleType.ALTITUDE) { + return OsmAndFormatter.getFormattedAlt(value, app); + } else if (selectedScaleType == GradientScaleType.SLOPE) { + return (int) value + " %"; + } + String speed = OsmAndFormatter.getFormattedSpeed(value, app); + Spannable formattedSpeed = new SpannableString(speed); + formattedSpeed.setSpan( + new ForegroundColorSpan(AndroidUtils.getColorFromAttr(app, android.R.attr.textColorSecondary)), + speed.indexOf(" "), speed.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return formattedSpeed; + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 4642175b09..1de2c1c6ee 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -15,14 +15,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ScrollView; -import androidx.activity.OnBackPressedCallback; -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - import net.osmand.AndroidUtils; import net.osmand.GPXUtilities.GPXFile; import net.osmand.PlatformUtil; @@ -60,6 +52,14 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import androidx.activity.OnBackPressedCallback; +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR; import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD; import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM; @@ -89,6 +89,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement private SplitIntervalCard splitIntervalCard; private TrackColoringCard trackColoringCard; private ColorsCard colorsCard; + private GradientCard gradientCard; private boolean showStartFinishIconsInitialValue; private ImageView trackIcon; @@ -340,6 +341,14 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (mapActivity != null) { if (card instanceof SplitIntervalCard) { SplitIntervalBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), trackDrawInfo, this); + } else if (card instanceof TrackColoringCard) { + GradientScaleType currentScaleType = ((TrackColoringCard) card).getSelectedScaleType(); + if (gradientCard != null) { + gradientCard.setSelectedScaleType(currentScaleType); + } + if (colorsCard != null) { + AndroidUiHelper.updateVisibility(colorsCard.getView(), currentScaleType == null); + } } else if (card instanceof ColorsCard) { int color = ((ColorsCard) card).getSelectedColor(); trackDrawInfo.setColor(color); @@ -553,6 +562,9 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (trackWidthCard != null) { trackWidthCard.updateItems(); } + if (trackColoringCard != null) { + trackColoringCard.updateColor(); + } MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { mapActivity.refreshMap(); @@ -640,12 +652,16 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement showStartFinishCard.setListener(this); cardsContainer.addView(showStartFinishCard.build(mapActivity)); - trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo, this); + trackColoringCard = new TrackColoringCard(mapActivity, selectedGpxFile.getTrackAnalysis(app), trackDrawInfo); trackColoringCard.setListener(this); cardsContainer.addView(trackColoringCard.build(mapActivity)); setupColorsCard(cardsContainer); + gradientCard = new GradientCard(mapActivity, selectedGpxFile.getTrackAnalysis(app)); + AndroidUiHelper.updateVisibility(gradientCard.build(mapActivity), false); + cardsContainer.addView(gradientCard.getView()); + trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index 0a17f5e06b..44645180ea 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -7,14 +7,10 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.snackbar.Snackbar; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.PlatformUtil; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -27,26 +23,29 @@ import org.apache.commons.logging.Log; import java.util.ArrayList; import java.util.List; -public class TrackColoringCard extends BaseCard { +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; - private static final int MINIMUM_CONTRAST_RATIO = 3; +public class TrackColoringCard extends BaseCard { private final static String SOLID_COLOR = "solid_color"; private static final Log log = PlatformUtil.getLog(TrackColoringCard.class); + private GPXTrackAnalysis gpxTrackAnalysis; private TrackDrawInfo trackDrawInfo; private TrackColoringAdapter coloringAdapter; private TrackAppearanceItem selectedAppearanceItem; private List appearanceItems; - private Fragment target; - - public TrackColoringCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo, Fragment target) { + public TrackColoringCard(MapActivity mapActivity, GPXTrackAnalysis gpxTrackAnalysis, TrackDrawInfo trackDrawInfo) { super(mapActivity); - this.target = target; this.trackDrawInfo = trackDrawInfo; - appearanceItems = getGradientAppearanceItems(); + this.gpxTrackAnalysis = gpxTrackAnalysis; + appearanceItems = getTrackAppearanceItems(); } @Override @@ -58,25 +57,44 @@ public class TrackColoringCard extends BaseCard { protected void updateContent() { updateHeader(); -// coloringAdapter = new TrackColoringAdapter(appearanceItems); -// RecyclerView groupRecyclerView = view.findViewById(R.id.recycler_view); -// groupRecyclerView.setAdapter(coloringAdapter); -// groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); + coloringAdapter = new TrackColoringAdapter(appearanceItems); + RecyclerView groupRecyclerView = view.findViewById(R.id.recycler_view); + groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); + groupRecyclerView.setAdapter(coloringAdapter); AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider()); } - private List getGradientAppearanceItems() { + public void updateColor() { + if (coloringAdapter != null) { + // Provide empty object to update item without animation + coloringAdapter.notifyItemChanged(0, new Object()); + } + } + + public GradientScaleType getSelectedScaleType() { + String attrName = selectedAppearanceItem.getAttrName(); + return attrName.equals(SOLID_COLOR) ? null : GradientScaleType.valueOf(attrName.toUpperCase()); + } + + private List getTrackAppearanceItems() { List items = new ArrayList<>(); - items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle)); - -// for (GradientScaleType scaleType : GradientScaleType.values()) { -// items.add(new TrackAppearanceItem(scaleType.getTypeName(), scaleType.getHumanString(app), scaleType.getIconId())); -// } - + items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle, true)); + for (GradientScaleType scaleType : GradientScaleType.values()) { + items.add(new TrackAppearanceItem(scaleType.getTypeName(), + scaleType.getHumanString(app), scaleType.getIconId(), isScaleTypeActive(scaleType))); + } return items; } + private boolean isScaleTypeActive(GradientScaleType scaleType) { + if (scaleType == GradientScaleType.SPEED) { + return gpxTrackAnalysis.isSpeedSpecified(); + } else { + return gpxTrackAnalysis.isElevationSpecified(); + } + } + private TrackAppearanceItem getSelectedAppearanceItem() { if (selectedAppearanceItem == null) { GradientScaleType scaleType = trackDrawInfo.getGradientScaleType(); @@ -98,27 +116,22 @@ public class TrackColoringCard extends BaseCard { headerView.setBackgroundDrawable(null); TextView titleView = view.findViewById(R.id.title); - titleView.setText(R.string.select_color); + titleView.setText(R.string.shared_string_color); TextView descriptionView = view.findViewById(R.id.description); descriptionView.setText(getSelectedAppearanceItem().getLocalizedValue()); } - private void updateColorSelector() { - boolean visible = getSelectedAppearanceItem().getAttrName().equals(SOLID_COLOR); - AndroidUiHelper.updateVisibility(view.findViewById(R.id.select_color), visible); - } - public void setGradientScaleType(TrackAppearanceItem item) { + selectedAppearanceItem = item; if (item.getAttrName().equals(SOLID_COLOR)) { trackDrawInfo.setGradientScaleType(null); } else { - trackDrawInfo.setGradientScaleType(GradientScaleType.valueOf(item.getAttrName())); + trackDrawInfo.setGradientScaleType(GradientScaleType.valueOf(item.getAttrName().toUpperCase())); } mapActivity.refreshMap(); updateHeader(); - updateColorSelector(); } private class TrackColoringAdapter extends RecyclerView.Adapter { @@ -136,42 +149,38 @@ public class TrackColoringCard extends BaseCard { View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false); view.getLayoutParams().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width); view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height); - - TrackAppearanceViewHolder holder = new TrackAppearanceViewHolder(view); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp, - R.drawable.ripple_solid_dark_6dp); - } - return holder; + return new TrackAppearanceViewHolder(view); } @Override public void onBindViewHolder(@NonNull final TrackAppearanceViewHolder holder, int position) { - TrackAppearanceItem item = items.get(position); - holder.title.setText(item.getLocalizedValue()); + final TrackAppearanceItem item = items.get(position); - updateButtonBg(holder, item); - - int colorId; - if (item.getAttrName().equals(SOLID_COLOR)) { - colorId = trackDrawInfo.getColor(); - } else if (item.getAttrName().equals(getSelectedAppearanceItem().getAttrName())) { - colorId = ContextCompat.getColor(app, nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light); - } else { - colorId = AndroidUtils.getColorFromAttr(holder.itemView.getContext(), R.attr.default_icon_color); + if (item.isActive() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp, + R.drawable.ripple_solid_dark_6dp); } - holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(item.getIconId(), colorId)); + updateButtonBg(holder, item); + updateTextAndIconColor(holder, item); + holder.title.setText(item.getLocalizedValue()); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + if (!item.isActive()) { + showSnackbar(view, item.getAttrName()); + return; + } + int prevSelectedPosition = getItemPosition(getSelectedAppearanceItem()); selectedAppearanceItem = items.get(holder.getAdapterPosition()); notifyItemChanged(holder.getAdapterPosition()); notifyItemChanged(prevSelectedPosition); - setGradientScaleType(selectedAppearanceItem); + if (getListener() != null) { + getListener().onCardPressed(TrackColoringCard.this); + } } }); } @@ -179,18 +188,70 @@ public class TrackColoringCard extends BaseCard { private void updateButtonBg(TrackAppearanceViewHolder holder, TrackAppearanceItem item) { GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline); if (rectContourDrawable != null) { - if (getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item)) { - int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light); - rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 2), strokeColor); + boolean itemSelected = getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item); + + int strokeColor; + int backgroundColor; + int strokeWidth; + + if (itemSelected) { + strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.pstsIndicatorColor); + backgroundColor = 0; + strokeWidth = 2; + } else if (!item.isActive()) { + strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.stroked_buttons_and_links_outline); + backgroundColor = AndroidUtils.getColorFromAttr(app, R.attr.ctx_menu_card_btn); + strokeWidth = 2; } else { - int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.stroked_buttons_and_links_outline_dark - : R.color.stroked_buttons_and_links_outline_light); - rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 1), strokeColor); + strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.stroked_buttons_and_links_outline); + backgroundColor = 0; + strokeWidth = 1; } + + rectContourDrawable.mutate(); + rectContourDrawable.setColor(backgroundColor); + rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, strokeWidth), strokeColor); holder.button.setImageDrawable(rectContourDrawable); } } + private void updateTextAndIconColor(TrackAppearanceViewHolder holder, TrackAppearanceItem item) { + boolean isSelected = item.getAttrName().equals(getSelectedAppearanceItem().getAttrName()); + int iconColorId; + int textColorId; + + if (isSelected) { + iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.default_icon_color); + textColorId = AndroidUtils.getColorFromAttr(app, android.R.attr.textColor); + } else if (!item.isActive()) { + iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.default_icon_color); + textColorId = AndroidUtils.getColorFromAttr(app, android.R.attr.textColorSecondary); + } else { + iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.pstsIndicatorColor); + textColorId = iconColorId; + } + + if (item.getAttrName().equals(SOLID_COLOR)) { + iconColorId = trackDrawInfo.getColor(); + } + + holder.icon.setImageDrawable(app.getUIUtilities().getPaintedIcon(item.getIconId(), iconColorId)); + holder.title.setTextColor(textColorId); + } + + private void showSnackbar(View view, String attrName) { + if (view == null || mapActivity == null) { + return; + } + String text = attrName.equals(GradientScaleType.SPEED.getTypeName()) ? + app.getString(R.string.track_has_no_speed) : app.getString(R.string.track_has_no_altitude); + text += " " + app.getString(R.string.select_another_colorization); + Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_LONG) + .setAnchorView(mapActivity.findViewById(R.id.dismiss_button)); + UiUtilities.setupSnackbar(snackbar, nightMode); + snackbar.show(); + } + @Override public int getItemCount() { return items.size(); @@ -209,10 +270,13 @@ public class TrackColoringCard extends BaseCard { @DrawableRes private int iconId; - public TrackAppearanceItem(String attrName, String localizedValue, int iconId) { + private boolean isActive; + + public TrackAppearanceItem(String attrName, String localizedValue, int iconId, boolean isActive) { this.attrName = attrName; this.localizedValue = localizedValue; this.iconId = iconId; + this.isActive = isActive; } public String getAttrName() { @@ -226,5 +290,9 @@ public class TrackColoringCard extends BaseCard { public int getIconId() { return iconId; } + + public boolean isActive() { + return isActive; + } } } \ No newline at end of file From a6cedd2767694089272b0902c69358553948244e Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 8 Mar 2021 21:32:19 +0500 Subject: [PATCH 2/7] Implement colorization type in settings --- .../main/java/net/osmand/GPXUtilities.java | 8 +-- .../java/net/osmand/router/RouteColorize.java | 21 ++++---- .../main/java/net/osmand/util/Algorithms.java | 27 ++++++++++ OsmAnd/src/net/osmand/plus/GPXDatabase.java | 51 +++++++++---------- OsmAnd/src/net/osmand/plus/GpxDbHelper.java | 4 +- .../net/osmand/plus/helpers/GpxUiHelper.java | 12 ++--- .../plus/settings/backend/OsmandSettings.java | 2 + .../backend/backup/GpxAppearanceInfo.java | 28 +++++----- .../backend/backup/GpxSettingsItem.java | 4 ++ .../osmand/plus/track/GradientScaleType.java | 13 +++++ .../plus/track/TrackAppearanceFragment.java | 4 ++ 11 files changed, 111 insertions(+), 63 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index 4db84c5c33..cb5f40a4b9 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -1662,16 +1662,16 @@ public class GPXUtilities { return new QuadRect(left, top, right, bottom); } - public int getGradientScaleColor(String gradientScaleType, int defColor) { + public int[] getGradientScaleColor(String gradientScaleType) { String clrValue = null; if (extensions != null) { clrValue = extensions.get(gradientScaleType); } - return parseColor(clrValue, defColor); + return Algorithms.stringToGradientPalette(clrValue); } - public void setGradientScaleColor(String gradientScaleType, int gradientScaleColor) { - getExtensionsToWrite().put(gradientScaleType, Algorithms.colorToString(gradientScaleColor)); + public void setGradientScaleColor(String gradientScaleType, int[] gradientScalePalette) { + getExtensionsToWrite().put(gradientScaleType, Algorithms.gradientPaletteToString(gradientScalePalette)); } public String getGradientScaleType() { 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 6730965d1f..63f0ee1cd3 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -24,11 +24,12 @@ public class RouteColorize { public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); - public static final int RED = rgbaToDecimal(255,1,1,255); - public static final int GREEN = rgbaToDecimal(46,185,0,191); - public static final int YELLOW = rgbaToDecimal(255,222,2,227); + public static final int GREEN = rgbaToDecimal(90, 220, 95, 1); + public static final int YELLOW = rgbaToDecimal(212, 239, 50, 1); + public static final int RED = rgbaToDecimal(243, 55, 77, 1); + public static final int[] colors = new int[] {GREEN, YELLOW, RED}; - public enum ValueType { + public enum ColorizationType { ELEVATION, SPEED, SLOPE, @@ -42,7 +43,7 @@ public class RouteColorize { private final int BLUE_COLOR_INDEX = 3;//RGB private final int ALPHA_COLOR_INDEX = 4;//RGBA - private ValueType valueType; + private ColorizationType colorizationType; public static int SLOPE_RANGE = 150;//150 meters private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5% @@ -73,7 +74,7 @@ public class RouteColorize { /** * @param type ELEVATION, SPEED, SLOPE */ - public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ValueType type) { + public RouteColorize(int zoom, GPXUtilities.GPXFile gpxFile, ColorizationType type) { if (!gpxFile.hasTrkPt()) { LOG.warn("GPX file is not consist of track points"); @@ -88,7 +89,7 @@ public class RouteColorize { for (GPXUtilities.WptPt p : ts.points) { latList.add(p.lat); lonList.add(p.lon); - if (type == ValueType.SPEED) { + if (type == ColorizationType.SPEED) { valList.add(p.speed); } else { valList.add(p.ele); @@ -101,14 +102,14 @@ public class RouteColorize { latitudes = listToArray(latList); longitudes = listToArray(lonList); - if (type == ValueType.SLOPE) { + if (type == ColorizationType.SLOPE) { values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE); } else { values = listToArray(valList); } calculateMinMaxValue(); - valueType = type; + colorizationType = type; checkPalette(); sortPalette(); } @@ -282,7 +283,7 @@ public class RouteColorize { double[][] defaultPalette = { {minValue, GREEN}, - {valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW}, + {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW}, {maxValue, RED} }; palette = defaultPalette; diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 36c0034a26..737e302e6a 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -2,6 +2,7 @@ package net.osmand.util; import net.osmand.IProgress; import net.osmand.PlatformUtil; +import net.osmand.router.RouteColorize; import org.apache.commons.logging.Log; import org.xmlpull.v1.XmlPullParser; @@ -1027,4 +1028,30 @@ public class Algorithms { } return false; } + + public static int[] stringToGradientPalette(String str) { + if (Algorithms.isBlank(str)) { + return RouteColorize.colors; + } + String[] arr = str.split(" "); + if (arr.length != 3) { + return RouteColorize.colors; + } + int[] colors = new int[3]; + try { + for (int i = 0; i < 3; i++) { + colors[i] = Algorithms.parseColor(arr[i]); + } + } catch (IllegalArgumentException e) { + return RouteColorize.colors; + } + return colors; + } + + public static String gradientPaletteToString(int[] colors) { + int[] src = colors.length == 3 ? colors : RouteColorize.colors; + return Algorithms.colorToString(src[0]) + " " + + Algorithms.colorToString(src[1]) + " " + + Algorithms.colorToString(src[2]); + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java index 74dc02be9c..b08013017f 100644 --- a/OsmAnd/src/net/osmand/plus/GPXDatabase.java +++ b/OsmAnd/src/net/osmand/plus/GPXDatabase.java @@ -178,9 +178,9 @@ public class GPXDatabase { private String width; private GradientScaleType gradientScaleType; private int color; - private int gradientSpeedColor; - private int gradientAltitudeColor; - private int gradientSlopeColor; + private int[] gradientSpeedPalette; + private int[] gradientAltitudePalette; + private int[] gradientSlopePalette; private int splitType; private double splitInterval; private long fileLastModifiedTime; @@ -210,9 +210,9 @@ public class GPXDatabase { width = gpxFile.getWidth(null); showArrows = gpxFile.isShowArrows(); showStartFinish = gpxFile.isShowStartFinish(); - gradientSpeedColor = gpxFile.getGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), 0); - gradientSlopeColor = gpxFile.getGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), 0); - gradientAltitudeColor = gpxFile.getGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), 0); + gradientSpeedPalette = gpxFile.getGradientScaleColor(GradientScaleType.SPEED.getColorTypeName()); + gradientSlopePalette = gpxFile.getGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName()); + gradientAltitudePalette = gpxFile.getGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName()); if (!Algorithms.isEmpty(gpxFile.getSplitType()) && gpxFile.getSplitInterval() > 0) { GpxSplitType gpxSplitType = GpxSplitType.getSplitTypeByName(gpxFile.getSplitType()); @@ -243,23 +243,22 @@ public class GPXDatabase { return gradientScaleType; } - public int getGradientSpeedColor() { - return gradientSpeedColor; + public int[] getGradientSpeedPalette() { + return gradientSpeedPalette; } - public int getGradientAltitudeColor() { - return gradientAltitudeColor; + public int[] getGradientAltitudePalette() { + return gradientAltitudePalette; } - public int getGradientSlopeColor() { - return gradientSlopeColor; + public int[] getGradientSlopePalette() { + return gradientSlopePalette; } public String getWidth() { return width; } - public long getFileLastModifiedTime() { return fileLastModifiedTime; } @@ -507,7 +506,7 @@ public class GPXDatabase { return false; } - public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int gradientScaleColor) { + public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int[] gradientScalePalette) { SQLiteConnection db = openConnection(false); if (db != null) { try { @@ -516,17 +515,17 @@ public class GPXDatabase { String columnName = null; if (GradientScaleType.SPEED == gradientScaleType) { columnName = GPX_COL_GRADIENT_SPEED_COLOR; - item.gradientSpeedColor = gradientScaleColor; + item.gradientSpeedPalette = gradientScalePalette; } else if (GradientScaleType.ALTITUDE == gradientScaleType) { columnName = GPX_COL_GRADIENT_ALTITUDE_COLOR; - item.gradientAltitudeColor = gradientScaleColor; + item.gradientAltitudePalette = gradientScalePalette; } else if (GradientScaleType.SLOPE == gradientScaleType) { columnName = GPX_COL_GRADIENT_SLOPE_COLOR; - item.gradientSlopeColor = gradientScaleColor; + item.gradientSlopePalette = gradientScalePalette; } db.execSQL("UPDATE " + GPX_TABLE_NAME + " SET " + columnName + " = ? " + " WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?", - new Object[] {(gradientScaleColor == 0 ? "" : Algorithms.colorToString(gradientScaleColor)), fileName, fileDir}); + new Object[] {Algorithms.gradientPaletteToString(gradientScalePalette), fileName, fileDir}); } finally { db.close(); } @@ -729,7 +728,7 @@ public class GPXDatabase { color, item.file.lastModified(), item.splitType, item.splitInterval, item.apiImported ? 1 : 0, Algorithms.encodeStringSet(item.analysis.wptCategoryNames), item.showAsMarkers ? 1 : 0, item.joinSegments ? 1 : 0, item.showArrows ? 1 : 0, item.showStartFinish ? 1 : 0, item.width, - item.gradientSpeedColor, item.gradientAltitudeColor, item.gradientSlopeColor, gradientScaleType}); + item.gradientSpeedPalette, item.gradientAltitudePalette, item.gradientSlopePalette, gradientScaleType}); } else { db.execSQL("INSERT INTO " + GPX_TABLE_NAME + "(" + GPX_COL_NAME + ", " + @@ -752,7 +751,7 @@ public class GPXDatabase { new Object[] {fileName, fileDir, color, 0, item.splitType, item.splitInterval, item.apiImported ? 1 : 0, item.showAsMarkers ? 1 : 0, item.joinSegments ? 1 : 0, item.showArrows ? 1 : 0, item.showStartFinish ? 1 : 0, item.width, - item.gradientSpeedColor, item.gradientAltitudeColor, item.gradientSlopeColor, gradientScaleType}); + item.gradientSpeedPalette, item.gradientAltitudePalette, item.gradientSlopePalette, gradientScaleType}); } } @@ -836,9 +835,9 @@ public class GPXDatabase { boolean showArrows = query.getInt(26) == 1; boolean showStartFinish = query.getInt(27) == 1; String width = query.getString(28); - String gradientSpeedColor = query.getString(29); - String gradientAltitudeColor = query.getString(30); - String gradientSlopeColor = query.getString(31); + String gradientSpeedPalette = query.getString(29); + String gradientAltitudePalette = query.getString(30); + String gradientSlopePalette = query.getString(31); String gradientScaleType = query.getString(32); GPXTrackAnalysis a = new GPXTrackAnalysis(); @@ -880,9 +879,9 @@ public class GPXDatabase { item.showArrows = showArrows; item.showStartFinish = showStartFinish; item.width = width; - item.gradientSpeedColor = parseColor(gradientSpeedColor); - item.gradientAltitudeColor = parseColor(gradientAltitudeColor); - item.gradientSlopeColor = parseColor(gradientSlopeColor); + item.gradientSpeedPalette = Algorithms.stringToGradientPalette(gradientSpeedPalette); + item.gradientAltitudePalette = Algorithms.stringToGradientPalette(gradientAltitudePalette); + item.gradientSlopePalette = Algorithms.stringToGradientPalette(gradientSlopePalette); try { item.gradientScaleType = Algorithms.isEmpty(gradientScaleType) ? null : GradientScaleType.valueOf(gradientScaleType); diff --git a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java index 8a7d886a63..ef93703190 100644 --- a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java @@ -78,8 +78,8 @@ public class GpxDbHelper { return res; } - public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int color) { - boolean res = db.updateGradientScaleColor(item, gradientScaleType, color); + public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int[] palette) { + boolean res = db.updateGradientScaleColor(item, gradientScaleType, palette); putToCache(item); return res; } diff --git a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java index c2f3d831b8..ce33c21803 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java @@ -2246,15 +2246,9 @@ public class GpxUiHelper { if (dataItem.getWidth() != null) { gpxFile.setWidth(dataItem.getWidth()); } - if (dataItem.getGradientSpeedColor() != 0) { - gpxFile.setGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), dataItem.getGradientSpeedColor()); - } - if (dataItem.getGradientSlopeColor() != 0) { - gpxFile.setGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), dataItem.getGradientSlopeColor()); - } - if (dataItem.getGradientAltitudeColor() != 0) { - gpxFile.setGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), dataItem.getGradientAltitudeColor()); - } + gpxFile.setGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), dataItem.getGradientSpeedPalette()); + gpxFile.setGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), dataItem.getGradientSlopePalette()); + gpxFile.setGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), dataItem.getGradientAltitudePalette()); if (dataItem.getGradientScaleType() != null) { gpxFile.setGradientScaleType(dataItem.getGradientScaleType().name()); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 2854520bbf..0635f8d7c1 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -50,6 +50,7 @@ import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode; import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.srtmplugin.TerrainMode; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode; import net.osmand.plus.voice.CommandPlayer; import net.osmand.plus.wikipedia.WikiArticleShowImages; @@ -1408,6 +1409,7 @@ public class OsmandSettings { public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal(); public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_COLORIZATION = new EnumStringPreference<>(this, "current_track_colorization", null, GradientScaleType.values()).makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().makeShared().cache(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxAppearanceInfo.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxAppearanceInfo.java index 157d5ecb0a..a893e63a41 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxAppearanceInfo.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxAppearanceInfo.java @@ -17,9 +17,9 @@ public class GpxAppearanceInfo { public String width; public GradientScaleType scaleType; public int color; - public int gradientSpeedColor; - public int gradientAltitudeColor; - public int gradientSlopeColor; + public int[] gradientSpeedPalette; + public int[] gradientAltitudePalette; + public int[] gradientSlopePalette; public int splitType; public double splitInterval; public boolean showArrows; @@ -41,9 +41,9 @@ public class GpxAppearanceInfo { splitType = dataItem.getSplitType(); splitInterval = dataItem.getSplitInterval(); scaleType = dataItem.getGradientScaleType(); - gradientSpeedColor = dataItem.getGradientSpeedColor(); - gradientSlopeColor = dataItem.getGradientSlopeColor(); - gradientAltitudeColor = dataItem.getGradientAltitudeColor(); + gradientSpeedPalette = dataItem.getGradientSpeedPalette(); + gradientSlopePalette = dataItem.getGradientSlopePalette(); + gradientAltitudePalette = dataItem.getGradientAltitudePalette(); GPXTrackAnalysis analysis = dataItem.getAnalysis(); if (analysis != null) { @@ -61,9 +61,9 @@ public class GpxAppearanceInfo { writeParam(json, "split_type", GpxSplitType.getSplitTypeByTypeId(splitType).getTypeName()); writeParam(json, "split_interval", splitInterval); writeParam(json, "gradient_scale_type", scaleType); - writeParam(json, GradientScaleType.SPEED.getColorTypeName(), gradientSpeedColor); - writeParam(json, GradientScaleType.SLOPE.getColorTypeName(), gradientSlopeColor); - writeParam(json, GradientScaleType.ALTITUDE.getColorTypeName(), gradientAltitudeColor); + writeParam(json, GradientScaleType.SPEED.getColorTypeName(), Algorithms.gradientPaletteToString(gradientSpeedPalette)); + writeParam(json, GradientScaleType.ALTITUDE.getColorTypeName(), Algorithms.gradientPaletteToString(gradientAltitudePalette)); + writeParam(json, GradientScaleType.SLOPE.getColorTypeName(), Algorithms.gradientPaletteToString(gradientSlopePalette)); writeParam(json, "time_span", timeSpan); writeParam(json, "wpt_points", wptPoints); @@ -79,9 +79,9 @@ public class GpxAppearanceInfo { gpxAppearanceInfo.splitType = GpxSplitType.getSplitTypeByName(json.optString("split_type")).getType(); gpxAppearanceInfo.splitInterval = json.optDouble("split_interval"); gpxAppearanceInfo.scaleType = getScaleType(json.optString("gradient_scale_type")); - gpxAppearanceInfo.gradientSpeedColor = json.optInt(GradientScaleType.SPEED.getColorTypeName()); - gpxAppearanceInfo.gradientSlopeColor = json.optInt(GradientScaleType.SLOPE.getColorTypeName()); - gpxAppearanceInfo.gradientAltitudeColor = json.optInt(GradientScaleType.ALTITUDE.getColorTypeName()); + gpxAppearanceInfo.gradientSpeedPalette = getGradientPalette(json, GradientScaleType.SPEED); + gpxAppearanceInfo.gradientAltitudePalette = getGradientPalette(json, GradientScaleType.ALTITUDE); + gpxAppearanceInfo.gradientSlopePalette = getGradientPalette(json, GradientScaleType.SLOPE); gpxAppearanceInfo.timeSpan = json.optLong("time_span"); gpxAppearanceInfo.wptPoints = json.optInt("wpt_points"); @@ -101,6 +101,10 @@ public class GpxAppearanceInfo { return null; } + private static int[] getGradientPalette(JSONObject json, GradientScaleType scaleType) { + return Algorithms.stringToGradientPalette(json.optString(scaleType.getColorTypeName())); + } + private static void writeParam(@NonNull JSONObject json, @NonNull String name, @Nullable Object value) throws JSONException { if (value instanceof Integer) { if ((Integer) value != 0) { diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java index b9c39026a9..2eca72fba1 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java @@ -9,6 +9,7 @@ import net.osmand.plus.GpxDbHelper; import net.osmand.plus.GpxDbHelper.GpxDataItemCallback; import net.osmand.plus.OsmandApplication; import net.osmand.plus.track.GpxSplitType; +import net.osmand.plus.track.GradientScaleType; import org.json.JSONException; import org.json.JSONObject; @@ -83,6 +84,9 @@ public class GpxSettingsItem extends FileSettingsItem { gpxDbHelper.updateShowStartFinish(dataItem, appearanceInfo.showStartFinish); gpxDbHelper.updateSplit(dataItem, splitType, appearanceInfo.splitInterval); gpxDbHelper.updateGradientScaleType(dataItem, appearanceInfo.scaleType); + gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.SPEED, appearanceInfo.gradientSpeedPalette); + gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.ALTITUDE, appearanceInfo.gradientAltitudePalette); + gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.SLOPE, appearanceInfo.gradientSlopePalette); } private void createGpxAppearanceInfo() { diff --git a/OsmAnd/src/net/osmand/plus/track/GradientScaleType.java b/OsmAnd/src/net/osmand/plus/track/GradientScaleType.java index f237c1e721..9b7e681122 100644 --- a/OsmAnd/src/net/osmand/plus/track/GradientScaleType.java +++ b/OsmAnd/src/net/osmand/plus/track/GradientScaleType.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; import net.osmand.plus.R; +import net.osmand.router.RouteColorize.ColorizationType; public enum GradientScaleType { @@ -44,6 +45,18 @@ public enum GradientScaleType { return ctx.getString(resId); } + public ColorizationType toColorizationType() { + if (this == SPEED) { + return ColorizationType.SPEED; + } else if (this == ALTITUDE) { + return ColorizationType.ELEVATION; + } else if (this == SLOPE) { + return ColorizationType.SLOPE; + } else { + return ColorizationType.NONE; + } + } + public static GradientScaleType getGradientTypeByName(@NonNull String name) { for (GradientScaleType scaleType : GradientScaleType.values()) { if (scaleType.name().equalsIgnoreCase(name)) { diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 1de2c1c6ee..98831141bc 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -159,6 +159,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (selectedGpxFile.isShowCurrentTrack()) { trackDrawInfo = new TrackDrawInfo(true); trackDrawInfo.setColor(app.getSettings().CURRENT_TRACK_COLOR.get()); + trackDrawInfo.setGradientScaleType(app.getSettings().CURRENT_TRACK_COLORIZATION.get()); trackDrawInfo.setWidth(app.getSettings().CURRENT_TRACK_WIDTH.get()); trackDrawInfo.setShowArrows(app.getSettings().CURRENT_TRACK_SHOW_ARROWS.get()); trackDrawInfo.setShowStartFinish(app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.get()); @@ -343,6 +344,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement SplitIntervalBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), trackDrawInfo, this); } else if (card instanceof TrackColoringCard) { GradientScaleType currentScaleType = ((TrackColoringCard) card).getSelectedScaleType(); + trackDrawInfo.setGradientScaleType(currentScaleType); + mapActivity.refreshMap(); if (gradientCard != null) { gradientCard.setSelectedScaleType(currentScaleType); } @@ -575,6 +578,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement GPXFile gpxFile = selectedGpxFile.getGpxFile(); if (gpxFile.showCurrentTrack) { app.getSettings().CURRENT_TRACK_COLOR.set(trackDrawInfo.getColor()); + app.getSettings().CURRENT_TRACK_COLORIZATION.set(trackDrawInfo.getGradientScaleType()); app.getSettings().CURRENT_TRACK_WIDTH.set(trackDrawInfo.getWidth()); app.getSettings().CURRENT_TRACK_SHOW_ARROWS.set(trackDrawInfo.isShowArrows()); app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.set(trackDrawInfo.isShowStartFinish()); From b0b5528cc6430628ae78e9cd0ca15d6bdcd0de70 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 10 Mar 2021 16:55:55 +0500 Subject: [PATCH 3/7] Add gradient coloring of track --- .../main/java/net/osmand/GPXUtilities.java | 17 ++++ .../java/net/osmand/router/RouteColorize.java | 18 +++- .../net/osmand/plus/track/TrackDrawInfo.java | 16 ++++ .../src/net/osmand/plus/views/Renderable.java | 52 ++++++++++- .../osmand/plus/views/layers/GPXLayer.java | 87 ++++++++++++++++++- 5 files changed, 180 insertions(+), 10 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java index cb5f40a4b9..ae4080b367 100644 --- a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java +++ b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java @@ -6,6 +6,7 @@ import net.osmand.binary.StringBundle; import net.osmand.binary.StringBundleWriter; import net.osmand.binary.StringBundleXmlWriter; import net.osmand.data.QuadRect; +import net.osmand.router.RouteColorize.ColorizationType; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -227,6 +228,9 @@ public class GPXUtilities { public double hdop = Double.NaN; public float heading = Float.NaN; public boolean deleted = false; + public int speedColor = 0; + public int altitudeColor = 0; + public int slopeColor = 0; public int colourARGB = 0; // point colour (used for altitude/speed colouring) public double distance = 0.0; // cumulative distance, if in a track @@ -249,6 +253,9 @@ public class GPXUtilities { this.hdop = wptPt.hdop; this.heading = wptPt.heading; this.deleted = wptPt.deleted; + this.speedColor = wptPt.speedColor; + this.altitudeColor = wptPt.altitudeColor; + this.slopeColor = wptPt.slopeColor; this.colourARGB = wptPt.colourARGB; this.distance = wptPt.distance; } @@ -311,6 +318,16 @@ public class GPXUtilities { getExtensionsToWrite().put(ICON_NAME_EXTENSION, iconName); } + public int getColor(ColorizationType type) { + if (type == ColorizationType.SPEED) { + return speedColor; + } else if (type == ColorizationType.ELEVATION) { + return altitudeColor; + } else { + return slopeColor; + } + } + public String getBackgroundType() { return getExtensionsToRead().get(BACKGROUND_TYPE_EXTENSION); } 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 63f0ee1cd3..301a69a101 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -5,6 +5,7 @@ import net.osmand.PlatformUtil; import net.osmand.osm.edit.Node; import net.osmand.osm.edit.OsmMapUtils; import net.osmand.util.MapUtils; + import org.apache.commons.logging.Log; import java.util.ArrayList; @@ -24,9 +25,9 @@ public class RouteColorize { public static final int DARK_GREY = rgbaToDecimal(92, 92, 92, 255); public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 255); - public static final int GREEN = rgbaToDecimal(90, 220, 95, 1); - public static final int YELLOW = rgbaToDecimal(212, 239, 50, 1); - public static final int RED = rgbaToDecimal(243, 55, 77, 1); + public static final int GREEN = rgbaToDecimal(90, 220, 95, 255); + public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255); + public static final int RED = rgbaToDecimal(243, 55, 77, 255); public static final int[] colors = new int[] {GREEN, YELLOW, RED}; public enum ColorizationType { @@ -202,6 +203,17 @@ public class RouteColorize { sortPalette(); } + public void setPalette(int[] gradientPalette) { + if (gradientPalette.length != 3) { + return; + } + setPalette(new double[][] { + {minValue, gradientPalette[0]}, + {colorizationType == ColorizationType.SLOPE ? 12.5 : (minValue + maxValue) / 2}, + {maxValue, gradientPalette[0]} + }); + } + private int getDefaultColor() { return rgbaToDecimal(0, 0, 0, 0); } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java index 18d1c30775..f08f87546d 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java @@ -26,6 +26,9 @@ public class TrackDrawInfo { private String width; private GradientScaleType gradientScaleType; private int color; + private int[] speedGradientPalette; + private int[] altitudeGradientPalette; + private int[] slopeGradientPalette; private int splitType; private double splitInterval; private boolean joinSegments; @@ -46,6 +49,9 @@ public class TrackDrawInfo { width = gpxDataItem.getWidth(); gradientScaleType = gpxDataItem.getGradientScaleType(); color = gpxDataItem.getColor(); + speedGradientPalette = gpxDataItem.getGradientSpeedPalette(); + altitudeGradientPalette = gpxDataItem.getGradientAltitudePalette(); + slopeGradientPalette = gpxDataItem.getGradientSlopePalette(); splitType = gpxDataItem.getSplitType(); splitInterval = gpxDataItem.getSplitInterval(); joinSegments = gpxDataItem.isJoinSegments(); @@ -82,6 +88,16 @@ public class TrackDrawInfo { this.color = color; } + public int[] getGradientPalette(@NonNull GradientScaleType scaleType) { + if (scaleType == GradientScaleType.SPEED) { + return speedGradientPalette; + } else if (scaleType == GradientScaleType.ALTITUDE) { + return altitudeGradientPalette; + } else { + return slopeGradientPalette; + } + } + public int getSplitType() { return splitType; } diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index ec8d302dab..e8d4a6183f 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -1,8 +1,10 @@ package net.osmand.plus.views; import android.graphics.Canvas; +import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.Shader; import androidx.annotation.NonNull; @@ -10,7 +12,7 @@ import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.WptPt; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; -import net.osmand.plus.views.layers.geometry.GeometryWay; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.views.layers.geometry.GpxGeometryWay; import net.osmand.util.Algorithms; @@ -65,6 +67,7 @@ public class Renderable { protected double zoom = -1; protected AsynchronousResampler culler = null; // The currently active resampler protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use + protected GradientScaleType scaleType = null; protected GpxGeometryWay geometryWay; @@ -85,6 +88,10 @@ public class Renderable { paint.setStrokeWidth(p.getStrokeWidth()); } + public void setGradientScaleType(GradientScaleType type) { + this.scaleType = type; + } + public GpxGeometryWay getGeometryWay() { return geometryWay; } @@ -124,7 +131,7 @@ public class Renderable { } } - protected void draw(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { + protected void drawSolid(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { if (pts.size() > 1) { updateLocalPaint(p); canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); @@ -160,6 +167,38 @@ public class Renderable { canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); } } + + protected void drawGradient(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { + if (pts.size() < 2) { + return; + } + + updateLocalPaint(p); + canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + QuadRect tileBounds = tileBox.getLatLonBounds(); + WptPt prevPt = pts.get(0); + for (int i = 1; i < pts.size(); i++) { + WptPt currentPt = pts.get(i); + if (Math.min(currentPt.lon, prevPt.lon) < tileBounds.right && Math.max(currentPt.lon, prevPt.lon) > tileBounds.left + && Math.min(currentPt.lat, prevPt.lat) < tileBounds.top && Math.max(currentPt.lat, prevPt.lat) > tileBounds.bottom) { + float startX = tileBox.getPixXFromLatLon(prevPt.lat, prevPt.lon); + float startY = tileBox.getPixYFromLatLon(prevPt.lat, prevPt.lon); + float endX = tileBox.getPixXFromLatLon(currentPt.lat, currentPt.lon); + float endY = tileBox.getPixYFromLatLon(currentPt.lat, currentPt.lon); + int prevColor = prevPt.getColor(scaleType.toColorizationType()); + int currentColor = currentPt.getColor(scaleType.toColorizationType()); + LinearGradient gradient = new LinearGradient(startX, startY, endX, endY, prevColor, currentColor, Shader.TileMode.CLAMP); + Paint paint = new Paint(this.paint); + paint.setShader(gradient); + Path path = new Path(); + path.moveTo(startX, startY); + path.lineTo(endX, endY); + canvas.drawPath(path, paint); + } + prevPt = currentPt; + } + canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + } } public static class StandardTrack extends RenderableSegment { @@ -193,7 +232,12 @@ public class Renderable { } @Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { - draw(culled.isEmpty() ? points : culled, p, canvas, tileBox); + if (scaleType != null) { + drawGradient(getPointsForDrawing(), p, canvas, tileBox); + scaleType = null; + } else { + drawSolid(getPointsForDrawing(), p, canvas, tileBox); + } } } @@ -215,7 +259,7 @@ public class Renderable { @Override protected void startCuller(double newZoom) {} @Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { - draw(points, p, canvas, tileBox); + drawSolid(points, p, canvas, tileBox); } } } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 339192e6b6..abb99e8428 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -53,6 +53,7 @@ import net.osmand.plus.render.OsmandRenderer; import net.osmand.plus.render.OsmandRenderer.RenderingContext; import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.track.GradientScaleType; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.TrackDrawInfo; import net.osmand.plus.views.OsmandMapLayer; @@ -66,6 +67,7 @@ import net.osmand.plus.views.layers.geometry.GpxGeometryWayContext; import net.osmand.render.RenderingRuleProperty; import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; +import net.osmand.router.RouteColorize; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -142,6 +144,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private CommonPreference defaultTrackWidthPref; private CommonPreference currentTrackColorPref; + private CommonPreference currentTrackScaleType; private CommonPreference currentTrackWidthPref; private CommonPreference currentTrackShowArrowsPref; private CommonPreference currentTrackShowStartFinishPref; @@ -155,6 +158,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer(); currentTrackColorPref = view.getSettings().CURRENT_TRACK_COLOR; + currentTrackScaleType = view.getSettings().CURRENT_TRACK_COLORIZATION; currentTrackWidthPref = view.getSettings().CURRENT_TRACK_WIDTH; currentTrackShowArrowsPref = view.getSettings().CURRENT_TRACK_SHOW_ARROWS; currentTrackShowStartFinishPref = view.getSettings().CURRENT_TRACK_SHOW_START_FINISH; @@ -661,10 +665,22 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private void drawSelectedFileSegments(SelectedGpxFile selectedGpxFile, boolean currentTrack, Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { + GPXFile gpxFile = selectedGpxFile.getGpxFile(); List segments = selectedGpxFile.getPointsToDisplay(); + GradientScaleType scaleType = getGradientScaleType(gpxFile); + List colorsOfPoints = null; + if (scaleType != null) { + RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, scaleType.toColorizationType()); + colorize.setPalette(getColorizationPalette(gpxFile, scaleType)); + colorsOfPoints = colorize.getResult(false); + } + int startIdx = 0; for (TrkSegment ts : segments) { - String width = getTrackWidthName(selectedGpxFile.getGpxFile(), defaultTrackWidthPref.get()); - int color = getTrackColor(selectedGpxFile.getGpxFile(), ts.getColor(cachedColor)); + String width = getTrackWidthName(gpxFile, defaultTrackWidthPref.get()); + int color = getTrackColor(gpxFile, ts.getColor(cachedColor)); + if (colorsOfPoints != null) { + startIdx = setColorsToPoints(ts, colorsOfPoints, scaleType, startIdx); + } if (ts.renderer == null && !ts.points.isEmpty()) { Renderable.RenderableSegment renderer; if (currentTrack) { @@ -677,11 +693,45 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox); if (ts.renderer instanceof Renderable.RenderableSegment) { - ((Renderable.RenderableSegment) ts.renderer).drawSegment(view.getZoom(), paint, canvas, tileBox); + Renderable.RenderableSegment renderableSegment = (Renderable.RenderableSegment) ts.renderer; + if (scaleType != null) { + renderableSegment.setGradientScaleType(scaleType); + } + renderableSegment.drawSegment(view.getZoom(), paint, canvas, tileBox); } } } + private int setColorsToPoints(TrkSegment segment, List colors, GradientScaleType scaleType, int startIdx) { + int pointsSize = segment.points.size(); + RouteColorize.RouteColorizationPoint startColor = colors.get(startIdx); + RouteColorize.RouteColorizationPoint endColor = colors.get(startIdx + pointsSize - 1); + WptPt firstPoint = segment.points.get(0); + WptPt lastPoint = segment.points.get(pointsSize - 1); + while (!compareCoordinates(firstPoint, startColor) && compareCoordinates(lastPoint, endColor)) { + startIdx++; + startColor = colors.get(startIdx); + endColor = colors.get(startIdx + pointsSize - 1); + } + + for (int i = startIdx; i < startIdx + pointsSize; i++) { + WptPt currentPoint = segment.points.get(i - startIdx); + int currentColor = colors.get(i).color; + if (scaleType == GradientScaleType.SPEED) { + currentPoint.speedColor = currentColor; + } else if (scaleType == GradientScaleType.ALTITUDE) { + currentPoint.altitudeColor = currentColor; + } else { + currentPoint.slopeColor = currentColor; + } + } + return startIdx; + } + + private boolean compareCoordinates(WptPt left, RouteColorize.RouteColorizationPoint right) { + return left.lat == right.lat && left.lon == right.lon; + } + private float getTrackWidth(String width, float defaultTrackWidth) { Float trackWidth = cachedTrackWidth.get(width); return trackWidth != null ? trackWidth : defaultTrackWidth; @@ -702,6 +752,37 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM return color != 0 ? color : defaultColor; } + private GradientScaleType getGradientScaleType(GPXFile gpxFile) { + if (hasTrackDrawInfoForTrack(gpxFile)) { + return trackDrawInfo.getGradientScaleType(); + } else if (gpxFile.showCurrentTrack) { + return currentTrackScaleType.get(); + } else { + GpxDataItem dataItem = gpxDbHelper.getItem(new File(gpxFile.path)); + if (dataItem != null && dataItem.getGradientScaleType() != null) { + return dataItem.getGradientScaleType(); + } + } + return null; + } + + private int[] getColorizationPalette(GPXFile gpxFile, GradientScaleType scaleType) { + if (hasTrackDrawInfoForTrack(gpxFile)) { + return trackDrawInfo.getGradientPalette(scaleType); + } + GpxDataItem dataItem = gpxDbHelper.getItem(new File(gpxFile.path)); + if (dataItem == null) { + return RouteColorize.colors; + } + if (scaleType == GradientScaleType.SPEED) { + return dataItem.getGradientSpeedPalette(); + } else if (scaleType == GradientScaleType.ALTITUDE) { + return dataItem.getGradientAltitudePalette(); + } else { + return dataItem.getGradientSlopePalette(); + } + } + private String getTrackWidthName(GPXFile gpxFile, String defaultWidth) { String width = null; if (hasTrackDrawInfoForTrack(gpxFile)) { From 116ec774add189de5628e8be26c8c0f5c6539ef6 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 10 Mar 2021 18:43:40 +0500 Subject: [PATCH 4/7] Small fixes --- .../java/net/osmand/router/RouteColorize.java | 2 +- OsmAnd/src/net/osmand/plus/GPXDatabase.java | 4 ++-- .../plus/settings/backend/OsmandSettings.java | 24 ++++++++++++++++++- .../net/osmand/plus/track/TrackDrawInfo.java | 2 +- .../src/net/osmand/plus/views/Renderable.java | 22 +++++++---------- 5 files changed, 35 insertions(+), 19 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 301a69a101..a259a8ebb6 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -204,7 +204,7 @@ public class RouteColorize { } public void setPalette(int[] gradientPalette) { - if (gradientPalette.length != 3) { + if (gradientPalette == null || gradientPalette.length != 3) { return; } setPalette(new double[][] { diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java index b08013017f..0f70144a73 100644 --- a/OsmAnd/src/net/osmand/plus/GPXDatabase.java +++ b/OsmAnd/src/net/osmand/plus/GPXDatabase.java @@ -176,8 +176,8 @@ public class GPXDatabase { private File file; private GPXTrackAnalysis analysis; private String width; - private GradientScaleType gradientScaleType; private int color; + private GradientScaleType gradientScaleType; private int[] gradientSpeedPalette; private int[] gradientAltitudePalette; private int[] gradientSlopePalette; @@ -884,7 +884,7 @@ public class GPXDatabase { item.gradientSlopePalette = Algorithms.stringToGradientPalette(gradientSlopePalette); try { - item.gradientScaleType = Algorithms.isEmpty(gradientScaleType) ? null : GradientScaleType.valueOf(gradientScaleType); + item.gradientScaleType = Algorithms.isEmpty(gradientScaleType) ? null : GradientScaleType.valueOf(gradientScaleType.toUpperCase()); } catch (IllegalArgumentException e) { item.gradientScaleType = null; } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 0635f8d7c1..7abb6245d6 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1409,7 +1409,29 @@ public class OsmandSettings { public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal(); public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().makeShared().cache(); - public final CommonPreference CURRENT_TRACK_COLORIZATION = new EnumStringPreference<>(this, "current_track_colorization", null, GradientScaleType.values()).makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_COLORIZATION = new CommonPreference(this, "current_track_colorization", null) { + @Override + protected GradientScaleType getValue(Object prefs, GradientScaleType defaultValue) { + String name = getSettingsAPI().getString(prefs, getId(), null); + return parseString(name); + } + + @Override + protected boolean setValue(Object prefs, GradientScaleType val) { + String name = val == null ? null : val.getTypeName(); + return getSettingsAPI().edit(prefs).putString(getId(), name).commit(); + } + + @Override + public GradientScaleType parseString(String s) { + for (GradientScaleType value : GradientScaleType.values()) { + if (value.name().equals(s)) { + return value; + } + } + return null; + } + }.makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().makeShared().cache(); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java index f08f87546d..d3531c0c9d 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java @@ -47,8 +47,8 @@ public class TrackDrawInfo { public TrackDrawInfo(@NonNull OsmandApplication app, @NonNull GpxDataItem gpxDataItem, boolean currentRecording) { filePath = gpxDataItem.getFile().getPath(); width = gpxDataItem.getWidth(); - gradientScaleType = gpxDataItem.getGradientScaleType(); color = gpxDataItem.getColor(); + gradientScaleType = gpxDataItem.getGradientScaleType(); speedGradientPalette = gpxDataItem.getGradientSpeedPalette(); altitudeGradientPalette = gpxDataItem.getGradientAltitudePalette(); slopeGradientPalette = gpxDataItem.getGradientSlopePalette(); diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index e8d4a6183f..a8d8351967 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -102,7 +102,14 @@ public class Renderable { protected abstract void startCuller(double newZoom); - protected void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) {} + protected void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { + if (scaleType != null) { + drawGradient(getPointsForDrawing(), p, canvas, tileBox); + scaleType = null; + } else { + drawSolid(getPointsForDrawing(), p, canvas, tileBox); + } + } public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { @@ -230,15 +237,6 @@ public class Renderable { } } } - - @Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { - if (scaleType != null) { - drawGradient(getPointsForDrawing(), p, canvas, tileBox); - scaleType = null; - } else { - drawSolid(getPointsForDrawing(), p, canvas, tileBox); - } - } } public static class CurrentTrack extends RenderableSegment { @@ -257,9 +255,5 @@ public class Renderable { } @Override protected void startCuller(double newZoom) {} - - @Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { - drawSolid(points, p, canvas, tileBox); - } } } From c473f77a4db72c9b7d92b1a5a1c504f0178f8987 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 10 Mar 2021 19:59:06 +0500 Subject: [PATCH 5/7] Fix palette --- .../src/main/java/net/osmand/router/RouteColorize.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 a259a8ebb6..7b9f46c108 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -209,8 +209,8 @@ public class RouteColorize { } setPalette(new double[][] { {minValue, gradientPalette[0]}, - {colorizationType == ColorizationType.SLOPE ? 12.5 : (minValue + maxValue) / 2}, - {maxValue, gradientPalette[0]} + {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2}, + {maxValue, gradientPalette[2]} }); } From 772df1dd46d856e0f49ce11d3f0bb7d0bd665033 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 10 Mar 2021 23:11:08 +0500 Subject: [PATCH 6/7] Fix NPE --- OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java index 737e302e6a..be59b4bf6f 100644 --- a/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java +++ b/OsmAnd-java/src/main/java/net/osmand/util/Algorithms.java @@ -1049,7 +1049,7 @@ public class Algorithms { } public static String gradientPaletteToString(int[] colors) { - int[] src = colors.length == 3 ? colors : RouteColorize.colors; + int[] src = (colors != null && colors.length == 3) ? colors : RouteColorize.colors; return Algorithms.colorToString(src[0]) + " " + Algorithms.colorToString(src[1]) + " " + Algorithms.colorToString(src[2]); From 979c10aba40ac4b84ca3f94d8c60044634ae9e30 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 12 Mar 2021 20:04:51 +0500 Subject: [PATCH 7/7] Small fixes & saving gradient palette of speed/altitude/slope scale types --- .../java/net/osmand/router/RouteColorize.java | 2 +- OsmAnd/res/layout/gradient_card.xml | 2 +- OsmAnd/src/net/osmand/plus/GPXDatabase.java | 12 +-- OsmAnd/src/net/osmand/plus/GpxDbHelper.java | 2 +- .../backend/EnumStringPreference.java | 6 +- .../plus/settings/backend/OsmandSettings.java | 27 +----- .../backend/backup/GpxSettingsItem.java | 6 +- .../net/osmand/plus/track/GradientCard.java | 9 +- .../plus/track/TrackAppearanceFragment.java | 17 +++- .../osmand/plus/track/TrackColoringCard.java | 23 ++--- .../net/osmand/plus/track/TrackDrawInfo.java | 24 ++++++ .../src/net/osmand/plus/views/Renderable.java | 86 +++++++++---------- .../osmand/plus/views/layers/GPXLayer.java | 20 ++++- 13 files changed, 136 insertions(+), 100 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 7b9f46c108..8fb0046bb4 100644 --- a/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java +++ b/OsmAnd-java/src/main/java/net/osmand/router/RouteColorize.java @@ -209,7 +209,7 @@ public class RouteColorize { } setPalette(new double[][] { {minValue, gradientPalette[0]}, - {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2}, + {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, gradientPalette[1]}, {maxValue, gradientPalette[2]} }); } diff --git a/OsmAnd/res/layout/gradient_card.xml b/OsmAnd/res/layout/gradient_card.xml index ff0834bee0..a4edba9be2 100644 --- a/OsmAnd/res/layout/gradient_card.xml +++ b/OsmAnd/res/layout/gradient_card.xml @@ -3,7 +3,7 @@ xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:orientation="vertical" android:padding="@dimen/content_padding" android:paddingStart="@dimen/content_padding" diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java index 0f70144a73..385ec79484 100644 --- a/OsmAnd/src/net/osmand/plus/GPXDatabase.java +++ b/OsmAnd/src/net/osmand/plus/GPXDatabase.java @@ -1,8 +1,5 @@ package net.osmand.plus; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.IndexConstants; @@ -16,6 +13,9 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + public class GPXDatabase { private static final int DB_VERSION = 11; @@ -751,7 +751,9 @@ public class GPXDatabase { new Object[] {fileName, fileDir, color, 0, item.splitType, item.splitInterval, item.apiImported ? 1 : 0, item.showAsMarkers ? 1 : 0, item.joinSegments ? 1 : 0, item.showArrows ? 1 : 0, item.showStartFinish ? 1 : 0, item.width, - item.gradientSpeedPalette, item.gradientAltitudePalette, item.gradientSlopePalette, gradientScaleType}); + Algorithms.gradientPaletteToString(item.gradientSpeedPalette), + Algorithms.gradientPaletteToString(item.gradientAltitudePalette), + Algorithms.gradientPaletteToString(item.gradientSlopePalette), gradientScaleType}); } } @@ -884,7 +886,7 @@ public class GPXDatabase { item.gradientSlopePalette = Algorithms.stringToGradientPalette(gradientSlopePalette); try { - item.gradientScaleType = Algorithms.isEmpty(gradientScaleType) ? null : GradientScaleType.valueOf(gradientScaleType.toUpperCase()); + item.gradientScaleType = GradientScaleType.getGradientTypeByName(gradientScaleType); } catch (IllegalArgumentException e) { item.gradientScaleType = null; } diff --git a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java index ef93703190..21154d5819 100644 --- a/OsmAnd/src/net/osmand/plus/GpxDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxDbHelper.java @@ -78,7 +78,7 @@ public class GpxDbHelper { return res; } - public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int[] palette) { + public boolean updateGradientScalePalette(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int[] palette) { boolean res = db.updateGradientScaleColor(item, gradientScaleType, palette); putToCache(item); return res; diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java index d51deca152..a88a17fed3 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/EnumStringPreference.java @@ -12,7 +12,8 @@ public class EnumStringPreference> extends CommonPreference @Override protected E getValue(Object prefs, E defaultValue) { try { - String name = getSettingsAPI().getString(prefs, getId(), defaultValue.name()); + String defaultValueName = defaultValue == null ? null : defaultValue.name(); + String name = getSettingsAPI().getString(prefs, getId(), defaultValueName); E value = parseString(name); return value != null ? value : defaultValue; } catch (ClassCastException ex) { @@ -23,7 +24,8 @@ public class EnumStringPreference> extends CommonPreference @Override public boolean setValue(Object prefs, E val) { - return getSettingsAPI().edit(prefs).putString(getId(), val.name()).commit(); + String name = val == null ? null : val.name(); + return getSettingsAPI().edit(prefs).putString(getId(), name).commit(); } @Override diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 7abb6245d6..1a2658870b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -1409,29 +1409,10 @@ public class OsmandSettings { public final OsmandPreference LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal(); public final CommonPreference CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().makeShared().cache(); - public final CommonPreference CURRENT_TRACK_COLORIZATION = new CommonPreference(this, "current_track_colorization", null) { - @Override - protected GradientScaleType getValue(Object prefs, GradientScaleType defaultValue) { - String name = getSettingsAPI().getString(prefs, getId(), null); - return parseString(name); - } - - @Override - protected boolean setValue(Object prefs, GradientScaleType val) { - String name = val == null ? null : val.getTypeName(); - return getSettingsAPI().edit(prefs).putString(getId(), name).commit(); - } - - @Override - public GradientScaleType parseString(String s) { - for (GradientScaleType value : GradientScaleType.values()) { - if (value.name().equals(s)) { - return value; - } - } - return null; - } - }.makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_COLORIZATION = new EnumStringPreference<>(this, "current_track_colorization", null, GradientScaleType.values()).makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_SPEED_GRADIENT_PALETTE = new StringPreference(this, "current_track_speed_gradient_palette", null).makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_ALTITUDE_GRADIENT_PALETTE = new StringPreference(this, "current_track_altitude_gradient_palette", null).makeGlobal().makeShared().cache(); + public final CommonPreference CURRENT_TRACK_SLOPE_GRADIENT_PALETTE = new StringPreference(this, "current_track_slope_gradient_palette", null).makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().makeShared().cache(); public final CommonPreference CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().makeShared().cache(); diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java index 2eca72fba1..fe6fd9b67a 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/GpxSettingsItem.java @@ -84,9 +84,9 @@ public class GpxSettingsItem extends FileSettingsItem { gpxDbHelper.updateShowStartFinish(dataItem, appearanceInfo.showStartFinish); gpxDbHelper.updateSplit(dataItem, splitType, appearanceInfo.splitInterval); gpxDbHelper.updateGradientScaleType(dataItem, appearanceInfo.scaleType); - gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.SPEED, appearanceInfo.gradientSpeedPalette); - gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.ALTITUDE, appearanceInfo.gradientAltitudePalette); - gpxDbHelper.updateGradientScaleColor(dataItem, GradientScaleType.SLOPE, appearanceInfo.gradientSlopePalette); + gpxDbHelper.updateGradientScalePalette(dataItem, GradientScaleType.SPEED, appearanceInfo.gradientSpeedPalette); + gpxDbHelper.updateGradientScalePalette(dataItem, GradientScaleType.ALTITUDE, appearanceInfo.gradientAltitudePalette); + gpxDbHelper.updateGradientScalePalette(dataItem, GradientScaleType.SLOPE, appearanceInfo.gradientSlopePalette); } private void createGpxAppearanceInfo() { diff --git a/OsmAnd/src/net/osmand/plus/track/GradientCard.java b/OsmAnd/src/net/osmand/plus/track/GradientCard.java index 77d881574e..217ad2a8f1 100644 --- a/OsmAnd/src/net/osmand/plus/track/GradientCard.java +++ b/OsmAnd/src/net/osmand/plus/track/GradientCard.java @@ -14,15 +14,17 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; public class GradientCard extends BaseCard { private GPXTrackAnalysis gpxTrackAnalysis; - private GradientScaleType selectedScaleType = null; + private GradientScaleType selectedScaleType; - public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis) { + public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis, @Nullable GradientScaleType selectedScaleType) { super(mapActivity); this.gpxTrackAnalysis = gpxTrackAnalysis; + this.selectedScaleType = selectedScaleType; } @Override @@ -72,10 +74,11 @@ public class GradientCard extends BaseCard { return (int) value + " %"; } String speed = OsmAndFormatter.getFormattedSpeed(value, app); + String speedUnit = app.getSettings().SPEED_SYSTEM.get().toShortString(app); Spannable formattedSpeed = new SpannableString(speed); formattedSpeed.setSpan( new ForegroundColorSpan(AndroidUtils.getColorFromAttr(app, android.R.attr.textColorSecondary)), - speed.indexOf(" "), speed.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + speed.indexOf(speedUnit), speed.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return formattedSpeed; } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java index 98831141bc..3aaeebccae 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackAppearanceFragment.java @@ -160,6 +160,9 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement trackDrawInfo = new TrackDrawInfo(true); trackDrawInfo.setColor(app.getSettings().CURRENT_TRACK_COLOR.get()); trackDrawInfo.setGradientScaleType(app.getSettings().CURRENT_TRACK_COLORIZATION.get()); + trackDrawInfo.setSpeedGradientPalette(Algorithms.stringToArray(app.getSettings().CURRENT_TRACK_SPEED_GRADIENT_PALETTE.get())); + trackDrawInfo.setAltitudeGradientPalette(Algorithms.stringToArray(app.getSettings().CURRENT_TRACK_ALTITUDE_GRADIENT_PALETTE.get())); + trackDrawInfo.setSlopeGradientPalette(Algorithms.stringToArray(app.getSettings().CURRENT_TRACK_SLOPE_GRADIENT_PALETTE.get())); trackDrawInfo.setWidth(app.getSettings().CURRENT_TRACK_WIDTH.get()); trackDrawInfo.setShowArrows(app.getSettings().CURRENT_TRACK_SHOW_ARROWS.get()); trackDrawInfo.setShowStartFinish(app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.get()); @@ -579,12 +582,18 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement if (gpxFile.showCurrentTrack) { app.getSettings().CURRENT_TRACK_COLOR.set(trackDrawInfo.getColor()); app.getSettings().CURRENT_TRACK_COLORIZATION.set(trackDrawInfo.getGradientScaleType()); + app.getSettings().CURRENT_TRACK_SPEED_GRADIENT_PALETTE.set(Algorithms.arrayToString(trackDrawInfo.getSpeedGradientPalette())); + app.getSettings().CURRENT_TRACK_ALTITUDE_GRADIENT_PALETTE.set(Algorithms.arrayToString(trackDrawInfo.getAltitudeGradientPalette())); + app.getSettings().CURRENT_TRACK_SLOPE_GRADIENT_PALETTE.set(Algorithms.arrayToString(trackDrawInfo.getSlopeGradientPalette())); app.getSettings().CURRENT_TRACK_WIDTH.set(trackDrawInfo.getWidth()); app.getSettings().CURRENT_TRACK_SHOW_ARROWS.set(trackDrawInfo.isShowArrows()); app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.set(trackDrawInfo.isShowStartFinish()); } else if (gpxDataItem != null) { GpxSplitType splitType = GpxSplitType.getSplitTypeByTypeId(trackDrawInfo.getSplitType()); gpxDbHelper.updateColor(gpxDataItem, trackDrawInfo.getColor()); + gpxDbHelper.updateGradientScalePalette(gpxDataItem, GradientScaleType.SPEED, trackDrawInfo.getSpeedGradientPalette()); + gpxDbHelper.updateGradientScalePalette(gpxDataItem, GradientScaleType.ALTITUDE, trackDrawInfo.getAltitudeGradientPalette()); + gpxDbHelper.updateGradientScalePalette(gpxDataItem, GradientScaleType.SLOPE, trackDrawInfo.getSlopeGradientPalette()); gpxDbHelper.updateWidth(gpxDataItem, trackDrawInfo.getWidth()); gpxDbHelper.updateShowArrows(gpxDataItem, trackDrawInfo.isShowArrows()); // gpxDbHelper.updateShowStartFinish(gpxDataItem, trackDrawInfo.isShowStartFinish()); @@ -662,9 +671,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement setupColorsCard(cardsContainer); - gradientCard = new GradientCard(mapActivity, selectedGpxFile.getTrackAnalysis(app)); - AndroidUiHelper.updateVisibility(gradientCard.build(mapActivity), false); - cardsContainer.addView(gradientCard.getView()); + gradientCard = new GradientCard(mapActivity, selectedGpxFile.getTrackAnalysis(app), trackDrawInfo.getGradientScaleType()); + cardsContainer.addView(gradientCard.build(mapActivity)); trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() { @@ -692,7 +700,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement List colors = getTrackColors(); colorsCard = new ColorsCard(mapActivity, trackDrawInfo.getColor(), this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null); colorsCard.setListener(this); - cardsContainer.addView(colorsCard.build(mapActivity)); + AndroidUiHelper.updateVisibility(colorsCard.build(mapActivity), trackDrawInfo.getGradientScaleType() == null); + cardsContainer.addView(colorsCard.getView()); } } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java index 44645180ea..41e17ac37e 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackColoringCard.java @@ -1,5 +1,6 @@ package net.osmand.plus.track; +import android.content.Context; import android.graphics.drawable.GradientDrawable; import android.os.Build; import android.view.LayoutInflater; @@ -188,6 +189,7 @@ public class TrackColoringCard extends BaseCard { private void updateButtonBg(TrackAppearanceViewHolder holder, TrackAppearanceItem item) { GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline); if (rectContourDrawable != null) { + Context ctx = holder.itemView.getContext(); boolean itemSelected = getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item); int strokeColor; @@ -195,39 +197,40 @@ public class TrackColoringCard extends BaseCard { int strokeWidth; if (itemSelected) { - strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.pstsIndicatorColor); + strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary); backgroundColor = 0; strokeWidth = 2; } else if (!item.isActive()) { - strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.stroked_buttons_and_links_outline); - backgroundColor = AndroidUtils.getColorFromAttr(app, R.attr.ctx_menu_card_btn); + strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.stroked_buttons_and_links_outline); + backgroundColor = AndroidUtils.getColorFromAttr(ctx, R.attr.ctx_menu_card_btn); strokeWidth = 2; } else { - strokeColor = AndroidUtils.getColorFromAttr(app, R.attr.stroked_buttons_and_links_outline); + strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.stroked_buttons_and_links_outline); backgroundColor = 0; strokeWidth = 1; } rectContourDrawable.mutate(); rectContourDrawable.setColor(backgroundColor); - rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, strokeWidth), strokeColor); + rectContourDrawable.setStroke(AndroidUtils.dpToPx(ctx, strokeWidth), strokeColor); holder.button.setImageDrawable(rectContourDrawable); } } private void updateTextAndIconColor(TrackAppearanceViewHolder holder, TrackAppearanceItem item) { + Context ctx = holder.itemView.getContext(); boolean isSelected = item.getAttrName().equals(getSelectedAppearanceItem().getAttrName()); int iconColorId; int textColorId; if (isSelected) { - iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.default_icon_color); - textColorId = AndroidUtils.getColorFromAttr(app, android.R.attr.textColor); + iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.default_icon_color); + textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColor); } else if (!item.isActive()) { - iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.default_icon_color); - textColorId = AndroidUtils.getColorFromAttr(app, android.R.attr.textColorSecondary); + iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.default_icon_color); + textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColorSecondary); } else { - iconColorId = AndroidUtils.getColorFromAttr(app, R.attr.pstsIndicatorColor); + iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary); textColorId = iconColorId; } diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java index d3531c0c9d..2f3d0a2c32 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java @@ -98,6 +98,30 @@ public class TrackDrawInfo { } } + public int[] getSpeedGradientPalette() { + return speedGradientPalette; + } + + public int[] getAltitudeGradientPalette() { + return altitudeGradientPalette; + } + + public int[] getSlopeGradientPalette() { + return slopeGradientPalette; + } + + public void setSpeedGradientPalette(int[] palette) { + this.speedGradientPalette = palette; + } + + public void setAltitudeGradientPalette(int[] palette) { + this.altitudeGradientPalette = palette; + } + + public void setSlopeGradientPalette(int[] palette) { + this.slopeGradientPalette = palette; + } + public int getSplitType() { return splitType; } diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index a8d8351967..5053f46a69 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -6,8 +6,6 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Shader; -import androidx.annotation.NonNull; - import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.WptPt; import net.osmand.data.QuadRect; @@ -27,6 +25,8 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import androidx.annotation.NonNull; + public class Renderable { @@ -103,12 +103,18 @@ public class Renderable { protected abstract void startCuller(double newZoom); protected void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) { + if (points.size() < 2) { + return; + } + + updateLocalPaint(p); + canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); if (scaleType != null) { drawGradient(getPointsForDrawing(), p, canvas, tileBox); - scaleType = null; } else { drawSolid(getPointsForDrawing(), p, canvas, tileBox); } + canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); } @@ -139,55 +145,44 @@ public class Renderable { } protected void drawSolid(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { - if (pts.size() > 1) { - updateLocalPaint(p); - canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); - QuadRect tileBounds = tileBox.getLatLonBounds(); - WptPt lastPt = pts.get(0); - boolean recalculateLastXY = true; - Path path = new Path(); - for (int i = 1; i < pts.size(); i++) { - WptPt pt = pts.get(i); - if (Math.min(pt.lon, lastPt.lon) < tileBounds.right && Math.max(pt.lon, lastPt.lon) > tileBounds.left - && Math.min(pt.lat, lastPt.lat) < tileBounds.top && Math.max(pt.lat, lastPt.lat) > tileBounds.bottom) { - if (recalculateLastXY) { - recalculateLastXY = false; - float lastX = tileBox.getPixXFromLatLon(lastPt.lat, lastPt.lon); - float lastY = tileBox.getPixYFromLatLon(lastPt.lat, lastPt.lon); - if (!path.isEmpty()) { - canvas.drawPath(path, paint); - } - path.reset(); - path.moveTo(lastX, lastY); + QuadRect tileBounds = tileBox.getLatLonBounds(); + WptPt lastPt = pts.get(0); + boolean recalculateLastXY = true; + Path path = new Path(); + for (int i = 1; i < pts.size(); i++) { + WptPt pt = pts.get(i); + if (arePointsInsideTile(pt, lastPt, tileBounds)) { + if (recalculateLastXY) { + recalculateLastXY = false; + float lastX = tileBox.getPixXFromLatLon(lastPt.lat, lastPt.lon); + float lastY = tileBox.getPixYFromLatLon(lastPt.lat, lastPt.lon); + if (!path.isEmpty()) { + canvas.drawPath(path, paint); } - float x = tileBox.getPixXFromLatLon(pt.lat, pt.lon); - float y = tileBox.getPixYFromLatLon(pt.lat, pt.lon); - path.lineTo(x, y); - } else { - recalculateLastXY = true; + path.reset(); + path.moveTo(lastX, lastY); } - lastPt = pt; + float x = tileBox.getPixXFromLatLon(pt.lat, pt.lon); + float y = tileBox.getPixYFromLatLon(pt.lat, pt.lon); + path.lineTo(x, y); + } else { + recalculateLastXY = true; } - if (!path.isEmpty()) { - canvas.drawPath(path, paint); - } - canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + lastPt = pt; + } + if (!path.isEmpty()) { + canvas.drawPath(path, paint); } } protected void drawGradient(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { - if (pts.size() < 2) { - return; - } - - updateLocalPaint(p); - canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); QuadRect tileBounds = tileBox.getLatLonBounds(); + Path path = new Path(); + Paint paint = new Paint(this.paint); WptPt prevPt = pts.get(0); for (int i = 1; i < pts.size(); i++) { WptPt currentPt = pts.get(i); - if (Math.min(currentPt.lon, prevPt.lon) < tileBounds.right && Math.max(currentPt.lon, prevPt.lon) > tileBounds.left - && Math.min(currentPt.lat, prevPt.lat) < tileBounds.top && Math.max(currentPt.lat, prevPt.lat) > tileBounds.bottom) { + if (arePointsInsideTile(currentPt, prevPt, tileBounds)) { float startX = tileBox.getPixXFromLatLon(prevPt.lat, prevPt.lon); float startY = tileBox.getPixYFromLatLon(prevPt.lat, prevPt.lon); float endX = tileBox.getPixXFromLatLon(currentPt.lat, currentPt.lon); @@ -195,16 +190,19 @@ public class Renderable { int prevColor = prevPt.getColor(scaleType.toColorizationType()); int currentColor = currentPt.getColor(scaleType.toColorizationType()); LinearGradient gradient = new LinearGradient(startX, startY, endX, endY, prevColor, currentColor, Shader.TileMode.CLAMP); - Paint paint = new Paint(this.paint); paint.setShader(gradient); - Path path = new Path(); + path.reset(); path.moveTo(startX, startY); path.lineTo(endX, endY); canvas.drawPath(path, paint); } prevPt = currentPt; } - canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + } + + protected boolean arePointsInsideTile(WptPt first, WptPt second, QuadRect tileBounds) { + return Math.min(first.lon, second.lon) < tileBounds.right && Math.max(first.lon, second.lon) > tileBounds.left + && Math.min(first.lat, second.lat) < tileBounds.top && Math.max(first.lat, second.lat) > tileBounds.bottom; } } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index abb99e8428..033437d27c 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -145,6 +145,9 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private CommonPreference currentTrackColorPref; private CommonPreference currentTrackScaleType; + private CommonPreference currentTrackSpeedGradientPalette; + private CommonPreference currentTrackAltitudeGradientPalette; + private CommonPreference currentTrackSlopeGradientPalette; private CommonPreference currentTrackWidthPref; private CommonPreference currentTrackShowArrowsPref; private CommonPreference currentTrackShowStartFinishPref; @@ -159,6 +162,9 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM currentTrackColorPref = view.getSettings().CURRENT_TRACK_COLOR; currentTrackScaleType = view.getSettings().CURRENT_TRACK_COLORIZATION; + currentTrackSpeedGradientPalette = view.getSettings().CURRENT_TRACK_SPEED_GRADIENT_PALETTE; + currentTrackAltitudeGradientPalette = view.getSettings().CURRENT_TRACK_ALTITUDE_GRADIENT_PALETTE; + currentTrackSlopeGradientPalette = view.getSettings().CURRENT_TRACK_SLOPE_GRADIENT_PALETTE; currentTrackWidthPref = view.getSettings().CURRENT_TRACK_WIDTH; currentTrackShowArrowsPref = view.getSettings().CURRENT_TRACK_SHOW_ARROWS; currentTrackShowStartFinishPref = view.getSettings().CURRENT_TRACK_SHOW_START_FINISH; @@ -694,9 +700,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox); if (ts.renderer instanceof Renderable.RenderableSegment) { Renderable.RenderableSegment renderableSegment = (Renderable.RenderableSegment) ts.renderer; - if (scaleType != null) { - renderableSegment.setGradientScaleType(scaleType); - } + renderableSegment.setGradientScaleType(scaleType); renderableSegment.drawSegment(view.getZoom(), paint, canvas, tileBox); } } @@ -769,6 +773,16 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private int[] getColorizationPalette(GPXFile gpxFile, GradientScaleType scaleType) { if (hasTrackDrawInfoForTrack(gpxFile)) { return trackDrawInfo.getGradientPalette(scaleType); + } else if (gpxFile.showCurrentTrack) { + String palette; + if (scaleType == GradientScaleType.SPEED) { + palette = currentTrackSpeedGradientPalette.get(); + } else if (scaleType == GradientScaleType.ALTITUDE) { + palette = currentTrackAltitudeGradientPalette.get(); + } else { + palette = currentTrackSlopeGradientPalette.get(); + } + return Algorithms.stringToArray(palette); } GpxDataItem dataItem = gpxDbHelper.getItem(new File(gpxFile.path)); if (dataItem == null) {