Added split / join segments feature to plan route
This commit is contained in:
parent
c091fb6cc0
commit
53de5bf80e
8 changed files with 341 additions and 45 deletions
|
@ -11,6 +11,10 @@
|
||||||
Thx - Hardy
|
Thx - Hardy
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
<string name="plan_route_add_new_segment">Add new segment</string>
|
||||||
|
<string name="plan_route_split_after">Split after</string>
|
||||||
|
<string name="plan_route_split_before">Split before</string>
|
||||||
|
<string name="plan_route_join_segments">Join segments</string>
|
||||||
<string name="app_mode_light_aircraft">Light aircraft</string>
|
<string name="app_mode_light_aircraft">Light aircraft</string>
|
||||||
<string name="elevation_data">You can use Elevation data for consideration of Ascent / Descent for your trip</string>
|
<string name="elevation_data">You can use Elevation data for consideration of Ascent / Descent for your trip</string>
|
||||||
<string name="ltr_or_rtl_combine_via_star">%1$s * %2$s</string>
|
<string name="ltr_or_rtl_combine_via_star">%1$s * %2$s</string>
|
||||||
|
|
|
@ -296,31 +296,6 @@ public class MeasurementEditingContext {
|
||||||
return !newData && hasDefaultPointsOnly && getPoints().size() > 2;
|
return !newData && hasDefaultPointsOnly && getPoints().size() > 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSelectionNeedApproximation() {
|
|
||||||
boolean hasDefaultPointsOnly = false;
|
|
||||||
boolean newData = isNewData();
|
|
||||||
if (!newData && selectedPointPosition != -1) {
|
|
||||||
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
|
||||||
List<TrkSegment> segments = getBeforeSegments();
|
|
||||||
List<WptPt> points = null;
|
|
||||||
for (TrkSegment segment : segments) {
|
|
||||||
if (segment.points.contains(selectedPoint)) {
|
|
||||||
points = segment.points;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!Algorithms.isEmpty(points)) {
|
|
||||||
hasDefaultPointsOnly = true;
|
|
||||||
for (WptPt point : points) {
|
|
||||||
if (point.hasProfile()) {
|
|
||||||
hasDefaultPointsOnly = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !newData && hasDefaultPointsOnly && getPoints().size() > 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearSnappedToRoadPoints() {
|
public void clearSnappedToRoadPoints() {
|
||||||
roadSegmentData.clear();
|
roadSegmentData.clear();
|
||||||
}
|
}
|
||||||
|
@ -430,13 +405,19 @@ public class MeasurementEditingContext {
|
||||||
if (position > 0 && position <= points.size()) {
|
if (position > 0 && position <= points.size()) {
|
||||||
WptPt prevPt = points.get(position - 1);
|
WptPt prevPt = points.get(position - 1);
|
||||||
if (prevPt.isGap()) {
|
if (prevPt.isGap()) {
|
||||||
point.setGap();
|
if (position == points.size() && getAfterPoints().size() == 0) {
|
||||||
if (position > 1) {
|
if (appMode != MeasurementEditingContext.DEFAULT_APP_MODE) {
|
||||||
WptPt pt = points.get(position - 2);
|
point.setProfileType(appMode.getStringKey());
|
||||||
if (pt.hasProfile()) {
|
}
|
||||||
prevPt.setProfileType(pt.getProfileType());
|
} else {
|
||||||
} else {
|
point.setGap();
|
||||||
prevPt.removeProfileType();
|
if (position > 1) {
|
||||||
|
WptPt pt = points.get(position - 2);
|
||||||
|
if (pt.hasProfile()) {
|
||||||
|
prevPt.setProfileType(pt.getProfileType());
|
||||||
|
} else {
|
||||||
|
prevPt.removeProfileType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (prevPt.hasProfile()) {
|
} else if (prevPt.hasProfile()) {
|
||||||
|
@ -540,6 +521,45 @@ public class MeasurementEditingContext {
|
||||||
clearAfterSegments();
|
clearAfterSegments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void splitPoints(int selectedPointPosition, boolean after) {
|
||||||
|
int pointIndex = after ? selectedPointPosition : selectedPointPosition - 1;
|
||||||
|
if (pointIndex >= 0 && pointIndex < before.points.size()) {
|
||||||
|
WptPt point = before.points.get(pointIndex);
|
||||||
|
WptPt newPoint = new WptPt();
|
||||||
|
newPoint.lat = point.lat;
|
||||||
|
newPoint.lon = point.lon;
|
||||||
|
newPoint.copyExtensions(point);
|
||||||
|
newPoint.setGap();
|
||||||
|
before.points.remove(pointIndex);
|
||||||
|
before.points.add(pointIndex, newPoint);
|
||||||
|
updateSegmentsForSnap(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void joinPoints(int selectedPointPosition) {
|
||||||
|
WptPt gapPoint = null;
|
||||||
|
int gapIndex = -1;
|
||||||
|
if (isFirstPointSelected(selectedPointPosition, false)) {
|
||||||
|
if (selectedPointPosition - 1 >= 0) {
|
||||||
|
gapPoint = before.points.get(selectedPointPosition - 1);
|
||||||
|
gapIndex = selectedPointPosition - 1;
|
||||||
|
}
|
||||||
|
} else if (isLastPointSelected(selectedPointPosition, false)) {
|
||||||
|
gapPoint = before.points.get(selectedPointPosition);
|
||||||
|
gapIndex = selectedPointPosition;
|
||||||
|
}
|
||||||
|
if (gapPoint != null) {
|
||||||
|
WptPt newPoint = new WptPt();
|
||||||
|
newPoint.lat = gapPoint.lat;
|
||||||
|
newPoint.lon = gapPoint.lon;
|
||||||
|
newPoint.copyExtensions(gapPoint);
|
||||||
|
newPoint.removeProfileType();
|
||||||
|
before.points.remove(gapIndex);
|
||||||
|
before.points.add(gapIndex, newPoint);
|
||||||
|
updateSegmentsForSnap(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void clearSegments() {
|
public void clearSegments() {
|
||||||
clearBeforeSegments();
|
clearBeforeSegments();
|
||||||
clearAfterSegments();
|
clearAfterSegments();
|
||||||
|
@ -560,15 +580,43 @@ public class MeasurementEditingContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFirstPointSelected() {
|
public boolean canSplit(boolean after) {
|
||||||
return isBorderPointSelected(true);
|
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
||||||
|
List<TrkSegment> segments = getBeforeSegments();
|
||||||
|
for (TrkSegment segment : segments) {
|
||||||
|
int i = segment.points.indexOf(selectedPoint);
|
||||||
|
if (i != -1) {
|
||||||
|
return after ? i < segment.points.size() - 2 : i > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLastPointSelected() {
|
public boolean isFirstPointSelected(boolean outer) {
|
||||||
return isBorderPointSelected(false);
|
return isFirstPointSelected(selectedPointPosition, outer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBorderPointSelected(boolean first) {
|
public boolean isFirstPointSelected(int selectedPointPosition, boolean outer) {
|
||||||
|
if (outer) {
|
||||||
|
return selectedPointPosition == 0;
|
||||||
|
} else {
|
||||||
|
return isBorderPointSelected(selectedPointPosition, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLastPointSelected(boolean outer) {
|
||||||
|
return isLastPointSelected(selectedPointPosition, outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLastPointSelected(int selectedPointPosition, boolean outer) {
|
||||||
|
if (outer) {
|
||||||
|
return selectedPointPosition == getPoints().size() - 1;
|
||||||
|
} else {
|
||||||
|
return isBorderPointSelected(selectedPointPosition, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBorderPointSelected(int selectedPointPosition, boolean first) {
|
||||||
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
WptPt selectedPoint = getPoints().get(selectedPointPosition);
|
||||||
List<TrkSegment> segments = getBeforeSegments();
|
List<TrkSegment> segments = getBeforeSegments();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
@ -64,10 +64,12 @@ import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
|
||||||
import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand;
|
import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand;
|
||||||
import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand.ChangeRouteType;
|
import net.osmand.plus.measurementtool.command.ChangeRouteModeCommand.ChangeRouteType;
|
||||||
import net.osmand.plus.measurementtool.command.ClearPointsCommand;
|
import net.osmand.plus.measurementtool.command.ClearPointsCommand;
|
||||||
|
import net.osmand.plus.measurementtool.command.JoinPointsCommand;
|
||||||
import net.osmand.plus.measurementtool.command.MovePointCommand;
|
import net.osmand.plus.measurementtool.command.MovePointCommand;
|
||||||
import net.osmand.plus.measurementtool.command.RemovePointCommand;
|
import net.osmand.plus.measurementtool.command.RemovePointCommand;
|
||||||
import net.osmand.plus.measurementtool.command.ReorderPointCommand;
|
import net.osmand.plus.measurementtool.command.ReorderPointCommand;
|
||||||
import net.osmand.plus.measurementtool.command.ReversePointsCommand;
|
import net.osmand.plus.measurementtool.command.ReversePointsCommand;
|
||||||
|
import net.osmand.plus.measurementtool.command.SplitPointsCommand;
|
||||||
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
|
||||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||||
|
@ -76,8 +78,8 @@ import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControll
|
||||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
|
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
|
||||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView;
|
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView;
|
||||||
import net.osmand.plus.widgets.MultiStateToggleButton;
|
import net.osmand.plus.widgets.MultiStateToggleButton;
|
||||||
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
|
|
||||||
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
|
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
|
||||||
|
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
|
||||||
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
|
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
@ -1012,6 +1014,39 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
|
||||||
trimRoute(AFTER);
|
trimRoute(AFTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSplitPointsAfter() {
|
||||||
|
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||||
|
editingCtx.getCommandManager().execute(new SplitPointsCommand(measurementLayer, true));
|
||||||
|
collapseInfoViewIfExpanded();
|
||||||
|
editingCtx.setSelectedPointPosition(-1);
|
||||||
|
updateUndoRedoButton(false, redoBtn);
|
||||||
|
updateUndoRedoButton(true, undoBtn);
|
||||||
|
updateDistancePointsText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSplitPointsBefore() {
|
||||||
|
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||||
|
editingCtx.getCommandManager().execute(new SplitPointsCommand(measurementLayer, false));
|
||||||
|
collapseInfoViewIfExpanded();
|
||||||
|
editingCtx.setSelectedPointPosition(-1);
|
||||||
|
updateUndoRedoButton(false, redoBtn);
|
||||||
|
updateUndoRedoButton(true, undoBtn);
|
||||||
|
updateDistancePointsText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onJoinPoints() {
|
||||||
|
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||||
|
editingCtx.getCommandManager().execute(new JoinPointsCommand(measurementLayer));
|
||||||
|
collapseInfoViewIfExpanded();
|
||||||
|
editingCtx.setSelectedPointPosition(-1);
|
||||||
|
updateUndoRedoButton(false, redoBtn);
|
||||||
|
updateUndoRedoButton(true, undoBtn);
|
||||||
|
updateDistancePointsText();
|
||||||
|
}
|
||||||
|
|
||||||
private void trimRoute(ClearCommandMode before) {
|
private void trimRoute(ClearCommandMode before) {
|
||||||
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
MeasurementToolLayer measurementLayer = getMeasurementLayer();
|
||||||
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
|
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
|
||||||
|
|
|
@ -328,7 +328,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
||||||
hasPointsBefore = true;
|
hasPointsBefore = true;
|
||||||
WptPt pt = segment.points.get(segment.points.size() - 1);
|
WptPt pt = segment.points.get(segment.points.size() - 1);
|
||||||
hasGapBefore = pt.isGap();
|
hasGapBefore = pt.isGap();
|
||||||
if (!pt.isGap() || !editingCtx.isInAddPointBeforeMode()) {
|
if (!pt.isGap() || (editingCtx.isInAddPointMode() && !editingCtx.isInAddPointBeforeMode())) {
|
||||||
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
||||||
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
||||||
tx.add(locX);
|
tx.add(locX);
|
||||||
|
@ -345,7 +345,7 @@ public class MeasurementToolLayer extends OsmandMapLayer implements ContextMenuL
|
||||||
tx.add((float) tb.getCenterPixelX());
|
tx.add((float) tb.getCenterPixelX());
|
||||||
ty.add((float) tb.getCenterPixelY());
|
ty.add((float) tb.getCenterPixelY());
|
||||||
}
|
}
|
||||||
if (!hasGapBefore || editingCtx.isInAddPointBeforeMode()) {
|
if (!hasGapBefore || (editingCtx.isInAddPointMode() && editingCtx.isInAddPointBeforeMode())) {
|
||||||
WptPt pt = segment.points.get(0);
|
WptPt pt = segment.points.get(0);
|
||||||
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
float locX = tb.getPixXFromLatLon(pt.lat, pt.lon);
|
||||||
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
float locY = tb.getPixYFromLatLon(pt.lat, pt.lon);
|
||||||
|
|
|
@ -133,7 +133,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setDisabled(editingCtx.isFirstPointSelected())
|
.setDisabled(editingCtx.isFirstPointSelected(false))
|
||||||
.create();
|
.create();
|
||||||
items.add(trimRouteBefore);
|
items.add(trimRouteBefore);
|
||||||
|
|
||||||
|
@ -152,10 +152,93 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setDisabled(editingCtx.isLastPointSelected())
|
.setDisabled(editingCtx.isLastPointSelected(false))
|
||||||
.create();
|
.create();
|
||||||
items.add(trimRouteAfter);
|
items.add(trimRouteAfter);
|
||||||
|
|
||||||
|
if (editingCtx.isFirstPointSelected(true)) {
|
||||||
|
// skip
|
||||||
|
} else if (editingCtx.isLastPointSelected(true)) {
|
||||||
|
items.add(new OptionsDividerItem(getContext()));
|
||||||
|
|
||||||
|
// new segment
|
||||||
|
BaseBottomSheetItem addNewSegment = new BottomSheetItemWithDescription.Builder()
|
||||||
|
//.setIcon(getContentIcon(R.drawable.ic_action_trim_right))
|
||||||
|
.setTitle(getString(R.string.plan_route_add_new_segment))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Fragment targetFragment = getTargetFragment();
|
||||||
|
if (targetFragment instanceof SelectedPointFragmentListener) {
|
||||||
|
((SelectedPointFragmentListener) targetFragment).onSplitPointsAfter();
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
items.add(addNewSegment);
|
||||||
|
} else if (editingCtx.isFirstPointSelected(false) || editingCtx.isLastPointSelected(false)) {
|
||||||
|
items.add(new OptionsDividerItem(getContext()));
|
||||||
|
|
||||||
|
// join
|
||||||
|
BaseBottomSheetItem joinSegments = new BottomSheetItemWithDescription.Builder()
|
||||||
|
//.setIcon(getContentIcon(R.drawable.ic_action_trim_right))
|
||||||
|
.setTitle(getString(R.string.plan_route_join_segments))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Fragment targetFragment = getTargetFragment();
|
||||||
|
if (targetFragment instanceof SelectedPointFragmentListener) {
|
||||||
|
((SelectedPointFragmentListener) targetFragment).onJoinPoints();
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.create();
|
||||||
|
items.add(joinSegments);
|
||||||
|
} else {
|
||||||
|
items.add(new OptionsDividerItem(getContext()));
|
||||||
|
|
||||||
|
// split
|
||||||
|
BaseBottomSheetItem splitAfter = new BottomSheetItemWithDescription.Builder()
|
||||||
|
//.setIcon(getContentIcon(R.drawable.ic_action_trim_right))
|
||||||
|
.setTitle(getString(R.string.plan_route_split_after))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Fragment targetFragment = getTargetFragment();
|
||||||
|
if (targetFragment instanceof SelectedPointFragmentListener) {
|
||||||
|
((SelectedPointFragmentListener) targetFragment).onSplitPointsAfter();
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setDisabled(!editingCtx.canSplit(true))
|
||||||
|
.create();
|
||||||
|
items.add(splitAfter);
|
||||||
|
|
||||||
|
BaseBottomSheetItem splitBefore = new BottomSheetItemWithDescription.Builder()
|
||||||
|
//.setIcon(getContentIcon(R.drawable.ic_action_trim_right))
|
||||||
|
.setTitle(getString(R.string.plan_route_split_before))
|
||||||
|
.setLayoutId(R.layout.bottom_sheet_item_with_descr_pad_32dp)
|
||||||
|
.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Fragment targetFragment = getTargetFragment();
|
||||||
|
if (targetFragment instanceof SelectedPointFragmentListener) {
|
||||||
|
((SelectedPointFragmentListener) targetFragment).onSplitPointsBefore();
|
||||||
|
}
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setDisabled(!editingCtx.canSplit(false))
|
||||||
|
.create();
|
||||||
|
items.add(splitBefore);
|
||||||
|
}
|
||||||
|
|
||||||
items.add(new OptionsDividerItem(getContext()));
|
items.add(new OptionsDividerItem(getContext()));
|
||||||
|
|
||||||
BaseBottomSheetItem changeRouteTypeBefore = new BottomSheetItemWithDescription.Builder()
|
BaseBottomSheetItem changeRouteTypeBefore = new BottomSheetItemWithDescription.Builder()
|
||||||
|
@ -172,7 +255,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setDisabled(editingCtx.isFirstPointSelected() || editingCtx.isSelectionNeedApproximation())
|
.setDisabled(editingCtx.isFirstPointSelected(false) || editingCtx.isApproximationNeeded())
|
||||||
.create();
|
.create();
|
||||||
items.add(changeRouteTypeBefore);
|
items.add(changeRouteTypeBefore);
|
||||||
|
|
||||||
|
@ -190,7 +273,7 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setDisabled(editingCtx.isLastPointSelected() || editingCtx.isSelectionNeedApproximation())
|
.setDisabled(editingCtx.isLastPointSelected(false) || editingCtx.isApproximationNeeded())
|
||||||
.create();
|
.create();
|
||||||
items.add(changeRouteTypeAfter);
|
items.add(changeRouteTypeAfter);
|
||||||
|
|
||||||
|
@ -352,6 +435,12 @@ public class SelectedPointBottomSheetDialogFragment extends MenuBottomSheetDialo
|
||||||
|
|
||||||
void onTrimRouteAfter();
|
void onTrimRouteAfter();
|
||||||
|
|
||||||
|
void onSplitPointsAfter();
|
||||||
|
|
||||||
|
void onSplitPointsBefore();
|
||||||
|
|
||||||
|
void onJoinPoints();
|
||||||
|
|
||||||
void onChangeRouteTypeBefore();
|
void onChangeRouteTypeBefore();
|
||||||
|
|
||||||
void onChangeRouteTypeAfter();
|
void onChangeRouteTypeAfter();
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package net.osmand.plus.measurementtool.command;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class JoinPointsCommand extends MeasurementModeCommand {
|
||||||
|
|
||||||
|
private List<WptPt> points;
|
||||||
|
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData;
|
||||||
|
private int pointPosition;
|
||||||
|
|
||||||
|
public JoinPointsCommand(MeasurementToolLayer measurementLayer) {
|
||||||
|
super(measurementLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute() {
|
||||||
|
pointPosition = getEditingCtx().getSelectedPointPosition();
|
||||||
|
executeCommand();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeCommand() {
|
||||||
|
MeasurementEditingContext ctx = getEditingCtx();
|
||||||
|
List<WptPt> pts = ctx.getPoints();
|
||||||
|
points = new ArrayList<>(pts);
|
||||||
|
roadSegmentData = ctx.getRoadSegmentData();
|
||||||
|
ctx.joinPoints(pointPosition);
|
||||||
|
refreshMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
MeasurementEditingContext ctx = getEditingCtx();
|
||||||
|
ctx.clearSegments();
|
||||||
|
ctx.setRoadSegmentData(roadSegmentData);
|
||||||
|
ctx.addPoints(points);
|
||||||
|
refreshMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo() {
|
||||||
|
executeCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MeasurementCommandType getType() {
|
||||||
|
return MeasurementCommandType.JOIN_POINTS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,8 @@ public abstract class MeasurementModeCommand implements Command {
|
||||||
SNAP_TO_ROAD,
|
SNAP_TO_ROAD,
|
||||||
CHANGE_ROUTE_MODE,
|
CHANGE_ROUTE_MODE,
|
||||||
APPROXIMATE_POINTS,
|
APPROXIMATE_POINTS,
|
||||||
REVERSE_POINTS
|
REVERSE_POINTS,
|
||||||
|
SPLIT_POINTS,
|
||||||
|
JOIN_POINTS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package net.osmand.plus.measurementtool.command;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementEditingContext;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementEditingContext.RoadSegmentData;
|
||||||
|
import net.osmand.plus.measurementtool.MeasurementToolLayer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SplitPointsCommand extends MeasurementModeCommand {
|
||||||
|
|
||||||
|
private boolean after;
|
||||||
|
private List<WptPt> points;
|
||||||
|
private Map<Pair<WptPt, WptPt>, RoadSegmentData> roadSegmentData;
|
||||||
|
private int pointPosition;
|
||||||
|
|
||||||
|
public SplitPointsCommand(MeasurementToolLayer measurementLayer, boolean after) {
|
||||||
|
super(measurementLayer);
|
||||||
|
this.after = after;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute() {
|
||||||
|
pointPosition = getEditingCtx().getSelectedPointPosition();
|
||||||
|
executeCommand();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeCommand() {
|
||||||
|
MeasurementEditingContext ctx = getEditingCtx();
|
||||||
|
List<WptPt> pts = ctx.getPoints();
|
||||||
|
points = new ArrayList<>(pts);
|
||||||
|
roadSegmentData = ctx.getRoadSegmentData();
|
||||||
|
ctx.splitPoints(pointPosition, after);
|
||||||
|
refreshMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
MeasurementEditingContext ctx = getEditingCtx();
|
||||||
|
ctx.clearSegments();
|
||||||
|
ctx.setRoadSegmentData(roadSegmentData);
|
||||||
|
ctx.addPoints(points);
|
||||||
|
refreshMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo() {
|
||||||
|
executeCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MeasurementCommandType getType() {
|
||||||
|
return MeasurementCommandType.SPLIT_POINTS;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue