Work on gpx details view
This commit is contained in:
parent
b93c380c68
commit
32a0dd426e
15 changed files with 773 additions and 582 deletions
|
@ -6,7 +6,8 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/color_transparent"
|
||||
android:clickable="true"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_bar_layout"
|
||||
|
@ -14,6 +15,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/dashboard_map_toolbar"
|
||||
android:gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:background="@drawable/gradient_toolbar"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
@ -36,7 +38,7 @@
|
|||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp">
|
||||
|
||||
<TextView
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/top_bar_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -45,8 +47,9 @@
|
|||
android:gravity="center_vertical"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textColor="@color/color_white"
|
||||
android:textSize="@dimen/abc_text_size_medium_material"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:text="@string/rendering_category_details"/>
|
||||
|
||||
<TextView
|
||||
|
@ -63,6 +66,8 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -85,7 +90,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/left_axis"
|
||||
android:id="@+id/y_axis"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:layout_weight="1"
|
||||
|
@ -95,7 +100,7 @@
|
|||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/left_axis_icon"
|
||||
android:id="@+id/y_axis_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
|
@ -103,7 +108,7 @@
|
|||
android:src="@drawable/ic_action_altitude_average"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/left_axis_title"
|
||||
android:id="@+id/y_axis_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -113,7 +118,7 @@
|
|||
tools:text="@string/altitude"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/left_axis_arrow"
|
||||
android:id="@+id/y_axis_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
|
@ -122,7 +127,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/right_axis"
|
||||
android:id="@+id/x_axis"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:layout_weight="1"
|
||||
|
@ -139,25 +144,25 @@
|
|||
android:focusable="false"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/right_axis_icon"
|
||||
android:id="@+id/x_axis_icon"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/list_content_padding"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:src="@drawable/ic_action_speed"/>
|
||||
android:src="@drawable/ic_action_marker_dark"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/right_axis_title"
|
||||
android:id="@+id/x_axis_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
tools:text="@string/map_widget_speed"/>
|
||||
tools:text="@string/distance"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/right_axis_arrow"
|
||||
android:id="@+id/x_axis_arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="@dimen/list_content_padding"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="shared_string_slope">Slope</string>
|
||||
<string name="add_new_folder">Add new folder</string>
|
||||
<string name="points_delete_multiple_succesful">Point(s) deleted successfully.</string>
|
||||
<string name="points_delete_multiple">You are going to delete %1$d point(s). Are you sure?</string>
|
||||
|
|
|
@ -92,10 +92,14 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
public static class Elevation {
|
||||
public double distance, elevation;
|
||||
public double distance;
|
||||
public int time;
|
||||
public double elevation;
|
||||
}
|
||||
public static class Speed {
|
||||
public double distance, speed;
|
||||
public double distance;
|
||||
public int time;
|
||||
public double speed;
|
||||
}
|
||||
|
||||
public static class WptPt extends GPXExtensions implements LocationPoint {
|
||||
|
@ -311,6 +315,7 @@ public class GPXUtilities {
|
|||
float totalElevation = 0;
|
||||
int elevationPoints = 0;
|
||||
int speedCount = 0;
|
||||
int timeDiff = 0;
|
||||
double totalSpeedSum = 0;
|
||||
points = 0;
|
||||
|
||||
|
@ -443,6 +448,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;
|
||||
timeDiff = (int)((point.time - prev.time) / 1000);
|
||||
|
||||
// Motion detection:
|
||||
// speed > 0 uses GPS chipset's motion detection
|
||||
|
@ -459,8 +466,10 @@ public class GPXUtilities {
|
|||
|
||||
}
|
||||
|
||||
elevation1.time = timeDiff;
|
||||
elevation1.distance = (j > 0) ? calculations[0] : 0;
|
||||
elevationData.add(elevation1);
|
||||
speed1.time = timeDiff;
|
||||
speed1.distance = elevation1.distance;
|
||||
speedData.add(speed1);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import net.osmand.plus.GPXUtilities.WptPt;
|
|||
import net.osmand.plus.OsmandSettings.MetricsConstants;
|
||||
import net.osmand.plus.activities.SavingTrackHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
@ -662,6 +664,10 @@ public class GpxSelectionHelper {
|
|||
public Bitmap image;
|
||||
public boolean expanded;
|
||||
|
||||
public WptPt locationOnMap;
|
||||
public GPXDataSetType chartType;
|
||||
public GPXDataSetAxisType chartAxisType = GPXDataSetAxisType.DISTANCE;
|
||||
|
||||
public Matrix chartMatrix;
|
||||
public float chartHighlightPos = -1f;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class OsmAndFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
public static String getFormattedDurationShort(int seconds, OsmandApplication ctx) {
|
||||
public static String getFormattedDurationShort(int seconds) {
|
||||
int hours = seconds / (60 * 60);
|
||||
int minutes = (seconds / 60) % 60;
|
||||
int sec = seconds % 60;
|
||||
|
|
|
@ -54,6 +54,8 @@ import net.osmand.plus.AppInitializer;
|
|||
import net.osmand.plus.AppInitializer.AppInitializeListener;
|
||||
import net.osmand.plus.AppInitializer.InitEvents;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.MapMarkersHelper.MapMarker;
|
||||
import net.osmand.plus.MapMarkersHelper.MapMarkerChangedListener;
|
||||
import net.osmand.plus.OnDismissDialogFragmentListener;
|
||||
|
@ -88,6 +90,8 @@ import net.osmand.plus.mapcontextmenu.MapContextMenuFragment;
|
|||
import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment;
|
||||
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
|
||||
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenuFragment;
|
||||
import net.osmand.plus.render.RendererRegistry;
|
||||
import net.osmand.plus.resources.ResourceManager;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
|
@ -442,6 +446,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
|
|||
showQuickSearch(ShowQuickSearchMode.CURRENT, false);
|
||||
return;
|
||||
}
|
||||
if (TrackDetailsMenu.isVisible()) {
|
||||
getMapLayers().getMapControlsLayer().getTrackDetailsMenu().hide();
|
||||
}
|
||||
if (prevActivityIntent != null && getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||
prevActivityIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
LatLon loc = getMapLocation();
|
||||
|
@ -780,7 +787,11 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
|
|||
}
|
||||
//mapContextMenu.setMapZoom(settings.getMapZoomToShow());
|
||||
mapContextMenu.setMapZoom(tb.getZoom());
|
||||
if (MapRouteInfoMenu.isVisible()) {
|
||||
if (toShow instanceof GpxDisplayItem) {
|
||||
TrackDetailsMenu trackDetailsMenu = mapLayers.getMapControlsLayer().getTrackDetailsMenu();
|
||||
trackDetailsMenu.setGpxItem((GpxDisplayItem) toShow);
|
||||
trackDetailsMenu.show();
|
||||
} else if (MapRouteInfoMenu.isVisible()) {
|
||||
mapContextMenu.showMinimized(latLonToShow, mapLabelToShow, toShow);
|
||||
mapLayers.getMapControlsLayer().getMapRouteInfoMenu().updateMenu();
|
||||
MapRouteInfoMenu.showLocationOnMap(this, latLonToShow.getLatitude(), latLonToShow.getLongitude());
|
||||
|
|
|
@ -43,6 +43,7 @@ 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.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
|
||||
import net.osmand.plus.routing.RouteDirectionInfo;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
|
@ -227,10 +228,12 @@ public class ShowRouteInfoDialogFragment extends DialogFragment {
|
|||
GPXTrackAnalysis analysis = gpx.getAnalysis(0);
|
||||
if (analysis.totalDistance > 0) {
|
||||
List<ILineDataSet> dataSets = new ArrayList<>();
|
||||
GpxUiHelper.OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, mChart, analysis, false, true);
|
||||
GpxUiHelper.OrderedLineDataSet elevationDataSet =
|
||||
GpxUiHelper.createGPXElevationDataSet(app, mChart, analysis, GPXDataSetAxisType.DISTANCE, false, true);
|
||||
dataSets.add(elevationDataSet);
|
||||
if (analysis.elevationData.size() > 1) {
|
||||
GpxUiHelper.OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, mChart, analysis, elevationDataSet.getValues(), true, true);
|
||||
GpxUiHelper.OrderedLineDataSet slopeDataSet =
|
||||
GpxUiHelper.createGPXSlopeDataSet(app, mChart, analysis, GPXDataSetAxisType.DISTANCE, elevationDataSet.getValues(), true, true);
|
||||
dataSets.add(slopeDataSet);
|
||||
}
|
||||
LineData data = new LineData(dataSets);
|
||||
|
|
|
@ -36,6 +36,7 @@ public class TrackActivity extends TabActivity {
|
|||
public static final String TRACK_FILE_NAME = "TRACK_FILE_NAME";
|
||||
public static final String CURRENT_RECORDING = "CURRENT_RECORDING";
|
||||
protected List<WeakReference<Fragment>> fragList = new ArrayList<>();
|
||||
protected PagerSlidingTabStrip slidingTabLayout;
|
||||
private File file = null;
|
||||
private GPXFile gpxFile;
|
||||
private GpxDataItem gpxDataItem;
|
||||
|
@ -43,6 +44,7 @@ public class TrackActivity extends TabActivity {
|
|||
private long modifiedTime = -1;
|
||||
private List<GpxDisplayGroup> displayGroups;
|
||||
private List<GpxDisplayGroup> originalGroups = new ArrayList<>();
|
||||
private boolean stopped = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
|
@ -69,7 +71,7 @@ public class TrackActivity extends TabActivity {
|
|||
}
|
||||
setContentView(R.layout.tab_content);
|
||||
|
||||
final PagerSlidingTabStrip slidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs);
|
||||
slidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs);
|
||||
if (slidingTabLayout != null) {
|
||||
slidingTabLayout.setShouldExpand(true);
|
||||
|
||||
|
@ -85,34 +87,54 @@ public class TrackActivity extends TabActivity {
|
|||
|
||||
@Override
|
||||
protected GPXFile doInBackground(Void... params) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
GPXFile result = null;
|
||||
if (file == null) {
|
||||
return getMyApplication().getSavingTrackHelper().getCurrentGpx();
|
||||
result = getMyApplication().getSavingTrackHelper().getCurrentGpx();
|
||||
} else {
|
||||
SelectedGpxFile selectedGpxFile = getMyApplication().getSelectedGpxHelper().getSelectedFileByPath(file.getAbsolutePath());
|
||||
if (selectedGpxFile != null && selectedGpxFile.getGpxFile() != null) {
|
||||
result = selectedGpxFile.getGpxFile();
|
||||
} else {
|
||||
result = GPXUtilities.loadGPXFile(TrackActivity.this, file);
|
||||
}
|
||||
}
|
||||
return GPXUtilities.loadGPXFile(TrackActivity.this, file);
|
||||
if (result != null) {
|
||||
while (System.currentTimeMillis() - startTime < 200) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPostExecute(GPXFile result) {
|
||||
setSupportProgressBarIndeterminateVisibility(false);
|
||||
|
||||
setGpx(result);
|
||||
setGpxDataItem(getMyApplication().getGpxDatabase().getItem(file));
|
||||
if (!stopped) {
|
||||
setGpx(result);
|
||||
setGpxDataItem(getMyApplication().getGpxDatabase().getItem(file));
|
||||
|
||||
for (WeakReference<Fragment> f : fragList) {
|
||||
Fragment frag = f.get();
|
||||
if (frag instanceof TrackSegmentFragment) {
|
||||
((TrackSegmentFragment) frag).setContent();
|
||||
} else if (frag instanceof TrackPointFragment) {
|
||||
((TrackPointFragment) frag).setContent();
|
||||
for (WeakReference<Fragment> f : fragList) {
|
||||
Fragment frag = f.get();
|
||||
if (frag instanceof TrackSegmentFragment) {
|
||||
((TrackSegmentFragment) frag).updateContent();
|
||||
} else if (frag instanceof TrackPointFragment) {
|
||||
((TrackPointFragment) frag).setContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab(
|
||||
getTabIndicator(R.string.gpx_track, TrackSegmentFragment.class));
|
||||
if (isHavingWayPoints() || isHavingRoutePoints()) {
|
||||
((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab(
|
||||
getTabIndicator(R.string.points, TrackPointFragment.class));
|
||||
} else {
|
||||
slidingTabLayout.setVisibility(View.GONE);
|
||||
getSupportActionBar().setElevation(AndroidUtils.dpToPx(getMyApplication(), 4f));
|
||||
getTabIndicator(R.string.gpx_track, TrackSegmentFragment.class));
|
||||
if (isHavingWayPoints() || isHavingRoutePoints()) {
|
||||
((OsmandFragmentPagerAdapter) mViewPager.getAdapter()).addTab(
|
||||
getTabIndicator(R.string.points, TrackPointFragment.class));
|
||||
} else {
|
||||
slidingTabLayout.setVisibility(View.GONE);
|
||||
getSupportActionBar().setElevation(AndroidUtils.dpToPx(getMyApplication(), 4f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute((Void) null);
|
||||
|
@ -164,7 +186,6 @@ public class TrackActivity extends TabActivity {
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
public OsmandApplication getMyApplication() {
|
||||
|
@ -175,8 +196,12 @@ public class TrackActivity extends TabActivity {
|
|||
protected void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
public Toolbar getClearToolbar(boolean visible) {
|
||||
final Toolbar tb = (Toolbar) findViewById(R.id.bottomControls);
|
||||
|
|
|
@ -9,8 +9,6 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
@ -36,7 +34,6 @@ import android.widget.ImageView;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.github.mikephil.charting.animation.ChartAnimator;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.AxisBase;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
|
@ -45,18 +42,13 @@ import com.github.mikephil.charting.components.XAxis;
|
|||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
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.formatter.IFillFormatter;
|
||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||
import com.github.mikephil.charting.highlight.Highlight;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
import com.github.mikephil.charting.renderer.LineChartRenderer;
|
||||
import com.github.mikephil.charting.utils.MPPointF;
|
||||
import com.github.mikephil.charting.utils.Transformer;
|
||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.CallbackWithObject;
|
||||
|
@ -67,6 +59,7 @@ import net.osmand.plus.GPXUtilities;
|
|||
import net.osmand.plus.GPXUtilities.Elevation;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GPXUtilities.Speed;
|
||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.IconsCache;
|
||||
|
@ -874,8 +867,6 @@ public class GpxUiHelper {
|
|||
mChart.setExtraTopOffset(24f);
|
||||
mChart.setExtraBottomOffset(16f);
|
||||
|
||||
mChart.setRenderer(new SplineRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler()));
|
||||
|
||||
// create a custom MarkerView (extend MarkerView) and specify the layout
|
||||
// to use for it
|
||||
GPXMarkerView mv = new GPXMarkerView(mChart.getContext());
|
||||
|
@ -914,7 +905,7 @@ public class GpxUiHelper {
|
|||
legend.setEnabled(false);
|
||||
}
|
||||
|
||||
private static float getXAxisParams(OsmandApplication ctx, float meters, float[] koef, StringBuilder format, StringBuilder unit) {
|
||||
private static float setupXAxisDistance(OsmandApplication ctx, XAxis xAxis, float meters) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
float divX;
|
||||
|
@ -970,33 +961,70 @@ public class GpxUiHelper {
|
|||
}
|
||||
}
|
||||
|
||||
koef[0] = divX;
|
||||
if (fmt != null) {
|
||||
format.append(fmt);
|
||||
}
|
||||
unit.append(ctx.getString(mainUnitStr));
|
||||
return granularity;
|
||||
final String formatX = fmt;
|
||||
final String mainUnitX = ctx.getString(mainUnitStr);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return divX;
|
||||
}
|
||||
|
||||
private static List<Entry> calculateElevationArray(GPXTrackAnalysis analysis, float divX, float convEle) {
|
||||
private static float setupXAxisTime(XAxis xAxis, long timeSpan) {
|
||||
|
||||
final boolean useHours = timeSpan / 3600000 > 0;
|
||||
xAxis.setGranularity(1f);
|
||||
xAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
public String getFormattedValue(float value, AxisBase axis) {
|
||||
int seconds = (int)value;
|
||||
if (useHours) {
|
||||
int hours = seconds / (60 * 60);
|
||||
int minutes = (seconds / 60) % 60;
|
||||
int sec = seconds % 60;
|
||||
return hours + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (sec < 10 ? "0" + sec : sec);
|
||||
} else {
|
||||
int minutes = (seconds / 60) % 60;
|
||||
int sec = seconds % 60;
|
||||
return (minutes < 10 ? "0" + minutes : minutes) + ":" + (sec < 10 ? "0" + sec : sec);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return 1f;
|
||||
}
|
||||
|
||||
private static List<Entry> calculateElevationArray(GPXTrackAnalysis analysis, GPXDataSetAxisType axisType,
|
||||
float divX, float convEle) {
|
||||
List<Entry> values = new ArrayList<>();
|
||||
List<Elevation> elevationData = analysis.elevationData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
float prevYM;
|
||||
float elev;
|
||||
float prevElevOrig = -80000;
|
||||
float prevElev = 0;
|
||||
int i = -1;
|
||||
int lastIndex = elevationData.size() - 1;
|
||||
float shift = 0f;
|
||||
Entry lastEntry = null;
|
||||
float lastXSameY = -1;
|
||||
boolean hasSameY = false;
|
||||
float x;
|
||||
for (Elevation e : elevationData) {
|
||||
i++;
|
||||
if (e.distance > 0) {
|
||||
nextX += (float) e.distance / divX;
|
||||
x = axisType == GPXDataSetAxisType.TIME ? e.time : (float) e.distance;
|
||||
if (x > 0) {
|
||||
nextX += x / divX;
|
||||
elev = (float) e.elevation;
|
||||
if (prevElevOrig != -80000) {
|
||||
if (elev > prevElevOrig) {
|
||||
|
@ -1026,36 +1054,23 @@ public class GpxUiHelper {
|
|||
return values;
|
||||
}
|
||||
|
||||
public static OrderedLineDataSet createGPXElevationDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
public static OrderedLineDataSet createGPXElevationDataSet(OsmandApplication ctx, LineChart mChart,
|
||||
GPXTrackAnalysis analysis,
|
||||
GPXDataSetAxisType axisType,
|
||||
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();
|
||||
|
||||
float divX;
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
||||
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
||||
} else {
|
||||
divX = setupXAxisDistance(ctx, xAxis, analysis.totalDistance);
|
||||
}
|
||||
|
||||
final String mainUnitY = useFeet ? ctx.getString(R.string.foot) : ctx.getString(R.string.m);
|
||||
|
||||
|
@ -1069,6 +1084,7 @@ public class GpxUiHelper {
|
|||
yAxis.setTextColor(ActivityCompat.getColor(mChart.getContext(), R.color.gpx_chart_blue));
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.gpx_chart_blue_grid));
|
||||
yAxis.setGranularity(1f);
|
||||
yAxis.resetAxisMinimum();
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
|
@ -1077,10 +1093,13 @@ public class GpxUiHelper {
|
|||
}
|
||||
});
|
||||
|
||||
List<Entry> values = calculateElevationArray(analysis, divX, convEle);
|
||||
List<Entry> values = calculateElevationArray(analysis, axisType, divX, convEle);
|
||||
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "", GPXDataSetType.ALTITUDE);
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "", GPXDataSetType.ALTITUDE, axisType);
|
||||
dataSet.priority = (float) (analysis.avgElevation - analysis.minElevation) * convEle;
|
||||
dataSet.divX = divX;
|
||||
dataSet.mulY = convEle;
|
||||
dataSet.divY = Float.NaN;
|
||||
dataSet.units = mainUnitY;
|
||||
|
||||
dataSet.setColor(ContextCompat.getColor(mChart.getContext(), R.color.gpx_chart_blue));
|
||||
|
@ -1107,7 +1126,6 @@ public class GpxUiHelper {
|
|||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
//dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
//dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
|
||||
dataSet.setFillFormatter(new IFillFormatter() {
|
||||
@Override
|
||||
|
@ -1121,41 +1139,20 @@ public class GpxUiHelper {
|
|||
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) {
|
||||
public static OrderedLineDataSet createGPXSpeedDataSet(OsmandApplication ctx, LineChart mChart,
|
||||
GPXTrackAnalysis analysis,
|
||||
GPXDataSetAxisType axisType,
|
||||
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();
|
||||
|
||||
float divX;
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
||||
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
||||
} else {
|
||||
divX = setupXAxisDistance(ctx, xAxis, analysis.totalDistance);
|
||||
}
|
||||
|
||||
OsmandSettings.SpeedConstants sps = settings.SPEED_SYSTEM.get();
|
||||
float mulSpeed = Float.NaN;
|
||||
|
@ -1194,12 +1191,14 @@ public class GpxUiHelper {
|
|||
});
|
||||
|
||||
ArrayList<Entry> values = new ArrayList<>();
|
||||
List<GPXUtilities.Speed> speedData = analysis.speedData;
|
||||
List<Speed> speedData = analysis.speedData;
|
||||
float nextX = 0;
|
||||
float nextY;
|
||||
for (GPXUtilities.Speed s : speedData) {
|
||||
if (s.distance > 0) {
|
||||
nextX += (float) s.distance / divX;
|
||||
float x;
|
||||
for (Speed s : speedData) {
|
||||
x = axisType == GPXDataSetAxisType.TIME ? s.time : (float) s.distance;
|
||||
if (x > 0) {
|
||||
nextX += x / divX;
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
nextY = (float) (s.speed * mulSpeed);
|
||||
} else {
|
||||
|
@ -1212,13 +1211,21 @@ public class GpxUiHelper {
|
|||
}
|
||||
}
|
||||
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "", GPXDataSetType.SPEED);
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(values, "", GPXDataSetType.SPEED, axisType);
|
||||
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
dataSet.priority = analysis.avgSpeed * mulSpeed;
|
||||
} else {
|
||||
dataSet.priority = divSpeed / analysis.avgSpeed;
|
||||
}
|
||||
dataSet.divX = divX;
|
||||
if (Float.isNaN(divSpeed)) {
|
||||
dataSet.mulY = mulSpeed;
|
||||
dataSet.divY = Float.NaN;
|
||||
} else {
|
||||
dataSet.divY = divSpeed;
|
||||
dataSet.mulY = Float.NaN;
|
||||
}
|
||||
dataSet.units = mainUnitY;
|
||||
|
||||
dataSet.setColor(ContextCompat.getColor(mChart.getContext(), R.color.gpx_chart_orange));
|
||||
|
@ -1251,15 +1258,11 @@ public class GpxUiHelper {
|
|||
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 OrderedLineDataSet createGPXSlopeDataSet(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, List<Entry> eleValues, boolean useRightAxis, boolean drawFilled) {
|
||||
public static OrderedLineDataSet createGPXSlopeDataSet(OsmandApplication ctx, LineChart mChart,
|
||||
GPXTrackAnalysis analysis,
|
||||
GPXDataSetAxisType axisType,
|
||||
List<Entry> eleValues,
|
||||
boolean useRightAxis, boolean drawFilled) {
|
||||
OsmandSettings settings = ctx.getSettings();
|
||||
boolean light = settings.isLightContent();
|
||||
OsmandSettings.MetricsConstants mc = settings.METRIC_SYSTEM.get();
|
||||
|
@ -1267,28 +1270,13 @@ public class GpxUiHelper {
|
|||
final float convEle = useFeet ? 3.28084f : 1.0f;
|
||||
final float totalDistance = analysis.totalDistance;
|
||||
|
||||
float[] koef = new float[] { 1f };
|
||||
StringBuilder fmt = new StringBuilder();
|
||||
StringBuilder unitX = new StringBuilder();
|
||||
|
||||
float granularity = getXAxisParams(ctx, totalDistance, koef, fmt, unitX);
|
||||
float divX = koef[0];
|
||||
final String formatX = fmt.toString();
|
||||
final String mainUnitX = unitX.toString();
|
||||
|
||||
float divX;
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (axisType == GPXDataSetAxisType.TIME && analysis.isTimeSpecified()) {
|
||||
divX = setupXAxisTime(xAxis, analysis.timeSpan);
|
||||
} else {
|
||||
divX = setupXAxisDistance(ctx, xAxis, analysis.totalDistance);
|
||||
}
|
||||
|
||||
final String mainUnitY = "%";
|
||||
|
||||
|
@ -1302,6 +1290,7 @@ public class GpxUiHelper {
|
|||
yAxis.setTextColor(ActivityCompat.getColor(mChart.getContext(), R.color.gpx_chart_green));
|
||||
yAxis.setGridColor(ActivityCompat.getColor(mChart.getContext(), R.color.gpx_chart_green_grid));
|
||||
yAxis.setGranularity(1f);
|
||||
yAxis.resetAxisMinimum();
|
||||
yAxis.setValueFormatter(new IAxisValueFormatter() {
|
||||
|
||||
@Override
|
||||
|
@ -1311,8 +1300,8 @@ public class GpxUiHelper {
|
|||
});
|
||||
|
||||
List<Entry> values;
|
||||
if (eleValues == null) {
|
||||
values = calculateElevationArray(analysis, 1f, 1f);
|
||||
if (eleValues == null || axisType == GPXDataSetAxisType.TIME) {
|
||||
values = calculateElevationArray(analysis, GPXDataSetAxisType.DISTANCE, 1f, 1f);
|
||||
} else {
|
||||
values = new ArrayList<>(eleValues.size());
|
||||
for (Entry e : eleValues) {
|
||||
|
@ -1328,6 +1317,12 @@ public class GpxUiHelper {
|
|||
|
||||
double STEP = 5;
|
||||
|
||||
float timeDistKoef = 1f;
|
||||
if (axisType == GPXDataSetAxisType.TIME) {
|
||||
timeDistKoef = analysis.timeSpan / totalDistance / 1000;
|
||||
divX = 1f;
|
||||
}
|
||||
|
||||
double[] calculatedDist = new double[(int) (totalDistance / STEP) + 1];
|
||||
double[] calculatedH = new double[(int) (totalDistance / STEP) + 1];
|
||||
int nextW = 0;
|
||||
|
@ -1350,7 +1345,7 @@ public class GpxUiHelper {
|
|||
|
||||
int index = (int) ((SLOPE_PROXIMITY / STEP) / 2);
|
||||
for (int k = 0; k < calculatedSlopeDist.length; k++) {
|
||||
calculatedSlopeDist[k] = calculatedDist[index + k];
|
||||
calculatedSlopeDist[k] = calculatedDist[index + k] * timeDistKoef;
|
||||
calculatedSlope[k] = (calculatedH[ 2 * index + k] - calculatedH[k]) * 100 / SLOPE_PROXIMITY;
|
||||
if (Double.isNaN(calculatedSlope[k])) {
|
||||
calculatedSlope[k] = 0;
|
||||
|
@ -1384,7 +1379,8 @@ public class GpxUiHelper {
|
|||
slopeValues.add(lastEntry);
|
||||
}
|
||||
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(slopeValues, "", GPXDataSetType.SLOPE);
|
||||
OrderedLineDataSet dataSet = new OrderedLineDataSet(slopeValues, "", GPXDataSetType.SLOPE, axisType);
|
||||
dataSet.divX = divX;
|
||||
dataSet.units = mainUnitY;
|
||||
|
||||
dataSet.setColor(ContextCompat.getColor(mChart.getContext(), R.color.gpx_chart_green));
|
||||
|
@ -1411,7 +1407,6 @@ public class GpxUiHelper {
|
|||
dataSet.setHighLightColor(light ? mChart.getResources().getColor(R.color.secondary_text_light) : mChart.getResources().getColor(R.color.secondary_text_dark));
|
||||
|
||||
//dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
//dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
|
||||
/*
|
||||
dataSet.setFillFormatter(new IFillFormatter() {
|
||||
|
@ -1427,51 +1422,108 @@ public class GpxUiHelper {
|
|||
return dataSet;
|
||||
}
|
||||
|
||||
public static void setGPXSlopeChartData(OsmandApplication ctx, LineChart mChart, GPXTrackAnalysis analysis, boolean useRightAxis, boolean drawFilled) {
|
||||
LineDataSet dataSet = createGPXSlopeDataSet(ctx, mChart, analysis, null, useRightAxis, drawFilled);
|
||||
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
|
||||
dataSets.add(dataSet);
|
||||
LineData data = new LineData(dataSets);
|
||||
mChart.setData(data);
|
||||
public enum GPXDataSetType {
|
||||
ALTITUDE(R.string.altitude, R.drawable.ic_action_altitude_average),
|
||||
SPEED(R.string.map_widget_speed, R.drawable.ic_action_speed),
|
||||
SLOPE(R.string.shared_string_slope, R.drawable.ic_action_altitude_ascent);
|
||||
|
||||
private int stringId;
|
||||
private int imageId;
|
||||
|
||||
private GPXDataSetType(int stringId, int imageId) {
|
||||
this.stringId = stringId;
|
||||
this.imageId = imageId;
|
||||
}
|
||||
|
||||
public String getName(Context ctx) {
|
||||
return ctx.getString(stringId);
|
||||
}
|
||||
|
||||
public int getStringId() {
|
||||
return stringId;
|
||||
}
|
||||
|
||||
public int getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
public Drawable getImageDrawable(OsmandApplication app) {
|
||||
return app.getIconsCache().getThemedIcon(imageId);
|
||||
}
|
||||
}
|
||||
|
||||
public enum GPXDataSetType {
|
||||
ALTITUDE,
|
||||
SPEED,
|
||||
SLOPE
|
||||
public enum GPXDataSetAxisType {
|
||||
DISTANCE(R.string.distance, R.drawable.ic_action_marker_dark),
|
||||
TIME(R.string.shared_string_time, R.drawable.ic_action_time);
|
||||
|
||||
private int stringId;
|
||||
private int imageId;
|
||||
|
||||
private GPXDataSetAxisType(int stringId, int imageId) {
|
||||
this.stringId = stringId;
|
||||
this.imageId = imageId;
|
||||
}
|
||||
|
||||
public String getName(Context ctx) {
|
||||
return ctx.getString(stringId);
|
||||
}
|
||||
|
||||
public int getStringId() {
|
||||
return stringId;
|
||||
}
|
||||
|
||||
public int getImageId() {
|
||||
return imageId;
|
||||
}
|
||||
|
||||
public Drawable getImageDrawable(OsmandApplication app) {
|
||||
return app.getIconsCache().getThemedIcon(imageId);
|
||||
}
|
||||
}
|
||||
|
||||
public static class OrderedLineDataSet extends LineDataSet {
|
||||
|
||||
private GPXDataSetType dataSetType;
|
||||
private GPXDataSetAxisType dataSetAxisType;
|
||||
|
||||
public float priority;
|
||||
public String units;
|
||||
public List<Segment> spline;
|
||||
float priority;
|
||||
String units;
|
||||
float divX = 1f;
|
||||
float divY = 1f;
|
||||
float mulY = 1f;
|
||||
|
||||
public OrderedLineDataSet(List<Entry> yVals, String label, GPXDataSetType dataSetType) {
|
||||
OrderedLineDataSet(List<Entry> yVals, String label, GPXDataSetType dataSetType, GPXDataSetAxisType dataSetAxisType) {
|
||||
super(yVals, label);
|
||||
this.dataSetType = dataSetType;
|
||||
|
||||
/*
|
||||
List<Point2D> points = new ArrayList<>(yVals.size());
|
||||
for (Entry e : yVals) {
|
||||
points.add(new Point2D(e.getX(), e.getY()));
|
||||
}
|
||||
spline = calculateSpline(points);
|
||||
*/
|
||||
this.dataSetAxisType = dataSetAxisType;
|
||||
}
|
||||
|
||||
public GPXDataSetType getDataSetType() {
|
||||
return dataSetType;
|
||||
}
|
||||
|
||||
public Segment getSegmentForEntryIndex(int index) {
|
||||
if (index < spline.size()) {
|
||||
return spline.get(index);
|
||||
} else {
|
||||
return spline.get(spline.size() - 1);
|
||||
}
|
||||
public GPXDataSetAxisType getDataSetAxisType() {
|
||||
return dataSetAxisType;
|
||||
}
|
||||
|
||||
public float getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public float getDivX() {
|
||||
return divX;
|
||||
}
|
||||
|
||||
public float getDivY() {
|
||||
return divY;
|
||||
}
|
||||
|
||||
public float getMulY() {
|
||||
return mulY;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1613,7 +1665,7 @@ public class GpxUiHelper {
|
|||
private long fileSize;
|
||||
private boolean selected;
|
||||
|
||||
public GPXInfo(String fileName, long lastModified, long fileSize) {
|
||||
GPXInfo(String fileName, long lastModified, long fileSize) {
|
||||
this.fileName = fileName;
|
||||
this.lastModified = lastModified;
|
||||
this.fileSize = fileSize;
|
||||
|
@ -1639,228 +1691,4 @@ public class GpxUiHelper {
|
|||
this.selected = selected;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Point2D {
|
||||
double x, y;
|
||||
|
||||
Point2D() {
|
||||
x = 0.0;
|
||||
y = 0.0;
|
||||
}
|
||||
|
||||
Point2D(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Point2D(Point2D p) {
|
||||
this.x = p.x;
|
||||
this.y = p.y;
|
||||
}
|
||||
|
||||
Point2D minus(Point2D point) {
|
||||
return new Point2D(x - point.x, y - point.y);
|
||||
}
|
||||
|
||||
Point2D plus(Point2D point) {
|
||||
return new Point2D(x + point.x, y + point.y);
|
||||
}
|
||||
|
||||
Point2D mult(double v) {
|
||||
return new Point2D(x * v, y * v);
|
||||
}
|
||||
|
||||
void thisMinus(Point2D point) {
|
||||
x -= point.x;
|
||||
y -= point.y;
|
||||
}
|
||||
|
||||
void thisPlus(Point2D point) {
|
||||
x += point.x;
|
||||
y += point.y;
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
double l = Math.sqrt(x * x + y * y);
|
||||
x /= l;
|
||||
y /= l;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Segment {
|
||||
Point2D[] points = new Point2D[4];
|
||||
|
||||
Segment() {
|
||||
}
|
||||
|
||||
void calc(double t, Point2D p)
|
||||
{
|
||||
double t2 = t * t;
|
||||
double t3 = t2 * t;
|
||||
double nt = 1.0 - t;
|
||||
double nt2 = nt * nt;
|
||||
double nt3 = nt2 * nt;
|
||||
p.x = nt3 * points[0].x + 3.0 * t * nt2 * points[1].x + 3.0 * t2 * nt * points[2].x + t3 * points[3].x;
|
||||
p.y = nt3 * points[0].y + 3.0 * t * nt2 * points[1].y + 3.0 * t2 * nt * points[2].y + t3 * points[3].y;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Segment> calculateSpline(List<Point2D> values) {
|
||||
final double EPSILON = 1.0e-5;
|
||||
|
||||
int n = values.size() - 1;
|
||||
|
||||
if (n < 2)
|
||||
return null;
|
||||
|
||||
List<Segment> bezier = new ArrayList<>(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
bezier.add(new Segment());
|
||||
}
|
||||
|
||||
Point2D tgL = new Point2D();
|
||||
Point2D tgR = new Point2D();
|
||||
Point2D cur;
|
||||
Point2D next = values.get(1).minus(values.get(0));
|
||||
next.normalize();
|
||||
|
||||
double l1, l2, tmp, x;
|
||||
|
||||
--n;
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
bezier.get(i).points[0] = new Point2D(values.get(i));
|
||||
bezier.get(i).points[1] = new Point2D(values.get(i));
|
||||
bezier.get(i).points[2] = new Point2D(values.get(i + 1));
|
||||
bezier.get(i).points[3] = new Point2D(values.get(i + 1));
|
||||
|
||||
cur = next;
|
||||
next = values.get(i + 2).minus(values.get(i + 1));
|
||||
next.normalize();
|
||||
|
||||
tgL = tgR;
|
||||
|
||||
tgR = cur.plus(next);
|
||||
tgR.normalize();
|
||||
|
||||
if (Math.abs(values.get(i + 1).y - values.get(i).y) < EPSILON)
|
||||
{
|
||||
l1 = 0.0;
|
||||
l2 = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = values.get(i + 1).x - values.get(i).x;
|
||||
l1 = Math.abs(tgL.x) > EPSILON ? tmp / (2.0 * tgL.x) : 1.0;
|
||||
l2 = Math.abs(tgR.x) > EPSILON ? tmp / (2.0 * tgR.x) : 1.0;
|
||||
}
|
||||
|
||||
if (Math.abs(tgL.x) > EPSILON && Math.abs(tgR.x) > EPSILON)
|
||||
{
|
||||
tmp = tgL.y / tgL.x - tgR.y / tgR.x;
|
||||
if (Math.abs(tmp) > EPSILON)
|
||||
{
|
||||
x = (values.get(i + 1).y - tgR.y / tgR.x * values.get(i + 1).x - values.get(i).y + tgL.y / tgL.x * values.get(i).x) / tmp;
|
||||
if (x > values.get(i).x && x < values.get(i + 1).x)
|
||||
{
|
||||
if (tgL.y > 0.0)
|
||||
{
|
||||
if (l1 > l2)
|
||||
l1 = 0.0;
|
||||
else
|
||||
l2 = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (l1 < l2)
|
||||
l1 = 0.0;
|
||||
else
|
||||
l2 = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bezier.get(i).points[1].thisPlus(tgL.mult(l1));
|
||||
bezier.get(i).points[2].thisMinus(tgR.mult(l2));
|
||||
}
|
||||
|
||||
l1 = Math.abs(tgL.x) > EPSILON ? (values.get(n + 1).x - values.get(n).x) / (2.0 * tgL.x) : 1.0;
|
||||
|
||||
bezier.get(n).points[0] = new Point2D(values.get(n));
|
||||
bezier.get(n).points[1] = new Point2D(values.get(n));
|
||||
bezier.get(n).points[2] = new Point2D(values.get(n + 1));
|
||||
bezier.get(n).points[3] = new Point2D(values.get(n + 1));
|
||||
bezier.get(n).points[1].thisPlus(tgR.mult(l1));
|
||||
|
||||
return bezier;
|
||||
}
|
||||
|
||||
public static class SplineRenderer extends LineChartRenderer {
|
||||
|
||||
public SplineRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
|
||||
super(chart, animator, viewPortHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawCubicBezier(ILineDataSet dataSet) {
|
||||
if (!(dataSet instanceof OrderedLineDataSet)) {
|
||||
super.drawCubicBezier(dataSet);
|
||||
} else {
|
||||
|
||||
OrderedLineDataSet ds = (OrderedLineDataSet) dataSet;
|
||||
|
||||
float phaseY = mAnimator.getPhaseY();
|
||||
|
||||
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
|
||||
|
||||
mXBounds.set(mChart, dataSet);
|
||||
|
||||
cubicPath.reset();
|
||||
|
||||
if (mXBounds.range >= 1) {
|
||||
|
||||
final int firstIndex = mXBounds.min + 1;
|
||||
final int lastIndex = mXBounds.min + mXBounds.range;
|
||||
|
||||
Segment seg = ds.getSegmentForEntryIndex(Math.max(firstIndex - 1, 0));
|
||||
|
||||
if (seg == null) return;
|
||||
|
||||
// let the spline start
|
||||
cubicPath.moveTo((float) seg.points[0].x, (float) seg.points[0].y * phaseY);
|
||||
|
||||
for (int j = firstIndex; j <= lastIndex; j++) {
|
||||
|
||||
seg = ds.getSegmentForEntryIndex(j);
|
||||
|
||||
cubicPath.cubicTo((float) seg.points[1].x, (float) seg.points[1].y * phaseY,
|
||||
(float) seg.points[2].x, (float) seg.points[2].y * phaseY,
|
||||
(float) seg.points[3].x, (float) seg.points[3].y * phaseY);
|
||||
}
|
||||
}
|
||||
|
||||
// if filled is enabled, close the path
|
||||
if (ds.isDrawFilledEnabled()) {
|
||||
|
||||
cubicFillPath.reset();
|
||||
cubicFillPath.addPath(cubicPath);
|
||||
|
||||
drawCubicFill(mBitmapCanvas, ds, cubicFillPath, trans, mXBounds);
|
||||
}
|
||||
|
||||
mRenderPaint.setColor(ds.getColor());
|
||||
|
||||
mRenderPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
trans.pathValueToPixel(cubicPath);
|
||||
|
||||
mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
|
||||
|
||||
mRenderPaint.setPathEffect(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,49 @@
|
|||
package net.osmand.plus.mapcontextmenu.other;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
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 net.osmand.data.LatLon;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.IconsCache;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.dialogs.DirectionsDialogs;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||
import net.osmand.plus.views.MapControlsLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TrackDetailsMenu {
|
||||
|
||||
private MapActivity mapActivity;
|
||||
private OsmandMapTileView mapView;
|
||||
private MapControlsLayer mapControlsLayer;
|
||||
private GpxDisplayItem gpxItem;
|
||||
|
||||
private static boolean VISIBLE;
|
||||
private boolean nightMode;
|
||||
|
@ -28,6 +54,18 @@ public class TrackDetailsMenu {
|
|||
mapView = mapActivity.getMapView();
|
||||
}
|
||||
|
||||
public GpxDisplayItem getGpxItem() {
|
||||
return gpxItem;
|
||||
}
|
||||
|
||||
public void setGpxItem(GpxDisplayItem gpxItem) {
|
||||
this.gpxItem = gpxItem;
|
||||
}
|
||||
|
||||
public static boolean isVisible() {
|
||||
return VISIBLE;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (!VISIBLE) {
|
||||
VISIBLE = true;
|
||||
|
@ -40,12 +78,7 @@ public class TrackDetailsMenu {
|
|||
|
||||
TrackDetailsMenuFragment.showInstance(mapActivity);
|
||||
|
||||
if (!AndroidUiHelper.isXLargeDevice(mapActivity)) {
|
||||
AndroidUiHelper.updateVisibility(mapActivity.findViewById(R.id.map_right_widgets_panel), false);
|
||||
}
|
||||
if (!portrait) {
|
||||
AndroidUiHelper.updateVisibility(mapActivity.findViewById(R.id.map_route_land_left_margin), true);
|
||||
}
|
||||
mapActivity.findViewById(R.id.MapHudButtonsOverlay).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +91,13 @@ public class TrackDetailsMenu {
|
|||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
WeakReference<TrackDetailsMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().updateInfo();
|
||||
}
|
||||
}
|
||||
|
||||
public WeakReference<TrackDetailsMenuFragment> findMenuFragment() {
|
||||
Fragment fragment = mapActivity.getSupportFragmentManager().findFragmentByTag(TrackDetailsMenuFragment.TAG);
|
||||
if (fragment != null && !fragment.isDetached()) {
|
||||
|
@ -69,10 +109,10 @@ public class TrackDetailsMenu {
|
|||
|
||||
public void onDismiss() {
|
||||
VISIBLE = false;
|
||||
mapActivity.getMapLayers().getGpxLayer().setSelectedPointLatLon(null);
|
||||
mapActivity.getMapView().setMapPositionX(0);
|
||||
mapActivity.getMapView().refreshMap();
|
||||
AndroidUiHelper.updateVisibility(mapActivity.findViewById(R.id.map_route_land_left_margin), false);
|
||||
AndroidUiHelper.updateVisibility(mapActivity.findViewById(R.id.map_right_widgets_panel), true);
|
||||
mapActivity.findViewById(R.id.MapHudButtonsOverlay).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void updateInfo(final View main) {
|
||||
|
@ -81,29 +121,217 @@ public class TrackDetailsMenu {
|
|||
}
|
||||
|
||||
private void updateView(final View parentView) {
|
||||
/*
|
||||
String via = generateViaDescription();
|
||||
View viaLayout = parentView.findViewById(R.id.ViaLayout);
|
||||
if (via.length() == 0) {
|
||||
viaLayout.setVisibility(View.GONE);
|
||||
parentView.findViewById(R.id.viaLayoutDivider).setVisibility(View.GONE);
|
||||
} else {
|
||||
viaLayout.setVisibility(View.VISIBLE);
|
||||
parentView.findViewById(R.id.viaLayoutDivider).setVisibility(View.VISIBLE);
|
||||
((TextView) parentView.findViewById(R.id.ViaView)).setText(via);
|
||||
}
|
||||
|
||||
viaLayout.setOnClickListener(new View.OnClickListener() {
|
||||
final LineChart chart = (LineChart) parentView.findViewById(R.id.chart);
|
||||
chart.setOnChartGestureListener(new OnChartGestureListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (getTargets().checkPointToNavigateShort()) {
|
||||
mapActivity.getMapActions().openIntermediatePointsDialog();
|
||||
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();
|
||||
|
||||
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) {
|
||||
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
||||
segment = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (segment != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (segment != null) {
|
||||
WptPt wpt = null;
|
||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||
float time = gpxItem.chartHighlightPos * 1000;
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.time - gpxItem.analysis.startTime >= time) {
|
||||
wpt = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.distance >= distance) {
|
||||
wpt = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wpt != null) {
|
||||
mapActivity.getMapLayers().getGpxLayer().setSelectedPointLatLon(new LatLon(wpt.lat, wpt.lon));
|
||||
mapActivity.setMapLocation(wpt.lat, wpt.lon);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gpxItem.chartHighlightPos = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
}
|
||||
});
|
||||
|
||||
ImageView viaIcon = (ImageView) parentView.findViewById(R.id.viaIcon);
|
||||
viaIcon.setImageDrawable(getIconOrig(R.drawable.list_intermediate));
|
||||
*/
|
||||
final OsmandApplication app = mapActivity.getMyApplication();
|
||||
final IconsCache ic = app.getIconsCache();
|
||||
GPXTrackAnalysis analysis = gpxItem.analysis;
|
||||
if (analysis != null) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
|
||||
if (gpxItem.chartType != null) {
|
||||
List<ILineDataSet> dataSets = new ArrayList<>();
|
||||
OrderedLineDataSet dataSet = null;
|
||||
if (gpxItem.chartType != null) {
|
||||
switch (gpxItem.chartType) {
|
||||
case ALTITUDE:
|
||||
dataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis,
|
||||
gpxItem.chartAxisType, false, true);
|
||||
break;
|
||||
case SPEED:
|
||||
dataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis,
|
||||
gpxItem.chartAxisType, false, true);
|
||||
break;
|
||||
case SLOPE:
|
||||
dataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart, analysis,
|
||||
gpxItem.chartAxisType, null, false, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataSets.add(dataSet);
|
||||
|
||||
chart.setData(new LineData(dataSets));
|
||||
updateChart(chart);
|
||||
}
|
||||
}
|
||||
|
||||
View yAxis = parentView.findViewById(R.id.y_axis);
|
||||
ImageView yAxisIcon = (ImageView) parentView.findViewById(R.id.y_axis_icon);
|
||||
TextView yAxisTitle = (TextView) parentView.findViewById(R.id.y_axis_title);
|
||||
View yAxisArrow = parentView.findViewById(R.id.y_axis_arrow);
|
||||
final List<GPXDataSetType> availableTypes = new ArrayList<>();
|
||||
if (analysis != null) {
|
||||
if (analysis.elevationData != null) {
|
||||
availableTypes.add(GPXDataSetType.ALTITUDE);
|
||||
availableTypes.add(GPXDataSetType.SLOPE);
|
||||
}
|
||||
if (analysis.isSpeedSpecified()) {
|
||||
availableTypes.add(GPXDataSetType.SPEED);
|
||||
}
|
||||
}
|
||||
availableTypes.remove(gpxItem.chartType);
|
||||
yAxisIcon.setImageDrawable(gpxItem.chartType.getImageDrawable(app));
|
||||
yAxisTitle.setText(gpxItem.chartType.getName(app));
|
||||
if (availableTypes.size() > 0) {
|
||||
yAxis.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final PopupMenu optionsMenu = new PopupMenu(mapActivity, v);
|
||||
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
|
||||
for (final GPXDataSetType type : availableTypes) {
|
||||
MenuItem menuItem = optionsMenu.getMenu().add(type.getStringId()).setIcon(type.getImageDrawable(app));
|
||||
menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem mItem) {
|
||||
gpxItem.chartType = type;
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
optionsMenu.show();
|
||||
}
|
||||
});
|
||||
yAxisArrow.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
yAxis.setOnClickListener(null);
|
||||
yAxisArrow.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
View xAxis = parentView.findViewById(R.id.x_axis);
|
||||
ImageView xAxisIcon = (ImageView) parentView.findViewById(R.id.x_axis_icon);
|
||||
TextView xAxisTitle = (TextView) parentView.findViewById(R.id.x_axis_title);
|
||||
View xAxisArrow = parentView.findViewById(R.id.x_axis_arrow);
|
||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time));
|
||||
xAxisTitle.setText(app.getString(R.string.shared_string_time));
|
||||
} else {
|
||||
xAxisIcon.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_marker_dark));
|
||||
xAxisTitle.setText(app.getString(R.string.distance));
|
||||
}
|
||||
if (analysis != null && analysis.isTimeSpecified()) {
|
||||
xAxis.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final PopupMenu optionsMenu = new PopupMenu(mapActivity, v);
|
||||
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
|
||||
final GPXDataSetAxisType type;
|
||||
if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) {
|
||||
type = GPXDataSetAxisType.DISTANCE;
|
||||
} else {
|
||||
type = GPXDataSetAxisType.TIME;
|
||||
}
|
||||
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();
|
||||
}
|
||||
});
|
||||
xAxisArrow.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
xAxis.setOnClickListener(null);
|
||||
xAxisArrow.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChart(LineChart chart) {
|
||||
if (gpxItem.chartMatrix != null) {
|
||||
chart.getViewPortHandler().refresh(new Matrix(gpxItem.chartMatrix), chart, true);
|
||||
}
|
||||
if (gpxItem.chartHighlightPos != -1) {
|
||||
chart.highlightValue(gpxItem.chartHighlightPos, 0);
|
||||
} else {
|
||||
chart.highlightValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import android.support.v4.app.FragmentManager;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
|
@ -19,6 +21,7 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
|
||||
private TrackDetailsMenu menu;
|
||||
private View mainView;
|
||||
private View topBar;
|
||||
|
||||
private MapActivity getMapActivity() {
|
||||
return (MapActivity) getActivity();
|
||||
|
@ -30,7 +33,7 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
MapActivity mapActivity = getMapActivity();
|
||||
|
||||
menu = mapActivity.getMapLayers().getMapControlsLayer().getTrackDetailsMenu();
|
||||
View view = inflater.inflate(R.layout.plan_route_info, container, false);
|
||||
View view = inflater.inflate(R.layout.track_details, container, false);
|
||||
if (menu == null) {
|
||||
return view;
|
||||
}
|
||||
|
@ -38,11 +41,22 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
view.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
MapActivity.clearPrevActivityIntent();
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
mainView = view.findViewById(R.id.main_view);
|
||||
topBar = view.findViewById(R.id.top_bar_layout);
|
||||
|
||||
ImageButton backButton = (ImageButton) topBar.findViewById(R.id.top_bar_back_button);
|
||||
backButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getActivity().onBackPressed();
|
||||
}
|
||||
});
|
||||
|
||||
updateInfo();
|
||||
|
||||
return view;
|
||||
|
@ -90,7 +104,7 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
int slideOutAnim = R.anim.slide_out_bottom;
|
||||
|
||||
mapActivity.getSupportFragmentManager().beginTransaction()
|
||||
.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
|
||||
//.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
|
||||
.add(R.id.routeMenuContainer, this, TAG)
|
||||
.addToBackStack(TAG)
|
||||
.commitAllowingStateLoss();
|
||||
|
@ -100,7 +114,7 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
FragmentActivity activity = getActivity();
|
||||
if (activity != null) {
|
||||
try {
|
||||
activity.getSupportFragmentManager().popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
activity.getSupportFragmentManager().popBackStackImmediate(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
@ -117,42 +131,16 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
} else {
|
||||
AndroidUtils.setBackground(ctx, mainView, nightMode, R.drawable.bg_left_menu_light, R.drawable.bg_left_menu_dark);
|
||||
}
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerModesLayout), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerFromDropDown), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.viaLayoutDivider), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerToDropDown), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerButtons), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
ImageButton backButton = (ImageButton) topBar.findViewById(R.id.top_bar_back_button);
|
||||
backButton.setImageDrawable(ctx.getMyApplication().getIconsCache().getIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha, R.color.color_white));
|
||||
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerBtn1), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerBtn2), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setBackground(ctx, mainView.findViewById(R.id.dividerBtn3), nightMode,
|
||||
R.color.dashboard_divider_light, R.color.dashboard_divider_dark);
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.y_axis_title), nightMode);
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.x_axis_title), nightMode);
|
||||
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.ViaView), nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(ctx, (TextView) mainView.findViewById(R.id.ViaSubView), nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(ctx, (TextView) mainView.findViewById(R.id.toTitle), nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(ctx, (TextView) mainView.findViewById(R.id.fromTitle), nightMode);
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.InfoTextView), nightMode);
|
||||
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.FromLayout), nightMode);
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.ViaLayout), nightMode);
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.ToLayout), nightMode);
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.Info), nightMode);
|
||||
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.Next), nightMode);
|
||||
AndroidUtils.setDashButtonBackground(ctx, mainView.findViewById(R.id.Prev), nightMode);
|
||||
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.DistanceText), nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(ctx, (TextView) mainView.findViewById(R.id.DistanceTitle), nightMode);
|
||||
AndroidUtils.setTextPrimaryColor(ctx, (TextView) mainView.findViewById(R.id.DurationText), nightMode);
|
||||
AndroidUtils.setTextSecondaryColor(ctx, (TextView) mainView.findViewById(R.id.DurationTitle), nightMode);
|
||||
ImageView yAxisArrow = (ImageView) mainView.findViewById(R.id.y_axis_arrow);
|
||||
ImageView xAxisArrow = (ImageView) mainView.findViewById(R.id.x_axis_arrow);
|
||||
yAxisArrow.setImageDrawable(ctx.getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_down));
|
||||
xAxisArrow.setImageDrawable(ctx.getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_down));
|
||||
}
|
||||
|
||||
public static boolean showInstance(final MapActivity mapActivity) {
|
||||
|
@ -168,9 +156,9 @@ public class TrackDetailsMenuFragment extends Fragment {
|
|||
slideOutAnim = R.anim.slide_out_left;
|
||||
}
|
||||
|
||||
MapRouteInfoMenuFragment fragment = new MapRouteInfoMenuFragment();
|
||||
TrackDetailsMenuFragment fragment = new TrackDetailsMenuFragment();
|
||||
mapActivity.getSupportFragmentManager().beginTransaction()
|
||||
.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
|
||||
//.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
|
||||
.add(R.id.routeMenuContainer, fragment, TAG)
|
||||
.addToBackStack(TAG).commitAllowingStateLoss();
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment {
|
|||
if (isRecording) {
|
||||
currentGpxView.findViewById(R.id.segment_time_div).setVisibility(View.VISIBLE);
|
||||
TextView segmentTime = (TextView) currentGpxView.findViewById(R.id.segment_time);
|
||||
segmentTime.setText(OsmAndFormatter.getFormattedDurationShort((int)(sth.getDuration() / 1000), app));
|
||||
segmentTime.setText(OsmAndFormatter.getFormattedDurationShort((int)(sth.getDuration() / 1000)));
|
||||
segmentTime.setVisibility(View.VISIBLE);
|
||||
stop.setCompoundDrawablesWithIntrinsicBounds(app.getIconsCache()
|
||||
.getIcon(R.drawable.ic_action_rec_stop, light ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark), null, null, null);
|
||||
|
|
|
@ -796,6 +796,9 @@ public class TrackPointFragment extends OsmandExpandableListFragment {
|
|||
public boolean onMenuItemClick(MenuItem mItem) {
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
LatLon location = new LatLon(gpxItem.locationStart.lat, gpxItem.locationStart.lon);
|
||||
if (gpxItem.group.getGpx() != null) {
|
||||
app.getSelectedGpxHelper().setGpxFileToDisplay(gpxItem.group.getGpx());
|
||||
}
|
||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
||||
|
|
|
@ -38,11 +38,14 @@ import com.github.mikephil.charting.listener.ChartTouchListener.ChartGesture;
|
|||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.GPXDatabase;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.plus.GPXUtilities.Track;
|
||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
|
@ -60,6 +63,8 @@ import net.osmand.plus.dialogs.ConfigureMapMenu.AppearanceListItem;
|
|||
import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter;
|
||||
import net.osmand.plus.dialogs.ConfigureMapMenu.GpxAppearanceAdapter.GpxAppearanceAdapterType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
|
||||
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
|
||||
import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider;
|
||||
|
@ -75,7 +80,6 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -89,7 +93,6 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
|
||||
private OsmandApplication app;
|
||||
private SegmentGPXAdapter adapter;
|
||||
private View headerView;
|
||||
|
||||
private GpxDisplayItemType[] filterTypes = { GpxSelectionHelper.GpxDisplayItemType.TRACK_SEGMENT };
|
||||
private List<String> options = new ArrayList<>();
|
||||
|
@ -97,7 +100,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
private TIntArrayList timeSplit = new TIntArrayList();
|
||||
private int selectedSplitInterval;
|
||||
private boolean updateEnable;
|
||||
|
||||
private View headerView;
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -117,14 +120,22 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
setHasOptionsMenu(true);
|
||||
View view = getActivity().getLayoutInflater().inflate(R.layout.update_index, container, false);
|
||||
view.findViewById(R.id.header_layout).setVisibility(View.GONE);
|
||||
|
||||
ListView listView = (ListView) view.findViewById(android.R.id.list);
|
||||
listView.setDivider(null);
|
||||
listView.setDividerHeight(0);
|
||||
|
||||
TextView tv = new TextView(getActivity());
|
||||
tv.setText(R.string.none_selected_gpx);
|
||||
tv.setTextSize(24);
|
||||
listView.setEmptyView(tv);
|
||||
setContent(listView);
|
||||
|
||||
adapter = new SegmentGPXAdapter(new ArrayList<GpxDisplayItem>());
|
||||
headerView = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_list_header, null, false);
|
||||
listView.addHeaderView(headerView);
|
||||
listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false));
|
||||
updateHeader();
|
||||
setListAdapter(adapter);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -200,12 +211,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
updateEnable = false;
|
||||
}
|
||||
|
||||
private void setupListView(ListView listView) {
|
||||
if (headerView == null) {
|
||||
headerView = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_list_header, null, false);
|
||||
listView.addHeaderView(headerView);
|
||||
listView.addFooterView(getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, null, false));
|
||||
}
|
||||
private void updateHeader() {
|
||||
final ImageView imageView = (ImageView) headerView.findViewById(R.id.imageView);
|
||||
final View splitColorView = headerView.findViewById(R.id.split_color_view);
|
||||
final View divider = headerView.findViewById(R.id.divider);
|
||||
|
@ -216,13 +222,8 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
vis.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false);
|
||||
if (vis.isChecked() && sf.getModifiableGpxFile() != null) {
|
||||
sf.processPoints();
|
||||
updateColorView(colorView);
|
||||
} else {
|
||||
updateColorView(colorView);
|
||||
}
|
||||
app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false);
|
||||
updateColorView(colorView);
|
||||
}
|
||||
});
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
|
@ -239,7 +240,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
false,
|
||||
item);
|
||||
} else {
|
||||
GPXUtilities.WptPt wpt = sf.getGpxFile().findPointToShow();
|
||||
WptPt wpt = sf.getGpxFile().findPointToShow();
|
||||
if (wpt != null) {
|
||||
app.getSettings().setMapLocationToShow(wpt.getLatitude(), wpt.getLongitude(),
|
||||
15,
|
||||
|
@ -427,24 +428,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
return groups;
|
||||
}
|
||||
|
||||
public void setContent() {
|
||||
setContent(getListView());
|
||||
}
|
||||
|
||||
public void setContent(ListView listView) {
|
||||
if (adapter == null) {
|
||||
adapter = new SegmentGPXAdapter(new ArrayList<GpxDisplayItem>());
|
||||
} else {
|
||||
adapter.clear();
|
||||
}
|
||||
updateContent();
|
||||
setupListView(listView);
|
||||
if (listView.getAdapter() == null) {
|
||||
setListAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateContent() {
|
||||
public void updateContent() {
|
||||
adapter.clear();
|
||||
List<GpxDisplayGroup> groups = getOriginalGroups();
|
||||
adapter.setNotifyOnChange(false);
|
||||
|
@ -453,6 +437,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
}
|
||||
adapter.setNotifyOnChange(true);
|
||||
adapter.notifyDataSetChanged();
|
||||
updateHeader();
|
||||
}
|
||||
|
||||
protected List<GpxDisplayItem> flatten(List<GpxDisplayGroup> groups) {
|
||||
|
@ -523,30 +508,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
|
||||
GpxDisplayItem child = adapter.getItem(position);
|
||||
if (child != null) {
|
||||
if (child.group.getGpx() != null) {
|
||||
app.getSelectedGpxHelper().setGpxFileToDisplay(child.group.getGpx());
|
||||
}
|
||||
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
LatLon location = new LatLon(child.locationStart.lat, child.locationStart.lon);
|
||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_GPX_ITEM, child.group.getGpxName()),
|
||||
false,
|
||||
child);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
class SegmentGPXAdapter extends ArrayAdapter<GpxDisplayItem> {
|
||||
private class SegmentGPXAdapter extends ArrayAdapter<GpxDisplayItem> {
|
||||
|
||||
private Map<GpxDisplayItem, GPXItemPagerAdapter> pagerAdaptersMap = new HashMap<>();
|
||||
|
||||
|
@ -603,11 +565,14 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
tabLayout = (PagerSlidingTabStrip) row.findViewById(R.id.sliding_tabs);
|
||||
pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
|
||||
}
|
||||
pager.setAdapter(getPagerAdapter(tabLayout, getItem(position)));
|
||||
if (create) {
|
||||
tabLayout.setViewPager(pager);
|
||||
} else {
|
||||
tabLayout.notifyDataSetChanged(true);
|
||||
GpxDisplayItem item = getItem(position);
|
||||
if (item != null) {
|
||||
pager.setAdapter(getPagerAdapter(tabLayout, item));
|
||||
if (create) {
|
||||
tabLayout.setViewPager(pager);
|
||||
} else {
|
||||
tabLayout.notifyDataSetChanged(true);
|
||||
}
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
@ -626,6 +591,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
private GpxDisplayItem gpxItem;
|
||||
private GPXTabItemType[] tabTypes;
|
||||
private String[] titles;
|
||||
private Map<GPXTabItemType, List<ILineDataSet>> dataSetsMap = new HashMap<>();
|
||||
|
||||
GPXItemPagerAdapter(PagerSlidingTabStrip tabs, GpxDisplayItem gpxItem) {
|
||||
super();
|
||||
|
@ -665,6 +631,59 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private List<ILineDataSet> getDataSets(GPXTabItemType tabType, LineChart chart) {
|
||||
List<ILineDataSet> dataSets = dataSetsMap.get(tabType);
|
||||
if (dataSets == null && chart != null) {
|
||||
dataSets = new ArrayList<>();
|
||||
GPXTrackAnalysis analysis = gpxItem.analysis;
|
||||
switch (tabType) {
|
||||
case GPX_TAB_ITEM_GENERAL: {
|
||||
OrderedLineDataSet speedDataSet = null;
|
||||
OrderedLineDataSet elevationDataSet = null;
|
||||
if (analysis.isSpeedSpecified()) {
|
||||
speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
|
||||
analysis, GPXDataSetAxisType.DISTANCE, true, true);
|
||||
}
|
||||
if (analysis.elevationData != null) {
|
||||
elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
|
||||
analysis, GPXDataSetAxisType.DISTANCE, false, true);
|
||||
}
|
||||
if (speedDataSet != null) {
|
||||
dataSets.add(speedDataSet);
|
||||
if (elevationDataSet != null) {
|
||||
dataSets.add(elevationDataSet.getPriority() < speedDataSet.getPriority()
|
||||
? 1 : 0, elevationDataSet);
|
||||
}
|
||||
} else if (elevationDataSet != null) {
|
||||
dataSets.add(elevationDataSet);
|
||||
}
|
||||
dataSetsMap.put(GPXTabItemType.GPX_TAB_ITEM_GENERAL, dataSets);
|
||||
break;
|
||||
}
|
||||
case GPX_TAB_ITEM_ALTITUDE: {
|
||||
OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
|
||||
analysis, GPXDataSetAxisType.DISTANCE, false, true);
|
||||
dataSets.add(elevationDataSet);
|
||||
if (analysis.elevationData.size() > 1) {
|
||||
OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
|
||||
analysis, GPXDataSetAxisType.DISTANCE, elevationDataSet.getValues(), true, true);
|
||||
dataSets.add(slopeDataSet);
|
||||
}
|
||||
dataSetsMap.put(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE, dataSets);
|
||||
break;
|
||||
}
|
||||
case GPX_TAB_ITEM_SPEED: {
|
||||
OrderedLineDataSet speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
|
||||
analysis, GPXDataSetAxisType.DISTANCE, false, true);
|
||||
dataSets.add(speedDataSet);
|
||||
dataSetsMap.put(GPXTabItemType.GPX_TAB_ITEM_SPEED, dataSets);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataSets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return tabTypes.length;
|
||||
|
@ -756,29 +775,11 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
switch (tabType) {
|
||||
case GPX_TAB_ITEM_GENERAL:
|
||||
if (analysis != null) {
|
||||
List<ILineDataSet> dataSets = new LinkedList<>();
|
||||
if ((analysis.elevationData != null && analysis.totalDistance > 0)
|
||||
|| analysis.isSpeedSpecified()) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
OrderedLineDataSet speedDataSet = null;
|
||||
OrderedLineDataSet elevationDataSet = null;
|
||||
if (analysis.isSpeedSpecified()) {
|
||||
speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart, analysis, true, true);
|
||||
}
|
||||
if (analysis.elevationData != null) {
|
||||
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.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_GENERAL, chart)));
|
||||
updateChart(chart);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
|
@ -821,7 +822,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//todo
|
||||
openDetails(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -830,15 +831,8 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
if (analysis != null) {
|
||||
if (analysis.elevationData != null && analysis.totalDistance > 0) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
List<ILineDataSet> dataSets = new ArrayList<>();
|
||||
OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart, analysis, false, true);
|
||||
dataSets.add(elevationDataSet);
|
||||
if (analysis.elevationData.size() > 1) {
|
||||
OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart, analysis, elevationDataSet.getValues(), true, true);
|
||||
dataSets.add(slopeDataSet);
|
||||
}
|
||||
LineData data = new LineData(dataSets);
|
||||
chart.setData(data);
|
||||
chart.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE, chart)));
|
||||
updateChart(chart);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
|
@ -872,7 +866,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//todo
|
||||
openDetails(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -881,7 +875,8 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
if (analysis != null && analysis.isSpeedSpecified()) {
|
||||
if (analysis.totalDistance > 0) {
|
||||
GpxUiHelper.setupGPXChart(app, chart, 4);
|
||||
GpxUiHelper.setGPXSpeedChartData(app, chart, analysis, false, true);
|
||||
chart.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_SPEED, chart)));
|
||||
updateChart(chart);
|
||||
chart.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
chart.setVisibility(View.GONE);
|
||||
|
@ -914,7 +909,7 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//todo
|
||||
openDetails(GPXTabItemType.GPX_TAB_ITEM_SPEED);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -1008,11 +1003,79 @@ public class TrackSegmentFragment extends OsmAndListFragment {
|
|||
if (gpxItem.chartMatrix != null) {
|
||||
chart.getViewPortHandler().refresh(new Matrix(gpxItem.chartMatrix), chart, true);
|
||||
}
|
||||
chart.highlightValue(gpxItem.chartHighlightPos, 0);
|
||||
if (gpxItem.chartHighlightPos != -1) {
|
||||
chart.highlightValue(gpxItem.chartHighlightPos, 0);
|
||||
} else {
|
||||
chart.highlightValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
void openDetails(GPXTabItemType tabType) {
|
||||
LatLon location = null;
|
||||
WptPt wpt = null;
|
||||
gpxItem.chartType = null;
|
||||
List<ILineDataSet> ds = getDataSets(tabType, null);
|
||||
if (ds != null && ds.size() > 0) {
|
||||
for (ILineDataSet dataSet : ds) {
|
||||
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) dataSet;
|
||||
if (orderedDataSet.getDataSetType() == GPXDataSetType.ALTITUDE) {
|
||||
gpxItem.chartType = GPXDataSetType.ALTITUDE;
|
||||
break;
|
||||
}
|
||||
gpxItem.chartType = orderedDataSet.getDataSetType();
|
||||
}
|
||||
if (gpxItem.chartHighlightPos != -1) {
|
||||
TrkSegment segment = null;
|
||||
for (Track t : gpxItem.group.getGpx().tracks) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) {
|
||||
segment = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (segment != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (segment != null) {
|
||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||
float distance = gpxItem.chartHighlightPos * dataSet.getDivX();
|
||||
for (WptPt p : segment.points) {
|
||||
if (p.distance >= distance) {
|
||||
wpt = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wpt != null) {
|
||||
location = new LatLon(wpt.lat, wpt.lon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (location == null) {
|
||||
location = new LatLon(gpxItem.locationStart.lat, gpxItem.locationStart.lon);
|
||||
}
|
||||
if (wpt != null) {
|
||||
gpxItem.locationOnMap = wpt;
|
||||
} else {
|
||||
gpxItem.locationOnMap = gpxItem.locationStart;
|
||||
}
|
||||
|
||||
if (gpxItem.group.getGpx() != null) {
|
||||
app.getSelectedGpxHelper().setGpxFileToDisplay(gpxItem.group.getGpx());
|
||||
}
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
settings.setMapLocationToShow(location.getLatitude(), location.getLongitude(),
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
||||
false,
|
||||
gpxItem);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
class SplitTrackAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
private class SplitTrackAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||
@Nullable
|
||||
private final SelectedGpxFile mSelectedGpxFile;
|
||||
@NonNull private final TrackSegmentFragment mFragment;
|
||||
|
|
|
@ -67,6 +67,9 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
|
|||
private Paint paintIcon;
|
||||
private Bitmap pointSmall;
|
||||
|
||||
private Bitmap selectedPoint;
|
||||
private LatLon selectedPointLatLon;
|
||||
|
||||
private static final int startZoom = 7;
|
||||
|
||||
|
||||
|
@ -141,6 +144,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
|
|||
|
||||
paintIcon = new Paint();
|
||||
pointSmall = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_white_shield_small);
|
||||
selectedPoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_default_location);
|
||||
|
||||
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
|
||||
|
||||
|
@ -343,6 +347,16 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
|
|||
drawBigPoint(canvas, o, fileColor, x, y);
|
||||
}
|
||||
}
|
||||
if (selectedPointLatLon != null
|
||||
&& selectedPointLatLon.getLatitude() >= latLonBounds.bottom
|
||||
&& selectedPointLatLon.getLatitude() <= latLonBounds.top
|
||||
&& selectedPointLatLon.getLongitude() >= latLonBounds.left
|
||||
&& selectedPointLatLon.getLongitude() <= latLonBounds.right) {
|
||||
float x = tileBox.getPixXFromLatLon(selectedPointLatLon.getLatitude(), selectedPointLatLon.getLongitude());
|
||||
float y = tileBox.getPixYFromLatLon(selectedPointLatLon.getLatitude(), selectedPointLatLon.getLongitude());
|
||||
paintIcon.setColorFilter(null);
|
||||
canvas.drawBitmap(selectedPoint, x - selectedPoint.getWidth() / 2, y - selectedPoint.getHeight() / 2, paintIcon);
|
||||
}
|
||||
this.fullObjectsLatLon = fullObjectsLatLon;
|
||||
this.smallObjectsLatLon = smallObjectsLatLon;
|
||||
}
|
||||
|
@ -402,10 +416,17 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
|
|||
}
|
||||
|
||||
private List<WptPt> getListStarPoints(SelectedGpxFile g) {
|
||||
|
||||
return g.getGpxFile().points;
|
||||
}
|
||||
|
||||
public LatLon getSelectedPointLatLon() {
|
||||
return selectedPointLatLon;
|
||||
}
|
||||
|
||||
public void setSelectedPointLatLon(LatLon selectedPointLatLon) {
|
||||
this.selectedPointLatLon = selectedPointLatLon;
|
||||
}
|
||||
|
||||
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
|
||||
return (Math.abs(objx - ex) <= radius * 2 && Math.abs(objy - ey) <= radius * 2);
|
||||
// return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
|
||||
|
|
Loading…
Reference in a new issue