From a55bef904f0189c0f0241354b5e1aafa8fc54803 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 12 Sep 2024 11:46:51 +0200 Subject: [PATCH 1/9] enable empty node list --- brouter-core/src/main/java/btools/router/FormatJson.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brouter-core/src/main/java/btools/router/FormatJson.java b/brouter-core/src/main/java/btools/router/FormatJson.java index a2c5b7a..dc7dcd4 100644 --- a/brouter-core/src/main/java/btools/router/FormatJson.java +++ b/brouter-core/src/main/java/btools/router/FormatJson.java @@ -122,7 +122,7 @@ public class FormatJson extends Formatter { .append(sele).append("],\n"); nn = n; } - sb.deleteCharAt(sb.lastIndexOf(",")); + if (t.nodes != null && !t.nodes.isEmpty()) sb.deleteCharAt(sb.lastIndexOf(",")); sb.append(" ]\n"); sb.append(" }\n"); From 9fc21b0fc8730c81c2cd598b814d4c1586a09fc4 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 12 Sep 2024 11:53:10 +0200 Subject: [PATCH 2/9] added a dynamic range check --- .../java/btools/router/RoutingContext.java | 3 ++ .../java/btools/router/RoutingEngine.java | 54 ++++++++++++++++++- 2 files changed, 56 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 86f1415..bd1c236 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -76,6 +76,7 @@ public final class RoutingContext { public double waypointCatchingRange; public boolean correctMisplacedViaPoints; public double correctMisplacedViaPointsDistance; + public boolean useDynamicDistance; private void setModel(String className) { if (className == null) { @@ -168,6 +169,8 @@ public final class RoutingContext { // Constant power of the biker (in W) bikerPower = expctxGlobal.getVariableValue("bikerPower", 100.f); + useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 1f; + boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f; if (!test) expctxGlobal.freeNoWays(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 09113a8..f612219 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -587,7 +587,13 @@ public class RoutingEngine extends Thread { mwp.direct = waypoints.get(i).direct; matchedWaypoints.add(mwp); } + int startSize = matchedWaypoints.size(); matchWaypointsToNodes(matchedWaypoints); + if (startSize < matchedWaypoints.size()) { + refTracks = new OsmTrack[matchedWaypoints.size()]; // used ways for alternatives + lastTracks = new OsmTrack[matchedWaypoints.size()]; + hasDirectRouting = true; + } routingContext.checkMatchedWaypointAgainstNogos(matchedWaypoints); @@ -968,7 +974,53 @@ public class RoutingEngine extends Thread { // geometric position matching finding the nearest routable way-section private void matchWaypointsToNodes(List unmatchedWaypoints) { resetCache(false); - nodesCache.matchWaypointsToNodes(unmatchedWaypoints, routingContext.waypointCatchingRange, islandNodePairs); + boolean useDynamicDistance = routingContext.useDynamicDistance; + double range = routingContext.waypointCatchingRange; + boolean ok = nodesCache.matchWaypointsToNodes(unmatchedWaypoints, range, islandNodePairs); + if (!ok && useDynamicDistance) { + logInfo("second check for way points"); + resetCache(false); + range = -range; + List tmp = new ArrayList<>(); + // only first or last checked + if (unmatchedWaypoints.get(0).crosspoint == null) tmp.add(unmatchedWaypoints.get(0)); + if (unmatchedWaypoints.get(unmatchedWaypoints.size()-1).crosspoint == null) tmp.add(unmatchedWaypoints.get(unmatchedWaypoints.size()-1)); + + ok = nodesCache.matchWaypointsToNodes(tmp, range, islandNodePairs); + } + if (!ok) { + for (MatchedWaypoint mwp :unmatchedWaypoints) { + if (mwp.crosspoint == null) throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + } + } + if (useDynamicDistance) { + List waypoints = new ArrayList<>(); + for (int i = 0; i < unmatchedWaypoints.size(); i++) { + MatchedWaypoint wp = unmatchedWaypoints.get(i); + if (wp.waypoint.calcDistance(wp.crosspoint) > routingContext.waypointCatchingRange) { + MatchedWaypoint nmw = new MatchedWaypoint(); + if (i==0) { + nmw.waypoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); + nmw.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); + nmw.direct = true; + wp.waypoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); + } else { + nmw.waypoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); + nmw.crosspoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); + nmw.node1 = new OsmNode(wp.node1.ilon, wp.node1.ilat); + nmw.node2 = new OsmNode(wp.node2.ilon, wp.node2.ilat); + nmw.direct = true; + wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); + } + nmw.name = wp.name; + waypoints.add(nmw); + wp.name = wp.name + "_add"; + } + waypoints.add(wp); + } + unmatchedWaypoints.clear(); + unmatchedWaypoints.addAll(waypoints); + } } private OsmTrack searchTrack(MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack) { From 0d28726ec9e5155386013dda5bb6139ef80bc72d Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 12 Sep 2024 11:54:55 +0200 Subject: [PATCH 3/9] search with dynamic and extended range --- .../java/btools/mapaccess/NodesCache.java | 19 +++++++++++-------- .../btools/mapaccess/WaypointMatcherImpl.java | 10 +++++++++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index e16b8d2..a7c34a7 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -177,7 +177,8 @@ public final class NodesCache { } MicroCache segment = osmf.getMicroCache(ilon, ilat); - if (segment == null) { + // needed for a second chance + if (segment == null || (waypointMatcher != null && ((WaypointMatcherImpl) waypointMatcher).useDynamicRange)) { checkEnableCacheCleaning(); segment = osmf.createMicroCache(ilon, ilat, dataBuffers, expCtxWay, waypointMatcher, directWeaving ? nodesMap : null); @@ -282,15 +283,15 @@ public final class NodesCache { return existing; } - public void matchWaypointsToNodes(List unmatchedWaypoints, double maxDistance, OsmNodePairSet islandNodePairs) { + public boolean matchWaypointsToNodes(List unmatchedWaypoints, double maxDistance, OsmNodePairSet islandNodePairs) { waypointMatcher = new WaypointMatcherImpl(unmatchedWaypoints, maxDistance, islandNodePairs); for (MatchedWaypoint mwp : unmatchedWaypoints) { int cellsize = 12500; - preloadPosition(mwp.waypoint, cellsize); + preloadPosition(mwp.waypoint, cellsize, 1); // get a second chance if (mwp.crosspoint == null) { cellsize = 1000000 / 32; - preloadPosition(mwp.waypoint, cellsize); + preloadPosition(mwp.waypoint, cellsize, maxDistance < 0 ? 5 : 2); } } @@ -305,7 +306,8 @@ public final class NodesCache { mwp.crosspoint = new OsmNode(mwp.waypoint.ilon, mwp.waypoint.ilat); mwp.direct = true; } else { - throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + // do not break here throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + return false; } } if (unmatchedWaypoints.size() > 1 && i == unmatchedWaypoints.size() - 1 && unmatchedWaypoints.get(i - 1).direct) { @@ -313,17 +315,18 @@ public final class NodesCache { mwp.direct = true; } } + return true; } - private void preloadPosition(OsmNode n, int d) { + private void preloadPosition(OsmNode n, int d, int scale) { first_file_access_failed = false; first_file_access_name = null; loadSegmentFor(n.ilon, n.ilat); if (first_file_access_failed) { throw new IllegalArgumentException("datafile " + first_file_access_name + " not found"); } - for (int idxLat = -1; idxLat <= 1; idxLat++) - for (int idxLon = -1; idxLon <= 1; idxLon++) { + for (int idxLat = -scale; idxLat <= scale; idxLat++) + for (int idxLon = -scale; idxLon <= scale; idxLon++) { if (idxLon != 0 || idxLat != 0) { loadSegmentFor(n.ilon + d * idxLon, n.ilat + d * idxLat); } diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index d646436..4b6e8a6 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -29,6 +29,8 @@ public final class WaypointMatcherImpl implements WaypointMatcher { private int lonLast; private int latLast; boolean useAsStartWay = true; + public boolean useDynamicRange; + private int maxWptIdx; private Comparator comparator; @@ -36,6 +38,11 @@ public final class WaypointMatcherImpl implements WaypointMatcher { this.waypoints = waypoints; this.islandPairs = islandPairs; MatchedWaypoint last = null; + this.useDynamicRange = maxDistance < 0; + if (maxDistance < 0.) { + maxDistance *= -1; + } + for (MatchedWaypoint mwp : waypoints) { mwp.radius = maxDistance; if (last != null && mwp.directionToNext == -1) { @@ -50,6 +57,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { } else { last.directionToNext = CheapAngleMeter.getDirection(last.waypoint.ilon, last.waypoint.ilat, waypoints.get(lastidx).waypoint.ilon, waypoints.get(lastidx).waypoint.ilat); } + maxWptIdx = waypoints.size() - 1; // sort result list comparator = new Comparator<>() { @@ -105,7 +113,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { double r22 = x2 * x2 + y2 * y2; double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d; - if (radius <= mwp.radius) { + if (radius <= mwp.radius || (this.useDynamicRange && (i == 0 || i == maxWptIdx))) { double s1 = x1 * dx + y1 * dy; double s2 = x2 * dx + y2 * dy; From 57726a36cea8abffb7266e5c6263306b42833f1d Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 13 Sep 2024 12:23:00 +0200 Subject: [PATCH 4/9] enabled via pts for dynamic range --- .../java/btools/router/RoutingEngine.java | 25 ++++++++++++++----- .../btools/mapaccess/WaypointMatcherImpl.java | 2 +- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index f612219..246144f 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -982,9 +982,10 @@ public class RoutingEngine extends Thread { resetCache(false); range = -range; List tmp = new ArrayList<>(); - // only first or last checked - if (unmatchedWaypoints.get(0).crosspoint == null) tmp.add(unmatchedWaypoints.get(0)); - if (unmatchedWaypoints.get(unmatchedWaypoints.size()-1).crosspoint == null) tmp.add(unmatchedWaypoints.get(unmatchedWaypoints.size()-1)); + // only w/o crosspoint check + for (MatchedWaypoint mwp: unmatchedWaypoints) { + if (mwp.crosspoint == null) tmp.add(mwp); + } ok = nodesCache.matchWaypointsToNodes(tmp, range, islandNodePairs); } @@ -1012,11 +1013,23 @@ public class RoutingEngine extends Thread { nmw.direct = true; wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); } - nmw.name = wp.name; + nmw.name = wp.name + "_1"; waypoints.add(nmw); - wp.name = wp.name + "_add"; + waypoints.add(wp); + if (wp.name.startsWith("via")) { + wp.direct = true; + MatchedWaypoint emw = new MatchedWaypoint(); + emw.waypoint = new OsmNode(nmw.crosspoint.ilon, nmw.crosspoint.ilat); + emw.crosspoint = new OsmNode(nmw.crosspoint.ilon, nmw.crosspoint.ilat); + emw.node1 = new OsmNode(nmw.node1.ilon, nmw.node1.ilat); + emw.node2 = new OsmNode(nmw.node2.ilon, nmw.node2.ilat); + emw.direct = false; + emw.name = wp.name + "_2"; + waypoints.add(emw); + } + } else { + waypoints.add(wp); } - waypoints.add(wp); } unmatchedWaypoints.clear(); unmatchedWaypoints.addAll(waypoints); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index 4b6e8a6..70aac74 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -113,7 +113,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { double r22 = x2 * x2 + y2 * y2; double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d; - if (radius <= mwp.radius || (this.useDynamicRange && (i == 0 || i == maxWptIdx))) { + if (radius <= mwp.radius || this.useDynamicRange) { double s1 = x1 * dx + y1 * dy; double s2 = x2 * dx + y2 * dy; From 22842f0305c09ed331001070e54835c5e53c9813 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 4 Oct 2024 11:06:33 +0200 Subject: [PATCH 5/9] error on dynamic range --- .../main/java/btools/router/RoutingEngine.java | 8 +------- .../btools/mapaccess/WaypointMatcherImpl.java | 18 +++++++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 246144f..eb53a2d 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -981,13 +981,7 @@ public class RoutingEngine extends Thread { logInfo("second check for way points"); resetCache(false); range = -range; - List tmp = new ArrayList<>(); - // only w/o crosspoint check - for (MatchedWaypoint mwp: unmatchedWaypoints) { - if (mwp.crosspoint == null) tmp.add(mwp); - } - - ok = nodesCache.matchWaypointsToNodes(tmp, range, islandNodePairs); + ok = nodesCache.matchWaypointsToNodes(unmatchedWaypoints, range, islandNodePairs); } if (!ok) { for (MatchedWaypoint mwp :unmatchedWaypoints) { diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index 70aac74..2f09110 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -1,12 +1,12 @@ package btools.mapaccess; -import java.util.List; import java.util.Collections; import java.util.Comparator; +import java.util.List; import btools.codec.WaypointMatcher; -import btools.util.CheapRuler; import btools.util.CheapAngleMeter; +import btools.util.CheapRuler; /** * the WaypointMatcher is feeded by the decoder with geoemtries of ways that are @@ -29,8 +29,9 @@ public final class WaypointMatcherImpl implements WaypointMatcher { private int lonLast; private int latLast; boolean useAsStartWay = true; - public boolean useDynamicRange; private int maxWptIdx; + private double maxDistance; + public boolean useDynamicRange = false; private Comparator comparator; @@ -38,9 +39,11 @@ public final class WaypointMatcherImpl implements WaypointMatcher { this.waypoints = waypoints; this.islandPairs = islandPairs; MatchedWaypoint last = null; - this.useDynamicRange = maxDistance < 0; + this.maxDistance = maxDistance; if (maxDistance < 0.) { + this.maxDistance = -1; maxDistance *= -1; + useDynamicRange = true; } for (MatchedWaypoint mwp : waypoints) { @@ -87,7 +90,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { //for ( MatchedWaypoint mwp : waypoints ) for (int i = 0; i < waypoints.size(); i++) { - if (!useAsStartWay && i==0) continue; + if (!useAsStartWay && i == 0) continue; MatchedWaypoint mwp = waypoints.get(i); if (mwp.direct && @@ -113,7 +116,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { double r22 = x2 * x2 + y2 * y2; double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d; - if (radius <= mwp.radius || this.useDynamicRange) { + if (radius <= mwp.radius || (this.maxDistance == -1d && (i == 0 || i == maxWptIdx))) { double s1 = x1 * dx + y1 * dy; double s2 = x2 * dx + y2 * dy; @@ -123,7 +126,8 @@ public final class WaypointMatcherImpl implements WaypointMatcher { } if (s2 > 0.) { radius = Math.sqrt(s1 < s2 ? r12 : r22); - if (radius > mwp.radius) + + if (radius > mwp.radius && this.maxDistance != -1) continue; } // new match for that waypoint From a6ba70a7861f8baca81294fbcfd13a4948874b81 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Sun, 6 Oct 2024 11:50:13 +0200 Subject: [PATCH 6/9] expanded dynamic range --- .../main/java/btools/router/RoutingEngine.java | 15 ++++++++++----- .../main/java/btools/mapaccess/NodesCache.java | 4 ++-- .../btools/mapaccess/WaypointMatcherImpl.java | 7 ++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index eb53a2d..7c8261b 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -981,11 +981,16 @@ public class RoutingEngine extends Thread { logInfo("second check for way points"); resetCache(false); range = -range; - ok = nodesCache.matchWaypointsToNodes(unmatchedWaypoints, range, islandNodePairs); + List tmp = new ArrayList<>(); + for (MatchedWaypoint mwp : unmatchedWaypoints) { + if (mwp.crosspoint == null) tmp.add(mwp); + } + ok = nodesCache.matchWaypointsToNodes(tmp, range, islandNodePairs); } - if (!ok) { - for (MatchedWaypoint mwp :unmatchedWaypoints) { - if (mwp.crosspoint == null) throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); + if (!ok) { + for (MatchedWaypoint mwp : unmatchedWaypoints) { + if (mwp.crosspoint == null) + throw new IllegalArgumentException(mwp.name + "-position not mapped in existing datafile"); } } if (useDynamicDistance) { @@ -994,7 +999,7 @@ public class RoutingEngine extends Thread { MatchedWaypoint wp = unmatchedWaypoints.get(i); if (wp.waypoint.calcDistance(wp.crosspoint) > routingContext.waypointCatchingRange) { MatchedWaypoint nmw = new MatchedWaypoint(); - if (i==0) { + if (i == 0) { nmw.waypoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); nmw.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); nmw.direct = true; diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index a7c34a7..6600c6a 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -289,9 +289,9 @@ public final class NodesCache { int cellsize = 12500; preloadPosition(mwp.waypoint, cellsize, 1); // get a second chance - if (mwp.crosspoint == null) { + if (mwp.crosspoint == null || mwp.radius > Math.abs(maxDistance)) { cellsize = 1000000 / 32; - preloadPosition(mwp.waypoint, cellsize, maxDistance < 0 ? 5 : 2); + preloadPosition(mwp.waypoint, cellsize, maxDistance < 0 ? 15 : 2); } } diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index 2f09110..85247d4 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -47,7 +47,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { } for (MatchedWaypoint mwp : waypoints) { - mwp.radius = maxDistance; + mwp.radius = useDynamicRange ? mwp.radius != maxDistance ? mwp.radius : -1 : maxDistance; if (last != null && mwp.directionToNext == -1) { last.directionToNext = CheapAngleMeter.getDirection(last.waypoint.ilon, last.waypoint.ilat, mwp.waypoint.ilon, mwp.waypoint.ilat); } @@ -116,7 +116,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { double r22 = x2 * x2 + y2 * y2; double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d; - if (radius <= mwp.radius || (this.maxDistance == -1d && (i == 0 || i == maxWptIdx))) { + if (radius < mwp.radius || (this.maxDistance == -1d)) { double s1 = x1 * dx + y1 * dy; double s2 = x2 * dx + y2 * dy; @@ -127,8 +127,9 @@ public final class WaypointMatcherImpl implements WaypointMatcher { if (s2 > 0.) { radius = Math.sqrt(s1 < s2 ? r12 : r22); - if (radius > mwp.radius && this.maxDistance != -1) + if (radius > mwp.radius && mwp.radius != -1) { continue; + } } // new match for that waypoint mwp.radius = radius; // shortest distance to way From 2f4c125bf5f3fe7135d3c0d630cb3098ace9e05b Mon Sep 17 00:00:00 2001 From: afischerdev Date: Mon, 21 Oct 2024 10:08:09 +0200 Subject: [PATCH 7/9] added distance check for dynamic range --- .../java/btools/codec/WaypointMatcher.java | 2 ++ .../java/btools/router/RoutingEngine.java | 35 +++++++++---------- .../java/btools/mapaccess/NodesCache.java | 24 ++++++++----- .../btools/mapaccess/WaypointMatcherImpl.java | 19 +++++++--- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/brouter-codec/src/main/java/btools/codec/WaypointMatcher.java b/brouter-codec/src/main/java/btools/codec/WaypointMatcher.java index 2957c03..2889c7e 100644 --- a/brouter-codec/src/main/java/btools/codec/WaypointMatcher.java +++ b/brouter-codec/src/main/java/btools/codec/WaypointMatcher.java @@ -11,4 +11,6 @@ public interface WaypointMatcher { void transferNode(int ilon, int ilat); void end(); + + boolean hasMatch(int lon, int lat); } diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 7c8261b..caefad8 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -47,6 +47,8 @@ public class RoutingEngine extends Thread { private int MAX_STEPS_CHECK = 10; + private int MAX_DYNAMIC_RANGE = 60000; + protected OsmTrack foundTrack = new OsmTrack(); private OsmTrack foundRawTrack = null; private int alternativeIndex = 0; @@ -980,7 +982,7 @@ public class RoutingEngine extends Thread { if (!ok && useDynamicDistance) { logInfo("second check for way points"); resetCache(false); - range = -range; + range = -MAX_DYNAMIC_RANGE; List tmp = new ArrayList<>(); for (MatchedWaypoint mwp : unmatchedWaypoints) { if (mwp.crosspoint == null) tmp.add(mwp); @@ -1000,35 +1002,30 @@ public class RoutingEngine extends Thread { if (wp.waypoint.calcDistance(wp.crosspoint) > routingContext.waypointCatchingRange) { MatchedWaypoint nmw = new MatchedWaypoint(); if (i == 0) { - nmw.waypoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); + OsmNodeNamed onn = new OsmNodeNamed(wp.waypoint); + onn.name = "from"; + nmw.waypoint = onn; + nmw.name = onn.name; nmw.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); nmw.direct = true; - wp.waypoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); + onn = new OsmNodeNamed(wp.crosspoint); + onn.name = wp.name + "_add"; + wp.waypoint = onn; } else { - nmw.waypoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); + OsmNodeNamed onn = new OsmNodeNamed(wp.crosspoint); + onn.name = wp.name + "_add"; + nmw.waypoint = onn; nmw.crosspoint = new OsmNode(wp.crosspoint.ilon, wp.crosspoint.ilat); nmw.node1 = new OsmNode(wp.node1.ilon, wp.node1.ilat); nmw.node2 = new OsmNode(wp.node2.ilon, wp.node2.ilat); nmw.direct = true; wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); } - nmw.name = wp.name + "_1"; + if (wp.name != null) nmw.name = wp.name; waypoints.add(nmw); - waypoints.add(wp); - if (wp.name.startsWith("via")) { - wp.direct = true; - MatchedWaypoint emw = new MatchedWaypoint(); - emw.waypoint = new OsmNode(nmw.crosspoint.ilon, nmw.crosspoint.ilat); - emw.crosspoint = new OsmNode(nmw.crosspoint.ilon, nmw.crosspoint.ilat); - emw.node1 = new OsmNode(nmw.node1.ilon, nmw.node1.ilat); - emw.node2 = new OsmNode(nmw.node2.ilon, nmw.node2.ilat); - emw.direct = false; - emw.name = wp.name + "_2"; - waypoints.add(emw); - } - } else { - waypoints.add(wp); + wp.name = wp.name + "_add"; } + waypoints.add(wp); } unmatchedWaypoints.clear(); unmatchedWaypoints.addAll(waypoints); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java index 6600c6a..4230e8b 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/NodesCache.java @@ -17,6 +17,9 @@ import btools.codec.WaypointMatcher; import btools.expressions.BExpressionContextWay; public final class NodesCache { + + private int MAX_DYNAMIC_CATCHES = 20; // used with RoutingEngiine MAX_DYNAMIC_RANGE = 60000m + private File segmentDir; private File secondarySegmentsDir = null; @@ -287,11 +290,11 @@ public final class NodesCache { waypointMatcher = new WaypointMatcherImpl(unmatchedWaypoints, maxDistance, islandNodePairs); for (MatchedWaypoint mwp : unmatchedWaypoints) { int cellsize = 12500; - preloadPosition(mwp.waypoint, cellsize, 1); + preloadPosition(mwp.waypoint, cellsize, 1, false); // get a second chance if (mwp.crosspoint == null || mwp.radius > Math.abs(maxDistance)) { cellsize = 1000000 / 32; - preloadPosition(mwp.waypoint, cellsize, maxDistance < 0 ? 15 : 2); + preloadPosition(mwp.waypoint, cellsize, maxDistance < 0 ? MAX_DYNAMIC_CATCHES : 2, maxDistance < 0); } } @@ -318,19 +321,24 @@ public final class NodesCache { return true; } - private void preloadPosition(OsmNode n, int d, int scale) { + private void preloadPosition(OsmNode n, int d, int maxscale, boolean bUseDynamicRange) { first_file_access_failed = false; first_file_access_name = null; loadSegmentFor(n.ilon, n.ilat); if (first_file_access_failed) { throw new IllegalArgumentException("datafile " + first_file_access_name + " not found"); } - for (int idxLat = -scale; idxLat <= scale; idxLat++) - for (int idxLon = -scale; idxLon <= scale; idxLon++) { - if (idxLon != 0 || idxLat != 0) { - loadSegmentFor(n.ilon + d * idxLon, n.ilat + d * idxLat); + int scale = 1; + while (scale < maxscale) { + for (int idxLat = -scale; idxLat <= scale; idxLat++) + for (int idxLon = -scale; idxLon <= scale; idxLon++) { + if (idxLon != 0 || idxLat != 0) { + loadSegmentFor(n.ilon + d * idxLon, n.ilat + d * idxLat); + } } - } + if (bUseDynamicRange && waypointMatcher.hasMatch(n.ilon, n.ilat)) break; + scale++; + } } private OsmFile fileForSegment(int lonDegree, int latDegree) throws Exception { diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java index 85247d4..6096c79 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java @@ -41,13 +41,13 @@ public final class WaypointMatcherImpl implements WaypointMatcher { MatchedWaypoint last = null; this.maxDistance = maxDistance; if (maxDistance < 0.) { - this.maxDistance = -1; + this.maxDistance *= -1; maxDistance *= -1; useDynamicRange = true; } for (MatchedWaypoint mwp : waypoints) { - mwp.radius = useDynamicRange ? mwp.radius != maxDistance ? mwp.radius : -1 : maxDistance; + mwp.radius = maxDistance; if (last != null && mwp.directionToNext == -1) { last.directionToNext = CheapAngleMeter.getDirection(last.waypoint.ilon, last.waypoint.ilat, mwp.waypoint.ilon, mwp.waypoint.ilat); } @@ -116,7 +116,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { double r22 = x2 * x2 + y2 * y2; double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d; - if (radius < mwp.radius || (this.maxDistance == -1d)) { + if (radius < mwp.radius) { double s1 = x1 * dx + y1 * dy; double s2 = x2 * dx + y2 * dy; @@ -127,7 +127,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher { if (s2 > 0.) { radius = Math.sqrt(s1 < s2 ? r12 : r22); - if (radius > mwp.radius && mwp.radius != -1) { + if (radius > mwp.radius) { continue; } } @@ -239,6 +239,17 @@ public final class WaypointMatcherImpl implements WaypointMatcher { } } + @Override + public boolean hasMatch(int lon, int lat) { + for (MatchedWaypoint mwp : waypoints) { + if (mwp.waypoint.ilon == lon && mwp.waypoint.ilat == lat && + (mwp.radius < this.maxDistance || mwp.crosspoint != null)) { + return true; + } + } + return false; + } + // check limit of list size (avoid long runs) void updateWayList(List ways, MatchedWaypoint mw) { ways.add(mw); From 504f8197e6070350bbf1c3ef4407255d98fd3e68 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 22 Oct 2024 11:10:06 +0200 Subject: [PATCH 8/9] protect wp list during alternative run --- brouter-core/src/main/java/btools/router/RoutingEngine.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index caefad8..7c2134c 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -623,6 +623,12 @@ public class RoutingEngine extends Thread { if (nearbyTrack != null) { matchedWaypoints.add(nearbyTrack.endPoint); } + } else { + if (lastTracks.length < matchedWaypoints.size()) { + refTracks = new OsmTrack[matchedWaypoints.size()]; // used ways for alternatives + lastTracks = new OsmTrack[matchedWaypoints.size()]; + hasDirectRouting = true; + } } OsmPath.seg = 1; // set segment counter From 566b69350ca4b785cacf89dc20f2c9d2c8744231 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 13 Nov 2024 10:39:15 +0100 Subject: [PATCH 9/9] add variable to profiles --- misc/profiles2/car-vario.brf | 2 ++ misc/profiles2/gravel.brf | 8 +++++--- misc/profiles2/hiking-mountain.brf | 2 ++ misc/profiles2/moped.brf | 4 +++- misc/profiles2/mtb.brf | 3 +++ misc/profiles2/river.brf | 2 ++ misc/profiles2/trekking.brf | 2 ++ 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/misc/profiles2/car-vario.brf b/misc/profiles2/car-vario.brf index 34e5be1..87aeac5 100644 --- a/misc/profiles2/car-vario.brf +++ b/misc/profiles2/car-vario.brf @@ -17,6 +17,8 @@ assign avoid_toll = false # %avoid_toll% | Avoid paid roads | boolean assign avoid_unpaved = false # %avoid_unpaved% | Avoid unpaved roads, if possible | boolean assign avoid_motorways = false # %avoid_motorways% | Avoid motorways | boolean +assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + # Kinematic model parameters assign vmax = 90 # %vmax% | Target speed (in km/h) | number assign recup_efficiency = 0.7 # %recup_efficiency% | (ratio) | number diff --git a/misc/profiles2/gravel.brf b/misc/profiles2/gravel.brf index 3468ae0..5485234 100644 --- a/misc/profiles2/gravel.brf +++ b/misc/profiles2/gravel.brf @@ -8,6 +8,8 @@ assign turnInstructionRoundabouts true # %turnInstructionRoundabouts% | Special assign considerTurnRestrictions true assign turnInstructionMode 1 # %turnInstructionMode% | Mode for the generated turn-by-turn directions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=oruxmaps-style] +assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + #assign processUnusedTags true assign pass1coefficient 4 assign validForBikes true @@ -48,7 +50,7 @@ assign uphillcutoff switch bad_when_steep ( min 1.5 uphillcutoff ) uphillcut assign any_cycleway or cycleway=track|lane|shared_lane|shared or and cycleway:right=track|lane|shared_lane reversedirection= and cycleway:left=track|lane|shared_lane reversedirection=yes - + assign any_cycleroute or route_bicycle_icn=yes or route_bicycle_ncn=yes or route_bicycle_rcn=yes route_bicycle_lcn=yes assign turncost switch junction=roundabout 15 65 @@ -166,7 +168,7 @@ assign is_paved assign initialcost multiply initialcost ( switch and prefer_unpaved_paths is_paved 2 1 ) - + assign smoothnesspenalty multiply smoothnesspenalty ( switch and prefer_unpaved_paths is_paved 2 1 ) @@ -231,7 +233,7 @@ assign noforestpenalty switch estimated_forest_class=6 1.0 1 1 assign townpenalty - switch avoid_towns + switch avoid_towns switch estimated_town_class= 1.0 switch estimated_town_class=1 1.2 switch estimated_town_class=2 1.4 diff --git a/misc/profiles2/hiking-mountain.brf b/misc/profiles2/hiking-mountain.brf index 688da66..d54aa2c 100644 --- a/misc/profiles2/hiking-mountain.brf +++ b/misc/profiles2/hiking-mountain.brf @@ -44,6 +44,8 @@ assign initialcost_value 0 # not used now assign allow_steps true # %allow_steps% | Set to false to disallow steps | boolean assign allow_ferries true # %allow_ferries% | set to false to disallow ferries | boolean +assign use_dynamic_range false # %use_dynamic_range% | Enable distant start/end points | boolean + assign cost_of_unknown 2 # 2 as default # diff --git a/misc/profiles2/moped.brf b/misc/profiles2/moped.brf index 50304de..e270fbf 100644 --- a/misc/profiles2/moped.brf +++ b/misc/profiles2/moped.brf @@ -16,7 +16,9 @@ assign uphillcutoff 0 assign validForBikes 1 assign validForCars 1 -assign turnInstructionMode = 1 # %turnInstructionMode% | Mode for the generated turn instructions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] +assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + +assign turnInstructionMode = 1 # %turnInstructionMode% | Mode for the generated turn instructions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] ---context:way # following code refers to way-tags diff --git a/misc/profiles2/mtb.brf b/misc/profiles2/mtb.brf index 1b360cb..3e52cc5 100644 --- a/misc/profiles2/mtb.brf +++ b/misc/profiles2/mtb.brf @@ -11,6 +11,9 @@ # bstart /global ---context:global + + assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + assign iswet 0 # 0 as default, *) flag for weather conditions assign turnInstructionMode = 1 # 0=none, 1=auto-choose, 2=locus-style, 3=osmand-style assign cycleroutes_pref 0.2 # also CRP *) costfactor penalty for not being cycleroute diff --git a/misc/profiles2/river.brf b/misc/profiles2/river.brf index 80b46cc..45fa29f 100644 --- a/misc/profiles2/river.brf +++ b/misc/profiles2/river.brf @@ -2,6 +2,8 @@ # the elevation parameters +assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + assign downhillcost 0 assign downhillcutoff 1.5 assign uphillcost 0 diff --git a/misc/profiles2/trekking.brf b/misc/profiles2/trekking.brf index b4aa6ed..5e7e400 100644 --- a/misc/profiles2/trekking.brf +++ b/misc/profiles2/trekking.brf @@ -15,6 +15,8 @@ assign ignore_cycleroutes = false # %ignore_cycleroutes% | Set true for assign stick_to_cycleroutes = false # %stick_to_cycleroutes% | Set true to just follow cycleroutes | boolean assign avoid_unsafe = false # %avoid_unsafe% | Set true to avoid standard highways | boolean +assign use_dynamic_range = false # %use_dynamic_range% | Enable distant start/end points | boolean + assign consider_noise = false # %consider_noise% | Activate to prefer a low-noise route | boolean assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or parks | boolean