package net.osmand.plus.myplaces;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.ListPopupWindow;
import android.support.v7.widget.SwitchCompat;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
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.ChartGesture;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import net.osmand.AndroidUtils;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.data.RotatedTileBox.RotatedTileBoxBuilder;
import net.osmand.plus.GPXDatabase.GpxDataItem;
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;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.OsmAndListFragment;
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.render.MapRenderRepositories;
import net.osmand.plus.resources.AsyncLoadingThread;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.Renderable;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import net.osmand.plus.views.controls.PagerSlidingTabStrip.CustomTabProvider;
import net.osmand.plus.views.controls.WrapContentHeightViewPager;
import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionInterface;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import gnu.trove.list.array.TIntArrayList;
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
public class TrackSegmentFragment extends OsmAndListFragment {
public static final String ARG_TO_FILTER_SHORT_TRACKS = "ARG_TO_FILTER_SHORT_TRACKS";
private OsmandApplication app;
private SegmentGPXAdapter adapter;
private GpxDisplayItemType[] filterTypes = { GpxSelectionHelper.GpxDisplayItemType.TRACK_SEGMENT };
private List<String> options = new ArrayList<>();
private List<Double> distanceSplit = new ArrayList<>();
private TIntArrayList timeSplit = new TIntArrayList();
private int selectedSplitInterval;
private boolean updateEnable;
private View headerView;
private int trackColor;
private int currentTrackColor;
private Paint paint;
private Bitmap selectedPoint;
private LatLon selectedPointLatLon;
private int defPointColor;
private Paint paintIcon;
private Bitmap pointSmall;
private ImageView imageView;
private RotatedTileBox rotatedTileBox;
private Bitmap mapBitmap;
private Bitmap mapTrackBitmap;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.app = getMyApplication();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getListView().setBackgroundColor(getResources().getColor(
getMyApplication().getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light
: R.color.ctx_menu_info_view_bg_dark));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
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);
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
paint.setStrokeWidth(AndroidUtils.dpToPx(app, 4f));
defPointColor = ContextCompat.getColor(app, R.color.gpx_color_point);
paintIcon = new Paint();
pointSmall = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_white_shield_small);
selectedPoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_default_location);
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;
}
public TrackActivity getMyActivity() {
return (TrackActivity) getActivity();
}
public ArrayAdapter<?> getAdapter() {
return adapter;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
getMyActivity().getClearToolbar(false);
if (getGpx() != null && getGpx().path != null && !getGpx().showCurrentTrack) {
MenuItem item = menu.add(R.string.shared_string_share).setIcon(R.drawable.ic_action_gshare_dark)
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
final Uri fileUri = Uri.fromFile(new File(getGpx().path));
final Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
sendIntent.setType("application/gpx+xml");
startActivity(sendIntent);
return true;
}
});
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
}
if (getGpx() != null && getGpx().showCurrentTrack) {
MenuItem item = menu.add(R.string.shared_string_refresh).setIcon(R.drawable.ic_action_refresh_dark)
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (updateEnable) {
updateContent();
adapter.notifyDataSetChanged();
}
return true;
}
});
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
}
}
private GPXFile getGpx() {
return getMyActivity().getGpx();
}
private GpxDataItem getGpxDataItem() {
return getMyActivity().getGpxDataItem();
}
private void startHandler() {
Handler updateCurrentRecordingTrack = new Handler();
updateCurrentRecordingTrack.postDelayed(new Runnable() {
@Override
public void run() {
if (updateEnable) {
updateContent();
adapter.notifyDataSetChanged();
startHandler();
}
}
}, 2000);
}
@Override
public void onResume() {
super.onResume();
updateContent();
updateEnable = true;
if (getGpx() != null && getGpx().showCurrentTrack) {
//startHandler();
}
}
@Override
public void onPause() {
super.onPause();
updateEnable = false;
}
private void updateHeader() {
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);
final View splitIntervalView = headerView.findViewById(R.id.split_interval_view);
final View colorView = headerView.findViewById(R.id.color_view);
final SwitchCompat vis = (SwitchCompat) headerView.findViewById(R.id.showOnMapToggle);
final ProgressBar progressBar = (ProgressBar) headerView.findViewById(R.id.mapLoadProgress);
boolean selected = getGpx() != null &&
((getGpx().showCurrentTrack && app.getSelectedGpxHelper().getSelectedCurrentRecordingTrack() != null) ||
(getGpx().path != null && app.getSelectedGpxHelper().getSelectedFileByPath(getGpx().path) != null));
vis.setChecked(selected);
vis.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false);
updateColorView(colorView);
}
});
updateColorView(colorView);
colorView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final ListPopupWindow popup = new ListPopupWindow(getActivity());
popup.setAnchorView(colorView);
popup.setContentWidth(AndroidUtils.dpToPx(app, 200f));
popup.setModal(true);
popup.setDropDownGravity(Gravity.RIGHT | Gravity.TOP);
popup.setVerticalOffset(AndroidUtils.dpToPx(app, -48f));
popup.setHorizontalOffset(AndroidUtils.dpToPx(app, -6f));
final GpxAppearanceAdapter gpxApprAdapter = new GpxAppearanceAdapter(getActivity(),
getGpx().getColor(0), GpxAppearanceAdapterType.TRACK_COLOR);
popup.setAdapter(gpxApprAdapter);
popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AppearanceListItem item = gpxApprAdapter.getItem(position);
if (item != null) {
if (item.getAttrName() == CURRENT_TRACK_COLOR_ATTR) {
int clr = item.getColor();
if (vis.isChecked()) {
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false);
if (clr != 0 && sf.getModifiableGpxFile() != null) {
sf.getModifiableGpxFile().setColor(clr);
if (getGpxDataItem() != null) {
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
}
}
} else if (getGpxDataItem() != null) {
app.getGpxDatabase().updateColor(getGpxDataItem(), clr);
}
if (getGpx().showCurrentTrack) {
app.getSettings().CURRENT_TRACK_COLOR.set(clr);
}
refreshTrackBitmap();
}
}
popup.dismiss();
updateColorView(colorView);
}
});
popup.show();
}
});
if (adapter.getCount() > 0) {
if (!getGpx().showCurrentTrack) {
prepareSplitIntervalAdapterData();
setupSplitIntervalView(splitIntervalView);
updateSplitIntervalView(splitIntervalView);
splitIntervalView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final ListPopupWindow popup = new ListPopupWindow(getActivity());
popup.setAnchorView(splitIntervalView);
popup.setContentWidth(AndroidUtils.dpToPx(app, 200f));
popup.setModal(true);
popup.setDropDownGravity(Gravity.RIGHT | Gravity.TOP);
popup.setVerticalOffset(AndroidUtils.dpToPx(app, -48f));
popup.setHorizontalOffset(AndroidUtils.dpToPx(app, -6f));
popup.setAdapter(new ArrayAdapter<>(getMyActivity(),
R.layout.popup_list_text_item, options));
popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedSplitInterval = position;
SelectedGpxFile sf = app.getSelectedGpxHelper().selectGpxFile(getGpx(), vis.isChecked(), false);
final List<GpxDisplayGroup> groups = getDisplayGroups();
if (groups.size() > 0) {
updateSplit(groups, vis.isChecked() ? sf : null);
}
popup.dismiss();
updateSplitIntervalView(splitIntervalView);
}
});
popup.show();
}
});
splitIntervalView.setVisibility(View.VISIBLE);
} else {
splitIntervalView.setVisibility(View.GONE);
}
splitColorView.setVisibility(View.VISIBLE);
divider.setVisibility(View.VISIBLE);
} else {
splitColorView.setVisibility(View.GONE);
divider.setVisibility(View.GONE);
}
if (rotatedTileBox == null || mapBitmap == null || mapTrackBitmap == null) {
QuadRect rect = getRect();
if (rect.left != 0 && rect.top != 0) {
progressBar.setVisibility(View.VISIBLE);
double clat = rect.bottom / 2 + rect.top / 2;
double clon = rect.left / 2 + rect.right / 2;
WindowManager mgr = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
mgr.getDefaultDisplay().getMetrics(dm);
RotatedTileBoxBuilder boxBuilder = new RotatedTileBoxBuilder()
.setLocation(clat, clon)
.setZoom(15)
.density(dm.density)
.setPixelDimensions(dm.widthPixels, AndroidUtils.dpToPx(app, 152f), 0.5f, 0.5f);
rotatedTileBox = boxBuilder.build();
while (rotatedTileBox.getZoom() < 17 && rotatedTileBox.containsLatLon(rect.top, rect.left) && rotatedTileBox.containsLatLon(rect.bottom, rect.right)) {
rotatedTileBox.setZoom(rotatedTileBox.getZoom() + 1);
}
while (rotatedTileBox.getZoom() >= 7 && (!rotatedTileBox.containsLatLon(rect.top, rect.left) || !rotatedTileBox.containsLatLon(rect.bottom, rect.right))) {
rotatedTileBox.setZoom(rotatedTileBox.getZoom() - 1);
}
final DrawSettings drawSettings = new DrawSettings(!app.getSettings().isLightContent(), true);
final ResourceManager resourceManager = app.getResourceManager();
final MapRenderRepositories renderer = resourceManager.getRenderer();
if (resourceManager.updateRenderedMapNeeded(rotatedTileBox, drawSettings)) {
resourceManager.updateRendererMap(rotatedTileBox, new AsyncLoadingThread.OnMapLoadedListener() {
@Override
public void onMapLoaded(boolean interrupted) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
if (updateEnable) {
mapBitmap = renderer.getBitmap();
if (mapBitmap != null) {
progressBar.setVisibility(View.GONE);
refreshTrackBitmap();
}
}
}
});
}
});
}
imageView.setVisibility(View.VISIBLE);
} else {
imageView.setVisibility(View.GONE);
}
} else {
refreshTrackBitmap();
}
}
private void refreshTrackBitmap() {
currentTrackColor = app.getSettings().CURRENT_TRACK_COLOR.get();
SelectedGpxFile sf;
if (getGpx().showCurrentTrack) {
sf = app.getSavingTrackHelper().getCurrentTrack();
} else {
sf = new SelectedGpxFile();
sf.setGpxFile(getGpx());
}
Bitmap bmp = mapBitmap.copy(mapBitmap.getConfig(), true);
Canvas canvas = new Canvas(bmp);
drawTrack(canvas, rotatedTileBox, sf);
drawPoints(canvas, rotatedTileBox, sf);
mapTrackBitmap = bmp;
Bitmap selectedPointBitmap = drawSelectedPoint();
if (selectedPointBitmap != null) {
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), selectedPointBitmap));
} else {
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), mapTrackBitmap));
}
}
private void drawTrack(Canvas canvas, RotatedTileBox tileBox, SelectedGpxFile g) {
GpxDataItem gpxDataItem = null;
if (!g.isShowCurrentTrack()) {
gpxDataItem = getGpxDataItem();
}
List<TrkSegment> segments = g.getPointsToDisplay();
for (TrkSegment ts : segments) {
int color = gpxDataItem != null ? gpxDataItem.getColor() : 0;
if (g.isShowCurrentTrack()) {
color = currentTrackColor;
}
if (color == 0) {
color = ts.getColor(trackColor);
}
if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD)
&& !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how?
if (g.isShowCurrentTrack()) {
ts.renders.add(new Renderable.CurrentTrack(ts.points));
} else {
ts.renders.add(new Renderable.StandardTrack(ts.points, 17.2));
}
}
paint.setColor(color == 0 ? trackColor : color);
ts.drawRenderers(tileBox.getZoom(), paint, canvas, tileBox);
}
}
private void drawPoints(Canvas canvas, RotatedTileBox tileBox, SelectedGpxFile g) {
List<WptPt> pts = g.getGpxFile().points;
@ColorInt
int fileColor = g.getColor() == 0 ? defPointColor : g.getColor();
for (WptPt o : pts) {
float x = tileBox.getPixXFromLatLon(o.lat, o.lon);
float y = tileBox.getPixYFromLatLon(o.lat, o.lon);
int pointColor = o.getColor(fileColor);
paintIcon.setColorFilter(new PorterDuffColorFilter(pointColor, PorterDuff.Mode.MULTIPLY));
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
}
}
private Bitmap drawSelectedPoint() {
if (mapTrackBitmap != null && rotatedTileBox != null && selectedPointLatLon != null) {
float x = rotatedTileBox.getPixXFromLatLon(selectedPointLatLon.getLatitude(), selectedPointLatLon.getLongitude());
float y = rotatedTileBox.getPixYFromLatLon(selectedPointLatLon.getLatitude(), selectedPointLatLon.getLongitude());
paintIcon.setColorFilter(null);
Bitmap bmp = mapTrackBitmap.copy(mapTrackBitmap.getConfig(), true);
Canvas canvas = new Canvas(bmp);
canvas.drawBitmap(selectedPoint, x - selectedPoint.getWidth() / 2, y - selectedPoint.getHeight() / 2, paintIcon);
return bmp;
} else {
return null;
}
}
private QuadRect getRect() {
double left = 0, right = 0;
double top = 0, bottom = 0;
if (getGpx() != null) {
for (Track track : getGpx().tracks) {
for (TrkSegment segment : track.segments) {
for (WptPt p : segment.points) {
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());
}
}
}
}
for (WptPt p : getGpx().points) {
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 List<GpxDisplayGroup> getOriginalGroups() {
return filterGroups(false);
}
private List<GpxDisplayGroup> getDisplayGroups() {
return filterGroups(true);
}
private void setupSplitIntervalView(View view) {
final TextView title = (TextView) view.findViewById(R.id.split_interval_title);
final TextView text = (TextView) view.findViewById(R.id.split_interval_text);
final ImageView img = (ImageView) view.findViewById(R.id.split_interval_arrow);
int colorId;
final List<GpxDisplayGroup> groups = getDisplayGroups();
if (groups.size() > 0) {
colorId = app.getSettings().isLightContent() ?
R.color.primary_text_light : R.color.primary_text_dark;
} else {
colorId = app.getSettings().isLightContent() ?
R.color.secondary_text_light : R.color.secondary_text_dark;
}
int color = app.getResources().getColor(colorId);
title.setTextColor(color);
text.setTextColor(color);
img.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_action_arrow_drop_down, colorId));
}
private void updateSplitIntervalView(View view) {
final TextView text = (TextView) view.findViewById(R.id.split_interval_text);
if (selectedSplitInterval == 0) {
text.setText(getString(R.string.shared_string_none));
} else {
text.setText(options.get(selectedSplitInterval));
}
}
private void updateColorView(View colorView) {
final ImageView colorImageView = (ImageView) colorView.findViewById(R.id.colorImage);
int color = getGpxDataItem() != null ? getGpxDataItem().getColor() : 0;
if (color == 0 && getGpx() != null) {
if (getGpx().showCurrentTrack) {
color = app.getSettings().CURRENT_TRACK_COLOR.get();
} else {
color = getGpx().getColor(0);
}
}
if (color == 0) {
final RenderingRulesStorage renderer = app.getRendererRegistry().getCurrentSelectedRenderer();
final OsmandSettings.CommonPreference<String> prefColor
= app.getSettings().getCustomRenderProperty(CURRENT_TRACK_COLOR_ATTR);
color = GpxAppearanceAdapter.parseTrackColor(renderer, prefColor.get());
}
if (color == 0) {
colorImageView.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_action_circle));
} else {
colorImageView.setImageDrawable(app.getIconsCache().getPaintedIcon(R.drawable.ic_action_circle, color));
}
trackColor = color;
}
private boolean isArgumentTrue(@NonNull String arg) {
return getArguments() != null && getArguments().getBoolean(arg);
}
protected boolean hasFilterType(GpxDisplayItemType filterType) {
for (GpxDisplayItemType type : filterTypes) {
if (type == filterType) {
return true;
}
}
return false;
}
private List<GpxDisplayGroup> filterGroups(boolean useDisplayGroups) {
List<GpxDisplayGroup> result = getMyActivity().getGpxFile(useDisplayGroups);
List<GpxDisplayGroup> groups = new ArrayList<>();
for (GpxDisplayGroup group : result) {
boolean add = hasFilterType(group.getType());
if (isArgumentTrue(ARG_TO_FILTER_SHORT_TRACKS)) {
Iterator<GpxDisplayItem> item = group.getModifiableList().iterator();
while (item.hasNext()) {
GpxDisplayItem it2 = item.next();
if (it2.analysis != null && it2.analysis.totalDistance < 100) {
item.remove();
}
}
if (group.getModifiableList().isEmpty()) {
add = false;
}
}
if (add) {
groups.add(group);
}
}
return groups;
}
public void updateContent() {
adapter.clear();
List<GpxDisplayGroup> groups = getOriginalGroups();
adapter.setNotifyOnChange(false);
for (GpxDisplayItem i : flatten(groups)) {
adapter.add(i);
}
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
updateHeader();
}
protected List<GpxDisplayItem> flatten(List<GpxDisplayGroup> groups) {
ArrayList<GpxDisplayItem> list = new ArrayList<>();
for(GpxDisplayGroup g : groups) {
list.addAll(g.getModifiableList());
}
return list;
}
private void prepareSplitIntervalAdapterData() {
final List<GpxDisplayGroup> groups = getDisplayGroups();
options.add(app.getString(R.string.shared_string_none));
distanceSplit.add(-1d);
timeSplit.add(-1);
addOptionSplit(30, true, groups); // 50 feet, 20 yards, 20
// m
addOptionSplit(60, true, groups); // 100 feet, 50 yards,
// 50 m
addOptionSplit(150, true, groups); // 200 feet, 100 yards,
// 100 m
addOptionSplit(300, true, groups); // 500 feet, 200 yards,
// 200 m
addOptionSplit(600, true, groups); // 1000 feet, 500 yards,
// 500 m
addOptionSplit(1500, true, groups); // 2000 feet, 1000 yards, 1 km
addOptionSplit(3000, true, groups); // 1 mi, 2 km
addOptionSplit(6000, true, groups); // 2 mi, 5 km
addOptionSplit(15000, true, groups); // 5 mi, 10 km
addOptionSplit(15, false, groups);
addOptionSplit(30, false, groups);
addOptionSplit(60, false, groups);
addOptionSplit(120, false, groups);
addOptionSplit(150, false, groups);
addOptionSplit(300, false, groups);
addOptionSplit(600, false, groups);
addOptionSplit(900, false, groups);
}
private void updateSplit(List<GpxDisplayGroup> groups, SelectedGpxFile sf) {
new SplitTrackAsyncTask(sf, groups).execute((Void) null);
}
private void addOptionSplit(int value, boolean distance, List<GpxDisplayGroup> model) {
if (distance) {
double dvalue = OsmAndFormatter.calculateRoundedDist(value, app);
options.add(OsmAndFormatter.getFormattedDistance((float) dvalue, app));
distanceSplit.add(dvalue);
timeSplit.add(-1);
if (Math.abs(model.get(0).getSplitDistance() - dvalue) < 1) {
selectedSplitInterval = distanceSplit.size() - 1;
}
} else {
if (value < 60) {
options.add(value + " " + app.getString(R.string.int_seconds));
} else if (value % 60 == 0) {
options.add((value / 60) + " " + app.getString(R.string.int_min));
} else {
options.add((value / 60f) + " " + app.getString(R.string.int_min));
}
distanceSplit.add(-1d);
timeSplit.add(value);
if (model.get(0).getSplitTime() == value) {
selectedSplitInterval = distanceSplit.size() - 1;
}
}
}
private class SegmentGPXAdapter extends ArrayAdapter<GpxDisplayItem> {
SegmentGPXAdapter(List<GpxDisplayItem> items) {
super(getActivity(), R.layout.gpx_list_item_tab_content, items);
}
@Override
public boolean isEmpty() {
return false;
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
View row = convertView;
PagerSlidingTabStrip tabLayout;
WrapContentHeightViewPager pager;
boolean create = false;
if (row == null) {
LayoutInflater inflater = getMyActivity().getLayoutInflater();
row = inflater.inflate(R.layout.gpx_list_item_tab_content, parent, false);
boolean light = app.getSettings().isLightContent();
tabLayout = (PagerSlidingTabStrip) row.findViewById(R.id.sliding_tabs);
tabLayout.setTabBackground(R.color.color_transparent);
tabLayout.setIndicatorColorResource(light ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark);
tabLayout.setIndicatorBgColorResource(light ? R.color.dashboard_divider_light : R.color.dashboard_divider_dark);
tabLayout.setIndicatorHeight(AndroidUtils.dpToPx(app, 1f));
tabLayout.setTextColor(tabLayout.getIndicatorColor());
tabLayout.setTextSize(AndroidUtils.spToPx(app, 12f));
tabLayout.setShouldExpand(true);
tabLayout.setTabSelectionType(PagerSlidingTabStrip.TabSelectionType.SOLID_COLOR);
pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
pager.setSwipeable(false);
pager.setOffscreenPageLimit(2);
create = true;
} else {
tabLayout = (PagerSlidingTabStrip) row.findViewById(R.id.sliding_tabs);
pager = (WrapContentHeightViewPager) row.findViewById(R.id.pager);
}
GpxDisplayItem item = getItem(position);
if (item != null) {
pager.setAdapter(new GPXItemPagerAdapter(tabLayout, item));
if (create) {
tabLayout.setViewPager(pager);
} else {
tabLayout.notifyDataSetChanged(true);
}
}
return row;
}
}
private enum GPXTabItemType {
GPX_TAB_ITEM_GENERAL,
GPX_TAB_ITEM_ALTITUDE,
GPX_TAB_ITEM_SPEED
}
private class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvider, ViewAtPositionInterface {
protected SparseArray<View> views = new SparseArray<>();
private PagerSlidingTabStrip tabs;
private GpxDisplayItem gpxItem;
private GPXTabItemType[] tabTypes;
private String[] titles;
private Map<GPXTabItemType, List<ILineDataSet>> dataSetsMap = new HashMap<>();
private TrkSegment segment;
GPXItemPagerAdapter(PagerSlidingTabStrip tabs, GpxDisplayItem gpxItem) {
super();
this.tabs = tabs;
this.gpxItem = gpxItem;
fetchTabTypes();
}
private void fetchTabTypes() {
List<GPXTabItemType> tabTypeList = new ArrayList<>();
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
if (gpxItem != null && gpxItem.analysis != null) {
if (gpxItem.analysis.hasElevationData) {
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
}
if (gpxItem.analysis.isSpeedSpecified()) {
tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_SPEED);
}
}
tabTypes = tabTypeList.toArray(new GPXTabItemType[tabTypeList.size()]);
Context context = tabs.getContext();
titles = new String[tabTypes.length];
for (int i = 0; i < titles.length; i++) {
switch (tabTypes[i]) {
case GPX_TAB_ITEM_GENERAL:
titles[i] = context.getString(R.string.shared_string_overview);
break;
case GPX_TAB_ITEM_ALTITUDE:
titles[i] = context.getString(R.string.altitude);
break;
case GPX_TAB_ITEM_SPEED:
titles[i] = context.getString(R.string.map_widget_speed);
break;
}
}
}
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.hasSpeedData) {
speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, true, true);
}
if (analysis.hasElevationData) {
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);
if (elevationDataSet != null) {
dataSets.add(elevationDataSet);
}
if (analysis.hasElevationData) {
OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, elevationDataSet.getValues(), true, true);
if (slopeDataSet != null) {
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);
if (speedDataSet != null) {
dataSets.add(speedDataSet);
}
dataSetsMap.put(GPXTabItemType.GPX_TAB_ITEM_SPEED, dataSets);
break;
}
}
}
return dataSets;
}
private TrkSegment getTrackSegment(LineChart chart) {
if (segment == null) {
List<ILineDataSet> ds = chart.getLineData().getDataSets();
if (ds != null && ds.size() > 0) {
for (GPXUtilities.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;
}
}
}
}
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 = pos * 1000;
for (WptPt p : segment.points) {
if (p.time - gpxItem.analysis.startTime >= time) {
wpt = p;
break;
}
}
} else {
float distance = pos * dataSet.getDivX();
for (WptPt p : segment.points) {
if (p.distance >= distance) {
wpt = p;
break;
}
}
}
}
return wpt;
}
@Override
public int getCount() {
return tabTypes.length;
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
GPXTabItemType tabType = tabTypes[position];
View view = null;
switch (tabType) {
case GPX_TAB_ITEM_GENERAL:
view = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_general, container, false);
break;
case GPX_TAB_ITEM_ALTITUDE:
view = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_altitude, container, false);
break;
case GPX_TAB_ITEM_SPEED:
view = getActivity().getLayoutInflater().inflate(R.layout.gpx_item_speed, container, false);
break;
}
if (view != null) {
if (gpxItem != null) {
GPXTrackAnalysis analysis = gpxItem.analysis;
final LineChart chart = (LineChart) view.findViewById(R.id.chart);
chart.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
getListView().requestDisallowInterceptTouchEvent(true);
return false;
}
});
chart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, Highlight h) {
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
}
}
@Override
public void onNothingSelected() {
}
});
final View finalView = view;
chart.setOnChartGestureListener(new OnChartGestureListener() {
float highlightDrawX = -1;
@Override
public void onChartGestureStart(MotionEvent me, ChartGesture lastPerformedGesture) {
if (chart.getHighlighted() != null && chart.getHighlighted().length > 0) {
highlightDrawX = chart.getHighlighted()[0].getDrawX();
} else {
highlightDrawX = -1;
}
}
@Override
public void onChartGestureEnd(MotionEvent me, ChartGesture lastPerformedGesture) {
gpxItem.chartMatrix = new Matrix(chart.getViewPortHandler().getMatrixTouch());
Highlight[] highlights = chart.getHighlighted();
if (highlights != null && highlights.length > 0) {
gpxItem.chartHighlightPos = highlights[0].getX();
} else {
gpxItem.chartHighlightPos = -1;
}
for (int i = 0; i < getCount(); i++) {
View v = getViewAtPosition(i);
if (v != finalView) {
updateChart(i);
}
}
}
@Override
public void onChartLongPressed(MotionEvent me) {
}
@Override
public void onChartDoubleTapped(MotionEvent me) {
}
@Override
public void onChartSingleTapped(MotionEvent me) {
}
@Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
}
@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
}
@Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {
if (highlightDrawX != -1) {
Highlight h = chart.getHighlightByTouchPoint(highlightDrawX, 0f);
if (h != null) {
chart.highlightValue(h);
WptPt wpt = getPoint(chart, h.getX());
if (wpt != null) {
selectedPointLatLon = new LatLon(wpt.lat, wpt.lon);
Bitmap bmp = drawSelectedPoint();
imageView.setImageDrawable(new BitmapDrawable(app.getResources(), bmp));
}
}
}
}
});
IconsCache ic = app.getIconsCache();
switch (tabType) {
case GPX_TAB_ITEM_GENERAL:
if (analysis != null) {
if (analysis.hasElevationData || analysis.hasSpeedData) {
GpxUiHelper.setupGPXChart(app, chart, 4);
chart.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_GENERAL, chart)));
updateChart(chart);
chart.setVisibility(View.VISIBLE);
} else {
chart.setVisibility(View.GONE);
}
((ImageView) view.findViewById(R.id.distance_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_polygom_dark));
((ImageView) view.findViewById(R.id.duration_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time_span));
((ImageView) view.findViewById(R.id.start_time_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time_start));
((ImageView) view.findViewById(R.id.end_time_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time_end));
((TextView) view.findViewById(R.id.distance_text))
.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistance, app));
((TextView) view.findViewById(R.id.duration_text))
.setText(Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled()));
if (analysis.timeSpan > 0) {
DateFormat tf = SimpleDateFormat.getTimeInstance(DateFormat.SHORT);
DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
Date start = new Date(analysis.startTime);
((TextView) view.findViewById(R.id.start_time_text)).setText(tf.format(start));
((TextView) view.findViewById(R.id.start_date_text)).setText(df.format(start));
Date end = new Date(analysis.endTime);
((TextView) view.findViewById(R.id.end_time_text)).setText(tf.format(end));
((TextView) view.findViewById(R.id.end_date_text)).setText(df.format(end));
} else {
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
view.findViewById(R.id.start_end_time).setVisibility(View.GONE);
}
} else {
chart.setVisibility(View.GONE);
view.findViewById(R.id.distance_time_span).setVisibility(View.GONE);
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
view.findViewById(R.id.start_end_time).setVisibility(View.GONE);
}
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDetails(GPXTabItemType.GPX_TAB_ITEM_GENERAL);
}
});
break;
case GPX_TAB_ITEM_ALTITUDE:
if (analysis != null) {
if (analysis.hasElevationData) {
GpxUiHelper.setupGPXChart(app, chart, 4);
chart.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE, chart)));
updateChart(chart);
chart.setVisibility(View.VISIBLE);
} else {
chart.setVisibility(View.GONE);
}
((ImageView) view.findViewById(R.id.average_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_altitude_average));
((ImageView) view.findViewById(R.id.range_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_altitude_average));
((ImageView) view.findViewById(R.id.ascent_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_altitude_ascent));
((ImageView) view.findViewById(R.id.descent_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_altitude_descent));
String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app);
String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app);
String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app);
String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app);
((TextView) view.findViewById(R.id.average_text))
.setText(OsmAndFormatter.getFormattedAlt(analysis.avgElevation, app));
((TextView) view.findViewById(R.id.range_text)).setText(min + " - " + max);
((TextView) view.findViewById(R.id.ascent_text)).setText(asc);
((TextView) view.findViewById(R.id.descent_text)).setText(desc);
} else {
chart.setVisibility(View.GONE);
view.findViewById(R.id.average_range).setVisibility(View.GONE);
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
view.findViewById(R.id.ascent_descent).setVisibility(View.GONE);
}
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDetails(GPXTabItemType.GPX_TAB_ITEM_ALTITUDE);
}
});
break;
case GPX_TAB_ITEM_SPEED:
if (analysis != null && analysis.isSpeedSpecified()) {
if (analysis.hasSpeedData) {
GpxUiHelper.setupGPXChart(app, chart, 4);
chart.setData(new LineData(getDataSets(GPXTabItemType.GPX_TAB_ITEM_SPEED, chart)));
updateChart(chart);
chart.setVisibility(View.VISIBLE);
} else {
chart.setVisibility(View.GONE);
}
((ImageView) view.findViewById(R.id.average_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_speed));
((ImageView) view.findViewById(R.id.max_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_max_speed));
((ImageView) view.findViewById(R.id.time_moving_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_time_span));
((ImageView) view.findViewById(R.id.distance_icon))
.setImageDrawable(ic.getThemedIcon(R.drawable.ic_action_polygom_dark));
String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app);
String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app);
((TextView) view.findViewById(R.id.average_text)).setText(avg);
((TextView) view.findViewById(R.id.max_text)).setText(max);
((TextView) view.findViewById(R.id.time_moving_text))
.setText(Algorithms.formatDuration((int) (analysis.timeMoving / 1000), app.accessibilityEnabled()));
((TextView) view.findViewById(R.id.distance_text))
.setText(OsmAndFormatter.getFormattedDistance(analysis.totalDistanceMoving, app));
} else {
chart.setVisibility(View.GONE);
view.findViewById(R.id.average_max).setVisibility(View.GONE);
view.findViewById(R.id.list_divider).setVisibility(View.GONE);
view.findViewById(R.id.time_distance).setVisibility(View.GONE);
}
view.findViewById(R.id.details_view).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openDetails(GPXTabItemType.GPX_TAB_ITEM_SPEED);
}
});
break;
}
}
}
container.addView(view, 0);
views.put(position, view);
return view;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
views.remove(position);
collection.removeView((View) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public View getCustomTabView(ViewGroup parent, int position) {
View tab = getActivity().getLayoutInflater().inflate(R.layout.gpx_tab, parent, false);
tab.setTag(tabTypes[position].name());
deselect(tab);
return tab;
}
private int getImageId(GPXTabItemType tabType) {
int imageId;
switch (tabType) {
case GPX_TAB_ITEM_GENERAL:
imageId = R.drawable.ic_action_polygom_dark;
break;
case GPX_TAB_ITEM_ALTITUDE:
imageId = R.drawable.ic_action_altitude_average;
break;
case GPX_TAB_ITEM_SPEED:
imageId = R.drawable.ic_action_speed;
break;
default:
imageId = R.drawable.ic_action_folder_stroke;
}
return imageId;
}
@Override
public void select(View tab) {
GPXTabItemType tabType = GPXTabItemType.valueOf((String)tab.getTag());
ImageView img = (ImageView) tab.findViewById(R.id.tab_image);
int imageId = getImageId(tabType);
switch (tabs.getTabSelectionType()) {
case ALPHA:
ViewCompat.setAlpha(img, tabs.getTabTextSelectedAlpha());
break;
case SOLID_COLOR:
img.setImageDrawable(app.getIconsCache().getPaintedIcon(imageId, tabs.getTextColor()));
break;
}
}
@Override
public void deselect(View tab) {
GPXTabItemType tabType = GPXTabItemType.valueOf((String)tab.getTag());
ImageView img = (ImageView) tab.findViewById(R.id.tab_image);
int imageId = getImageId(tabType);
switch (tabs.getTabSelectionType()) {
case ALPHA:
ViewCompat.setAlpha(img, tabs.getTabTextAlpha());
break;
case SOLID_COLOR:
img.setImageDrawable(app.getIconsCache().getPaintedIcon(imageId, tabs.getTabInactiveTextColor()));
break;
}
}
@Override
public View getViewAtPosition(int position) {
return views.get(position);
}
void updateChart(int position) {
View view = getViewAtPosition(position);
if (view != null) {
updateChart((LineChart) view.findViewById(R.id.chart));
}
}
void updateChart(LineChart chart) {
if (chart != null && !chart.isEmpty()) {
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);
}
}
}
void openDetails(GPXTabItemType tabType) {
LatLon location = null;
WptPt wpt = null;
gpxItem.chartTypes = null;
List<ILineDataSet> ds = getDataSets(tabType, null);
if (ds != null && ds.size() > 0) {
gpxItem.chartTypes = new GPXDataSetType[ds.size()];
for (int i = 0; i < ds.size(); i++) {
OrderedLineDataSet orderedDataSet = (OrderedLineDataSet) ds.get(i);
gpxItem.chartTypes[i] = 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) {
gpxItem.wasHidden = app.getSelectedGpxHelper().getSelectedFileByPath(getGpx().path) == 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());
}
}
private class SplitTrackAsyncTask extends AsyncTask<Void, Void, Void> {
@Nullable
private final SelectedGpxFile mSelectedGpxFile;
@NonNull private final TrackSegmentFragment mFragment;
@NonNull private final TrackActivity mActivity;
private final List<GpxDisplayGroup> groups;
SplitTrackAsyncTask(@Nullable SelectedGpxFile selectedGpxFile, List<GpxDisplayGroup> groups) {
mSelectedGpxFile = selectedGpxFile;
mFragment = TrackSegmentFragment.this;
mActivity = getMyActivity();
this.groups = groups;
}
protected void onPostExecute(Void result) {
if (mSelectedGpxFile != null) {
mSelectedGpxFile.setDisplayGroups(getDisplayGroups());
}
if (mFragment.isVisible()) {
//mFragment.updateContent();
}
if (!mActivity.isFinishing()) {
mActivity.setProgressBarIndeterminateVisibility(false);
}
}
protected void onPreExecute() {
mActivity.setProgressBarIndeterminateVisibility(true);
}
@Override
protected Void doInBackground(Void... params) {
for (GpxDisplayGroup model : groups) {
OsmandApplication application = mActivity.getMyApplication();
if (selectedSplitInterval == 0) {
model.noSplit(application);
} else if (distanceSplit.get(selectedSplitInterval) > 0) {
model.splitByDistance(application, distanceSplit.get(selectedSplitInterval));
} else if (timeSplit.get(selectedSplitInterval) > 0) {
model.splitByTime(application, timeSplit.get(selectedSplitInterval));
}
}
return null;
}
}
}