Merge pull request #755 from afischerdev/getinfo

Get elevation expanded, added get info
This commit is contained in:
afischerdev 2025-01-20 17:43:27 +01:00 committed by GitHub
commit 147745999a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 123 additions and 52 deletions

View File

@ -197,10 +197,7 @@ public class FormatGpx extends Formatter {
for (int i = 0; i <= t.pois.size() - 1; i++) { for (int i = 0; i <= t.pois.size() - 1; i++) {
OsmNodeNamed poi = t.pois.get(i); OsmNodeNamed poi = t.pois.get(i);
sb.append(" <wpt lon=\"").append(formatILon(poi.ilon)).append("\" lat=\"") formatWaypointGpx(sb, poi);
.append(formatILat(poi.ilat)).append("\">\n")
.append(" <name>").append(StringUtils.escapeXml10(poi.name)).append("</name>\n")
.append(" </wpt>\n");
} }
if (t.exportWaypoints) { if (t.exportWaypoints) {

View File

@ -130,8 +130,8 @@ public class FormatJson extends Formatter {
sb.append(" },\n"); sb.append(" },\n");
for (int i = 0; i <= t.pois.size() - 1; i++) { for (int i = 0; i <= t.pois.size() - 1; i++) {
OsmNodeNamed poi = t.pois.get(i); OsmNodeNamed poi = t.pois.get(i);
addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon); addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon, poi.getSElev());
if (i < t.matchedWaypoints.size() - 1) { if (i < t.pois.size() - 1) {
sb.append(","); sb.append(",");
} }
sb.append(" \n"); sb.append(" \n");
@ -148,7 +148,7 @@ public class FormatJson extends Formatter {
} }
MatchedWaypoint wp = t.matchedWaypoints.get(i); MatchedWaypoint wp = t.matchedWaypoints.get(i);
addFeature(sb, type, wp.name, wp.waypoint.ilat, wp.waypoint.ilon); addFeature(sb, type, wp.name, wp.waypoint.ilat, wp.waypoint.ilon, wp.waypoint.getSElev());
if (i < t.matchedWaypoints.size() - 1) { if (i < t.matchedWaypoints.size() - 1) {
sb.append(","); sb.append(",");
} }
@ -164,7 +164,7 @@ public class FormatJson extends Formatter {
return sb.toString(); return sb.toString();
} }
private void addFeature(StringBuilder sb, String type, String name, int ilat, int ilon) { private void addFeature(StringBuilder sb, String type, String name, int ilat, int ilon, short selev) {
sb.append(" {\n"); sb.append(" {\n");
sb.append(" \"type\": \"Feature\",\n"); sb.append(" \"type\": \"Feature\",\n");
sb.append(" \"properties\": {\n"); sb.append(" \"properties\": {\n");
@ -175,7 +175,7 @@ public class FormatJson extends Formatter {
sb.append(" \"type\": \"Point\",\n"); sb.append(" \"type\": \"Point\",\n");
sb.append(" \"coordinates\": [\n"); sb.append(" \"coordinates\": [\n");
sb.append(" " + formatILon(ilon) + ",\n"); sb.append(" " + formatILon(ilon) + ",\n");
sb.append(" " + formatILat(ilat) + "\n"); sb.append(" " + formatILat(ilat) + (selev != Short.MIN_VALUE ? ",\n " + selev / 4. : "") + "\n");
sb.append(" ]\n"); sb.append(" ]\n");
sb.append(" }\n"); sb.append(" }\n");
sb.append(" }"); sb.append(" }");

View File

@ -172,10 +172,15 @@ public final class RoutingContext {
useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 1f; useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 1f;
boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f; boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f;
if (!test) expctxGlobal.freeNoWays(); if (!test) freeNoWays();
} }
public void freeNoWays() {
BExpressionContext expctxGlobal = expctxWay;
if (expctxGlobal != null) expctxGlobal.freeNoWays();
}
public List<OsmNodeNamed> poipoints; public List<OsmNodeNamed> poipoints;
public List<OsmNodeNamed> nogopoints = null; public List<OsmNodeNamed> nogopoints = null;

View File

@ -30,6 +30,7 @@ public class RoutingEngine extends Thread {
public final static int BROUTER_ENGINEMODE_ROUTING = 0; public final static int BROUTER_ENGINEMODE_ROUTING = 0;
public final static int BROUTER_ENGINEMODE_SEED = 1; public final static int BROUTER_ENGINEMODE_SEED = 1;
public final static int BROUTER_ENGINEMODE_GETELEV = 2; public final static int BROUTER_ENGINEMODE_GETELEV = 2;
public final static int BROUTER_ENGINEMODE_GETINFO = 3;
private NodesCache nodesCache; private NodesCache nodesCache;
private SortedHeap<OsmPath> openSet = new SortedHeap<>(); private SortedHeap<OsmPath> openSet = new SortedHeap<>();
@ -171,10 +172,11 @@ public class RoutingEngine extends Thread {
case BROUTER_ENGINEMODE_SEED: /* do nothing, handled the old way */ case BROUTER_ENGINEMODE_SEED: /* do nothing, handled the old way */
throw new IllegalArgumentException("not a valid engine mode"); throw new IllegalArgumentException("not a valid engine mode");
case BROUTER_ENGINEMODE_GETELEV: case BROUTER_ENGINEMODE_GETELEV:
case BROUTER_ENGINEMODE_GETINFO:
if (waypoints.size() < 1) { if (waypoints.size() < 1) {
throw new IllegalArgumentException("we need one lat/lon point at least!"); throw new IllegalArgumentException("we need one lat/lon point at least!");
} }
doGetElev(); doGetInfo();
break; break;
default: default:
throw new IllegalArgumentException("not a valid engine mode"); throw new IllegalArgumentException("not a valid engine mode");
@ -321,11 +323,12 @@ public class RoutingEngine extends Thread {
} }
} }
public void doGetElev() { public void doGetInfo() {
try { try {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
routingContext.turnInstructionMode = 9; routingContext.freeNoWays();
MatchedWaypoint wpt1 = new MatchedWaypoint(); MatchedWaypoint wpt1 = new MatchedWaypoint();
wpt1.waypoint = waypoints.get(0); wpt1.waypoint = waypoints.get(0);
wpt1.name = "wpt_info"; wpt1.name = "wpt_info";
@ -336,44 +339,105 @@ public class RoutingEngine extends Thread {
resetCache(true); resetCache(true);
nodesCache.nodesMap.cleanupMode = 0; nodesCache.nodesMap.cleanupMode = 0;
int dist_cn1 = listOne.get(0).crosspoint.calcDistance(listOne.get(0).node1); OsmNode start1 = nodesCache.getGraphNode(listOne.get(0).node1);
int dist_cn2 = listOne.get(0).crosspoint.calcDistance(listOne.get(0).node2); boolean b = nodesCache.obtainNonHollowNode(start1);
OsmNode startNode; guideTrack = new OsmTrack();
if (dist_cn1 < dist_cn2) { guideTrack.addNode(OsmPathElement.create(wpt1.node2.ilon, wpt1.node2.ilat, (short) 0, null));
startNode = nodesCache.getStartNode(listOne.get(0).node1.getIdFromPos()); guideTrack.addNode(OsmPathElement.create(wpt1.node1.ilon, wpt1.node1.ilat, (short) 0, null));
} else {
startNode = nodesCache.getStartNode(listOne.get(0).node2.getIdFromPos());
}
OsmNodeNamed n = new OsmNodeNamed(listOne.get(0).crosspoint); matchedWaypoints = new ArrayList<>();
n.selev = startNode != null ? startNode.getSElev() : Short.MIN_VALUE; MatchedWaypoint wp1 = new MatchedWaypoint();
wp1.crosspoint = new OsmNode(wpt1.node1.ilon, wpt1.node1.ilat);
wp1.node1 = new OsmNode(wpt1.node1.ilon, wpt1.node1.ilat);
wp1.node2 = new OsmNode(wpt1.node2.ilon, wpt1.node2.ilat);
matchedWaypoints.add(wp1);
MatchedWaypoint wp2 = new MatchedWaypoint();
wp2.crosspoint = new OsmNode(wpt1.node2.ilon, wpt1.node2.ilat);
wp2.node1 = new OsmNode(wpt1.node1.ilon, wpt1.node1.ilat);
wp2.node2 = new OsmNode(wpt1.node2.ilon, wpt1.node2.ilat);
matchedWaypoints.add(wp2);
switch (routingContext.outputFormat) { OsmTrack t = findTrack("getinfo", wp1, wp2, null, null, false);
case "gpx": if (t != null) {
outputMessage = new FormatGpx(routingContext).formatAsWaypoint(n); t.messageList = new ArrayList<>();
break; t.matchedWaypoints = matchedWaypoints;
case "geojson": t.name = (outfileBase == null ? "getinfo" : outfileBase);
case "json":
outputMessage = new FormatJson(routingContext).formatAsWaypoint(n); // find nearest point
break; int mindist = 99999;
case "kml": int minIdx = -1;
case "csv": for (int i = 0; i < t.nodes.size(); i++) {
default: OsmPathElement ope = t.nodes.get(i);
outputMessage = null; int dist = ope.calcDistance(listOne.get(0).crosspoint);
break; if (mindist > dist) {
} mindist = dist;
if (outfileBase != null) { minIdx = i;
String filename = outfileBase + "." + routingContext.outputFormat; }
File out = new File(filename);
FileWriter fw = new FileWriter(filename);
fw.write(outputMessage);
fw.close();
outputMessage = null;
} else {
if (!quite && outputMessage != null) {
System.out.println(outputMessage);
} }
int otherIdx = 0;
if (minIdx == t.nodes.size()-1) {
otherIdx = minIdx-1;
} else {
otherIdx = minIdx+1;
}
int otherdist = t.nodes.get(otherIdx).calcDistance(listOne.get(0).crosspoint);
int minSElev = t.nodes.get(minIdx).getSElev();
int otherSElev = t.nodes.get(otherIdx).getSElev();
int diffSElev = 0;
diffSElev = otherSElev - minSElev;
double diff = (double) mindist/(mindist + otherdist) * diffSElev;
OsmNodeNamed n = new OsmNodeNamed(listOne.get(0).crosspoint);
n.name = wpt1.name;
n.selev = minIdx != -1 ? (short) (minSElev + (int) diff) : Short.MIN_VALUE;
if (engineMode == BROUTER_ENGINEMODE_GETINFO) {
n.nodeDescription = (start1 != null && start1.firstlink!=null ? start1.firstlink.descriptionBitmap : null);
t.pois.add(n);
//t.message = "get_info";
//t.messageList.add(t.message);
t.matchedWaypoints = listOne;
t.exportWaypoints = routingContext.exportWaypoints;
}
switch (routingContext.outputFormat) {
case "gpx":
if (engineMode == BROUTER_ENGINEMODE_GETELEV) {
outputMessage = new FormatGpx(routingContext).formatAsWaypoint(n);
} else {
outputMessage = new FormatGpx(routingContext).format(t);
}
break;
case "geojson":
case "json":
if (engineMode == BROUTER_ENGINEMODE_GETELEV) {
outputMessage = new FormatJson(routingContext).formatAsWaypoint(n);
} else {
outputMessage = new FormatJson(routingContext).format(t);
}
break;
case "kml":
case "csv":
default:
outputMessage = null;
break;
}
if (outfileBase != null) {
String filename = outfileBase + "." + routingContext.outputFormat;
File out = new File(filename);
FileWriter fw = new FileWriter(filename);
fw.write(outputMessage);
fw.close();
outputMessage = null;
} else {
if (!quite && outputMessage != null) {
System.out.println(outputMessage);
}
}
} else {
if (errorMessage == null) errorMessage = "no track found";
} }
long endTime = System.currentTimeMillis(); long endTime = System.currentTimeMillis();
logInfo("execution time = " + (endTime - startTime) / 1000. + " seconds"); logInfo("execution time = " + (endTime - startTime) / 1000. + " seconds");
@ -630,7 +694,7 @@ public class RoutingEngine extends Thread {
} }
for (MatchedWaypoint mwp : matchedWaypoints) { for (MatchedWaypoint mwp : matchedWaypoints) {
if (hasInfo()) logInfo("new wp=" + mwp.waypoint + " " + mwp.crosspoint + (mwp.direct ? " direct" : "")); if (hasInfo() && matchedWaypoints.size() != nUnmatched) logInfo("new wp=" + mwp.waypoint + " " + mwp.crosspoint + (mwp.direct ? " direct" : ""));
} }
routingContext.checkMatchedWaypointAgainstNogos(matchedWaypoints); routingContext.checkMatchedWaypointAgainstNogos(matchedWaypoints);

View File

@ -35,7 +35,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) // "engineMode" = 0 (optional, default 0, 2 = get elevation, 3 = get segment info)
// 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

@ -102,7 +102,8 @@ public class BRouter {
} }
try { try {
RoutingEngine re = null; RoutingEngine re = null;
if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_GETELEV) { if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_GETELEV ||
engineMode == RoutingEngine.BROUTER_ENGINEMODE_GETINFO) {
re = new RoutingEngine("testinfo", null, new File(args[0]), wplist, rc, engineMode); re = new RoutingEngine("testinfo", null, new File(args[0]), wplist, rc, engineMode);
} else { } else {
re = new RoutingEngine("testtrack", null, new File(args[0]), wplist, rc, engineMode); re = new RoutingEngine("testtrack", null, new File(args[0]), wplist, rc, engineMode);

View File

@ -131,4 +131,8 @@ This suppress the first question after installation for the BRouter path, genera
### get elevation ### get elevation
"engineMode=2" allows a client to only request an elevation for a point. This can be restricted with "waypointCatchingRange". "engineMode=2" allows a client to request only an elevation for a point. This can be restricted with "waypointCatchingRange".
### get info
"engineMode=3" allows a client to request the description tags for a segment. This can be restricted with "waypointCatchingRange".