Calculate route among segments
This commit is contained in:
parent
773a0a7342
commit
cae7027177
2 changed files with 77 additions and 45 deletions
|
@ -1,8 +1,9 @@
|
|||
package net.osmand.plus.routing;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Route;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -18,6 +19,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static net.osmand.plus.routing.RouteProvider.collectSegmentPointsFromGpx;
|
||||
import static net.osmand.router.RouteExporter.OSMAND_ROUTER_V2;
|
||||
|
||||
public class GPXRouteParams {
|
||||
|
@ -29,6 +31,7 @@ public class GPXRouteParams {
|
|||
protected List<RouteDirectionInfo> directions;
|
||||
protected List<Location> points = new ArrayList<>();
|
||||
protected List<WptPt> routePoints = new ArrayList<>();
|
||||
protected List<Pair<Location, Location>> segmentEndpoints = new ArrayList<>();
|
||||
protected boolean reverse;
|
||||
protected boolean passWholeRoute;
|
||||
protected boolean calculateOsmAndRoute;
|
||||
|
@ -82,7 +85,7 @@ public class GPXRouteParams {
|
|||
}
|
||||
int selectedSegment = builder.getSelectedSegment();
|
||||
if (OSMAND_ROUTER_V2.equals(file.author)) {
|
||||
route = RouteProvider.parseOsmAndGPXRoute(points, file, selectedSegment);
|
||||
route = RouteProvider.parseOsmAndGPXRoute(points, file, segmentEndpoints, selectedSegment);
|
||||
if (selectedSegment == -1) {
|
||||
routePoints = file.getRoutePoints();
|
||||
} else {
|
||||
|
@ -94,7 +97,7 @@ public class GPXRouteParams {
|
|||
}
|
||||
addMissingTurns = route != null && route.isEmpty();
|
||||
} else if (file.isCloudmadeRouteFile() || OSMAND_ROUTER.equals(file.author)) {
|
||||
directions = RouteProvider.parseOsmAndGPXRoute(points, file, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
|
||||
directions = RouteProvider.parseOsmAndGPXRoute(points, file, segmentEndpoints, OSMAND_ROUTER.equals(file.author), builder.leftSide, 10, selectedSegment);
|
||||
if (OSMAND_ROUTER.equals(file.author) && file.hasRtePt()) {
|
||||
// For files generated by OSMAND_ROUTER use directions contained unaltered
|
||||
addMissingTurns = false;
|
||||
|
@ -108,19 +111,7 @@ public class GPXRouteParams {
|
|||
} else {
|
||||
// first of all check tracks
|
||||
if (!useIntermediatePointsRTE) {
|
||||
List<TrkSegment> segments = file.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt p : segment.points) {
|
||||
points.add(RouteProvider.createLocation(p));
|
||||
}
|
||||
} else {
|
||||
for (TrkSegment tkSeg : segments) {
|
||||
for (WptPt p : tkSeg.points) {
|
||||
points.add(RouteProvider.createLocation(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
collectSegmentPointsFromGpx(file, points, segmentEndpoints, selectedSegment);
|
||||
}
|
||||
if (points.isEmpty()) {
|
||||
for (Route rte : file.routes) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus.routing;
|
|||
|
||||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
import android.util.Pair;
|
||||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
|
@ -22,6 +23,7 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
|||
import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
|
||||
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
|
||||
import net.osmand.plus.render.NativeOsmandLibrary;
|
||||
import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.settings.backend.CommonPreference;
|
||||
import net.osmand.plus.settings.backend.OsmandSettings;
|
||||
|
@ -266,6 +268,7 @@ public class RouteProvider {
|
|||
}
|
||||
final List<RouteDirectionInfo> inputDirections = gpxParams.directions;
|
||||
List<RouteDirectionInfo> gpxDirections = calcDirections(startI, endI, inputDirections);
|
||||
insertSegments(routeParams, gpxRoute, gpxDirections, gpxParams.segmentEndpoints, calculateOsmAndRouteParts);
|
||||
insertInitialSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
|
||||
insertFinalSegment(routeParams, gpxRoute, gpxDirections, calculateOsmAndRouteParts);
|
||||
|
||||
|
@ -279,6 +282,28 @@ public class RouteProvider {
|
|||
gpxParams.wpt, routeParams.gpxRoute.addMissingTurns);
|
||||
}
|
||||
|
||||
public void insertSegments(RouteCalculationParams routeParams, List<Location> points, List<RouteDirectionInfo> directions,
|
||||
List<Pair<Location, Location>> segmentEndpoints, boolean calculateOsmAndRouteParts) {
|
||||
for (Pair<Location, Location> pair : segmentEndpoints) {
|
||||
int index = points.indexOf(pair.second);
|
||||
if (calculateOsmAndRouteParts && index != -1 && points.contains(pair.first)) {
|
||||
LatLon end = new LatLon(pair.second.getLatitude(), pair.second.getLongitude());
|
||||
RouteCalculationResult newRes = findOfflineRouteSegment(routeParams, pair.first, end);
|
||||
|
||||
if (newRes != null && newRes.isCalculated()) {
|
||||
List<Location> loct = newRes.getImmutableAllLocations();
|
||||
List<RouteDirectionInfo> dt = newRes.getImmutableAllDirections();
|
||||
|
||||
for (RouteDirectionInfo i : dt) {
|
||||
i.routePointOffset += points.size();
|
||||
}
|
||||
points.addAll(index, loct);
|
||||
directions.addAll(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RouteCalculationResult calculateOsmAndRouteWithIntermediatePoints(RouteCalculationParams routeParams,
|
||||
final List<Location> intermediates) throws IOException {
|
||||
RouteCalculationParams rp = new RouteCalculationParams();
|
||||
|
@ -737,7 +762,9 @@ public class RouteProvider {
|
|||
return new RouteCalculationResult("Empty result");
|
||||
}
|
||||
|
||||
protected static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, int selectedSegment) {
|
||||
protected static List<RouteSegmentResult> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile,
|
||||
List<Pair<Location, Location>> segmentEndpoints,
|
||||
int selectedSegment) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
|
@ -747,37 +774,50 @@ public class RouteProvider {
|
|||
RouteImporter routeImporter = new RouteImporter(segment);
|
||||
return routeImporter.importRoute();
|
||||
} else {
|
||||
for (TrkSegment ts : segments) {
|
||||
for (WptPt p : ts.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
}
|
||||
collectPointsFromSegments(segments, points, segmentEndpoints);
|
||||
RouteImporter routeImporter = new RouteImporter(gpxFile);
|
||||
return routeImporter.importRoute();
|
||||
}
|
||||
}
|
||||
|
||||
protected static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile, boolean osmandRouter,
|
||||
boolean leftSide, float defSpeed, int selectedSegment) {
|
||||
protected static void collectSegmentPointsFromGpx(GPXFile gpxFile, List<Location> points,
|
||||
List<Pair<Location, Location>> segmentEndpoints, int selectedSegment) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt wptPt : segment.points) {
|
||||
points.add(createLocation(wptPt));
|
||||
}
|
||||
} else {
|
||||
collectPointsFromSegments(segments, points, segmentEndpoints);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void collectPointsFromSegments(List<TrkSegment> segments, List<Location> points, List<Pair<Location, Location>> segmentEndpoints) {
|
||||
Location lastPoint = null;
|
||||
for (int i = 0; i < segments.size(); i++) {
|
||||
TrkSegment segment = segments.get(i);
|
||||
for (WptPt wptPt : segment.points) {
|
||||
points.add(createLocation(wptPt));
|
||||
}
|
||||
if (i <= segments.size() - 1 && lastPoint != null) {
|
||||
segmentEndpoints.add(new Pair<>(lastPoint, points.get((points.size() - segment.points.size()))));
|
||||
}
|
||||
lastPoint = points.get(points.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected static List<RouteDirectionInfo> parseOsmAndGPXRoute(List<Location> points, GPXFile gpxFile,
|
||||
List<Pair<Location, Location>> segmentEndpoints,
|
||||
boolean osmandRouter, boolean leftSide,
|
||||
float defSpeed, int selectedSegment) {
|
||||
List<RouteDirectionInfo> directions = null;
|
||||
if (!osmandRouter) {
|
||||
for (WptPt pt : gpxFile.getPoints()) {
|
||||
points.add(createLocation(pt));
|
||||
}
|
||||
} else {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(false);
|
||||
if (selectedSegment != -1 && segments.size() > selectedSegment) {
|
||||
TrkSegment segment = segments.get(selectedSegment);
|
||||
for (WptPt p : segment.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
} else {
|
||||
for (TrkSegment ts : segments) {
|
||||
for (WptPt p : ts.points) {
|
||||
points.add(createLocation(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
collectSegmentPointsFromGpx(gpxFile, points, segmentEndpoints, selectedSegment);
|
||||
}
|
||||
float[] distanceToEnd = new float[points.size()];
|
||||
for (int i = points.size() - 2; i >= 0; i--) {
|
||||
|
@ -1042,9 +1082,10 @@ public class RouteProvider {
|
|||
bpars.putString("turnInstructionFormat", "osmand");
|
||||
bpars.putString("acceptCompressedResult", "true");
|
||||
|
||||
OsmandApplication ctx = (OsmandApplication) params.ctx;
|
||||
OsmandApplication ctx = params.ctx;
|
||||
List<Location> res = new ArrayList<Location>();
|
||||
List<RouteDirectionInfo > dir = new ArrayList<>();
|
||||
List<RouteDirectionInfo> dir = new ArrayList<>();
|
||||
List<Pair<Location, Location>> segmentEndpoints = new ArrayList<>();
|
||||
|
||||
IBRouterService brouterService = ctx.getBRouterService();
|
||||
if (brouterService == null) {
|
||||
|
@ -1057,22 +1098,22 @@ public class RouteProvider {
|
|||
|
||||
boolean isZ64Encoded = gpxMessage.startsWith("ejY0"); // base-64 version of "z64"
|
||||
|
||||
if (!( isZ64Encoded || gpxMessage.startsWith("<") ) ) {
|
||||
if (!(isZ64Encoded || gpxMessage.startsWith("<"))) {
|
||||
return new RouteCalculationResult(gpxMessage);
|
||||
}
|
||||
|
||||
InputStream gpxStream;
|
||||
if ( isZ64Encoded ) {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream( Base64.decode(gpxMessage, Base64.DEFAULT) );
|
||||
bais.read( new byte[3] ); // skip prefix
|
||||
gpxStream = new GZIPInputStream( bais );
|
||||
if (isZ64Encoded) {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(gpxMessage, Base64.DEFAULT));
|
||||
bais.read(new byte[3]); // skip prefix
|
||||
gpxStream = new GZIPInputStream(bais);
|
||||
} else {
|
||||
gpxStream = new ByteArrayInputStream(gpxMessage.getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(gpxStream);
|
||||
|
||||
dir = parseOsmAndGPXRoute(res, gpxFile, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
|
||||
dir = parseOsmAndGPXRoute(res, gpxFile, segmentEndpoints, true, params.leftSide, params.mode.getDefaultSpeed(), -1);
|
||||
|
||||
if (dir != null) {
|
||||
addMissingTurns = false;
|
||||
|
|
Loading…
Reference in a new issue