Calculate route between segments with gpxRouteResult

This commit is contained in:
Vitaliy 2021-03-02 06:48:00 +02:00
parent f1e0ad342c
commit 0dfd710013
2 changed files with 82 additions and 37 deletions

View file

@ -290,12 +290,16 @@ public class RouteCalculationResult {
} }
public List<RouteSegmentResult> getOriginalRoute(int startIndex) { public List<RouteSegmentResult> getOriginalRoute(int startIndex) {
return getOriginalRoute(startIndex, segments.size());
}
public List<RouteSegmentResult> getOriginalRoute(int startIndex, int endIndex) {
if (segments.size() == 0) { if (segments.size() == 0) {
return null; return null;
} }
List<RouteSegmentResult> list = new ArrayList<RouteSegmentResult>(); List<RouteSegmentResult> list = new ArrayList<>();
list.add(segments.get(startIndex++)); list.add(segments.get(startIndex++));
for (int i = startIndex; i < segments.size(); i++) { for (int i = startIndex; i < endIndex; i++) {
if (segments.get(i - 1) != segments.get(i)) { if (segments.get(i - 1) != segments.get(i)) {
list.add(segments.get(i)); list.add(segments.get(i));
} }

View file

@ -153,8 +153,9 @@ public class RouteProvider {
GPXRouteParams gpxParams = routeParams.gpxRoute; GPXRouteParams gpxParams = routeParams.gpxRoute;
boolean calcWholeRoute = routeParams.gpxRoute.passWholeRoute && (routeParams.previousToRecalculate == null || !routeParams.onlyStartPointChanged); boolean calcWholeRoute = routeParams.gpxRoute.passWholeRoute && (routeParams.previousToRecalculate == null || !routeParams.onlyStartPointChanged);
boolean calculateOsmAndRouteParts = gpxParams.calculateOsmAndRouteParts; boolean calculateOsmAndRouteParts = gpxParams.calculateOsmAndRouteParts;
boolean reverseRoutePoints = gpxParams.reverse && gpxParams.routePoints.size() > 1;
List<RouteSegmentResult> gpxRouteResult = routeParams.gpxRoute.route; List<RouteSegmentResult> gpxRouteResult = routeParams.gpxRoute.route;
if (gpxParams.reverse && gpxParams.routePoints.size() > 1) { if (reverseRoutePoints) {
List<Location> gpxRouteLocations = new ArrayList<>(); List<Location> gpxRouteLocations = new ArrayList<>();
List<RouteSegmentResult> gpxRoute = new ArrayList<>(); List<RouteSegmentResult> gpxRoute = new ArrayList<>();
WptPt firstGpxPoint = gpxParams.routePoints.get(0); WptPt firstGpxPoint = gpxParams.routePoints.get(0);
@ -214,18 +215,27 @@ public class RouteProvider {
List<RouteSegmentResult> firstSegmentRoute = null; List<RouteSegmentResult> firstSegmentRoute = null;
List<RouteSegmentResult> lastSegmentRoute = null; List<RouteSegmentResult> lastSegmentRoute = null;
List<RouteSegmentResult> gpxRoute; List<RouteSegmentResult> gpxRoute;
if (nearestGpxPointInd > 0) {
nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd); if (calculateOsmAndRouteParts && !reverseRoutePoints && !Algorithms.isEmpty(gpxParams.segmentEndpoints)) {
gpxRoute = result.getOriginalRoute(nearestGpxPointInd); if (nearestGpxPointInd > 0) {
if (gpxRoute.size() > 0) { nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
gpxRoute.remove(0);
} }
gpxRoute = findRouteWithIntermediateSegments(routeParams, result, gpxRouteLocations, gpxParams.segmentEndpoints, nearestGpxPointInd);
} else { } else {
if (!gpxRouteLocations.isEmpty()) { if (nearestGpxPointInd > 0) {
nearestGpxLocation = gpxRouteLocations.get(0); nearestGpxLocation = gpxRouteLocations.get(nearestGpxPointInd);
gpxRoute = result.getOriginalRoute(nearestGpxPointInd);
if (gpxRoute.size() > 0) {
gpxRoute.remove(0);
}
} else {
if (!gpxRouteLocations.isEmpty()) {
nearestGpxLocation = gpxRouteLocations.get(0);
}
gpxRoute = result.getOriginalRoute();
} }
gpxRoute = result.getOriginalRoute();
} }
if (calculateOsmAndRouteParts if (calculateOsmAndRouteParts
&& routeParams.start != null && nearestGpxLocation != null && routeParams.start != null && nearestGpxLocation != null
&& nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) { && nearestGpxLocation.distanceTo(routeParams.start) > MIN_DISTANCE_FOR_INSERTING_ROUTE_SEGMENT) {
@ -267,7 +277,7 @@ public class RouteProvider {
} }
final List<RouteDirectionInfo> inputDirections = gpxParams.directions; final List<RouteDirectionInfo> inputDirections = gpxParams.directions;
List<RouteDirectionInfo> gpxDirections = calcDirections(startI, endI, inputDirections); List<RouteDirectionInfo> gpxDirections = calcDirections(startI, endI, inputDirections);
insertSegments(routeParams, gpxRoute, gpxDirections, gpxParams.segmentEndpoints, calculateOsmAndRouteParts); insertIntermediateSegments(routeParams, gpxRoute, gpxDirections, gpxParams.segmentEndpoints, calculateOsmAndRouteParts);
insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts); insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
insertFinalSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts); insertFinalSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
@ -281,31 +291,6 @@ public class RouteProvider {
gpxParams.wpt, routeParams.gpxRoute.addMissingTurns); gpxParams.wpt, routeParams.gpxRoute.addMissingTurns);
} }
public void insertSegments(RouteCalculationParams routeParams, List<Location> points, List<RouteDirectionInfo> directions,
List<Location> segmentEndpoints, boolean calculateOsmAndRouteParts) {
for (int i = 0; i < segmentEndpoints.size() - 1; i++) {
Location prevSegmentPoint = segmentEndpoints.get(i);
Location newSegmentPoint = segmentEndpoints.get(i + 1);
int index = points.indexOf(newSegmentPoint);
if (calculateOsmAndRouteParts && index != -1 && points.contains(prevSegmentPoint)) {
LatLon end = new LatLon(newSegmentPoint.getLatitude(), newSegmentPoint.getLongitude());
RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, prevSegmentPoint, end);
if (newRes != null && newRes.isCalculated()) {
List<Location> loct = newRes.getImmutableAllLocations();
List<RouteDirectionInfo> dt = newRes.getImmutableAllDirections();
for (RouteDirectionInfo directionInfo : dt) {
directionInfo.routePointOffset += points.size();
}
points.addAll(index, loct);
directions.addAll(dt);
}
}
}
}
private RouteCalculationResult calculateOsmAndRouteWithIntermediatePoints(RouteCalculationParams routeParams, private RouteCalculationResult calculateOsmAndRouteWithIntermediatePoints(RouteCalculationParams routeParams,
final List<Location> intermediates) throws IOException { final List<Location> intermediates) throws IOException {
RouteCalculationParams rp = new RouteCalculationParams(); RouteCalculationParams rp = new RouteCalculationParams();
@ -442,6 +427,62 @@ public class RouteProvider {
} }
} }
public void insertIntermediateSegments(RouteCalculationParams routeParams, List<Location> points, List<RouteDirectionInfo> directions,
List<Location> segmentEndpoints, boolean calculateOsmAndRouteParts) {
for (int i = 0; i < segmentEndpoints.size() - 1; i++) {
Location prevSegmentPoint = segmentEndpoints.get(i);
Location newSegmentPoint = segmentEndpoints.get(i + 1);
int index = points.indexOf(newSegmentPoint);
if (calculateOsmAndRouteParts && index != -1 && points.contains(prevSegmentPoint)) {
LatLon end = new LatLon(newSegmentPoint.getLatitude(), newSegmentPoint.getLongitude());
RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, prevSegmentPoint, end);
if (newRes != null && newRes.isCalculated()) {
List<Location> loct = newRes.getImmutableAllLocations();
List<RouteDirectionInfo> dt = newRes.getImmutableAllDirections();
for (RouteDirectionInfo directionInfo : dt) {
directionInfo.routePointOffset += points.size();
}
points.addAll(index, loct);
directions.addAll(dt);
}
}
}
}
public List<RouteSegmentResult> findRouteWithIntermediateSegments(RouteCalculationParams routeParams,
RouteCalculationResult result,
List<Location> gpxRouteLocations,
List<Location> segmentEndpoints,
int nearestGpxPointInd) {
List<RouteSegmentResult> newGpxRoute = new ArrayList<>();
int lastIndex = nearestGpxPointInd;
for (int i = 0; i < segmentEndpoints.size() - 1; i++) {
Location prevSegmentPoint = segmentEndpoints.get(i);
Location newSegmentPoint = segmentEndpoints.get(i + 1);
int indexNew = findNearestGpxPointIndexFromRoute(gpxRouteLocations, newSegmentPoint, routeParams.gpxRoute.calculateOsmAndRouteParts);
int indexPrev = findNearestGpxPointIndexFromRoute(gpxRouteLocations, prevSegmentPoint, routeParams.gpxRoute.calculateOsmAndRouteParts);
if (indexPrev != -1 && indexPrev > nearestGpxPointInd && indexNew != -1) {
newGpxRoute.addAll(result.getOriginalRoute(lastIndex, indexPrev));
lastIndex = indexNew;
LatLon end = new LatLon(newSegmentPoint.getLatitude(), newSegmentPoint.getLongitude());
RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, prevSegmentPoint, end);
List<RouteSegmentResult> segmentResults = newRes.getOriginalRoute();
if (!Algorithms.isEmpty(segmentResults)) {
newGpxRoute.addAll(segmentResults);
}
}
}
newGpxRoute.addAll(result.getOriginalRoute(lastIndex));
return newGpxRoute;
}
private RouteCalculationResult findOfflineRouteSegment(RouteCalculationParams rParams, Location start, private RouteCalculationResult findOfflineRouteSegment(RouteCalculationParams rParams, Location start,
LatLon end) { LatLon end) {
RouteCalculationParams newParams = new RouteCalculationParams(); RouteCalculationParams newParams = new RouteCalculationParams();