
org.opentripplanner.ext.dataoverlay.DataOverlayStreetEdgeCostExtension Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
The newest version!
package org.opentripplanner.ext.dataoverlay;
import java.io.Serializable;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import net.objecthunter.exp4j.tokenizer.UnknownFunctionOrVariableException;
import org.opentripplanner.ext.dataoverlay.configuration.TimeUnit;
import org.opentripplanner.ext.dataoverlay.routing.DataOverlayContext;
import org.opentripplanner.ext.dataoverlay.routing.Parameter;
import org.opentripplanner.street.model.edge.StreetEdgeCostExtension;
import org.opentripplanner.street.search.TraverseMode;
import org.opentripplanner.street.search.state.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstract grid data description class which is stored at StreetEdge.
*
* @author Katja Danilova
*/
class DataOverlayStreetEdgeCostExtension implements StreetEdgeCostExtension, Serializable {
private static final Logger LOG = LoggerFactory.getLogger(
DataOverlayStreetEdgeCostExtension.class
);
private final Instant dataStartTime;
private final Map variableValues;
private final TimeUnit timeUnit;
/**
* Sets the abstract grid data
*
* @param dataStartTime the time when the grid records start
* @param variableValues map of variable names and arrays of their values
* @param timeUnit time unit of the data overlay
*/
DataOverlayStreetEdgeCostExtension(
Instant dataStartTime,
Map variableValues,
TimeUnit timeUnit
) {
this.dataStartTime = dataStartTime;
this.variableValues = variableValues;
this.timeUnit = timeUnit;
}
@Override
public double calculateExtraCost(State state, int edgeLength, TraverseMode traverseMode) {
if (traverseMode.isWalking() || traverseMode.isCyclingIsh()) {
return calculateDataOverlayPenalties(state) * edgeLength / 1000;
}
return 0d;
}
/**
* Calculates the total penalties based on request parameters and overlay data
*
* @return total penalty
*/
private double calculateDataOverlayPenalties(State s) {
if (variableValues == null) {
return 0d;
}
double totalPenalty = 0d;
Instant requestInstant = s.getRequest().startTime();
DataOverlayContext context = s.dataOverlayContext();
for (Parameter parameter : context.getParameters()) {
var threshold = parameter.getThreshold();
var penalty = parameter.getPenalty();
String indexVariableName = parameter.getVariable();
Instant dataStartTime = Instant.EPOCH;
float[] genDataValuesForTime = new float[0];
if (variableValues.containsKey(indexVariableName)) {
dataStartTime = this.dataStartTime;
genDataValuesForTime = variableValues.get(indexVariableName);
}
//calculate time format based on the input file settings
int dataQualityRequestedTime = timeUnit.between(dataStartTime, requestInstant);
if (dataQualityRequestedTime >= 0) {
if (dataQualityRequestedTime < genDataValuesForTime.length) {
float value = genDataValuesForTime[dataQualityRequestedTime];
String penaltyFormulaString = parameter.getFormula();
double penaltyForParameters = calculatePenaltyFromParameters(
penaltyFormulaString,
value,
threshold,
penalty
);
if (penaltyForParameters >= 0) {
totalPenalty += penaltyForParameters;
}
} else {
LOG.warn("No available data overlay for the given time");
}
}
}
return totalPenalty;
}
/**
* Uses the formula from the penalty parameter and calculates the penalty based on that
*
* @param formula penalty formula
* @param value data
* @param threshold threshold parameter value
* @param penalty penalty parameter value
* @return penalty
*/
private double calculatePenaltyFromParameters(
String formula,
float value,
double threshold,
double penalty
) {
Map variables = new HashMap<>();
variables.put("THRESHOLD", threshold);
variables.put("PENALTY", penalty);
variables.put("VALUE", (double) value);
try {
Expression expression = new ExpressionBuilder(formula)
.variables(variables.keySet().toArray(new String[0]))
.build()
.setVariables(variables);
return expression.evaluate();
} catch (UnknownFunctionOrVariableException ex) {
throw new IllegalArgumentException(
String.format("Formula %s did not receive all the required parameters", formula)
);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy