Merge pull request #10025 from osmandapp/GraphsFixCrash

Fix algorithm for compiling an ordered list of RoadSegmentResult
This commit is contained in:
Vitaliy 2020-10-15 13:44:01 +03:00 committed by GitHub
commit 7947f9a44a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -314,71 +314,17 @@ public class MeasurementEditingContext {
} }
public List<RouteSegmentResult> getAllRouteSegments() { public List<RouteSegmentResult> getAllRouteSegments() {
// prepare data for sorting List<RouteSegmentResult> allSegments = new ArrayList<>();
List<TmpRouteSegmentData> fullList = new ArrayList<>(); for (Pair<WptPt, WptPt> key : getOrderedRoadSegmentDataKeys()) {
for (Map.Entry<Pair<WptPt, WptPt>, RoadSegmentData> entry : roadSegmentData.entrySet()) { RoadSegmentData data = roadSegmentData.get(key);
fullList.add(new TmpRouteSegmentData( if (data != null) {
entry.getKey().first, List<RouteSegmentResult> segments = data.getSegments();
entry.getKey().second, if (segments != null) {
entry.getValue().getSegments())); allSegments.addAll(segments);
}
// sorting data by connecting together
while (fullList.size() > 1) {
TmpRouteSegmentData firstInList = fullList.get(0);
for (int i = 1; i < fullList.size(); i++) {
TmpRouteSegmentData other = fullList.get(i);
boolean isMatched = false;
if (firstInList.isAfterOf(other)) {
isMatched = true;
firstInList.joinBefore(other);
} else if (firstInList.isBeforeOf(other)) {
isMatched = true;
firstInList.joinAfter(other);
}
if (isMatched) {
fullList.remove(other);
break;
} }
} }
} }
return fullList.size() > 0 ? fullList.get(0).getRouteSegments() : null; return allSegments.size() > 0 ? allSegments : null;
}
private static class TmpRouteSegmentData {
private WptPt start;
private WptPt end;
private List<RouteSegmentResult> routeSegments;
public TmpRouteSegmentData(WptPt start, WptPt end,
List<RouteSegmentResult> routeSegments) {
this.start = start;
this.end = end;
this.routeSegments = new ArrayList<>(routeSegments);
}
boolean isAfterOf(TmpRouteSegmentData other) {
return Algorithms.objectEquals(this.start, other.end);
}
boolean isBeforeOf(TmpRouteSegmentData other) {
return Algorithms.objectEquals(this.end, other.start);
}
void joinAfter(TmpRouteSegmentData other) {
end = other.end;
routeSegments.addAll(other.routeSegments);
}
void joinBefore(TmpRouteSegmentData other) {
start = other.start;
routeSegments.addAll(0, other.routeSegments);
}
public List<RouteSegmentResult> getRouteSegments() {
return routeSegments;
}
} }
void splitSegments(int position) { void splitSegments(int position) {
@ -501,6 +447,16 @@ public class MeasurementEditingContext {
return res; return res;
} }
private List<Pair<WptPt, WptPt>> getOrderedRoadSegmentDataKeys() {
List<Pair<WptPt, WptPt>> keys = new ArrayList<>();
for (List<WptPt> points : Arrays.asList(before.points, after.points)) {
for (int i = 0; i < points.size() - 1; i++) {
keys.add(new Pair<>(points.get(i), points.get(i + 1)));
}
}
return keys;
}
private void recreateCacheForSnap(TrkSegment cache, TrkSegment original, boolean calculateIfNeeded) { private void recreateCacheForSnap(TrkSegment cache, TrkSegment original, boolean calculateIfNeeded) {
boolean hasDefaultModeOnly = true; boolean hasDefaultModeOnly = true;
if (original.points.size() > 1) { if (original.points.size() > 1) {