diff --git a/src/main/java/com/conveyal/osmlib/main/SpeedSetter.java b/src/main/java/com/conveyal/osmlib/main/SpeedSetter.java index f969435c4..803f8c095 100644 --- a/src/main/java/com/conveyal/osmlib/main/SpeedSetter.java +++ b/src/main/java/com/conveyal/osmlib/main/SpeedSetter.java @@ -25,9 +25,13 @@ public static void main (String[] args) throws Exception { String[] fields = line.split(","); long osmWayId = Long.parseLong(fields[0]); double speedKph = Double.parseDouble(fields[1]); + double walkFactor = Double.parseDouble(fields[2]); + double bikeFactor = Double.parseDouble(fields[2]); Way way = osm.ways.get(osmWayId); // R5 currently prioritizes maxspeed:motorcar above all other maxspeed tags way.addOrReplaceTag("maxspeed:motorcar", String.format("%1.1f kph", speedKph)); + way.addOrReplaceTag("walk_factor", String.format("%1.1f", walkFactor)); + way.addOrReplaceTag("bike_factor", String.format("%1.1f", bikeFactor)); osm.ways.put(osmWayId, way); } } diff --git a/src/main/java/com/conveyal/r5/streets/CustomBikeCostSupplier.java b/src/main/java/com/conveyal/r5/streets/CustomBikeCostSupplier.java new file mode 100644 index 000000000..6399ecb9a --- /dev/null +++ b/src/main/java/com/conveyal/r5/streets/CustomBikeCostSupplier.java @@ -0,0 +1,19 @@ +package com.conveyal.r5.streets; + +public class CustomBikeCostSupplier implements SingleModeTraversalTimes.Supplier { + private final CustomCostTags tags; + + public CustomBikeCostSupplier(CustomCostTags tags) { + this.tags = tags; + } + + @Override + public double perceivedLengthMultipler () { + return tags.bikeFactor; + } + + @Override + public int turnTimeSeconds (SingleModeTraversalTimes.TurnDirection turnDirection) { + return 0; + } +} \ No newline at end of file diff --git a/src/main/java/com/conveyal/r5/streets/CustomCostTags.java b/src/main/java/com/conveyal/r5/streets/CustomCostTags.java new file mode 100644 index 000000000..bee99ccc4 --- /dev/null +++ b/src/main/java/com/conveyal/r5/streets/CustomCostTags.java @@ -0,0 +1,39 @@ +package com.conveyal.r5.streets; + +import com.conveyal.osmlib.Way; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * For both directions (forward and backward) of a single OSM Way, tags used to represent the per-edge factors + * contributing to generalized costs. + */ +public class CustomCostTags { + + private static final Logger LOG = LoggerFactory.getLogger(CustomCostTags.class); + + final double walkFactor; + final double bikeFactor; + + public CustomCostTags(Way way) { + walkFactor = parseDoubleTag(way, "walk_factor"); + bikeFactor = parseDoubleTag(way, "bike_factor"); + } + + /** + * Read a single tag from the given OSM way and interpret it as a double-precision floating point value. + * If no tag is present, or if the tag cannot be parsed as a double, use default generalized cost value (1). + */ + private static double parseDoubleTag (Way way, String tagKey) { + String tagValue = way.getTag(tagKey); + if (tagValue == null) { + return 1; + } + try { + return Double.parseDouble(tagValue); + } catch (NumberFormatException nfe) { + LOG.error("Could not parse generalized cost tag as a double: " + tagValue); + return 1; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/conveyal/r5/streets/CustomWalkCostSupplier.java b/src/main/java/com/conveyal/r5/streets/CustomWalkCostSupplier.java new file mode 100644 index 000000000..ad5d4216e --- /dev/null +++ b/src/main/java/com/conveyal/r5/streets/CustomWalkCostSupplier.java @@ -0,0 +1,19 @@ +package com.conveyal.r5.streets; + +public class CustomWalkCostSupplier implements SingleModeTraversalTimes.Supplier { + private final CustomCostTags tags; + + public CustomWalkCostSupplier(CustomCostTags tags) { + this.tags = tags; + } + + @Override + public double perceivedLengthMultipler () { + return tags.walkFactor; + } + + @Override + public int turnTimeSeconds (SingleModeTraversalTimes.TurnDirection turnDirection) { + return 0; + } +} \ No newline at end of file diff --git a/src/main/java/com/conveyal/r5/streets/EdgeTraversalTimes.java b/src/main/java/com/conveyal/r5/streets/EdgeTraversalTimes.java index 07d515bdf..18d6ec0bc 100644 --- a/src/main/java/com/conveyal/r5/streets/EdgeTraversalTimes.java +++ b/src/main/java/com/conveyal/r5/streets/EdgeTraversalTimes.java @@ -44,12 +44,13 @@ public int turnTimeSeconds (int fromEdge, int toEdge, StreetMode streetMode) { public void setEdgePair (int forwardEdge, Way way) { int backwardEdge = forwardEdge + 1; - LaDotCostTags forwardTags = new LaDotCostTags(way, FORWARD); - walkTraversalTimes.setOneEdge(forwardEdge, new LaDotWalkCostSupplier(forwardTags)); - bikeTraversalTimes.setOneEdge(forwardEdge, new LaDotBikeCostSupplier(forwardTags)); - LaDotCostTags backwardTags = new LaDotCostTags(way, BACKWARD); - walkTraversalTimes.setOneEdge(backwardEdge, new LaDotWalkCostSupplier(backwardTags)); - bikeTraversalTimes.setOneEdge(backwardEdge, new LaDotBikeCostSupplier(backwardTags)); + CustomCostTags tags = new CustomCostTags(way); + CustomWalkCostSupplier walkSupplier = new CustomWalkCostSupplier(tags); + CustomBikeCostSupplier bikeSupplier = new CustomBikeCostSupplier(tags); + walkTraversalTimes.setOneEdge(forwardEdge, walkSupplier); + bikeTraversalTimes.setOneEdge(forwardEdge, bikeSupplier); + walkTraversalTimes.setOneEdge(backwardEdge, walkSupplier); + bikeTraversalTimes.setOneEdge(backwardEdge, bikeSupplier); } public void summarize () {