From 829baba0373c6be9786a18b17be7c6c835f88a28 Mon Sep 17 00:00:00 2001 From: quaelnix <122357328+quaelnix@users.noreply.github.com> Date: Sun, 15 Jan 2023 17:41:30 +0100 Subject: [PATCH] Allow hill cost and hill cutoff in way context This removes the limitation that `downhillcutoff` and `uphillcutoff` as well as `downhillcost` and `uphillcost` cannot be used in the way context. --- .../java/btools/router/KinematicPath.java | 4 +- .../src/main/java/btools/router/OsmPath.java | 4 +- .../java/btools/router/RoutingContext.java | 10 ---- .../java/btools/router/RoutingEngine.java | 4 +- .../src/main/java/btools/router/StdPath.java | 49 +++++++++++++------ .../expressions/BExpressionContextWay.java | 18 ++++++- 6 files changed, 56 insertions(+), 33 deletions(-) diff --git a/brouter-core/src/main/java/btools/router/KinematicPath.java b/brouter-core/src/main/java/btools/router/KinematicPath.java index bcb43182a..41f7a0384 100644 --- a/brouter-core/src/main/java/btools/router/KinematicPath.java +++ b/brouter-core/src/main/java/btools/router/KinematicPath.java @@ -248,12 +248,12 @@ private void cutEkin(double weight, double speed) { @Override - public int elevationCorrection(RoutingContext rc) { + public int elevationCorrection() { return 0; } @Override - public boolean definitlyWorseThan(OsmPath path, RoutingContext rc) { + public boolean definitlyWorseThan(OsmPath path) { KinematicPath p = (KinematicPath) path; int c = p.cost; diff --git a/brouter-core/src/main/java/btools/router/OsmPath.java b/brouter-core/src/main/java/btools/router/OsmPath.java index f9c0101ff..e0b29090c 100644 --- a/brouter-core/src/main/java/btools/router/OsmPath.java +++ b/brouter-core/src/main/java/btools/router/OsmPath.java @@ -409,9 +409,9 @@ public short interpolateEle(short e1, short e2, double fraction) { protected void computeKinematic(RoutingContext rc, double dist, double delta_h, boolean detailMode) { } - public abstract int elevationCorrection(RoutingContext rc); + public abstract int elevationCorrection(); - public abstract boolean definitlyWorseThan(OsmPath p, RoutingContext rc); + public abstract boolean definitlyWorseThan(OsmPath p); public OsmNode getSourceNode() { return sourceNode; diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 120c3ce19..b565808c9 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -52,10 +52,6 @@ public String getProfileName() { public int memoryclass = 64; - public int downhillcostdiv; - public int downhillcutoff; - public int uphillcostdiv; - public int uphillcutoff; public boolean carMode; public boolean bikeMode; public boolean footMode; @@ -123,12 +119,6 @@ public void readGlobalConfig() { setModel(expctxGlobal._modelClass); - downhillcostdiv = (int) expctxGlobal.getVariableValue("downhillcost", 0.f); - downhillcutoff = (int) (expctxGlobal.getVariableValue("downhillcutoff", 0.f) * 10000); - uphillcostdiv = (int) expctxGlobal.getVariableValue("uphillcost", 0.f); - uphillcutoff = (int) (expctxGlobal.getVariableValue("uphillcutoff", 0.f) * 10000); - if (downhillcostdiv != 0) downhillcostdiv = 1000000 / downhillcostdiv; - if (uphillcostdiv != 0) uphillcostdiv = 1000000 / uphillcostdiv; carMode = 0.f != expctxGlobal.getVariableValue("validForCars", 0.f); bikeMode = 0.f != expctxGlobal.getVariableValue("validForBikes", 0.f); footMode = 0.f != expctxGlobal.getVariableValue("validForFoot", 0.f); diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index 77b9eac7e..48ce81ccd 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -977,7 +977,7 @@ private OsmTrack _findTrack(String operationName, MatchedWaypoint startWp, Match if (parentcost < firstMatchCost) firstMatchCost = parentcost; int costEstimate = path.cost - + path.elevationCorrection(routingContext) + + path.elevationCorrection() + (costCuttingTrack.cost - pe.cost); if (costEstimate <= maxTotalCost) { matchPath = OsmPathElement.create(path, routingContext.countTraffic); @@ -1110,7 +1110,7 @@ private OsmTrack _findTrack(String operationName, MatchedWaypoint startWp, Match OsmLinkHolder dominator = link.getFirstLinkHolder(currentNode); while (!trafficSim && dominator != null) { OsmPath dp = (OsmPath) dominator; - if (dp.airdistance != -1 && bestPath.definitlyWorseThan(dp, routingContext)) { + if (dp.airdistance != -1 && bestPath.definitlyWorseThan(dp)) { break; } dominator = dominator.getNextForLink(); diff --git a/brouter-core/src/main/java/btools/router/StdPath.java b/brouter-core/src/main/java/btools/router/StdPath.java index b890c27d0..4b6d4ce90 100644 --- a/brouter-core/src/main/java/btools/router/StdPath.java +++ b/brouter-core/src/main/java/btools/router/StdPath.java @@ -18,6 +18,9 @@ final class StdPath extends OsmPath { private float totalEnergy; // total route energy (Joule) private float elevation_buffer; // just another elevation buffer (for travel time) + private int uphillcostdiv; + private int downhillcostdiv; + // Gravitational constant, g private static final double GRAVITY = 9.81; // in meters per second^(-2) @@ -37,6 +40,8 @@ protected void resetState() { ehbu = 0; totalTime = 0.f; totalEnergy = 0.f; + uphillcostdiv = 0; + downhillcostdiv = 0; elevation_buffer = 0.f; } @@ -44,12 +49,24 @@ protected void resetState() { protected double processWaySection(RoutingContext rc, double distance, double delta_h, double elevation, double angle, double cosangle, boolean isStartpoint, int nsection, int lastpriorityclassifier) { // calculate the costfactor inputs float turncostbase = rc.expctxWay.getTurncost(); + float uphillcutoff = rc.expctxWay.getUphillcutoff() * 10000; + float downhillcutoff = rc.expctxWay.getDownhillcutoff() * 10000; float cfup = rc.expctxWay.getUphillCostfactor(); float cfdown = rc.expctxWay.getDownhillCostfactor(); float cf = rc.expctxWay.getCostfactor(); cfup = cfup == 0.f ? cf : cfup; cfdown = cfdown == 0.f ? cf : cfdown; + downhillcostdiv = (int) rc.expctxWay.getDownhillcost(); + if (downhillcostdiv > 0) { + downhillcostdiv = 1000000 / downhillcostdiv; + } + + uphillcostdiv = (int) rc.expctxWay.getUphillcost(); + if (uphillcostdiv > 0) { + uphillcostdiv = 1000000 / uphillcostdiv; + } + int dist = (int) distance; // legacy arithmetics needs int // penalty for turning angle @@ -66,8 +83,8 @@ protected double processWaySection(RoutingContext rc, double distance, double de // leads to an immediate penalty int delta_h_micros = (int) (1000000. * delta_h); - ehbd += -delta_h_micros - dist * rc.downhillcutoff; - ehbu += delta_h_micros - dist * rc.uphillcutoff; + ehbd += -delta_h_micros - dist * downhillcutoff; + ehbu += delta_h_micros - dist * uphillcutoff; float downweight = 0.f; if (ehbd > rc.elevationpenaltybuffer) { @@ -84,8 +101,8 @@ protected double processWaySection(RoutingContext rc, double distance, double de reduce = excess; } ehbd -= reduce; - if (rc.downhillcostdiv > 0) { - int elevationCost = reduce / rc.downhillcostdiv; + if (downhillcostdiv > 0) { + int elevationCost = reduce / downhillcostdiv; sectionCost += elevationCost; if (message != null) { message.linkelevationcost += elevationCost; @@ -110,8 +127,8 @@ protected double processWaySection(RoutingContext rc, double distance, double de reduce = excess; } ehbu -= reduce; - if (rc.uphillcostdiv > 0) { - int elevationCost = reduce / rc.uphillcostdiv; + if (uphillcostdiv > 0) { + int elevationCost = reduce / uphillcostdiv; sectionCost += elevationCost; if (message != null) { message.linkelevationcost += elevationCost; @@ -153,23 +170,23 @@ protected double processTargetNode(RoutingContext rc) { } @Override - public int elevationCorrection(RoutingContext rc) { - return (rc.downhillcostdiv > 0 ? ehbd / rc.downhillcostdiv : 0) - + (rc.uphillcostdiv > 0 ? ehbu / rc.uphillcostdiv : 0); + public int elevationCorrection() { + return (downhillcostdiv > 0 ? ehbd / downhillcostdiv : 0) + + (uphillcostdiv > 0 ? ehbu / uphillcostdiv : 0); } @Override - public boolean definitlyWorseThan(OsmPath path, RoutingContext rc) { + public boolean definitlyWorseThan(OsmPath path) { StdPath p = (StdPath) path; int c = p.cost; - if (rc.downhillcostdiv > 0) { - int delta = p.ehbd - ehbd; - if (delta > 0) c += delta / rc.downhillcostdiv; + if (p.downhillcostdiv > 0) { + int delta = p.ehbd / p.downhillcostdiv - (downhillcostdiv > 0 ? ehbd / downhillcostdiv : 0); + if (delta > 0) c += delta; } - if (rc.uphillcostdiv > 0) { - int delta = p.ehbu - ehbu; - if (delta > 0) c += delta / rc.uphillcostdiv; + if (p.uphillcostdiv > 0) { + int delta = p.ehbu / p.uphillcostdiv - (uphillcostdiv > 0 ? ehbu / uphillcostdiv : 0); + if (delta > 0) c += delta; } return cost > c; diff --git a/brouter-expressions/src/main/java/btools/expressions/BExpressionContextWay.java b/brouter-expressions/src/main/java/btools/expressions/BExpressionContextWay.java index 9d286f5d2..5b37b7cee 100644 --- a/brouter-expressions/src/main/java/btools/expressions/BExpressionContextWay.java +++ b/brouter-expressions/src/main/java/btools/expressions/BExpressionContextWay.java @@ -12,7 +12,7 @@ public final class BExpressionContextWay extends BExpressionContext implements T private boolean decodeForbidden = true; private static String[] buildInVariables = - {"costfactor", "turncost", "uphillcostfactor", "downhillcostfactor", "initialcost", "nodeaccessgranted", "initialclassifier", "trafficsourcedensity", "istrafficbackbone", "priorityclassifier", "classifiermask", "maxspeed"}; + {"costfactor", "turncost", "uphillcostfactor", "downhillcostfactor", "initialcost", "nodeaccessgranted", "initialclassifier", "trafficsourcedensity", "istrafficbackbone", "priorityclassifier", "classifiermask", "maxspeed", "uphillcost", "downhillcost", "uphillcutoff", "downhillcutoff"}; protected String[] getBuildInVariableNames() { return buildInVariables; @@ -66,6 +66,22 @@ public float getMaxspeed() { return getBuildInVariable(11); } + public float getUphillcost() { + return getBuildInVariable(12); + } + + public float getDownhillcost() { + return getBuildInVariable(13); + } + + public float getUphillcutoff() { + return getBuildInVariable(14); + } + + public float getDownhillcutoff() { + return getBuildInVariable(15); + } + public BExpressionContextWay(BExpressionMetaData meta) { super("way", meta); }