Fix large slope chart crash

This commit is contained in:
crimean 2019-04-04 21:36:33 +03:00
parent f5b015d501
commit b43a1b166b
2 changed files with 33 additions and 25 deletions

View file

@ -60,18 +60,18 @@ import com.github.mikephil.charting.utils.MPPointF;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.CallbackWithObject; import net.osmand.CallbackWithObject;
import net.osmand.IndexConstants;
import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.Elevation; import net.osmand.GPXUtilities.Elevation;
import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.GPXTrackAnalysis; import net.osmand.GPXUtilities.GPXTrackAnalysis;
import net.osmand.GPXUtilities.Speed; import net.osmand.GPXUtilities.Speed;
import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.IndexConstants;
import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -96,6 +96,8 @@ import net.osmand.router.RouteStatistics;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.MessageFormat; import java.text.MessageFormat;
@ -106,7 +108,6 @@ 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,7 +124,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 int DEFAULT_DISTANCE_FOR_SLOPE_DATA = 2000000; private static final int MAX_CHART_DATA_ITEMS = 10000;
private static final Log LOG = PlatformUtil.getLog(GpxUiHelper.class); 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) {
@ -1619,8 +1620,9 @@ public class GpxUiHelper {
int lastIndex = values.size() - 1; int lastIndex = values.size() - 1;
double STEP = 5; double STEP = 5;
if (totalDistance > DEFAULT_DISTANCE_FOR_SLOPE_DATA) { int l = 10;
STEP = STEP * (totalDistance / DEFAULT_DISTANCE_FOR_SLOPE_DATA); while (l > 0 && totalDistance / STEP > MAX_CHART_DATA_ITEMS) {
STEP = Math.max(STEP, totalDistance / (values.size() * l--));
} }
double[] calculatedDist = new double[(int) (totalDistance / STEP) + 1]; double[] calculatedDist = new double[(int) (totalDistance / STEP) + 1];
@ -1630,15 +1632,15 @@ public class GpxUiHelper {
if (k > 0) { if (k > 0) {
calculatedDist[k] = calculatedDist[k - 1] + STEP; calculatedDist[k] = calculatedDist[k - 1] + STEP;
} }
while(nextW < lastIndex && calculatedDist[k] > values.get(nextW).getX()) { while (nextW < lastIndex && calculatedDist[k] > values.get(nextW).getX()) {
nextW ++; nextW++;
} }
double pd = nextW == 0 ? 0 : values.get(nextW - 1).getX(); double pd = nextW == 0 ? 0 : values.get(nextW - 1).getX();
double ph = nextW == 0 ? values.get(0).getY() : values.get(nextW - 1).getY(); double ph = nextW == 0 ? values.get(0).getY() : values.get(nextW - 1).getY();
calculatedH[k] = ph + (values.get(nextW).getY() - ph) / (values.get(nextW).getX() - pd) * (calculatedDist[k] - pd); calculatedH[k] = ph + (values.get(nextW).getY() - ph) / (values.get(nextW).getX() - pd) * (calculatedDist[k] - pd);
} }
double SLOPE_PROXIMITY = 100; double SLOPE_PROXIMITY = Math.max(100, STEP * 2);
if (totalDistance - SLOPE_PROXIMITY < 0) { if (totalDistance - SLOPE_PROXIMITY < 0) {
if (useRightAxis) { if (useRightAxis) {

View file

@ -27,6 +27,7 @@ public class SimpleRouteCard extends BaseCard {
private MapActivity mapActivity; private MapActivity mapActivity;
private GPXFile gpx; private GPXFile gpx;
private LineData data;
public SimpleRouteCard(MapActivity mapActivity, GPXFile gpx) { public SimpleRouteCard(MapActivity mapActivity, GPXFile gpx) {
super(mapActivity); super(mapActivity);
@ -114,19 +115,24 @@ public class SimpleRouteCard extends BaseCard {
GpxUiHelper.setupGPXChart(mChart, 4, 4f, 4f, !nightMode, false); GpxUiHelper.setupGPXChart(mChart, 4, 4f, 4f, !nightMode, false);
if (analysis.hasElevationData) { if (analysis.hasElevationData) {
List<ILineDataSet> dataSets = new ArrayList<>(); LineData data = this.data;
OrderedLineDataSet slopeDataSet = null; if (data == null) {
OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, mChart, analysis, List<ILineDataSet> dataSets = new ArrayList<>();
GpxUiHelper.GPXDataSetAxisType.DISTANCE, false, true); OrderedLineDataSet slopeDataSet = null;
if (elevationDataSet != null) { OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, mChart, analysis,
dataSets.add(elevationDataSet); GpxUiHelper.GPXDataSetAxisType.DISTANCE, false, true);
slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, mChart, analysis, if (elevationDataSet != null) {
GpxUiHelper.GPXDataSetAxisType.DISTANCE, elevationDataSet.getValues(), true, true); dataSets.add(elevationDataSet);
slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, mChart, analysis,
GpxUiHelper.GPXDataSetAxisType.DISTANCE, elevationDataSet.getValues(), true, true);
}
if (slopeDataSet != null) {
dataSets.add(slopeDataSet);
}
data = new LineData(dataSets);
this.data = data;
} }
if (slopeDataSet != null) { mChart.setData(data);
dataSets.add(slopeDataSet);
}
mChart.setData(new LineData(dataSets));
mChart.setVisibility(View.VISIBLE); mChart.setVisibility(View.VISIBLE);
} else { } else {
mChart.setVisibility(View.GONE); mChart.setVisibility(View.GONE);