Skip to content

Commit

Permalink
Support extracting a segment from closed ways
Browse files Browse the repository at this point in the history
  • Loading branch information
simonpoole committed Dec 1, 2024
1 parent a5e20c9 commit 50013bf
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 114 deletions.
22 changes: 12 additions & 10 deletions src/androidTest/java/de/blau/android/osm/GeometryEditsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,10 @@ public void closedWaySplit() {
final Node n5 = nList1.get(4);
assertEquals(n1, n5);
assertTrue(w1.isClosed());
Way[] ways = logic.performClosedWaySplit(main, w1, n2, n4, false);
assertEquals(2, ways.length);
assertEquals(3, ways[0].getNodes().size());
assertEquals(3, ways[1].getNodes().size());
List<Result> results = logic.performClosedWaySplit(main, w1, n2, n4, false);
assertEquals(2, results.size());
assertEquals(3, ((Way) results.get(0).getElement()).getNodes().size());
assertEquals(3, ((Way) results.get(1).getElement()).getNodes().size());
} catch (Exception igit) {
fail(igit.getMessage());
}
Expand Down Expand Up @@ -361,12 +361,14 @@ public void closedWaySplitToPolygons() {
final Node n5 = nList1.get(4);
assertEquals(n1, n5);
assertTrue(w1.isClosed());
Way[] ways = logic.performClosedWaySplit(main, w1, n1, n3, true);
assertEquals(2, ways.length);
assertEquals(4, ways[0].getNodes().size());
assertTrue(ways[0].isClosed());
assertEquals(4, ways[1].getNodes().size());
assertTrue(ways[1].isClosed());
List<Result> results = logic.performClosedWaySplit(main, w1, n1, n3, true);
assertEquals(2, results.size());
final Way way0 = (Way) results.get(0).getElement();
assertEquals(4, way0.getNodes().size());
assertTrue(way0.isClosed());
final Way way1 = (Way) results.get(1).getElement();
assertEquals(4, way1.getNodes().size());
assertTrue(way1.isClosed());
} catch (Exception igit) {
fail(igit.getMessage());
}
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/de/blau/android/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -2144,17 +2144,18 @@ public synchronized List<Result> performSplit(@Nullable final FragmentActivity a
* @param node1 first split point
* @param node2 second split point
* @param createPolygons create polygons by closing the split ways if true
* @return null if the split fails, the two ways otherwise
* @return a List of Result objects containing the original Way in the 1st element and the new Way in the 2ndand any
* issues
* @throws OsmIllegalOperationException if the operation failed
* @throws StorageException if we ran out of memory
*/
@NonNull
public synchronized Way[] performClosedWaySplit(@Nullable FragmentActivity activity, @NonNull Way way, @NonNull Node node1, @NonNull Node node2,
public synchronized List<Result> performClosedWaySplit(@Nullable FragmentActivity activity, @NonNull Way way, @NonNull Node node1, @NonNull Node node2,
boolean createPolygons) {
createCheckpoint(activity, R.string.undo_action_split_way);
try {
displayAttachedObjectWarning(activity, way);
Way[] result = getDelegator().splitAtNodes(way, node1, node2, createPolygons);
List<Result> result = getDelegator().splitAtNodes(way, node1, node2, createPolygons);
invalidateMap();
return result;
} catch (OsmIllegalOperationException | StorageException ex) {
Expand All @@ -2167,26 +2168,26 @@ public synchronized Way[] performClosedWaySplit(@Nullable FragmentActivity activ
* Extract a segment from a way (the way between two nodes of the same way)
*
* @param activity activity we were called fron
* @param way Unclosed Way to split
* @param way Way to split
* @param node1 first split point
* @param node2 second split point
* @return null if the split fails, the segment otherwise
* @return the segment in the 1st Result if successful, otherwise the results contain issues
*/
@NonNull
public synchronized List<Result> performExtractSegment(@Nullable FragmentActivity activity, @NonNull Way way, @NonNull Node node1, @NonNull Node node2) {
createCheckpoint(activity, R.string.undo_action_extract_segment);
try {
displayAttachedObjectWarning(activity, way);
List<Result> result = null;
if (way.isEndNode(node1)) {
if (way.isClosed()) {
result = getDelegator().splitAtNodes(way, node1, node2, false);
return result.subList(1, result.size()); // extracted segment is in the 2nd result
} else if (way.isEndNode(node1)) {
result = extractSegmentAtEnd(way, node1, node2);
} else if (way.isEndNode(node2)) {
result = extractSegmentAtEnd(way, node2, node1);
} else {
result = getDelegator().splitAtNode(way, node1, true);
if (result.isEmpty()) {
throw new OsmIllegalOperationException("Splitting way " + way.getOsmId() + " at node " + node1.getOsmId() + " failed");
}
Result first = result.get(0);
boolean splitOriginal = way.hasNode(node2);
Way newWay = (Way) first.getElement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import android.util.Log;
import androidx.annotation.NonNull;
import de.blau.android.dialogs.ElementIssueDialog;
import de.blau.android.exception.OsmIllegalOperationException;
import de.blau.android.exception.StorageException;
import de.blau.android.osm.Node;
import de.blau.android.osm.OsmElement;
import de.blau.android.osm.Result;
import de.blau.android.osm.Way;
import de.blau.android.util.SerializableState;

Expand Down Expand Up @@ -88,17 +90,24 @@ public boolean handleElementClick(OsmElement element) { // NOSONAR
super.handleElementClick(element);
try {
if (element instanceof Node) {
Way[] result = logic.performClosedWaySplit(main, way, node, (Node) element, createPolygons);
if (result.length == 2) {
logic.setSelectedNode(null);
logic.setSelectedRelation(null);
logic.setSelectedWay(result[0]);
logic.addSelectedWay(result[1]);
List<OsmElement> selection = new ArrayList<>();
selection.addAll(logic.getSelectedWays());
main.startSupportActionMode(new MultiSelectWithGeometryActionModeCallback(manager, selection));
return true;
List<Result> results = logic.performClosedWaySplit(main, way, node, (Node) element, createPolygons);
logic.setSelectedNode(null);
logic.setSelectedRelation(null);
logic.setSelectedWay((Way) results.get(0).getElement());
logic.addSelectedWay((Way) results.get(1).getElement());
List<OsmElement> selection = new ArrayList<>();
selection.addAll(logic.getSelectedWays());
main.startSupportActionMode(new MultiSelectWithGeometryActionModeCallback(manager, selection));
List<Result> resultsWithIssue = new ArrayList<>();
for (Result r : results) {
if (r.hasIssue()) {
resultsWithIssue.add(r);
}
}
if (!resultsWithIssue.isEmpty()) {
ElementIssueDialog.showTagConflictDialog(main, resultsWithIssue);
}
return true;
}
} catch (OsmIllegalOperationException | StorageException ex) {
// toast has already been displayed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
updated |= setItemVisibility(joined, unjoinItem, false);
updated |= setItemVisibility(joined, unjoinDissimilarItem, false);

updated |= setItemVisibility(size >= 3 && !closed, extractSegmentItem, false);
updated |= setItemVisibility(size >= 3, extractSegmentItem, false);

if (updated) {
arrangeMenu(menu);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.blau.android.easyedit.turnrestriction;

import static de.blau.android.contract.Constants.LOG_TAG_LEN;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
Expand All @@ -24,10 +26,13 @@
*
*/
public class RestrictionClosedWaySplittingActionModeCallback extends AbstractClosedWaySplittingActionModeCallback {
private static final String DEBUG_TAG = RestrictionClosedWaySplittingActionModeCallback.class.getSimpleName().substring(0, Math.min(23, RestrictionClosedWaySplittingActionModeCallback.class.getSimpleName().length()));
private final Way way;
private final Node node;
private final Way fromWay;

private static final int TAG_LEN = Math.min(LOG_TAG_LEN, RestrictionClosedWaySplittingActionModeCallback.class.getSimpleName().length());
private static final String DEBUG_TAG = RestrictionClosedWaySplittingActionModeCallback.class.getSimpleName().substring(0, TAG_LEN);

private final Way way;
private final Node node;
private final Way fromWay;

/**
* Construct a new callback for splitting a closed way/polygon as part of a turn restriction
Expand Down Expand Up @@ -58,22 +63,23 @@ public boolean handleElementClick(OsmElement element) { // NOSONAR
super.handleElementClick(element);
try {
if (element instanceof Node) {
Way[] result = logic.performClosedWaySplit(main, way, node, (Node) element, false);
if (result.length == 2) {
if (fromWay == null) {
Set<OsmElement> candidates = new HashSet<>();
candidates.add(result[0]);
candidates.add(result[1]);
main.startSupportActionMode(new RestartFromElementActionModeCallback(manager, candidates, candidates, savedResults));
} else {
Way viaWay = result[0];
if (fromWay.hasCommonNode(result[1])) {
viaWay = result[1];
}
main.startSupportActionMode(new ViaElementActionModeCallback(manager, fromWay, viaWay, savedResults));
List<Result> results = logic.performClosedWaySplit(main, way, node, (Node) element, false);
// FIXME we currently don't display any issues as that would be confusing
Way way0 = (Way) results.get(0).getElement();
Way way1 = (Way) results.get(1).getElement();
if (fromWay == null) {
Set<OsmElement> candidates = new HashSet<>();
candidates.add(way0);
candidates.add(way1);
main.startSupportActionMode(new RestartFromElementActionModeCallback(manager, candidates, candidates, savedResults));
} else {
Way viaWay = way0;
if (fromWay.hasCommonNode(way1)) {
viaWay = way1;
}
return true;
main.startSupportActionMode(new ViaElementActionModeCallback(manager, fromWay, viaWay, savedResults));
}
return true;
}
} catch (OsmIllegalOperationException | StorageException ex) {
// toast has already been displayed
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/de/blau/android/osm/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,20 @@ public Collection<Issue> getIssues() {
*
* @return the element
*/
@Nullable
public OsmElement getElement() {
return element;
}

/**
* Check if this result contains an OsmElement
*
* @return true if an element is present
*/
public boolean hasElement() {
return element != null;
}

/**
* Set the stored OsmElement
*
Expand Down
Loading

0 comments on commit 50013bf

Please sign in to comment.