Merge pull request #6585 from osmandapp/issue_6499_timescale
Issue 6499 timescale
This commit is contained in:
commit
9135f9d169
4 changed files with 75 additions and 30 deletions
|
@ -9,7 +9,12 @@
|
||||||
3. If you modify the English strings file, please add new strings at the top of the file, this makes periodic reviews before releases easier.
|
3. If you modify the English strings file, please add new strings at the top of the file, this makes periodic reviews before releases easier.
|
||||||
- For wording and consistency, please note https://osmand.net/help-online?id=technical-articles#Creating_a_Consistent_User_Experience
|
- For wording and consistency, please note https://osmand.net/help-online?id=technical-articles#Creating_a_Consistent_User_Experience
|
||||||
Thx - Hardy
|
Thx - Hardy
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<string name="time_of_day">Time of day</string>
|
||||||
|
<string name="add_destination_query">Please add Destination first</string>
|
||||||
<string name="by_transport_type">By %1$s</string>
|
<string name="by_transport_type">By %1$s</string>
|
||||||
<string name="step_by_step">Step by step</string>
|
<string name="step_by_step">Step by step</string>
|
||||||
<string name="road_types">Road types</string>
|
<string name="road_types">Road types</string>
|
||||||
|
|
|
@ -74,6 +74,12 @@ public class OsmAndFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFormattedTimeShort(long seconds) {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(seconds * 1000);
|
||||||
|
return SIMPLE_TIME_OF_DAY_FORMAT.format(calendar.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
public static String getFormattedDate(Context context, long milliseconds) {
|
public static String getFormattedDate(Context context, long milliseconds) {
|
||||||
return DateUtils.formatDateTime(context, milliseconds, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
|
return DateUtils.formatDateTime(context, milliseconds, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ import net.osmand.AndroidUtils;
|
||||||
import net.osmand.CallbackWithObject;
|
import net.osmand.CallbackWithObject;
|
||||||
import net.osmand.IndexConstants;
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
|
import net.osmand.PlatformUtil;
|
||||||
import net.osmand.plus.ContextMenuAdapter;
|
import net.osmand.plus.ContextMenuAdapter;
|
||||||
import net.osmand.plus.ContextMenuItem;
|
import net.osmand.plus.ContextMenuItem;
|
||||||
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
import net.osmand.plus.GPXDatabase.GpxDataItem;
|
||||||
|
@ -107,6 +108,7 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
import static com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM;
|
import static com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM;
|
||||||
import static net.osmand.binary.RouteDataObject.HEIGHT_UNDEFINED;
|
import static net.osmand.binary.RouteDataObject.HEIGHT_UNDEFINED;
|
||||||
|
@ -123,6 +125,7 @@ import static net.osmand.plus.download.DownloadActivity.formatMb;
|
||||||
public class GpxUiHelper {
|
public class GpxUiHelper {
|
||||||
|
|
||||||
private static final int OPEN_GPX_DOCUMENT_REQUEST = 1005;
|
private static final int OPEN_GPX_DOCUMENT_REQUEST = 1005;
|
||||||
|
private static final Log LOG = PlatformUtil.getLog(GpxUiHelper.class);
|
||||||
|
|
||||||
public static String getDescription(OsmandApplication app, GPXFile result, File f, boolean html) {
|
public static String getDescription(OsmandApplication app, GPXFile result, File f, boolean html) {
|
||||||
GPXTrackAnalysis analysis = result.getAnalysis(f == null ? 0 : f.lastModified());
|
GPXTrackAnalysis analysis = result.getAnalysis(f == null ? 0 : f.lastModified());
|
||||||
|
@ -1124,11 +1127,9 @@ public class GpxUiHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float setupXAxisTime(XAxis xAxis, long timeSpan) {
|
private static float setupXAxisTime(XAxis xAxis, long timeSpan) {
|
||||||
|
|
||||||
final boolean useHours = timeSpan / 3600000 > 0;
|
final boolean useHours = timeSpan / 3600000 > 0;
|
||||||
xAxis.setGranularity(1f);
|
xAxis.setGranularity(1f);
|
||||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFormattedValue(float value, AxisBase axis) {
|
public String getFormattedValue(float value, AxisBase axis) {
|
||||||
int seconds = (int)value;
|
int seconds = (int)value;
|
||||||
|
@ -1148,6 +1149,18 @@ public class GpxUiHelper {
|
||||||
return 1f;
|
return 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float setupXAxisTimeOfDay(XAxis xAxis, final long startTime) {
|
||||||
|
xAxis.setGranularity(1f);
|
||||||
|
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||||
|
@Override
|
||||||
|
public String getFormattedValue(float value, AxisBase axis) {
|
||||||
|
long seconds = (long) (startTime/1000 + value);
|
||||||
|
return OsmAndFormatter.getFormattedTimeShort(seconds);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
private static List<Entry> calculateElevationArray(GPXTrackAnalysis analysis, GPXDataSetAxisType axisType,
|
private static List<Entry> calculateElevationArray(GPXTrackAnalysis analysis, GPXDataSetAxisType axisType,
|
||||||
float divX, float convEle) {
|
float divX, float convEle) {
|
||||||
List<Entry> values = new ArrayList<>();
|
List<Entry> values = new ArrayList<>();
|
||||||
|
@ -1165,7 +1178,11 @@ public class GpxUiHelper {
|
||||||
float x;
|
float x;
|
||||||
for (Elevation e : elevationData) {
|
for (Elevation e : elevationData) {
|
||||||
i++;
|
i++;
|
||||||
x = axisType == GPXDataSetAxisType.TIME ? e.time : e.distance;
|
if (axisType == GPXDataSetAxisType.TIME || axisType == GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
|
x = e.time;
|
||||||
|
} else {
|
||||||
|
x = e.distance;
|
||||||
|
}
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
nextX += x / divX;
|
nextX += x / divX;
|
||||||
if (!Float.isNaN(e.elevation)) {
|
if (!Float.isNaN(e.elevation)) {
|
||||||
|
@ -1323,6 +1340,8 @@ public class GpxUiHelper {
|
||||||
XAxis xAxis = mChart.getXAxis();
|
XAxis xAxis = mChart.getXAxis();
|
||||||
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
||||||
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
||||||
|
} else if (axisType == GPXDataSetAxisType.TIMEOFDAY && analysis.isTimeSpecified()) {
|
||||||
|
divX = setupXAxisTimeOfDay(xAxis, analysis.startTime);
|
||||||
} else {
|
} else {
|
||||||
divX = setupAxisDistance(ctx, xAxis, analysis.totalDistance);
|
divX = setupAxisDistance(ctx, xAxis, analysis.totalDistance);
|
||||||
}
|
}
|
||||||
|
@ -1407,6 +1426,8 @@ public class GpxUiHelper {
|
||||||
XAxis xAxis = mChart.getXAxis();
|
XAxis xAxis = mChart.getXAxis();
|
||||||
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
||||||
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
||||||
|
} else if (axisType == GPXDataSetAxisType.TIMEOFDAY && analysis.isTimeSpecified()) {
|
||||||
|
divX = setupXAxisTimeOfDay(xAxis, analysis.startTime);
|
||||||
} else {
|
} else {
|
||||||
divX = setupAxisDistance(ctx, xAxis, analysis.totalDistance);
|
divX = setupAxisDistance(ctx, xAxis, analysis.totalDistance);
|
||||||
}
|
}
|
||||||
|
@ -1452,9 +1473,19 @@ public class GpxUiHelper {
|
||||||
float nextY;
|
float nextY;
|
||||||
float x;
|
float x;
|
||||||
for (Speed s : speedData) {
|
for (Speed s : speedData) {
|
||||||
x = axisType == GPXDataSetAxisType.TIME ? s.time : s.distance;
|
switch(axisType) {
|
||||||
|
case TIMEOFDAY:
|
||||||
|
case TIME:
|
||||||
|
x = s.time;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
x = s.distance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
if (axisType == GPXDataSetAxisType.TIME && x > 60) {
|
if (axisType == GPXDataSetAxisType.TIME && x > 60 ||
|
||||||
|
axisType == GPXDataSetAxisType.TIMEOFDAY && x > 60) {
|
||||||
values.add(new Entry(nextX + 1, 0));
|
values.add(new Entry(nextX + 1, 0));
|
||||||
values.add(new Entry(nextX + x - 1, 0));
|
values.add(new Entry(nextX + x - 1, 0));
|
||||||
}
|
}
|
||||||
|
@ -1550,7 +1581,7 @@ public class GpxUiHelper {
|
||||||
@Nullable List<Entry> eleValues,
|
@Nullable List<Entry> eleValues,
|
||||||
boolean useRightAxis,
|
boolean useRightAxis,
|
||||||
boolean drawFilled) {
|
boolean drawFilled) {
|
||||||
if (axisType == GPXDataSetAxisType.TIME) {
|
if (axisType == GPXDataSetAxisType.TIME || axisType == GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
OsmandSettings settings = ctx.getSettings();
|
OsmandSettings settings = ctx.getSettings();
|
||||||
|
@ -1767,7 +1798,8 @@ public class GpxUiHelper {
|
||||||
|
|
||||||
public enum GPXDataSetAxisType {
|
public enum GPXDataSetAxisType {
|
||||||
DISTANCE(R.string.distance, R.drawable.ic_action_marker_dark),
|
DISTANCE(R.string.distance, R.drawable.ic_action_marker_dark),
|
||||||
TIME(R.string.shared_string_time, R.drawable.ic_action_time);
|
TIME(R.string.shared_string_time, R.drawable.ic_action_time),
|
||||||
|
TIMEOFDAY(R.string.time_of_day, R.drawable.ic_action_time_span);
|
||||||
|
|
||||||
private int stringId;
|
private int stringId;
|
||||||
private int imageId;
|
private int imageId;
|
||||||
|
|
|
@ -186,7 +186,8 @@ public class TrackDetailsMenu {
|
||||||
if (ds != null && ds.size() > 0) {
|
if (ds != null && ds.size() > 0) {
|
||||||
TrkSegment segment = getTrackSegment(chart);
|
TrkSegment segment = getTrackSegment(chart);
|
||||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME ||
|
||||||
|
gpxItem.chartAxisType == GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
float time = pos * 1000;
|
float time = pos * 1000;
|
||||||
for (WptPt p : segment.points) {
|
for (WptPt p : segment.points) {
|
||||||
if (p.time - gpxItem.analysis.startTime >= time) {
|
if (p.time - gpxItem.analysis.startTime >= time) {
|
||||||
|
@ -222,12 +223,11 @@ public class TrackDetailsMenu {
|
||||||
if (ds != null && ds.size() > 0) {
|
if (ds != null && ds.size() > 0) {
|
||||||
TrkSegment segment = getTrackSegment(chart);
|
TrkSegment segment = getTrackSegment(chart);
|
||||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME || gpxItem.chartAxisType == GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
float startTime = startPos * 1000;
|
float startTime = startPos * 1000;
|
||||||
float endTime = endPos * 1000;
|
float endTime = endPos * 1000;
|
||||||
for (WptPt p : segment.points) {
|
for (WptPt p : segment.points) {
|
||||||
if (p.time - gpxItem.analysis.startTime >= startTime &&
|
if (p.time - gpxItem.analysis.startTime >= startTime && p.time - gpxItem.analysis.startTime <= endTime) {
|
||||||
p.time - gpxItem.analysis.startTime <= endTime) {
|
|
||||||
if (left == 0 && right == 0) {
|
if (left == 0 && right == 0) {
|
||||||
left = p.getLongitude();
|
left = p.getLongitude();
|
||||||
right = p.getLongitude();
|
right = p.getLongitude();
|
||||||
|
@ -501,14 +501,16 @@ public class TrackDetailsMenu {
|
||||||
boolean hasSlopeChart = false;
|
boolean hasSlopeChart = false;
|
||||||
if (analysis.hasElevationData) {
|
if (analysis.hasElevationData) {
|
||||||
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.ALTITUDE });
|
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.ALTITUDE });
|
||||||
if (gpxItem.chartAxisType != GPXDataSetAxisType.TIME) {
|
if (gpxItem.chartAxisType != GPXDataSetAxisType.TIME
|
||||||
|
&& gpxItem.chartAxisType != GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
availableTypes.add(new GPXDataSetType[]{GPXDataSetType.SLOPE});
|
availableTypes.add(new GPXDataSetType[]{GPXDataSetType.SLOPE});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (analysis.hasSpeedData) {
|
if (analysis.hasSpeedData) {
|
||||||
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.SPEED });
|
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.SPEED });
|
||||||
}
|
}
|
||||||
if (analysis.hasElevationData && gpxItem.chartAxisType != GPXDataSetAxisType.TIME) {
|
if (analysis.hasElevationData && gpxItem.chartAxisType != GPXDataSetAxisType.TIME
|
||||||
|
&& gpxItem.chartAxisType != GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE });
|
availableTypes.add(new GPXDataSetType[] { GPXDataSetType.ALTITUDE, GPXDataSetType.SLOPE });
|
||||||
}
|
}
|
||||||
if (analysis.hasElevationData && analysis.hasSpeedData) {
|
if (analysis.hasElevationData && analysis.hasSpeedData) {
|
||||||
|
@ -541,7 +543,6 @@ public class TrackDetailsMenu {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
optionsMenu.show();
|
optionsMenu.show();
|
||||||
}
|
}
|
||||||
|
@ -560,6 +561,9 @@ public class TrackDetailsMenu {
|
||||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||||
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time));
|
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time));
|
||||||
xAxisTitle.setText(app.getString(R.string.shared_string_time));
|
xAxisTitle.setText(app.getString(R.string.shared_string_time));
|
||||||
|
} else if (gpxItem.chartAxisType == GPXDataSetAxisType.TIMEOFDAY) {
|
||||||
|
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time_span));
|
||||||
|
xAxisTitle.setText(app.getString(R.string.time_of_day));
|
||||||
} else {
|
} else {
|
||||||
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_marker_dark));
|
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_marker_dark));
|
||||||
xAxisTitle.setText(app.getString(R.string.distance));
|
xAxisTitle.setText(app.getString(R.string.distance));
|
||||||
|
@ -570,23 +574,21 @@ public class TrackDetailsMenu {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
final PopupMenu optionsMenu = new PopupMenu(mapActivity, v);
|
final PopupMenu optionsMenu = new PopupMenu(mapActivity, v);
|
||||||
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
|
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
|
||||||
final GPXDataSetAxisType type;
|
for (final GPXDataSetAxisType type : GPXDataSetAxisType.values()) {
|
||||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
MenuItem menuItem = optionsMenu.getMenu()
|
||||||
type = GPXDataSetAxisType.DISTANCE;
|
.add(type.getStringId()).setIcon(type.getImageDrawable(app));
|
||||||
} else {
|
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
type = GPXDataSetAxisType.TIME;
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem mItem) {
|
||||||
|
|
||||||
|
gpxItem.chartAxisType = type;
|
||||||
|
gpxItem.chartHighlightPos = -1;
|
||||||
|
gpxItem.chartMatrix = null;
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
MenuItem menuItem = optionsMenu.getMenu().add(type.getStringId()).setIcon(type.getImageDrawable(app));
|
|
||||||
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onMenuItemClick(MenuItem mItem) {
|
|
||||||
gpxItem.chartAxisType = type;
|
|
||||||
gpxItem.chartHighlightPos = -1;
|
|
||||||
gpxItem.chartMatrix = null;
|
|
||||||
update();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
optionsMenu.show();
|
optionsMenu.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue