Skip to content

Commit

Permalink
Merge pull request #600 from ratrun/issue597_part1
Browse files Browse the repository at this point in the history
Compensate loss of road type speed by low maxspeed values via increase of preference
  • Loading branch information
karussell committed Dec 30, 2015
2 parents d7b3386 + 45f617e commit 6507530
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 39 deletions.
Expand Up @@ -791,16 +791,18 @@ protected static String getStr( String str, String key )
}

/**
* @param force should be false if speed should be changed only if it is bigger than maxspeed.
* @param way: needed to retrieve OSM tags
* @param speed: speed guessed e.g. from the road type or other tags
* @return The assumed speed.
*/
protected double applyMaxSpeed( OSMWay way, double speed, boolean force )
protected double applyMaxSpeed( OSMWay way, double speed )
{
double maxSpeed = getMaxSpeed(way);
// apply only if smaller maxSpeed
// We obay speed limits
if (maxSpeed >= 0)
{
if (force || maxSpeed < speed)
return maxSpeed * 0.9;
// We assume that the average speed is 90% of the allowed maximum
return maxSpeed * 0.9;
}
return speed;
}
Expand Down
Expand Up @@ -319,20 +319,42 @@ public long handleRelationTags( OSMRelation relation, long oldRelationFlags )
return oldRelationFlags;
}

/**
* Apply maxspeed: In contrast to the implementation of the AbstractFlagEncoder,
* we assume that we can reach the maxspeed for bicycles in case that the road
* type speed is higher and not just only 90%.
* <p>
* @param way: needed to retrieve OSM tags
* @param speed: speed guessed e.g. from the road type or other tags
* @return The assumed avererage speed.
*/
@Override
protected double applyMaxSpeed( OSMWay way, double speed)
{
double maxSpeed = getMaxSpeed(way);
if (maxSpeed >= 0)
{
// We strictly obay speed limits, see #600
if ( maxSpeed < speed )
{
return maxSpeed;
}
}
return speed;
}

@Override
public long handleWayTags( OSMWay way, long allowed, long relationFlags )
{
if (!isAccept(allowed))
return 0;

long encoded = 0;
double wayTypeSpeed = getSpeed(way);
if (!isFerry(allowed))
{
double speed = getSpeed(way);

// bike maxspeed handling is different from car as we don't increase speed
speed = applyMaxSpeed(way, speed, false);
encoded = handleSpeed(way, speed, encoded);
wayTypeSpeed = applyMaxSpeed(way, wayTypeSpeed);
encoded = handleSpeed(way, wayTypeSpeed, encoded);
encoded = handleBikeRelated(way, encoded, relationFlags > UNCHANGED.getValue());

boolean isRoundabout = way.hasTag("junction", "roundabout");
Expand All @@ -353,7 +375,7 @@ public long handleWayTags( OSMWay way, long allowed, long relationFlags )
if (relationFlags != 0)
priorityFromRelation = (int) relationCodeEncoder.getValue(relationFlags);

encoded = priorityWayEncoder.setValue(encoded, handlePriority(way, priorityFromRelation));
encoded = priorityWayEncoder.setValue(encoded, handlePriority(way, wayTypeSpeed, priorityFromRelation));
return encoded;
}

Expand Down Expand Up @@ -469,15 +491,15 @@ String getWayName( int pavementType, int wayType, Translation tr )
* <p>
* @return new priority based on priorityFromRelation and on the tags in OSMWay.
*/
protected int handlePriority( OSMWay way, int priorityFromRelation )
protected int handlePriority( OSMWay way, double wayTypeSpeed, int priorityFromRelation )
{
TreeMap<Double, Integer> weightToPrioMap = new TreeMap<Double, Integer>();
if (priorityFromRelation == 0)
weightToPrioMap.put(0d, UNCHANGED.getValue());
else
weightToPrioMap.put(110d, priorityFromRelation);

collect(way, weightToPrioMap);
collect(way, wayTypeSpeed, weightToPrioMap);

// pick priority with biggest order value
return weightToPrioMap.lastEntry().getValue();
Expand Down Expand Up @@ -520,7 +542,7 @@ private PriorityCode convertClassValueToPriority( String tagvalue )
* @param weightToPrioMap associate a weight with every priority. This sorted map allows
* subclasses to 'insert' more important priorities as well as overwrite determined priorities.
*/
void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
void collect( OSMWay way, double wayTypeSpeed, TreeMap<Double, Integer> weightToPrioMap )
{
String service = way.getTag("service");
String highway = way.getTag("highway");
Expand Down Expand Up @@ -573,8 +595,9 @@ void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
if (classBicycle != null)
weightToPrioMap.put(100d, convertClassValueToPriority(classBicycle).getValue());
}

if (way.hasTag("scenic", "yes"))

// 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 (weightToPrioMap.lastEntry().getValue() < BEST.getValue())
// Increase the prio by one step
Expand Down
Expand Up @@ -246,7 +246,7 @@ public long handleWayTags( OSMWay way, long allowed, long relationFlags )
{
// get assumed speed from highway type
double speed = getSpeed(way);
speed = applyMaxSpeed(way, speed, true);
speed = applyMaxSpeed(way, speed);

// limit speed to max 30 km/h if bad surface
if (speed > 30 && way.hasTag("surface", badSurfaceSpeedMap))
Expand Down
Expand Up @@ -208,7 +208,7 @@ public long handleWayTags( OSMWay way, long allowed, long priorityFromRelation )
{
// get assumed speed from highway type
double speed = getSpeed(way);
speed = applyMaxSpeed(way, speed, true);
speed = applyMaxSpeed(way, speed);

double maxMCSpeed = parseSpeed(way.getTag("maxspeed:motorcycle"));
if (maxMCSpeed > 0 && maxMCSpeed < speed)
Expand Down
Expand Up @@ -154,9 +154,9 @@ public int getVersion()
}

@Override
void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
void collect( OSMWay way, double wayTypeSpeed, TreeMap<Double, Integer> weightToPrioMap )
{
super.collect(way, weightToPrioMap);
super.collect(way, wayTypeSpeed, weightToPrioMap);

String highway = way.getTag("highway");
if ("track".equals(highway))
Expand Down
Expand Up @@ -142,9 +142,9 @@ public int getVersion()
}

@Override
void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
void collect( OSMWay way, double wayTypeSpeed, TreeMap<Double, Integer> weightToPrioMap )
{
super.collect(way, weightToPrioMap);
super.collect(way, wayTypeSpeed, weightToPrioMap);

String highway = way.getTag("highway");
if ("service".equals(highway))
Expand Down
Expand Up @@ -56,7 +56,7 @@ protected void assertPriority( int expectedPrio, OSMWay way )

protected void assertPriority( int expectedPrio, OSMWay way, long relationFlags )
{
assertEquals(expectedPrio, encoder.handlePriority(way, (int) encoder.relationCodeEncoder.getValue(relationFlags)));
assertEquals(expectedPrio, encoder.handlePriority(way, 18, (int) encoder.relationCodeEncoder.getValue(relationFlags)));
}

protected double getSpeedFromFlags( OSMWay way )
Expand Down Expand Up @@ -373,15 +373,15 @@ public void testReduceToMaxSpeed()
{
OSMWay way = new OSMWay(12);
way.setTag("maxspeed", "90");
assertEquals(12, encoder.applyMaxSpeed(way, 12, false), 1e-2);
assertEquals(12, encoder.applyMaxSpeed(way, 12), 1e-2);
}

@Test
public void testPreferenceForSlowSpeed()
{
OSMWay osmWay = new OSMWay(1);
osmWay.setTag("highway", "tertiary");
assertEquals(30, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 49, false))), 1e-1);
assertEquals(30, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 49))), 1e-1);
assertPriority(PREFER.getValue(), osmWay);
}

Expand Down
Expand Up @@ -423,18 +423,29 @@ public void testMaxSpeed()
long allowed = encoder.acceptWay(way);
long encoded = encoder.handleWayTags(way, allowed, 0);
assertEquals(10, encoder.getSpeed(encoded), 1e-1);
assertPriority(VERY_NICE.getValue(), way);

way = new OSMWay(1);
way.setTag("highway", "tertiary");
way.setTag("maxspeed", "90");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(way, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(way, 20))), 1e-1);
assertPriority(UNCHANGED.getValue(), way);

way = new OSMWay(1);
way.setTag("highway", "track");
way.setTag("maxspeed", "90");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(way, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(way, 20))), 1e-1);
assertPriority(UNCHANGED.getValue(), way);

way = new OSMWay(1);
way.setTag("highway", "residential");
way.setTag("maxspeed", "15");
assertEquals(15, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(way, 15))), 1.0);
allowed = encoder.acceptWay(way);
encoded = encoder.handleWayTags(way, allowed, 0);
assertEquals(15, encoder.getSpeed(encoded), 1.0);
assertPriority(VERY_NICE.getValue(), way);

}

@Test
Expand Down Expand Up @@ -539,10 +550,18 @@ public void testClassBicycle()
assertPriority(REACH_DEST.getValue(), way);
way.setTag("class:bicycle", "-3");
assertPriority(AVOID_AT_ALL_COSTS.getValue(), way);

way.setTag("highway", "residential");
way.setTag("bicycle", "designated");
way.setTag("class:bicycle", "3");
assertPriority(BEST.getValue(), way);

// Now we test overriding by a specific class subtype
way.setTag("class:bicycle:touring", "2");
assertPriority(VERY_NICE.getValue(), way);

way.setTag("maxspeed", "15");
assertPriority(BEST.getValue(), way);
}

}
Expand Up @@ -172,7 +172,7 @@ public long handleRelationTags( OSMRelation relation, long oldRelFlags )
}

@Override
protected int handlePriority( OSMWay way, int priorityFromRelation )
protected int handlePriority( OSMWay way, double wayTypeSpeed, int priorityFromRelation )
{
return priorityFromRelation;
}
Expand Down
Expand Up @@ -210,58 +210,58 @@ public void testAvoidanceOfHighMaxSpeed()
OSMWay osmWay = new OSMWay(1);
osmWay.setTag("highway", "tertiary");
osmWay.setTag("maxspeed", "50");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(PREFER.getValue(), osmWay);

osmWay.setTag("maxspeed", "60");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(PREFER.getValue(), osmWay);

osmWay.setTag("maxspeed", "80");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(PREFER.getValue(), osmWay);

osmWay.setTag("maxspeed", "90");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(UNCHANGED.getValue(), osmWay);

osmWay.setTag("maxspeed", "120");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(UNCHANGED.getValue(), osmWay);

osmWay.setTag("highway", "motorway");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(REACH_DEST.getValue(), osmWay);

osmWay.setTag("tunnel", "yes");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(AVOID_AT_ALL_COSTS.getValue(), osmWay);

osmWay.clearTags();
osmWay.setTag("highway", "motorway");
osmWay.setTag("tunnel", "yes");
osmWay.setTag("maxspeed", "80");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(AVOID_AT_ALL_COSTS.getValue(), osmWay);

osmWay.clearTags();
osmWay.setTag("highway", "motorway");
osmWay.setTag("tunnel", "yes");
osmWay.setTag("maxspeed", "120");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(AVOID_AT_ALL_COSTS.getValue(), osmWay);

osmWay.clearTags();
osmWay.setTag("highway", "notdefined");
osmWay.setTag("tunnel", "yes");
osmWay.setTag("maxspeed", "120");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(AVOID_AT_ALL_COSTS.getValue(), osmWay);

osmWay.clearTags();
osmWay.setTag("highway", "notdefined");
osmWay.setTag("maxspeed", "50");
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20, false))), 1e-1);
assertEquals(20, encoder.getSpeed(encoder.setSpeed(0, encoder.applyMaxSpeed(osmWay, 20))), 1e-1);
assertPriority(UNCHANGED.getValue(), osmWay);

}
Expand Down

0 comments on commit 6507530

Please sign in to comment.