Merge pull request #549 from afischerdev/engine-mode

Introducing engineMode for future use
This commit is contained in:
afischerdev 2023-05-21 11:27:15 +02:00 committed by GitHub
commit 781661ea12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 91 deletions

View file

@ -839,6 +839,49 @@ public final class OsmTrack {
return sb.toString(); return sb.toString();
} }
static public String formatAsGpxWaypoint(OsmNodeNamed n) {
try {
StringWriter sw = new StringWriter(8192);
BufferedWriter bw = new BufferedWriter(sw);
formatGpxHeader(bw);
formatWaypointGpx(bw, n);
formatGpxFooter(bw);
bw.close();
sw.close();
return sw.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static public void formatGpxHeader(BufferedWriter sb) throws IOException {
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<gpx \n");
sb.append(" xmlns=\"http://www.topografix.com/GPX/1/1\" \n");
sb.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n");
sb.append(" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n");
sb.append(" creator=\"BRouter-" + version + "\" version=\"1.1\">\n");
}
static public void formatGpxFooter(BufferedWriter sb) throws IOException {
sb.append("</gpx>\n");
}
static public void formatWaypointGpx(BufferedWriter sb, OsmNodeNamed n) throws IOException {
sb.append(" <wpt lon=\"").append(formatILon(n.ilon)).append("\" lat=\"")
.append(formatILat(n.ilat)).append("\">");
if (n.getSElev() != Short.MIN_VALUE) {
sb.append("<ele>").append("" + n.getElev()).append("</ele>");
}
if (n.name != null) {
sb.append("<name>").append(StringUtils.escapeXml10(n.name)).append("</name>");
}
if (n.nodeDescription != null) {
sb.append("<desc>").append("hat desc").append("</desc>");
}
sb.append("</wpt>\n");
}
public void writeKml(String filename) throws Exception { public void writeKml(String filename) throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter(filename)); BufferedWriter bw = new BufferedWriter(new FileWriter(filename));

View file

@ -25,6 +25,11 @@ import btools.util.SortedHeap;
import btools.util.StackSampler; import btools.util.StackSampler;
public class RoutingEngine extends Thread { public class RoutingEngine extends Thread {
public final static int BROUTER_ENGINEMODE_ROUTING = 0;
public final static int BROUTER_ENGINEMODE_SEED = 1;
public final static int BROUTER_ENGINEMODE_GETELEV = 2;
private NodesCache nodesCache; private NodesCache nodesCache;
private SortedHeap<OsmPath> openSet = new SortedHeap<>(); private SortedHeap<OsmPath> openSet = new SortedHeap<>();
private boolean finished = false; private boolean finished = false;
@ -37,12 +42,15 @@ public class RoutingEngine extends Thread {
private int MAXNODES_ISLAND_CHECK = 500; private int MAXNODES_ISLAND_CHECK = 500;
private OsmNodePairSet islandNodePairs = new OsmNodePairSet(MAXNODES_ISLAND_CHECK); private OsmNodePairSet islandNodePairs = new OsmNodePairSet(MAXNODES_ISLAND_CHECK);
private int engineMode = 0;
private int MAX_STEPS_CHECK = 10; private int MAX_STEPS_CHECK = 10;
protected OsmTrack foundTrack = new OsmTrack(); protected OsmTrack foundTrack = new OsmTrack();
private OsmTrack foundRawTrack = null; private OsmTrack foundRawTrack = null;
private int alternativeIndex = 0; private int alternativeIndex = 0;
protected String outputMessage = null;
protected String errorMessage = null; protected String errorMessage = null;
private volatile boolean terminated; private volatile boolean terminated;
@ -73,12 +81,18 @@ public class RoutingEngine extends Thread {
public RoutingEngine(String outfileBase, String logfileBase, File segmentDir, public RoutingEngine(String outfileBase, String logfileBase, File segmentDir,
List<OsmNodeNamed> waypoints, RoutingContext rc) { List<OsmNodeNamed> waypoints, RoutingContext rc) {
this(outfileBase, logfileBase, segmentDir, waypoints, rc, 0);
}
public RoutingEngine(String outfileBase, String logfileBase, File segmentDir,
List<OsmNodeNamed> waypoints, RoutingContext rc, int engineMode) {
this.segmentDir = segmentDir; this.segmentDir = segmentDir;
this.outfileBase = outfileBase; this.outfileBase = outfileBase;
this.logfileBase = logfileBase; this.logfileBase = logfileBase;
this.waypoints = waypoints; this.waypoints = waypoints;
this.infoLogEnabled = outfileBase != null; this.infoLogEnabled = outfileBase != null;
this.routingContext = rc; this.routingContext = rc;
this.engineMode = engineMode;
File baseFolder = new File(routingContext.localFunction).getParentFile(); File baseFolder = new File(routingContext.localFunction).getParentFile();
baseFolder = baseFolder == null ? null : baseFolder.getParentFile(); baseFolder = baseFolder == null ? null : baseFolder.getParentFile();
@ -105,6 +119,7 @@ public class RoutingEngine extends Thread {
if (hasInfo()) { if (hasInfo()) {
logInfo("parsed profile " + rc.localFunction + " cached=" + cachedProfile); logInfo("parsed profile " + rc.localFunction + " cached=" + cachedProfile);
} }
} }
private boolean hasInfo() { private boolean hasInfo() {
@ -138,6 +153,24 @@ public class RoutingEngine extends Thread {
} }
public void doRun(long maxRunningTime) { public void doRun(long maxRunningTime) {
switch (engineMode) {
case BROUTER_ENGINEMODE_ROUTING:
doRouting(maxRunningTime);
break;
case BROUTER_ENGINEMODE_SEED: /* do nothing, handled the old way */
break;
case BROUTER_ENGINEMODE_GETELEV:
doGetElev();
break;
default:
doRouting(maxRunningTime);
break;
}
}
public void doRouting(long maxRunningTime) {
try { try {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
long startTime0 = startTime; long startTime0 = startTime;
@ -237,6 +270,44 @@ public class RoutingEngine extends Thread {
} }
} }
public void doGetElev() {
try {
startTime = System.currentTimeMillis();
routingContext.turnInstructionMode = 9;
MatchedWaypoint wpt1 = new MatchedWaypoint();
wpt1.waypoint = waypoints.get(0);
wpt1.name = "wpt_info";
List<MatchedWaypoint> listOne = new ArrayList<>();
listOne.add(wpt1);
matchWaypointsToNodes(listOne);
resetCache(true);
nodesCache.nodesMap.cleanupMode = 0;
int dist_cn1 = listOne.get(0).crosspoint.calcDistance(listOne.get(0).node1);
int dist_cn2 = listOne.get(0).crosspoint.calcDistance(listOne.get(0).node2);
OsmNode startNode;
if (dist_cn1 < dist_cn2) {
startNode = nodesCache.getStartNode(listOne.get(0).node1.getIdFromPos());
} else {
startNode = nodesCache.getStartNode(listOne.get(0).node2.getIdFromPos());
}
OsmNodeNamed n = new OsmNodeNamed(listOne.get(0).crosspoint);
n.selev = startNode != null ? startNode.getSElev() : Short.MIN_VALUE;
outputMessage = OsmTrack.formatAsGpxWaypoint(n);
long endTime = System.currentTimeMillis();
logInfo("execution time = " + (endTime - startTime) / 1000. + " seconds");
} catch (Exception e) {
e.getStackTrace();
logException(e);
}
}
private void postElevationCheck(OsmTrack track) { private void postElevationCheck(OsmTrack track) {
OsmPathElement lastPt = null; OsmPathElement lastPt = null;
OsmPathElement startPt = null; OsmPathElement startPt = null;
@ -1543,6 +1614,10 @@ public class RoutingEngine extends Thread {
return foundTrack; return foundTrack;
} }
public String getFoundInfo() {
return outputMessage;
}
public int getAlternativeIndex() { public int getAlternativeIndex() {
return alternativeIndex; return alternativeIndex;
} }

View file

@ -34,6 +34,7 @@ interface IBRouterService {
// "timode" = turnInstructionMode [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] default 0 // "timode" = turnInstructionMode [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] default 0
// "heading" = angle (optional to give a route a start direction) // "heading" = angle (optional to give a route a start direction)
// "direction" = angle (optional, used like "heading" on a recalculation request by Locus as start direction) // "direction" = angle (optional, used like "heading" on a recalculation request by Locus as start direction)
// "engineMode" = 0 (optional, default 0, 2 = get elevation)
// return null if all ok and no path given, the track if ok and path given, an error message if it was wrong // return null if all ok and no path given, the track if ok and path given, an error message if it was wrong
// the resultas string when 'pathToFileResult' is null, this should be default when Android Q or later // the resultas string when 'pathToFileResult' is null, this should be default when Android Q or later

View file

@ -6,7 +6,6 @@ import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Base64; import android.util.Base64;
import android.util.Log;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -24,6 +23,7 @@ import java.util.List;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
import btools.router.RoutingEngine;
public class BRouterService extends Service { public class BRouterService extends Service {
@ -39,6 +39,15 @@ public class BRouterService extends Service {
BRouterWorker worker = new BRouterWorker(); BRouterWorker worker = new BRouterWorker();
for (String key : params.keySet()) {
// Log.d("BS", "income " + key + " = " + params.get(key));
}
int engineMode = 0;
if (params.containsKey("engineMode")) {
engineMode = params.getInt("engineMode", 0);
}
// get base dir from private file // get base dir from private file
String baseDir = null; String baseDir = null;
InputStream configInput = null; InputStream configInput = null;
@ -56,14 +65,15 @@ public class BRouterService extends Service {
} }
worker.baseDir = baseDir; worker.baseDir = baseDir;
worker.segmentDir = new File(baseDir, "brouter/segments4"); worker.segmentDir = new File(baseDir, "brouter/segments4");
String errMsg = null;
if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) {
String remoteProfile = params.getString("remoteProfile", null); String remoteProfile = params.getString("remoteProfile", null);
if (remoteProfile == null) { if (remoteProfile == null) {
remoteProfile = checkForTestDummy(baseDir); remoteProfile = checkForTestDummy(baseDir);
} }
String errMsg = null;
if (remoteProfile != null) { if (remoteProfile != null) {
errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile); errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile);
} else if (params.containsKey("profile")) { } else if (params.containsKey("profile")) {
@ -83,7 +93,9 @@ public class BRouterService extends Service {
} else { } else {
errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast")); errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast"));
} }
} else {
worker.profilePath = baseDir + "/brouter/profiles2/dummy.brf";
}
if (errMsg != null) { if (errMsg != null) {
return errMsg; return errMsg;
} }
@ -290,7 +302,6 @@ public class BRouterService extends Service {
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId) { public void onStart(Intent intent, int startId) {
Log.d(getClass().getSimpleName(), "onStart()");
handleStart(intent, startId); handleStart(intent, startId);
} }

View file

@ -33,6 +33,12 @@ public class BRouterWorker {
public String profileParams; public String profileParams;
public String getTrackFromParams(Bundle params) { public String getTrackFromParams(Bundle params) {
int engineMode = 0;
if (params.containsKey("engineMode")) {
engineMode = params.getInt("engineMode", 0);
}
String pathToFileResult = params.getString("pathToFileResult"); String pathToFileResult = params.getString("pathToFileResult");
if (pathToFileResult != null) { if (pathToFileResult != null) {
@ -97,7 +103,7 @@ public class BRouterWorker {
waypoints = readPositions(params); waypoints = readPositions(params);
} }
if (params.containsKey("lonlats")) { if (params.containsKey("lonlats")) {
waypoints = readLonlats(params); waypoints = readLonlats(params, engineMode);
} }
if (waypoints == null) return "no pts "; if (waypoints == null) return "no pts ";
@ -141,16 +147,16 @@ public class BRouterWorker {
} }
} }
try { try {
writeTimeoutData(rc); writeTimeoutData(rc);
} catch (Exception e) { } catch (Exception e) {
} }
RoutingEngine cr = new RoutingEngine(null, null, segmentDir, waypoints, rc); RoutingEngine cr = new RoutingEngine(null, null, segmentDir, waypoints, rc, engineMode);
cr.quite = true; cr.quite = true;
cr.doRun(maxRunningTime); cr.doRun(maxRunningTime);
if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) {
// store new reference track if any // store new reference track if any
// (can exist for timed-out search) // (can exist for timed-out search)
if (cr.getFoundRawTrack() != null) { if (cr.getFoundRawTrack() != null) {
@ -208,6 +214,12 @@ public class BRouterWorker {
return "error writing file: " + e; return "error writing file: " + e;
} }
} }
} else { // get other infos
if (cr.getErrorMessage() != null) {
return cr.getErrorMessage();
}
return cr.getFoundInfo();
}
return null; return null;
} }
@ -229,25 +241,31 @@ public class BRouterWorker {
wplist.add(n); wplist.add(n);
} }
if (wplist.get(0).name.startsWith("via")) wplist.get(0).name = "from"; if (wplist.get(0).name.startsWith("via")) wplist.get(0).name = "from";
if (wplist.get(wplist.size() - 1).name.startsWith("via")) wplist.get(wplist.size() - 1).name = "to"; if (wplist.get(wplist.size() - 1).name.startsWith("via"))
wplist.get(wplist.size() - 1).name = "to";
return wplist; return wplist;
} }
private List<OsmNodeNamed> readLonlats(Bundle params) { private List<OsmNodeNamed> readLonlats(Bundle params, int mode) {
List<OsmNodeNamed> wplist = new ArrayList<>(); List<OsmNodeNamed> wplist = new ArrayList<>();
String lonLats = params.getString("lonlats"); String lonLats = params.getString("lonlats");
if (lonLats == null) throw new IllegalArgumentException("lonlats parameter not set"); if (lonLats == null) throw new IllegalArgumentException("lonlats parameter not set");
String[] coords = lonLats.split("\\|"); String[] coords;
if (mode == 0) {
coords = lonLats.split("\\|");
if (coords.length < 2) if (coords.length < 2)
throw new IllegalArgumentException("we need two lat/lon points at least!"); throw new IllegalArgumentException("we need two lat/lon points at least!");
} else {
coords = new String[1];
coords[0] = lonLats;
}
for (int i = 0; i < coords.length; i++) { for (int i = 0; i < coords.length; i++) {
String[] lonLat = coords[i].split(","); String[] lonLat = coords[i].split(",");
if (lonLat.length < 2) if (lonLat.length < 2)
throw new IllegalArgumentException("we need two lat/lon points at least!"); throw new IllegalArgumentException("we need a lat and lon point at least!");
wplist.add(readPosition(lonLat[0], lonLat[1], "via" + i)); wplist.add(readPosition(lonLat[0], lonLat[1], "via" + i));
if (lonLat.length > 2) { if (lonLat.length > 2) {
if (lonLat[2].equals("d")) { if (lonLat[2].equals("d")) {
@ -259,7 +277,8 @@ public class BRouterWorker {
} }
if (wplist.get(0).name.startsWith("via")) wplist.get(0).name = "from"; if (wplist.get(0).name.startsWith("via")) wplist.get(0).name = "from";
if (wplist.get(wplist.size() - 1).name.startsWith("via")) wplist.get(wplist.size() - 1).name = "to"; if (wplist.get(wplist.size() - 1).name.startsWith("via"))
wplist.get(wplist.size() - 1).name = "to";
return wplist; return wplist;
} }

View file

@ -191,8 +191,11 @@ public class RouteServer extends Thread implements Comparable<RouteServer> {
if (wplist.size() < 10) { if (wplist.size() < 10) {
SuspectManager.nearRecentWps.add(wplist); SuspectManager.nearRecentWps.add(wplist);
} }
int engineMode = 0;
for (Map.Entry<String, String> e : params.entrySet()) { for (Map.Entry<String, String> e : params.entrySet()) {
if ("timode".equals(e.getKey())) { if ("engineMode".equals(e.getKey())) {
engineMode = Integer.parseInt(e.getValue());
} else if ("timode".equals(e.getKey())) {
rc.turnInstructionMode = Integer.parseInt(e.getValue()); rc.turnInstructionMode = Integer.parseInt(e.getValue());
} else if ("heading".equals(e.getKey())) { } else if ("heading".equals(e.getKey())) {
rc.startDirection = Integer.parseInt(e.getValue()); rc.startDirection = Integer.parseInt(e.getValue());
@ -210,7 +213,7 @@ public class RouteServer extends Thread implements Comparable<RouteServer> {
} }
} }
} }
cr = new RoutingEngine(null, null, serviceContext.segmentDir, wplist, rc); cr = new RoutingEngine(null, null, serviceContext.segmentDir, wplist, rc, engineMode);
cr.quite = true; cr.quite = true;
cr.doRun(maxRunningTime); cr.doRun(maxRunningTime);

View file

@ -44,3 +44,10 @@ This parameters are needed to tell BRouter what to do.
Profile parameters affect the result of a profile. Profile parameters affect the result of a profile.
For the app it is a list of params concatenated by '&'. E.g. extraParams=avoidferry=1&avoidsteps=0 For the app it is a list of params concatenated by '&'. E.g. extraParams=avoidferry=1&avoidsteps=0
The server calls profile params by a prefix 'profile:'. E.g. ...&profile:avoidferry=1&profile:avoidsteps=0 The server calls profile params by a prefix 'profile:'. E.g. ...&profile:avoidferry=1&profile:avoidsteps=0
## other routing engine modes in app
### get elevation
"engineMode=2" allows a client to only request an elevation for a point. This can be restricted with "waypointCatchingRange".

View file

@ -2,6 +2,18 @@
(ZIP-Archives including APK, readme + profiles) (ZIP-Archives including APK, readme + profiles)
### New since last version
Android
- Add parameter dialog for profile
Library
- Add new function 'get elevation'
- Minor bug fixes
### [brouter-1.7.0.zip](../brouter_bin/brouter-1.7.0.zip) (current revision, 29.04.2023) ### [brouter-1.7.0.zip](../brouter_bin/brouter-1.7.0.zip) (current revision, 29.04.2023)
Android Android