Merge pull request #11105 from osmandapp/track_dependent_coloring
Track coloring based on speed / altitude / slope
This commit is contained in:
commit
5f9047cc6d
23 changed files with 687 additions and 199 deletions
|
@ -6,6 +6,7 @@ import net.osmand.binary.StringBundle;
|
||||||
import net.osmand.binary.StringBundleWriter;
|
import net.osmand.binary.StringBundleWriter;
|
||||||
import net.osmand.binary.StringBundleXmlWriter;
|
import net.osmand.binary.StringBundleXmlWriter;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
|
import net.osmand.router.RouteColorize.ColorizationType;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -227,6 +228,9 @@ public class GPXUtilities {
|
||||||
public double hdop = Double.NaN;
|
public double hdop = Double.NaN;
|
||||||
public float heading = Float.NaN;
|
public float heading = Float.NaN;
|
||||||
public boolean deleted = false;
|
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 int colourARGB = 0; // point colour (used for altitude/speed colouring)
|
||||||
public double distance = 0.0; // cumulative distance, if in a track
|
public double distance = 0.0; // cumulative distance, if in a track
|
||||||
|
|
||||||
|
@ -249,6 +253,9 @@ public class GPXUtilities {
|
||||||
this.hdop = wptPt.hdop;
|
this.hdop = wptPt.hdop;
|
||||||
this.heading = wptPt.heading;
|
this.heading = wptPt.heading;
|
||||||
this.deleted = wptPt.deleted;
|
this.deleted = wptPt.deleted;
|
||||||
|
this.speedColor = wptPt.speedColor;
|
||||||
|
this.altitudeColor = wptPt.altitudeColor;
|
||||||
|
this.slopeColor = wptPt.slopeColor;
|
||||||
this.colourARGB = wptPt.colourARGB;
|
this.colourARGB = wptPt.colourARGB;
|
||||||
this.distance = wptPt.distance;
|
this.distance = wptPt.distance;
|
||||||
}
|
}
|
||||||
|
@ -311,6 +318,16 @@ public class GPXUtilities {
|
||||||
getExtensionsToWrite().put(ICON_NAME_EXTENSION, iconName);
|
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() {
|
public String getBackgroundType() {
|
||||||
return getExtensionsToRead().get(BACKGROUND_TYPE_EXTENSION);
|
return getExtensionsToRead().get(BACKGROUND_TYPE_EXTENSION);
|
||||||
}
|
}
|
||||||
|
@ -1662,16 +1679,16 @@ public class GPXUtilities {
|
||||||
return new QuadRect(left, top, right, bottom);
|
return new QuadRect(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGradientScaleColor(String gradientScaleType, int defColor) {
|
public int[] getGradientScaleColor(String gradientScaleType) {
|
||||||
String clrValue = null;
|
String clrValue = null;
|
||||||
if (extensions != null) {
|
if (extensions != null) {
|
||||||
clrValue = extensions.get(gradientScaleType);
|
clrValue = extensions.get(gradientScaleType);
|
||||||
}
|
}
|
||||||
return parseColor(clrValue, defColor);
|
return Algorithms.stringToGradientPalette(clrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGradientScaleColor(String gradientScaleType, int gradientScaleColor) {
|
public void setGradientScaleColor(String gradientScaleType, int[] gradientScalePalette) {
|
||||||
getExtensionsToWrite().put(gradientScaleType, Algorithms.colorToString(gradientScaleColor));
|
getExtensionsToWrite().put(gradientScaleType, Algorithms.gradientPaletteToString(gradientScalePalette));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGradientScaleType() {
|
public String getGradientScaleType() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import net.osmand.PlatformUtil;
|
||||||
import net.osmand.osm.edit.Node;
|
import net.osmand.osm.edit.Node;
|
||||||
import net.osmand.osm.edit.OsmMapUtils;
|
import net.osmand.osm.edit.OsmMapUtils;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
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 DARK_GREY = rgbaToDecimal(92, 92, 92, 255);
|
||||||
public static final int LIGHT_GREY = rgbaToDecimal(200, 200, 200, 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(90, 220, 95, 255);
|
||||||
public static final int GREEN = rgbaToDecimal(46,185,0,191);
|
public static final int YELLOW = rgbaToDecimal(212, 239, 50, 255);
|
||||||
public static final int YELLOW = rgbaToDecimal(255,222,2,227);
|
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,
|
ELEVATION,
|
||||||
SPEED,
|
SPEED,
|
||||||
SLOPE,
|
SLOPE,
|
||||||
|
@ -42,7 +44,7 @@ public class RouteColorize {
|
||||||
private final int BLUE_COLOR_INDEX = 3;//RGB
|
private final int BLUE_COLOR_INDEX = 3;//RGB
|
||||||
private final int ALPHA_COLOR_INDEX = 4;//RGBA
|
private final int ALPHA_COLOR_INDEX = 4;//RGBA
|
||||||
|
|
||||||
private ValueType valueType;
|
private ColorizationType colorizationType;
|
||||||
|
|
||||||
public static int SLOPE_RANGE = 150;//150 meters
|
public static int SLOPE_RANGE = 150;//150 meters
|
||||||
private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5%
|
private static final double MIN_DIFFERENCE_SLOPE = 0.05d;//5%
|
||||||
|
@ -73,7 +75,7 @@ public class RouteColorize {
|
||||||
/**
|
/**
|
||||||
* @param type ELEVATION, SPEED, SLOPE
|
* @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()) {
|
if (!gpxFile.hasTrkPt()) {
|
||||||
LOG.warn("GPX file is not consist of track points");
|
LOG.warn("GPX file is not consist of track points");
|
||||||
|
@ -88,7 +90,7 @@ public class RouteColorize {
|
||||||
for (GPXUtilities.WptPt p : ts.points) {
|
for (GPXUtilities.WptPt p : ts.points) {
|
||||||
latList.add(p.lat);
|
latList.add(p.lat);
|
||||||
lonList.add(p.lon);
|
lonList.add(p.lon);
|
||||||
if (type == ValueType.SPEED) {
|
if (type == ColorizationType.SPEED) {
|
||||||
valList.add(p.speed);
|
valList.add(p.speed);
|
||||||
} else {
|
} else {
|
||||||
valList.add(p.ele);
|
valList.add(p.ele);
|
||||||
|
@ -101,14 +103,14 @@ public class RouteColorize {
|
||||||
latitudes = listToArray(latList);
|
latitudes = listToArray(latList);
|
||||||
longitudes = listToArray(lonList);
|
longitudes = listToArray(lonList);
|
||||||
|
|
||||||
if (type == ValueType.SLOPE) {
|
if (type == ColorizationType.SLOPE) {
|
||||||
values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE);
|
values = calculateSlopesByElevations(latitudes, longitudes, listToArray(valList), SLOPE_RANGE);
|
||||||
} else {
|
} else {
|
||||||
values = listToArray(valList);
|
values = listToArray(valList);
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateMinMaxValue();
|
calculateMinMaxValue();
|
||||||
valueType = type;
|
colorizationType = type;
|
||||||
checkPalette();
|
checkPalette();
|
||||||
sortPalette();
|
sortPalette();
|
||||||
}
|
}
|
||||||
|
@ -201,6 +203,17 @@ public class RouteColorize {
|
||||||
sortPalette();
|
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() {
|
private int getDefaultColor() {
|
||||||
return rgbaToDecimal(0, 0, 0, 0);
|
return rgbaToDecimal(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -282,7 +295,7 @@ public class RouteColorize {
|
||||||
|
|
||||||
double[][] defaultPalette = {
|
double[][] defaultPalette = {
|
||||||
{minValue, GREEN},
|
{minValue, GREEN},
|
||||||
{valueType == ValueType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW},
|
{colorizationType == ColorizationType.SLOPE ? 0 : (minValue + maxValue) / 2, YELLOW},
|
||||||
{maxValue, RED}
|
{maxValue, RED}
|
||||||
};
|
};
|
||||||
palette = defaultPalette;
|
palette = defaultPalette;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.osmand.util;
|
||||||
|
|
||||||
import net.osmand.IProgress;
|
import net.osmand.IProgress;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.router.RouteColorize;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -1061,4 +1062,30 @@ public class Algorithms {
|
||||||
}
|
}
|
||||||
return false;
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
13
OsmAnd/res/drawable/bg_track_gradient.xml
Normal file
13
OsmAnd/res/drawable/bg_track_gradient.xml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<gradient
|
||||||
|
android:angle="0"
|
||||||
|
android:startColor="@color/track_gradient_start"
|
||||||
|
android:centerColor="@color/track_gradient_center"
|
||||||
|
android:endColor="@color/track_gradient_end"
|
||||||
|
android:type="linear" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
46
OsmAnd/res/layout/gradient_card.xml
Normal file
46
OsmAnd/res/layout/gradient_card.xml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/content_padding"
|
||||||
|
android:paddingStart="@dimen/content_padding"
|
||||||
|
android:paddingEnd="@dimen/content_padding">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/pages_item_size"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_half"
|
||||||
|
android:background="@drawable/bg_track_gradient" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/min_value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textColor="?attr/main_font_color_basic"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="100 m"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/max_value"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="end"
|
||||||
|
android:textColor="?attr/main_font_color_basic"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_regular"
|
||||||
|
tools:text="100 m"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -20,9 +20,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
android:paddingTop="@dimen/context_menu_buttons_padding_bottom">
|
||||||
android:paddingBottom="@dimen/content_padding"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
|
@ -41,15 +39,4 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.FlowLayout
|
|
||||||
android:id="@+id/select_color"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/content_padding"
|
|
||||||
android:layout_marginLeft="@dimen/content_padding"
|
|
||||||
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
|
|
||||||
android:layout_marginEnd="@dimen/content_padding"
|
|
||||||
android:layout_marginRight="@dimen/content_padding"
|
|
||||||
android:layout_marginBottom="@dimen/content_padding_half" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -45,7 +45,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingBottom="@dimen/content_padding">
|
android:paddingBottom="@dimen/favorites_select_group_button_height">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -482,4 +482,8 @@
|
||||||
<color name="text_input_background_dark">#1AFFFFFF</color>
|
<color name="text_input_background_dark">#1AFFFFFF</color>
|
||||||
<color name="mtrl_textinput_default_box_stroke_color">#67727272</color>
|
<color name="mtrl_textinput_default_box_stroke_color">#67727272</color>
|
||||||
|
|
||||||
|
<color name="track_gradient_start">#5ADC5F</color>
|
||||||
|
<color name="track_gradient_center">#D4EF32</color>
|
||||||
|
<color name="track_gradient_end">#F3374D</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -12,6 +12,9 @@
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<string name="select_another_colorization">Please select another type of colorization.</string>
|
||||||
|
<string name="track_has_no_speed">The track does not contain speed data.</string>
|
||||||
|
<string name="track_has_no_altitude">The track does not contain altitude data.</string>
|
||||||
<string name="shared_string_interval">Interval</string>
|
<string name="shared_string_interval">Interval</string>
|
||||||
<string name="quick_action_show_hide_title">Show/hide</string>
|
<string name="quick_action_show_hide_title">Show/hide</string>
|
||||||
<string name="copy_poi_name">Copy POI name</string>
|
<string name="copy_poi_name">Copy POI name</string>
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package net.osmand.plus;
|
package net.osmand.plus;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
|
@ -16,6 +13,9 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public class GPXDatabase {
|
public class GPXDatabase {
|
||||||
|
|
||||||
private static final int DB_VERSION = 11;
|
private static final int DB_VERSION = 11;
|
||||||
|
@ -176,11 +176,11 @@ public class GPXDatabase {
|
||||||
private File file;
|
private File file;
|
||||||
private GPXTrackAnalysis analysis;
|
private GPXTrackAnalysis analysis;
|
||||||
private String width;
|
private String width;
|
||||||
private GradientScaleType gradientScaleType;
|
|
||||||
private int color;
|
private int color;
|
||||||
private int gradientSpeedColor;
|
private GradientScaleType gradientScaleType;
|
||||||
private int gradientAltitudeColor;
|
private int[] gradientSpeedPalette;
|
||||||
private int gradientSlopeColor;
|
private int[] gradientAltitudePalette;
|
||||||
|
private int[] gradientSlopePalette;
|
||||||
private int splitType;
|
private int splitType;
|
||||||
private double splitInterval;
|
private double splitInterval;
|
||||||
private long fileLastModifiedTime;
|
private long fileLastModifiedTime;
|
||||||
|
@ -210,9 +210,9 @@ public class GPXDatabase {
|
||||||
width = gpxFile.getWidth(null);
|
width = gpxFile.getWidth(null);
|
||||||
showArrows = gpxFile.isShowArrows();
|
showArrows = gpxFile.isShowArrows();
|
||||||
showStartFinish = gpxFile.isShowStartFinish();
|
showStartFinish = gpxFile.isShowStartFinish();
|
||||||
gradientSpeedColor = gpxFile.getGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), 0);
|
gradientSpeedPalette = gpxFile.getGradientScaleColor(GradientScaleType.SPEED.getColorTypeName());
|
||||||
gradientSlopeColor = gpxFile.getGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), 0);
|
gradientSlopePalette = gpxFile.getGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName());
|
||||||
gradientAltitudeColor = gpxFile.getGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), 0);
|
gradientAltitudePalette = gpxFile.getGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName());
|
||||||
|
|
||||||
if (!Algorithms.isEmpty(gpxFile.getSplitType()) && gpxFile.getSplitInterval() > 0) {
|
if (!Algorithms.isEmpty(gpxFile.getSplitType()) && gpxFile.getSplitInterval() > 0) {
|
||||||
GpxSplitType gpxSplitType = GpxSplitType.getSplitTypeByName(gpxFile.getSplitType());
|
GpxSplitType gpxSplitType = GpxSplitType.getSplitTypeByName(gpxFile.getSplitType());
|
||||||
|
@ -243,23 +243,22 @@ public class GPXDatabase {
|
||||||
return gradientScaleType;
|
return gradientScaleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGradientSpeedColor() {
|
public int[] getGradientSpeedPalette() {
|
||||||
return gradientSpeedColor;
|
return gradientSpeedPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGradientAltitudeColor() {
|
public int[] getGradientAltitudePalette() {
|
||||||
return gradientAltitudeColor;
|
return gradientAltitudePalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGradientSlopeColor() {
|
public int[] getGradientSlopePalette() {
|
||||||
return gradientSlopeColor;
|
return gradientSlopePalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWidth() {
|
public String getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long getFileLastModifiedTime() {
|
public long getFileLastModifiedTime() {
|
||||||
return fileLastModifiedTime;
|
return fileLastModifiedTime;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +506,7 @@ public class GPXDatabase {
|
||||||
return false;
|
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);
|
SQLiteConnection db = openConnection(false);
|
||||||
if (db != null) {
|
if (db != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -516,17 +515,17 @@ public class GPXDatabase {
|
||||||
String columnName = null;
|
String columnName = null;
|
||||||
if (GradientScaleType.SPEED == gradientScaleType) {
|
if (GradientScaleType.SPEED == gradientScaleType) {
|
||||||
columnName = GPX_COL_GRADIENT_SPEED_COLOR;
|
columnName = GPX_COL_GRADIENT_SPEED_COLOR;
|
||||||
item.gradientSpeedColor = gradientScaleColor;
|
item.gradientSpeedPalette = gradientScalePalette;
|
||||||
} else if (GradientScaleType.ALTITUDE == gradientScaleType) {
|
} else if (GradientScaleType.ALTITUDE == gradientScaleType) {
|
||||||
columnName = GPX_COL_GRADIENT_ALTITUDE_COLOR;
|
columnName = GPX_COL_GRADIENT_ALTITUDE_COLOR;
|
||||||
item.gradientAltitudeColor = gradientScaleColor;
|
item.gradientAltitudePalette = gradientScalePalette;
|
||||||
} else if (GradientScaleType.SLOPE == gradientScaleType) {
|
} else if (GradientScaleType.SLOPE == gradientScaleType) {
|
||||||
columnName = GPX_COL_GRADIENT_SLOPE_COLOR;
|
columnName = GPX_COL_GRADIENT_SLOPE_COLOR;
|
||||||
item.gradientSlopeColor = gradientScaleColor;
|
item.gradientSlopePalette = gradientScalePalette;
|
||||||
}
|
}
|
||||||
db.execSQL("UPDATE " + GPX_TABLE_NAME + " SET " + columnName + " = ? " +
|
db.execSQL("UPDATE " + GPX_TABLE_NAME + " SET " + columnName + " = ? " +
|
||||||
" WHERE " + GPX_COL_NAME + " = ? AND " + GPX_COL_DIR + " = ?",
|
" 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 {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
@ -729,7 +728,7 @@ public class GPXDatabase {
|
||||||
color, item.file.lastModified(), item.splitType, item.splitInterval, item.apiImported ? 1 : 0,
|
color, item.file.lastModified(), item.splitType, item.splitInterval, item.apiImported ? 1 : 0,
|
||||||
Algorithms.encodeStringSet(item.analysis.wptCategoryNames), item.showAsMarkers ? 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.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 {
|
} else {
|
||||||
db.execSQL("INSERT INTO " + GPX_TABLE_NAME + "(" +
|
db.execSQL("INSERT INTO " + GPX_TABLE_NAME + "(" +
|
||||||
GPX_COL_NAME + ", " +
|
GPX_COL_NAME + ", " +
|
||||||
|
@ -752,7 +751,9 @@ public class GPXDatabase {
|
||||||
new Object[] {fileName, fileDir, color, 0, item.splitType, item.splitInterval,
|
new Object[] {fileName, fileDir, color, 0, item.splitType, item.splitInterval,
|
||||||
item.apiImported ? 1 : 0, item.showAsMarkers ? 1 : 0, item.joinSegments ? 1 : 0,
|
item.apiImported ? 1 : 0, item.showAsMarkers ? 1 : 0, item.joinSegments ? 1 : 0,
|
||||||
item.showArrows ? 1 : 0, item.showStartFinish ? 1 : 0, item.width,
|
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 showArrows = query.getInt(26) == 1;
|
||||||
boolean showStartFinish = query.getInt(27) == 1;
|
boolean showStartFinish = query.getInt(27) == 1;
|
||||||
String width = query.getString(28);
|
String width = query.getString(28);
|
||||||
String gradientSpeedColor = query.getString(29);
|
String gradientSpeedPalette = query.getString(29);
|
||||||
String gradientAltitudeColor = query.getString(30);
|
String gradientAltitudePalette = query.getString(30);
|
||||||
String gradientSlopeColor = query.getString(31);
|
String gradientSlopePalette = query.getString(31);
|
||||||
String gradientScaleType = query.getString(32);
|
String gradientScaleType = query.getString(32);
|
||||||
|
|
||||||
GPXTrackAnalysis a = new GPXTrackAnalysis();
|
GPXTrackAnalysis a = new GPXTrackAnalysis();
|
||||||
|
@ -880,12 +881,12 @@ public class GPXDatabase {
|
||||||
item.showArrows = showArrows;
|
item.showArrows = showArrows;
|
||||||
item.showStartFinish = showStartFinish;
|
item.showStartFinish = showStartFinish;
|
||||||
item.width = width;
|
item.width = width;
|
||||||
item.gradientSpeedColor = parseColor(gradientSpeedColor);
|
item.gradientSpeedPalette = Algorithms.stringToGradientPalette(gradientSpeedPalette);
|
||||||
item.gradientAltitudeColor = parseColor(gradientAltitudeColor);
|
item.gradientAltitudePalette = Algorithms.stringToGradientPalette(gradientAltitudePalette);
|
||||||
item.gradientSlopeColor = parseColor(gradientSlopeColor);
|
item.gradientSlopePalette = Algorithms.stringToGradientPalette(gradientSlopePalette);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
item.gradientScaleType = Algorithms.isEmpty(gradientScaleType) ? null : GradientScaleType.valueOf(gradientScaleType);
|
item.gradientScaleType = GradientScaleType.getGradientTypeByName(gradientScaleType);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
item.gradientScaleType = null;
|
item.gradientScaleType = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ public class GpxDbHelper {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean updateGradientScaleColor(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int color) {
|
public boolean updateGradientScalePalette(@NonNull GpxDataItem item, @NonNull GradientScaleType gradientScaleType, int[] palette) {
|
||||||
boolean res = db.updateGradientScaleColor(item, gradientScaleType, color);
|
boolean res = db.updateGradientScaleColor(item, gradientScaleType, palette);
|
||||||
putToCache(item);
|
putToCache(item);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2310,15 +2310,9 @@ public class GpxUiHelper {
|
||||||
if (dataItem.getWidth() != null) {
|
if (dataItem.getWidth() != null) {
|
||||||
gpxFile.setWidth(dataItem.getWidth());
|
gpxFile.setWidth(dataItem.getWidth());
|
||||||
}
|
}
|
||||||
if (dataItem.getGradientSpeedColor() != 0) {
|
gpxFile.setGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), dataItem.getGradientSpeedPalette());
|
||||||
gpxFile.setGradientScaleColor(GradientScaleType.SPEED.getColorTypeName(), dataItem.getGradientSpeedColor());
|
gpxFile.setGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), dataItem.getGradientSlopePalette());
|
||||||
}
|
gpxFile.setGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), dataItem.getGradientAltitudePalette());
|
||||||
if (dataItem.getGradientSlopeColor() != 0) {
|
|
||||||
gpxFile.setGradientScaleColor(GradientScaleType.SLOPE.getColorTypeName(), dataItem.getGradientSlopeColor());
|
|
||||||
}
|
|
||||||
if (dataItem.getGradientAltitudeColor() != 0) {
|
|
||||||
gpxFile.setGradientScaleColor(GradientScaleType.ALTITUDE.getColorTypeName(), dataItem.getGradientAltitudeColor());
|
|
||||||
}
|
|
||||||
if (dataItem.getGradientScaleType() != null) {
|
if (dataItem.getGradientScaleType() != null) {
|
||||||
gpxFile.setGradientScaleType(dataItem.getGradientScaleType().name());
|
gpxFile.setGradientScaleType(dataItem.getGradientScaleType().name());
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ public class EnumStringPreference<E extends Enum<E>> extends CommonPreference<E>
|
||||||
@Override
|
@Override
|
||||||
protected E getValue(Object prefs, E defaultValue) {
|
protected E getValue(Object prefs, E defaultValue) {
|
||||||
try {
|
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);
|
E value = parseString(name);
|
||||||
return value != null ? value : defaultValue;
|
return value != null ? value : defaultValue;
|
||||||
} catch (ClassCastException ex) {
|
} catch (ClassCastException ex) {
|
||||||
|
@ -23,7 +24,8 @@ public class EnumStringPreference<E extends Enum<E>> extends CommonPreference<E>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setValue(Object prefs, E val) {
|
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
|
@Override
|
||||||
|
|
|
@ -50,6 +50,7 @@ import net.osmand.plus.rastermaps.LayerTransparencySeekbarMode;
|
||||||
import net.osmand.plus.render.RendererRegistry;
|
import net.osmand.plus.render.RendererRegistry;
|
||||||
import net.osmand.plus.routing.RouteService;
|
import net.osmand.plus.routing.RouteService;
|
||||||
import net.osmand.plus.srtmplugin.TerrainMode;
|
import net.osmand.plus.srtmplugin.TerrainMode;
|
||||||
|
import net.osmand.plus.track.GradientScaleType;
|
||||||
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
|
import net.osmand.plus.views.layers.RadiusRulerControlLayer.RadiusRulerMode;
|
||||||
import net.osmand.plus.voice.CommandPlayer;
|
import net.osmand.plus.voice.CommandPlayer;
|
||||||
import net.osmand.plus.wikipedia.WikiArticleShowImages;
|
import net.osmand.plus.wikipedia.WikiArticleShowImages;
|
||||||
|
@ -1408,6 +1409,10 @@ public class OsmandSettings {
|
||||||
public final OsmandPreference<Long> LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal();
|
public final OsmandPreference<Long> LAST_UPDATES_CARD_REFRESH = new LongPreference(this, "last_updates_card_refresh", 0).makeGlobal();
|
||||||
|
|
||||||
public final CommonPreference<Integer> CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().makeShared().cache();
|
public final CommonPreference<Integer> CURRENT_TRACK_COLOR = new IntPreference(this, "current_track_color", 0).makeGlobal().makeShared().cache();
|
||||||
|
public final CommonPreference<GradientScaleType> CURRENT_TRACK_COLORIZATION = new EnumStringPreference<>(this, "current_track_colorization", null, GradientScaleType.values()).makeGlobal().makeShared().cache();
|
||||||
|
public final CommonPreference<String> CURRENT_TRACK_SPEED_GRADIENT_PALETTE = new StringPreference(this, "current_track_speed_gradient_palette", null).makeGlobal().makeShared().cache();
|
||||||
|
public final CommonPreference<String> CURRENT_TRACK_ALTITUDE_GRADIENT_PALETTE = new StringPreference(this, "current_track_altitude_gradient_palette", null).makeGlobal().makeShared().cache();
|
||||||
|
public final CommonPreference<String> CURRENT_TRACK_SLOPE_GRADIENT_PALETTE = new StringPreference(this, "current_track_slope_gradient_palette", null).makeGlobal().makeShared().cache();
|
||||||
public final CommonPreference<String> CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().makeShared().cache();
|
public final CommonPreference<String> CURRENT_TRACK_WIDTH = new StringPreference(this, "current_track_width", "").makeGlobal().makeShared().cache();
|
||||||
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().makeShared().cache();
|
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_ARROWS = new BooleanPreference(this, "current_track_show_arrows", false).makeGlobal().makeShared().cache();
|
||||||
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().makeShared().cache();
|
public final CommonPreference<Boolean> CURRENT_TRACK_SHOW_START_FINISH = new BooleanPreference(this, "current_track_show_start_finish", true).makeGlobal().makeShared().cache();
|
||||||
|
|
|
@ -17,9 +17,9 @@ public class GpxAppearanceInfo {
|
||||||
public String width;
|
public String width;
|
||||||
public GradientScaleType scaleType;
|
public GradientScaleType scaleType;
|
||||||
public int color;
|
public int color;
|
||||||
public int gradientSpeedColor;
|
public int[] gradientSpeedPalette;
|
||||||
public int gradientAltitudeColor;
|
public int[] gradientAltitudePalette;
|
||||||
public int gradientSlopeColor;
|
public int[] gradientSlopePalette;
|
||||||
public int splitType;
|
public int splitType;
|
||||||
public double splitInterval;
|
public double splitInterval;
|
||||||
public boolean showArrows;
|
public boolean showArrows;
|
||||||
|
@ -41,9 +41,9 @@ public class GpxAppearanceInfo {
|
||||||
splitType = dataItem.getSplitType();
|
splitType = dataItem.getSplitType();
|
||||||
splitInterval = dataItem.getSplitInterval();
|
splitInterval = dataItem.getSplitInterval();
|
||||||
scaleType = dataItem.getGradientScaleType();
|
scaleType = dataItem.getGradientScaleType();
|
||||||
gradientSpeedColor = dataItem.getGradientSpeedColor();
|
gradientSpeedPalette = dataItem.getGradientSpeedPalette();
|
||||||
gradientSlopeColor = dataItem.getGradientSlopeColor();
|
gradientSlopePalette = dataItem.getGradientSlopePalette();
|
||||||
gradientAltitudeColor = dataItem.getGradientAltitudeColor();
|
gradientAltitudePalette = dataItem.getGradientAltitudePalette();
|
||||||
|
|
||||||
GPXTrackAnalysis analysis = dataItem.getAnalysis();
|
GPXTrackAnalysis analysis = dataItem.getAnalysis();
|
||||||
if (analysis != null) {
|
if (analysis != null) {
|
||||||
|
@ -61,9 +61,9 @@ public class GpxAppearanceInfo {
|
||||||
writeParam(json, "split_type", GpxSplitType.getSplitTypeByTypeId(splitType).getTypeName());
|
writeParam(json, "split_type", GpxSplitType.getSplitTypeByTypeId(splitType).getTypeName());
|
||||||
writeParam(json, "split_interval", splitInterval);
|
writeParam(json, "split_interval", splitInterval);
|
||||||
writeParam(json, "gradient_scale_type", scaleType);
|
writeParam(json, "gradient_scale_type", scaleType);
|
||||||
writeParam(json, GradientScaleType.SPEED.getColorTypeName(), gradientSpeedColor);
|
writeParam(json, GradientScaleType.SPEED.getColorTypeName(), Algorithms.gradientPaletteToString(gradientSpeedPalette));
|
||||||
writeParam(json, GradientScaleType.SLOPE.getColorTypeName(), gradientSlopeColor);
|
writeParam(json, GradientScaleType.ALTITUDE.getColorTypeName(), Algorithms.gradientPaletteToString(gradientAltitudePalette));
|
||||||
writeParam(json, GradientScaleType.ALTITUDE.getColorTypeName(), gradientAltitudeColor);
|
writeParam(json, GradientScaleType.SLOPE.getColorTypeName(), Algorithms.gradientPaletteToString(gradientSlopePalette));
|
||||||
|
|
||||||
writeParam(json, "time_span", timeSpan);
|
writeParam(json, "time_span", timeSpan);
|
||||||
writeParam(json, "wpt_points", wptPoints);
|
writeParam(json, "wpt_points", wptPoints);
|
||||||
|
@ -79,9 +79,9 @@ public class GpxAppearanceInfo {
|
||||||
gpxAppearanceInfo.splitType = GpxSplitType.getSplitTypeByName(json.optString("split_type")).getType();
|
gpxAppearanceInfo.splitType = GpxSplitType.getSplitTypeByName(json.optString("split_type")).getType();
|
||||||
gpxAppearanceInfo.splitInterval = json.optDouble("split_interval");
|
gpxAppearanceInfo.splitInterval = json.optDouble("split_interval");
|
||||||
gpxAppearanceInfo.scaleType = getScaleType(json.optString("gradient_scale_type"));
|
gpxAppearanceInfo.scaleType = getScaleType(json.optString("gradient_scale_type"));
|
||||||
gpxAppearanceInfo.gradientSpeedColor = json.optInt(GradientScaleType.SPEED.getColorTypeName());
|
gpxAppearanceInfo.gradientSpeedPalette = getGradientPalette(json, GradientScaleType.SPEED);
|
||||||
gpxAppearanceInfo.gradientSlopeColor = json.optInt(GradientScaleType.SLOPE.getColorTypeName());
|
gpxAppearanceInfo.gradientAltitudePalette = getGradientPalette(json, GradientScaleType.ALTITUDE);
|
||||||
gpxAppearanceInfo.gradientAltitudeColor = json.optInt(GradientScaleType.ALTITUDE.getColorTypeName());
|
gpxAppearanceInfo.gradientSlopePalette = getGradientPalette(json, GradientScaleType.SLOPE);
|
||||||
|
|
||||||
gpxAppearanceInfo.timeSpan = json.optLong("time_span");
|
gpxAppearanceInfo.timeSpan = json.optLong("time_span");
|
||||||
gpxAppearanceInfo.wptPoints = json.optInt("wpt_points");
|
gpxAppearanceInfo.wptPoints = json.optInt("wpt_points");
|
||||||
|
@ -101,6 +101,10 @@ public class GpxAppearanceInfo {
|
||||||
return null;
|
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 {
|
private static void writeParam(@NonNull JSONObject json, @NonNull String name, @Nullable Object value) throws JSONException {
|
||||||
if (value instanceof Integer) {
|
if (value instanceof Integer) {
|
||||||
if ((Integer) value != 0) {
|
if ((Integer) value != 0) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import net.osmand.plus.GpxDbHelper;
|
||||||
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.track.GpxSplitType;
|
import net.osmand.plus.track.GpxSplitType;
|
||||||
|
import net.osmand.plus.track.GradientScaleType;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -83,6 +84,9 @@ public class GpxSettingsItem extends FileSettingsItem {
|
||||||
gpxDbHelper.updateShowStartFinish(dataItem, appearanceInfo.showStartFinish);
|
gpxDbHelper.updateShowStartFinish(dataItem, appearanceInfo.showStartFinish);
|
||||||
gpxDbHelper.updateSplit(dataItem, splitType, appearanceInfo.splitInterval);
|
gpxDbHelper.updateSplit(dataItem, splitType, appearanceInfo.splitInterval);
|
||||||
gpxDbHelper.updateGradientScaleType(dataItem, appearanceInfo.scaleType);
|
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() {
|
private void createGpxAppearanceInfo() {
|
||||||
|
|
84
OsmAnd/src/net/osmand/plus/track/GradientCard.java
Normal file
84
OsmAnd/src/net/osmand/plus/track/GradientCard.java
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.router.RouteColorize.ColorizationType;
|
||||||
|
|
||||||
public enum GradientScaleType {
|
public enum GradientScaleType {
|
||||||
|
|
||||||
|
@ -44,6 +45,18 @@ public enum GradientScaleType {
|
||||||
return ctx.getString(resId);
|
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) {
|
public static GradientScaleType getGradientTypeByName(@NonNull String name) {
|
||||||
for (GradientScaleType scaleType : GradientScaleType.values()) {
|
for (GradientScaleType scaleType : GradientScaleType.values()) {
|
||||||
if (scaleType.name().equalsIgnoreCase(name)) {
|
if (scaleType.name().equalsIgnoreCase(name)) {
|
||||||
|
|
|
@ -15,14 +15,6 @@ import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ScrollView;
|
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.AndroidUtils;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
@ -60,6 +52,14 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
|
||||||
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD;
|
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_BOLD;
|
||||||
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM;
|
import static net.osmand.plus.dialogs.GpxAppearanceAdapter.TRACK_WIDTH_MEDIUM;
|
||||||
|
@ -89,6 +89,7 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
private SplitIntervalCard splitIntervalCard;
|
private SplitIntervalCard splitIntervalCard;
|
||||||
private TrackColoringCard trackColoringCard;
|
private TrackColoringCard trackColoringCard;
|
||||||
private ColorsCard colorsCard;
|
private ColorsCard colorsCard;
|
||||||
|
private GradientCard gradientCard;
|
||||||
private boolean showStartFinishIconsInitialValue;
|
private boolean showStartFinishIconsInitialValue;
|
||||||
|
|
||||||
private ImageView trackIcon;
|
private ImageView trackIcon;
|
||||||
|
@ -158,6 +159,10 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
if (selectedGpxFile.isShowCurrentTrack()) {
|
if (selectedGpxFile.isShowCurrentTrack()) {
|
||||||
trackDrawInfo = new TrackDrawInfo(true);
|
trackDrawInfo = new TrackDrawInfo(true);
|
||||||
trackDrawInfo.setColor(app.getSettings().CURRENT_TRACK_COLOR.get());
|
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.setWidth(app.getSettings().CURRENT_TRACK_WIDTH.get());
|
||||||
trackDrawInfo.setShowArrows(app.getSettings().CURRENT_TRACK_SHOW_ARROWS.get());
|
trackDrawInfo.setShowArrows(app.getSettings().CURRENT_TRACK_SHOW_ARROWS.get());
|
||||||
trackDrawInfo.setShowStartFinish(app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.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 (mapActivity != null) {
|
||||||
if (card instanceof SplitIntervalCard) {
|
if (card instanceof SplitIntervalCard) {
|
||||||
SplitIntervalBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), trackDrawInfo, this);
|
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) {
|
} else if (card instanceof ColorsCard) {
|
||||||
int color = ((ColorsCard) card).getSelectedColor();
|
int color = ((ColorsCard) card).getSelectedColor();
|
||||||
trackDrawInfo.setColor(color);
|
trackDrawInfo.setColor(color);
|
||||||
|
@ -555,6 +570,9 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
if (trackWidthCard != null) {
|
if (trackWidthCard != null) {
|
||||||
trackWidthCard.updateItems();
|
trackWidthCard.updateItems();
|
||||||
}
|
}
|
||||||
|
if (trackColoringCard != null) {
|
||||||
|
trackColoringCard.updateColor();
|
||||||
|
}
|
||||||
MapActivity mapActivity = getMapActivity();
|
MapActivity mapActivity = getMapActivity();
|
||||||
if (mapActivity != null) {
|
if (mapActivity != null) {
|
||||||
mapActivity.refreshMap();
|
mapActivity.refreshMap();
|
||||||
|
@ -565,12 +583,19 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||||
if (gpxFile.showCurrentTrack) {
|
if (gpxFile.showCurrentTrack) {
|
||||||
app.getSettings().CURRENT_TRACK_COLOR.set(trackDrawInfo.getColor());
|
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_WIDTH.set(trackDrawInfo.getWidth());
|
||||||
app.getSettings().CURRENT_TRACK_SHOW_ARROWS.set(trackDrawInfo.isShowArrows());
|
app.getSettings().CURRENT_TRACK_SHOW_ARROWS.set(trackDrawInfo.isShowArrows());
|
||||||
app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.set(trackDrawInfo.isShowStartFinish());
|
app.getSettings().CURRENT_TRACK_SHOW_START_FINISH.set(trackDrawInfo.isShowStartFinish());
|
||||||
} else if (gpxDataItem != null) {
|
} else if (gpxDataItem != null) {
|
||||||
GpxSplitType splitType = GpxSplitType.getSplitTypeByTypeId(trackDrawInfo.getSplitType());
|
GpxSplitType splitType = GpxSplitType.getSplitTypeByTypeId(trackDrawInfo.getSplitType());
|
||||||
gpxDbHelper.updateColor(gpxDataItem, trackDrawInfo.getColor());
|
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.updateWidth(gpxDataItem, trackDrawInfo.getWidth());
|
||||||
gpxDbHelper.updateShowArrows(gpxDataItem, trackDrawInfo.isShowArrows());
|
gpxDbHelper.updateShowArrows(gpxDataItem, trackDrawInfo.isShowArrows());
|
||||||
// gpxDbHelper.updateShowStartFinish(gpxDataItem, trackDrawInfo.isShowStartFinish());
|
// gpxDbHelper.updateShowStartFinish(gpxDataItem, trackDrawInfo.isShowStartFinish());
|
||||||
|
@ -642,12 +667,15 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
showStartFinishCard.setListener(this);
|
showStartFinishCard.setListener(this);
|
||||||
cardsContainer.addView(showStartFinishCard.build(mapActivity));
|
cardsContainer.addView(showStartFinishCard.build(mapActivity));
|
||||||
|
|
||||||
trackColoringCard = new TrackColoringCard(mapActivity, trackDrawInfo, this);
|
trackColoringCard = new TrackColoringCard(mapActivity, selectedGpxFile.getTrackAnalysis(app), trackDrawInfo);
|
||||||
trackColoringCard.setListener(this);
|
trackColoringCard.setListener(this);
|
||||||
cardsContainer.addView(trackColoringCard.build(mapActivity));
|
cardsContainer.addView(trackColoringCard.build(mapActivity));
|
||||||
|
|
||||||
setupColorsCard(cardsContainer);
|
setupColorsCard(cardsContainer);
|
||||||
|
|
||||||
|
gradientCard = new GradientCard(mapActivity, selectedGpxFile.getTrackAnalysis(app), trackDrawInfo.getGradientScaleType());
|
||||||
|
cardsContainer.addView(gradientCard.build(mapActivity));
|
||||||
|
|
||||||
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() {
|
trackWidthCard = new TrackWidthCard(mapActivity, trackDrawInfo, new OnNeedScrollListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -674,7 +702,8 @@ public class TrackAppearanceFragment extends ContextMenuScrollFragment implement
|
||||||
List<Integer> colors = getTrackColors();
|
List<Integer> colors = getTrackColors();
|
||||||
colorsCard = new ColorsCard(mapActivity, trackDrawInfo.getColor(), this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null);
|
colorsCard = new ColorsCard(mapActivity, trackDrawInfo.getColor(), this, colors, app.getSettings().CUSTOM_TRACK_COLORS, null);
|
||||||
colorsCard.setListener(this);
|
colorsCard.setListener(this);
|
||||||
cardsContainer.addView(colorsCard.build(mapActivity));
|
AndroidUiHelper.updateVisibility(colorsCard.build(mapActivity), trackDrawInfo.getGradientScaleType() == null);
|
||||||
|
cardsContainer.addView(colorsCard.getView());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package net.osmand.plus.track;
|
package net.osmand.plus.track;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -7,14 +8,10 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
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 net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.UiUtilities;
|
import net.osmand.plus.UiUtilities;
|
||||||
|
@ -27,26 +24,29 @@ import org.apache.commons.logging.Log;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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 final static String SOLID_COLOR = "solid_color";
|
||||||
private static final Log log = PlatformUtil.getLog(TrackColoringCard.class);
|
private static final Log log = PlatformUtil.getLog(TrackColoringCard.class);
|
||||||
|
|
||||||
|
private GPXTrackAnalysis gpxTrackAnalysis;
|
||||||
private TrackDrawInfo trackDrawInfo;
|
private TrackDrawInfo trackDrawInfo;
|
||||||
|
|
||||||
private TrackColoringAdapter coloringAdapter;
|
private TrackColoringAdapter coloringAdapter;
|
||||||
private TrackAppearanceItem selectedAppearanceItem;
|
private TrackAppearanceItem selectedAppearanceItem;
|
||||||
private List<TrackAppearanceItem> appearanceItems;
|
private List<TrackAppearanceItem> appearanceItems;
|
||||||
|
|
||||||
private Fragment target;
|
public TrackColoringCard(MapActivity mapActivity, GPXTrackAnalysis gpxTrackAnalysis, TrackDrawInfo trackDrawInfo) {
|
||||||
|
|
||||||
public TrackColoringCard(MapActivity mapActivity, TrackDrawInfo trackDrawInfo, Fragment target) {
|
|
||||||
super(mapActivity);
|
super(mapActivity);
|
||||||
this.target = target;
|
|
||||||
this.trackDrawInfo = trackDrawInfo;
|
this.trackDrawInfo = trackDrawInfo;
|
||||||
appearanceItems = getGradientAppearanceItems();
|
this.gpxTrackAnalysis = gpxTrackAnalysis;
|
||||||
|
appearanceItems = getTrackAppearanceItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,25 +58,44 @@ public class TrackColoringCard extends BaseCard {
|
||||||
protected void updateContent() {
|
protected void updateContent() {
|
||||||
updateHeader();
|
updateHeader();
|
||||||
|
|
||||||
// coloringAdapter = new TrackColoringAdapter(appearanceItems);
|
coloringAdapter = new TrackColoringAdapter(appearanceItems);
|
||||||
// RecyclerView groupRecyclerView = view.findViewById(R.id.recycler_view);
|
RecyclerView groupRecyclerView = view.findViewById(R.id.recycler_view);
|
||||||
// groupRecyclerView.setAdapter(coloringAdapter);
|
groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
||||||
// groupRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
|
groupRecyclerView.setAdapter(coloringAdapter);
|
||||||
|
|
||||||
AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider());
|
AndroidUiHelper.updateVisibility(view.findViewById(R.id.top_divider), isShowDivider());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TrackAppearanceItem> 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<TrackAppearanceItem> getTrackAppearanceItems() {
|
||||||
List<TrackAppearanceItem> items = new ArrayList<>();
|
List<TrackAppearanceItem> items = new ArrayList<>();
|
||||||
items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle));
|
items.add(new TrackAppearanceItem(SOLID_COLOR, app.getString(R.string.track_coloring_solid), R.drawable.ic_action_circle, true));
|
||||||
|
for (GradientScaleType scaleType : GradientScaleType.values()) {
|
||||||
// for (GradientScaleType scaleType : GradientScaleType.values()) {
|
items.add(new TrackAppearanceItem(scaleType.getTypeName(),
|
||||||
// items.add(new TrackAppearanceItem(scaleType.getTypeName(), scaleType.getHumanString(app), scaleType.getIconId()));
|
scaleType.getHumanString(app), scaleType.getIconId(), isScaleTypeActive(scaleType)));
|
||||||
// }
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isScaleTypeActive(GradientScaleType scaleType) {
|
||||||
|
if (scaleType == GradientScaleType.SPEED) {
|
||||||
|
return gpxTrackAnalysis.isSpeedSpecified();
|
||||||
|
} else {
|
||||||
|
return gpxTrackAnalysis.isElevationSpecified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private TrackAppearanceItem getSelectedAppearanceItem() {
|
private TrackAppearanceItem getSelectedAppearanceItem() {
|
||||||
if (selectedAppearanceItem == null) {
|
if (selectedAppearanceItem == null) {
|
||||||
GradientScaleType scaleType = trackDrawInfo.getGradientScaleType();
|
GradientScaleType scaleType = trackDrawInfo.getGradientScaleType();
|
||||||
|
@ -98,27 +117,22 @@ public class TrackColoringCard extends BaseCard {
|
||||||
headerView.setBackgroundDrawable(null);
|
headerView.setBackgroundDrawable(null);
|
||||||
|
|
||||||
TextView titleView = view.findViewById(R.id.title);
|
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);
|
TextView descriptionView = view.findViewById(R.id.description);
|
||||||
descriptionView.setText(getSelectedAppearanceItem().getLocalizedValue());
|
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) {
|
public void setGradientScaleType(TrackAppearanceItem item) {
|
||||||
|
selectedAppearanceItem = item;
|
||||||
if (item.getAttrName().equals(SOLID_COLOR)) {
|
if (item.getAttrName().equals(SOLID_COLOR)) {
|
||||||
trackDrawInfo.setGradientScaleType(null);
|
trackDrawInfo.setGradientScaleType(null);
|
||||||
} else {
|
} else {
|
||||||
trackDrawInfo.setGradientScaleType(GradientScaleType.valueOf(item.getAttrName()));
|
trackDrawInfo.setGradientScaleType(GradientScaleType.valueOf(item.getAttrName().toUpperCase()));
|
||||||
}
|
}
|
||||||
mapActivity.refreshMap();
|
mapActivity.refreshMap();
|
||||||
|
|
||||||
updateHeader();
|
updateHeader();
|
||||||
updateColorSelector();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TrackColoringAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
private class TrackColoringAdapter extends RecyclerView.Adapter<TrackAppearanceViewHolder> {
|
||||||
|
@ -136,42 +150,38 @@ public class TrackColoringCard extends BaseCard {
|
||||||
View view = themedInflater.inflate(R.layout.point_editor_group_select_item, parent, false);
|
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().width = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_width);
|
||||||
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
view.getLayoutParams().height = app.getResources().getDimensionPixelSize(R.dimen.gpx_group_button_height);
|
||||||
|
return new TrackAppearanceViewHolder(view);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final TrackAppearanceViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final TrackAppearanceViewHolder holder, int position) {
|
||||||
TrackAppearanceItem item = items.get(position);
|
final TrackAppearanceItem item = items.get(position);
|
||||||
holder.title.setText(item.getLocalizedValue());
|
|
||||||
|
|
||||||
updateButtonBg(holder, item);
|
if (item.isActive() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
AndroidUtils.setBackground(app, holder.button, nightMode, R.drawable.ripple_solid_light_6dp,
|
||||||
int colorId;
|
R.drawable.ripple_solid_dark_6dp);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
|
if (!item.isActive()) {
|
||||||
|
showSnackbar(view, item.getAttrName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int prevSelectedPosition = getItemPosition(getSelectedAppearanceItem());
|
int prevSelectedPosition = getItemPosition(getSelectedAppearanceItem());
|
||||||
selectedAppearanceItem = items.get(holder.getAdapterPosition());
|
selectedAppearanceItem = items.get(holder.getAdapterPosition());
|
||||||
notifyItemChanged(holder.getAdapterPosition());
|
notifyItemChanged(holder.getAdapterPosition());
|
||||||
notifyItemChanged(prevSelectedPosition);
|
notifyItemChanged(prevSelectedPosition);
|
||||||
|
|
||||||
setGradientScaleType(selectedAppearanceItem);
|
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) {
|
private void updateButtonBg(TrackAppearanceViewHolder holder, TrackAppearanceItem item) {
|
||||||
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
GradientDrawable rectContourDrawable = (GradientDrawable) AppCompatResources.getDrawable(app, R.drawable.bg_select_group_button_outline);
|
||||||
if (rectContourDrawable != null) {
|
if (rectContourDrawable != null) {
|
||||||
if (getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item)) {
|
Context ctx = holder.itemView.getContext();
|
||||||
int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light);
|
boolean itemSelected = getSelectedAppearanceItem() != null && getSelectedAppearanceItem().equals(item);
|
||||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 2), strokeColor);
|
|
||||||
|
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 {
|
} else {
|
||||||
int strokeColor = ContextCompat.getColor(app, nightMode ? R.color.stroked_buttons_and_links_outline_dark
|
strokeColor = AndroidUtils.getColorFromAttr(ctx, R.attr.stroked_buttons_and_links_outline);
|
||||||
: R.color.stroked_buttons_and_links_outline_light);
|
backgroundColor = 0;
|
||||||
rectContourDrawable.setStroke(AndroidUtils.dpToPx(app, 1), strokeColor);
|
strokeWidth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rectContourDrawable.mutate();
|
||||||
|
rectContourDrawable.setColor(backgroundColor);
|
||||||
|
rectContourDrawable.setStroke(AndroidUtils.dpToPx(ctx, strokeWidth), strokeColor);
|
||||||
holder.button.setImageDrawable(rectContourDrawable);
|
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
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return items.size();
|
return items.size();
|
||||||
|
@ -209,10 +273,13 @@ public class TrackColoringCard extends BaseCard {
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
private int iconId;
|
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.attrName = attrName;
|
||||||
this.localizedValue = localizedValue;
|
this.localizedValue = localizedValue;
|
||||||
this.iconId = iconId;
|
this.iconId = iconId;
|
||||||
|
this.isActive = isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAttrName() {
|
public String getAttrName() {
|
||||||
|
@ -226,5 +293,9 @@ public class TrackColoringCard extends BaseCard {
|
||||||
public int getIconId() {
|
public int getIconId() {
|
||||||
return iconId;
|
return iconId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,6 +26,9 @@ public class TrackDrawInfo {
|
||||||
private String width;
|
private String width;
|
||||||
private GradientScaleType gradientScaleType;
|
private GradientScaleType gradientScaleType;
|
||||||
private int color;
|
private int color;
|
||||||
|
private int[] speedGradientPalette;
|
||||||
|
private int[] altitudeGradientPalette;
|
||||||
|
private int[] slopeGradientPalette;
|
||||||
private int splitType;
|
private int splitType;
|
||||||
private double splitInterval;
|
private double splitInterval;
|
||||||
private boolean joinSegments;
|
private boolean joinSegments;
|
||||||
|
@ -44,8 +47,11 @@ public class TrackDrawInfo {
|
||||||
public TrackDrawInfo(@NonNull OsmandApplication app, @NonNull GpxDataItem gpxDataItem, boolean currentRecording) {
|
public TrackDrawInfo(@NonNull OsmandApplication app, @NonNull GpxDataItem gpxDataItem, boolean currentRecording) {
|
||||||
filePath = gpxDataItem.getFile().getPath();
|
filePath = gpxDataItem.getFile().getPath();
|
||||||
width = gpxDataItem.getWidth();
|
width = gpxDataItem.getWidth();
|
||||||
gradientScaleType = gpxDataItem.getGradientScaleType();
|
|
||||||
color = gpxDataItem.getColor();
|
color = gpxDataItem.getColor();
|
||||||
|
gradientScaleType = gpxDataItem.getGradientScaleType();
|
||||||
|
speedGradientPalette = gpxDataItem.getGradientSpeedPalette();
|
||||||
|
altitudeGradientPalette = gpxDataItem.getGradientAltitudePalette();
|
||||||
|
slopeGradientPalette = gpxDataItem.getGradientSlopePalette();
|
||||||
splitType = gpxDataItem.getSplitType();
|
splitType = gpxDataItem.getSplitType();
|
||||||
splitInterval = gpxDataItem.getSplitInterval();
|
splitInterval = gpxDataItem.getSplitInterval();
|
||||||
joinSegments = gpxDataItem.isJoinSegments();
|
joinSegments = gpxDataItem.isJoinSegments();
|
||||||
|
@ -82,6 +88,40 @@ public class TrackDrawInfo {
|
||||||
this.color = color;
|
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() {
|
public int getSplitType() {
|
||||||
return splitType;
|
return splitType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package net.osmand.plus.views;
|
package net.osmand.plus.views;
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Shader;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import net.osmand.GPXUtilities;
|
import net.osmand.GPXUtilities;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.data.RotatedTileBox;
|
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.plus.views.layers.geometry.GpxGeometryWay;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
|
||||||
public class Renderable {
|
public class Renderable {
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ public class Renderable {
|
||||||
protected double zoom = -1;
|
protected double zoom = -1;
|
||||||
protected AsynchronousResampler culler = null; // The currently active resampler
|
protected AsynchronousResampler culler = null; // The currently active resampler
|
||||||
protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use
|
protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use
|
||||||
|
protected GradientScaleType scaleType = null;
|
||||||
|
|
||||||
protected GpxGeometryWay geometryWay;
|
protected GpxGeometryWay geometryWay;
|
||||||
|
|
||||||
|
@ -85,6 +88,10 @@ public class Renderable {
|
||||||
paint.setStrokeWidth(p.getStrokeWidth());
|
paint.setStrokeWidth(p.getStrokeWidth());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGradientScaleType(GradientScaleType type) {
|
||||||
|
this.scaleType = type;
|
||||||
|
}
|
||||||
|
|
||||||
public GpxGeometryWay getGeometryWay() {
|
public GpxGeometryWay getGeometryWay() {
|
||||||
return geometryWay;
|
return geometryWay;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +102,20 @@ public class Renderable {
|
||||||
|
|
||||||
protected abstract void startCuller(double newZoom);
|
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) {
|
public void drawSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
||||||
|
@ -124,18 +144,14 @@ public class Renderable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void draw(List<WptPt> pts, Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
protected void drawSolid(List<WptPt> 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();
|
QuadRect tileBounds = tileBox.getLatLonBounds();
|
||||||
WptPt lastPt = pts.get(0);
|
WptPt lastPt = pts.get(0);
|
||||||
boolean recalculateLastXY = true;
|
boolean recalculateLastXY = true;
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
for (int i = 1; i < pts.size(); i++) {
|
for (int i = 1; i < pts.size(); i++) {
|
||||||
WptPt pt = pts.get(i);
|
WptPt pt = pts.get(i);
|
||||||
if (Math.min(pt.lon, lastPt.lon) < tileBounds.right && Math.max(pt.lon, lastPt.lon) > tileBounds.left
|
if (arePointsInsideTile(pt, lastPt, tileBounds)) {
|
||||||
&& Math.min(pt.lat, lastPt.lat) < tileBounds.top && Math.max(pt.lat, lastPt.lat) > tileBounds.bottom) {
|
|
||||||
if (recalculateLastXY) {
|
if (recalculateLastXY) {
|
||||||
recalculateLastXY = false;
|
recalculateLastXY = false;
|
||||||
float lastX = tileBox.getPixXFromLatLon(lastPt.lat, lastPt.lon);
|
float lastX = tileBox.getPixXFromLatLon(lastPt.lat, lastPt.lon);
|
||||||
|
@ -157,8 +173,36 @@ public class Renderable {
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
canvas.drawPath(path, paint);
|
canvas.drawPath(path, paint);
|
||||||
}
|
}
|
||||||
canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void drawGradient(List<WptPt> 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);
|
||||||
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
public static class CurrentTrack extends RenderableSegment {
|
||||||
|
@ -213,9 +253,5 @@ public class Renderable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void startCuller(double newZoom) {}
|
@Override protected void startCuller(double newZoom) {}
|
||||||
|
|
||||||
@Override public void drawSingleSegment(double zoom, Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
|
||||||
draw(points, p, canvas, tileBox);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import net.osmand.plus.render.OsmandRenderer;
|
||||||
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
|
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
|
||||||
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
|
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
|
||||||
import net.osmand.plus.settings.backend.CommonPreference;
|
import net.osmand.plus.settings.backend.CommonPreference;
|
||||||
|
import net.osmand.plus.track.GradientScaleType;
|
||||||
import net.osmand.plus.track.SaveGpxAsyncTask;
|
import net.osmand.plus.track.SaveGpxAsyncTask;
|
||||||
import net.osmand.plus.track.TrackDrawInfo;
|
import net.osmand.plus.track.TrackDrawInfo;
|
||||||
import net.osmand.plus.views.OsmandMapLayer;
|
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.RenderingRuleProperty;
|
||||||
import net.osmand.render.RenderingRuleSearchRequest;
|
import net.osmand.render.RenderingRuleSearchRequest;
|
||||||
import net.osmand.render.RenderingRulesStorage;
|
import net.osmand.render.RenderingRulesStorage;
|
||||||
|
import net.osmand.router.RouteColorize;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
|
@ -142,6 +144,10 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
private CommonPreference<String> defaultTrackWidthPref;
|
private CommonPreference<String> defaultTrackWidthPref;
|
||||||
|
|
||||||
private CommonPreference<Integer> currentTrackColorPref;
|
private CommonPreference<Integer> currentTrackColorPref;
|
||||||
|
private CommonPreference<GradientScaleType> currentTrackScaleType;
|
||||||
|
private CommonPreference<String> currentTrackSpeedGradientPalette;
|
||||||
|
private CommonPreference<String> currentTrackAltitudeGradientPalette;
|
||||||
|
private CommonPreference<String> currentTrackSlopeGradientPalette;
|
||||||
private CommonPreference<String> currentTrackWidthPref;
|
private CommonPreference<String> currentTrackWidthPref;
|
||||||
private CommonPreference<Boolean> currentTrackShowArrowsPref;
|
private CommonPreference<Boolean> currentTrackShowArrowsPref;
|
||||||
private CommonPreference<Boolean> currentTrackShowStartFinishPref;
|
private CommonPreference<Boolean> currentTrackShowStartFinishPref;
|
||||||
|
@ -155,6 +161,10 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer();
|
osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer();
|
||||||
|
|
||||||
currentTrackColorPref = view.getSettings().CURRENT_TRACK_COLOR;
|
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;
|
currentTrackWidthPref = view.getSettings().CURRENT_TRACK_WIDTH;
|
||||||
currentTrackShowArrowsPref = view.getSettings().CURRENT_TRACK_SHOW_ARROWS;
|
currentTrackShowArrowsPref = view.getSettings().CURRENT_TRACK_SHOW_ARROWS;
|
||||||
currentTrackShowStartFinishPref = view.getSettings().CURRENT_TRACK_SHOW_START_FINISH;
|
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,
|
private void drawSelectedFileSegments(SelectedGpxFile selectedGpxFile, boolean currentTrack, Canvas canvas,
|
||||||
RotatedTileBox tileBox, DrawSettings settings) {
|
RotatedTileBox tileBox, DrawSettings settings) {
|
||||||
|
GPXFile gpxFile = selectedGpxFile.getGpxFile();
|
||||||
List<TrkSegment> segments = selectedGpxFile.getPointsToDisplay();
|
List<TrkSegment> segments = selectedGpxFile.getPointsToDisplay();
|
||||||
|
GradientScaleType scaleType = getGradientScaleType(gpxFile);
|
||||||
|
List<RouteColorize.RouteColorizationPoint> 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) {
|
for (TrkSegment ts : segments) {
|
||||||
String width = getTrackWidthName(selectedGpxFile.getGpxFile(), defaultTrackWidthPref.get());
|
String width = getTrackWidthName(gpxFile, defaultTrackWidthPref.get());
|
||||||
int color = getTrackColor(selectedGpxFile.getGpxFile(), ts.getColor(cachedColor));
|
int color = getTrackColor(gpxFile, ts.getColor(cachedColor));
|
||||||
|
if (colorsOfPoints != null) {
|
||||||
|
startIdx = setColorsToPoints(ts, colorsOfPoints, scaleType, startIdx);
|
||||||
|
}
|
||||||
if (ts.renderer == null && !ts.points.isEmpty()) {
|
if (ts.renderer == null && !ts.points.isEmpty()) {
|
||||||
Renderable.RenderableSegment renderer;
|
Renderable.RenderableSegment renderer;
|
||||||
if (currentTrack) {
|
if (currentTrack) {
|
||||||
|
@ -677,11 +699,43 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
}
|
}
|
||||||
updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox);
|
updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox);
|
||||||
if (ts.renderer instanceof Renderable.RenderableSegment) {
|
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<RouteColorize.RouteColorizationPoint> 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) {
|
private float getTrackWidth(String width, float defaultTrackWidth) {
|
||||||
Float trackWidth = cachedTrackWidth.get(width);
|
Float trackWidth = cachedTrackWidth.get(width);
|
||||||
return trackWidth != null ? trackWidth : defaultTrackWidth;
|
return trackWidth != null ? trackWidth : defaultTrackWidth;
|
||||||
|
@ -702,6 +756,47 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
||||||
return color != 0 ? color : defaultColor;
|
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) {
|
private String getTrackWidthName(GPXFile gpxFile, String defaultWidth) {
|
||||||
String width = null;
|
String width = null;
|
||||||
if (hasTrackDrawInfoForTrack(gpxFile)) {
|
if (hasTrackDrawInfoForTrack(gpxFile)) {
|
||||||
|
|
Loading…
Reference in a new issue