Merge pull request #4341 from osmandapp/sasha_pasha_branch

Sasha pasha branch
This commit is contained in:
vshcherb 2017-08-26 16:07:02 +02:00 committed by GitHub
commit 60bfd28830
20 changed files with 834 additions and 768 deletions

View file

@ -121,7 +121,7 @@
android:visibility="gone"/> android:visibility="gone"/>
<TextView <TextView
android:id="@+id/add_point_after_text" android:id="@+id/add_point_before_after_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
@ -131,22 +131,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon" android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon" android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_after" tools:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_before_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle" android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/> android:visibility="gone"/>
</RelativeLayout> </RelativeLayout>

View file

@ -116,7 +116,7 @@
android:visibility="gone"/> android:visibility="gone"/>
<TextView <TextView
android:id="@+id/add_point_after_text" android:id="@+id/add_point_before_after_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
@ -126,22 +126,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon" android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon" android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_after" tools:text="@string/add_point_after"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_before_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="4dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/add_point_before"
android:textAppearance="@style/TextAppearance.ListItemTitle" android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/> android:visibility="gone"/>
</RelativeLayout> </RelativeLayout>

View file

@ -52,15 +52,42 @@
android:textAppearance="@style/TextAppearance.ListItemTitle" android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="Point 2"/> tools:text="Point 2"/>
<TextView <LinearLayout
android:id="@+id/selected_point_distance"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle" <TextView
android:textColor="?android:textColorSecondary" android:id="@+id/selected_point_distance"
android:textSize="@dimen/default_list_text_size" android:layout_width="wrap_content"
tools:text="386 m"/> android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="386 m"/>
<android.support.v7.widget.AppCompatTextView
android:maxLines="1"
android:id="@+id/selected_point_ele"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
tools:text="Altitude: 345 m"/>
<android.support.v7.widget.AppCompatTextView
android:maxLines="1"
android:id="@+id/selected_point_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_list_text_size"
tools:text="Speed: 45 km/h"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -9,8 +9,6 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="measurement_tool_altitude">Altitude: %1$s</string>
<string name="measurement_tool_speed">Speed: %1$s</string>
<string name="line">Line</string> <string name="line">Line</string>
<string name="save_as_route_point">Save as route points</string> <string name="save_as_route_point">Save as route points</string>
<string name="save_as_line">Save as line</string> <string name="save_as_line">Save as line</string>

View file

@ -95,6 +95,7 @@ import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu; import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment; import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenuFragment;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu; import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolFragment; import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.measurementtool.NewGpxData; import net.osmand.plus.measurementtool.NewGpxData;
import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.render.RendererRegistry;
@ -944,7 +945,9 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
NewGpxData newGpxData = (NewGpxData) toShow; NewGpxData newGpxData = (NewGpxData) toShow;
QuadRect qr = newGpxData.getRect(); QuadRect qr = newGpxData.getRect();
mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0); mapView.fitRectToMap(qr.left, qr.right, qr.top, qr.bottom, (int) qr.width(), (int) qr.height(), 0);
MeasurementToolFragment.showInstance(getSupportFragmentManager(), newGpxData); MeasurementEditingContext editingContext = new MeasurementEditingContext();
editingContext.setNewGpxData(newGpxData);
MeasurementToolFragment.showInstance(getSupportFragmentManager(), editingContext);
} else { } else {
mapContextMenu.show(latLonToShow, mapLabelToShow, toShow); mapContextMenu.show(latLonToShow, mapLabelToShow, toShow);
} }

View file

@ -764,7 +764,7 @@ public class MapActivityActions implements DialogProvider {
.setListener(new ContextMenuAdapter.ItemClickListener() { .setListener(new ContextMenuAdapter.ItemClickListener() {
@Override @Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked) { public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked) {
MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager(), null); MeasurementToolFragment.showInstance(mapActivity.getSupportFragmentManager());
return true; return true;
} }
}).createItem()); }).createItem());

View file

@ -0,0 +1,315 @@
package net.osmand.plus.measurementtool;
import android.util.Pair;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.measurementtool.command.MeasurementCommandManager;
import net.osmand.plus.routing.RouteCalculationParams;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.router.RouteCalculationProgress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
public class MeasurementEditingContext {
private OsmandApplication application;
private final MeasurementCommandManager commandManager = new MeasurementCommandManager();
private TrkSegment before = new TrkSegment();
// cache should be deleted if before changed or snappedToRoadPoints
private TrkSegment beforeCacheForSnap;
private TrkSegment after = new TrkSegment();
// cache should be deleted if after changed or snappedToRoadPoints
private TrkSegment afterCacheForSnap;
private NewGpxData newGpxData;
private int selectedPointPosition = -1;
private WptPt originalPointToMove;
private boolean inSnapToRoadMode;
private SnapToRoadProgressListener progressListener;
private ApplicationMode snapToRoadAppMode;
private RouteCalculationProgress calculationProgress;
private Queue<Pair<WptPt, WptPt>> snapToRoadPairsToCalculate = new ConcurrentLinkedQueue<>();
private Map<Pair<WptPt, WptPt>, List<WptPt>> snappedToRoadPoints = new ConcurrentHashMap<>();
public void setApplication(OsmandApplication application) {
this.application = application;
}
public MeasurementCommandManager getCommandManager() {
return commandManager;
}
public boolean isInSnapToRoadMode() {
return inSnapToRoadMode;
}
public int getSelectedPointPosition() {
return selectedPointPosition;
}
public void setSelectedPointPosition(int selectedPointPosition) {
this.selectedPointPosition = selectedPointPosition;
}
public WptPt getOriginalPointToMove() {
return originalPointToMove;
}
public void setOriginalPointToMove(WptPt originalPointToMove) {
this.originalPointToMove = originalPointToMove;
}
public void setInSnapToRoadMode(boolean inSnapToRoadMode) {
this.inSnapToRoadMode = inSnapToRoadMode;
}
public NewGpxData getNewGpxData() {
return newGpxData;
}
public void setNewGpxData(NewGpxData newGpxData) {
this.newGpxData = newGpxData;
}
public void setProgressListener(SnapToRoadProgressListener progressListener) {
this.progressListener = progressListener;
}
public ApplicationMode getSnapToRoadAppMode() {
return snapToRoadAppMode;
}
public void setSnapToRoadAppMode(ApplicationMode snapToRoadAppMode) {
this.snapToRoadAppMode = snapToRoadAppMode;
}
public Map<Pair<WptPt, WptPt>, List<WptPt>> getSnappedPoints() {
return snappedToRoadPoints;
}
public TrkSegment getBeforeTrkSegmentLine() {
if (beforeCacheForSnap != null) {
return beforeCacheForSnap;
}
return before;
}
public TrkSegment getAfterTrkSegmentLine() {
if (afterCacheForSnap != null) {
return afterCacheForSnap;
}
return after;
}
public List<WptPt> getPoints() {
return getBeforePoints();
}
public List<WptPt> getBeforePoints() {
return before.points;
}
public List<WptPt> getAfterPoints() {
return after.points;
}
public int getPointsCount() {
return before.points.size();
}
public void splitSegments(int position) {
List<WptPt> points = new ArrayList<>();
points.addAll(before.points);
points.addAll(after.points);
before.points.clear();
after.points.clear();
before.points.addAll(points.subList(0, position));
after.points.addAll(points.subList(position, points.size()));
updateCacheForSnapIfNeeded(true);
}
public void addPoint(WptPt pt) {
before.points.add(pt);
updateCacheForSnapIfNeeded(false);
}
public void addPoint(int position, WptPt pt) {
before.points.add(position, pt);
updateCacheForSnapIfNeeded(false);
}
public void addPoints(List<WptPt> points) {
before.points.addAll(points);
updateCacheForSnapIfNeeded(false);
}
public WptPt removePoint(int position) {
WptPt pt = before.points.remove(position);
updateCacheForSnapIfNeeded(false);
return pt;
}
public void clearSegments() {
before.points.clear();
after.points.clear();
beforeCacheForSnap = null;
afterCacheForSnap = null;
}
void scheduleRouteCalculateIfNotEmpty() {
if (application == null || (before.points.size() < 1 && after.points.size() < 1)) {
return;
}
snapToRoadPairsToCalculate.clear();
findPointsToCalculate(Arrays.asList(before.points, after.points));
RoutingHelper routingHelper = application.getRoutingHelper();
if (!snapToRoadPairsToCalculate.isEmpty() && progressListener != null && !routingHelper.isRouteBeingCalculated()) {
routingHelper.startRouteCalculationThread(getParams(), true, true);
application.runInUIThread(new Runnable() {
@Override
public void run() {
progressListener.showProgressBar();
}
});
}
}
private void findPointsToCalculate(List<List<WptPt>> pointsList) {
for (List<WptPt> points : pointsList) {
for (int i = 0; i < points.size() - 1; i++) {
Pair<WptPt, WptPt> pair = new Pair<>(points.get(i), points.get(i + 1));
if (snappedToRoadPoints.get(pair) == null) {
snapToRoadPairsToCalculate.add(pair);
}
}
}
}
private void recreateCacheForSnap(TrkSegment cache, TrkSegment original) {
if (original.points.size() > 1) {
for (int i = 0; i < original.points.size() - 1; i++) {
Pair<WptPt, WptPt> pair = new Pair<>(original.points.get(i), original.points.get(i + 1));
List<WptPt> pts = snappedToRoadPoints.get(pair);
if (pts != null) {
cache.points.addAll(pts);
} else {
if (inSnapToRoadMode) {
scheduleRouteCalculateIfNotEmpty();
}
cache.points.addAll(Arrays.asList(pair.first, pair.second));
}
}
} else {
cache.points.addAll(original.points);
}
}
private void updateCacheForSnapIfNeeded(boolean both) {
if (inSnapToRoadMode) {
recreateCacheForSnap(beforeCacheForSnap = new TrkSegment(), before);
if (both) {
recreateCacheForSnap(afterCacheForSnap = new TrkSegment(), after);
}
}
}
void cancelSnapToRoad() {
progressListener.hideProgressBar();
snapToRoadPairsToCalculate.clear();
if (calculationProgress != null) {
calculationProgress.isCancelled = true;
}
}
private RouteCalculationParams getParams() {
OsmandSettings settings = application.getSettings();
final Pair<WptPt, WptPt> currentPair = snapToRoadPairsToCalculate.poll();
Location start = new Location("");
start.setLatitude(currentPair.first.getLatitude());
start.setLongitude(currentPair.first.getLongitude());
LatLon end = new LatLon(currentPair.second.getLatitude(), currentPair.second.getLongitude());
final RouteCalculationParams params = new RouteCalculationParams();
params.start = start;
params.end = end;
params.leftSide = settings.DRIVING_REGION.get().leftHandDriving;
params.fast = settings.FAST_ROUTE_MODE.getModeValue(snapToRoadAppMode);
params.type = settings.ROUTER_SERVICE.getModeValue(snapToRoadAppMode);
params.mode = snapToRoadAppMode;
params.ctx = application;
params.calculationProgress = calculationProgress = new RouteCalculationProgress();
params.calculationProgressCallback = new RoutingHelper.RouteCalculationProgressCallback() {
@Override
public void updateProgress(int progress) {
progressListener.updateProgress(progress);
}
@Override
public void requestPrivateAccessRouting() {
}
@Override
public void finish() {
progressListener.refreshMap();
}
};
params.resultListener = new RouteCalculationParams.RouteCalculationResultListener() {
@Override
public void onRouteCalculated(List<Location> locations) {
ArrayList<WptPt> pts = new ArrayList<>(locations.size());
for (Location loc : locations) {
WptPt pt = new WptPt();
pt.lat = loc.getLatitude();
pt.lon = loc.getLongitude();
pts.add(pt);
}
snappedToRoadPoints.put(currentPair, pts);
updateCacheForSnapIfNeeded(true);
progressListener.refreshMap();
if (!snapToRoadPairsToCalculate.isEmpty()) {
application.getRoutingHelper().startRouteCalculationThread(getParams(), true, true);
} else {
application.runInUIThread(new Runnable() {
@Override
public void run() {
progressListener.hideProgressBar();
}
});
}
}
};
return params;
}
interface SnapToRoadProgressListener {
void showProgressBar();
void updateProgress(int progress);
void hideProgressBar();
void refreshMap();
}
}

View file

@ -7,54 +7,49 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PointF; import android.graphics.PointF;
import net.osmand.AndroidUtils;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.QuadPoint; import net.osmand.data.QuadPoint;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.views.ContextMenuLayer; import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.Renderable;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.util.LinkedList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import gnu.trove.list.array.TIntArrayList; import gnu.trove.list.array.TIntArrayList;
public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider { public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
private static final int POINTS_TO_DRAW = 50;
private OsmandMapTileView view; private OsmandMapTileView view;
private boolean inMeasurementMode; private boolean inMeasurementMode;
private boolean inMovePointMode;
private boolean inAddPointAfterMode;
private boolean inAddPointBeforeMode;
private List<WptPt> measurementPoints = new LinkedList<>();
private List<WptPt> snappedToRoadPoints = new LinkedList<>();
private Bitmap centerIconDay; private Bitmap centerIconDay;
private Bitmap centerIconNight; private Bitmap centerIconNight;
private Bitmap pointIcon; private Bitmap pointIcon;
private Bitmap applyingPointIcon; private Bitmap applyingPointIcon;
private Paint bitmapPaint; private Paint bitmapPaint;
private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine"); private final RenderingLineAttributes lineAttrs = new RenderingLineAttributes("measureDistanceLine");
private final Path path = new Path();
private int marginPointIconX; private int marginPointIconX;
private int marginPointIconY; private int marginPointIconY;
private int marginApplyingPointIconX; private int marginApplyingPointIconX;
private int marginApplyingPointIconY; private int marginApplyingPointIconY;
private final TIntArrayList tx = new TIntArrayList(); private Path path = new Path();
private final TIntArrayList ty = new TIntArrayList(); private TIntArrayList tx = new TIntArrayList();
private TIntArrayList ty = new TIntArrayList();
private OnMeasureDistanceToCenter measureDistanceToCenterListener; private OnMeasureDistanceToCenter measureDistanceToCenterListener;
private OnSingleTapListener singleTapListener; private OnSingleTapListener singleTapListener;
private OnEnterMovePointModeListener enterMovePointModeListener; private OnEnterMovePointModeListener enterMovePointModeListener;
private int selectedPointPos = -1;
private WptPt selectedCachedPoint;
private LatLon pressedPointLatLon; private LatLon pressedPointLatLon;
private boolean overlapped; private boolean overlapped;
private int pointsToDraw = 50; private MeasurementEditingContext editingCtx;
@Override @Override
public void initLayer(OsmandMapTileView view) { public void initLayer(OsmandMapTileView view) {
@ -81,6 +76,10 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
this.singleTapListener = listener; this.singleTapListener = listener;
} }
void setEditingCtx(MeasurementEditingContext editingCtx) {
this.editingCtx = editingCtx;
}
void setOnEnterMovePointModeListener(OnEnterMovePointModeListener listener) { void setOnEnterMovePointModeListener(OnEnterMovePointModeListener listener) {
this.enterMovePointModeListener = listener; this.enterMovePointModeListener = listener;
} }
@ -89,64 +88,25 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
this.measureDistanceToCenterListener = listener; this.measureDistanceToCenterListener = listener;
} }
void setSelectedPointPos(int pos) { public MeasurementEditingContext getEditingCtx() {
selectedPointPos = pos; return editingCtx;
}
void setSelectedCachedPoint(WptPt selectedCachedPoint) {
this.selectedCachedPoint = selectedCachedPoint;
}
WptPt getSelectedCachedPoint() {
return selectedCachedPoint;
}
int getSelectedPointPos() {
return selectedPointPos;
} }
public boolean isInMeasurementMode() { public boolean isInMeasurementMode() {
return inMeasurementMode; return inMeasurementMode;
} }
boolean isInMovePointMode() {
return inMovePointMode;
}
boolean isInAddPointAfterMode() {
return inAddPointAfterMode;
}
boolean isInAddPointBeforeMode() {
return inAddPointBeforeMode;
}
void setInMeasurementMode(boolean inMeasurementMode) { void setInMeasurementMode(boolean inMeasurementMode) {
this.inMeasurementMode = inMeasurementMode; this.inMeasurementMode = inMeasurementMode;
} }
public List<WptPt> getMeasurementPoints() {
return measurementPoints;
}
void setMeasurementPoints(List<WptPt> points) {
measurementPoints = points;
}
public List<WptPt> getSnappedToRoadPoints() {
return snappedToRoadPoints;
}
public void setSnappedToRoadPoints(List<WptPt> snappedToRoadPoints) {
this.snappedToRoadPoints = snappedToRoadPoints;
}
String getDistanceSt() { String getDistanceSt() {
float dist = 0; float dist = 0;
if (measurementPoints.size() > 0) { List<WptPt> points = editingCtx.getPoints();
for (int i = 1; i < measurementPoints.size(); i++) { if (points.size() > 0) {
dist += MapUtils.getDistance(measurementPoints.get(i - 1).lat, measurementPoints.get(i - 1).lon, for (int i = 1; i < points.size(); i++) {
measurementPoints.get(i).lat, measurementPoints.get(i).lon); dist += MapUtils.getDistance(points.get(i - 1).lat, points.get(i - 1).lon,
points.get(i).lat, points.get(i).lon);
} }
} }
return OsmAndFormatter.getFormattedDistance(dist, view.getApplication()); return OsmAndFormatter.getFormattedDistance(dist, view.getApplication());
@ -154,15 +114,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
@Override @Override
public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
if (singleTapListener != null) { if (inMeasurementMode && editingCtx.getSelectedPointPosition() == -1) {
if (inMeasurementMode && !inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) { if (!overlapped) {
if (overlapped) { selectPoint(point.x, point.y, true);
clearSelection(); }
} else { if (editingCtx.getSelectedPointPosition() == -1) {
selectPoint(point.x, point.y, true); pressedPointLatLon = tileBox.getLatLonFromPixel(point.x, point.y);
} if (singleTapListener != null) {
if (selectedPointPos == -1) {
pressedPointLatLon = tileBox.getLatLonFromPixel(point.x, point.y);
singleTapListener.onAddPoint(); singleTapListener.onAddPoint();
} }
} }
@ -170,19 +128,14 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
return false; return false;
} }
void clearSelection() {
selectedPointPos = -1;
selectedCachedPoint = null;
}
@Override @Override
public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) { public boolean onLongPressEvent(PointF point, RotatedTileBox tileBox) {
if (inMeasurementMode) { if (inMeasurementMode) {
if (!overlapped && !inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode && measurementPoints.size() > 0) { if (!overlapped && getEditingCtx().getSelectedPointPosition() == -1 && editingCtx.getPointsCount() > 0) {
selectPoint(point.x, point.y, false); selectPoint(point.x, point.y, false);
if (selectedCachedPoint != null && selectedPointPos != -1) { if (editingCtx.getSelectedPointPosition() != -1) {
enterMovingPointMode(); enterMovingPointMode();
if (inMeasurementMode && inMovePointMode && enterMovePointModeListener != null) { if (enterMovePointModeListener != null) {
enterMovePointModeListener.onEnterMovePointMode(); enterMovePointModeListener.onEnterMovePointMode();
} }
} }
@ -192,48 +145,53 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
} }
void enterMovingPointMode() { void enterMovingPointMode() {
inMovePointMode = true; moveMapToPoint(editingCtx.getSelectedPointPosition());
moveMapToPoint(selectedPointPos); WptPt pt = editingCtx.removePoint(editingCtx.getSelectedPointPosition());
} editingCtx.setOriginalPointToMove(pt);
editingCtx.splitSegments(editingCtx.getSelectedPointPosition());
void enterAddingPointAfterMode() {
inAddPointAfterMode = true;
moveMapToPoint(selectedPointPos);
}
void enterAddingPointBeforeMode() {
inAddPointBeforeMode = true;
moveMapToPoint(selectedPointPos);
} }
private void selectPoint(double x, double y, boolean singleTap) { private void selectPoint(double x, double y, boolean singleTap) {
clearSelection();
RotatedTileBox tb = view.getCurrentRotatedTileBox(); RotatedTileBox tb = view.getCurrentRotatedTileBox();
double lowestDistance = view.getResources().getDimension(R.dimen.measurement_tool_select_radius); double lowestDistance = view.getResources().getDimension(R.dimen.measurement_tool_select_radius);
for (int i = 0; i < measurementPoints.size(); i++) { for (int i = 0; i < editingCtx.getPointsCount(); i++) {
WptPt pt = measurementPoints.get(i); WptPt pt = editingCtx.getPoints().get(i);
if (tb.containsLatLon(pt.getLatitude(), pt.getLongitude())) { if (tb.containsLatLon(pt.getLatitude(), pt.getLongitude())) {
double xDiff = tb.getPixXFromLonNoRot(pt.getLongitude()) - x; double xDiff = tb.getPixXFromLonNoRot(pt.getLongitude()) - x;
double yDiff = tb.getPixYFromLatNoRot(pt.getLatitude()) - y; double yDiff = tb.getPixYFromLatNoRot(pt.getLatitude()) - y;
double distToPoint = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)); double distToPoint = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2));
if (distToPoint < lowestDistance) { if (distToPoint < lowestDistance) {
lowestDistance = distToPoint; lowestDistance = distToPoint;
selectedCachedPoint = new WptPt(pt); editingCtx.setSelectedPointPosition(i);
selectedPointPos = i;
} }
} }
} }
if (singleTap && singleTapListener != null) { if (singleTap && singleTapListener != null) {
singleTapListener.onSelectPoint(selectedPointPos, selectedCachedPoint); singleTapListener.onSelectPoint(editingCtx.getSelectedPointPosition());
} }
} }
void selectPoint(int position) { void selectPoint(int position) {
clearSelection(); editingCtx.setSelectedPointPosition(position);
selectedCachedPoint = new WptPt(measurementPoints.get(position));
selectedPointPos = position;
if (singleTapListener != null) { if (singleTapListener != null) {
singleTapListener.onSelectPoint(selectedPointPos, selectedCachedPoint); singleTapListener.onSelectPoint(editingCtx.getSelectedPointPosition());
}
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
if (inMeasurementMode) {
lineAttrs.updatePaints(view, settings, tb);
TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
before.renders.clear();
before.renders.add(new Renderable.StandardTrack(new ArrayList<>(before.points), 17.2));
before.drawRenderers(view.getZoom(), lineAttrs.paint, canvas, tb);
TrkSegment after = editingCtx.getAfterTrkSegmentLine();
after.renders.clear();
after.renders.add(new Renderable.StandardTrack(new ArrayList<>(after.points), 17.2));
after.drawRenderers(view.getZoom(), lineAttrs.paint, canvas, tb);
} }
} }
@ -241,12 +199,13 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) { public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
if (inMeasurementMode) { if (inMeasurementMode) {
lineAttrs.updatePaints(view, settings, tb); lineAttrs.updatePaints(view, settings, tb);
if (!inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) {
if (editingCtx.getSelectedPointPosition() == -1) {
drawCenterIcon(canvas, tb, tb.getCenterPixelPoint(), settings.isNightMode()); drawCenterIcon(canvas, tb, tb.getCenterPixelPoint(), settings.isNightMode());
if (measureDistanceToCenterListener != null) { if (measureDistanceToCenterListener != null) {
float distance = 0; float distance = 0;
if (measurementPoints.size() > 0) { if (editingCtx.getPointsCount() > 0) {
WptPt lastPoint = measurementPoints.get(measurementPoints.size() - 1); WptPt lastPoint = editingCtx.getPoints().get(editingCtx.getPointsCount() - 1);
LatLon centerLatLon = tb.getCenterLatLon(); LatLon centerLatLon = tb.getCenterLatLon();
distance = (float) MapUtils.getDistance(lastPoint.lat, lastPoint.lon, centerLatLon.getLatitude(), centerLatLon.getLongitude()); distance = (float) MapUtils.getDistance(lastPoint.lat, lastPoint.lon, centerLatLon.getLatitude(), centerLatLon.getLongitude());
} }
@ -254,119 +213,101 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
} }
} }
List<WptPt> drawPoints; TrkSegment before = editingCtx.getBeforeTrkSegmentLine();
if (snappedToRoadPoints.size() > 0) { TrkSegment after = editingCtx.getAfterTrkSegmentLine();
drawPoints = snappedToRoadPoints;
} else { if (before.points.size() > 0 || after.points.size() > 0) {
drawPoints = measurementPoints;
}
if (drawPoints.size() > 0) {
path.reset(); path.reset();
tx.reset(); tx.reset();
ty.reset(); ty.reset();
for (int i = 0; i < drawPoints.size(); i++) { if (before.points.size() > 0) {
WptPt pt = drawPoints.get(i); WptPt pt = before.points.get(before.points.size() - 1);
int locX; int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY; int locY = tb.getPixYFromLatNoRot(pt.lat);
if (selectedPointPos == i && (inMovePointMode || inAddPointAfterMode || inAddPointBeforeMode)) { path.moveTo(locX, locY);
locX = tb.getCenterPixelX(); tx.add(locX);
locY = tb.getCenterPixelY(); ty.add(locY);
} else {
locX = tb.getPixXFromLonNoRot(pt.lon);
locY = tb.getPixYFromLatNoRot(pt.lat);
}
if (inAddPointAfterMode) {
int previousLocX = tb.getPixXFromLonNoRot(pt.lon);
int previousLocY = tb.getPixYFromLatNoRot(pt.lat);
if (i == 0) {
path.moveTo(previousLocX, previousLocY);
} else {
path.lineTo(previousLocX, previousLocY);
}
tx.add(previousLocX);
ty.add(previousLocY);
path.lineTo(locX, locY);
tx.add(locX);
ty.add(locY);
} else if (inAddPointBeforeMode) {
if (i == 0) {
path.moveTo(locX, locY);
} else {
path.lineTo(locX, locY);
}
tx.add(locX);
ty.add(locY);
int followingLocX = tb.getPixXFromLonNoRot(pt.lon);
int followingLocY = tb.getPixYFromLatNoRot(pt.lat);
path.lineTo(followingLocX, followingLocY);
tx.add(followingLocX);
ty.add(followingLocY);
} else {
if (i == 0) {
path.moveTo(locX, locY);
} else {
path.lineTo(locX, locY);
}
tx.add(locX);
ty.add(locY);
}
}
if (!inMovePointMode && !inAddPointAfterMode && !inAddPointBeforeMode) {
path.lineTo(tb.getCenterPixelX(), tb.getCenterPixelY()); path.lineTo(tb.getCenterPixelX(), tb.getCenterPixelY());
tx.add(tb.getCenterPixelX()); tx.add(tb.getCenterPixelX());
ty.add(tb.getCenterPixelY()); ty.add(tb.getCenterPixelY());
} }
if (after.points.size() > 0) {
if (before.points.size() == 0) {
path.moveTo(tb.getCenterPixelX(), tb.getCenterPixelY());
tx.add(tb.getCenterPixelX());
ty.add(tb.getCenterPixelY());
}
WptPt pt = after.points.get(0);
int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat);
path.lineTo(locX, locY);
tx.add(locX);
ty.add(locY);
}
calculatePath(tb, tx, ty, path); calculatePath(tb, tx, ty, path);
canvas.drawPath(path, lineAttrs.paint); canvas.drawPath(path, lineAttrs.paint);
}
overlapped = false; List<WptPt> points = new ArrayList<>();
int drawn = 0; points.addAll(editingCtx.getBeforePoints());
for (int i = 0; i < measurementPoints.size(); i++) { points.addAll(editingCtx.getAfterPoints());
WptPt pt = measurementPoints.get(i); overlapped = false;
int drawn = 0;
for (int i = 0; i < points.size(); i++) {
WptPt pt = points.get(i);
int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat);
if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
drawn++;
if (drawn > POINTS_TO_DRAW) {
overlapped = true;
break;
}
}
}
if (overlapped) {
WptPt pt = points.get(0);
int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat);
if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint);
}
pt = points.get(points.size() - 1);
locX = tb.getPixXFromLonNoRot(pt.lon);
locY = tb.getPixYFromLatNoRot(pt.lat);
if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint);
}
} else {
for (int i = 0; i < points.size(); i++) {
WptPt pt = points.get(i);
int locX = tb.getPixXFromLonNoRot(pt.lon); int locX = tb.getPixXFromLonNoRot(pt.lon);
int locY = tb.getPixYFromLatNoRot(pt.lat); int locY = tb.getPixYFromLatNoRot(pt.lat);
if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) { if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) {
if (!(inMovePointMode && i == selectedPointPos)) { canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint);
drawn++;
if (drawn > pointsToDraw) {
overlapped = true;
break;
}
}
} }
} }
if (!overlapped) { }
for (int i = 0; i < measurementPoints.size(); i++) {
WptPt pt = measurementPoints.get(i); if (editingCtx.getSelectedPointPosition() != -1) {
int locX = tb.getPixXFromLonNoRot(pt.lon); int locX = tb.getCenterPixelX();
int locY = tb.getPixYFromLatNoRot(pt.lat); int locY = tb.getCenterPixelY();
if (locX >= 0 && locX <= tb.getPixWidth() && locY >= 0 && locY <= tb.getPixHeight()) { canvas.drawBitmap(applyingPointIcon, locX - marginApplyingPointIconX, locY - marginApplyingPointIconY, bitmapPaint);
if (!(inMovePointMode && i == selectedPointPos)) {
canvas.drawBitmap(pointIcon, locX - marginPointIconX, locY - marginPointIconY, bitmapPaint);
}
}
}
}
if (inAddPointAfterMode || inAddPointBeforeMode || inMovePointMode) {
int locX = tb.getCenterPixelX();
int locY = tb.getCenterPixelY();
canvas.drawBitmap(applyingPointIcon, locX - marginApplyingPointIconX, locY - marginApplyingPointIconY, bitmapPaint);
}
} }
} }
} }
void exitMovePointMode() { void exitMovePointMode(boolean saveOriginalPoint) {
inMovePointMode = false; if (saveOriginalPoint) {
} WptPt pt = editingCtx.getOriginalPointToMove();
editingCtx.addPoint(pt);
void exitAddPointAfterMode() { }
inAddPointAfterMode = false; editingCtx.setOriginalPointToMove(null);
} editingCtx.setSelectedPointPosition(-1);
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
void exitAddPointBeforeMode() {
inAddPointBeforeMode = false;
} }
private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode) { private void drawCenterIcon(Canvas canvas, RotatedTileBox tb, QuadPoint center, boolean nightMode) {
@ -381,30 +322,32 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
canvas.rotate(tb.getRotate(), center.x, center.y); canvas.rotate(tb.getRotate(), center.x, center.y);
} }
public WptPt addCenterPoint(int position) { public WptPt addCenterPoint() {
RotatedTileBox tb = view.getCurrentRotatedTileBox(); RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon l = tb.getLatLonFromPixel(tb.getCenterPixelX(), tb.getCenterPixelY()); LatLon l = tb.getLatLonFromPixel(tb.getCenterPixelX(), tb.getCenterPixelY());
WptPt pt = new WptPt(); WptPt pt = new WptPt();
pt.lat = l.getLatitude(); pt.lat = l.getLatitude();
pt.lon = l.getLongitude(); pt.lon = l.getLongitude();
boolean allowed = measurementPoints.size() == 0 || !measurementPoints.get(measurementPoints.size() - 1).equals(pt); boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt);
if (allowed) { if (allowed) {
measurementPoints.add(position, pt); editingCtx.addPoint(pt);
return pt; return pt;
} }
return null; return null;
} }
public WptPt addPoint(int position) { public WptPt addPoint() {
if (pressedPointLatLon != null) { if (pressedPointLatLon != null) {
WptPt pt = new WptPt(); WptPt pt = new WptPt();
pt.lat = pressedPointLatLon.getLatitude(); double lat = pressedPointLatLon.getLatitude();
pt.lon = pressedPointLatLon.getLongitude(); double lon = pressedPointLatLon.getLongitude();
pt.lat = lat;
pt.lon = lon;
pressedPointLatLon = null; pressedPointLatLon = null;
boolean allowed = measurementPoints.size() == 0 || !measurementPoints.get(measurementPoints.size() - 1).equals(pt); boolean allowed = editingCtx.getPointsCount() == 0 || !editingCtx.getPoints().get(editingCtx.getPointsCount() - 1).equals(pt);
if (allowed) { if (allowed) {
measurementPoints.add(position, pt); editingCtx.addPoint(pt);
moveMapToPoint(position); moveMapToLatLon(lat, lon);
return pt; return pt;
} }
} }
@ -414,24 +357,28 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
WptPt getMovedPointToApply() { WptPt getMovedPointToApply() {
RotatedTileBox tb = view.getCurrentRotatedTileBox(); RotatedTileBox tb = view.getCurrentRotatedTileBox();
LatLon latLon = tb.getCenterLatLon(); LatLon latLon = tb.getCenterLatLon();
WptPt pt = measurementPoints.get(selectedPointPos); WptPt pt = new WptPt(editingCtx.getOriginalPointToMove());
pt.lat = latLon.getLatitude(); pt.lat = latLon.getLatitude();
pt.lon = latLon.getLongitude(); pt.lon = latLon.getLongitude();
return pt; return pt;
} }
public void moveMapToPoint(int pos) { private void moveMapToLatLon(double lat, double lon) {
if (measurementPoints.size() > 0) { view.getAnimatedDraggingThread().startMoving(lat, lon, view.getZoom(), true);
if (pos >= measurementPoints.size()) {
pos = measurementPoints.size() - 1;
} else if (pos < 0) {
pos = 0;
}
WptPt pt = measurementPoints.get(pos);
view.getAnimatedDraggingThread().startMoving(pt.getLatitude(), pt.getLongitude(), view.getZoom(), true);
}
} }
public void moveMapToPoint(int pos) {
if (editingCtx.getPointsCount() > 0) {
if (pos >= editingCtx.getPointsCount()) {
pos = editingCtx.getPointsCount() - 1;
} else if (pos < 0) {
pos = 0;
}
WptPt pt = editingCtx.getPoints().get(pos);
moveMapToLatLon(pt.getLatitude(), pt.getLongitude());
}
}
public void refreshMap() { public void refreshMap() {
view.refreshMap(); view.refreshMap();
} }
@ -480,7 +427,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
void onAddPoint(); void onAddPoint();
void onSelectPoint(int selectedPointPos, WptPt selectedCachedPoint); void onSelectPoint(int selectedPointPos);
} }
interface OnEnterMovePointModeListener { interface OnEnterMovePointModeListener {

View file

@ -23,9 +23,9 @@ import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.measurementtool.NewGpxData.ActionType;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.util.List; import java.util.List;
@ -37,16 +37,11 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
private SelectedPointFragmentListener listener; private SelectedPointFragmentListener listener;
private boolean nightMode; private boolean nightMode;
private boolean portrait; private boolean portrait;
private NewGpxData.ActionType actionType;
public void setListener(SelectedPointFragmentListener listener) { public void setListener(SelectedPointFragmentListener listener) {
this.listener = listener; this.listener = listener;
} }
public void setActionType(NewGpxData.ActionType actionType) {
this.actionType = actionType;
}
@Nullable @Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -108,19 +103,28 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() { mainView.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (listener != null) {
listener.onClearSelection();
}
dismiss(); dismiss();
} }
}); });
List<WptPt> points = measurementLayer.getMeasurementPoints(); List<WptPt> points = measurementLayer.getEditingCtx().getPoints();
int pos = measurementLayer.getSelectedPointPos(); int pos = measurementLayer.getEditingCtx().getSelectedPointPosition();
WptPt pt = points.get(pos); WptPt pt = points.get(pos);
String pointTitle = pt.name; String pointTitle = pt.name;
if (!TextUtils.isEmpty(pointTitle)) { if (!TextUtils.isEmpty(pointTitle)) {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(pointTitle); ((TextView) mainView.findViewById(R.id.selected_point_title)).setText(pointTitle);
} else { } else {
if (actionType == NewGpxData.ActionType.ADD_ROUTE_POINTS) { NewGpxData newGpxData = measurementLayer.getEditingCtx().getNewGpxData();
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.route_point) + " - " + (pos + 1)); if (newGpxData != null) {
ActionType actionType = measurementLayer.getEditingCtx().getNewGpxData().getActionType();
if (actionType == ActionType.ADD_ROUTE_POINTS) {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.route_point) + " - " + (pos + 1));
} else {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1));
}
} else { } else {
((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1)); ((TextView) mainView.findViewById(R.id.selected_point_title)).setText(mapActivity.getString(R.string.plugin_distance_point) + " - " + (pos + 1));
} }
@ -139,6 +143,19 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
((TextView) mainView.findViewById(R.id.selected_point_distance)).setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication())); ((TextView) mainView.findViewById(R.id.selected_point_distance)).setText(OsmAndFormatter.getFormattedDistance(dist, mapActivity.getMyApplication()));
} }
} }
NewGpxData newGpxData = measurementLayer.getEditingCtx().getNewGpxData();
if (newGpxData != null && newGpxData.getActionType() == ActionType.EDIT_SEGMENT) {
double elevation = pt.ele;
if (!Double.isNaN(elevation)) {
String eleStr = (mapActivity.getString(R.string.altitude)).substring(0, 1);
((TextView) mainView.findViewById(R.id.selected_point_ele)).setText(eleStr + ": " + OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication()));
}
float speed = (float) pt.speed;
if (speed != 0) {
String speedStr = (mapActivity.getString(R.string.map_widget_speed)).substring(0, 1);
((TextView) mainView.findViewById(R.id.selected_point_speed)).setText(speedStr + ": " + OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication()));
}
}
final int screenHeight = AndroidUtils.getScreenHeight(getActivity()); final int screenHeight = AndroidUtils.getScreenHeight(getActivity());
final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity()); final int statusBarHeight = AndroidUtils.getStatusBarHeight(getActivity());
@ -208,6 +225,7 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
if (listener != null) { if (listener != null) {
listener.onCloseMenu(); listener.onCloseMenu();
listener.onClearSelection();
} }
super.onCancel(dialog); super.onCancel(dialog);
} }
@ -223,5 +241,7 @@ public class SelectedPointBottomSheetDialogFragment extends BottomSheetDialogFra
void addPointBeforeOnClick(); void addPointBeforeOnClick();
void onCloseMenu(); void onCloseMenu();
void onClearSelection();
} }
} }

View file

@ -108,13 +108,15 @@ public class MeasurementToolAdapter extends RecyclerView.Adapter<MeasurementTool
if (actionType == NewGpxData.ActionType.EDIT_SEGMENT) { if (actionType == NewGpxData.ActionType.EDIT_SEGMENT) {
double elevation = pt.ele; double elevation = pt.ele;
if (!Double.isNaN(elevation)) { if (!Double.isNaN(elevation)) {
holder.elevation.setText(mapActivity.getString(R.string.measurement_tool_altitude, OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication()))); String eleStr = (mapActivity.getString(R.string.altitude)).substring(0, 1);
holder.elevation.setText(eleStr + ": " + OsmAndFormatter.getFormattedAlt(elevation, mapActivity.getMyApplication()));
} else { } else {
holder.elevation.setText(""); holder.elevation.setText("");
} }
float speed = (float) pt.speed; float speed = (float) pt.speed;
if (speed != 0) { if (speed != 0) {
holder.speed.setText(mapActivity.getString(R.string.measurement_tool_speed, OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication()))); String speedStr = (mapActivity.getString(R.string.map_widget_speed)).substring(0, 1);
holder.speed.setText(speedStr + ": " + OsmAndFormatter.getFormattedSpeed(speed, mapActivity.getMyApplication()));
} else { } else {
holder.speed.setText(""); holder.speed.setText("");
} }

View file

@ -9,24 +9,18 @@ public class AddPointCommand extends MeasurementModeCommand {
private WptPt point; private WptPt point;
private boolean center; private boolean center;
public AddPointCommand(MeasurementToolLayer measurementLayer, int position) {
this.measurementLayer = measurementLayer;
this.center = true;
this.position = position;
}
public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) { public AddPointCommand(MeasurementToolLayer measurementLayer, boolean center) {
this.measurementLayer = measurementLayer; this.measurementLayer = measurementLayer;
this.center = center; this.center = center;
position = measurementLayer.getMeasurementPoints().size(); position = measurementLayer.getEditingCtx().getPointsCount();
} }
@Override @Override
public boolean execute() { public boolean execute() {
if (center) { if (center) {
point = measurementLayer.addCenterPoint(position); point = measurementLayer.addCenterPoint();
} else { } else {
point = measurementLayer.addPoint(position); point = measurementLayer.addPoint();
} }
measurementLayer.refreshMap(); measurementLayer.refreshMap();
return point != null; return point != null;
@ -34,13 +28,13 @@ public class AddPointCommand extends MeasurementModeCommand {
@Override @Override
public void undo() { public void undo() {
measurementLayer.getMeasurementPoints().remove(position); measurementLayer.getEditingCtx().removePoint(position);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getMeasurementPoints().add(position, point); measurementLayer.getEditingCtx().addPoint(position, point);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
measurementLayer.moveMapToPoint(position); measurementLayer.moveMapToPoint(position);
} }

View file

@ -9,7 +9,6 @@ import java.util.List;
public class ClearPointsCommand extends MeasurementModeCommand { public class ClearPointsCommand extends MeasurementModeCommand {
private List<WptPt> points; private List<WptPt> points;
private List<WptPt> snappedToRoadPoints;
public ClearPointsCommand(MeasurementToolLayer measurementLayer) { public ClearPointsCommand(MeasurementToolLayer measurementLayer) {
this.measurementLayer = measurementLayer; this.measurementLayer = measurementLayer;
@ -17,27 +16,23 @@ public class ClearPointsCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
List<WptPt> pts = measurementLayer.getMeasurementPoints(); List<WptPt> pts = measurementLayer.getEditingCtx().getPoints();
List<WptPt> snappedPts = measurementLayer.getSnappedToRoadPoints();
points = new LinkedList<>(pts); points = new LinkedList<>(pts);
snappedToRoadPoints = new LinkedList<>(snappedPts);
pts.clear(); pts.clear();
snappedPts.clear(); measurementLayer.getEditingCtx().clearSegments();
measurementLayer.refreshMap(); measurementLayer.refreshMap();
return true; return true;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getMeasurementPoints().addAll(points); measurementLayer.getEditingCtx().addPoints(points);
measurementLayer.getSnappedToRoadPoints().addAll(snappedToRoadPoints);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getMeasurementPoints().clear(); measurementLayer.getEditingCtx().clearSegments();
measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }

View file

@ -23,15 +23,15 @@ public class MovePointCommand extends MeasurementModeCommand {
@Override @Override
public void undo() { public void undo() {
measurementLayer.getMeasurementPoints().remove(position); measurementLayer.getEditingCtx().removePoint(position);
measurementLayer.getMeasurementPoints().add(position, oldPoint); measurementLayer.getEditingCtx().addPoint(position, oldPoint);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getMeasurementPoints().remove(position); measurementLayer.getEditingCtx().removePoint(position);
measurementLayer.getMeasurementPoints().add(position, newPoint); measurementLayer.getEditingCtx().addPoint(position, newPoint);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }

View file

@ -15,21 +15,21 @@ public class RemovePointCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
point = measurementLayer.getMeasurementPoints().remove(position); point = measurementLayer.getEditingCtx().removePoint(position);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
return true; return true;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getMeasurementPoints().add(position, point); measurementLayer.getEditingCtx().addPoint(position, point);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
measurementLayer.moveMapToPoint(position); measurementLayer.moveMapToPoint(position);
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getMeasurementPoints().remove(position); measurementLayer.getEditingCtx().removePoint(position);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }

View file

@ -31,7 +31,7 @@ public class ReorderPointCommand extends MeasurementModeCommand {
} }
private void swap() { private void swap() {
Collections.swap(measurementLayer.getMeasurementPoints(), from, to); Collections.swap(measurementLayer.getEditingCtx().getPoints(), from, to);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }

View file

@ -16,21 +16,21 @@ public class SnapToRoadCommand extends MeasurementModeCommand {
@Override @Override
public boolean execute() { public boolean execute() {
measurementLayer.getSnappedToRoadPoints().clear(); // measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints); // measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints);
measurementLayer.refreshMap(); // measurementLayer.refreshMap();
return true; return true;
} }
@Override @Override
public void undo() { public void undo() {
measurementLayer.getSnappedToRoadPoints().clear(); // measurementLayer.getSnappedToRoadPoints().clear();
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }
@Override @Override
public void redo() { public void redo() {
measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints); // measurementLayer.getSnappedToRoadPoints().addAll(snappedPoints);
measurementLayer.refreshMap(); measurementLayer.refreshMap();
} }

View file

@ -6,8 +6,9 @@ import net.osmand.plus.ApplicationMode;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import net.osmand.plus.routing.RouteProvider.GPXRouteParams;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.SnapToRoadParams; import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutingContext;
import java.util.List; import java.util.List;
@ -19,13 +20,20 @@ public class RouteCalculationParams {
public OsmandApplication ctx; public OsmandApplication ctx;
public RoutingContext cachedRoutingContext;
public ApplicationMode mode; public ApplicationMode mode;
public RouteService type; public RouteService type;
public GPXRouteParams gpxRoute; public GPXRouteParams gpxRoute;
public SnapToRoadParams snapToRoadParams;
public RouteCalculationResult previousToRecalculate; public RouteCalculationResult previousToRecalculate;
public boolean onlyStartPointChanged; public boolean onlyStartPointChanged;
public boolean fast; public boolean fast;
public boolean leftSide; public boolean leftSide;
public boolean inSnapToRoadMode;
public RouteCalculationProgress calculationProgress; public RouteCalculationProgress calculationProgress;
public RouteCalculationProgressCallback calculationProgressCallback;
public RouteCalculationResultListener resultListener;
public interface RouteCalculationResultListener {
void onRouteCalculated(List<Location> locations);
}
} }

View file

@ -1,26 +1,9 @@
package net.osmand.plus.routing; package net.osmand.plus.routing;
import java.io.BufferedReader; import android.content.Context;
import java.io.ByteArrayInputStream; import android.os.Build;
import java.io.FileNotFoundException; import android.os.Bundle;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
@ -44,13 +27,11 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.SettingsNavigationActivity; import net.osmand.plus.activities.SettingsNavigationActivity;
import net.osmand.plus.render.NativeOsmandLibrary; import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback;
import net.osmand.router.GeneralRouter; import net.osmand.router.GeneralRouter;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RoutingParameter; import net.osmand.router.GeneralRouter.RoutingParameter;
import net.osmand.router.GeneralRouter.RoutingParameterType; import net.osmand.router.GeneralRouter.RoutingParameterType;
import net.osmand.router.PrecalculatedRouteDirection; import net.osmand.router.PrecalculatedRouteDirection;
import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutePlannerFrontEnd; import net.osmand.router.RoutePlannerFrontEnd;
import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode; import net.osmand.router.RoutePlannerFrontEnd.RouteCalculationMode;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
@ -59,22 +40,36 @@ import net.osmand.router.RoutingConfiguration.Builder;
import net.osmand.router.RoutingContext; import net.osmand.router.RoutingContext;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import net.osmand.util.GeoPolylineParserUtil; import net.osmand.util.GeoPolylineParserUtil;
import net.osmand.util.MapUtils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import android.content.Context; import java.io.BufferedReader;
import android.os.Build; import java.io.ByteArrayInputStream;
import android.os.Bundle; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import btools.routingapp.IBRouterService; import btools.routingapp.IBRouterService;
@ -284,19 +279,6 @@ public class RouteProvider {
} }
} }
public static class SnapToRoadParams {
public ApplicationMode applicationMode;
public RouteCalculationProgress calculationProgress;
public RouteCalculationProgressCallback calculationProgressCallback;
public SnapToRoadListener listener;
public List<Location> points;
public interface SnapToRoadListener {
void onSnapToRoadDone();
}
}
private static Location createLocation(WptPt pt){ private static Location createLocation(WptPt pt){
Location loc = new Location("OsmandRouteProvider"); Location loc = new Location("OsmandRouteProvider");
loc.setLatitude(pt.lat); loc.setLatitude(pt.lat);
@ -769,7 +751,7 @@ public class RouteProvider {
paramsR.put(key, vl); paramsR.put(key, vl);
} }
} }
if (params.snapToRoadParams != null) { if (params.inSnapToRoadMode) {
paramsR.put(GeneralRouter.ALLOW_PRIVATE, "true"); paramsR.put(GeneralRouter.ALLOW_PRIVATE, "true");
} }
float mb = (1 << 20); float mb = (1 << 20);

View file

@ -19,7 +19,6 @@ import net.osmand.plus.notifications.OsmandNotification.NotificationType;
import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo;
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder; import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
import net.osmand.plus.routing.RouteProvider.RouteService; import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.routing.RouteProvider.SnapToRoadParams;
import net.osmand.router.RouteCalculationProgress; import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RouteSegmentResult; import net.osmand.router.RouteSegmentResult;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
@ -388,7 +387,7 @@ public class RoutingHelper {
if (calculateRoute) { if (calculateRoute) {
recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute, recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute,
previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged, null); previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged);
} else { } else {
Thread job = currentRunningJob; Thread job = currentRunningJob;
if(job instanceof RouteRecalculationThread) { if(job instanceof RouteRecalculationThread) {
@ -871,11 +870,8 @@ public class RoutingHelper {
synchronized (RoutingHelper.this) { synchronized (RoutingHelper.this) {
if (res.isCalculated()) { if (res.isCalculated()) {
route = res; route = res;
if (params.snapToRoadParams != null) { if (params.resultListener != null) {
params.snapToRoadParams.points = res.getRouteLocations(); params.resultListener.onRouteCalculated(res.getRouteLocations());
if (params.snapToRoadParams.listener != null) {
params.snapToRoadParams.listener.onSnapToRoadDone();
}
} }
} else { } else {
evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899 evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899
@ -911,18 +907,13 @@ public class RoutingHelper {
} }
} }
public void recalculateSnapToRoad(final Location start, final LatLon end, final List<LatLon> intermediates, SnapToRoadParams params) {
recalculateRouteInBackground(start, end, intermediates, null, route, true, false, params);
}
public void recalculateRouteDueToSettingsChange() { public void recalculateRouteDueToSettingsChange() {
clearCurrentRoute(finalLocation, intermediatePoints); clearCurrentRoute(finalLocation, intermediatePoints);
recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false, null); recalculateRouteInBackground(lastFixedLocation, finalLocation, intermediatePoints, currentGPXRoute, route, true, false);
} }
private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates, private void recalculateRouteInBackground(final Location start, final LatLon end, final List<LatLon> intermediates,
final GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged, final GPXRouteParamsBuilder gpxRoute, final RouteCalculationResult previousRoute, boolean paramsChanged, boolean onlyStartPointChanged){
final SnapToRoadParams snapToRoadParams){
if (start == null || end == null) { if (start == null || end == null) {
return; return;
} }
@ -944,42 +935,39 @@ public class RoutingHelper {
recalculateCountInInterval = 0; recalculateCountInInterval = 0;
} }
params.leftSide = settings.DRIVING_REGION.get().leftHandDriving; params.leftSide = settings.DRIVING_REGION.get().leftHandDriving;
ApplicationMode mode;
if (snapToRoadParams != null && snapToRoadParams.applicationMode != null) {
params.snapToRoadParams = snapToRoadParams;
mode = snapToRoadParams.applicationMode;
} else {
mode = this.mode;
}
params.fast = settings.FAST_ROUTE_MODE.getModeValue(mode); params.fast = settings.FAST_ROUTE_MODE.getModeValue(mode);
params.type = settings.ROUTER_SERVICE.getModeValue(mode); params.type = settings.ROUTER_SERVICE.getModeValue(mode);
params.mode = mode; params.mode = mode;
params.ctx = app; params.ctx = app;
boolean updateProgress = false;
if (params.type == RouteService.OSMAND) { if (params.type == RouteService.OSMAND) {
if (snapToRoadParams != null && snapToRoadParams.calculationProgress != null) { params.calculationProgress = new RouteCalculationProgress();
params.calculationProgress = snapToRoadParams.calculationProgress; updateProgress = true;
} else {
params.calculationProgress = new RouteCalculationProgress();
}
updateProgress(params);
} }
synchronized (this) { startRouteCalculationThread(params, paramsChanged, updateProgress);
final Thread prevRunningJob = currentRunningJob; }
RouteRecalculationThread newThread = new RouteRecalculationThread( }
"Calculating route", params, paramsChanged); //$NON-NLS-1$
currentRunningJob = newThread; public void startRouteCalculationThread(RouteCalculationParams params, boolean paramsChanged, boolean updateProgress) {
if (prevRunningJob != null) { if (updateProgress) {
newThread.setWaitPrevJob(prevRunningJob); updateProgress(params);
} }
currentRunningJob.start(); synchronized (this) {
final Thread prevRunningJob = currentRunningJob;
RouteRecalculationThread newThread = new RouteRecalculationThread(
"Calculating route", params, paramsChanged); //$NON-NLS-1$
currentRunningJob = newThread;
if (prevRunningJob != null) {
newThread.setWaitPrevJob(prevRunningJob);
} }
currentRunningJob.start();
} }
} }
private void updateProgress(final RouteCalculationParams params) { private void updateProgress(final RouteCalculationParams params) {
final RouteCalculationProgressCallback progressRoute; final RouteCalculationProgressCallback progressRoute;
if (params.snapToRoadParams != null) { if (params.calculationProgressCallback != null) {
progressRoute = params.snapToRoadParams.calculationProgressCallback; progressRoute = params.calculationProgressCallback;
} else { } else {
progressRoute = this.progressRoute; progressRoute = this.progressRoute;
} }