From a5fca2d8f24074114718e2ce61c3cff7dc1c209c Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 21 Jan 2025 12:13:25 +0100 Subject: [PATCH 01/28] added engineMode roundtrip --- .../java/btools/router/RoutingContext.java | 3 + .../java/btools/router/RoutingEngine.java | 72 ++++++++++++++++++- .../btools/router/RoutingParamCollector.java | 6 ++ 3 files changed, 80 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 2559f3a..8e03e96 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -191,6 +191,9 @@ public final class RoutingContext { public Integer startDirection; public boolean startDirectionValid; public boolean forceUseStartDirection; + public Integer roundtripDistance; + public Integer roundtripDirectionAdd; + public boolean allowSamewayback; public CheapAngleMeter anglemeter = new CheapAngleMeter(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 14fa36f..9e74244 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -21,6 +21,7 @@ import btools.mapaccess.OsmLinkHolder; import btools.mapaccess.OsmNode; import btools.mapaccess.OsmNodePairSet; import btools.mapaccess.OsmPos; +import btools.util.CheapRuler; import btools.util.CompactLongMap; import btools.util.SortedHeap; import btools.util.StackSampler; @@ -31,6 +32,7 @@ public class RoutingEngine extends Thread { public final static int BROUTER_ENGINEMODE_SEED = 1; public final static int BROUTER_ENGINEMODE_GETELEV = 2; public final static int BROUTER_ENGINEMODE_GETINFO = 3; + public final static int BROUTER_ENGINEMODE_ROUNDTRIP = 4; private NodesCache nodesCache; private SortedHeap openSet = new SortedHeap<>(); @@ -48,7 +50,7 @@ public class RoutingEngine extends Thread { private int engineMode = 0; - private int MAX_STEPS_CHECK = 10; + private int MAX_STEPS_CHECK = 20; private int MAX_DYNAMIC_RANGE = 60000; @@ -178,6 +180,11 @@ public class RoutingEngine extends Thread { } doGetInfo(); break; + case BROUTER_ENGINEMODE_ROUNDTRIP: + if (waypoints.size() < 1) + throw new IllegalArgumentException("we need one lat/lon point at least!"); + doRoundTrip(); + break; default: throw new IllegalArgumentException("not a valid engine mode"); } @@ -447,6 +454,69 @@ public class RoutingEngine extends Thread { } } + public void doRoundTrip() { + try { + startTime = System.currentTimeMillis(); + MatchedWaypoint wpt1 = new MatchedWaypoint(); + wpt1.waypoint = waypoints.get(0); + wpt1.name = "roundtrip"; + + routingContext.useDynamicDistance = true; + double searchRadius = (routingContext.roundtripDistance == null ? 1500 :routingContext.roundtripDistance); + double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection); + if (direction == -1) direction = (int) (Math.random()*360); + double directionAdd = (routingContext.roundtripDirectionAdd == null ? 20 :routingContext.roundtripDirectionAdd); + + //direction = 59; + if (routingContext.allowSamewayback) { + int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction); + MatchedWaypoint wpt2 = new MatchedWaypoint(); + wpt2.waypoint = new OsmNode(pos[0], pos[1]); + wpt2.name = "rt1_" + (direction); + + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via1"; + onn.radius = 1000; + waypoints.add(onn); + } else { + int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction-directionAdd); + MatchedWaypoint wpt2 = new MatchedWaypoint(); + wpt2.waypoint = new OsmNode(pos[0], pos[1]); + wpt2.name = "rt1_" + (direction); + + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via1"; + onn.radius = 1000; + waypoints.add(onn); + + + pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction+directionAdd); + MatchedWaypoint wpt3 = new MatchedWaypoint(); + wpt3.waypoint = new OsmNode(pos[0], pos[1]); + wpt3.name = "rt2_" + (direction); + + onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via2"; + onn.radius = 1000; + waypoints.add(onn); + } + OsmNodeNamed onn = new OsmNodeNamed(waypoints.get(0)); + onn.name = "rt_end"; + waypoints.add(onn); + + routingContext.waypointCatchingRange = 1000; + + doRouting(0); + + 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; diff --git a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java index b8d7f6b..a169f07 100644 --- a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java +++ b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java @@ -202,6 +202,12 @@ public class RoutingParamCollector { rctx.forceUseStartDirection = true; } else if (key.equals("direction")) { rctx.startDirection = Integer.valueOf(value); + } else if (key.equals("roundtripDistance")) { + rctx.roundtripDistance = Integer.valueOf(value); + } else if (key.equals("roundtripDirectionAdd")) { + rctx.roundtripDirectionAdd = Integer.valueOf(value); + } else if (key.equals("allowSamewayback")) { + rctx.allowSamewayback = Integer.parseInt(value)==1; } else if (key.equals("alternativeidx")) { rctx.setAlternativeIdx(Integer.parseInt(value)); } else if (key.equals("turnInstructionMode")) { From 9bcf8714e537e5f72481f99385734ae1fae2687d Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 21 Jan 2025 12:14:15 +0100 Subject: [PATCH 02/28] added destination ruler --- .../src/main/java/btools/util/CheapRuler.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/brouter-util/src/main/java/btools/util/CheapRuler.java b/brouter-util/src/main/java/btools/util/CheapRuler.java index 7a7dc8f..454b2b9 100644 --- a/brouter-util/src/main/java/btools/util/CheapRuler.java +++ b/brouter-util/src/main/java/btools/util/CheapRuler.java @@ -77,4 +77,21 @@ public final class CheapRuler { double dlat = (ilat1 - ilat2) * kxky[1]; return Math.sqrt(dlat * dlat + dlon * dlon); // in m } + + public static int[] destination(int lon1, int lat1, double distance, double angle) { + + double[] lonlat2m = getLonLatToMeterScales(lat1); + double lon2m = lonlat2m[0]; + double lat2m = lonlat2m[1]; + angle = 90. - angle; + double st = Math.sin(angle * Math.PI / 180.); + double ct = Math.cos(angle * Math.PI / 180.); + + int lon2 = (int) (0.5 + lon1 + ct * distance / lon2m); + int lat2 = (int) (0.5 + lat1 + st * distance / lat2m); + int[] ret = new int[2]; + ret[0] = lon2; + ret[1] = lat2; + return ret; + } } From 08e825c52a082de4735c771d59f2373bd8e96e50 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 21 Jan 2025 12:14:43 +0100 Subject: [PATCH 03/28] added destination tests --- .../java/btools/router/OsmNodeNamedTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/brouter-core/src/test/java/btools/router/OsmNodeNamedTest.java b/brouter-core/src/test/java/btools/router/OsmNodeNamedTest.java index ce2eb47..86d3279 100644 --- a/brouter-core/src/test/java/btools/router/OsmNodeNamedTest.java +++ b/brouter-core/src/test/java/btools/router/OsmNodeNamedTest.java @@ -1,6 +1,7 @@ package btools.router; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -110,4 +111,22 @@ public class OsmNodeNamedTest { 0.1 * 5 ); } + + @Test + public void testDestination() { + // Segment ends + int lon1, lat1, lon2, lat2; + // Circle definition + OsmNodeNamed node = new OsmNodeNamed(); + // Center + node.ilon = toOsmLon(0); + node.ilat = toOsmLat(0); + double startDist = 1000; + + for (int i = 0; i <= 360; i += 45) { + int[] pos = CheapRuler.destination(node.ilon, node.ilat, startDist, i); + double dist = CheapRuler.distance(node.ilon, node.ilat, pos[0], pos[1]); + assertTrue("pos " + pos[0] + " " + pos[1] + " distance (" + dist + ") should be around (" + startDist + ")", dist -1 < startDist && dist +1 > startDist); + } + } } From 19cb111b2760922bc48020590d1666e8db7ffc71 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 21 Jan 2025 12:15:23 +0100 Subject: [PATCH 04/28] enabled roundtrip for app --- .../src/main/java/btools/routingapp/BRouterWorker.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 1c733ba..c366b86 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java @@ -136,7 +136,8 @@ public class BRouterWorker { cr.quite = true; cr.doRun(maxRunningTime); - if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) { + if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING || + engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUNDTRIP) { // store new reference track if any // (can exist for timed-out search) if (cr.getFoundRawTrack() != null) { From a9da9464b778b276bfa31b78eb0d736da64b996f Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 24 Jan 2025 13:56:47 +0100 Subject: [PATCH 05/28] enabled roundtrip for server --- brouter-server/src/main/java/btools/server/RouteServer.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/brouter-server/src/main/java/btools/server/RouteServer.java b/brouter-server/src/main/java/btools/server/RouteServer.java index 36145dc..4b2be7a 100644 --- a/brouter-server/src/main/java/btools/server/RouteServer.java +++ b/brouter-server/src/main/java/btools/server/RouteServer.java @@ -222,7 +222,8 @@ public class RouteServer extends Thread implements Comparable { } String headers = encodings == null || encodings.indexOf("gzip") < 0 ? null : "Content-Encoding: gzip\n"; writeHttpHeader(bw, handler.getMimeType(), handler.getFileName(), headers, HTTP_STATUS_OK); - if (engineMode == 0) { + if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING || + engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUNDTRIP) { if (track != null) { if (headers != null) { // compressed ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -235,7 +236,8 @@ public class RouteServer extends Thread implements Comparable { bw.write(handler.formatTrack(track)); } } - } else if (engineMode == 2) { + } else if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_GETELEV || + engineMode == RoutingEngine.BROUTER_ENGINEMODE_GETINFO) { String s = cr.getFoundInfo(); if (s != null) { bw.write(s); From 59425c5b323dcad2bf6460c5b0507c464e0ed38a Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 24 Jan 2025 14:36:39 +0100 Subject: [PATCH 06/28] enabled same way back for all --- .../java/btools/router/RoutingEngine.java | 64 ++++++++++++++----- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 9e74244..47cf7b0 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -50,7 +50,9 @@ public class RoutingEngine extends Thread { private int engineMode = 0; - private int MAX_STEPS_CHECK = 20; + private int MAX_STEPS_CHECK = 250; + + private int ROUNDTRIP_DEFAULT_DIRECTIONADD = 45; private int MAX_DYNAMIC_RANGE = 60000; @@ -196,6 +198,28 @@ public class RoutingEngine extends Thread { startTime = System.currentTimeMillis(); long startTime0 = startTime; this.maxRunningTime = maxRunningTime; + + if (routingContext.allowSamewayback) { + if (waypoints.size() == 2) { + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(waypoints.get(0).ilon, waypoints.get(0).ilat)); + onn.name = "to"; + onn.radius = 1000; + waypoints.add(onn); + } else { + waypoints.get(waypoints.size()-1).name = "via" + (waypoints.size()-1) + "_center"; + List newpoints = new ArrayList<>(); + for (int i = waypoints.size()-2; i >= 0; i--) { + // System.out.println("back " + waypoints.get(i)); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(waypoints.get(i).ilon, waypoints.get(i).ilat)); + onn.name = "via"; + onn.radius = 1000; + newpoints.add(onn); + } + newpoints.get(newpoints.size()-1).name = "to"; + waypoints.addAll(newpoints); + } + } + int nsections = waypoints.size() - 1; OsmTrack[] refTracks = new OsmTrack[nsections]; // used ways for alternatives OsmTrack[] lastTracks = new OsmTrack[nsections]; @@ -465,14 +489,13 @@ public class RoutingEngine extends Thread { double searchRadius = (routingContext.roundtripDistance == null ? 1500 :routingContext.roundtripDistance); double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection); if (direction == -1) direction = (int) (Math.random()*360); - double directionAdd = (routingContext.roundtripDirectionAdd == null ? 20 :routingContext.roundtripDirectionAdd); + double directionAdd = (routingContext.roundtripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundtripDirectionAdd); - //direction = 59; if (routingContext.allowSamewayback) { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction); MatchedWaypoint wpt2 = new MatchedWaypoint(); wpt2.waypoint = new OsmNode(pos[0], pos[1]); - wpt2.name = "rt1_" + (direction); + wpt2.name = "rt1_" + direction; OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via1"; @@ -482,7 +505,7 @@ public class RoutingEngine extends Thread { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction-directionAdd); MatchedWaypoint wpt2 = new MatchedWaypoint(); wpt2.waypoint = new OsmNode(pos[0], pos[1]); - wpt2.name = "rt1_" + (direction); + wpt2.name = "via1_" + (int) (direction-directionAdd); OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via1"; @@ -493,16 +516,27 @@ public class RoutingEngine extends Thread { pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction+directionAdd); MatchedWaypoint wpt3 = new MatchedWaypoint(); wpt3.waypoint = new OsmNode(pos[0], pos[1]); - wpt3.name = "rt2_" + (direction); + wpt3.name = "via2_" + (int) (direction+directionAdd); onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via2"; onn.radius = 1000; waypoints.add(onn); + + pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius/2, direction); + OsmNodeNamed n = new OsmNodeNamed(); + n.name = "nogo" + (int) (searchRadius/3); + n.ilon = pos[0]; + n.ilat = pos[1]; + n.isNogo = true; + n.radius = (int) (searchRadius/3); + n.nogoWeight = Double.NaN; + routingContext.setWaypoint(n, false); + + onn = new OsmNodeNamed(waypoints.get(0)); + onn.name = "to_rt"; + waypoints.add(onn); } - OsmNodeNamed onn = new OsmNodeNamed(waypoints.get(0)); - onn.name = "rt_end"; - waypoints.add(onn); routingContext.waypointCatchingRange = 1000; @@ -825,7 +859,7 @@ public class RoutingEngine extends Thread { return null; boolean changed = false; - if (routingContext.correctMisplacedViaPoints && !matchedWaypoints.get(i).direct) { + if (routingContext.correctMisplacedViaPoints && !matchedWaypoints.get(i).direct && !routingContext.allowSamewayback) { changed = snappPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i)); } if (wptIndex > 0) @@ -946,15 +980,11 @@ public class RoutingEngine extends Thread { } indexback--; indexfore++; + + if (routingContext.correctMisplacedViaPointsDistance > 0 && + wayDistance > routingContext.correctMisplacedViaPointsDistance) break; } - if (routingContext.correctMisplacedViaPointsDistance > 0 && - wayDistance > routingContext.correctMisplacedViaPointsDistance) { - removeVoiceHintList.clear(); - removeBackList.clear(); - removeForeList.clear(); - return false; - } // time hold float atime = 0; From be2b6019643e7e51e99a8b61f4c022634b0ea20c Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 30 Jan 2025 17:58:56 +0100 Subject: [PATCH 07/28] removed unused defs --- brouter-core/src/main/java/btools/router/RoutingEngine.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 47cf7b0..3e85f9e 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -203,7 +203,6 @@ public class RoutingEngine extends Thread { if (waypoints.size() == 2) { OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(waypoints.get(0).ilon, waypoints.get(0).ilat)); onn.name = "to"; - onn.radius = 1000; waypoints.add(onn); } else { waypoints.get(waypoints.size()-1).name = "via" + (waypoints.size()-1) + "_center"; @@ -212,7 +211,6 @@ public class RoutingEngine extends Thread { // System.out.println("back " + waypoints.get(i)); OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(waypoints.get(i).ilon, waypoints.get(i).ilat)); onn.name = "via"; - onn.radius = 1000; newpoints.add(onn); } newpoints.get(newpoints.size()-1).name = "to"; @@ -499,7 +497,6 @@ public class RoutingEngine extends Thread { OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via1"; - onn.radius = 1000; waypoints.add(onn); } else { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction-directionAdd); @@ -509,7 +506,6 @@ public class RoutingEngine extends Thread { OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via1"; - onn.radius = 1000; waypoints.add(onn); @@ -520,7 +516,6 @@ public class RoutingEngine extends Thread { onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); onn.name = "via2"; - onn.radius = 1000; waypoints.add(onn); pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius/2, direction); From 0b5df946b95b14238cccb58875844a6701b44c38 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 30 Jan 2025 18:11:41 +0100 Subject: [PATCH 08/28] disabled beelines on round trip --- .../java/btools/router/RoutingEngine.java | 83 ++++++++++--------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 3e85f9e..cb678aa 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -1204,49 +1204,52 @@ public class RoutingEngine extends Thread { 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) { - 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; - onn = new OsmNodeNamed(wp.crosspoint); - onn.name = wp.name + "_add"; - wp.waypoint = onn; - waypoints.add(nmw); - wp.name = wp.name + "_add"; - waypoints.add(wp); - } else { - 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; + if (engineMode != BROUTER_ENGINEMODE_ROUNDTRIP) { + MatchedWaypoint nmw = new MatchedWaypoint(); + if (i == 0) { + 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; + onn = new OsmNodeNamed(wp.crosspoint); + onn.name = wp.name + "_add"; + wp.waypoint = onn; + waypoints.add(nmw); + wp.name = wp.name + "_add"; + waypoints.add(wp); + } else { + 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; - if (wp.name != null) nmw.name = wp.name; - waypoints.add(nmw); - wp.name = wp.name + "_add"; - waypoints.add(wp); - if (wp.name.startsWith("via")) { - wp.direct = true; - MatchedWaypoint emw = new MatchedWaypoint(); - OsmNodeNamed onn2 = new OsmNodeNamed(wp.crosspoint); - onn2.name = wp.name + "_2"; - emw.name = onn2.name; - emw.waypoint = onn2; - 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; - waypoints.add(emw); + if (wp.name != null) nmw.name = wp.name; + waypoints.add(nmw); + wp.name = wp.name + "_add"; + waypoints.add(wp); + if (wp.name.startsWith("via")) { + wp.direct = true; + MatchedWaypoint emw = new MatchedWaypoint(); + OsmNodeNamed onn2 = new OsmNodeNamed(wp.crosspoint); + onn2.name = wp.name + "_2"; + emw.name = onn2.name; + emw.waypoint = onn2; + 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; + waypoints.add(emw); + } + wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); } - wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); + } else { + waypoints.add(wp); } - } else { waypoints.add(wp); } From 9fd52f02d3600048e0669cc109fe8b1d5a3e082a Mon Sep 17 00:00:00 2001 From: afischerdev Date: Sun, 9 Feb 2025 10:41:47 +0100 Subject: [PATCH 09/28] new round trip function --- .../java/btools/router/RoutingEngine.java | 233 ++++++++++-------- 1 file changed, 128 insertions(+), 105 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index cb678aa..d90714c 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -50,7 +50,7 @@ public class RoutingEngine extends Thread { private int engineMode = 0; - private int MAX_STEPS_CHECK = 250; + private int MAX_STEPS_CHECK = 500; private int ROUNDTRIP_DEFAULT_DIRECTIONADD = 45; @@ -205,15 +205,15 @@ public class RoutingEngine extends Thread { onn.name = "to"; waypoints.add(onn); } else { - waypoints.get(waypoints.size()-1).name = "via" + (waypoints.size()-1) + "_center"; + waypoints.get(waypoints.size() - 1).name = "via" + (waypoints.size() - 1) + "_center"; List newpoints = new ArrayList<>(); - for (int i = waypoints.size()-2; i >= 0; i--) { + for (int i = waypoints.size() - 2; i >= 0; i--) { // System.out.println("back " + waypoints.get(i)); OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(waypoints.get(i).ilon, waypoints.get(i).ilat)); onn.name = "via"; newpoints.add(onn); } - newpoints.get(newpoints.size()-1).name = "to"; + newpoints.get(newpoints.size() - 1).name = "to"; waypoints.addAll(newpoints); } } @@ -405,24 +405,24 @@ public class RoutingEngine extends Thread { } } int otherIdx = 0; - if (minIdx == t.nodes.size()-1) { - otherIdx = minIdx-1; + if (minIdx == t.nodes.size() - 1) { + otherIdx = minIdx - 1; } else { - otherIdx = minIdx+1; + 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; + 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); + n.nodeDescription = (start1 != null && start1.firstlink != null ? start1.firstlink.descriptionBitmap : null); t.pois.add(n); //t.message = "get_info"; //t.messageList.add(t.message); @@ -484,10 +484,10 @@ public class RoutingEngine extends Thread { wpt1.name = "roundtrip"; routingContext.useDynamicDistance = true; - double searchRadius = (routingContext.roundtripDistance == null ? 1500 :routingContext.roundtripDistance); - double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection); - if (direction == -1) direction = (int) (Math.random()*360); - double directionAdd = (routingContext.roundtripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundtripDirectionAdd); + double searchRadius = (routingContext.roundtripDistance == null ? 1500 : routingContext.roundtripDistance); + double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection); + if (direction == -1) direction = (int) (Math.random() * 360); + double directionAdd = (routingContext.roundtripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundtripDirectionAdd); if (routingContext.allowSamewayback) { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction); @@ -496,41 +496,11 @@ public class RoutingEngine extends Thread { wpt2.name = "rt1_" + direction; OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via1"; + onn.name = "rt1"; waypoints.add(onn); } else { - int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction-directionAdd); - MatchedWaypoint wpt2 = new MatchedWaypoint(); - wpt2.waypoint = new OsmNode(pos[0], pos[1]); - wpt2.name = "via1_" + (int) (direction-directionAdd); - - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via1"; - waypoints.add(onn); - - - pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction+directionAdd); - MatchedWaypoint wpt3 = new MatchedWaypoint(); - wpt3.waypoint = new OsmNode(pos[0], pos[1]); - wpt3.name = "via2_" + (int) (direction+directionAdd); - - onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via2"; - waypoints.add(onn); - - pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius/2, direction); - OsmNodeNamed n = new OsmNodeNamed(); - n.name = "nogo" + (int) (searchRadius/3); - n.ilon = pos[0]; - n.ilat = pos[1]; - n.isNogo = true; - n.radius = (int) (searchRadius/3); - n.nogoWeight = Double.NaN; - routingContext.setWaypoint(n, false); - - onn = new OsmNodeNamed(waypoints.get(0)); - onn.name = "to_rt"; - waypoints.add(onn); + //buildPointsFromAngle(waypoints, direction, directionAdd, searchRadius, true); + buildPointsFromCircle(waypoints, direction, searchRadius, 5); } routingContext.waypointCatchingRange = 1000; @@ -546,6 +516,50 @@ public class RoutingEngine extends Thread { } + void buildPointsFromAngle(List waypoints, double startAngle, double addAngle, double searchRadius, boolean withNogoCenter) { + int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, startAngle - addAngle); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "rt1"; + waypoints.add(onn); + + pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, startAngle + addAngle); + onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "rt2"; + waypoints.add(onn); + + onn = new OsmNodeNamed(waypoints.get(0)); + onn.name = "to_rt"; + waypoints.add(onn); + + if (withNogoCenter) { // add a nogo area + pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius/2, startAngle); + OsmNodeNamed n = new OsmNodeNamed(); + n.name = "nogo" + (int) (searchRadius/3); + n.ilon = pos[0]; + n.ilat = pos[1]; + n.isNogo = true; + n.radius = (int) (searchRadius/3); + n.nogoWeight = Double.NaN; + routingContext.setWaypoint(n, false); + } + } + + void buildPointsFromCircle(List waypoints, double startAngle, double searchRadius, int points) { + //startAngle -= 90; + for (int i = 1; i < points; i++) { + double anAngle = 90 - (180.0 * i / points); + int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, startAngle - anAngle); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "rt" + i; + waypoints.add(onn); + } + + OsmNodeNamed onn = new OsmNodeNamed(waypoints.get(0)); + onn.name = "to_rt"; + waypoints.add(onn); + } + + private void postElevationCheck(OsmTrack track) { OsmPathElement lastPt = null; OsmPathElement startPt = null; @@ -738,21 +752,21 @@ public class RoutingEngine extends Thread { // add extra waypoints from the last broken round for (OsmNodeNamed wp : extraWaypoints) { if (wp.direct) hasDirectRouting = true; - if (wp.name.startsWith("from")) { + if (wp.name.startsWith("from")) { waypoints.add(1, wp); waypoints.get(0).direct = true; nUnmatched++; } else { - waypoints.add(waypoints.size()-1, wp); - waypoints.get(waypoints.size()-2).direct = true; + waypoints.add(waypoints.size() - 1, wp); + waypoints.get(waypoints.size() - 2).direct = true; nUnmatched++; } } extraWaypoints = null; } - if (lastTracks.length < waypoints.size()-1) { - refTracks = new OsmTrack[waypoints.size()-1]; // used ways for alternatives - lastTracks = new OsmTrack[waypoints.size()-1]; + if (lastTracks.length < waypoints.size() - 1) { + refTracks = new OsmTrack[waypoints.size() - 1]; // used ways for alternatives + lastTracks = new OsmTrack[waypoints.size() - 1]; hasDirectRouting = true; } for (OsmNodeNamed wp : waypoints) { @@ -787,13 +801,14 @@ public class RoutingEngine extends Thread { int startSize = matchedWaypoints.size(); matchWaypointsToNodes(matchedWaypoints); if (startSize < matchedWaypoints.size()) { - refTracks = new OsmTrack[matchedWaypoints.size()-1]; // used ways for alternatives - lastTracks = new OsmTrack[matchedWaypoints.size()-1]; + refTracks = new OsmTrack[matchedWaypoints.size() - 1]; // used ways for alternatives + lastTracks = new OsmTrack[matchedWaypoints.size() - 1]; hasDirectRouting = true; } for (MatchedWaypoint mwp : matchedWaypoints) { - if (hasInfo() && matchedWaypoints.size() != nUnmatched) 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); @@ -823,9 +838,9 @@ public class RoutingEngine extends Thread { matchedWaypoints.add(nearbyTrack.endPoint); } } else { - if (lastTracks.length < matchedWaypoints.size()-1) { - refTracks = new OsmTrack[matchedWaypoints.size()-1]; // used ways for alternatives - lastTracks = new OsmTrack[matchedWaypoints.size()-1]; + if (lastTracks.length < matchedWaypoints.size() - 1) { + refTracks = new OsmTrack[matchedWaypoints.size() - 1]; // used ways for alternatives + lastTracks = new OsmTrack[matchedWaypoints.size() - 1]; hasDirectRouting = true; } } @@ -884,7 +899,7 @@ public class RoutingEngine extends Thread { // check for way back on way point private boolean snappPathConnection(OsmTrack tt, OsmTrack t, MatchedWaypoint startWp) { - if (!startWp.name.startsWith("via")) + if (!startWp.name.startsWith("via") && !startWp.name.startsWith("rt")) return false; int ourSize = tt.nodes.size(); @@ -977,7 +992,7 @@ public class RoutingEngine extends Thread { indexfore++; if (routingContext.correctMisplacedViaPointsDistance > 0 && - wayDistance > routingContext.correctMisplacedViaPointsDistance) break; + wayDistance > routingContext.correctMisplacedViaPointsDistance) break; } @@ -1188,7 +1203,8 @@ public class RoutingEngine extends Thread { range = -MAX_DYNAMIC_RANGE; List tmp = new ArrayList<>(); for (MatchedWaypoint mwp : unmatchedWaypoints) { - if (mwp.crosspoint == null || mwp.radius >= routingContext.waypointCatchingRange) tmp.add(mwp); + if (mwp.crosspoint == null || mwp.radius >= routingContext.waypointCatchingRange) + tmp.add(mwp); } ok = nodesCache.matchWaypointsToNodes(tmp, range, islandNodePairs); } @@ -1199,56 +1215,53 @@ public class RoutingEngine extends Thread { } } // add beeline points when not already done - if (useDynamicDistance && !useNodePoints) { + if (useDynamicDistance && !useNodePoints && engineMode != BROUTER_ENGINEMODE_ROUNDTRIP) { 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) { - if (engineMode != BROUTER_ENGINEMODE_ROUNDTRIP) { - MatchedWaypoint nmw = new MatchedWaypoint(); - if (i == 0) { - 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; - onn = new OsmNodeNamed(wp.crosspoint); - onn.name = wp.name + "_add"; - wp.waypoint = onn; - waypoints.add(nmw); - wp.name = wp.name + "_add"; - waypoints.add(wp); - } else { - 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; - if (wp.name != null) nmw.name = wp.name; - waypoints.add(nmw); - wp.name = wp.name + "_add"; - waypoints.add(wp); - if (wp.name.startsWith("via")) { - wp.direct = true; - MatchedWaypoint emw = new MatchedWaypoint(); - OsmNodeNamed onn2 = new OsmNodeNamed(wp.crosspoint); - onn2.name = wp.name + "_2"; - emw.name = onn2.name; - emw.waypoint = onn2; - 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; - waypoints.add(emw); - } - wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); - } - } else { + MatchedWaypoint nmw = new MatchedWaypoint(); + if (i == 0) { + 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; + onn = new OsmNodeNamed(wp.crosspoint); + onn.name = wp.name + "_add"; + wp.waypoint = onn; + waypoints.add(nmw); + wp.name = wp.name + "_add"; waypoints.add(wp); + } else { + 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; + + if (wp.name != null) nmw.name = wp.name; + waypoints.add(nmw); + wp.name = wp.name + "_add"; + waypoints.add(wp); + if (wp.name.startsWith("via")) { + wp.direct = true; + MatchedWaypoint emw = new MatchedWaypoint(); + OsmNodeNamed onn2 = new OsmNodeNamed(wp.crosspoint); + onn2.name = wp.name + "_2"; + emw.name = onn2.name; + emw.waypoint = onn2; + 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; + waypoints.add(emw); + } + wp.crosspoint = new OsmNode(wp.waypoint.ilon, wp.waypoint.ilat); } } else { waypoints.add(wp); @@ -1257,6 +1270,16 @@ public class RoutingEngine extends Thread { unmatchedWaypoints.clear(); unmatchedWaypoints.addAll(waypoints); } + + // round trip cross point to way point + if (engineMode == BROUTER_ENGINEMODE_ROUNDTRIP) { + for (int i = 1; i < unmatchedWaypoints.size()-1; i++) { + MatchedWaypoint wp = unmatchedWaypoints.get(i); + wp.waypoint.ilon = wp.crosspoint.ilon; + wp.waypoint.ilat = wp.crosspoint.ilat; + } + } + } private OsmTrack searchTrack(MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack) { From e19101ee26d5750b28da78394b0a6f338598401e Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 14 Feb 2025 10:18:50 +0100 Subject: [PATCH 10/28] added variable points for round trip --- .../src/main/java/btools/router/RoutingContext.java | 6 ++++++ brouter-core/src/main/java/btools/router/RoutingEngine.java | 2 +- 2 files changed, 7 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 8e03e96..045ac0c 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -77,6 +77,7 @@ public final class RoutingContext { public boolean correctMisplacedViaPoints; public double correctMisplacedViaPointsDistance; public boolean useDynamicDistance; + public int roundTripPoints; private void setModel(String className) { if (className == null) { @@ -171,6 +172,11 @@ public final class RoutingContext { useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 1f; + roundTripPoints = (int) expctxGlobal.getVariableValue("roundTripPoints", 5.f); + if (roundTripPoints < 3 || roundTripPoints > 20) { + roundTripPoints = 5; + } + boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f; if (!test) freeNoWays(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index d90714c..11d6442 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -500,7 +500,7 @@ public class RoutingEngine extends Thread { waypoints.add(onn); } else { //buildPointsFromAngle(waypoints, direction, directionAdd, searchRadius, true); - buildPointsFromCircle(waypoints, direction, searchRadius, 5); + buildPointsFromCircle(waypoints, direction, searchRadius, routingContext.roundTripPoints); } routingContext.waypointCatchingRange = 1000; From c509fb280b1a1975c197bc0aa896c3230f576d38 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 26 Feb 2025 17:32:44 +0100 Subject: [PATCH 11/28] moved roundTripPoints to internal vars --- .../src/main/java/btools/router/RoutingContext.java | 7 +------ .../src/main/java/btools/router/RoutingParamCollector.java | 5 +++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 045ac0c..888da30 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -77,7 +77,6 @@ public final class RoutingContext { public boolean correctMisplacedViaPoints; public double correctMisplacedViaPointsDistance; public boolean useDynamicDistance; - public int roundTripPoints; private void setModel(String className) { if (className == null) { @@ -172,11 +171,6 @@ public final class RoutingContext { useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 0f) == 1f; - roundTripPoints = (int) expctxGlobal.getVariableValue("roundTripPoints", 5.f); - if (roundTripPoints < 3 || roundTripPoints > 20) { - roundTripPoints = 5; - } - boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f; if (!test) freeNoWays(); @@ -199,6 +193,7 @@ public final class RoutingContext { public boolean forceUseStartDirection; public Integer roundtripDistance; public Integer roundtripDirectionAdd; + public Integer roundTripPoints; public boolean allowSamewayback; public CheapAngleMeter anglemeter = new CheapAngleMeter(); diff --git a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java index a169f07..05dab70 100644 --- a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java +++ b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java @@ -206,6 +206,11 @@ public class RoutingParamCollector { rctx.roundtripDistance = Integer.valueOf(value); } else if (key.equals("roundtripDirectionAdd")) { rctx.roundtripDirectionAdd = Integer.valueOf(value); + } else if (key.equals("roundTripPoints")) { + rctx.roundTripPoints = Integer.valueOf(value); + if (rctx.roundTripPoints == null || rctx.roundTripPoints < 3 || rctx.roundTripPoints > 20) { + rctx.roundTripPoints = 5; + } } else if (key.equals("allowSamewayback")) { rctx.allowSamewayback = Integer.parseInt(value)==1; } else if (key.equals("alternativeidx")) { From 901dd3ae550867d51132766c0034be5ae1cf3d17 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 26 Feb 2025 17:54:20 +0100 Subject: [PATCH 12/28] added info collector --- .../src/main/java/btools/router/AreaInfo.java | 74 +++++++++++++++++++ .../java/btools/router/RoutingContext.java | 4 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 brouter-core/src/main/java/btools/router/AreaInfo.java diff --git a/brouter-core/src/main/java/btools/router/AreaInfo.java b/brouter-core/src/main/java/btools/router/AreaInfo.java new file mode 100644 index 0000000..209bb68 --- /dev/null +++ b/brouter-core/src/main/java/btools/router/AreaInfo.java @@ -0,0 +1,74 @@ +package btools.router; + +import btools.expressions.BExpressionContext; + +public class AreaInfo { + final static int RESULT_TYPE_NONE = 0; + final static int RESULT_TYPE_ELEV50 = 1; + final static int RESULT_TYPE_GREEN = 4; + final static int RESULT_TYPE_RIVER = 5; + + public int direction; + public int numForest = -1; + public int numRiver = -1; + + public OsmNogoPolygon polygon; + + public int ways = 0; + public int greenWays = 0; + public int riverWays = 0; + public double elevStart = 0; + public int elev50 = 0; + public int elev100 = 0; + public int elevMore = 0; + + public AreaInfo(int dir) { + direction = dir; + } + + void checkGreeness(BExpressionContext expctxWay, double elev, byte[] ab) { + ways++; + + double test = elevStart - elev; + if (Math.abs(test) < 50) elev50++; + + int[] ld2 = expctxWay.createNewLookupData(); + expctxWay.decode(ld2, false, ab); + + if (numForest != -1 && ld2[numForest] > 1) { + greenWays++; + } + + if (numRiver != -1 && ld2[numForest] > 1) { + riverWays++; + } + + + } + + public int getElev50Weight() { + if (ways == 0) return 0; + return (int) (elev50 * 100. / ways); + } + + public int getGreen() { + if (ways == 0) return 0; + return (int) (greenWays * 100. / ways); + } + + public int getRiver() { + if (ways == 0) return 0; + return (int) (riverWays * 100. / ways); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Area ").append(direction).append(" ").append(elevStart).append("m ways ").append(ways); + if (ways > 0) { + sb.append("\nArea ways <50m " + elev50 + " " + getElev50Weight() + "%"); + sb.append("\nArea ways green " + greenWays + " " + getGreen() + "% " /*+ (greenWaysWeight/greenWays)*/); + sb.append("\nArea ways river " + riverWays + " " + getRiver() + "% " /*+ (greenWaysWeight/greenWays)*/); + } + return sb.toString(); + } +} diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 888da30..1ba7481 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -78,6 +78,8 @@ public final class RoutingContext { public double correctMisplacedViaPointsDistance; public boolean useDynamicDistance; + public AreaInfo ai; + private void setModel(String className) { if (className == null) { pm = new StdModel(); @@ -120,7 +122,7 @@ public final class RoutingContext { considerTurnRestrictions = 0.f != expctxGlobal.getVariableValue("considerTurnRestrictions", footMode ? 0.f : 1.f); correctMisplacedViaPoints = 0.f != expctxGlobal.getVariableValue("correctMisplacedViaPoints", 1.f); - correctMisplacedViaPointsDistance = expctxGlobal.getVariableValue("correctMisplacedViaPointsDistance", 40.f); + correctMisplacedViaPointsDistance = expctxGlobal.getVariableValue("correctMisplacedViaPointsDistance", 0.f); // 0 == don't use distance // process tags not used in the profile (to have them in the data-tab) processUnusedTags = 0.f != expctxGlobal.getVariableValue("processUnusedTags", 0.f); From c02e9cbae6741fcd61db498b758a4617862aa87f Mon Sep 17 00:00:00 2001 From: afischerdev Date: Thu, 27 Feb 2025 18:01:51 +0100 Subject: [PATCH 13/28] added an area info function --- .../src/main/java/btools/router/AreaInfo.java | 4 +- .../src/main/java/btools/router/OsmPath.java | 4 + .../java/btools/router/RoutingEngine.java | 147 ++++++++++++++++-- 3 files changed, 139 insertions(+), 16 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/AreaInfo.java b/brouter-core/src/main/java/btools/router/AreaInfo.java index 209bb68..ae6512f 100644 --- a/brouter-core/src/main/java/btools/router/AreaInfo.java +++ b/brouter-core/src/main/java/btools/router/AreaInfo.java @@ -26,7 +26,7 @@ public class AreaInfo { direction = dir; } - void checkGreeness(BExpressionContext expctxWay, double elev, byte[] ab) { + void checkAreaInfo(BExpressionContext expctxWay, double elev, byte[] ab) { ways++; double test = elevStart - elev; @@ -39,7 +39,7 @@ public class AreaInfo { greenWays++; } - if (numRiver != -1 && ld2[numForest] > 1) { + if (numRiver != -1 && ld2[numRiver] > 1) { riverWays++; } diff --git a/brouter-core/src/main/java/btools/router/OsmPath.java b/brouter-core/src/main/java/btools/router/OsmPath.java index 94549c9..9ce8123 100644 --- a/brouter-core/src/main/java/btools/router/OsmPath.java +++ b/brouter-core/src/main/java/btools/router/OsmPath.java @@ -141,6 +141,10 @@ abstract class OsmPath implements OsmLinkHolder { // evaluate the way tags rc.expctxWay.evaluate(rc.inverseDirection ^ isReverse, description); + // and check if is useful + if (rc.ai != null && rc.ai.polygon.isWithin(lon1, lat1)) { + rc.ai.checkAreaInfo(rc.expctxWay, ele1/4., description); + } // calculate the costfactor inputs float costfactor = rc.expctxWay.getCostfactor(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 11d6442..fd318e7 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -7,6 +7,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; +import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -225,6 +226,10 @@ public class RoutingEngine extends Thread { List messageList = new ArrayList<>(); for (int i = 0; ; i++) { track = findTrack(refTracks, lastTracks); + + // we are only looking for info + if (routingContext.ai != null) return; + track.message = "track-length = " + track.distance + " filtered ascend = " + track.ascend + " plain-ascend = " + track.plainAscend + " cost=" + track.cost; if (track.energy != 0) { @@ -478,7 +483,7 @@ public class RoutingEngine extends Thread { public void doRoundTrip() { try { - startTime = System.currentTimeMillis(); + long startTime = System.currentTimeMillis(); MatchedWaypoint wpt1 = new MatchedWaypoint(); wpt1.waypoint = waypoints.get(0); wpt1.name = "roundtrip"; @@ -486,8 +491,8 @@ public class RoutingEngine extends Thread { routingContext.useDynamicDistance = true; double searchRadius = (routingContext.roundtripDistance == null ? 1500 : routingContext.roundtripDistance); double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection); - if (direction == -1) direction = (int) (Math.random() * 360); double directionAdd = (routingContext.roundtripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundtripDirectionAdd); + if (direction == -1) direction = getRandomDirectionByRouting(waypoints.get(0), searchRadius); if (routingContext.allowSamewayback) { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction); @@ -500,15 +505,15 @@ public class RoutingEngine extends Thread { waypoints.add(onn); } else { //buildPointsFromAngle(waypoints, direction, directionAdd, searchRadius, true); - buildPointsFromCircle(waypoints, direction, searchRadius, routingContext.roundTripPoints); + buildPointsFromCircle(waypoints, direction, searchRadius, routingContext.roundTripPoints == null ? 5 : routingContext.roundTripPoints); } - routingContext.waypointCatchingRange = 1000; + routingContext.waypointCatchingRange = 250; doRouting(0); long endTime = System.currentTimeMillis(); - logInfo("execution time = " + (endTime - startTime) / 1000. + " seconds"); + logInfo("round trip execution time = " + (endTime - startTime) / 1000. + " seconds"); } catch (Exception e) { e.getStackTrace(); logException(e); @@ -559,6 +564,126 @@ public class RoutingEngine extends Thread { waypoints.add(onn); } + int getRandomDirectionByRouting(OsmNodeNamed wp, double searchRadius) { + + long start = System.currentTimeMillis(); + + int preferredRandomType = 0; + boolean consider_elevation = routingContext.expctxWay.getVariableValue("consider_elevation", 0f) == 1f; + boolean consider_forest = routingContext.expctxWay.getVariableValue("consider_forest", 0f) == 1f; + boolean consider_river = routingContext.expctxWay.getVariableValue("consider_river", 0f) == 1f; + if (consider_elevation) { + preferredRandomType = AreaInfo.RESULT_TYPE_ELEV50; + } else if (consider_forest) { + preferredRandomType = AreaInfo.RESULT_TYPE_GREEN; + } else if (consider_river) { + preferredRandomType = AreaInfo.RESULT_TYPE_RIVER; + } else { + return (int) (Math.random()*360); + } + + MatchedWaypoint wpt1 = new MatchedWaypoint(); + wpt1.waypoint = wp; + wpt1.name = "start_info"; + List listStart = new ArrayList<>(); + listStart.add(wpt1); + + List wpliststart = new ArrayList<>(); + wpliststart.add(wp); + + List listSearch = new ArrayList<>(); + + for (int a = 45; a < 360; a +=90) { + int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 2, a); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via" + a; + + MatchedWaypoint wpt = new MatchedWaypoint(); + wpt.waypoint = onn; + wpt.name = onn.name; + listStart.add(wpt); + } + + for (int a = 0; a < 360; a +=90) { + int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius, a); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via" + a; + listSearch.add(onn); + } + + RoutingEngine re = null; + RoutingContext rc = new RoutingContext(); + rc.localFunction = "dummy"; + + re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); + rc.useDynamicDistance = true; + re.matchWaypointsToNodes(listStart); + re.resetCache(true); + + int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); + int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); + + OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); + + double elev = (start1 == null ? 0 : start1.getElev()); + + List ais = new ArrayList<>(); + + listStart.remove(0); + for (int a = 0; a < 4; a++) { + rc.ai = new AreaInfo(a * 90 +90); + rc.ai.elevStart = elev; + rc.ai.numForest = numForest; + rc.ai.numRiver = numRiver; + + List wplist = new ArrayList<>(); + wplist.add(new OsmNodeNamed(listStart.get(a).waypoint)); + if (a == 3) wplist.add(new OsmNodeNamed(listStart.get(0).waypoint)); + else wplist.add(new OsmNodeNamed(listStart.get(a+1).waypoint)); + + rc.ai.polygon = new OsmNogoPolygon(true); + rc.ai.polygon.addVertex(wp.ilon, wp.ilat); + rc.ai.polygon.addVertex(wplist.get(0).ilon, wplist.get(0).ilat); + rc.ai.polygon.addVertex(wplist.get(1).ilon, wplist.get(1).ilat); + + List wpsearchlist = new ArrayList<>(); + wpsearchlist.add(listSearch.get(a)); + if (a == 3) wpsearchlist.add(listSearch.get(0)); + else wpsearchlist.add(listSearch.get(a+1)); + + rc.useDynamicDistance = true; + re = new RoutingEngine(null, null, segmentDir, wpsearchlist, rc, 0); + rc.processUnusedTags = true; + rc.turnInstructionMode = 9; + re.doRun(0); + + ais.add(rc.ai); + } + + logInfo("execution time get area = " + (System.currentTimeMillis() - start) / 1000. + " seconds"); + + + // for (AreaInfo ai: ais) { + // System.out.println("\n" + ai.toString()); + //} + + switch (preferredRandomType) { + case AreaInfo.RESULT_TYPE_ELEV50: + ais.sort(Comparator.comparingInt(AreaInfo::getElev50Weight)); + break; + case AreaInfo.RESULT_TYPE_GREEN: + ais.sort(Comparator.comparingInt(AreaInfo::getGreen)); + break; + case AreaInfo.RESULT_TYPE_RIVER: + ais.sort(Comparator.comparingInt(AreaInfo::getRiver)); + break; + default: + return (int) (Math.random()*360); + } + + int angle = ais.get(ais.size()-1).direction; + return angle - 45 + (int) (Math.random()*90); + } private void postElevationCheck(OsmTrack track) { OsmPathElement lastPt = null; @@ -868,6 +993,8 @@ public class RoutingEngine extends Thread { if (seg == null) return null; + if (routingContext.ai != null) return null; + boolean changed = false; if (routingContext.correctMisplacedViaPoints && !matchedWaypoints.get(i).direct && !routingContext.allowSamewayback) { changed = snappPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i)); @@ -1271,15 +1398,6 @@ public class RoutingEngine extends Thread { unmatchedWaypoints.addAll(waypoints); } - // round trip cross point to way point - if (engineMode == BROUTER_ENGINEMODE_ROUNDTRIP) { - for (int i = 1; i < unmatchedWaypoints.size()-1; i++) { - MatchedWaypoint wp = unmatchedWaypoints.get(i); - wp.waypoint.ilon = wp.crosspoint.ilon; - wp.waypoint.ilat = wp.crosspoint.ilat; - } - } - } private OsmTrack searchTrack(MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack) { @@ -1341,6 +1459,7 @@ public class RoutingEngine extends Thread { OsmTrack t; try { t = findTrack(cfi == 0 ? "pass0" : "pass1", startWp, endWp, track, refTrack, false); + if (routingContext.ai != null) return t; } catch (IllegalArgumentException iae) { if (!terminated && matchPath != null) { // timeout, but eventually prepare a dirty ref track logInfo("supplying dirty reference track after timeout"); From eb413181d6b8e1f883162fcaa34a8f6892afac37 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 28 Feb 2025 14:31:05 +0100 Subject: [PATCH 14/28] changes name for uniformity --- .../src/main/java/btools/router/RoutingContext.java | 4 ++-- .../src/main/java/btools/router/RoutingEngine.java | 4 ++-- .../main/java/btools/router/RoutingParamCollector.java | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 1ba7481..bc8706e 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -193,8 +193,8 @@ public final class RoutingContext { public Integer startDirection; public boolean startDirectionValid; public boolean forceUseStartDirection; - public Integer roundtripDistance; - public Integer roundtripDirectionAdd; + public Integer roundTripDistance; + public Integer roundTripDirectionAdd; public Integer roundTripPoints; public boolean allowSamewayback; diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index fd318e7..2fd7100 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -489,9 +489,9 @@ public class RoutingEngine extends Thread { wpt1.name = "roundtrip"; routingContext.useDynamicDistance = true; - double searchRadius = (routingContext.roundtripDistance == null ? 1500 : routingContext.roundtripDistance); + double searchRadius = (routingContext.roundTripDistance == null ? 1500 : routingContext.roundTripDistance); double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection); - double directionAdd = (routingContext.roundtripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundtripDirectionAdd); + double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundTripDirectionAdd); if (direction == -1) direction = getRandomDirectionByRouting(waypoints.get(0), searchRadius); if (routingContext.allowSamewayback) { diff --git a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java index 05dab70..f239315 100644 --- a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java +++ b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java @@ -202,10 +202,10 @@ public class RoutingParamCollector { rctx.forceUseStartDirection = true; } else if (key.equals("direction")) { rctx.startDirection = Integer.valueOf(value); - } else if (key.equals("roundtripDistance")) { - rctx.roundtripDistance = Integer.valueOf(value); - } else if (key.equals("roundtripDirectionAdd")) { - rctx.roundtripDirectionAdd = Integer.valueOf(value); + } else if (key.equals("roundTripDistance")) { + rctx.roundTripDistance = Integer.valueOf(value); + } else if (key.equals("roundTripDirectionAdd")) { + rctx.roundTripDirectionAdd = Integer.valueOf(value); } else if (key.equals("roundTripPoints")) { rctx.roundTripPoints = Integer.valueOf(value); if (rctx.roundTripPoints == null || rctx.roundTripPoints < 3 || rctx.roundTripPoints > 20) { From 03910506002bb1ab9334a0d8bb4b65cc2ccdeb1f Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 28 Feb 2025 14:53:01 +0100 Subject: [PATCH 15/28] changes to Collections.sort --- .../src/main/java/btools/router/RoutingEngine.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 2fd7100..fdb9000 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -7,6 +7,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; @@ -669,13 +670,13 @@ public class RoutingEngine extends Thread { switch (preferredRandomType) { case AreaInfo.RESULT_TYPE_ELEV50: - ais.sort(Comparator.comparingInt(AreaInfo::getElev50Weight)); + Collections.sort(ais, Comparator.comparingInt(AreaInfo::getElev50Weight)); break; case AreaInfo.RESULT_TYPE_GREEN: - ais.sort(Comparator.comparingInt(AreaInfo::getGreen)); + Collections.sort(ais, Comparator.comparingInt(AreaInfo::getGreen)); break; case AreaInfo.RESULT_TYPE_RIVER: - ais.sort(Comparator.comparingInt(AreaInfo::getRiver)); + Collections.sort(ais, Comparator.comparingInt(AreaInfo::getRiver)); break; default: return (int) (Math.random()*360); From 9224cace908b402e066c84480313d97d27472e3a Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 28 Feb 2025 16:13:05 +0100 Subject: [PATCH 16/28] changed to plain Comparator --- .../main/java/btools/router/RoutingEngine.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index fdb9000..66addd0 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -670,13 +670,25 @@ public class RoutingEngine extends Thread { switch (preferredRandomType) { case AreaInfo.RESULT_TYPE_ELEV50: - Collections.sort(ais, Comparator.comparingInt(AreaInfo::getElev50Weight)); + Collections.sort(ais, new Comparator() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getElev50Weight() - o1.getElev50Weight(); + } + }); break; case AreaInfo.RESULT_TYPE_GREEN: - Collections.sort(ais, Comparator.comparingInt(AreaInfo::getGreen)); + Collections.sort(ais, new Comparator() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getGreen() - o1.getGreen(); + } + }); break; case AreaInfo.RESULT_TYPE_RIVER: - Collections.sort(ais, Comparator.comparingInt(AreaInfo::getRiver)); + Collections.sort(ais, new Comparator() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getRiver() - o1.getRiver(); + } + }); break; default: return (int) (Math.random()*360); From 1040780c2d4bc38fccc202633cb26fba4419bf12 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Fri, 28 Feb 2025 16:20:52 +0100 Subject: [PATCH 17/28] removed type arguments --- brouter-core/src/main/java/btools/router/RoutingEngine.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 66addd0..4dbee89 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -670,21 +670,21 @@ public class RoutingEngine extends Thread { switch (preferredRandomType) { case AreaInfo.RESULT_TYPE_ELEV50: - Collections.sort(ais, new Comparator() { + Collections.sort(ais, new Comparator<>() { public int compare(AreaInfo o1, AreaInfo o2) { return o2.getElev50Weight() - o1.getElev50Weight(); } }); break; case AreaInfo.RESULT_TYPE_GREEN: - Collections.sort(ais, new Comparator() { + Collections.sort(ais, new Comparator<>() { public int compare(AreaInfo o1, AreaInfo o2) { return o2.getGreen() - o1.getGreen(); } }); break; case AreaInfo.RESULT_TYPE_RIVER: - Collections.sort(ais, new Comparator() { + Collections.sort(ais, new Comparator<>() { public int compare(AreaInfo o1, AreaInfo o2) { return o2.getRiver() - o1.getRiver(); } From 6a8863510dd4c2dec832e9c7085aa9005db83c0d Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 12 Mar 2025 10:09:57 +0100 Subject: [PATCH 18/28] new surrounding check' --- .../main/java/btools/router/AreaReader.java | 161 ++++++++++++++++++ .../java/btools/router/RoutingEngine.java | 150 +++++++++++++++- .../main/java/btools/mapaccess/OsmFile.java | 2 +- .../java/btools/mapaccess/PhysicalFile.java | 10 ++ 4 files changed, 314 insertions(+), 9 deletions(-) create mode 100644 brouter-core/src/main/java/btools/router/AreaReader.java diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java new file mode 100644 index 0000000..b302eb2 --- /dev/null +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -0,0 +1,161 @@ +package btools.router; + +import java.io.File; +import java.util.List; + +import btools.codec.DataBuffers; +import btools.codec.MicroCache; +import btools.expressions.BExpressionContextWay; +import btools.mapaccess.NodesCache; +import btools.mapaccess.OsmFile; +import btools.mapaccess.OsmLink; +import btools.mapaccess.OsmNode; +import btools.mapaccess.OsmNodesMap; +import btools.mapaccess.PhysicalFile; + +public class AreaReader { + + File segmentFolder; + + public void getDirectAllData(File folder, RoutingContext rc, OsmNodeNamed wp, int maxscale, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais) { + this.segmentFolder = folder; + + int cellsize = 1000000 / 32; + int scale = maxscale; + int count = 0; + int used = 0; + for (int idxLat = -scale; idxLat <= scale; idxLat++) { + for (int idxLon = -scale; idxLon <= scale; idxLon++) { + int tmplon = wp.ilon + cellsize * idxLon; + int tmplat = wp.ilat + cellsize * idxLat; + if (getDirectData(tmplon, tmplat, rc, expctxWay, searchRect, ais)) used++; + count++; + } + } + + } + + public boolean getDirectData(int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais) { + int lonDegree = inlon / 1000000; + int latDegree = inlat / 1000000; + int lonMod5 = (int) lonDegree % 5; + int latMod5 = (int) latDegree % 5; + + int lon = (int) lonDegree - 180 - lonMod5; + String slon = lon < 0 ? "W" + (-lon) : "E" + lon; + + int lat = (int) latDegree - 90 - latMod5; + String slat = lat < 0 ? "S" + (-lat) : "N" + lat; + lon = 180000000 + (int) (lon * 1000000 + 0.5); + lat = 90000000 + (int) (lat * 1000000 + 0.5); + + String filenameBase = slon + "_" + slat; + + File file = new File(segmentFolder, filenameBase + ".rd5"); + PhysicalFile pf = null; + + long maxmem = rc.memoryclass * 1024L * 1024L; // in MB + NodesCache nodesCache = new NodesCache(segmentFolder, expctxWay, rc.forceSecondaryData, maxmem, null, false); + + OsmNodesMap nodesMap = new OsmNodesMap(); + + try { + + DataBuffers dataBuffers = new DataBuffers(); + pf = new PhysicalFile(file, dataBuffers, -1, -1); + int div = pf.divisor; + + OsmFile osmf = new OsmFile(pf, lonDegree, latDegree, dataBuffers); + if (osmf.hasData()) { + int cellsize = 1000000 / div; + int tmplon = inlon; // + cellsize * idxLon; + int tmplat = inlat; // + cellsize * idxLat; + int lonIdx = tmplon / cellsize; + int latIdx = tmplat / cellsize; + int subIdx = (latIdx - div * latDegree) * div + (lonIdx - div * lonDegree); + + int subLonIdx = (lonIdx - div * lonDegree); + int subLatIdx = (latIdx - div * latDegree); + + OsmNogoPolygon dataRect = new OsmNogoPolygon(true); + lon = lonDegree * 1000000; + lat = latDegree * 1000000; + int tmplon2 = lon + cellsize * (subLonIdx); + int tmplat2 = lat + cellsize * (subLatIdx); + dataRect.addVertex(tmplon2, tmplat2); + + tmplon2 = lon + cellsize * (subLonIdx + 1); + tmplat2 = lat + cellsize * (subLatIdx); + dataRect.addVertex(tmplon2, tmplat2); + + tmplon2 = lon + cellsize * (subLonIdx + 1); + tmplat2 = lat + cellsize * (subLatIdx + 1); + dataRect.addVertex(tmplon2, tmplat2); + + tmplon2 = lon + cellsize * (subLonIdx); + tmplat2 = lat + cellsize * (subLatIdx + 1); + dataRect.addVertex(tmplon2, tmplat2); + + boolean intersects = searchRect.intersects(dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); + if (!intersects) + intersects = searchRect.intersects(dataRect.points.get(1).x, dataRect.points.get(1).y, dataRect.points.get(3).x, dataRect.points.get(3).y); + if (!intersects) + intersects = containsRect(searchRect, dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); + + if (!intersects) { + return false; + } + + MicroCache segment = osmf.createMicroCache(lonIdx, latIdx, dataBuffers, expctxWay, null, true, null); + + if (segment != null /*&& segment.getDataSize()>0*/) { + int size = segment.getSize(); + for (int i = 0; i < size; i++) { + long id = segment.getIdForIndex(i); + OsmNode node = new OsmNode(id); + if (segment.getAndClear(id)) { + node.parseNodeBody(segment, nodesMap, expctxWay); + if (node.firstlink instanceof OsmLink) { + for (OsmLink link = node.firstlink; link != null; link = link.getNext(node)) { + OsmNode nextNode = link.getTarget(node); + if (nextNode.firstlink == null) + continue; // don't care about dead ends + if (nextNode.firstlink.descriptionBitmap == null) + continue; + + for (AreaInfo ai : ais) { + if (ai.polygon.isWithin(node.ilon, node.ilat)) { + ai.checkAreaInfo(expctxWay, node.getElev(), nextNode.firstlink.descriptionBitmap); + break; + } + } + break; + } + } + } + } + } + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (pf != null) + try { + pf.close(); + } catch (Exception ee) { + } + nodesCache.close(); + nodesCache = null; + } + return false; + } + + /* + in this case the polygon is 'only' a rectangle + */ + boolean containsRect(OsmNogoPolygon searchRect, int p1x, int p1y, int p2x, int p2y) { + return searchRect.isWithin((long) p1x, (long) p1y) && + searchRect.isWithin(p2x, p2y); + } +} diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 4dbee89..1996488 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -485,15 +485,13 @@ public class RoutingEngine extends Thread { public void doRoundTrip() { try { long startTime = System.currentTimeMillis(); - MatchedWaypoint wpt1 = new MatchedWaypoint(); - wpt1.waypoint = waypoints.get(0); - wpt1.name = "roundtrip"; routingContext.useDynamicDistance = true; - double searchRadius = (routingContext.roundTripDistance == null ? 1500 : routingContext.roundTripDistance); - double direction = (routingContext.startDirection == null ? -1 : routingContext.startDirection); - double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD : routingContext.roundTripDirectionAdd); - if (direction == -1) direction = getRandomDirectionByRouting(waypoints.get(0), searchRadius); + double searchRadius = (routingContext.roundTripDistance == null ? 1500 :routingContext.roundTripDistance); + double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection); + double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundTripDirectionAdd); + //if (direction == -1) direction = getRandomDirectionFromRouting(waypoints.get(0), searchRadius); + if (direction == -1) direction = getRandomDirectionFromData(waypoints.get(0), searchRadius); if (routingContext.allowSamewayback) { int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, direction); @@ -565,7 +563,141 @@ public class RoutingEngine extends Thread { waypoints.add(onn); } - int getRandomDirectionByRouting(OsmNodeNamed wp, double searchRadius) { + int getRandomDirectionFromData(OsmNodeNamed wp, double searchRadius) { + + long start = System.currentTimeMillis(); + + int preferredRandomType = 0; + boolean consider_elevation = routingContext.expctxWay.getVariableValue("consider_elevation", 0f) == 1f; + boolean consider_forest = routingContext.expctxWay.getVariableValue("consider_forest", 0f) == 1f; + boolean consider_river = routingContext.expctxWay.getVariableValue("consider_river", 0f) == 1f; + if (consider_elevation) { + preferredRandomType = AreaInfo.RESULT_TYPE_ELEV50; + } else if (consider_forest) { + preferredRandomType = AreaInfo.RESULT_TYPE_GREEN; + } else if (consider_river) { + preferredRandomType = AreaInfo.RESULT_TYPE_RIVER; + } else { + return (int) (Math.random()*360); + } + + MatchedWaypoint wpt1 = new MatchedWaypoint(); + wpt1.waypoint = wp; + wpt1.name = "start_info"; + List listStart = new ArrayList<>(); + listStart.add(wpt1); + + List wpliststart = new ArrayList<>(); + wpliststart.add(wp); + + List listOne = new ArrayList<>(); + + for (int a = 45; a < 360; a +=90) { + int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 1.5, a); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via" + a; + listOne.add(onn); + + MatchedWaypoint wpt = new MatchedWaypoint(); + wpt.waypoint = onn; + wpt.name = onn.name; + listStart.add(wpt); + } + + RoutingEngine re = null; + RoutingContext rc = new RoutingContext(); + rc.localFunction = "dummy"; + + re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); + rc.useDynamicDistance = true; + re.matchWaypointsToNodes(listStart); + re.resetCache(true); + + int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); + int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); + + OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); + + double elev = (start1 == null ? 0 : start1.getElev()); // listOne.get(0).crosspoint.getElev(); + + List ais = new ArrayList<>(); + int maxlon = Integer.MIN_VALUE; + int minlon = Integer.MAX_VALUE; + int maxlat = Integer.MIN_VALUE; + int minlat = Integer.MAX_VALUE; + for (OsmNodeNamed on: listOne) { + maxlon = Math.max(on.ilon, maxlon); + minlon = Math.min(on.ilon, minlon); + maxlat = Math.max(on.ilat, maxlat); + minlat = Math.min(on.ilat, minlat); + } + OsmNogoPolygon searchRect = new OsmNogoPolygon(true); + searchRect.addVertex(maxlon, maxlat); + searchRect.addVertex(maxlon, minlat); + searchRect.addVertex(minlon, minlat); + searchRect.addVertex(minlon, maxlat); + + for (int a = 0; a < 4; a++) { + rc.ai = new AreaInfo(a * 90 +90); + rc.ai.elevStart = elev; + rc.ai.numForest = numForest; + rc.ai.numRiver = numRiver; + + rc.ai.polygon = new OsmNogoPolygon(true); + rc.ai.polygon.addVertex(wp.ilon, wp.ilat); + rc.ai.polygon.addVertex(listOne.get(a).ilon, listOne.get(a).ilat); + if (a==3) + rc.ai.polygon.addVertex(listOne.get(0).ilon, listOne.get(0).ilat); + else + rc.ai.polygon.addVertex(listOne.get(a+1).ilon, listOne.get(a+1).ilat); + + ais.add(rc.ai); + } + + int maxscale = Math.abs(searchRect.points.get(2).x - searchRect.points.get(0).x); + maxscale = Math.max(1, Math.round(maxscale/31250f/2)+1); + + new AreaReader().getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); + + logInfo("round trip execution time = " + (System.currentTimeMillis() - start) / 1000. + " seconds"); + + //for (AreaInfo ai: ais) { + // System.out.println("\n" + ai.toString()); + //} + + switch (preferredRandomType) { + case AreaInfo.RESULT_TYPE_ELEV50: + Collections.sort(ais, new Comparator<>() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getElev50Weight() - o1.getElev50Weight(); + } + }); + break; + case AreaInfo.RESULT_TYPE_GREEN: + Collections.sort(ais, new Comparator<>() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getGreen() - o1.getGreen(); + } + }); + break; + case AreaInfo.RESULT_TYPE_RIVER: + Collections.sort(ais, new Comparator<>() { + public int compare(AreaInfo o1, AreaInfo o2) { + return o2.getRiver() - o1.getRiver(); + } + }); + break; + default: + return (int) (Math.random()*360); + } + + rc.ai = null; + + int angle = ais.get(0).direction; + return angle - 45 + (int) (Math.random()*90); + } + + int getRandomDirectionFromRouting(OsmNodeNamed wp, double searchRadius) { long start = System.currentTimeMillis(); @@ -698,6 +830,8 @@ public class RoutingEngine extends Thread { return angle - 45 + (int) (Math.random()*90); } + + private void postElevationCheck(OsmTrack track) { OsmPathElement lastPt = null; OsmPathElement startPt = null; diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmFile.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmFile.java index 9b5724b..2df3844 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmFile.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmFile.java @@ -17,7 +17,7 @@ import btools.codec.WaypointMatcher; import btools.util.ByteDataReader; import btools.util.Crc32; -final class OsmFile { +final public class OsmFile { private RandomAccessFile is = null; private long fileOffset; diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/PhysicalFile.java b/brouter-mapaccess/src/main/java/btools/mapaccess/PhysicalFile.java index e61f469..0ea3af7 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/PhysicalFile.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/PhysicalFile.java @@ -143,4 +143,14 @@ final public class PhysicalFile { elevationType = dis.readByte(); } catch (Exception e) {} } + + public void close(){ + if (ra != null) { + try { + ra.close(); + } catch (Exception ee) { + } + } + } + } From a07fd6a4005ea1be0daf904bdf584e038b98e160 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 12 Mar 2025 18:55:55 +0100 Subject: [PATCH 19/28] fix 'dummy' parameter --- .../src/main/java/btools/router/RoutingEngine.java | 8 ++++++-- .../src/main/java/btools/routingapp/BRouterService.java | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 1996488..dac558d 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -606,7 +606,9 @@ public class RoutingEngine extends Thread { RoutingEngine re = null; RoutingContext rc = new RoutingContext(); - rc.localFunction = "dummy"; + String name = routingContext.localFunction; + int idx = name.lastIndexOf(File.separator); + rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx+1) + "dummy.brf"; re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); rc.useDynamicDistance = true; @@ -746,7 +748,9 @@ public class RoutingEngine extends Thread { RoutingEngine re = null; RoutingContext rc = new RoutingContext(); - rc.localFunction = "dummy"; + String name = routingContext.localFunction; + int idx = name.lastIndexOf(File.separator); + rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx+1) + "dummy.brf"; re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); rc.useDynamicDistance = true; 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 a1e8963..9dbdade 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java @@ -64,7 +64,8 @@ public class BRouterService extends Service { worker.segmentDir = new File(baseDir, "brouter/segments4"); String errMsg = null; - if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING) { + if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING || + engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUNDTRIP) { String remoteProfile = params.getString("remoteProfile", null); if (remoteProfile == null) { From a134c128bc47752ea701da0913430fe1ad018ed1 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 12 Mar 2025 19:01:57 +0100 Subject: [PATCH 20/28] added new dynamic --- brouter-core/src/main/java/btools/router/RoutingContext.java | 4 +++- brouter-core/src/main/java/btools/router/RoutingEngine.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index bc8706e..8daa9da 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -77,6 +77,7 @@ public final class RoutingContext { public boolean correctMisplacedViaPoints; public double correctMisplacedViaPointsDistance; public boolean useDynamicDistance; + public boolean buildBeelineOnRange; public AreaInfo ai; @@ -171,7 +172,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; + useDynamicDistance = expctxGlobal.getVariableValue("use_dynamic_range", 1f) == 1f; + buildBeelineOnRange = expctxGlobal.getVariableValue("add_beeline", 0f) == 1f; boolean test = expctxGlobal.getVariableValue("check_start_way", 1f) == 1f; if (!test) freeNoWays(); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index dac558d..f512a23 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -1473,6 +1473,7 @@ public class RoutingEngine extends Thread { private void matchWaypointsToNodes(List unmatchedWaypoints) { resetCache(false); boolean useDynamicDistance = routingContext.useDynamicDistance; + boolean bAddBeeline = routingContext.buildBeelineOnRange; double range = routingContext.waypointCatchingRange; boolean ok = nodesCache.matchWaypointsToNodes(unmatchedWaypoints, range, islandNodePairs); if (!ok && useDynamicDistance) { @@ -1493,7 +1494,7 @@ public class RoutingEngine extends Thread { } } // add beeline points when not already done - if (useDynamicDistance && !useNodePoints && engineMode != BROUTER_ENGINEMODE_ROUNDTRIP) { + if (useDynamicDistance && !useNodePoints && bAddBeeline) { List waypoints = new ArrayList<>(); for (int i = 0; i < unmatchedWaypoints.size(); i++) { MatchedWaypoint wp = unmatchedWaypoints.get(i); From 2ee44b7b8530ed052f24ed49c2b46db34d85d25c Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 12 Mar 2025 19:33:12 +0100 Subject: [PATCH 21/28] added nogo logic on round trip points --- .../src/main/java/btools/router/RoutingEngine.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index f512a23..f58a618 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -1140,6 +1140,18 @@ public class RoutingEngine extends Thread { } else { seg = searchTrack(matchedWaypoints.get(i), matchedWaypoints.get(i + 1), i == matchedWaypoints.size() - 2 ? nearbyTrack : null, refTracks[i]); wptIndex = i; + if (engineMode == BROUTER_ENGINEMODE_ROUNDTRIP) { + if (i < matchedWaypoints.size() - 2) { + OsmNode lastPoint = seg.containsNode(matchedWaypoints.get(i+1).node1) ? matchedWaypoints.get(i+1).node1 : matchedWaypoints.get(i+1).node2; + OsmNodeNamed nogo = new OsmNodeNamed(lastPoint); + nogo.radius = 5; + nogo.name = "nogo" + (i+1); + nogo.nogoWeight = 9999.; + nogo.isNogo = true; + if (routingContext.nogopoints == null) routingContext.nogopoints = new ArrayList<>(); + routingContext.nogopoints.add(nogo); + } + } } if (seg == null) return null; From a3c3b1e17bf57b61089d238c07e50766a827ee85 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Sat, 15 Mar 2025 15:36:08 +0100 Subject: [PATCH 22/28] exclude some areas from collection --- .../main/java/btools/router/AreaReader.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java index b302eb2..86e5be7 100644 --- a/brouter-core/src/main/java/btools/router/AreaReader.java +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -26,16 +26,17 @@ public class AreaReader { int used = 0; for (int idxLat = -scale; idxLat <= scale; idxLat++) { for (int idxLon = -scale; idxLon <= scale; idxLon++) { + if (ignoreCenter(maxscale, idxLon, idxLat)) continue; int tmplon = wp.ilon + cellsize * idxLon; int tmplat = wp.ilat + cellsize * idxLat; - if (getDirectData(tmplon, tmplat, rc, expctxWay, searchRect, ais)) used++; + if (getDirectData(tmplon, tmplat, rc, expctxWay, searchRect, ais, maxscale > 7)) used++; count++; } } } - public boolean getDirectData(int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais) { + public boolean getDirectData(int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais, boolean checkBorder) { int lonDegree = inlon / 1000000; int latDegree = inlat / 1000000; int lonMod5 = (int) lonDegree % 5; @@ -96,7 +97,13 @@ public class AreaReader { tmplat2 = lat + cellsize * (subLatIdx + 1); dataRect.addVertex(tmplon2, tmplat2); - boolean intersects = searchRect.intersects(dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); + // check for quadrant border + boolean intersects = checkBorder && dataRect.intersects(searchRect.points.get(0).x, searchRect.points.get(0).y, searchRect.points.get(2).x, searchRect.points.get(2).y); + if (!intersects && checkBorder) intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); + if (intersects) { + return false; + } + intersects = searchRect.intersects(dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); if (!intersects) intersects = searchRect.intersects(dataRect.points.get(1).x, dataRect.points.get(1).y, dataRect.points.get(3).x, dataRect.points.get(3).y); if (!intersects) @@ -151,6 +158,14 @@ public class AreaReader { return false; } + boolean ignoreCenter(int maxscale, int idxLon, int idxLat) { + int centerScale = (int) Math.round(maxscale * .2) -1; + if (centerScale < 0) return false; + if (idxLon >= -centerScale && idxLon <= centerScale && + idxLat >= -centerScale && idxLat <= centerScale) return true; + return false; + } + /* in this case the polygon is 'only' a rectangle */ From ddeb08c67d14541650e33ec57fbe28ce9a5e92cc Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 18 Mar 2025 10:26:45 +0100 Subject: [PATCH 23/28] added write/read area info --- .../main/java/btools/router/AreaReader.java | 66 ++++++- .../java/btools/router/RoutingContext.java | 1 + .../java/btools/router/RoutingEngine.java | 170 ++++++++++-------- 3 files changed, 159 insertions(+), 78 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java index 86e5be7..698f52a 100644 --- a/brouter-core/src/main/java/btools/router/AreaReader.java +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -1,11 +1,19 @@ package btools.router; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.List; import btools.codec.DataBuffers; import btools.codec.MicroCache; import btools.expressions.BExpressionContextWay; +import btools.mapaccess.MatchedWaypoint; import btools.mapaccess.NodesCache; import btools.mapaccess.OsmFile; import btools.mapaccess.OsmLink; @@ -99,7 +107,8 @@ public class AreaReader { // check for quadrant border boolean intersects = checkBorder && dataRect.intersects(searchRect.points.get(0).x, searchRect.points.get(0).y, searchRect.points.get(2).x, searchRect.points.get(2).y); - if (!intersects && checkBorder) intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); + if (!intersects && checkBorder) + intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); if (intersects) { return false; } @@ -159,10 +168,10 @@ public class AreaReader { } boolean ignoreCenter(int maxscale, int idxLon, int idxLat) { - int centerScale = (int) Math.round(maxscale * .2) -1; + int centerScale = (int) Math.round(maxscale * .2) - 1; if (centerScale < 0) return false; if (idxLon >= -centerScale && idxLon <= centerScale && - idxLat >= -centerScale && idxLat <= centerScale) return true; + idxLat >= -centerScale && idxLat <= centerScale) return true; return false; } @@ -173,4 +182,55 @@ public class AreaReader { return searchRect.isWithin((long) p1x, (long) p1y) && searchRect.isWithin(p2x, p2y); } + + public void writeAreaInfo(String filename, MatchedWaypoint wp, List ais) throws Exception { + DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename))); + + wp.writeToStream(dos); + for (AreaInfo ai : ais) { + dos.writeInt(ai.direction); + dos.writeDouble(ai.elevStart); + dos.writeInt(ai.ways); + dos.writeInt(ai.greenWays); + dos.writeInt(ai.riverWays); + dos.writeInt(ai.elev50); + } + dos.close(); + } + + public void readAreaInfo(File fai, MatchedWaypoint wp, List ais) { + DataInputStream dis = null; + MatchedWaypoint ep = null; + try { + dis = new DataInputStream(new BufferedInputStream(new FileInputStream(fai))); + ep = MatchedWaypoint.readFromStream(dis); + if (Math.abs(ep.waypoint.ilon - wp.waypoint.ilon) > 500 && + Math.abs(ep.waypoint.ilat - wp.waypoint.ilat) > 500) { + return; + } + if (Math.abs(ep.radius - wp.radius) > 500) { + return; + } + for (int i = 0; i < 4; i++) { + int direction = dis.readInt(); + AreaInfo ai = new AreaInfo(direction); + ai.elevStart = dis.readDouble(); + ai.ways = dis.readInt(); + ai.greenWays = dis.readInt(); + ai.riverWays = dis.readInt(); + ai.elev50 = dis.readInt(); + ais.add(ai); + } + } catch (IOException e) { + ais.clear(); + } finally { + if (dis != null) { + try { + dis.close(); + } catch (IOException e) { + } + } + } + } + } diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 8daa9da..f5b2bf3 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -36,6 +36,7 @@ public final class RoutingContext { public Map keyValues; public String rawTrackPath; + public String rawAreaPath; public String getProfileName() { String name = localFunction == null ? "unknown" : localFunction; diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index f58a618..f4e1109 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -583,87 +583,109 @@ public class RoutingEngine extends Thread { MatchedWaypoint wpt1 = new MatchedWaypoint(); wpt1.waypoint = wp; - wpt1.name = "start_info"; - List listStart = new ArrayList<>(); - listStart.add(wpt1); - - List wpliststart = new ArrayList<>(); - wpliststart.add(wp); - - List listOne = new ArrayList<>(); - - for (int a = 45; a < 360; a +=90) { - int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 1.5, a); - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via" + a; - listOne.add(onn); - - MatchedWaypoint wpt = new MatchedWaypoint(); - wpt.waypoint = onn; - wpt.name = onn.name; - listStart.add(wpt); - } - - RoutingEngine re = null; - RoutingContext rc = new RoutingContext(); - String name = routingContext.localFunction; - int idx = name.lastIndexOf(File.separator); - rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx+1) + "dummy.brf"; - - re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); - rc.useDynamicDistance = true; - re.matchWaypointsToNodes(listStart); - re.resetCache(true); - - int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); - int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); - - OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); - - double elev = (start1 == null ? 0 : start1.getElev()); // listOne.get(0).crosspoint.getElev(); + wpt1.name = "info"; + wpt1.radius = searchRadius * 1.5; List ais = new ArrayList<>(); - int maxlon = Integer.MIN_VALUE; - int minlon = Integer.MAX_VALUE; - int maxlat = Integer.MIN_VALUE; - int minlat = Integer.MAX_VALUE; - for (OsmNodeNamed on: listOne) { - maxlon = Math.max(on.ilon, maxlon); - minlon = Math.min(on.ilon, minlon); - maxlat = Math.max(on.ilat, maxlat); - minlat = Math.min(on.ilat, minlat); - } - OsmNogoPolygon searchRect = new OsmNogoPolygon(true); - searchRect.addVertex(maxlon, maxlat); - searchRect.addVertex(maxlon, minlat); - searchRect.addVertex(minlon, minlat); - searchRect.addVertex(minlon, maxlat); - - for (int a = 0; a < 4; a++) { - rc.ai = new AreaInfo(a * 90 +90); - rc.ai.elevStart = elev; - rc.ai.numForest = numForest; - rc.ai.numRiver = numRiver; - - rc.ai.polygon = new OsmNogoPolygon(true); - rc.ai.polygon.addVertex(wp.ilon, wp.ilat); - rc.ai.polygon.addVertex(listOne.get(a).ilon, listOne.get(a).ilat); - if (a==3) - rc.ai.polygon.addVertex(listOne.get(0).ilon, listOne.get(0).ilat); - else - rc.ai.polygon.addVertex(listOne.get(a+1).ilon, listOne.get(a+1).ilat); - - ais.add(rc.ai); + AreaReader areareader = new AreaReader(); + if (routingContext.rawAreaPath != null) { + File fai = new File(routingContext.rawAreaPath); + if (fai.exists()) { + areareader.readAreaInfo(fai, wpt1, ais); + } } - int maxscale = Math.abs(searchRect.points.get(2).x - searchRect.points.get(0).x); - maxscale = Math.max(1, Math.round(maxscale/31250f/2)+1); + if (ais.isEmpty()) { + List listStart = new ArrayList<>(); + listStart.add(wpt1); - new AreaReader().getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); + List wpliststart = new ArrayList<>(); + wpliststart.add(wp); + + List listOne = new ArrayList<>(); + + for (int a = 45; a < 360; a += 90) { + int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 1.5, a); + OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); + onn.name = "via" + a; + listOne.add(onn); + + MatchedWaypoint wpt = new MatchedWaypoint(); + wpt.waypoint = onn; + wpt.name = onn.name; + listStart.add(wpt); + } + + RoutingEngine re = null; + RoutingContext rc = new RoutingContext(); + String name = routingContext.localFunction; + int idx = name.lastIndexOf(File.separator); + rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx + 1) + "dummy.brf"; + + re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); + rc.useDynamicDistance = true; + re.matchWaypointsToNodes(listStart); + re.resetCache(true); + + int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); + int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); + + OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); + + double elev = (start1 == null ? 0 : start1.getElev()); // listOne.get(0).crosspoint.getElev(); + + int maxlon = Integer.MIN_VALUE; + int minlon = Integer.MAX_VALUE; + int maxlat = Integer.MIN_VALUE; + int minlat = Integer.MAX_VALUE; + for (OsmNodeNamed on : listOne) { + maxlon = Math.max(on.ilon, maxlon); + minlon = Math.min(on.ilon, minlon); + maxlat = Math.max(on.ilat, maxlat); + minlat = Math.min(on.ilat, minlat); + } + OsmNogoPolygon searchRect = new OsmNogoPolygon(true); + searchRect.addVertex(maxlon, maxlat); + searchRect.addVertex(maxlon, minlat); + searchRect.addVertex(minlon, minlat); + searchRect.addVertex(minlon, maxlat); + + for (int a = 0; a < 4; a++) { + rc.ai = new AreaInfo(a * 90 + 90); + rc.ai.elevStart = elev; + rc.ai.numForest = numForest; + rc.ai.numRiver = numRiver; + + rc.ai.polygon = new OsmNogoPolygon(true); + rc.ai.polygon.addVertex(wp.ilon, wp.ilat); + rc.ai.polygon.addVertex(listOne.get(a).ilon, listOne.get(a).ilat); + if (a == 3) + rc.ai.polygon.addVertex(listOne.get(0).ilon, listOne.get(0).ilat); + else + rc.ai.polygon.addVertex(listOne.get(a + 1).ilon, listOne.get(a + 1).ilat); + + ais.add(rc.ai); + } + + int maxscale = Math.abs(searchRect.points.get(2).x - searchRect.points.get(0).x); + maxscale = Math.max(1, Math.round(maxscale / 31250f / 2) + 1); + + areareader.getDirectAllData(segmentDir, rc, wp, maxscale, rc.expctxWay, searchRect, ais); + + if (routingContext.rawAreaPath != null) { + try { + wpt1.radius = searchRadius * 1.5; + areareader.writeAreaInfo(routingContext.rawAreaPath, wpt1, ais); + } catch (Exception e) { + } + } + rc.ai = null; + + } logInfo("round trip execution time = " + (System.currentTimeMillis() - start) / 1000. + " seconds"); - //for (AreaInfo ai: ais) { + // for (AreaInfo ai: ais) { // System.out.println("\n" + ai.toString()); //} @@ -693,8 +715,6 @@ public class RoutingEngine extends Thread { return (int) (Math.random()*360); } - rc.ai = null; - int angle = ais.get(0).direction; return angle - 45 + (int) (Math.random()*90); } From ac429bc0e79dcb05cb80d3c0818f3834ecd40db7 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 18 Mar 2025 10:27:12 +0100 Subject: [PATCH 24/28] added filename for the apk --- .../src/main/java/btools/routingapp/BRouterWorker.java | 1 + 1 file changed, 1 insertion(+) 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 c366b86..8f174dc 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java @@ -46,6 +46,7 @@ public class BRouterWorker { RoutingContext rc = new RoutingContext(); rc.rawTrackPath = rawTrackPath; + rc.rawAreaPath = rawTrackPath.substring(0, rawTrackPath.lastIndexOf(File.separator)+1) + "rawAreaInfo.dat"; rc.localFunction = profilePath; RoutingParamCollector routingParamCollector = new RoutingParamCollector(); From 79d41dc58b462700bf169cfb99e67468cb80b57b Mon Sep 17 00:00:00 2001 From: afischerdev Date: Sun, 23 Mar 2025 17:30:27 +0100 Subject: [PATCH 25/28] protected from null --- .../src/main/java/btools/routingapp/BRouterWorker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8f174dc..33ee802 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java @@ -46,7 +46,7 @@ public class BRouterWorker { RoutingContext rc = new RoutingContext(); rc.rawTrackPath = rawTrackPath; - rc.rawAreaPath = rawTrackPath.substring(0, rawTrackPath.lastIndexOf(File.separator)+1) + "rawAreaInfo.dat"; + rc.rawAreaPath = (rawTrackPath != null ? rawTrackPath.substring(0, rawTrackPath.lastIndexOf(File.separator)+1) + "rawAreaInfo.dat" : null); rc.localFunction = profilePath; RoutingParamCollector routingParamCollector = new RoutingParamCollector(); From 09001da91e19469ad88efa41766138aa5c39e34a Mon Sep 17 00:00:00 2001 From: afischerdev Date: Sun, 23 Mar 2025 17:33:42 +0100 Subject: [PATCH 26/28] normalized data read from rd5 --- .../main/java/btools/router/AreaReader.java | 139 +++++++++++------- 1 file changed, 87 insertions(+), 52 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java index 698f52a..4c0c83b 100644 --- a/brouter-core/src/main/java/btools/router/AreaReader.java +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -8,7 +8,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import btools.codec.DataBuffers; import btools.codec.MicroCache; @@ -28,57 +33,30 @@ public class AreaReader { public void getDirectAllData(File folder, RoutingContext rc, OsmNodeNamed wp, int maxscale, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais) { this.segmentFolder = folder; - int cellsize = 1000000 / 32; + int div = 32; + int cellsize = 1000000 / div; int scale = maxscale; int count = 0; int used = 0; + boolean checkBorder = maxscale > 7; + + Map tiles = new TreeMap<>(); for (int idxLat = -scale; idxLat <= scale; idxLat++) { for (int idxLon = -scale; idxLon <= scale; idxLon++) { if (ignoreCenter(maxscale, idxLon, idxLat)) continue; int tmplon = wp.ilon + cellsize * idxLon; int tmplat = wp.ilat + cellsize * idxLat; - if (getDirectData(tmplon, tmplat, rc, expctxWay, searchRect, ais, maxscale > 7)) used++; - count++; - } - } + int lonDegree = tmplon / 1000000; + int latDegree = tmplat / 1000000; + int lonMod5 = (int) lonDegree % 5; + int latMod5 = (int) latDegree % 5; - } + int lon = (int) lonDegree - 180 - lonMod5; + String slon = lon < 0 ? "W" + (-lon) : "E" + lon; + int lat = (int) latDegree - 90 - latMod5; + String slat = lat < 0 ? "S" + (-lat) : "N" + lat; + String filenameBase = slon + "_" + slat; - public boolean getDirectData(int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, OsmNogoPolygon searchRect, List ais, boolean checkBorder) { - int lonDegree = inlon / 1000000; - int latDegree = inlat / 1000000; - int lonMod5 = (int) lonDegree % 5; - int latMod5 = (int) latDegree % 5; - - int lon = (int) lonDegree - 180 - lonMod5; - String slon = lon < 0 ? "W" + (-lon) : "E" + lon; - - int lat = (int) latDegree - 90 - latMod5; - String slat = lat < 0 ? "S" + (-lat) : "N" + lat; - lon = 180000000 + (int) (lon * 1000000 + 0.5); - lat = 90000000 + (int) (lat * 1000000 + 0.5); - - String filenameBase = slon + "_" + slat; - - File file = new File(segmentFolder, filenameBase + ".rd5"); - PhysicalFile pf = null; - - long maxmem = rc.memoryclass * 1024L * 1024L; // in MB - NodesCache nodesCache = new NodesCache(segmentFolder, expctxWay, rc.forceSecondaryData, maxmem, null, false); - - OsmNodesMap nodesMap = new OsmNodesMap(); - - try { - - DataBuffers dataBuffers = new DataBuffers(); - pf = new PhysicalFile(file, dataBuffers, -1, -1); - int div = pf.divisor; - - OsmFile osmf = new OsmFile(pf, lonDegree, latDegree, dataBuffers); - if (osmf.hasData()) { - int cellsize = 1000000 / div; - int tmplon = inlon; // + cellsize * idxLon; - int tmplat = inlat; // + cellsize * idxLat; int lonIdx = tmplon / cellsize; int latIdx = tmplat / cellsize; int subIdx = (latIdx - div * latDegree) * div + (lonIdx - div * lonDegree); @@ -105,13 +83,13 @@ public class AreaReader { tmplat2 = lat + cellsize * (subLatIdx + 1); dataRect.addVertex(tmplon2, tmplat2); - // check for quadrant border boolean intersects = checkBorder && dataRect.intersects(searchRect.points.get(0).x, searchRect.points.get(0).y, searchRect.points.get(2).x, searchRect.points.get(2).y); if (!intersects && checkBorder) intersects = dataRect.intersects(searchRect.points.get(1).x, searchRect.points.get(1).y, searchRect.points.get(2).x, searchRect.points.get(3).y); if (intersects) { - return false; + continue; } + intersects = searchRect.intersects(dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); if (!intersects) intersects = searchRect.intersects(dataRect.points.get(1).x, dataRect.points.get(1).y, dataRect.points.get(3).x, dataRect.points.get(3).y); @@ -119,9 +97,73 @@ public class AreaReader { intersects = containsRect(searchRect, dataRect.points.get(0).x, dataRect.points.get(0).y, dataRect.points.get(2).x, dataRect.points.get(2).y); if (!intersects) { - return false; + continue; } + tiles.put(((long) tmplon) << 32 | tmplat, filenameBase); + count++; + } + } + + List> list = new ArrayList<>(tiles.entrySet()); + Collections.sort(list, new Comparator<>() { + @Override + public int compare(Map.Entry e1, Map.Entry e2) { + return e1.getValue().compareTo(e2.getValue()); + } + }); + + long maxmem = rc.memoryclass * 1024L * 1024L; // in MB + NodesCache nodesCache = new NodesCache(segmentFolder, expctxWay, rc.forceSecondaryData, maxmem, null, false); + PhysicalFile pf = null; + String lastFilenameBase = ""; + DataBuffers dataBuffers = null; + try { + for (Map.Entry entry : list) { + OsmNode n = new OsmNode(entry.getKey()); + // System.out.println("areareader set " + n.getILon() + "_" + n.getILat() + " " + entry.getValue()); + String filenameBase = entry.getValue(); + if (!filenameBase.equals(lastFilenameBase)) { + if (pf != null) pf.close(); + lastFilenameBase = filenameBase; + File file = new File(segmentFolder, filenameBase + ".rd5"); + dataBuffers = new DataBuffers(); + + pf = new PhysicalFile(file, dataBuffers, -1, -1); + } + if (getDirectData(pf, dataBuffers, n.getILon(), n.getILat(), rc, expctxWay, ais)) + used++; + } + } catch (Exception e) { + System.err.println(e.getMessage()); + } finally { + if (pf != null) + try { + pf.close(); + } catch (Exception ee) { + } + nodesCache.close(); + } + } + + public boolean getDirectData(PhysicalFile pf, DataBuffers dataBuffers, int inlon, int inlat, RoutingContext rc, BExpressionContextWay expctxWay, List ais) { + + int lonDegree = inlon / 1000000; + int latDegree = inlat / 1000000; + + OsmNodesMap nodesMap = new OsmNodesMap(); + + try { + int div = pf.divisor; + + OsmFile osmf = new OsmFile(pf, lonDegree, latDegree, dataBuffers); + if (osmf.hasData()) { + int cellsize = 1000000 / div; + int tmplon = inlon; // + cellsize * idxLon; + int tmplat = inlat; // + cellsize * idxLat; + int lonIdx = tmplon / cellsize; + int latIdx = tmplat / cellsize; + MicroCache segment = osmf.createMicroCache(lonIdx, latIdx, dataBuffers, expctxWay, null, true, null); if (segment != null /*&& segment.getDataSize()>0*/) { @@ -154,15 +196,8 @@ public class AreaReader { return true; } } catch (Exception e) { - e.printStackTrace(); + System.err.println(e.getMessage()); } finally { - if (pf != null) - try { - pf.close(); - } catch (Exception ee) { - } - nodesCache.close(); - nodesCache = null; } return false; } From ea3399d761ce705c40748c46790a70995c5e2f89 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Tue, 25 Mar 2025 13:31:19 +0100 Subject: [PATCH 27/28] pushed angle a little --- brouter-core/src/main/java/btools/router/RoutingEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index f4e1109..4352e38 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -716,7 +716,7 @@ public class RoutingEngine extends Thread { } int angle = ais.get(0).direction; - return angle - 45 + (int) (Math.random()*90); + return angle - 30 + (int) (Math.random() * 60); } int getRandomDirectionFromRouting(OsmNodeNamed wp, double searchRadius) { From 956557fa948b67fb4ff1261c92af360239257323 Mon Sep 17 00:00:00 2001 From: afischerdev Date: Wed, 26 Mar 2025 15:57:38 +0100 Subject: [PATCH 28/28] cleanup unused things --- .../src/main/java/btools/router/AreaInfo.java | 9 +- .../main/java/btools/router/AreaReader.java | 17 +- .../java/btools/router/RoutingEngine.java | 165 ------------------ 3 files changed, 11 insertions(+), 180 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/AreaInfo.java b/brouter-core/src/main/java/btools/router/AreaInfo.java index ae6512f..79f503e 100644 --- a/brouter-core/src/main/java/btools/router/AreaInfo.java +++ b/brouter-core/src/main/java/btools/router/AreaInfo.java @@ -19,8 +19,6 @@ public class AreaInfo { public int riverWays = 0; public double elevStart = 0; public int elev50 = 0; - public int elev100 = 0; - public int elevMore = 0; public AreaInfo(int dir) { direction = dir; @@ -43,7 +41,6 @@ public class AreaInfo { riverWays++; } - } public int getElev50Weight() { @@ -65,9 +62,9 @@ public class AreaInfo { StringBuilder sb = new StringBuilder(); sb.append("Area ").append(direction).append(" ").append(elevStart).append("m ways ").append(ways); if (ways > 0) { - sb.append("\nArea ways <50m " + elev50 + " " + getElev50Weight() + "%"); - sb.append("\nArea ways green " + greenWays + " " + getGreen() + "% " /*+ (greenWaysWeight/greenWays)*/); - sb.append("\nArea ways river " + riverWays + " " + getRiver() + "% " /*+ (greenWaysWeight/greenWays)*/); + sb.append("\nArea ways <50m ").append(elev50).append(" ").append(getElev50Weight()).append("%"); + sb.append("\nArea ways green ").append(greenWays).append(" ").append(getGreen()).append("%"); + sb.append("\nArea ways river ").append(riverWays).append(" ").append(getRiver()).append("%"); } return sb.toString(); } diff --git a/brouter-core/src/main/java/btools/router/AreaReader.java b/brouter-core/src/main/java/btools/router/AreaReader.java index 4c0c83b..d661e9b 100644 --- a/brouter-core/src/main/java/btools/router/AreaReader.java +++ b/brouter-core/src/main/java/btools/router/AreaReader.java @@ -135,7 +135,8 @@ public class AreaReader { used++; } } catch (Exception e) { - System.err.println(e.getMessage()); + System.err.println("AreaReader: after " + used + "/" + count + " " + e.getMessage()); + ais.clear(); } finally { if (pf != null) try { @@ -159,14 +160,14 @@ public class AreaReader { OsmFile osmf = new OsmFile(pf, lonDegree, latDegree, dataBuffers); if (osmf.hasData()) { int cellsize = 1000000 / div; - int tmplon = inlon; // + cellsize * idxLon; - int tmplat = inlat; // + cellsize * idxLat; + int tmplon = inlon; + int tmplat = inlat; int lonIdx = tmplon / cellsize; int latIdx = tmplat / cellsize; MicroCache segment = osmf.createMicroCache(lonIdx, latIdx, dataBuffers, expctxWay, null, true, null); - if (segment != null /*&& segment.getDataSize()>0*/) { + if (segment != null) { int size = segment.getSize(); for (int i = 0; i < size; i++) { long id = segment.getIdForIndex(i); @@ -196,8 +197,7 @@ public class AreaReader { return true; } } catch (Exception e) { - System.err.println(e.getMessage()); - } finally { + System.err.println("AreaReader: " + e.getMessage()); } return false; } @@ -205,9 +205,8 @@ public class AreaReader { boolean ignoreCenter(int maxscale, int idxLon, int idxLat) { int centerScale = (int) Math.round(maxscale * .2) - 1; if (centerScale < 0) return false; - if (idxLon >= -centerScale && idxLon <= centerScale && - idxLat >= -centerScale && idxLat <= centerScale) return true; - return false; + return idxLon >= -centerScale && idxLon <= centerScale && + idxLat >= -centerScale && idxLat <= centerScale; } /* diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 4352e38..698bc7b 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -490,7 +490,6 @@ public class RoutingEngine extends Thread { double searchRadius = (routingContext.roundTripDistance == null ? 1500 :routingContext.roundTripDistance); double direction = (routingContext.startDirection == null ? -1 :routingContext.startDirection); double directionAdd = (routingContext.roundTripDirectionAdd == null ? ROUNDTRIP_DEFAULT_DIRECTIONADD :routingContext.roundTripDirectionAdd); - //if (direction == -1) direction = getRandomDirectionFromRouting(waypoints.get(0), searchRadius); if (direction == -1) direction = getRandomDirectionFromData(waypoints.get(0), searchRadius); if (routingContext.allowSamewayback) { @@ -503,7 +502,6 @@ public class RoutingEngine extends Thread { onn.name = "rt1"; waypoints.add(onn); } else { - //buildPointsFromAngle(waypoints, direction, directionAdd, searchRadius, true); buildPointsFromCircle(waypoints, direction, searchRadius, routingContext.roundTripPoints == null ? 5 : routingContext.roundTripPoints); } @@ -520,34 +518,6 @@ public class RoutingEngine extends Thread { } - void buildPointsFromAngle(List waypoints, double startAngle, double addAngle, double searchRadius, boolean withNogoCenter) { - int[] pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, startAngle - addAngle); - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "rt1"; - waypoints.add(onn); - - pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius, startAngle + addAngle); - onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "rt2"; - waypoints.add(onn); - - onn = new OsmNodeNamed(waypoints.get(0)); - onn.name = "to_rt"; - waypoints.add(onn); - - if (withNogoCenter) { // add a nogo area - pos = CheapRuler.destination(waypoints.get(0).ilon, waypoints.get(0).ilat, searchRadius/2, startAngle); - OsmNodeNamed n = new OsmNodeNamed(); - n.name = "nogo" + (int) (searchRadius/3); - n.ilon = pos[0]; - n.ilat = pos[1]; - n.isNogo = true; - n.radius = (int) (searchRadius/3); - n.nogoWeight = Double.NaN; - routingContext.setWaypoint(n, false); - } - } - void buildPointsFromCircle(List waypoints, double startAngle, double searchRadius, int points) { //startAngle -= 90; for (int i = 1; i < points; i++) { @@ -719,141 +689,6 @@ public class RoutingEngine extends Thread { return angle - 30 + (int) (Math.random() * 60); } - int getRandomDirectionFromRouting(OsmNodeNamed wp, double searchRadius) { - - long start = System.currentTimeMillis(); - - int preferredRandomType = 0; - boolean consider_elevation = routingContext.expctxWay.getVariableValue("consider_elevation", 0f) == 1f; - boolean consider_forest = routingContext.expctxWay.getVariableValue("consider_forest", 0f) == 1f; - boolean consider_river = routingContext.expctxWay.getVariableValue("consider_river", 0f) == 1f; - if (consider_elevation) { - preferredRandomType = AreaInfo.RESULT_TYPE_ELEV50; - } else if (consider_forest) { - preferredRandomType = AreaInfo.RESULT_TYPE_GREEN; - } else if (consider_river) { - preferredRandomType = AreaInfo.RESULT_TYPE_RIVER; - } else { - return (int) (Math.random()*360); - } - - MatchedWaypoint wpt1 = new MatchedWaypoint(); - wpt1.waypoint = wp; - wpt1.name = "start_info"; - List listStart = new ArrayList<>(); - listStart.add(wpt1); - - List wpliststart = new ArrayList<>(); - wpliststart.add(wp); - - List listSearch = new ArrayList<>(); - - for (int a = 45; a < 360; a +=90) { - int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius * 2, a); - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via" + a; - - MatchedWaypoint wpt = new MatchedWaypoint(); - wpt.waypoint = onn; - wpt.name = onn.name; - listStart.add(wpt); - } - - for (int a = 0; a < 360; a +=90) { - int[] pos = CheapRuler.destination(wp.ilon, wp.ilat, searchRadius, a); - OsmNodeNamed onn = new OsmNodeNamed(new OsmNode(pos[0], pos[1])); - onn.name = "via" + a; - listSearch.add(onn); - } - - RoutingEngine re = null; - RoutingContext rc = new RoutingContext(); - String name = routingContext.localFunction; - int idx = name.lastIndexOf(File.separator); - rc.localFunction = idx == -1 ? "dummy" : name.substring(0, idx+1) + "dummy.brf"; - - re = new RoutingEngine(null, null, segmentDir, wpliststart, rc, BROUTER_ENGINEMODE_ROUNDTRIP); - rc.useDynamicDistance = true; - re.matchWaypointsToNodes(listStart); - re.resetCache(true); - - int numForest = rc.expctxWay.getLookupKey("estimated_forest_class"); - int numRiver = rc.expctxWay.getLookupKey("estimated_river_class"); - - OsmNode start1 = re.nodesCache.getStartNode(listStart.get(0).node1.getIdFromPos()); - - double elev = (start1 == null ? 0 : start1.getElev()); - - List ais = new ArrayList<>(); - - listStart.remove(0); - for (int a = 0; a < 4; a++) { - rc.ai = new AreaInfo(a * 90 +90); - rc.ai.elevStart = elev; - rc.ai.numForest = numForest; - rc.ai.numRiver = numRiver; - - List wplist = new ArrayList<>(); - wplist.add(new OsmNodeNamed(listStart.get(a).waypoint)); - if (a == 3) wplist.add(new OsmNodeNamed(listStart.get(0).waypoint)); - else wplist.add(new OsmNodeNamed(listStart.get(a+1).waypoint)); - - rc.ai.polygon = new OsmNogoPolygon(true); - rc.ai.polygon.addVertex(wp.ilon, wp.ilat); - rc.ai.polygon.addVertex(wplist.get(0).ilon, wplist.get(0).ilat); - rc.ai.polygon.addVertex(wplist.get(1).ilon, wplist.get(1).ilat); - - List wpsearchlist = new ArrayList<>(); - wpsearchlist.add(listSearch.get(a)); - if (a == 3) wpsearchlist.add(listSearch.get(0)); - else wpsearchlist.add(listSearch.get(a+1)); - - rc.useDynamicDistance = true; - re = new RoutingEngine(null, null, segmentDir, wpsearchlist, rc, 0); - rc.processUnusedTags = true; - rc.turnInstructionMode = 9; - re.doRun(0); - - ais.add(rc.ai); - } - - logInfo("execution time get area = " + (System.currentTimeMillis() - start) / 1000. + " seconds"); - - - // for (AreaInfo ai: ais) { - // System.out.println("\n" + ai.toString()); - //} - - switch (preferredRandomType) { - case AreaInfo.RESULT_TYPE_ELEV50: - Collections.sort(ais, new Comparator<>() { - public int compare(AreaInfo o1, AreaInfo o2) { - return o2.getElev50Weight() - o1.getElev50Weight(); - } - }); - break; - case AreaInfo.RESULT_TYPE_GREEN: - Collections.sort(ais, new Comparator<>() { - public int compare(AreaInfo o1, AreaInfo o2) { - return o2.getGreen() - o1.getGreen(); - } - }); - break; - case AreaInfo.RESULT_TYPE_RIVER: - Collections.sort(ais, new Comparator<>() { - public int compare(AreaInfo o1, AreaInfo o2) { - return o2.getRiver() - o1.getRiver(); - } - }); - break; - default: - return (int) (Math.random()*360); - } - - int angle = ais.get(ais.size()-1).direction; - return angle - 45 + (int) (Math.random()*90); - } - private void postElevationCheck(OsmTrack track) {