From c07f5d3df8bb4a82aba7ced30ce703a96a424ced Mon Sep 17 00:00:00 2001 From: ansons Date: Wed, 11 Nov 2020 17:59:50 -0500 Subject: [PATCH 1/2] feat(gen-cost): write custom cost tags instead of calculating them with the default LADOT cost supplier --- .../com/conveyal/osmlib/main/SpeedSetter.java | 4 ++ .../r5/streets/CustomBikeCostSupplier.java | 19 +++++++++ .../conveyal/r5/streets/CustomCostTags.java | 39 +++++++++++++++++++ .../r5/streets/CustomWalkCostSupplier.java | 19 +++++++++ .../r5/streets/EdgeTraversalTimes.java | 13 ++++--- .../conveyal/r5/streets/EgressCostTable.java | 2 +- 6 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/conveyal/r5/streets/CustomBikeCostSupplier.java create mode 100644 src/main/java/com/conveyal/r5/streets/CustomCostTags.java create mode 100644 src/main/java/com/conveyal/r5/streets/CustomWalkCostSupplier.java 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 e76ccf439..d187f5427 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 () { diff --git a/src/main/java/com/conveyal/r5/streets/EgressCostTable.java b/src/main/java/com/conveyal/r5/streets/EgressCostTable.java index 895cae6f5..4d520bf85 100644 --- a/src/main/java/com/conveyal/r5/streets/EgressCostTable.java +++ b/src/main/java/com/conveyal/r5/streets/EgressCostTable.java @@ -102,7 +102,7 @@ public class EgressCostTable implements Serializable { /** * Build an EgressCostTable for the given LinkedPointSet. * If the LinkedPointSet is for a scenario built on top of a baseline, elements in the EgressCostTable for the - * baseline should be reused where possible, with only the differences recomputed. + * baseline should be reused where possible, with only the differences recomsputed. * * For each transit stop in the associated TransportNetwork, make a table of distances to nearby points in this * PointSet. From c680fefc2312c9987e3d8770e2f95595d72917b1 Mon Sep 17 00:00:00 2001 From: Anson Stewart Date: Wed, 16 Dec 2020 20:17:21 -0500 Subject: [PATCH 2/2] fix(typo) --- src/main/java/com/conveyal/r5/streets/EgressCostTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/conveyal/r5/streets/EgressCostTable.java b/src/main/java/com/conveyal/r5/streets/EgressCostTable.java index 4d520bf85..895cae6f5 100644 --- a/src/main/java/com/conveyal/r5/streets/EgressCostTable.java +++ b/src/main/java/com/conveyal/r5/streets/EgressCostTable.java @@ -102,7 +102,7 @@ public class EgressCostTable implements Serializable { /** * Build an EgressCostTable for the given LinkedPointSet. * If the LinkedPointSet is for a scenario built on top of a baseline, elements in the EgressCostTable for the - * baseline should be reused where possible, with only the differences recomsputed. + * baseline should be reused where possible, with only the differences recomputed. * * For each transit stop in the associated TransportNetwork, make a table of distances to nearby points in this * PointSet.