Skip to content

Commit

Permalink
Bicycle improvement: Add support for tag segregated #721
Browse files Browse the repository at this point in the history
  • Loading branch information
ratrun authored and karussell committed Sep 20, 2016
1 parent eb69a03 commit f868236
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 21 deletions.
Expand Up @@ -294,6 +294,8 @@ public long handleRelationTags(ReaderRelation relation, long oldRelationFlags) {
Integer val = bikeNetworkToCode.get(relation.getTag("network"));
if (val != null)
code = val;
else
code = PriorityCode.PREFER.getValue(); // Assume priority of network "lcn" as bicycle route default
} else if (relation.hasTag("route", "ferry")) {
code = AVOID_IF_POSSIBLE.getValue();
}
Expand Down Expand Up @@ -364,14 +366,19 @@ int getSpeed(ReaderWay way) {
String highwayTag = way.getTag("highway");
Integer highwaySpeed = highwaySpeeds.get(highwayTag);

// Under certain conditions we need to increase the speed of pushing sections to the speed of a "highway=cycleway"
if (way.hasTag("highway", pushingSectionsHighways)
&& ((way.hasTag("foot", "yes") && way.hasTag("segregated", "yes"))
|| way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official")))
highwaySpeed = getHighwaySpeed("cycleway");

String s = way.getTag("surface");
if (!Helper.isEmpty(s)) {
Integer surfaceSpeed = surfaceSpeeds.get(s);
if (surfaceSpeed != null) {
speed = surfaceSpeed;
// Boost handling for good surfaces
// boost handling for good surfaces but avoid boosting if pushing section
if (highwaySpeed != null && surfaceSpeed > highwaySpeed) {
// Avoid boosting if pushing section
if (pushingSectionsHighways.contains(highwayTag))
speed = highwaySpeed;
else
Expand All @@ -397,13 +404,19 @@ int getSpeed(ReaderWay way) {
if (speed > PUSHING_SECTION_SPEED
&& (way.hasTag("highway", pushingSectionsHighways) || way.hasTag("bicycle", "dismount"))) {
if (!way.hasTag("bicycle", intendedValues)) {
// Here we set the speed for pushing sections and set speed for steps as even lower:
if (way.hasTag("highway", "steps"))
speed = PUSHING_SECTION_SPEED / 2;
else
speed = PUSHING_SECTION_SPEED;
} else if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official"))
speed = getHighwaySpeed("cycleway");
else
} else if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official")) {
// Here we handle the cases where the OSM tagging results in something similar to "highway=cycleway"
speed = highwaySpeeds.get("cycleway");
} else {
speed = PUSHING_SECTION_SPEED;
}
// Increase speed in case of segregated
if (speed <= PUSHING_SECTION_SPEED && way.hasTag("segregated", "yes"))
speed = PUSHING_SECTION_SPEED * 2;
}

Expand Down Expand Up @@ -515,8 +528,12 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
weightToPrioMap.put(100d, PREFER.getValue());
}

if ("cycleway".equals(highway))
weightToPrioMap.put(100d, VERY_NICE.getValue());
if ("cycleway".equals(highway)) {
if (way.hasTag("foot", intendedValues) && !way.hasTag("segregated", "yes"))
weightToPrioMap.put(100d, PREFER.getValue());
else
weightToPrioMap.put(100d, VERY_NICE.getValue());
}

double maxSpeed = getMaxSpeed(way);
if (preferHighwayTags.contains(highway) || maxSpeed > 0 && maxSpeed <= 30) {
Expand All @@ -535,10 +552,17 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
if (pushingSectionsHighways.contains(highway)
|| way.hasTag("bicycle", "use_sidepath")
|| "parking_aisle".equals(service)) {
if (way.hasTag("bicycle", "yes"))
weightToPrioMap.put(100d, UNCHANGED.getValue());
else
weightToPrioMap.put(50d, AVOID_IF_POSSIBLE.getValue());
int pushingSectionPrio = AVOID_IF_POSSIBLE.getValue();
if (way.hasTag("bicycle", "yes") || way.hasTag("bicycle", "permissive"))
pushingSectionPrio = PREFER.getValue();
if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official"))
pushingSectionPrio = VERY_NICE.getValue();
if (way.hasTag("foot", "yes")) {
pushingSectionPrio = Math.max(pushingSectionPrio - 1, WORST.getValue());
if (way.hasTag("segregated", "yes"))
pushingSectionPrio = Math.min(pushingSectionPrio + 1, BEST.getValue());
}
weightToPrioMap.put(100d, pushingSectionPrio);
}

if (way.hasTag("railway", "tram"))
Expand All @@ -555,7 +579,7 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
}

// Increase the priority for scenic routes or in case that maxspeed limits our average speed as compensation. See #630
if (way.hasTag("scenic", "yes") || ((maxSpeed > 0) && (maxSpeed < wayTypeSpeed))) {
if (way.hasTag("scenic", "yes") || maxSpeed > 0 && maxSpeed < wayTypeSpeed) {
if (weightToPrioMap.lastEntry().getValue() < BEST.getValue())
// Increase the prio by one step
weightToPrioMap.put(110d, weightToPrioMap.lastEntry().getValue() + 1);
Expand Down
Expand Up @@ -70,33 +70,68 @@ public void testGetSpeed() {
way.clearTags();
way.setTag("highway", "footway");
way.setTag("bicycle", "yes");
assertEquals(PUSHING_SECTION_SPEED, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);
way.setTag("segregated", "no");
assertEquals(PUSHING_SECTION_SPEED, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);
way.setTag("segregated", "yes");
assertEquals(PUSHING_SECTION_SPEED * 2, encoder.getSpeed(way));
assertPriority(UNCHANGED.getValue(), way);
assertPriority(PREFER.getValue(), way);

way.clearTags();
way.setTag("highway", "footway");
way.setTag("surface", "paved");
way.setTag("bicycle", "yes");

assertEquals(PUSHING_SECTION_SPEED, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);
way.setTag("segregated", "yes");
assertEquals(PUSHING_SECTION_SPEED * 2, encoder.getSpeed(way));
assertPriority(UNCHANGED.getValue(), way);
assertPriority(PREFER.getValue(), way);

way.clearTags();
way.setTag("highway", "cycleway");
assertEquals(18, encoder.getSpeed(way));
assertPriority(VERY_NICE.getValue(), way);
int cyclewaySpeed = encoder.getSpeed(way);
way.setTag("foot", "yes");
way.setTag("segregated", "yes");
assertPriority(VERY_NICE.getValue(), way);
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
way.setTag("segregated", "no");
assertPriority(PREFER.getValue(), way);
assertEquals(cyclewaySpeed, encoder.getSpeed(way));

// Make sure that highway=cycleway" and highway=path with bicycle = designated give same result
// Make sure that "highway=cycleway" and "highway=path" with "bicycle=designated" give the same result
way.clearTags();
way.setTag("highway", "path");
way.setTag("bicycle", "designated");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
// Assume foot=no for designated in absence of a foot tag
assertPriority(VERY_NICE.getValue(), way);
way.setTag("foot", "yes");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);

way.setTag("foot", "no");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
assertPriority(VERY_NICE.getValue(), way);

way.setTag("segregated", "yes");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
assertPriority(VERY_NICE.getValue(), way);

way.setTag("segregated", "no");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
assertPriority(VERY_NICE.getValue(), way);

way.setTag("bicycle", "yes");
assertEquals(PUSHING_SECTION_SPEED, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);

way.setTag("segregated", "yes");
assertEquals(PUSHING_SECTION_SPEED * 2, encoder.getSpeed(way));
assertPriority(UNCHANGED.getValue(), way);
assertPriority(PREFER.getValue(), way);

way.setTag("surface", "unpaved");
assertEquals(PUSHING_SECTION_SPEED * 2, encoder.getSpeed(way));
Expand Down Expand Up @@ -127,7 +162,7 @@ public void testGetSpeed() {
way.setTag("surface", "paved");
way.setTag("bicycle", "designated");
assertEquals(cyclewaySpeed, encoder.getSpeed(way));
assertPriority(PREFER.getValue(), way);
assertPriority(VERY_NICE.getValue(), way);

way.clearTags();
way.setTag("highway", "track");
Expand Down Expand Up @@ -167,6 +202,12 @@ public void testGetSpeed() {
way.setTag("surface", "paved");
assertEquals(18, encoder.getSpeed(way));

way.clearTags();
way.setTag("highway", "path");
way.setTag("surface", "ground");
assertEquals(4, encoder.getSpeed(way));
assertPriority(AVOID_IF_POSSIBLE.getValue(), way);

way.clearTags();
way.setTag("highway", "track");
way.setTag("bicycle", "yes");
Expand All @@ -181,6 +222,13 @@ public void testGetSpeed() {
way.setTag("surface", "fine_gravel");
assertEquals(18, encoder.getSpeed(way));

way.clearTags();
way.setTag("highway", "track");
way.setTag("surface", "gravel");
way.setTag("tracktype", "grade2");
assertEquals(12, encoder.getSpeed(way));
assertPriority(UNCHANGED.getValue(), way);

way.clearTags();
way.setTag("highway", "primary");
way.setTag("surface", "paved");
Expand Down Expand Up @@ -336,6 +384,10 @@ public void testHandleWayTagsInfluencedByRelation() {

// relation code is PREFER
osmRel.setTag("route", "bicycle");
relFlags = encoder.handleRelationTags(osmRel, 0);
flags = encoder.handleWayTags(osmWay, allowed, relFlags);
assertEquals(12, encoder.getSpeed(flags), 1e-1);
assertPriority(PREFER.getValue(), osmWay, relFlags);
osmRel.setTag("network", "lcn");
relFlags = encoder.handleRelationTags(osmRel, 0);
flags = encoder.handleWayTags(osmWay, allowed, relFlags);
Expand Down
Expand Up @@ -45,6 +45,7 @@
import static com.graphhopper.util.Parameters.Algorithms.ASTAR;
import static com.graphhopper.util.Parameters.Algorithms.DIJKSTRA_BI;
import static org.junit.Assert.assertEquals;
import org.junit.Ignore;

/**
* Try algorithms, indices and graph storages with real data
Expand Down Expand Up @@ -366,7 +367,7 @@ public void testMonacoBike() {
public void testMonacoMountainBike() {
List<OneRun> list = new ArrayList<OneRun>();
list.add(new OneRun(43.730864, 7.420771, 43.727687, 7.418737, 2322, 110));
list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3613, 178));
list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3655, 176));
list.add(new OneRun(43.728677, 7.41016, 43.739213, 7.427806, 2331, 121));
// hard to select between secondary and primary (both are AVOID for mtb)
list.add(new OneRun(43.733802, 7.413433, 43.739662, 7.424355, 1459, 88));
Expand Down Expand Up @@ -400,7 +401,7 @@ public void testKremsBikeRelation() {
List<OneRun> list = new ArrayList<OneRun>();
list.add(new OneRun(48.409523, 15.602394, 48.375466, 15.72916, 12491, 159));
// 3109m is better as cyclepath is used
list.add(new OneRun(48.410061, 15.63951, 48.411386, 15.604899, 3077, 79));
list.add(new OneRun(48.410061, 15.63951, 48.411386, 15.604899, 3112, 87));
list.add(new OneRun(48.412294, 15.62007, 48.398306, 15.609667, 3965, 94));

runAlgo(testCollector, DIR + "/krems.osm.gz", "target/krems-gh",
Expand Down Expand Up @@ -495,8 +496,11 @@ public void testMonacoVia() {
@Test
public void testHarsdorf() {
List<OneRun> list = new ArrayList<OneRun>();
// TODO somehow the bigger road is take even if we make it less preferred (e.g. introduce AVOID AT ALL costs for lanes=2&&maxspeed>50)
list.add(new OneRun(50.004333, 11.600254, 50.044449, 11.543434, 6952, 190));

// choose Unterloher Weg and the following residential + cycleway
list.add(new OneRun(50.004333, 11.600254, 50.044449, 11.543434, 6931, 184));
// list.add(new OneRun(50.004333, 11.600254, 50.044449, 11.543434, 6931, 184));
runAlgo(testCollector, DIR + "/north-bayreuth.osm.gz", "target/north-bayreuth-gh",
list, "bike", true, "bike", "fastest", false);
assertEquals(testCollector.toString(), 0, testCollector.errors.size());
Expand Down

0 comments on commit f868236

Please sign in to comment.