From c8aab5d4db86de235c056d2c22384ad0039500d6 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Mon, 13 Jan 2025 17:53:21 +0100 Subject: [PATCH 1/3] get elevation expanded, added get info --- .../main/java/btools/router/FormatGpx.java | 5 +- .../main/java/btools/router/FormatJson.java | 10 +- .../java/btools/router/RoutingEngine.java | 138 +++++++++++++----- .../src/main/java/btools/server/BRouter.java | 5 +- 4 files changed, 109 insertions(+), 49 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/FormatGpx.java b/brouter-core/src/main/java/btools/router/FormatGpx.java index 582cb4425..c652a0ac9 100644 --- a/brouter-core/src/main/java/btools/router/FormatGpx.java +++ b/brouter-core/src/main/java/btools/router/FormatGpx.java @@ -197,10 +197,7 @@ public String formatAsGpx(BufferedWriter sb, OsmTrack t) throws IOException { for (int i = 0; i <= t.pois.size() - 1; i++) { OsmNodeNamed poi = t.pois.get(i); - sb.append(" \n") - .append(" ").append(StringUtils.escapeXml10(poi.name)).append("\n") - .append(" \n"); + formatWaypointGpx(sb, poi); } if (t.exportWaypoints) { diff --git a/brouter-core/src/main/java/btools/router/FormatJson.java b/brouter-core/src/main/java/btools/router/FormatJson.java index 3c52d9a7b..53f0b4a43 100644 --- a/brouter-core/src/main/java/btools/router/FormatJson.java +++ b/brouter-core/src/main/java/btools/router/FormatJson.java @@ -130,8 +130,8 @@ public String format(OsmTrack t) { sb.append(" },\n"); for (int i = 0; i <= t.pois.size() - 1; i++) { OsmNodeNamed poi = t.pois.get(i); - addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon); - if (i < t.matchedWaypoints.size() - 1) { + addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon, poi.getSElev()); + if (i < t.pois.size() - 1) { sb.append(","); } sb.append(" \n"); @@ -148,7 +148,7 @@ public String format(OsmTrack t) { } 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) { sb.append(","); } @@ -164,7 +164,7 @@ public String format(OsmTrack t) { 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(" \"type\": \"Feature\",\n"); sb.append(" \"properties\": {\n"); @@ -175,7 +175,7 @@ private void addFeature(StringBuilder sb, String type, String name, int ilat, in sb.append(" \"type\": \"Point\",\n"); sb.append(" \"coordinates\": [\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(" }"); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 1c9adad95..0cd4a18dd 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -30,6 +30,7 @@ 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; + public final static int BROUTER_ENGINEMODE_GETINFO = 3; private NodesCache nodesCache; private SortedHeap openSet = new SortedHeap<>(); @@ -171,10 +172,11 @@ public void doRun(long maxRunningTime) { case BROUTER_ENGINEMODE_SEED: /* do nothing, handled the old way */ throw new IllegalArgumentException("not a valid engine mode"); case BROUTER_ENGINEMODE_GETELEV: + case BROUTER_ENGINEMODE_GETINFO: if (waypoints.size() < 1) { throw new IllegalArgumentException("we need one lat/lon point at least!"); } - doGetElev(); + doGetInfo(); break; default: throw new IllegalArgumentException("not a valid engine mode"); @@ -321,11 +323,10 @@ public void doRouting(long maxRunningTime) { } } - public void doGetElev() { + public void doGetInfo() { try { startTime = System.currentTimeMillis(); - routingContext.turnInstructionMode = 9; MatchedWaypoint wpt1 = new MatchedWaypoint(); wpt1.waypoint = waypoints.get(0); wpt1.name = "wpt_info"; @@ -336,44 +337,105 @@ public void doGetElev() { 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 start1 = nodesCache.getGraphNode(listOne.get(0).node1); + boolean b = nodesCache.obtainNonHollowNode(start1); - OsmNode startNode; - if (dist_cn1 < dist_cn2) { - startNode = nodesCache.getStartNode(listOne.get(0).node1.getIdFromPos()); - } else { - startNode = nodesCache.getStartNode(listOne.get(0).node2.getIdFromPos()); - } + guideTrack = new OsmTrack(); + guideTrack.addNode(OsmPathElement.create(wpt1.node2.ilon, wpt1.node2.ilat, (short) 0, null)); + guideTrack.addNode(OsmPathElement.create(wpt1.node1.ilon, wpt1.node1.ilat, (short) 0, null)); - OsmNodeNamed n = new OsmNodeNamed(listOne.get(0).crosspoint); - n.selev = startNode != null ? startNode.getSElev() : Short.MIN_VALUE; - - switch (routingContext.outputFormat) { - case "gpx": - outputMessage = new FormatGpx(routingContext).formatAsWaypoint(n); - break; - case "geojson": - case "json": - outputMessage = new FormatJson(routingContext).formatAsWaypoint(n); - break; - case "kml": - case "csv": - default: + matchedWaypoints = new ArrayList<>(); + 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); + + OsmTrack t = findTrack("getinfo", wp1, wp2, null, null, false); + if (t != null) { + t.messageList = new ArrayList<>(); + t.matchedWaypoints = matchedWaypoints; + t.name = (outfileBase == null ? "getinfo" : outfileBase); + + // find nearest point + int mindist = 99999; + int minIdx = -1; + for (int i = 0; i < t.nodes.size(); i++) { + OsmPathElement ope = t.nodes.get(i); + int dist = ope.calcDistance(listOne.get(0).crosspoint); + if (mindist > dist) { + mindist = dist; + minIdx = i; + } + } + 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; - 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 (!quite && outputMessage != null) { + System.out.println(outputMessage); + } } + + } else { + if (errorMessage == null) errorMessage = "no track found"; } long endTime = System.currentTimeMillis(); logInfo("execution time = " + (endTime - startTime) / 1000. + " seconds"); @@ -630,7 +692,7 @@ private OsmTrack tryFindTrack(OsmTrack[] refTracks, OsmTrack[] lastTracks) { } 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); diff --git a/brouter-server/src/main/java/btools/server/BRouter.java b/brouter-server/src/main/java/btools/server/BRouter.java index a6dfe1037..308dab732 100644 --- a/brouter-server/src/main/java/btools/server/BRouter.java +++ b/brouter-server/src/main/java/btools/server/BRouter.java @@ -102,7 +102,8 @@ public static void main(String[] args) throws Exception { } try { 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); } else { re = new RoutingEngine("testtrack", null, new File(args[0]), wplist, rc, engineMode); @@ -111,7 +112,7 @@ public static void main(String[] args) throws Exception { } catch (Exception e) { System.out.println(e.getMessage()); } - + } From 6f83e2e9c4bc4a3b7534272eeda7168107aac911 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Mon, 13 Jan 2025 17:53:55 +0100 Subject: [PATCH 2/3] added some doc entries --- .../src/main/aidl/btools/routingapp/IBRouterService.aidl | 2 +- docs/developers/android_service.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) 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 b233082df..0e35a7927 100644 --- a/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl +++ b/brouter-routing-app/src/main/aidl/btools/routingapp/IBRouterService.aidl @@ -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 // "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) + // "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 // the resultas string when 'pathToFileResult' is null, this should be default when Android Q or later diff --git a/docs/developers/android_service.md b/docs/developers/android_service.md index 5bbc47535..cd45a5efd 100644 --- a/docs/developers/android_service.md +++ b/docs/developers/android_service.md @@ -131,4 +131,8 @@ This suppress the first question after installation for the BRouter path, genera ### 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". From 068eda48adc0503219bf8b6f167717d442e6899e Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 14 Jan 2025 11:38:45 +0100 Subject: [PATCH 3/3] protect against start way logic --- .../src/main/java/btools/router/RoutingContext.java | 7 ++++++- .../src/main/java/btools/router/RoutingEngine.java | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 0d6d3b570..2559f3a03 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -172,10 +172,15 @@ public void readGlobalConfig() { useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 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 poipoints; public List nogopoints = null; diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 0cd4a18dd..14fa36f63 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -327,6 +327,8 @@ public void doGetInfo() { try { startTime = System.currentTimeMillis(); + routingContext.freeNoWays(); + MatchedWaypoint wpt1 = new MatchedWaypoint(); wpt1.waypoint = waypoints.get(0); wpt1.name = "wpt_info";