Skip to content

Commit

Permalink
move computeSurfaceFactor to BicycleParamsDefaultImpl and add test fo…
Browse files Browse the repository at this point in the history
…r the method
  • Loading branch information
simei94 committed Dec 16, 2024
1 parent b6536e1 commit 6282d86
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.matsim.contrib.bicycle;

import com.google.inject.Inject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.network.Link;
Expand All @@ -9,13 +10,13 @@
import org.matsim.core.mobsim.qsim.qnetsimengine.QVehicle;
import org.matsim.vehicles.Vehicle;

import jakarta.inject.Inject;
import org.matsim.vehicles.VehicleType;

import java.util.Objects;

public final class BicycleLinkSpeedCalculatorDefaultImpl implements BicycleLinkSpeedCalculator {
private static final Logger log = LogManager.getLogger(BicycleLinkSpeedCalculatorDefaultImpl.class );
@Inject private BicycleParams params;
@Inject private BicycleConfigGroup bicycleConfigGroup;
@Inject private QSimConfigGroup qSimConfigGroup;
@Inject private Config config;
Expand Down Expand Up @@ -47,7 +48,7 @@ public double getMaximumVelocityForLink(Link link, Vehicle vehicle) {
// prior to matsim 12.0 routers would not pass a vehicle. This is why we have a fallback for a default value from the config
double maxBicycleSpeed = vehicle == null ? bicycleConfigGroup.getMaxBicycleSpeedForRouting() : vehicle.getType().getMaximumVelocity();
double bicycleInfrastructureFactor = computeInfrastructureFactor(link);
double surfaceFactor = computeSurfaceFactor(link);
double surfaceFactor = params.computeSurfaceFactor(link);
double gradientFactor = computeGradientFactor(link);
double speed = maxBicycleSpeed * bicycleInfrastructureFactor * surfaceFactor * gradientFactor;
return Math.min(speed, link.getFreespeed());
Expand Down Expand Up @@ -79,69 +80,12 @@ private double computeGradientFactor(Link link) {
return factor;
}

// TODO combine this with comfort
private double computeSurfaceFactor(Link link) {
if (hasNotAttribute(link, BicycleUtils.WAY_TYPE)
|| BicycleUtils.CYCLEWAY.equals(link.getAttributes().getAttribute(BicycleUtils.WAY_TYPE))
|| hasNotAttribute(link, BicycleUtils.SURFACE)
) {
return 1.0;
}

//so, the link is NOT a cycleway, and has a surface attribute
String surface = (String) link.getAttributes().getAttribute(BicycleUtils.SURFACE);
switch (Objects.requireNonNull(surface)) {
case "paved":
case "asphalt":
return 1.0;

case "cobblestone (bad)":
case "grass":
return 0.4;

case "cobblestone;flattened":
case "cobblestone:flattened":
case "sett":
case "earth":
return 0.6;

case "concrete":
case "asphalt;paving_stones:35":
case "compacted":
return 0.9;

case "concrete:lanes":
case "concrete_plates":
case "concrete:plates":
case "paving_stones:3":
return 0.8;

case "paving_stones":
case "paving_stones:35":
case "paving_stones:30":
case "compressed":
case "bricks":
case "stone":
case "pebblestone":
case "fine_gravel":
case "gravel":
case "ground":
return 0.7;

case "sand":
return 0.2;

default:
return 0.5;
}
}

private double computeInfrastructureFactor(Link link) {
var speedFactor = link.getAttributes().getAttribute(BicycleUtils.BICYCLE_INFRASTRUCTURE_SPEED_FACTOR);
return speedFactor == null ? 1.0 : Double.parseDouble(speedFactor.toString());
}

private boolean hasNotAttribute(Link link, String attributeName) {
static boolean hasNotAttribute(Link link, String attributeName) {
return link.getAttributes().getAttribute(attributeName) == null;
}

Expand All @@ -155,7 +99,7 @@ private boolean isBike(QVehicle qVehicle) {
final VehicleType vehicleType = qVehicle.getVehicle().getType();

// the below consistentcy check is to broad; need a version that is more narrow ...

// if ( qSimConfigGroup.getVehiclesSource()== QSimConfigGroup.VehiclesSource.modeVehicleTypesFromVehiclesData ) {
// if ( !vehicleType.getId().toString().equals( vehicleType.getNetworkMode() ) ) {
// throw new RuntimeException( "You are using mode vehicles but the network mode of the vehicle type is wrong: vehType.id=" + vehicleType.getId()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ public interface BicycleParams {
double getInfrastructureFactor(String type, String cyclewaytype);

double getGradient(Link link);

double computeSurfaceFactor(Link link);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import org.matsim.api.core.v01.network.Link;

import java.util.Objects;

import static org.matsim.contrib.bicycle.BicycleLinkSpeedCalculatorDefaultImpl.hasNotAttribute;

public class BicycleParamsDefaultImpl implements BicycleParams {

// TODO Combine this with speeds?
Expand Down Expand Up @@ -60,6 +64,64 @@ public double getInfrastructureFactor( String type, String cyclewaytype ) {
}
}

// TODO combine this with comfort
@Override
public double computeSurfaceFactor(Link link) {
if (hasNotAttribute(link, BicycleUtils.WAY_TYPE)
|| BicycleUtils.CYCLEWAY.equals(link.getAttributes().getAttribute(BicycleUtils.WAY_TYPE))
|| hasNotAttribute(link, BicycleUtils.SURFACE)
) {
return 1.0;
}

//so, the link is NOT a cycleway, and has a surface attribute
String surface = (String) link.getAttributes().getAttribute(BicycleUtils.SURFACE);
switch (Objects.requireNonNull(surface)) {
case "paved":
case "asphalt":
return 1.0;

case "cobblestone (bad)":
case "grass":
return 0.4;

case "cobblestone;flattened":
case "cobblestone:flattened":
case "sett":
case "earth":
return 0.6;

case "concrete":
case "asphalt;paving_stones:35":
case "compacted":
return 0.9;

case "concrete:lanes":
case "concrete_plates":
case "concrete:plates":
case "paving_stones:3":
return 0.8;

case "paving_stones":
case "paving_stones:35":
case "paving_stones:30":
case "compressed":
case "bricks":
case "stone":
case "pebblestone":
case "fine_gravel":
case "gravel":
case "ground":
return 0.7;

case "sand":
return 0.2;

default:
return 0.5;
}
}

@Override
public double getGradient(Link link) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,30 @@ void testInfrastructureFactors() {
}
}

@Test
void testComputeSurfaceFactor() {
List<ObjectDoublePair<String>> surfaces = List.of(ObjectDoublePair.of("paved", 1.0), ObjectDoublePair.of("asphalt", 1.0),
ObjectDoublePair.of("concrete:lanes", .8), ObjectDoublePair.of("concrete_plates", .8), ObjectDoublePair.of("concrete:plates", .8),
ObjectDoublePair.of("fine_gravel", .7), ObjectDoublePair.of("paving_stones", .7), ObjectDoublePair.of("paving_stones:35", .7),
ObjectDoublePair.of("paving_stones:30", .7), ObjectDoublePair.of("compacted", .9),
ObjectDoublePair.of("asphalt;paving_stones:35", .9), ObjectDoublePair.of("bricks", .7), ObjectDoublePair.of("gravel", .7),
ObjectDoublePair.of("ground", .7), ObjectDoublePair.of("sett", .6), ObjectDoublePair.of("cobblestone;flattened", .6),
ObjectDoublePair.of("cobblestone:flattened", .6), ObjectDoublePair.of("stone", .7),
ObjectDoublePair.of("grass", .4), ObjectDoublePair.of("compressed", .7), ObjectDoublePair.of("paving_stones:3", .8),
ObjectDoublePair.of("cobblestone (bad)", .4), ObjectDoublePair.of("earth", .6), ObjectDoublePair.of("pebblestone", .7),
ObjectDoublePair.of("sand", .2), ObjectDoublePair.of("concrete", .9),
ObjectDoublePair.of(null, 1.), ObjectDoublePair.of("test:default", .5));

Link link = createLink(new Coord(0, 0), new Coord(100, 0));
link.getAttributes().putAttribute(BicycleUtils.WAY_TYPE, "type");

for (ObjectDoublePair<String> pair : surfaces) {
link.getAttributes().putAttribute(OsmTags.SURFACE, pair.left());
assertEquals(pair.rightDouble(), params.computeSurfaceFactor(link), 0.00001);
}

}

private static Link createLink(Coord from, Coord to) {

Network net = NetworkUtils.createNetwork();
Expand Down

0 comments on commit 6282d86

Please sign in to comment.