diff --git a/brouter-core/src/main/java/btools/router/OsmPath.java b/brouter-core/src/main/java/btools/router/OsmPath.java index fe8da57..1771858 100644 --- a/brouter-core/src/main/java/btools/router/OsmPath.java +++ b/brouter-core/src/main/java/btools/router/OsmPath.java @@ -30,8 +30,6 @@ final class OsmPath implements OsmLinkHolder // if the corresponding node has not public short selev; - private static final int MAX_EHB = 10000000; - public int adjustedCost = 0; public void setAirDistanceCostAdjustment( int costAdjustment ) @@ -199,30 +197,60 @@ final class OsmPath implements OsmLinkHolder ehbu += (ele2 - ele1)*elefactor - dist * rc.uphillcutoff; } - if ( ehbd > MAX_EHB ) + float downweight = 0.f; + if ( ehbd > rc.elevationpenaltybuffer ) { + downweight = 1.f; + + int excess = ehbd - rc.elevationpenaltybuffer; + int reduce = dist * rc.elevationbufferreduce; + if ( reduce > excess ) + { + downweight = ((float)reduce)/excess; + reduce = excess; + } + excess = ehbd - rc.elevationmaxbuffer; + if ( reduce < excess ) + { + reduce = excess; + } + ehbd -= reduce; if ( rc.downhillcostdiv > 0 ) { - int elevationCost = (ehbd-MAX_EHB)/rc.downhillcostdiv; + int elevationCost = reduce/rc.downhillcostdiv; cost += elevationCost; linkelevationcost += elevationCost; } - ehbd = MAX_EHB; } else if ( ehbd < 0 ) { ehbd = 0; } - if ( ehbu > MAX_EHB ) + float upweight = 0.f; + if ( ehbu > rc.elevationpenaltybuffer ) { - if ( rc.uphillcostdiv > 0 ) - { - int elevationCost = (ehbu-MAX_EHB)/rc.uphillcostdiv; - cost += elevationCost; - linkelevationcost += elevationCost; - } - ehbu = MAX_EHB; + upweight = 1.f; + + int excess = ehbu - rc.elevationpenaltybuffer; + int reduce = dist * rc.elevationbufferreduce; + if ( reduce > excess ) + { + upweight = ((float)reduce)/excess; + reduce = excess; + } + excess = ehbu - rc.elevationmaxbuffer; + if ( reduce < excess ) + { + reduce = excess; + } + ehbu -= reduce; + if ( rc.uphillcostdiv > 0 ) + { + int elevationCost = reduce/rc.uphillcostdiv; + cost += elevationCost; + linkelevationcost += elevationCost; + } } else if ( ehbu < 0 ) { @@ -230,9 +258,16 @@ final class OsmPath implements OsmLinkHolder } // *** penalty for distance - float costfactor = rc.expctxWay.getCostfactor(); + 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; + + float costfactor = cfup*upweight + cf*(1.f - upweight - downweight) + cfdown*downweight; float fcost = dist * costfactor + 0.5f; - if ( costfactor >= 10000. || fcost + cost >= 2000000000. ) + if ( cf >= 10000. || fcost + cost >= 2000000000. ) { cost = -1; return; @@ -241,10 +276,10 @@ final class OsmPath implements OsmLinkHolder cost += waycost; // *** add initial cost if factor changed - float costdiff = costfactor - lastCostfactor; + float costdiff = cf - lastCostfactor; if ( costdiff > 0.0005 || costdiff < -0.0005 ) { - lastCostfactor = costfactor; + lastCostfactor = cf; float initialcost = rc.expctxWay.getInitialcost(); int iicost = (int)initialcost; cost += iicost; @@ -252,7 +287,8 @@ final class OsmPath implements OsmLinkHolder if ( recordTransferNodes ) { - int iCost = (int)(rc.expctxWay.getCostfactor()*1000 + 0.5f); + int iCost = (int)(costfactor*1000 + 0.5f); + //int iCost = (int)(rc.expctxWay.getCostfactor()*1000 + 0.5f); lastMessage = (lon2-180000000) + "\t" + (lat2-90000000) + "\t" + ele2/4 + "\t" diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index 7792786..3a70589 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -47,6 +47,9 @@ public final class RoutingContext implements DistanceChecker public boolean carMode; public double pass1coefficient; public double pass2coefficient; + public int elevationpenaltybuffer; + public int elevationmaxbuffer; + public int elevationbufferreduce; public void readGlobalConfig( BExpressionContext expctxGlobal ) { @@ -59,6 +62,9 @@ public final class RoutingContext implements DistanceChecker carMode = 0.f != expctxGlobal.getVariableValue( "validForCars", 0.f ); pass1coefficient = expctxGlobal.getVariableValue( "pass1coefficient", 1.5f ); pass2coefficient = expctxGlobal.getVariableValue( "pass2coefficient", 0.f ); + elevationpenaltybuffer = (int)(expctxGlobal.getVariableValue( "elevationpenaltybuffer", 10.f )*1000000); + elevationmaxbuffer = (int)(expctxGlobal.getVariableValue( "elevationmaxbuffer", 10.f )*1000000); + elevationbufferreduce = (int)(expctxGlobal.getVariableValue( "elevationbufferreduce", 1.f )*10000); } public RoutingMessageHandler messageHandler = new RoutingMessageHandler(); diff --git a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java index 81a56d6..4eb2716 100644 --- a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java +++ b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java @@ -60,16 +60,22 @@ public final class BExpressionContext // build-in variable indexes for fast access private int costfactorIdx; private int turncostIdx; + private int uphillcostfactorIdx; + private int downhillcostfactorIdx; private int initialcostIdx; private int nodeaccessgrantedIdx; private float[] _arrayCostfactor; private float[] _arrayTurncost; + private float[] _arrayUphillCostfactor; + private float[] _arrayDownhillCostfactor; private float[] _arrayInitialcost; private float[] _arrayNodeAccessGranted; public float getCostfactor() { return _arrayCostfactor[currentHashBucket]; } public float getTurncost() { return _arrayTurncost[currentHashBucket]; } + public float getUphillCostfactor() { return _arrayUphillCostfactor[currentHashBucket]; } + public float getDownhillCostfactor() { return _arrayDownhillCostfactor[currentHashBucket]; } public float getInitialcost() { return _arrayInitialcost[currentHashBucket]; } public float getNodeAccessGranted() { return _arrayNodeAccessGranted[currentHashBucket]; } @@ -102,6 +108,8 @@ public final class BExpressionContext _arrayCostfactor = new float[hashSize]; _arrayTurncost = new float[hashSize]; + _arrayUphillCostfactor = new float[hashSize]; + _arrayDownhillCostfactor = new float[hashSize]; _arrayInitialcost = new float[hashSize]; _arrayNodeAccessGranted = new float[hashSize]; } @@ -423,6 +431,8 @@ public final class BExpressionContext _arrayCostfactor[currentHashBucket] = variableData[costfactorIdx]; _arrayTurncost[currentHashBucket] = variableData[turncostIdx]; + _arrayUphillCostfactor[currentHashBucket] = variableData[uphillcostfactorIdx]; + _arrayDownhillCostfactor[currentHashBucket] = variableData[downhillcostfactorIdx]; _arrayInitialcost[currentHashBucket] = variableData[initialcostIdx]; _arrayNodeAccessGranted[currentHashBucket] = variableData[nodeaccessgrantedIdx]; @@ -608,9 +618,12 @@ public final class BExpressionContext costfactorIdx = getVariableIdx( "costfactor", true ); turncostIdx = getVariableIdx( "turncost", true ); + uphillcostfactorIdx = getVariableIdx( "uphillcostfactor", true ); + downhillcostfactorIdx = getVariableIdx( "downhillcostfactor", true ); initialcostIdx = getVariableIdx( "initialcost", true ); nodeaccessgrantedIdx = getVariableIdx( "nodeaccessgranted", true ); + expressionList = _parseFile( file ); float[] readOnlyData = variableData; variableData = new float[variableNumbers.size()];