diff --git a/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java b/OsmAnd-java/src/main/java/net/osmand/GPXUtilities.java
index 4db84c5c33..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);
}
@@ -1662,16 +1679,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..8fb0046bb4 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,11 +25,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, 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 ValueType {
+ public enum ColorizationType {
ELEVATION,
SPEED,
SLOPE,
@@ -42,7 +44,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 +75,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 +90,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 +103,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();
}
@@ -201,6 +203,17 @@ public class RouteColorize {
sortPalette();
}
+ public void setPalette(int[] gradientPalette) {
+ if (gradientPalette == null || gradientPalette.length != 3) {
+ return;
+ }
+ setPalette(new double[][] {
+ {minValue, gradientPalette[0]},
+ {colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, gradientPalette[1]},
+ {maxValue, gradientPalette[2]}
+ });
+ }
+
private int getDefaultColor() {
return rgbaToDecimal(0, 0, 0, 0);
}
@@ -282,7 +295,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 7aa4389f67..ab12baf5e1 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 net.osmand.data.LatLon;
import org.apache.commons.logging.Log;
@@ -1061,4 +1062,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 != null && 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/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..a4edba9be2
--- /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 0a7231f67a..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:paddingBottom="@dimen/content_padding"
- android:visibility="gone">
+ 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 e919df6e29..c44c777164 100644
--- a/OsmAnd/res/layout/track_width_card.xml
+++ b/OsmAnd/res/layout/track_width_card.xml
@@ -45,7 +45,7 @@
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 66d7b6ec59..fcc2dd7b75 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.
Interval
Show/hide
Copy POI name
diff --git a/OsmAnd/src/net/osmand/plus/GPXDatabase.java b/OsmAnd/src/net/osmand/plus/GPXDatabase.java
index 74dc02be9c..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;
@@ -176,11 +176,11 @@ public class GPXDatabase {
private File file;
private GPXTrackAnalysis analysis;
private String width;
- private GradientScaleType gradientScaleType;
private int color;
- private int gradientSpeedColor;
- private int gradientAltitudeColor;
- private int gradientSlopeColor;
+ private GradientScaleType gradientScaleType;
+ 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,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.gradientSpeedColor, item.gradientAltitudeColor, item.gradientSlopeColor, gradientScaleType});
+ Algorithms.gradientPaletteToString(item.gradientSpeedPalette),
+ Algorithms.gradientPaletteToString(item.gradientAltitudePalette),
+ Algorithms.gradientPaletteToString(item.gradientSlopePalette), gradientScaleType});
}
}
@@ -836,9 +837,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,12 +881,12 @@ 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);
+ 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 8a7d886a63..21154d5819 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 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/helpers/GpxUiHelper.java b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
index 1d49394ea0..e871969042 100644
--- a/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
+++ b/OsmAnd/src/net/osmand/plus/helpers/GpxUiHelper.java
@@ -2310,15 +2310,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/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 0762f453f1..01758f60b2 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.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,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 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/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..fe6fd9b67a 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.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
new file mode 100644
index 0000000000..217ad2a8f1
--- /dev/null
+++ b/OsmAnd/src/net/osmand/plus/track/GradientCard.java
@@ -0,0 +1,84 @@
+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;
+import androidx.annotation.Nullable;
+
+public class GradientCard extends BaseCard {
+
+ private GPXTrackAnalysis gpxTrackAnalysis;
+ private GradientScaleType selectedScaleType;
+
+ public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis, @Nullable GradientScaleType selectedScaleType) {
+ super(mapActivity);
+ this.gpxTrackAnalysis = gpxTrackAnalysis;
+ this.selectedScaleType = selectedScaleType;
+ }
+
+ @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);
+ 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(speedUnit), speed.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return formattedSpeed;
+ }
+}
\ No newline at end of file
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 43b0c78eca..f33571bdd6 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;
@@ -158,6 +159,10 @@ 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.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());
@@ -340,6 +345,16 @@ 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();
+ trackDrawInfo.setGradientScaleType(currentScaleType);
+ mapActivity.refreshMap();
+ 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);
@@ -555,6 +570,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();
@@ -565,12 +583,19 @@ 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_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());
@@ -642,12 +667,15 @@ 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), trackDrawInfo.getGradientScaleType());
+ cardsContainer.addView(gradientCard.build(mapActivity));
+
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() {
@Override
@@ -674,7 +702,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 0a17f5e06b..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;
@@ -7,14 +8,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 +24,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 +58,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 +117,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 +150,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 +189,72 @@ 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);
+ Context ctx = holder.itemView.getContext();
+ boolean itemSelected = getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item);
+
+ int strokeColor;
+ int backgroundColor;
+ int strokeWidth;
+
+ if (itemSelected) {
+ strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary);
+ backgroundColor = 0;
+ strokeWidth = 2;
+ } else if (!item.isActive()) {
+ strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.stroked_buttons_and_links_outline);
+ backgroundColor = AndroidUtils.getColorFromAttr(ctx, 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(ctx, R.attr.stroked_buttons_and_links_outline);
+ backgroundColor = 0;
+ strokeWidth = 1;
}
+
+ rectContourDrawable.mutate();
+ rectContourDrawable.setColor(backgroundColor);
+ 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(ctx, R.attr.default_icon_color);
+ textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColor);
+ } else if (!item.isActive()) {
+ iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.default_icon_color);
+ textColorId = AndroidUtils.getColorFromAttr(ctx, android.R.attr.textColorSecondary);
+ } else {
+ iconColorId = AndroidUtils.getColorFromAttr(ctx, R.attr.colorPrimary);
+ 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 +273,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 +293,9 @@ public class TrackColoringCard extends BaseCard {
public int getIconId() {
return iconId;
}
+
+ public boolean isActive() {
+ return isActive;
+ }
}
}
\ No newline at end of file
diff --git a/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java b/OsmAnd/src/net/osmand/plus/track/TrackDrawInfo.java
index 18d1c30775..2f3d0a2c32 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;
@@ -44,8 +47,11 @@ 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();
splitType = gpxDataItem.getSplitType();
splitInterval = gpxDataItem.getSplitInterval();
joinSegments = gpxDataItem.isJoinSegments();
@@ -82,6 +88,40 @@ 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[] 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 ec8d302dab..5053f46a69 100644
--- a/OsmAnd/src/net/osmand/plus/views/Renderable.java
+++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java
@@ -1,16 +1,16 @@
package net.osmand.plus.views;
import android.graphics.Canvas;
+import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
-
-import androidx.annotation.NonNull;
+import android.graphics.Shader;
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;
@@ -25,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 {
@@ -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;
}
@@ -95,7 +102,20 @@ 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 (points.size() < 2) {
+ return;
+ }
+
+ updateLocalPaint(p);
+ canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
+ if (scaleType != null) {
+ drawGradient(getPointsForDrawing(), p, canvas, tileBox);
+ } else {
+ drawSolid(getPointsForDrawing(), p, canvas, tileBox);
+ }
+ canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
+ }
public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) {
@@ -124,42 +144,66 @@ public class Renderable {
}
}
- protected void draw(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);
+ protected void drawSolid(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) {
+ 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()) {
+ lastPt = pt;
+ }
+ if (!path.isEmpty()) {
+ canvas.drawPath(path, paint);
+ }
+ }
+
+ protected void drawGradient(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) {
+ 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 (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);
+ 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.setShader(gradient);
+ path.reset();
+ path.moveTo(startX, startY);
+ path.lineTo(endX, endY);
canvas.drawPath(path, paint);
}
- canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
+ prevPt = currentPt;
}
}
+
+ 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;
+ }
}
public static class StandardTrack extends RenderableSegment {
@@ -191,10 +235,6 @@ public class Renderable {
}
}
}
-
- @Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) {
- draw(culled.isEmpty() ? points : culled, p, canvas, tileBox);
- }
}
public static class CurrentTrack extends RenderableSegment {
@@ -213,9 +253,5 @@ 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);
- }
}
}
diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java
index b2a79dafb7..95d599fb56 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,10 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
private CommonPreference defaultTrackWidthPref;
private CommonPreference currentTrackColorPref;
+ private CommonPreference currentTrackScaleType;
+ private CommonPreference currentTrackSpeedGradientPalette;
+ private CommonPreference currentTrackAltitudeGradientPalette;
+ private CommonPreference currentTrackSlopeGradientPalette;
private CommonPreference currentTrackWidthPref;
private CommonPreference currentTrackShowArrowsPref;
private CommonPreference currentTrackShowStartFinishPref;
@@ -155,6 +161,10 @@ 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;
+ 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;
@@ -661,10 +671,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 +699,43 @@ 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;
+ 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 +756,47 @@ 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);
+ } 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) {
+ 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)) {