Merge pull request #9252 from osmandapp/open_analyze_track

Select tracks from map first part
This commit is contained in:
vshcherb 2020-06-16 15:00:08 +02:00 committed by GitHub
commit 0043dcea4d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 284 additions and 17 deletions

View file

@ -29,6 +29,7 @@ public class PointDescription {
public static final String POINT_TYPE_FAVORITE = "favorite";
public static final String POINT_TYPE_WPT = "wpt";
public static final String POINT_TYPE_GPX = "gpx";
public static final String POINT_TYPE_RTE = "rte";
public static final String POINT_TYPE_POI = "poi";
public static final String POINT_TYPE_ADDRESS = "address";

View file

@ -32,6 +32,7 @@ import net.osmand.data.TransportStop;
import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
@ -59,6 +60,7 @@ import net.osmand.plus.mapcontextmenu.controllers.MapMarkerMenuController;
import net.osmand.plus.mapcontextmenu.controllers.MyLocationMenuController;
import net.osmand.plus.mapcontextmenu.controllers.PointDescriptionMenuController;
import net.osmand.plus.mapcontextmenu.controllers.RenderedObjectMenuController;
import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController;
import net.osmand.plus.mapcontextmenu.controllers.TargetPointMenuController;
import net.osmand.plus.mapcontextmenu.controllers.TransportRouteController;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
@ -227,6 +229,8 @@ public abstract class MenuController extends BaseMenuController implements Colla
menuController = new RenderedObjectMenuController(mapActivity, pointDescription, (RenderedObject) object);
} else if (object instanceof MapillaryImage) {
menuController = new MapillaryMenuController(mapActivity, pointDescription, (MapillaryImage) object);
} else if (object instanceof SelectedGpxFile) {
menuController = new SelectedGpxMenuController(mapActivity, pointDescription, (SelectedGpxFile) object);
}
}
if (menuController == null) {

View file

@ -0,0 +1,178 @@
package net.osmand.plus.mapcontextmenu.controllers;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import net.osmand.GPXUtilities;
import net.osmand.data.PointDescription;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.settings.backend.OsmandSettings;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class SelectedGpxMenuController extends MenuController {
private SelectedGpxFile item;
public SelectedGpxMenuController(@NonNull final MapActivity mapActivity, @NonNull PointDescription pointDescription, @NonNull final SelectedGpxFile item) {
super(new MenuBuilder(mapActivity), pointDescription, mapActivity);
this.item = item;
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.OPEN_TRACKS_LIST, true);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
mapActivity.startActivity(intent);
}
};
leftTitleButtonController.caption = mapActivity.getString(R.string.shared_string_open_track);
leftTitleButtonController.startIconId = R.drawable.ic_action_folder;
rightTitleButtonController = new TitleButtonController() {
@Override
public void buttonPressed() {
new OpenGpxDetailsTask(item).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 SelectedGpxFile item;
ProgressDialog progressDialog;
OpenGpxDetailsTask(SelectedGpxFile item) {
this.item = item;
}
@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();
}
}
@Override
protected GpxSelectionHelper.GpxDisplayItem doInBackground(Void... voids) {
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 (gpxFile != null) {
generalTrack = gpxFile.getGeneralTrack();
}
OsmandApplication app = getMapActivity().getMyApplication();
if (generalTrack != null) {
gpxFile.addGeneralTrack();
gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, generalTrack);
} else if (gpxFile != null && gpxFile.tracks.size() > 0) {
gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, gpxFile.tracks.get(0));
}
List<GpxSelectionHelper.GpxDisplayItem> items = null;
if (gpxDisplayGroup != null) {
items = gpxDisplayGroup.getModifiableList();
}
if (items != null && items.size() > 0) {
return items.get(0);
}
return null;
}
@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);
}
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[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;
}
}
@Override
protected Object getObject() {
return item;
}
@NonNull
@Override
public String getTypeStr() {
return getPointDescription().getTypeName();
}
@NonNull
@Override
public String getCommonTypeStr() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
return mapActivity.getString(R.string.shared_string_gpx_track);
} else {
return "";
}
}
@Override
public boolean needStreetName() {
return false;
}
@Override
public Drawable getRightIcon() {
int color = isLight() ? R.color.active_color_primary_light : R.color.active_color_primary_dark;
return getIcon(R.drawable.ic_action_polygom_dark, color);
}
}

View file

@ -41,16 +41,19 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.MapMarkersHelper.MapMarkersGroup;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.base.FavoriteImageDrawable;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu.TrackChartPoints;
import net.osmand.plus.render.OsmandRenderer;
import net.osmand.plus.render.OsmandRenderer.RenderingContext;
import net.osmand.plus.settings.backend.OsmandSettings.CommonPreference;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import net.osmand.plus.views.ContextMenuLayer.IMoveObjectProvider;
import net.osmand.plus.views.MapTextLayer.MapTextProvider;
import net.osmand.render.RenderingRuleProperty;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms;
import java.io.File;
import java.util.ArrayList;
@ -62,8 +65,10 @@ import java.util.Map;
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_COLOR_ATTR;
import static net.osmand.plus.dialogs.ConfigureMapMenu.CURRENT_TRACK_WIDTH_ATTR;
public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
ContextMenuLayer.IMoveObjectProvider, MapTextProvider<WptPt> {
public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IMoveObjectProvider, MapTextProvider<WptPt> {
private static final double TOUCH_RADIUS_MULTIPLIER = 1.5;
private static final int START_ZOOM = 7;
private OsmandMapTileView view;
@ -83,9 +88,6 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private LayerDrawable selectedPoint;
private TrackChartPoints trackChartPoints;
private static final int startZoom = 7;
private GpxSelectionHelper selectedGpxHelper;
private MapMarkersHelper mapMarkersHelper;
private Paint paintBmp;
@ -96,15 +98,13 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private Paint paintOuterRect;
private Paint paintInnerRect;
private Paint paintGridOuterCircle;
private Paint paintGridOuterCircle;
private Paint paintGridCircle;
private Paint paintTextIcon;
private OsmandRenderer osmandRenderer;
private GPXFile gpx;
private ContextMenuLayer contextMenuLayer;
@ColorInt
private int visitedColor;
@ -290,7 +290,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private void drawSelectedFilesSplits(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles,
DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
if (tileBox.getZoom() >= START_ZOOM) {
// request to load
for (SelectedGpxFile g : selectedGPXFiles) {
List<GpxDisplayGroup> groups = g.getDisplayGroups(view.getApplication());
@ -371,7 +371,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
private void drawSelectedFilesPoints(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles) {
if (tileBox.getZoom() >= startZoom) {
if (tileBox.getZoom() >= START_ZOOM) {
float textScale = view.getSettings().TEXT_SCALE.get();
float iconSize = FavoriteImageDrawable.getOrCreate(view.getContext(), 0,
true, (WptPt) null).getIntrinsicWidth() * 3 / 2.5f * textScale;
@ -575,12 +575,11 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return (Math.abs(objx - ex) <= radius * 1.5 && Math.abs(objy - ey) <= radius * 1.5);
// return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
return (Math.abs(objx - ex) <= radius && Math.abs(objy - ey) <= radius);
}
public void getWptFromPoint(RotatedTileBox tb, PointF point, List<? super WptPt> res) {
int r = getScaledTouchRadius(view.getApplication(), getDefaultRadiusPoi(tb));
int r = (int) (getScaledTouchRadius(view.getApplication(), getDefaultRadiusPoi(tb)) * TOUCH_RADIUS_MULTIPLIER);
int ex = (int) point.x;
int ey = (int) point.y;
List<SelectedGpxFile> selectedGpxFiles = new ArrayList<>(selectedGpxHelper.getSelectedGPXFiles());
@ -597,14 +596,98 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
}
public void getTracksFromPoint(RotatedTileBox tb, PointF point, List<Object> res) {
int r = getScaledTouchRadius(view.getApplication(), getDefaultRadiusPoi(tb));
int mx = (int) point.x;
int my = (int) point.y;
List<SelectedGpxFile> selectedGpxFiles = new ArrayList<>(selectedGpxHelper.getSelectedGPXFiles());
for (SelectedGpxFile selectedGpxFile : selectedGpxFiles) {
List<TrkSegment> segments = selectedGpxFile.getPointsToDisplay();
for (TrkSegment segment : segments) {
boolean nearSegment = isPointNearSegment(tb, segment.points, r, mx, my);
if (nearSegment) {
res.add(selectedGpxFile);
break;
}
}
}
}
private boolean isPointNearSegment(RotatedTileBox tb, 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);
int pcross = placeInBbox(ppx, ppy, mx, my, r, r);
for (int i = 1; i < points.size(); i++) {
WptPt point = points.get(i);
int px = (int) tb.getPixXFromLatLon(point.lat, point.lon);
int py = (int) tb.getPixYFromLatLon(point.lat, point.lon);
int cross = placeInBbox(px, py, mx, my, r, r);
if (cross == 0) {
return true;
}
if ((pcross & cross) == 0) {
int mpx = px;
int mpy = py;
int mcross = cross;
while (Math.abs(mpx - ppx) > r || Math.abs(mpy - ppy) > r) {
int mpxnew = mpx / 2 + ppx / 2;
int mpynew = mpy / 2 + ppy / 2;
int mcrossnew = placeInBbox(mpxnew, mpynew, mx, my, r, r);
if (mcrossnew == 0) {
return true;
}
if ((mcrossnew & mcross) != 0) {
mpx = mpxnew;
mpy = mpynew;
mcross = mcrossnew;
} else if ((mcrossnew & pcross) != 0) {
ppx = mpxnew;
ppy = mpynew;
pcross = mcrossnew;
} else {
// this should never happen theoretically
break;
}
}
}
pcross = cross;
ppx = px;
ppy = py;
}
return false;
}
int placeInBbox(int x, int y, int mx, int my, int halfw, int halfh) {
int cross = 0;
cross |= (x < mx - halfw ? 1 : 0);
cross |= (x > mx + halfw ? 2 : 0);
cross |= (y < my - halfh ? 4 : 0);
cross |= (y > my + halfh ? 8 : 0);
return cross;
}
@Override
public PointDescription getObjectName(Object o) {
if (o instanceof WptPt) {
return new PointDescription(PointDescription.POINT_TYPE_WPT, ((WptPt) o).name); //$NON-NLS-1$
return new PointDescription(PointDescription.POINT_TYPE_WPT, ((WptPt) o).name);
} else if (o instanceof SelectedGpxFile) {
SelectedGpxFile selectedGpxFile = (SelectedGpxFile) o;
String name = formatName(Algorithms.getFileWithoutDirs(selectedGpxFile.getGpxFile().path));
return new PointDescription(PointDescription.POINT_TYPE_GPX, name);
}
return null;
}
private String formatName(String name) {
int ext = name.lastIndexOf('.');
if (ext != -1) {
name = name.substring(0, ext);
}
return name.replace('_', ' ');
}
@Override
public boolean disableSingleTap() {
return false;
@ -617,7 +700,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
@Override
public boolean isObjectClickable(Object o) {
return o instanceof WptPt;
return o instanceof WptPt || o instanceof SelectedGpxFile;
}
@Override
@ -627,8 +710,9 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
@Override
public void collectObjectsFromPoint(PointF point, RotatedTileBox tileBox, List<Object> res, boolean unknownLocation) {
if (tileBox.getZoom() >= startZoom) {
if (tileBox.getZoom() >= START_ZOOM) {
getWptFromPoint(tileBox, point, res);
getTracksFromPoint(tileBox, point, res);
}
}