Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
78c5967cbf
5 changed files with 494 additions and 384 deletions
|
@ -5,29 +5,13 @@ import android.content.Context;
|
|||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.myplaces.SelectedGPXFragment;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.Renderable;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -51,7 +35,6 @@ import java.io.StringWriter;
|
|||
import java.io.Writer;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -65,13 +48,6 @@ import java.util.Map;
|
|||
import java.util.Stack;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM;
|
||||
import static net.osmand.plus.OsmAndFormatter.FEET_IN_ONE_METER;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_KILOMETER;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_ONE_MILE;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_ONE_NAUTICALMILE;
|
||||
import static net.osmand.plus.OsmAndFormatter.YARDS_IN_ONE_METER;
|
||||
|
||||
public class GPXUtilities {
|
||||
public final static Log log = PlatformUtil.getLog(GPXUtilities.class);
|
||||
|
||||
|
@ -1306,345 +1282,4 @@ public class GPXUtilities {
|
|||
to.warning = from.warning;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupGPXChart(OsmandApplication ctx, LineChart mChart, int yLabelsCount) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS);
|
||||
boolean light = settings.isLightContent();
|
||||
|
||||
//mChart.setHardwareAccelerationEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setScaleEnabled(true);
|
||||
mChart.setPinchZoom(true);
|
||||
mChart.setScaleYEnabled(false);
|
||||
mChart.setAutoScaleMinMaxEnabled(true);
|
||||
mChart.setDrawBorders(false);
|
||||
mChart.getDescription().setEnabled(false);
|
||||
mChart.setMaxVisibleValueCount(10);
|
||||
mChart.setMinOffset(0f);
|
||||
|
||||
mChart.setExtraTopOffset(24f);
|
||||
mChart.setExtraBottomOffset(16f);
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
SelectedGPXFragment.MyMarkerView mv =
|
||||
new SelectedGPXFragment.MyMarkerView(mChart.getContext(), R.layout.chart_marker_view);
|
||||
mv.setChartView(mChart); // For bounds control
|
||||
mChart.setMarker(mv); // Set the marker to the chart
|
||||
mChart.setDrawMarkers(true);
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setDrawAxisLine(false);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setPosition(BOTTOM);
|
||||
xAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
YAxis yAxis = mChart.getAxisLeft();
|
||||
yAxis.enableGridDashedLine(10f, 5f, 0f);
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.divider_color));
|
||||
yAxis.setDrawAxisLine(false);
|
||||
yAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
yAxis.setXOffset(16f);
|
||||
yAxis.setYOffset(-6f);
|
||||
yAxis.setLabelCount(yLabelsCount);
|
||||
yAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.enableGridDashedLine(10f, 5f, 0f);
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.divider_color));
|
||||
yAxis.setDrawAxisLine(false);
|
||||
yAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
yAxis.setXOffset(16f);
|
||||
yAxis.setYOffset(-6f);
|
||||
yAxis.setLabelCount(yLabelsCount);
|
||||
yAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
yAxis.setEnabled(false);
|
||||
|
||||
Legend legend = mChart.getLegend();
|
||||
legend.setEnabled(false);
|
||||
}
|
||||
|
||||
private static void getXAxisParams(OsmandApplication ctx, float meters, float[] koef, StringBuilder format, StringBuilder unit) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
float divX;
|
||||
|
||||
String format1 = "{0,number,0.#} ";
|
||||
String format2 = "{0,number,0.##} ";
|
||||
String fmt = null;
|
||||
int mainUnitStr;
|
||||
float mainUnitInMeters;
|
||||
if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
mainUnitStr = R.string.km;
|
||||
mainUnitInMeters = METERS_IN_KILOMETER;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES) {
|
||||
mainUnitStr = R.string.nm;
|
||||
mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE;
|
||||
} else {
|
||||
mainUnitStr = R.string.mile;
|
||||
mainUnitInMeters = METERS_IN_ONE_MILE;
|
||||
}
|
||||
if (meters > 9.99f * mainUnitInMeters) {
|
||||
fmt = format1;
|
||||
}
|
||||
if (meters >= 100 * mainUnitInMeters ||
|
||||
meters > 9.99f * mainUnitInMeters ||
|
||||
meters > 0.999f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) {
|
||||
|
||||
divX = mainUnitInMeters;
|
||||
if (fmt == null) {
|
||||
fmt = format2;
|
||||
}
|
||||
} else {
|
||||
fmt = null;
|
||||
if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS || mc == OsmandSettings.MetricsConstants.MILES_AND_METERS) {
|
||||
divX = 1f;
|
||||
mainUnitStr = R.string.m;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) {
|
||||
divX = 1f / FEET_IN_ONE_METER;
|
||||
mainUnitStr = R.string.foot;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS) {
|
||||
divX = 1f / YARDS_IN_ONE_METER;
|
||||
mainUnitStr = R.string.yard;
|
||||
} else {
|
||||
divX = 1f;
|
||||
mainUnitStr = R.string.m;
|
||||
}
|
||||
}
|
||||
|
||||
koef[0] = divX;
|
||||
format.append(fmt);
|
||||
unit.append(ctx.getString(mainUnitStr));
|
||||
}
|
||||
|
||||
public static LineDataSet createGPXElevationDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS);
|
||||
boolean light = settings.isLightContent();
|
||||
final float convEle = useFeet ? 3.28084f : 1.0f;
|
||||
final float meters = analysis.totalDistance;
|
||||
|
||||
float[] koef = new float[] { 1f };
|
||||
StringBuilder fmt = new StringBuilder();
|
||||
StringBuilder unitX = new StringBuilder();
|
||||
|
||||
getXAxisParams(ctx, meters, koef, fmt, unitX);
|
||||
float divX = koef[0];
|
||||
final String formatX = fmt.toString();
|
||||
final String mainUnitX = unitX.toString();
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
if (!Algorithms.isEmpty(formatX)) {
|
||||
return MessageFormat.format(formatX + mainUnitX, value);
|
||||
} else {
|
||||
return (int)value + " " + mainUnitX;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final String mainUnitY = useFeet ? ctx.getString(R.string.foot) : ctx.getString(R.string.m);
|
||||
|
||||
YAxis yAxis;
|
||||
if (useRightAxis) {
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.setEnabled(true);
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsRight(mainUnitY);
|
||||
} else {
|
||||
yAxis = mChart.getAxisLeft();
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsLeft(mainUnitY);
|
||||
}
|
||||
if (analysis.minElevation >=0) {
|
||||
yAxis.setAxisMinimum(0f);
|
||||
}
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return (int)value + " " + mainUnitY;
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
List<Elevation> elevationData = analysis.elevationData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
for (Elevation e : elevationData) {
|
||||
if (e.distance > 0) {
|
||||
nextX += (float) e.distance / divX;
|
||||
nextY = (float) (e.elevation * convEle);
|
||||
values.add(new Entry(nextX, nextY));
|
||||
}
|
||||
}
|
||||
|
||||
LineDataSet dataSet = new LineDataSet(values, "");
|
||||
|
||||
dataSet.setColor(Color.BLACK);
|
||||
dataSet.setDrawValues(false);
|
||||
dataSet.setLineWidth(0f);
|
||||
dataSet.setValueTextSize(9f);
|
||||
dataSet.setDrawFilled(true);
|
||||
dataSet.setFormLineWidth(1f);
|
||||
dataSet.setFormSize(15.f);
|
||||
|
||||
dataSet.setDrawCircles(false);
|
||||
dataSet.setDrawCircleHole(false);
|
||||
|
||||
dataSet.setHighlightEnabled(true);
|
||||
dataSet.setDrawVerticalHighlightIndicator(true);
|
||||
dataSet.setDrawHorizontalHighlightIndicator(false);
|
||||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
if (Utils.getSDKInt() >= 18) {
|
||||
// fill drawable only supported on api level 18 and above
|
||||
Drawable drawable = ContextCompat.getDrawable(mChart.getContext(), R.drawable.line_chart_fade_blue);
|
||||
dataSet.setFillDrawable(drawable);
|
||||
} else {
|
||||
dataSet.setFillColor(ContextCompat.getColor(mChart.getContext(), R.color.transport_route_line));
|
||||
}
|
||||
if (useRightAxis) {
|
||||
dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public static void setGPXElevationChartData(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis) {
|
||||
LineDataSet dataSet = createGPXElevationDataSet(ctx, mChart, analysis, useRightAxis);
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(dataSet);
|
||||
LineData data = new LineData(dataSets);
|
||||
mChart.setData(data);
|
||||
}
|
||||
|
||||
public static LineDataSet createGPXSpeedDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
boolean light = settings.isLightContent();
|
||||
final float meters = analysis.totalDistance;
|
||||
|
||||
float[] koef = new float[] { 1f };
|
||||
StringBuilder fmt = new StringBuilder();
|
||||
StringBuilder unitX = new StringBuilder();
|
||||
|
||||
getXAxisParams(ctx, meters, koef, fmt, unitX);
|
||||
float divX = koef[0];
|
||||
final String formatX = fmt.toString();
|
||||
final String mainUnitX = unitX.toString();
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
if (!Algorithms.isEmpty(formatX)) {
|
||||
return MessageFormat.format(formatX + mainUnitX, value);
|
||||
} else {
|
||||
return (int)value + " " + mainUnitX;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
OsmandSettings.SpeedConstants sps = settings.SPEED_SYSTEM.get();
|
||||
float mulSpeed = Float.NaN;
|
||||
float divSpeed = Float.NaN;
|
||||
final String mainUnitY = sps.toShortString(ctx);
|
||||
if (sps == OsmandSettings.SpeedConstants.KILOMETERS_PER_HOUR) {
|
||||
mulSpeed = 3.6f;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MILES_PER_HOUR) {
|
||||
mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_MILE;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.NAUTICALMILES_PER_HOUR) {
|
||||
mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_KILOMETER) {
|
||||
divSpeed = METERS_IN_KILOMETER / 60;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_MILE) {
|
||||
divSpeed = METERS_IN_ONE_MILE / 60;
|
||||
} else {
|
||||
mulSpeed = 1f;
|
||||
}
|
||||
|
||||
YAxis yAxis;
|
||||
if (useRightAxis) {
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.setEnabled(true);
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsRight(mainUnitY);
|
||||
} else {
|
||||
yAxis = mChart.getAxisLeft();
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsLeft(mainUnitY);
|
||||
}
|
||||
yAxis.setAxisMinimum(0f);
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return (int)value + " " + mainUnitY;
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
List<Speed> speedData = analysis.speedData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
for (Speed s : speedData) {
|
||||
if (s.distance > 0) {
|
||||
nextX += (float) s.distance / divX;
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
nextY = (float) (s.speed * mulSpeed);
|
||||
} else {
|
||||
nextY = (float) (divSpeed / s.speed);
|
||||
}
|
||||
if (nextY < 0) {
|
||||
nextY = 0;
|
||||
}
|
||||
values.add(new Entry(nextX, nextY));
|
||||
}
|
||||
}
|
||||
|
||||
LineDataSet dataSet = new LineDataSet(values, "");
|
||||
|
||||
dataSet.setColor(Color.BLACK);
|
||||
dataSet.setDrawValues(false);
|
||||
dataSet.setLineWidth(0f);
|
||||
dataSet.setValueTextSize(9f);
|
||||
dataSet.setDrawFilled(true);
|
||||
dataSet.setFormLineWidth(1f);
|
||||
dataSet.setFormSize(15.f);
|
||||
|
||||
dataSet.setDrawCircles(false);
|
||||
dataSet.setDrawCircleHole(false);
|
||||
|
||||
dataSet.setHighlightEnabled(true);
|
||||
dataSet.setDrawVerticalHighlightIndicator(true);
|
||||
dataSet.setDrawHorizontalHighlightIndicator(false);
|
||||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
if (Utils.getSDKInt() >= 18) {
|
||||
// fill drawable only supported on api level 18 and above
|
||||
Drawable drawable = ContextCompat.getDrawable(mChart.getContext(), R.drawable.line_chart_fade_red);
|
||||
dataSet.setFillDrawable(drawable);
|
||||
} else {
|
||||
dataSet.setFillColor(ContextCompat.getColor(mChart.getContext(), R.color.transport_end));
|
||||
}
|
||||
if (useRightAxis) {
|
||||
dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public static void setGPXSpeedChartData(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis) {
|
||||
LineDataSet dataSet = createGPXSpeedDataSet(ctx, mChart, analysis, useRightAxis);
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(dataSet);
|
||||
LineData data = new LineData(dataSets);
|
||||
mChart.setData(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
|
@ -660,5 +661,6 @@ public class GpxSelectionHelper {
|
|||
public String url;
|
||||
public Bitmap image;
|
||||
public boolean expanded;
|
||||
public Matrix chartMatrix;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.widget.ListView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.PointDescription;
|
||||
|
@ -41,6 +40,7 @@ import net.osmand.plus.OsmAndFormatter;
|
|||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
|
||||
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
|
@ -212,7 +212,7 @@ public class ShowRouteInfoDialogFragment extends DialogFragment {
|
|||
private void buildHeader(View headerView) {
|
||||
OsmandApplication app = getMyApplication();
|
||||
LineChart mChart = (LineChart) headerView.findViewById(R.id.chart);
|
||||
GPXUtilities.setupGPXChart(app, mChart, 4);
|
||||
GpxUiHelper.setupGPXChart(app, mChart, 4);
|
||||
mChart.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
|
@ -222,7 +222,7 @@ public class ShowRouteInfoDialogFragment extends DialogFragment {
|
|||
});
|
||||
|
||||
GPXTrackAnalysis analysis = gpx.getAnalysis(0);
|
||||
GPXUtilities.setGPXElevationChartData(app, mChart, analysis, false);
|
||||
GpxUiHelper.setGPXElevationChartData(app, mChart, analysis, false, true);
|
||||
|
||||
((TextView) headerView.findViewById(R.id.average_text))
|
||||
.setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app));
|
||||
|
|
|
@ -7,9 +7,11 @@ import android.app.ProgressDialog;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.ListPopupWindow;
|
||||
|
@ -31,6 +33,21 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.DefaultFillFormatter;
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||
import com.github.mikephil.charting.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.IndexConstants;
|
||||
|
@ -54,6 +71,7 @@ import net.osmand.plus.activities.SettingsActivity;
|
|||
import net.osmand.plus.dialogs.ConfigureMapMenu;
|
||||
import net.osmand.plus.dialogs.ConfigureMapMenu.AppearanceListItem;
|
||||
import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter;
|
||||
import net.osmand.plus.myplaces.SelectedGPXFragment;
|
||||
import net.osmand.render.RenderingRuleProperty;
|
||||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -63,6 +81,7 @@ import java.io.File;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.DateFormat;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -70,6 +89,12 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM;
|
||||
import static net.osmand.plus.OsmAndFormatter.FEET_IN_ONE_METER;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_KILOMETER;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_ONE_MILE;
|
||||
import static net.osmand.plus.OsmAndFormatter.METERS_IN_ONE_NAUTICALMILE;
|
||||
import static net.osmand.plus.OsmAndFormatter.YARDS_IN_ONE_METER;
|
||||
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
|
||||
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_WIDTH_ATTR;
|
||||
import static net.osmand.plus.dialogs.ConfigureMapMenu.refreshMapComplete;
|
||||
|
@ -819,6 +844,387 @@ public class GpxUiHelper {
|
|||
}, "Loading gpx").start(); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public static void setupGPXChart(OsmandApplication ctx, LineChart mChart, int yLabelsCount) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS);
|
||||
boolean light = settings.isLightContent();
|
||||
|
||||
//mChart.setHardwareAccelerationEnabled(true);
|
||||
mChart.setTouchEnabled(true);
|
||||
mChart.setDragEnabled(true);
|
||||
mChart.setScaleEnabled(true);
|
||||
mChart.setPinchZoom(true);
|
||||
mChart.setScaleYEnabled(false);
|
||||
mChart.setAutoScaleMinMaxEnabled(true);
|
||||
mChart.setDrawBorders(false);
|
||||
mChart.getDescription().setEnabled(false);
|
||||
mChart.setMaxVisibleValueCount(10);
|
||||
mChart.setMinOffset(0f);
|
||||
|
||||
mChart.setExtraTopOffset(24f);
|
||||
mChart.setExtraBottomOffset(16f);
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
SelectedGPXFragment.MyMarkerView mv =
|
||||
new SelectedGPXFragment.MyMarkerView(mChart.getContext(), R.layout.chart_marker_view);
|
||||
mv.setChartView(mChart); // For bounds control
|
||||
mChart.setMarker(mv); // Set the marker to the chart
|
||||
mChart.setDrawMarkers(true);
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setDrawAxisLine(false);
|
||||
xAxis.setDrawGridLines(false);
|
||||
xAxis.setPosition(BOTTOM);
|
||||
xAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
YAxis yAxis = mChart.getAxisLeft();
|
||||
yAxis.enableGridDashedLine(10f, 5f, 0f);
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.divider_color));
|
||||
yAxis.setDrawAxisLine(false);
|
||||
yAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
yAxis.setXOffset(16f);
|
||||
yAxis.setYOffset(-6f);
|
||||
yAxis.setLabelCount(yLabelsCount);
|
||||
yAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.enableGridDashedLine(10f, 5f, 0f);
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.divider_color));
|
||||
yAxis.setDrawAxisLine(false);
|
||||
yAxis.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
|
||||
yAxis.setXOffset(16f);
|
||||
yAxis.setYOffset(-6f);
|
||||
yAxis.setLabelCount(yLabelsCount);
|
||||
yAxis.setTextColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
yAxis.setEnabled(false);
|
||||
|
||||
Legend legend = mChart.getLegend();
|
||||
legend.setEnabled(false);
|
||||
}
|
||||
|
||||
private static float getXAxisParams(OsmandApplication ctx, float meters, float[] koef, StringBuilder format, StringBuilder unit) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
float divX;
|
||||
|
||||
String format1 = "{0,number,0.#} ";
|
||||
String format2 = "{0,number,0.##} ";
|
||||
String fmt = null;
|
||||
float granularity = 1f;
|
||||
int mainUnitStr;
|
||||
float mainUnitInMeters;
|
||||
if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
mainUnitStr = R.string.km;
|
||||
mainUnitInMeters = METERS_IN_KILOMETER;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES) {
|
||||
mainUnitStr = R.string.nm;
|
||||
mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE;
|
||||
} else {
|
||||
mainUnitStr = R.string.mile;
|
||||
mainUnitInMeters = METERS_IN_ONE_MILE;
|
||||
}
|
||||
if (meters > 9.99f * mainUnitInMeters) {
|
||||
fmt = format1;
|
||||
granularity = .1f;
|
||||
}
|
||||
if (meters >= 100 * mainUnitInMeters ||
|
||||
meters > 9.99f * mainUnitInMeters ||
|
||||
meters > 0.999f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters ||
|
||||
mc == OsmandSettings.MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) {
|
||||
|
||||
divX = mainUnitInMeters;
|
||||
if (fmt == null) {
|
||||
fmt = format2;
|
||||
granularity = .01f;
|
||||
}
|
||||
} else {
|
||||
fmt = null;
|
||||
granularity = 1f;
|
||||
if (mc == OsmandSettings.MetricsConstants.KILOMETERS_AND_METERS || mc == OsmandSettings.MetricsConstants.MILES_AND_METERS) {
|
||||
divX = 1f;
|
||||
mainUnitStr = R.string.m;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) {
|
||||
divX = 1f / FEET_IN_ONE_METER;
|
||||
mainUnitStr = R.string.foot;
|
||||
} else if (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS) {
|
||||
divX = 1f / YARDS_IN_ONE_METER;
|
||||
mainUnitStr = R.string.yard;
|
||||
} else {
|
||||
divX = 1f;
|
||||
mainUnitStr = R.string.m;
|
||||
}
|
||||
}
|
||||
|
||||
koef[0] = divX;
|
||||
if (fmt != null) {
|
||||
format.append(fmt);
|
||||
}
|
||||
unit.append(ctx.getString(mainUnitStr));
|
||||
return granularity;
|
||||
}
|
||||
|
||||
public static OrderedLineDataSet createGPXElevationDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
boolean useFeet = (mc == OsmandSettings.MetricsConstants.MILES_AND_FEET) || (mc == OsmandSettings.MetricsConstants.MILES_AND_YARDS);
|
||||
boolean light = settings.isLightContent();
|
||||
final float convEle = useFeet ? 3.28084f : 1.0f;
|
||||
final float meters = analysis.totalDistance;
|
||||
|
||||
float[] koef = new float[] { 1f };
|
||||
StringBuilder fmt = new StringBuilder();
|
||||
StringBuilder unitX = new StringBuilder();
|
||||
|
||||
float granularity = getXAxisParams(ctx, meters, koef, fmt, unitX);
|
||||
float divX = koef[0];
|
||||
final String formatX = fmt.toString();
|
||||
final String mainUnitX = unitX.toString();
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setGranularity(granularity);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
if (!Algorithms.isEmpty(formatX)) {
|
||||
return MessageFormat.format(formatX + mainUnitX, value);
|
||||
} else {
|
||||
return (int)value + " " + mainUnitX;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final String mainUnitY = useFeet ? ctx.getString(R.string.foot) : ctx.getString(R.string.m);
|
||||
|
||||
YAxis yAxis;
|
||||
if (useRightAxis) {
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.setEnabled(true);
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsRight(mainUnitY);
|
||||
} else {
|
||||
yAxis = mChart.getAxisLeft();
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsLeft(mainUnitY);
|
||||
}
|
||||
yAxis.setGranularity(1f);
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return (int)value + " " + mainUnitY;
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
List<GPXUtilities.Elevation> elevationData = analysis.elevationData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
for (GPXUtilities.Elevation e : elevationData) {
|
||||
if (e.distance > 0) {
|
||||
nextX += (float) e.distance / divX;
|
||||
nextY = (float) (e.elevation * convEle);
|
||||
values.add(new Entry(nextX, nextY));
|
||||
}
|
||||
}
|
||||
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "");
|
||||
dataSet.priority = (float) (analysis.avgElevation - analysis.minElevation) * convEle;
|
||||
if (drawFilled) {
|
||||
dataSet.setColor(Color.BLACK);
|
||||
dataSet.setLineWidth(0f);
|
||||
dataSet.setDrawFilled(true);
|
||||
} else {
|
||||
dataSet.setColor(ContextCompat.getColor(mChart.getContext(), R.color.map_widget_blue));
|
||||
dataSet.setLineWidth(1f);
|
||||
dataSet.setDrawFilled(false);
|
||||
}
|
||||
dataSet.setDrawValues(false);
|
||||
dataSet.setValueTextSize(9f);
|
||||
dataSet.setFormLineWidth(1f);
|
||||
dataSet.setFormSize(15.f);
|
||||
|
||||
dataSet.setDrawCircles(false);
|
||||
dataSet.setDrawCircleHole(false);
|
||||
|
||||
dataSet.setHighlightEnabled(true);
|
||||
dataSet.setDrawVerticalHighlightIndicator(true);
|
||||
dataSet.setDrawHorizontalHighlightIndicator(false);
|
||||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
if (Utils.getSDKInt() >= 18) {
|
||||
// fill drawable only supported on api level 18 and above
|
||||
Drawable drawable = ContextCompat.getDrawable(mChart.getContext(), R.drawable.line_chart_fade_blue);
|
||||
dataSet.setFillDrawable(drawable);
|
||||
} else {
|
||||
dataSet.setFillColor(ContextCompat.getColor(mChart.getContext(), R.color.transport_route_line));
|
||||
}
|
||||
dataSet.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
|
||||
return dataProvider.getYChartMin();
|
||||
}
|
||||
});
|
||||
if (useRightAxis) {
|
||||
dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public static void setGPXElevationChartData(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
LineDataSet dataSet = createGPXElevationDataSet(ctx, mChart, analysis, useRightAxis, drawFilled);
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(dataSet);
|
||||
LineData data = new LineData(dataSets);
|
||||
mChart.setData(data);
|
||||
}
|
||||
|
||||
public static OrderedLineDataSet createGPXSpeedDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
boolean light = settings.isLightContent();
|
||||
final float meters = analysis.totalDistance;
|
||||
|
||||
float[] koef = new float[] { 1f };
|
||||
StringBuilder fmt = new StringBuilder();
|
||||
StringBuilder unitX = new StringBuilder();
|
||||
|
||||
float granularity = getXAxisParams(ctx, meters, koef, fmt, unitX);
|
||||
float divX = koef[0];
|
||||
final String formatX = fmt.toString();
|
||||
final String mainUnitX = unitX.toString();
|
||||
|
||||
XAxis xAxis = mChart.getXAxis();
|
||||
xAxis.setGranularity(granularity);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
if (!Algorithms.isEmpty(formatX)) {
|
||||
return MessageFormat.format(formatX + mainUnitX, value);
|
||||
} else {
|
||||
return (int)value + " " + mainUnitX;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
OsmandSettings.SpeedConstants sps = settings.SPEED_SYSTEM.get();
|
||||
float mulSpeed = Float.NaN;
|
||||
float divSpeed = Float.NaN;
|
||||
final String mainUnitY = sps.toShortString(ctx);
|
||||
if (sps == OsmandSettings.SpeedConstants.KILOMETERS_PER_HOUR) {
|
||||
mulSpeed = 3.6f;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MILES_PER_HOUR) {
|
||||
mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_MILE;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.NAUTICALMILES_PER_HOUR) {
|
||||
mulSpeed = 3.6f * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_KILOMETER) {
|
||||
divSpeed = METERS_IN_KILOMETER / 60;
|
||||
} else if (sps == OsmandSettings.SpeedConstants.MINUTES_PER_MILE) {
|
||||
divSpeed = METERS_IN_ONE_MILE / 60;
|
||||
} else {
|
||||
mulSpeed = 1f;
|
||||
}
|
||||
|
||||
YAxis yAxis;
|
||||
if (useRightAxis) {
|
||||
yAxis = mChart.getAxisRight();
|
||||
yAxis.setEnabled(true);
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsRight(mainUnitY);
|
||||
} else {
|
||||
yAxis = mChart.getAxisLeft();
|
||||
((SelectedGPXFragment.MyMarkerView)mChart.getMarker()).setUnitsLeft(mainUnitY);
|
||||
}
|
||||
yAxis.setAxisMinimum(0f);
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
return (int)value + " " + mainUnitY;
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
List<GPXUtilities.Speed> speedData = analysis.speedData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
for (GPXUtilities.Speed s : speedData) {
|
||||
if (s.distance > 0) {
|
||||
nextX += (float) s.distance / divX;
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
nextY = (float) (s.speed * mulSpeed);
|
||||
} else {
|
||||
nextY = (float) (divSpeed / s.speed);
|
||||
}
|
||||
if (nextY < 0) {
|
||||
nextY = 0;
|
||||
}
|
||||
values.add(new Entry(nextX, nextY));
|
||||
}
|
||||
}
|
||||
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "");
|
||||
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
dataSet.priority = analysis.avgSpeed * mulSpeed;
|
||||
} else {
|
||||
dataSet.priority = divSpeed / analysis.avgSpeed;
|
||||
}
|
||||
|
||||
if (drawFilled) {
|
||||
dataSet.setColor(Color.BLACK);
|
||||
dataSet.setLineWidth(0f);
|
||||
dataSet.setDrawFilled(true);
|
||||
} else {
|
||||
dataSet.setColor(ContextCompat.getColor(mChart.getContext(), R.color.transport_end));
|
||||
dataSet.setLineWidth(1f);
|
||||
dataSet.setDrawFilled(false);
|
||||
}
|
||||
dataSet.setDrawValues(false);
|
||||
dataSet.setValueTextSize(9f);
|
||||
dataSet.setFormLineWidth(1f);
|
||||
dataSet.setFormSize(15.f);
|
||||
|
||||
dataSet.setDrawCircles(false);
|
||||
dataSet.setDrawCircleHole(false);
|
||||
|
||||
dataSet.setHighlightEnabled(true);
|
||||
dataSet.setDrawVerticalHighlightIndicator(true);
|
||||
dataSet.setDrawHorizontalHighlightIndicator(false);
|
||||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
if (Utils.getSDKInt() >= 18) {
|
||||
// fill drawable only supported on api level 18 and above
|
||||
Drawable drawable = ContextCompat.getDrawable(mChart.getContext(), R.drawable.line_chart_fade_red);
|
||||
dataSet.setFillDrawable(drawable);
|
||||
} else {
|
||||
dataSet.setFillColor(ContextCompat.getColor(mChart.getContext(), R.color.transport_end));
|
||||
}
|
||||
if (useRightAxis) {
|
||||
dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
}
|
||||
return dataSet;
|
||||
}
|
||||
|
||||
public static void setGPXSpeedChartData(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
LineDataSet dataSet = createGPXSpeedDataSet(ctx, mChart, analysis, useRightAxis, drawFilled);
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(dataSet);
|
||||
LineData data = new LineData(dataSets);
|
||||
mChart.setData(data);
|
||||
}
|
||||
|
||||
public static class OrderedLineDataSet extends LineDataSet {
|
||||
|
||||
public float priority;
|
||||
|
||||
public OrderedLineDataSet(List<Entry> yVals, String label) {
|
||||
super(yVals, label);
|
||||
}
|
||||
}
|
||||
|
||||
public static class GPXInfo {
|
||||
private String fileName;
|
||||
private long lastModified;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus.myplaces;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
|
@ -19,11 +20,11 @@ import android.widget.TextView;
|
|||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture;
|
||||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
|
@ -32,6 +33,8 @@ import net.osmand.plus.IconsCache;
|
|||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider;
|
||||
import net.osmand.plus.views.controls.WrapContentHeightViewPager;
|
||||
|
@ -99,6 +102,7 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
View row = convertView;
|
||||
PagerSlidingTabStrip tabLayout = null;
|
||||
WrapContentHeightViewPager pager;
|
||||
if (row == null) {
|
||||
LayoutInflater inflater = getMyActivity().getLayoutInflater();
|
||||
row = inflater.inflate(R.layout.gpx_list_item_tab_content, parent, false);
|
||||
|
@ -113,12 +117,15 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
tabLayout.setTextSize(AndroidUtils.spToPx(app, 12f));
|
||||
tabLayout.setShouldExpand(true);
|
||||
tabLayout.setTabSelectionType(PagerSlidingTabStrip.TabSelectionType.SOLID_COLOR);
|
||||
pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
|
||||
pager.setSwipeable(false);
|
||||
} else {
|
||||
pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
|
||||
}
|
||||
|
||||
if (tabLayout != null) {
|
||||
final WrapContentHeightViewPager pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
|
||||
pager.setAdapter(getPagerAdapter(tabLayout, getItem(position)));
|
||||
pager.setSwipeable(false);
|
||||
pager.setOffscreenPageLimit(2);
|
||||
tabLayout.setViewPager(pager);
|
||||
}
|
||||
|
||||
|
@ -209,7 +216,7 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
OsmandApplication app = (OsmandApplication) getActivity().getApplicationContext();
|
||||
if (gpxItem != null) {
|
||||
GPXTrackAnalysis analysis = gpxItem.analysis;
|
||||
LineChart chart = (LineChart) view.findViewById(R.id.chart);
|
||||
final LineChart chart = (LineChart) view.findViewById(R.id.chart);
|
||||
chart.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
|
@ -217,22 +224,72 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
return false;
|
||||
}
|
||||
});
|
||||
final View finalView = view;
|
||||
chart.setOnChartGestureListener(new OnChartGestureListener() {
|
||||
@Override
|
||||
public void onChartGestureStart(MotionEvent me, ChartGesture lastPerformedGesture) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureEnd(MotionEvent me, ChartGesture lastPerformedGesture) {
|
||||
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
View v = getViewAtPosition(i);
|
||||
if (v != finalView) {
|
||||
updateChart(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartLongPressed(MotionEvent me) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartDoubleTapped(MotionEvent me) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartSingleTapped(MotionEvent me) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartTranslate(MotionEvent me, float dX, float dY) {
|
||||
}
|
||||
});
|
||||
|
||||
IconsCache ic = app.getIconsCache();
|
||||
switch (tabType) {
|
||||
case GPX_TAB_ITEM_GENERAL:
|
||||
if (analysis != null) {
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
List<ILineDataSet> dataSets = new ArrayList<>();
|
||||
if (analysis.elevationData != null || analysis.isSpeedSpecified()) {
|
||||
GPXUtilities.setupGPXChart(app, chart, 4);
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
OrderedLineDataSet speedDataSet = null;
|
||||
OrderedLineDataSet elevationDataSet = null;
|
||||
if (analysis.isSpeedSpecified()) {
|
||||
LineDataSet dataSet = GPXUtilities.createGPXSpeedDataSet(app, chart, analysis, true);
|
||||
dataSets.add(dataSet);
|
||||
speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis, true, true);
|
||||
}
|
||||
if (analysis.elevationData != null) {
|
||||
LineDataSet dataSet = GPXUtilities.createGPXElevationDataSet(app, chart, analysis, false);
|
||||
dataSets.add(dataSet);
|
||||
elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis, false, true);
|
||||
}
|
||||
if (speedDataSet != null) {
|
||||
dataSets.add(speedDataSet);
|
||||
if (elevationDataSet != null) {
|
||||
dataSets.add(elevationDataSet.priority < speedDataSet.priority ? 1 : 0, elevationDataSet);
|
||||
}
|
||||
} else if (elevationDataSet != null) {
|
||||
dataSets.add(elevationDataSet);
|
||||
}
|
||||
|
||||
LineData data = new LineData(dataSets);
|
||||
chart.setData(data);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
|
@ -285,8 +342,8 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
case GPX_TAB_ITEM_ALTITUDE:
|
||||
if (analysis != null) {
|
||||
if (analysis.elevationData != null) {
|
||||
GPXUtilities.setupGPXChart(app, chart, 4);
|
||||
GPXUtilities.setGPXElevationChartData(app, chart, analysis, false);
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
GpxUiHelper.setGPXElevationChartData(app, chart, analysis, false, true);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
|
@ -327,9 +384,8 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
break;
|
||||
case GPX_TAB_ITEM_SPEED:
|
||||
if (analysis != null && analysis.isSpeedSpecified()) {
|
||||
GPXUtilities.setupGPXChart(app, chart, 4);
|
||||
GPXUtilities.setGPXSpeedChartData(app, chart, analysis, false);
|
||||
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
GpxUiHelper.setGPXSpeedChartData(app, chart, analysis, false, true);
|
||||
((ImageView) view.findViewById(R.id.average_icon))
|
||||
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_speed));
|
||||
((ImageView) view.findViewById(R.id.max_icon))
|
||||
|
@ -442,5 +498,16 @@ public class TrackSegmentFragment extends SelectedGPXFragment {
|
|||
public View getViewAtPosition(int position) {
|
||||
return views.get(position);
|
||||
}
|
||||
|
||||
void updateChart(int position) {
|
||||
View view = getViewAtPosition(position);
|
||||
updateChart((LineChart) view.findViewById(R.id.chart));
|
||||
}
|
||||
|
||||
void updateChart(LineChart chart) {
|
||||
if (gpxItem.chartMatrix != null) {
|
||||
chart.getViewPortHandler().refresh(new Matrix(gpxItem.chartMatrix), chart, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue