diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java
index 4d8da0d..9da73a1 100644
--- a/brouter-core/src/main/java/btools/router/OsmTrack.java
+++ b/brouter-core/src/main/java/btools/router/OsmTrack.java
@@ -839,6 +839,49 @@ public final class OsmTrack {
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("\n");
+ sb.append("\n");
+ }
+
+ static public void formatGpxFooter(BufferedWriter sb) throws IOException {
+ sb.append("\n");
+ }
+
+ static public void formatWaypointGpx(BufferedWriter sb, OsmNodeNamed n) throws IOException {
+ sb.append(" ");
+ if (n.getSElev() != Short.MIN_VALUE) {
+ sb.append("").append("" + n.getElev()).append("");
+ }
+ if (n.name != null) {
+ sb.append("").append(StringUtils.escapeXml10(n.name)).append("");
+ }
+ if (n.nodeDescription != null) {
+ sb.append("").append("hat desc").append("");
+ }
+ sb.append("\n");
+ }
+
public void writeKml(String filename) throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java
index c731b5c..1681387 100644
--- a/brouter-core/src/main/java/btools/router/RoutingEngine.java
+++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java
@@ -25,6 +25,11 @@ import btools.util.SortedHeap;
import btools.util.StackSampler;
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 SortedHeap openSet = new SortedHeap<>();
private boolean finished = false;
@@ -37,12 +42,15 @@ public class RoutingEngine extends Thread {
private int MAXNODES_ISLAND_CHECK = 500;
private OsmNodePairSet islandNodePairs = new OsmNodePairSet(MAXNODES_ISLAND_CHECK);
+ private int engineMode = 0;
+
private int MAX_STEPS_CHECK = 10;
protected OsmTrack foundTrack = new OsmTrack();
private OsmTrack foundRawTrack = null;
private int alternativeIndex = 0;
+ protected String outputMessage = null;
protected String errorMessage = null;
private volatile boolean terminated;
@@ -73,12 +81,18 @@ public class RoutingEngine extends Thread {
public RoutingEngine(String outfileBase, String logfileBase, File segmentDir,
List waypoints, RoutingContext rc) {
+ this(outfileBase, logfileBase, segmentDir, waypoints, rc, 0);
+ }
+
+ public RoutingEngine(String outfileBase, String logfileBase, File segmentDir,
+ List waypoints, RoutingContext rc, int engineMode) {
this.segmentDir = segmentDir;
this.outfileBase = outfileBase;
this.logfileBase = logfileBase;
this.waypoints = waypoints;
this.infoLogEnabled = outfileBase != null;
this.routingContext = rc;
+ this.engineMode = engineMode;
File baseFolder = new File(routingContext.localFunction).getParentFile();
baseFolder = baseFolder == null ? null : baseFolder.getParentFile();
@@ -105,6 +119,7 @@ public class RoutingEngine extends Thread {
if (hasInfo()) {
logInfo("parsed profile " + rc.localFunction + " cached=" + cachedProfile);
}
+
}
private boolean hasInfo() {
@@ -138,6 +153,24 @@ public class RoutingEngine extends Thread {
}
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 {
startTime = System.currentTimeMillis();
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 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) {
OsmPathElement lastPt = null;
OsmPathElement startPt = null;
@@ -1543,6 +1614,10 @@ public class RoutingEngine extends Thread {
return foundTrack;
}
+ public String getFoundInfo() {
+ return outputMessage;
+ }
+
public int getAlternativeIndex() {
return alternativeIndex;
}
diff --git a/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl b/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl
index ed1dde7..bfd2f81 100644
--- a/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl
+++ b/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl
@@ -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
// "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)
+ // "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
// the resultas string when 'pathToFileResult' is null, this should be default when Android Q or later
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java
index b2429a0..95dbadd 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java
@@ -6,7 +6,6 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Base64;
-import android.util.Log;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
@@ -24,6 +23,7 @@ import java.util.List;
import java.util.zip.GZIPOutputStream;
import btools.router.OsmNodeNamed;
+import btools.router.RoutingEngine;
public class BRouterService extends Service {
@@ -39,6 +39,15 @@ public class BRouterService extends Service {
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
String baseDir = null;
InputStream configInput = null;
@@ -56,34 +65,37 @@ public class BRouterService extends Service {
}
worker.baseDir = baseDir;
worker.segmentDir = new File(baseDir, "brouter/segments4");
-
- String remoteProfile = params.getString("remoteProfile", null);
-
- if (remoteProfile == null) {
- remoteProfile = checkForTestDummy(baseDir);
- }
-
String errMsg = null;
- if (remoteProfile != null) {
- errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile);
- } else if (params.containsKey("profile")) {
- String profile = params.getString("profile");
- worker.profileName = profile;
- worker.profilePath = baseDir + "/brouter/profiles2/" + profile + ".brf";
- worker.rawTrackPath = baseDir + "/brouter/modes/" + profile + "_rawtrack.dat";
- if (!new File(worker.profilePath).exists()) {
- errMsg = "Profile " + profile + " does not exists";
- } else {
- try {
- readNogos(worker, baseDir);
- } catch (Exception e) {
- errMsg = e.getLocalizedMessage();
+
+ if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) {
+ String remoteProfile = params.getString("remoteProfile", null);
+
+ if (remoteProfile == null) {
+ remoteProfile = checkForTestDummy(baseDir);
+ }
+
+ if (remoteProfile != null) {
+ errMsg = getConfigForRemoteProfile(worker, baseDir, remoteProfile);
+ } else if (params.containsKey("profile")) {
+ String profile = params.getString("profile");
+ worker.profileName = profile;
+ worker.profilePath = baseDir + "/brouter/profiles2/" + profile + ".brf";
+ worker.rawTrackPath = baseDir + "/brouter/modes/" + profile + "_rawtrack.dat";
+ if (!new File(worker.profilePath).exists()) {
+ errMsg = "Profile " + profile + " does not exists";
+ } else {
+ try {
+ readNogos(worker, baseDir);
+ } catch (Exception e) {
+ errMsg = e.getLocalizedMessage();
+ }
}
+ } else {
+ errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast"));
}
} else {
- errMsg = getConfigFromMode(worker, baseDir, params.getString("v"), params.getString("fast"));
+ worker.profilePath = baseDir + "/brouter/profiles2/dummy.brf";
}
-
if (errMsg != null) {
return errMsg;
}
@@ -121,7 +133,7 @@ public class BRouterService extends Service {
try {
String modesFile = baseDir + "/brouter/modes/serviceconfig.dat";
br = new BufferedReader(new FileReader(modesFile));
- for (;;) {
+ for (; ; ) {
String line = br.readLine();
if (line == null)
break;
@@ -244,7 +256,7 @@ public class BRouterService extends Service {
StringBuilder sb = new StringBuilder();
try {
br = new BufferedReader(new FileReader(testdummy));
- for (;;) {
+ for (; ; ) {
String line = br.readLine();
if (line == null)
break;
@@ -290,7 +302,6 @@ public class BRouterService extends Service {
@Override
@SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId) {
- Log.d(getClass().getSimpleName(), "onStart()");
handleStart(intent, startId);
}
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
index 4543b8d..e140561 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
@@ -33,6 +33,12 @@ public class BRouterWorker {
public String profileParams;
public String getTrackFromParams(Bundle params) {
+
+ int engineMode = 0;
+ if (params.containsKey("engineMode")) {
+ engineMode = params.getInt("engineMode", 0);
+ }
+
String pathToFileResult = params.getString("pathToFileResult");
if (pathToFileResult != null) {
@@ -97,7 +103,7 @@ public class BRouterWorker {
waypoints = readPositions(params);
}
if (params.containsKey("lonlats")) {
- waypoints = readLonlats(params);
+ waypoints = readLonlats(params, engineMode);
}
if (waypoints == null) return "no pts ";
@@ -141,72 +147,78 @@ public class BRouterWorker {
}
}
-
try {
writeTimeoutData(rc);
} 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.doRun(maxRunningTime);
- // store new reference track if any
- // (can exist for timed-out search)
- if (cr.getFoundRawTrack() != null) {
- try {
- cr.getFoundRawTrack().writeBinary(rawTrackPath);
- } catch (Exception e) {
- }
- }
-
- if (cr.getErrorMessage() != null) {
- return cr.getErrorMessage();
- }
-
- String format = params.getString("trackFormat");
- int writeFromat = OUTPUT_FORMAT_GPX;
- if (format != null) {
- if ("kml".equals(format)) writeFromat = OUTPUT_FORMAT_KML;
- if ("json".equals(format)) writeFromat = OUTPUT_FORMAT_JSON;
- }
-
- OsmTrack track = cr.getFoundTrack();
- if (track != null) {
- if (params.containsKey("exportWaypoints")) {
- track.exportWaypoints = (params.getInt("exportWaypoints", 0) == 1);
- }
- if (pathToFileResult == null) {
- switch (writeFromat) {
- case OUTPUT_FORMAT_GPX:
- return track.formatAsGpx();
- case OUTPUT_FORMAT_KML:
- return track.formatAsKml();
- case OUTPUT_FORMAT_JSON:
- return track.formatAsGeoJson();
- default:
- return track.formatAsGpx();
+ if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) {
+ // store new reference track if any
+ // (can exist for timed-out search)
+ if (cr.getFoundRawTrack() != null) {
+ try {
+ cr.getFoundRawTrack().writeBinary(rawTrackPath);
+ } catch (Exception e) {
}
+ }
+ if (cr.getErrorMessage() != null) {
+ return cr.getErrorMessage();
}
- try {
- switch (writeFromat) {
- case OUTPUT_FORMAT_GPX:
- track.writeGpx(pathToFileResult);
- break;
- case OUTPUT_FORMAT_KML:
- track.writeKml(pathToFileResult);
- break;
- case OUTPUT_FORMAT_JSON:
- track.writeJson(pathToFileResult);
- break;
- default:
- track.writeGpx(pathToFileResult);
- break;
+
+ String format = params.getString("trackFormat");
+ int writeFromat = OUTPUT_FORMAT_GPX;
+ if (format != null) {
+ if ("kml".equals(format)) writeFromat = OUTPUT_FORMAT_KML;
+ if ("json".equals(format)) writeFromat = OUTPUT_FORMAT_JSON;
+ }
+
+ OsmTrack track = cr.getFoundTrack();
+ if (track != null) {
+ if (params.containsKey("exportWaypoints")) {
+ track.exportWaypoints = (params.getInt("exportWaypoints", 0) == 1);
+ }
+ if (pathToFileResult == null) {
+ switch (writeFromat) {
+ case OUTPUT_FORMAT_GPX:
+ return track.formatAsGpx();
+ case OUTPUT_FORMAT_KML:
+ return track.formatAsKml();
+ case OUTPUT_FORMAT_JSON:
+ return track.formatAsGeoJson();
+ default:
+ return track.formatAsGpx();
+ }
+
+ }
+ try {
+ switch (writeFromat) {
+ case OUTPUT_FORMAT_GPX:
+ track.writeGpx(pathToFileResult);
+ break;
+ case OUTPUT_FORMAT_KML:
+ track.writeKml(pathToFileResult);
+ break;
+ case OUTPUT_FORMAT_JSON:
+ track.writeJson(pathToFileResult);
+ break;
+ default:
+ track.writeGpx(pathToFileResult);
+ break;
+ }
+ } catch (Exception e) {
+ return "error writing file: " + e;
}
- } catch (Exception e) {
- return "error writing file: " + e;
}
+ } else { // get other infos
+ if (cr.getErrorMessage() != null) {
+ return cr.getErrorMessage();
+ }
+ return cr.getFoundInfo();
}
return null;
}
@@ -229,25 +241,31 @@ public class BRouterWorker {
wplist.add(n);
}
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;
}
- private List readLonlats(Bundle params) {
+ private List readLonlats(Bundle params, int mode) {
List wplist = new ArrayList<>();
String lonLats = params.getString("lonlats");
if (lonLats == null) throw new IllegalArgumentException("lonlats parameter not set");
- String[] coords = lonLats.split("\\|");
- if (coords.length < 2)
- throw new IllegalArgumentException("we need two lat/lon points at least!");
-
+ String[] coords;
+ if (mode == 0) {
+ coords = lonLats.split("\\|");
+ if (coords.length < 2)
+ 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++) {
String[] lonLat = coords[i].split(",");
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));
if (lonLat.length > 2) {
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(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;
}
diff --git a/brouter-server/src/main/java/btools/server/RouteServer.java b/brouter-server/src/main/java/btools/server/RouteServer.java
index 9ac91d9..c0e5846 100644
--- a/brouter-server/src/main/java/btools/server/RouteServer.java
+++ b/brouter-server/src/main/java/btools/server/RouteServer.java
@@ -191,8 +191,11 @@ public class RouteServer extends Thread implements Comparable {
if (wplist.size() < 10) {
SuspectManager.nearRecentWps.add(wplist);
}
+ int engineMode = 0;
for (Map.Entry 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());
} else if ("heading".equals(e.getKey())) {
rc.startDirection = Integer.parseInt(e.getValue());
@@ -210,7 +213,7 @@ public class RouteServer extends Thread implements Comparable {
}
}
}
- cr = new RoutingEngine(null, null, serviceContext.segmentDir, wplist, rc);
+ cr = new RoutingEngine(null, null, serviceContext.segmentDir, wplist, rc, engineMode);
cr.quite = true;
cr.doRun(maxRunningTime);
diff --git a/docs/developers/android_service.md b/docs/developers/android_service.md
index 52159a7..36da40c 100644
--- a/docs/developers/android_service.md
+++ b/docs/developers/android_service.md
@@ -44,3 +44,10 @@ This parameters are needed to tell BRouter what to do.
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
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".
diff --git a/docs/revisions.md b/docs/revisions.md
index 600cc0c..d30070d 100644
--- a/docs/revisions.md
+++ b/docs/revisions.md
@@ -2,6 +2,18 @@
(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)
Android