Merge pull request #9252 from osmandapp/open_analyze_track
Select tracks from map first part
This commit is contained in:
commit
0043dcea4d
4 changed files with 284 additions and 17 deletions
|
@ -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";
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue