Add locationOnMap check to analyze track screen and add bearing to selected gpx point
This commit is contained in:
parent
69d1830b8f
commit
675faeae73
5 changed files with 120 additions and 72 deletions
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="shared_string_bearing">Bearing</string>
|
||||
<string name="quick_action_showhide_mapillary_descr">A toggle to show or hide the Mapillary layer on the map.</string>
|
||||
<string name="quick_action_mapillary_show">Show Mapillary</string>
|
||||
<string name="quick_action_mapillary_hide">Hide Mapillary</string>
|
||||
|
|
|
@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat;
|
|||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities.GPXTrackAnalysis;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
|
@ -31,15 +30,15 @@ import java.util.Date;
|
|||
|
||||
public class SelectedGpxMenuBuilder extends MenuBuilder {
|
||||
|
||||
private SelectedGpxFile selectedGpxFile;
|
||||
private SelectedGpxPoint selectedGpxPoint;
|
||||
private GPXTrackAnalysis analysis;
|
||||
private WptPt selectedPoint;
|
||||
|
||||
public SelectedGpxMenuBuilder(@NonNull MapActivity mapActivity, @NonNull SelectedGpxPoint selectedGpxPoint) {
|
||||
super(mapActivity);
|
||||
selectedGpxFile = selectedGpxPoint.getSelectedGpxFile();
|
||||
this.selectedGpxPoint = selectedGpxPoint;
|
||||
selectedPoint = selectedGpxPoint.getSelectedPoint();
|
||||
analysis = selectedGpxFile.getTrackAnalysis(mapActivity.getMyApplication());
|
||||
analysis = selectedGpxPoint.getSelectedGpxFile().getTrackAnalysis(mapActivity.getMyApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -129,18 +128,27 @@ public class SelectedGpxMenuBuilder extends MenuBuilder {
|
|||
OsmAndFormatter.getFormattedDistance((float) selectedPoint.distance, app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
|
||||
DateFormat format = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_time_start), null, app.getString(R.string.shared_string_time),
|
||||
format.format(selectedPoint.time), 0, null,
|
||||
false, null, false, 0, false, false, false, null, true);
|
||||
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_altitude), null, app.getString(R.string.altitude),
|
||||
OsmAndFormatter.getFormattedAlt(selectedPoint.ele, app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_speed), null, app.getString(R.string.average_speed),
|
||||
OsmAndFormatter.getFormattedSpeed((float) selectedPoint.speed, app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
if (selectedPoint.time != 0) {
|
||||
DateFormat format = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_time_start), null, app.getString(R.string.shared_string_time),
|
||||
format.format(selectedPoint.time), 0, null,
|
||||
false, null, false, 0, false, false, false, null, true);
|
||||
}
|
||||
if (!Double.isNaN(selectedPoint.ele)) {
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_altitude), null, app.getString(R.string.altitude),
|
||||
OsmAndFormatter.getFormattedAlt(selectedPoint.ele, app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
}
|
||||
if (!Double.isNaN(selectedPoint.speed)) {
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_speed), null, app.getString(R.string.average_speed),
|
||||
OsmAndFormatter.getFormattedSpeed((float) selectedPoint.speed, app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
}
|
||||
if (selectedGpxPoint.getPointLocation().hasBearing()) {
|
||||
buildRow(view, getThemedIcon(R.drawable.ic_action_relative_bearing), null, app.getString(R.string.shared_string_bearing),
|
||||
OsmAndFormatter.getFormattedAzimuth(selectedGpxPoint.getPointLocation().getBearing(), app), 0, null,
|
||||
false, null, false, 0, false, false, false, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildCategoryView(View view, String name) {
|
||||
|
|
|
@ -7,8 +7,10 @@ import android.os.AsyncTask;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.GpxSelectionHelper;
|
||||
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
|
||||
|
@ -22,24 +24,25 @@ import net.osmand.plus.mapcontextmenu.builders.SelectedGpxMenuBuilder;
|
|||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SelectedGpxMenuController extends MenuController {
|
||||
|
||||
private SelectedGpxFile item;
|
||||
private SelectedGpxPoint selectedGpxPoint;
|
||||
|
||||
public SelectedGpxMenuController(@NonNull final MapActivity mapActivity, @NonNull PointDescription pointDescription,
|
||||
@NonNull SelectedGpxPoint selectedGpxPoint) {
|
||||
@NonNull final SelectedGpxPoint selectedGpxPoint) {
|
||||
super(new SelectedGpxMenuBuilder(mapActivity, selectedGpxPoint), pointDescription, mapActivity);
|
||||
this.item = selectedGpxPoint.getSelectedGpxFile();
|
||||
this.selectedGpxPoint = selectedGpxPoint;
|
||||
builder.setShowOnlinePhotos(false);
|
||||
|
||||
leftTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
Intent intent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization().getTrackActivity());
|
||||
intent.putExtra(TrackActivity.TRACK_FILE_NAME, item.getGpxFile().path);
|
||||
intent.putExtra(TrackActivity.TRACK_FILE_NAME, selectedGpxPoint.getSelectedGpxFile().getGpxFile().path);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
mapActivity.startActivity(intent);
|
||||
}
|
||||
|
@ -50,30 +53,41 @@ public class SelectedGpxMenuController extends MenuController {
|
|||
rightTitleButtonController = new TitleButtonController() {
|
||||
@Override
|
||||
public void buttonPressed() {
|
||||
new OpenGpxDetailsTask(item).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
new OpenGpxDetailsTask(selectedGpxPoint.getSelectedGpxFile(), selectedGpxPoint.getSelectedPoint(), mapActivity).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
rightTitleButtonController.caption = mapActivity.getString(R.string.analyze_on_map);
|
||||
rightTitleButtonController.startIconId = R.drawable.ic_action_track_16;
|
||||
}
|
||||
|
||||
private class OpenGpxDetailsTask extends AsyncTask<Void, Void, GpxSelectionHelper.GpxDisplayItem> {
|
||||
private static class OpenGpxDetailsTask extends AsyncTask<Void, Void, GpxSelectionHelper.GpxDisplayItem> {
|
||||
|
||||
private SelectedGpxFile item;
|
||||
ProgressDialog progressDialog;
|
||||
private OsmandApplication app;
|
||||
|
||||
OpenGpxDetailsTask(SelectedGpxFile item) {
|
||||
this.item = item;
|
||||
private WptPt selectedPoint;
|
||||
private SelectedGpxFile selectedGpxFile;
|
||||
|
||||
private ProgressDialog progressDialog;
|
||||
private WeakReference<MapActivity> activityRef;
|
||||
|
||||
OpenGpxDetailsTask(SelectedGpxFile selectedGpxFile, WptPt selectedPoint, MapActivity mapActivity) {
|
||||
app = mapActivity.getMyApplication();
|
||||
this.activityRef = new WeakReference<>(mapActivity);
|
||||
this.selectedGpxFile = selectedGpxFile;
|
||||
this.selectedPoint = selectedPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
if (item.getGpxFile().path != null) {
|
||||
progressDialog = new ProgressDialog(getMapActivity());
|
||||
progressDialog.setTitle("");
|
||||
progressDialog.setMessage(getMapActivity().getResources().getString(R.string.loading_data));
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
MapActivity activity = activityRef.get();
|
||||
if (activity != null && AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
if (selectedGpxFile.getGpxFile().path != null) {
|
||||
progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setTitle("");
|
||||
progressDialog.setMessage(app.getString(R.string.loading_data));
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,13 +96,12 @@ public class SelectedGpxMenuController extends MenuController {
|
|||
GpxSelectionHelper.GpxDisplayGroup gpxDisplayGroup = null;
|
||||
GPXUtilities.GPXFile gpxFile = null;
|
||||
GPXUtilities.Track generalTrack = null;
|
||||
if (item.getGpxFile().path != null) {
|
||||
gpxFile = GPXUtilities.loadGPXFile(new File(item.getGpxFile().path));
|
||||
if (selectedGpxFile.getGpxFile().path != null) {
|
||||
gpxFile = GPXUtilities.loadGPXFile(new File(selectedGpxFile.getGpxFile().path));
|
||||
}
|
||||
if (gpxFile != null) {
|
||||
generalTrack = gpxFile.getGeneralTrack();
|
||||
}
|
||||
OsmandApplication app = getMapActivity().getMyApplication();
|
||||
if (generalTrack != null) {
|
||||
gpxFile.addGeneralTrack();
|
||||
gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, generalTrack);
|
||||
|
@ -107,47 +120,48 @@ public class SelectedGpxMenuController extends MenuController {
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(GpxSelectionHelper.GpxDisplayItem gpxItem) {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
if (gpxItem != null && gpxItem.analysis != null) {
|
||||
ArrayList<GpxUiHelper.GPXDataSetType> list = new ArrayList<>();
|
||||
if (gpxItem.analysis.hasElevationData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.ALTITUDE);
|
||||
MapActivity activity = activityRef.get();
|
||||
if (activity != null) {
|
||||
if (progressDialog != null && AndroidUtils.isActivityNotDestroyed(activity)) {
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
if (gpxItem.analysis.hasSpeedData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.SPEED);
|
||||
} else if (gpxItem.analysis.hasElevationData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.SLOPE);
|
||||
if (gpxItem != null && gpxItem.analysis != null) {
|
||||
ArrayList<GpxUiHelper.GPXDataSetType> list = new ArrayList<>();
|
||||
if (gpxItem.analysis.hasElevationData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.ALTITUDE);
|
||||
}
|
||||
if (gpxItem.analysis.hasSpeedData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.SPEED);
|
||||
} else if (gpxItem.analysis.hasElevationData) {
|
||||
list.add(GpxUiHelper.GPXDataSetType.SLOPE);
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
gpxItem.chartTypes = list.toArray(new GpxUiHelper.GPXDataSetType[0]);
|
||||
}
|
||||
gpxItem.locationOnMap = selectedPoint;
|
||||
OsmandSettings settings = app.getSettings();
|
||||
settings.setMapLocationToShow(gpxItem.locationStart.lat, gpxItem.locationStart.lon,
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
||||
false,
|
||||
gpxItem);
|
||||
activity.getContextMenu().hide();
|
||||
MapActivity.launchMapActivityMoveToTop(activity);
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
gpxItem.chartTypes = list.toArray(new GpxUiHelper.GPXDataSetType[list.size()]);
|
||||
}
|
||||
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
OsmandApplication app = mapActivity.getMyApplication();
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
settings.setMapLocationToShow(gpxItem.locationStart.lat, gpxItem.locationStart.lon,
|
||||
settings.getLastKnownMapZoom(),
|
||||
new PointDescription(PointDescription.POINT_TYPE_WPT, gpxItem.name),
|
||||
false,
|
||||
gpxItem);
|
||||
mapActivity.getContextMenu().hide();
|
||||
MapActivity.launchMapActivityMoveToTop(mapActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setObject(Object object) {
|
||||
if (object instanceof SelectedGpxFile) {
|
||||
this.item = (SelectedGpxFile) object;
|
||||
if (object instanceof SelectedGpxPoint) {
|
||||
this.selectedGpxPoint = (SelectedGpxPoint) object;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getObject() {
|
||||
return item;
|
||||
return selectedGpxPoint;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -182,10 +196,12 @@ public class SelectedGpxMenuController extends MenuController {
|
|||
|
||||
private final WptPt selectedPoint;
|
||||
private final SelectedGpxFile selectedGpxFile;
|
||||
private final Location pointLocation;
|
||||
|
||||
public SelectedGpxPoint(WptPt selectedPoint, SelectedGpxFile selectedGpxFile) {
|
||||
public SelectedGpxPoint(SelectedGpxFile selectedGpxFile, WptPt selectedPoint, Location pointLocation) {
|
||||
this.selectedPoint = selectedPoint;
|
||||
this.selectedGpxFile = selectedGpxFile;
|
||||
this.pointLocation = pointLocation;
|
||||
}
|
||||
|
||||
public WptPt getSelectedPoint() {
|
||||
|
@ -195,5 +211,9 @@ public class SelectedGpxMenuController extends MenuController {
|
|||
public SelectedGpxFile getSelectedGpxFile() {
|
||||
return selectedGpxFile;
|
||||
}
|
||||
|
||||
public Location getPointLocation() {
|
||||
return pointLocation;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -737,6 +737,14 @@ public class TrackDetailsMenu {
|
|||
}
|
||||
if (gpxItem.chartHighlightPos != -1) {
|
||||
chart.highlightValue(gpxItem.chartHighlightPos, 0);
|
||||
} else if (gpxItem.locationOnMap != null) {
|
||||
LineData lineData = chart.getLineData();
|
||||
List<ILineDataSet> ds = lineData != null ? lineData.getDataSets() : null;
|
||||
if (ds != null && ds.size() > 0) {
|
||||
OrderedLineDataSet dataSet = (OrderedLineDataSet) ds.get(0);
|
||||
gpxItem.chartHighlightPos = (float) (gpxItem.locationOnMap.distance / dataSet.getDivX());
|
||||
chart.highlightValue(gpxItem.chartHighlightPos, 0);
|
||||
}
|
||||
} else {
|
||||
chart.highlightValue(null);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
|
@ -608,9 +609,9 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
for (TrkSegment segment : segments) {
|
||||
QuadRect trackBounds = GPXUtilities.calculateBounds(segment.points);
|
||||
if (QuadRect.trivialOverlap(tb.getLatLonBounds(), trackBounds)) {
|
||||
WptPt selectedPoint = findPointNearSegment(tb, segment.points, r, mx, my);
|
||||
if (selectedPoint != null) {
|
||||
res.add(new SelectedGpxPoint(selectedPoint, selectedGpxFile));
|
||||
SelectedGpxPoint selectedGpxPoint = findPointNearSegment(tb, selectedGpxFile, segment.points, r, mx, my);
|
||||
if (selectedGpxPoint != null) {
|
||||
res.add(selectedGpxPoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -618,7 +619,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
}
|
||||
}
|
||||
|
||||
private WptPt findPointNearSegment(RotatedTileBox tb, List<WptPt> points, int r, int mx, int my) {
|
||||
private SelectedGpxPoint findPointNearSegment(RotatedTileBox tb, SelectedGpxFile selectedGpxFile, List<WptPt> points, int r, int mx, int my) {
|
||||
WptPt firstPoint = points.get(0);
|
||||
int ppx = (int) tb.getPixXFromLatLon(firstPoint.lat, firstPoint.lon);
|
||||
int ppy = (int) tb.getPixYFromLatLon(firstPoint.lat, firstPoint.lon);
|
||||
|
@ -630,7 +631,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
int py = (int) tb.getPixYFromLatLon(point.lat, point.lon);
|
||||
int cross = placeInBbox(px, py, mx, my, r, r);
|
||||
if (cross == 0) {
|
||||
return createProjectionPoint(points.get(i - 1), point, tb.getLatLonFromPixel(mx, my));
|
||||
return createProjectionPoint(selectedGpxFile, points.get(i - 1), point, tb.getLatLonFromPixel(mx, my));
|
||||
}
|
||||
if ((pcross & cross) == 0) {
|
||||
int mpx = px;
|
||||
|
@ -641,7 +642,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
int mpynew = mpy / 2 + ppy / 2;
|
||||
int mcrossnew = placeInBbox(mpxnew, mpynew, mx, my, r, r);
|
||||
if (mcrossnew == 0) {
|
||||
return createProjectionPoint(points.get(i - 1), point, tb.getLatLonFromPixel(mx, my));
|
||||
return createProjectionPoint(selectedGpxFile, points.get(i - 1), point, tb.getLatLonFromPixel(mx, my));
|
||||
}
|
||||
if ((mcrossnew & mcross) != 0) {
|
||||
mpx = mpxnew;
|
||||
|
@ -664,7 +665,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
return null;
|
||||
}
|
||||
|
||||
private WptPt createProjectionPoint(WptPt prevPoint, WptPt nextPoint, LatLon latLon) {
|
||||
private SelectedGpxPoint createProjectionPoint(SelectedGpxFile selectedGpxFile, WptPt prevPoint, WptPt nextPoint, LatLon latLon) {
|
||||
LatLon projection = MapUtils.getProjection(latLon.getLatitude(), latLon.getLongitude(), prevPoint.lat, prevPoint.lon, nextPoint.lat, nextPoint.lon);
|
||||
|
||||
WptPt projectionPoint = new WptPt();
|
||||
|
@ -678,7 +679,17 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
|
|||
projectionPoint.time = (long) getValueByDistInterpolation(projectionPoint.distance, prevPoint.distance, prevPoint.time, nextPoint.distance, nextPoint.time);
|
||||
}
|
||||
|
||||
return projectionPoint;
|
||||
Location projectionLocation = new Location("");
|
||||
projectionLocation.setLatitude(projectionPoint.lat);
|
||||
projectionLocation.setLongitude(projectionPoint.lon);
|
||||
|
||||
Location nextPointLocation = new Location("");
|
||||
nextPointLocation.setLatitude(nextPoint.lat);
|
||||
nextPointLocation.setLongitude(nextPoint.lon);
|
||||
|
||||
projectionLocation.setBearing(projectionLocation.bearingTo(nextPointLocation));
|
||||
|
||||
return new SelectedGpxPoint(selectedGpxFile, projectionPoint, projectionLocation);
|
||||
}
|
||||
|
||||
private double getValueByDistInterpolation(double projectionDist, double prevDist, double prevVal, double nextDist, double nextVal) {
|
||||
|
|
Loading…
Reference in a new issue