Dynamic weighting based on timeband

Hi,

As part of our routing we support Historical speeds based on a time band, for example.

34.28@(Mo-Fr04:00-07:00);28.49@(Mo-Fr07:00-09:00);30.74@(Mo-Fr09:00-12:00);31.7@(Mo-Fr12:00-14:00);30.58@(Mo-Fr14:00-16:00);27.84@(Mo-Fr16:00-19:00);23.82@(Mo-Fr19:00-22:00);35.24@(Mo-Fr22:00-04:00);26.23@(Sa-Su04:00-07:00);25.75@(Sa-Su07:00-10:00);

As part of calculating the weight per edge i am hardcoding a time band range for testing “16:00-19:00” these weights come from OS road data which provides the weight of each edge based on the time of the day.

If the edge has a time band weight “weight @” then we will use this as the return, if no weight is present for the edge then use the default logic.

When i pick a time band such as rush hour 16:00-19:00 there is no difference in the route select than picking a route for 04:00-07:00 which obviously in there would be in places such as London

@Override
public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) {
double priority = edgeToPriorityMapping.get(edgeState, reverse);
if (priority == 0) return Double.POSITIVE_INFINITY;

    final double distance = edgeState.getDistance();
    double speed = 0;

    Map<String, KVStorage.KValue> obj = edgeState.getKeyValues();
    String fullTimebands = null;

    if (reverse) {
        KVStorage.KValue value = obj.get("avgspeed_backward_conditional");
        fullTimebands = (value != null) ? value.toString() : null;
    } else {
        KVStorage.KValue value = obj.get("avgspeed_forward_conditional");
        fullTimebands = (value != null) ? value.toString() : null;
    }

    if (fullTimebands != null) {
        Pattern timebandRegex = Pattern.compile("([\\d.]+)@\\(Mo-Fr16:00-19:00\\)");
        Matcher matcher = timebandRegex.matcher(fullTimebands);
        if (matcher.find()) {
            String speedStr = matcher.group(1);
            if (speedStr != null && !speedStr.isEmpty()) {
                speed = Double.parseDouble(speedStr);
            }
        }
    }

    if (speed <= 0) {
        speed = edgeToSpeedMapping.get(edgeState, reverse);
        if (speed <= 0) return Double.POSITIVE_INFINITY;
    }

    double seconds = distance / speed * SPEED_CONV;
    if (Double.isInfinite(seconds)) return Double.POSITIVE_INFINITY;

    if (edgeState.get(EdgeIteratorState.UNFAVORED_EDGE)) {
        seconds += headingPenaltySeconds;
    }

    double distanceCosts = distance * distanceInfluence;
    if (Double.isInfinite(distanceCosts)) return Double.POSITIVE_INFINITY;

    return seconds / priority + distanceCosts;
}