From 675faeae7325e7fcc350a110fcc8e22ea03ef123 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Fri, 19 Jun 2020 13:35:06 +0300 Subject: [PATCH] Add locationOnMap check to analyze track screen and add bearing to selected gpx point --- OsmAnd/res/values/strings.xml | 1 + .../builders/SelectedGpxMenuBuilder.java | 40 +++--- .../SelectedGpxMenuController.java | 116 ++++++++++-------- .../other/TrackDetailsMenu.java | 8 ++ .../src/net/osmand/plus/views/GPXLayer.java | 27 ++-- 5 files changed, 120 insertions(+), 72 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 6362a76dc1..940de81238 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,7 @@ Thx - Hardy --> + Bearing A toggle to show or hide the Mapillary layer on the map. Show Mapillary Hide Mapillary diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java index 5914e8b4c1..29c54f5b90 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java @@ -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) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java index 05e1c2a4da..e6e48ac725 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/SelectedGpxMenuController.java @@ -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 { + private static class OpenGpxDetailsTask extends AsyncTask { - 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 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 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 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; + } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java index 9e0274d557..98991fc351 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/other/TrackDetailsMenu.java @@ -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 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); } diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index 88381c5bee..881b7159f4 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -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 points, int r, int mx, int my) { + private SelectedGpxPoint findPointNearSegment(RotatedTileBox tb, SelectedGpxFile selectedGpxFile, List 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) {