Fit chart to the map view (track details)
This commit is contained in:
parent
6af7b1aeb3
commit
4fc57fd04c
4 changed files with 183 additions and 54 deletions
|
@ -337,6 +337,7 @@ public class GPXUtilities {
|
|||
channelBottom = channelBase;
|
||||
channelThres = channelThresMin;
|
||||
|
||||
float segmentDistance = 0f;
|
||||
metricEnd += s.metricEnd;
|
||||
secondaryMetricEnd += s.secondaryMetricEnd;
|
||||
points += numberOfPoints;
|
||||
|
@ -448,7 +449,8 @@ public class GPXUtilities {
|
|||
// a little more exact, also seems slightly faster:
|
||||
net.osmand.Location.distanceBetween(prev.lat, prev.lon, point.lat, point.lon, calculations);
|
||||
totalDistance += calculations[0];
|
||||
point.distance = totalDistance;
|
||||
segmentDistance += calculations[0];
|
||||
point.distance = segmentDistance;
|
||||
timeDiff = (int)((point.time - prev.time) / 1000);
|
||||
|
||||
// Motion detection:
|
||||
|
|
|
@ -10,15 +10,20 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.listener.ChartTouchListener;
|
||||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.IconsCache;
|
||||
|
@ -43,6 +48,7 @@ public class TrackDetailsMenu {
|
|||
private MapActivity mapActivity;
|
||||
private GpxDisplayItem gpxItem;
|
||||
private TrackDetailsBarController toolbarController;
|
||||
private TrkSegment segment;
|
||||
|
||||
private static boolean VISIBLE;
|
||||
|
||||
|
@ -99,6 +105,7 @@ public class TrackDetailsMenu {
|
|||
if (fragmentRef != null) {
|
||||
fragmentRef.get().dismiss();
|
||||
} else {
|
||||
segment = null;
|
||||
VISIBLE = false;
|
||||
}
|
||||
}
|
||||
|
@ -129,31 +136,19 @@ public class TrackDetailsMenu {
|
|||
mapActivity.getMapLayers().getMapInfoLayer().setSelectedPointLatLon(null);
|
||||
mapActivity.getMapView().setMapPositionX(0);
|
||||
mapActivity.getMapView().refreshMap();
|
||||
segment = null;
|
||||
}
|
||||
|
||||
public void updateInfo(final View main) {
|
||||
updateView(main);
|
||||
}
|
||||
|
||||
private void updateView(final View parentView) {
|
||||
final LineChart chart = (LineChart) parentView.findViewById(R.id.chart);
|
||||
chart.setOnChartGestureListener(new OnChartGestureListener() {
|
||||
@Override
|
||||
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
|
||||
Highlight[] highlights = chart.getHighlighted();
|
||||
if (highlights != null && highlights.length > 0) {
|
||||
gpxItem.chartHighlightPos = highlights[0].getX();
|
||||
|
||||
private TrkSegment getTrackSegment(LineChart chart) {
|
||||
if (segment == null) {
|
||||
List<ILineDataSet> ds = chart.getLineData().getDataSets();
|
||||
if (ds != null && ds.size() > 0) {
|
||||
GPXUtilities.TrkSegment segment = null;
|
||||
for (GPXUtilities.Track t : gpxItem.group.getGpx().tracks) {
|
||||
for (GPXUtilities.TrkSegment s : t.segments) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
||||
segment = s;
|
||||
break;
|
||||
|
@ -163,11 +158,19 @@ public class TrackDetailsMenu {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (segment != null) {
|
||||
}
|
||||
}
|
||||
return segment;
|
||||
}
|
||||
|
||||
private WptPt getPoint(LineChart chart, float pos) {
|
||||
WptPt wpt = null;
|
||||
List<ILineDataSet> ds = chart.getLineData().getDataSets();
|
||||
if (ds != null && ds.size() > 0) {
|
||||
TrkSegment segment = getTrackSegment(chart);
|
||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||
float time = gpxItem.chartHighlightPos * 1000;
|
||||
float time = pos * 1000;
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.time - gpxItem.analysis.startTime >= time) {
|
||||
wpt = p;
|
||||
|
@ -175,7 +178,7 @@ public class TrackDetailsMenu {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
||||
float distance = pos * dataSet.getDivX();
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.distance >= distance) {
|
||||
wpt = p;
|
||||
|
@ -183,19 +186,123 @@ public class TrackDetailsMenu {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return wpt;
|
||||
}
|
||||
|
||||
private QuadRect getRect(LineChart chart, float startPos, float endPos) {
|
||||
double left = 0, right = 0;
|
||||
double top = 0, bottom = 0;
|
||||
List<ILineDataSet> ds = chart.getLineData().getDataSets();
|
||||
if (ds != null && ds.size() > 0) {
|
||||
TrkSegment segment = getTrackSegment(chart);
|
||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||
float startTime = startPos * 1000;
|
||||
float endTime = endPos * 1000;
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.time - gpxItem.analysis.startTime >= startTime &&
|
||||
p.time - gpxItem.analysis.startTime <= endTime) {
|
||||
if (left == 0 && right == 0) {
|
||||
left = p.getLongitude();
|
||||
right = p.getLongitude();
|
||||
top = p.getLatitude();
|
||||
bottom = p.getLatitude();
|
||||
} else {
|
||||
left = Math.min(left, p.getLongitude());
|
||||
right = Math.max(right, p.getLongitude());
|
||||
top = Math.max(top, p.getLatitude());
|
||||
bottom = Math.min(bottom, p.getLatitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float startDistance = startPos * dataSet.getDivX();
|
||||
float endDistance = endPos * dataSet.getDivX();
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.distance >= startDistance && p.distance <= endDistance) {
|
||||
if (left == 0 && right == 0) {
|
||||
left = p.getLongitude();
|
||||
right = p.getLongitude();
|
||||
top = p.getLatitude();
|
||||
bottom = p.getLatitude();
|
||||
} else {
|
||||
left = Math.min(left, p.getLongitude());
|
||||
right = Math.max(right, p.getLongitude());
|
||||
top = Math.max(top, p.getLatitude());
|
||||
bottom = Math.min(bottom, p.getLatitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new QuadRect(left, top, right, bottom);
|
||||
}
|
||||
|
||||
private void fitTrackOnMap(LineChart chart) {
|
||||
QuadRect rect = getRect(chart, chart.getLowestVisibleX(), chart.getHighestVisibleX());
|
||||
if (rect != null) {
|
||||
RotatedTileBox tb = mapActivity.getMapView().getCurrentRotatedTileBox().copy();
|
||||
int tileBoxWidthPx = 0;
|
||||
int tileBoxHeightPx = 0;
|
||||
|
||||
WeakReference<TrackDetailsMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
TrackDetailsMenuFragment f = fragmentRef.get();
|
||||
boolean portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
|
||||
if (!portrait) {
|
||||
tileBoxWidthPx = tb.getPixWidth() - f.getWidth();
|
||||
} else {
|
||||
tileBoxHeightPx = tb.getPixHeight() - f.getHeight();
|
||||
}
|
||||
}
|
||||
mapActivity.getMapView().fitRectToMap(rect.left, rect.right, rect.top, rect.bottom,
|
||||
tileBoxWidthPx, tileBoxHeightPx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void refreshChart(LineChart chart) {
|
||||
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
|
||||
Highlight[] highlights = chart.getHighlighted();
|
||||
if (highlights != null && highlights.length > 0) {
|
||||
gpxItem.chartHighlightPos = highlights[0].getX();
|
||||
WptPt wpt = getPoint(chart, gpxItem.chartHighlightPos);
|
||||
if (wpt != null) {
|
||||
if (gpxItem.route) {
|
||||
mapActivity.getMapLayers().getMapInfoLayer().setSelectedPointLatLon(new LatLon(wpt.lat, wpt.lon));
|
||||
} else {
|
||||
mapActivity.getMapLayers().getGpxLayer().setSelectedPointLatLon(new LatLon(wpt.lat, wpt.lon));
|
||||
}
|
||||
mapActivity.setMapLocation(wpt.lat, wpt.lon);
|
||||
}
|
||||
}
|
||||
//mapActivity.setMapLocation(wpt.lat, wpt.lon);
|
||||
}
|
||||
} else {
|
||||
gpxItem.chartHighlightPos = -1;
|
||||
}
|
||||
fitTrackOnMap(chart);
|
||||
}
|
||||
|
||||
private void updateView(final View parentView) {
|
||||
final LineChart chart = (LineChart) parentView.findViewById(R.id.chart);
|
||||
chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
|
||||
@Override
|
||||
public void onValueSelected(Entry e, Highlight h) {
|
||||
refreshChart(chart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
|
||||
}
|
||||
});
|
||||
chart.setOnChartGestureListener(new OnChartGestureListener() {
|
||||
@Override
|
||||
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
|
||||
refreshChart(chart);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -343,6 +450,8 @@ public class TrackDetailsMenu {
|
|||
xAxis.setBackgroundResource(0);
|
||||
xAxisArrow.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
refreshChart(chart);
|
||||
}
|
||||
|
||||
private void updateChart(LineChart chart) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.osmand.plus.mapcontextmenu.other;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
@ -7,6 +8,7 @@ import android.support.v4.app.FragmentManager;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
@ -61,6 +63,22 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
|
||||
updateInfo();
|
||||
|
||||
ViewTreeObserver vto = mainView.getViewTreeObserver();
|
||||
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
|
||||
ViewTreeObserver obs = mainView.getViewTreeObserver();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
obs.removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
obs.removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
updateInfo();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
|
|
@ -636,7 +636,7 @@ public class MapControlsLayer extends OsmandMapLayer {
|
|||
boolean trackDialogOpened = TrackDetailsMenu.isVisible();
|
||||
boolean showRouteCalculationControls = routePlanningMode ||
|
||||
((app.accessibilityEnabled() || (System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS)) && routeFollowingMode);
|
||||
updateMyLocation(rh, routeDialogOpened);
|
||||
updateMyLocation(rh, routeDialogOpened || trackDialogOpened);
|
||||
boolean showButtons = (showRouteCalculationControls || !routeFollowingMode)
|
||||
&& !isInChangeMarkerPositionMode() && !isInGpxDetailsMode();
|
||||
//routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_gabout_dark : R.drawable.map_directions);
|
||||
|
|
Loading…
Reference in a new issue